Statistics
| Branch: | Tag: | Revision:

root / qa / qa_os.py @ 6d3d13ab

History | View | Annotate | Download (6.9 kB)

1
#
2
#
3

    
4
# Copyright (C) 2007, 2008, 2009, 2010, 2011 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""OS related QA tests.
23

24
"""
25

    
26
import os
27
import os.path
28

    
29
from ganeti import utils
30
from ganeti import constants
31
from ganeti import pathutils
32

    
33
import qa_config
34
import qa_utils
35
import qa_error
36

    
37
from qa_utils import AssertCommand, AssertIn, AssertNotIn
38

    
39

    
40
_TEMP_OS_NAME = "TEMP-Ganeti-QA-OS"
41
_TEMP_OS_PATH = os.path.join(pathutils.OS_SEARCH_PATH[0], _TEMP_OS_NAME)
42

    
43
(_ALL_VALID,
44
 _ALL_INVALID,
45
 _PARTIALLY_VALID) = range(1, 4)
46

    
47

    
48
def TestOsList():
49
  """gnt-os list"""
50
  AssertCommand(["gnt-os", "list"])
51

    
52

    
53
def TestOsDiagnose():
54
  """gnt-os diagnose"""
55
  AssertCommand(["gnt-os", "diagnose"])
56

    
57

    
58
def _TestOsModify(hvp_dict, fail=False):
59
  """gnt-os modify"""
60
  cmd = ["gnt-os", "modify"]
61

    
62
  for hv_name, hv_params in hvp_dict.items():
63
    cmd.append("-H")
64
    options = []
65
    for key, value in hv_params.items():
66
      options.append("%s=%s" % (key, value))
67
    cmd.append("%s:%s" % (hv_name, ",".join(options)))
68

    
69
  cmd.append(_TEMP_OS_NAME)
70
  AssertCommand(cmd, fail=fail)
71

    
72

    
73
def _TestOsStates(os_name):
74
  """gnt-os modify, more stuff"""
75
  cmd = ["gnt-os", "modify"]
76

    
77
  for param in ["hidden", "blacklisted"]:
78
    for val in ["yes", "no"]:
79
      new_cmd = cmd + ["--%s" % param, val, os_name]
80
      AssertCommand(new_cmd)
81
      # check that double-running the command is OK
82
      AssertCommand(new_cmd)
83

    
84

    
85
def _SetupTempOs(node, dirname, variant, valid):
86
  """Creates a temporary OS definition on the given node.
87

88
  """
89
  sq = utils.ShellQuoteArgs
90
  parts = [
91
    sq(["rm", "-rf", dirname]),
92
    sq(["mkdir", "-p", dirname]),
93
    sq(["cd", dirname]),
94
    sq(["ln", "-fs", "/bin/true", "export"]),
95
    sq(["ln", "-fs", "/bin/true", "import"]),
96
    sq(["ln", "-fs", "/bin/true", "rename"]),
97
    sq(["ln", "-fs", "/bin/true", "verify"]),
98
    ]
99

    
100
  if valid:
101
    parts.append(sq(["ln", "-fs", "/bin/true", "create"]))
102

    
103
  parts.append(sq(["echo", str(constants.OS_API_V20)]) +
104
               " >ganeti_api_version")
105

    
106
  parts.append(sq(["echo", variant]) + " >variants.list")
107
  parts.append(sq(["echo", "funny this is funny"]) + " >parameters.list")
108

    
109
  cmd = " && ".join(parts)
110

    
111
  print qa_utils.FormatInfo("Setting up %s with %s OS definition" %
112
                            (node["primary"],
113
                             ["an invalid", "a valid"][int(valid)]))
114

    
115
  AssertCommand(cmd, node=node)
116

    
117

    
118
def _RemoveTempOs(node, dirname):
119
  """Removes a temporary OS definition.
120

121
  """
122
  AssertCommand(["rm", "-rf", dirname], node=node)
123

    
124

    
125
def _TestOs(mode, rapi_cb):
126
  """Generic function for OS definition testing
127

128
  """
129
  master = qa_config.GetMasterNode()
130

    
131
  name = _TEMP_OS_NAME
132
  variant = "default"
133
  fullname = "%s+%s" % (name, variant)
134
  dirname = _TEMP_OS_PATH
135

    
136
  # Ensure OS is usable
137
  cmd = ["gnt-os", "modify", "--hidden=no", "--blacklisted=no", name]
138
  AssertCommand(cmd)
139

    
140
  nodes = []
141
  try:
142
    for i, node in enumerate(qa_config.get("nodes")):
143
      nodes.append(node)
144
      if mode == _ALL_INVALID:
145
        valid = False
146
      elif mode == _ALL_VALID:
147
        valid = True
148
      elif mode == _PARTIALLY_VALID:
149
        valid = bool(i % 2)
150
      else:
151
        raise AssertionError("Unknown mode %s" % mode)
152
      _SetupTempOs(node, dirname, variant, valid)
153

    
154
    # TODO: Use Python 2.6's itertools.permutations
155
    for (hidden, blacklisted) in [(False, False), (True, False),
156
                                  (False, True), (True, True)]:
157
      # Change OS' visibility
158
      cmd = ["gnt-os", "modify", "--hidden", ["no", "yes"][int(hidden)],
159
             "--blacklisted", ["no", "yes"][int(blacklisted)], name]
160
      AssertCommand(cmd)
161

    
162
      # Diagnose, checking exit status
163
      AssertCommand(["gnt-os", "diagnose"], fail=(mode != _ALL_VALID))
164

    
165
      # Diagnose again, ignoring exit status
166
      output = qa_utils.GetCommandOutput(master["primary"],
167
                                         "gnt-os diagnose || :")
168
      for line in output.splitlines():
169
        if line.startswith("OS: %s [global status:" % name):
170
          break
171
      else:
172
        raise qa_error.Error("Didn't find OS '%s' in 'gnt-os diagnose'" % name)
173

    
174
      # Check info for all
175
      cmd = ["gnt-os", "info"]
176
      output = qa_utils.GetCommandOutput(master["primary"],
177
                                         utils.ShellQuoteArgs(cmd))
178
      AssertIn("%s:" % name, output.splitlines())
179

    
180
      # Check info for OS
181
      cmd = ["gnt-os", "info", name]
182
      output = qa_utils.GetCommandOutput(master["primary"],
183
                                         utils.ShellQuoteArgs(cmd)).splitlines()
184
      AssertIn("%s:" % name, output)
185
      for (field, value) in [("valid", mode == _ALL_VALID),
186
                             ("hidden", hidden),
187
                             ("blacklisted", blacklisted)]:
188
        AssertIn("  - %s: %s" % (field, value), output)
189

    
190
      # Only valid OSes should be listed
191
      cmd = ["gnt-os", "list", "--no-headers"]
192
      output = qa_utils.GetCommandOutput(master["primary"],
193
                                         utils.ShellQuoteArgs(cmd))
194
      if mode == _ALL_VALID and not (hidden or blacklisted):
195
        assert_fn = AssertIn
196
      else:
197
        assert_fn = AssertNotIn
198
      assert_fn(fullname, output.splitlines())
199

    
200
      # Check via RAPI
201
      if rapi_cb:
202
        assert_fn(fullname, rapi_cb())
203
  finally:
204
    for node in nodes:
205
      _RemoveTempOs(node, dirname)
206

    
207

    
208
def TestOsValid(rapi_cb):
209
  """Testing valid OS definition"""
210
  return _TestOs(_ALL_VALID, rapi_cb)
211

    
212

    
213
def TestOsInvalid(rapi_cb):
214
  """Testing invalid OS definition"""
215
  return _TestOs(_ALL_INVALID, rapi_cb)
216

    
217

    
218
def TestOsPartiallyValid(rapi_cb):
219
  """Testing partially valid OS definition"""
220
  return _TestOs(_PARTIALLY_VALID, rapi_cb)
221

    
222

    
223
def TestOsModifyValid():
224
  """Testing a valid os modify invocation"""
225
  hv_dict = {
226
    constants.HT_XEN_PVM: {
227
      constants.HV_ROOT_PATH: "/dev/sda5",
228
      },
229
    constants.HT_XEN_HVM: {
230
      constants.HV_ACPI: False,
231
      constants.HV_PAE: True,
232
      },
233
    }
234

    
235
  return _TestOsModify(hv_dict)
236

    
237

    
238
def TestOsModifyInvalid():
239
  """Testing an invalid os modify invocation"""
240
  hv_dict = {
241
    "blahblahblubb": {"bar": ""},
242
    }
243

    
244
  return _TestOsModify(hv_dict, fail=True)
245

    
246

    
247
def TestOsStatesNonExisting():
248
  """Testing OS states with non-existing OS"""
249
  AssertCommand(["test", "-e", _TEMP_OS_PATH], fail=True)
250
  return _TestOsStates(_TEMP_OS_NAME)