4 # Copyright (C) 2007 Google Inc.
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.
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.
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
22 """Script for doing QA on Ganeti.
41 from ganeti import utils
44 def RunTest(fn, *args):
45 """Runs a test after printing a header.
49 desc = fn.__doc__.splitlines()[0].strip()
53 now = str(datetime.datetime.now())
56 print '---', now, ('-' * (55 - len(now)))
64 """Run several environment tests.
67 if not qa_config.TestEnabled('env'):
70 RunTest(qa_env.TestSshConnection)
71 RunTest(qa_env.TestIcmpPing)
72 RunTest(qa_env.TestGanetiCommands)
75 def SetupCluster(rapi_user, rapi_secret):
76 """Initializes the cluster.
78 @param rapi_user: Login user for RAPI
79 @param rapi_secret: Login secret for RAPI
82 if qa_config.TestEnabled('create-cluster'):
83 RunTest(qa_cluster.TestClusterInit, rapi_user, rapi_secret)
84 RunTest(qa_node.TestNodeAddAll)
86 # consider the nodes are already there
87 qa_node.MarkNodeAddedAll()
88 if qa_config.TestEnabled('node-info'):
89 RunTest(qa_node.TestNodeInfo)
92 def RunClusterTests():
93 """Runs tests related to gnt-cluster.
96 if qa_config.TestEnabled("cluster-renew-crypto"):
97 RunTest(qa_cluster.TestClusterRenewCrypto)
99 if qa_config.TestEnabled('cluster-verify'):
100 RunTest(qa_cluster.TestClusterVerify)
102 if qa_config.TestEnabled('cluster-rename'):
103 RunTest(qa_cluster.TestClusterRename)
105 if qa_config.TestEnabled('cluster-info'):
106 RunTest(qa_cluster.TestClusterVersion)
107 RunTest(qa_cluster.TestClusterInfo)
108 RunTest(qa_cluster.TestClusterGetmaster)
110 if qa_config.TestEnabled('cluster-copyfile'):
111 RunTest(qa_cluster.TestClusterCopyfile)
113 if qa_config.TestEnabled('cluster-command'):
114 RunTest(qa_cluster.TestClusterCommand)
116 if qa_config.TestEnabled('cluster-burnin'):
117 RunTest(qa_cluster.TestClusterBurnin)
119 if qa_config.TestEnabled('cluster-master-failover'):
120 RunTest(qa_cluster.TestClusterMasterFailover)
122 if qa_rapi.Enabled():
123 RunTest(qa_rapi.TestVersion)
124 RunTest(qa_rapi.TestEmptyCluster)
128 """Runs all tests related to gnt-os.
131 if not qa_config.TestEnabled('os'):
134 RunTest(qa_os.TestOsList)
135 RunTest(qa_os.TestOsDiagnose)
136 RunTest(qa_os.TestOsValid)
137 RunTest(qa_os.TestOsInvalid)
138 RunTest(qa_os.TestOsPartiallyValid)
139 RunTest(qa_os.TestOsModifyValid)
140 RunTest(qa_os.TestOsModifyInvalid)
143 def RunCommonInstanceTests(instance):
144 """Runs a few tests that are common to all disk types.
147 if qa_config.TestEnabled('instance-shutdown'):
148 RunTest(qa_instance.TestInstanceShutdown, instance)
149 RunTest(qa_instance.TestInstanceStartup, instance)
151 if qa_config.TestEnabled('instance-list'):
152 RunTest(qa_instance.TestInstanceList)
154 if qa_config.TestEnabled('instance-info'):
155 RunTest(qa_instance.TestInstanceInfo, instance)
157 if qa_config.TestEnabled('instance-modify'):
158 RunTest(qa_instance.TestInstanceModify, instance)
160 if qa_config.TestEnabled('instance-console'):
161 RunTest(qa_instance.TestInstanceConsole, instance)
163 if qa_config.TestEnabled('instance-reinstall'):
164 RunTest(qa_instance.TestInstanceShutdown, instance)
165 RunTest(qa_instance.TestInstanceReinstall, instance)
166 RunTest(qa_instance.TestInstanceStartup, instance)
168 if qa_config.TestEnabled('instance-reboot'):
169 RunTest(qa_instance.TestInstanceReboot, instance)
171 if qa_config.TestEnabled('instance-rename'):
172 RunTest(qa_instance.TestInstanceShutdown, instance)
173 RunTest(qa_instance.TestInstanceRename, instance)
174 RunTest(qa_instance.TestInstanceStartup, instance)
176 if qa_config.TestEnabled('tags'):
177 RunTest(qa_tags.TestInstanceTags, instance)
179 if qa_config.TestEnabled('node-volumes'):
180 RunTest(qa_node.TestNodeVolumes)
182 if qa_config.TestEnabled("node-storage"):
183 RunTest(qa_node.TestNodeStorage)
185 if qa_rapi.Enabled():
186 RunTest(qa_rapi.TestInstance, instance)
189 def RunExportImportTests(instance, pnode):
190 """Tries to export and import the instance.
193 if qa_config.TestEnabled('instance-export'):
194 expnode = qa_config.AcquireNode(exclude=pnode)
196 name = RunTest(qa_instance.TestInstanceExport, instance, expnode)
198 RunTest(qa_instance.TestBackupList, expnode)
200 if qa_config.TestEnabled('instance-import'):
201 newinst = qa_config.AcquireInstance()
203 RunTest(qa_instance.TestInstanceImport, pnode, newinst,
205 RunTest(qa_instance.TestInstanceRemove, newinst)
207 qa_config.ReleaseInstance(newinst)
209 qa_config.ReleaseNode(expnode)
212 def RunDaemonTests(instance, pnode):
213 """Test the ganeti-watcher script.
216 automatic_restart = \
217 qa_config.TestEnabled('instance-automatic-restart')
218 consecutive_failures = \
219 qa_config.TestEnabled('instance-consecutive-failures')
221 if automatic_restart or consecutive_failures:
222 qa_daemon.PrintCronWarning()
224 if automatic_restart:
225 RunTest(qa_daemon.TestInstanceAutomaticRestart, pnode, instance)
227 if consecutive_failures:
228 RunTest(qa_daemon.TestInstanceConsecutiveFailures, pnode, instance)
231 def RunHardwareFailureTests(instance, pnode, snode):
232 """Test cluster internal hardware failure recovery.
235 if qa_config.TestEnabled('instance-failover'):
236 RunTest(qa_instance.TestInstanceFailover, instance)
238 if qa_config.TestEnabled('instance-replace-disks'):
239 othernode = qa_config.AcquireNode(exclude=[pnode, snode])
241 RunTest(qa_instance.TestReplaceDisks,
242 instance, pnode, snode, othernode)
244 qa_config.ReleaseNode(othernode)
246 if qa_config.TestEnabled('node-evacuate'):
247 RunTest(qa_node.TestNodeEvacuate, pnode, snode)
249 if qa_config.TestEnabled('node-failover'):
250 RunTest(qa_node.TestNodeFailover, pnode, snode)
252 if qa_config.TestEnabled('instance-disk-failure'):
253 RunTest(qa_instance.TestInstanceMasterDiskFailure,
254 instance, pnode, snode)
255 RunTest(qa_instance.TestInstanceSecondaryDiskFailure,
256 instance, pnode, snode)
263 parser = optparse.OptionParser(usage="%prog [options] <config-file>")
264 parser.add_option('--yes-do-it', dest='yes_do_it',
266 help="Really execute the tests")
267 (qa_config.options, args) = parser.parse_args()
270 (config_file, ) = args
272 parser.error("Wrong number of arguments.")
274 if not qa_config.options.yes_do_it:
275 print ("Executing this script irreversibly destroys any Ganeti\n"
276 "configuration on all nodes involved. If you really want\n"
277 "to start testing, supply the --yes-do-it option.")
280 qa_config.Load(config_file)
282 rapi_user = "ganeti-qa"
283 rapi_secret = utils.GenerateSecret()
284 qa_rapi.OpenerFactory.SetCredentials(rapi_user, rapi_secret)
287 SetupCluster(rapi_user, rapi_secret)
291 if qa_config.TestEnabled('tags'):
292 RunTest(qa_tags.TestClusterTags)
294 if qa_config.TestEnabled('node-readd'):
295 master = qa_config.GetMasterNode()
296 pnode = qa_config.AcquireNode(exclude=master)
298 RunTest(qa_node.TestNodeReadd, pnode)
300 qa_config.ReleaseNode(pnode)
302 pnode = qa_config.AcquireNode()
304 if qa_config.TestEnabled('tags'):
305 RunTest(qa_tags.TestNodeTags, pnode)
307 if qa_rapi.Enabled():
308 RunTest(qa_rapi.TestNode, pnode)
310 if qa_config.TestEnabled('instance-add-plain-disk'):
311 instance = RunTest(qa_instance.TestInstanceAddWithPlainDisk, pnode)
312 RunCommonInstanceTests(instance)
313 RunExportImportTests(instance, pnode)
314 RunDaemonTests(instance, pnode)
315 RunTest(qa_instance.TestInstanceRemove, instance)
319 ('instance-add-drbd-disk',
320 qa_instance.TestInstanceAddWithDrbdDisk),
323 for name, func in multinode_tests:
324 if qa_config.TestEnabled(name):
325 snode = qa_config.AcquireNode(exclude=pnode)
327 instance = RunTest(func, pnode, snode)
328 RunCommonInstanceTests(instance)
329 if qa_config.TestEnabled('instance-convert-disk'):
330 RunTest(qa_instance.TestInstanceConvertDisk, instance, snode)
331 RunExportImportTests(instance, pnode)
332 RunHardwareFailureTests(instance, pnode, snode)
333 RunTest(qa_instance.TestInstanceRemove, instance)
336 qa_config.ReleaseNode(snode)
339 qa_config.ReleaseNode(pnode)
341 if qa_config.TestEnabled('create-cluster'):
342 RunTest(qa_node.TestNodeRemoveAll)
344 if qa_config.TestEnabled('cluster-destroy'):
345 RunTest(qa_cluster.TestClusterDestroy)
348 if __name__ == '__main__':