bash_completion: Enable extglob while parsing file
[ganeti-local] / test / ganeti.rapi.rlib2_unittest.py
1 #!/usr/bin/python
2 #
3
4 # Copyright (C) 2010 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 """Script for unittesting the RAPI rlib2 module
23
24 """
25
26
27 import unittest
28 import itertools
29 import random
30
31 from ganeti import constants
32 from ganeti import opcodes
33 from ganeti import compat
34 from ganeti import http
35 from ganeti import query
36 from ganeti import luxi
37 from ganeti import errors
38
39 from ganeti.rapi import rlib2
40
41 import testutils
42
43
44 class _FakeRequestPrivateData:
45   def __init__(self, body_data):
46     self.body_data = body_data
47
48
49 class _FakeRequest:
50   def __init__(self, body_data):
51     self.private = _FakeRequestPrivateData(body_data)
52
53
54 def _CreateHandler(cls, items, queryargs, body_data, client_cls):
55   return cls(items, queryargs, _FakeRequest(body_data),
56              _client_cls=client_cls)
57
58
59 class _FakeClient:
60   def __init__(self):
61     self._jobs = []
62
63   def GetNextSubmittedJob(self):
64     return self._jobs.pop(0)
65
66   def SubmitJob(self, ops):
67     job_id = str(1 + int(random.random() * 1000000))
68     self._jobs.append((job_id, ops))
69     return job_id
70
71
72 class _FakeClientFactory:
73   def __init__(self, cls):
74     self._client_cls = cls
75     self._clients = []
76
77   def GetNextClient(self):
78     return self._clients.pop(0)
79
80   def __call__(self):
81     cl = self._client_cls()
82     self._clients.append(cl)
83     return cl
84
85
86 class TestConstants(unittest.TestCase):
87   def testConsole(self):
88     # Exporting the console field without authentication might expose
89     # information
90     assert "console" in query.INSTANCE_FIELDS
91     self.assertTrue("console" not in rlib2.I_FIELDS)
92
93   def testFields(self):
94     checks = {
95       constants.QR_INSTANCE: rlib2.I_FIELDS,
96       constants.QR_NODE: rlib2.N_FIELDS,
97       constants.QR_GROUP: rlib2.G_FIELDS,
98       }
99
100     for (qr, fields) in checks.items():
101       self.assertFalse(set(fields) - set(query.ALL_FIELDS[qr].keys()))
102
103
104 class TestClientConnectError(unittest.TestCase):
105   @staticmethod
106   def _FailingClient():
107     raise luxi.NoMasterError("test")
108
109   def test(self):
110     resources = [
111       rlib2.R_2_groups,
112       rlib2.R_2_instances,
113       rlib2.R_2_nodes,
114       ]
115     for cls in resources:
116       handler = _CreateHandler(cls, ["name"], [], None, self._FailingClient)
117       self.assertRaises(http.HttpBadGateway, handler.GET)
118
119
120 class TestJobSubmitError(unittest.TestCase):
121   class _SubmitErrorClient:
122     @staticmethod
123     def SubmitJob(ops):
124       raise errors.JobQueueFull("test")
125
126   def test(self):
127     handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None,
128                              self._SubmitErrorClient)
129     self.assertRaises(http.HttpServiceUnavailable, handler.PUT)
130
131
132 class TestClusterModify(unittest.TestCase):
133   def test(self):
134     clfactory = _FakeClientFactory(_FakeClient)
135     handler = _CreateHandler(rlib2.R_2_cluster_modify, [], [], {
136       "vg_name": "testvg",
137       "candidate_pool_size": 100,
138       }, clfactory)
139     job_id = handler.PUT()
140
141     cl = clfactory.GetNextClient()
142     self.assertRaises(IndexError, clfactory.GetNextClient)
143
144     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
145     self.assertEqual(job_id, exp_job_id)
146     self.assertTrue(isinstance(op, opcodes.OpClusterSetParams))
147     self.assertEqual(op.vg_name, "testvg")
148     self.assertEqual(op.candidate_pool_size, 100)
149
150     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
151
152   def testInvalidValue(self):
153     for attr in ["vg_name", "candidate_pool_size", "beparams", "_-Unknown#"]:
154       clfactory = _FakeClientFactory(_FakeClient)
155       handler = _CreateHandler(rlib2.R_2_cluster_modify, [], [], {
156         attr: True,
157         }, clfactory)
158       self.assertRaises(http.HttpBadRequest, handler.PUT)
159       self.assertRaises(IndexError, clfactory.GetNextClient)
160
161
162 class TestRedistConfig(unittest.TestCase):
163   def test(self):
164     clfactory = _FakeClientFactory(_FakeClient)
165     handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None, clfactory)
166     job_id = handler.PUT()
167
168     cl = clfactory.GetNextClient()
169     self.assertRaises(IndexError, clfactory.GetNextClient)
170
171     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
172     self.assertEqual(job_id, exp_job_id)
173     self.assertTrue(isinstance(op, opcodes.OpClusterRedistConf))
174
175     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
176
177
178 class TestNodeMigrate(unittest.TestCase):
179   def test(self):
180     clfactory = _FakeClientFactory(_FakeClient)
181     handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node1"], {}, {
182       "iallocator": "fooalloc",
183       }, clfactory)
184     job_id = handler.POST()
185
186     cl = clfactory.GetNextClient()
187     self.assertRaises(IndexError, clfactory.GetNextClient)
188
189     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
190     self.assertEqual(job_id, exp_job_id)
191     self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
192     self.assertEqual(op.node_name, "node1")
193     self.assertEqual(op.iallocator, "fooalloc")
194
195     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
196
197   def testQueryArgsConflict(self):
198     clfactory = _FakeClientFactory(_FakeClient)
199     handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node2"], {
200       "live": True,
201       "mode": constants.HT_MIGRATION_NONLIVE,
202       }, None, clfactory)
203     self.assertRaises(http.HttpBadRequest, handler.POST)
204     self.assertRaises(IndexError, clfactory.GetNextClient)
205
206   def testQueryArgsMode(self):
207     clfactory = _FakeClientFactory(_FakeClient)
208     queryargs = {
209       "mode": [constants.HT_MIGRATION_LIVE],
210       }
211     handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node17292"],
212                              queryargs, None, clfactory)
213     job_id = handler.POST()
214
215     cl = clfactory.GetNextClient()
216     self.assertRaises(IndexError, clfactory.GetNextClient)
217
218     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
219     self.assertEqual(job_id, exp_job_id)
220     self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
221     self.assertEqual(op.node_name, "node17292")
222     self.assertEqual(op.mode, constants.HT_MIGRATION_LIVE)
223
224     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
225
226   def testQueryArgsLive(self):
227     clfactory = _FakeClientFactory(_FakeClient)
228
229     for live in [False, True]:
230       queryargs = {
231         "live": [str(int(live))],
232         }
233       handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node6940"],
234                                queryargs, None, clfactory)
235       job_id = handler.POST()
236
237       cl = clfactory.GetNextClient()
238       self.assertRaises(IndexError, clfactory.GetNextClient)
239
240       (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
241       self.assertEqual(job_id, exp_job_id)
242       self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
243       self.assertEqual(op.node_name, "node6940")
244       if live:
245         self.assertEqual(op.mode, constants.HT_MIGRATION_LIVE)
246       else:
247         self.assertEqual(op.mode, constants.HT_MIGRATION_NONLIVE)
248
249       self.assertRaises(IndexError, cl.GetNextSubmittedJob)
250
251
252 class TestNodeEvacuate(unittest.TestCase):
253   def test(self):
254     clfactory = _FakeClientFactory(_FakeClient)
255     handler = _CreateHandler(rlib2.R_2_nodes_name_evacuate, ["node92"], {
256       "dry-run": ["1"],
257       }, {
258       "mode": constants.IALLOCATOR_NEVAC_SEC,
259       }, clfactory)
260     job_id = handler.POST()
261
262     cl = clfactory.GetNextClient()
263     self.assertRaises(IndexError, clfactory.GetNextClient)
264
265     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
266     self.assertEqual(job_id, exp_job_id)
267     self.assertTrue(isinstance(op, opcodes.OpNodeEvacuate))
268     self.assertEqual(op.node_name, "node92")
269     self.assertEqual(op.mode, constants.IALLOCATOR_NEVAC_SEC)
270     self.assertTrue(op.dry_run)
271
272     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
273
274
275 class TestNodePowercycle(unittest.TestCase):
276   def test(self):
277     clfactory = _FakeClientFactory(_FakeClient)
278     handler = _CreateHandler(rlib2.R_2_nodes_name_powercycle, ["node20744"], {
279       "force": ["1"],
280       }, None, clfactory)
281     job_id = handler.POST()
282
283     cl = clfactory.GetNextClient()
284     self.assertRaises(IndexError, clfactory.GetNextClient)
285
286     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
287     self.assertEqual(job_id, exp_job_id)
288     self.assertTrue(isinstance(op, opcodes.OpNodePowercycle))
289     self.assertEqual(op.node_name, "node20744")
290     self.assertTrue(op.force)
291
292     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
293
294
295 class TestGroupAssignNodes(unittest.TestCase):
296   def test(self):
297     clfactory = _FakeClientFactory(_FakeClient)
298     handler = _CreateHandler(rlib2.R_2_groups_name_assign_nodes, ["grp-a"], {
299       "dry-run": ["1"],
300       "force": ["1"],
301       }, {
302       "nodes": ["n2", "n3"],
303       }, clfactory)
304     job_id = handler.PUT()
305
306     cl = clfactory.GetNextClient()
307     self.assertRaises(IndexError, clfactory.GetNextClient)
308
309     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
310     self.assertEqual(job_id, exp_job_id)
311     self.assertTrue(isinstance(op, opcodes.OpGroupAssignNodes))
312     self.assertEqual(op.group_name, "grp-a")
313     self.assertEqual(op.nodes, ["n2", "n3"])
314     self.assertTrue(op.dry_run)
315     self.assertTrue(op.force)
316
317     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
318
319
320 class TestInstanceDelete(unittest.TestCase):
321   def test(self):
322     clfactory = _FakeClientFactory(_FakeClient)
323     handler = _CreateHandler(rlib2.R_2_instances_name, ["inst30965"], {
324       "dry-run": ["1"],
325       }, {}, clfactory)
326     job_id = handler.DELETE()
327
328     cl = clfactory.GetNextClient()
329     self.assertRaises(IndexError, clfactory.GetNextClient)
330
331     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
332     self.assertEqual(job_id, exp_job_id)
333     self.assertTrue(isinstance(op, opcodes.OpInstanceRemove))
334     self.assertEqual(op.instance_name, "inst30965")
335     self.assertTrue(op.dry_run)
336     self.assertFalse(op.ignore_failures)
337
338     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
339
340
341 class TestInstanceInfo(unittest.TestCase):
342   def test(self):
343     clfactory = _FakeClientFactory(_FakeClient)
344     handler = _CreateHandler(rlib2.R_2_instances_name_info, ["inst31217"], {
345       "static": ["1"],
346       }, {}, clfactory)
347     job_id = handler.GET()
348
349     cl = clfactory.GetNextClient()
350     self.assertRaises(IndexError, clfactory.GetNextClient)
351
352     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
353     self.assertEqual(job_id, exp_job_id)
354     self.assertTrue(isinstance(op, opcodes.OpInstanceQueryData))
355     self.assertEqual(op.instances, ["inst31217"])
356     self.assertTrue(op.static)
357
358     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
359
360
361 class TestInstanceReboot(unittest.TestCase):
362   def test(self):
363     clfactory = _FakeClientFactory(_FakeClient)
364     handler = _CreateHandler(rlib2.R_2_instances_name_reboot, ["inst847"], {
365       "dry-run": ["1"],
366       "ignore_secondaries": ["1"],
367       }, {}, clfactory)
368     job_id = handler.POST()
369
370     cl = clfactory.GetNextClient()
371     self.assertRaises(IndexError, clfactory.GetNextClient)
372
373     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
374     self.assertEqual(job_id, exp_job_id)
375     self.assertTrue(isinstance(op, opcodes.OpInstanceReboot))
376     self.assertEqual(op.instance_name, "inst847")
377     self.assertEqual(op.reboot_type, constants.INSTANCE_REBOOT_HARD)
378     self.assertTrue(op.ignore_secondaries)
379     self.assertTrue(op.dry_run)
380
381     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
382
383
384 class TestInstanceStartup(unittest.TestCase):
385   def test(self):
386     clfactory = _FakeClientFactory(_FakeClient)
387     handler = _CreateHandler(rlib2.R_2_instances_name_startup, ["inst31083"], {
388       "force": ["1"],
389       "no_remember": ["1"],
390       }, {}, clfactory)
391     job_id = handler.PUT()
392
393     cl = clfactory.GetNextClient()
394     self.assertRaises(IndexError, clfactory.GetNextClient)
395
396     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
397     self.assertEqual(job_id, exp_job_id)
398     self.assertTrue(isinstance(op, opcodes.OpInstanceStartup))
399     self.assertEqual(op.instance_name, "inst31083")
400     self.assertTrue(op.no_remember)
401     self.assertTrue(op.force)
402     self.assertFalse(op.dry_run)
403
404     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
405
406
407 class TestInstanceShutdown(unittest.TestCase):
408   def test(self):
409     clfactory = _FakeClientFactory(_FakeClient)
410     handler = _CreateHandler(rlib2.R_2_instances_name_shutdown, ["inst26791"], {
411       "no_remember": ["0"],
412       }, {}, clfactory)
413     job_id = handler.PUT()
414
415     cl = clfactory.GetNextClient()
416     self.assertRaises(IndexError, clfactory.GetNextClient)
417
418     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
419     self.assertEqual(job_id, exp_job_id)
420     self.assertTrue(isinstance(op, opcodes.OpInstanceShutdown))
421     self.assertEqual(op.instance_name, "inst26791")
422     self.assertFalse(op.no_remember)
423     self.assertFalse(op.dry_run)
424
425     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
426
427
428 class TestInstanceActivateDisks(unittest.TestCase):
429   def test(self):
430     clfactory = _FakeClientFactory(_FakeClient)
431     handler = _CreateHandler(rlib2.R_2_instances_name_activate_disks, ["xyz"], {
432       "ignore_size": ["1"],
433       }, {}, clfactory)
434     job_id = handler.PUT()
435
436     cl = clfactory.GetNextClient()
437     self.assertRaises(IndexError, clfactory.GetNextClient)
438
439     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
440     self.assertEqual(job_id, exp_job_id)
441     self.assertTrue(isinstance(op, opcodes.OpInstanceActivateDisks))
442     self.assertEqual(op.instance_name, "xyz")
443     self.assertTrue(op.ignore_size)
444     self.assertFalse(hasattr(op, "dry_run"))
445
446     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
447
448
449 class TestInstanceDeactivateDisks(unittest.TestCase):
450   def test(self):
451     clfactory = _FakeClientFactory(_FakeClient)
452     handler = _CreateHandler(rlib2.R_2_instances_name_deactivate_disks,
453                              ["inst22357"], {}, {}, clfactory)
454     job_id = handler.PUT()
455
456     cl = clfactory.GetNextClient()
457     self.assertRaises(IndexError, clfactory.GetNextClient)
458
459     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
460     self.assertEqual(job_id, exp_job_id)
461     self.assertTrue(isinstance(op, opcodes.OpInstanceDeactivateDisks))
462     self.assertEqual(op.instance_name, "inst22357")
463     self.assertFalse(hasattr(op, "dry_run"))
464     self.assertFalse(hasattr(op, "force"))
465
466     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
467
468
469 class TestInstanceRecreateDisks(unittest.TestCase):
470   def test(self):
471     clfactory = _FakeClientFactory(_FakeClient)
472     handler = _CreateHandler(rlib2.R_2_instances_name_recreate_disks,
473                              ["inst22357"], {}, {}, clfactory)
474     job_id = handler.POST()
475
476     cl = clfactory.GetNextClient()
477     self.assertRaises(IndexError, clfactory.GetNextClient)
478
479     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
480     self.assertEqual(job_id, exp_job_id)
481     self.assertTrue(isinstance(op, opcodes.OpInstanceRecreateDisks))
482     self.assertEqual(op.instance_name, "inst22357")
483     self.assertFalse(hasattr(op, "dry_run"))
484     self.assertFalse(hasattr(op, "force"))
485
486     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
487
488
489 class TestInstanceFailover(unittest.TestCase):
490   def test(self):
491     clfactory = _FakeClientFactory(_FakeClient)
492     handler = _CreateHandler(rlib2.R_2_instances_name_failover,
493                              ["inst12794"], {}, {}, clfactory)
494     job_id = handler.PUT()
495
496     cl = clfactory.GetNextClient()
497     self.assertRaises(IndexError, clfactory.GetNextClient)
498
499     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
500     self.assertEqual(job_id, exp_job_id)
501     self.assertTrue(isinstance(op, opcodes.OpInstanceFailover))
502     self.assertEqual(op.instance_name, "inst12794")
503     self.assertFalse(hasattr(op, "dry_run"))
504     self.assertFalse(hasattr(op, "force"))
505
506     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
507
508
509 class TestInstanceDiskGrow(unittest.TestCase):
510   def test(self):
511     clfactory = _FakeClientFactory(_FakeClient)
512     data = {
513       "amount": 1024,
514       }
515     handler = _CreateHandler(rlib2.R_2_instances_name_disk_grow,
516                              ["inst10742", "3"], {}, data, clfactory)
517     job_id = handler.POST()
518
519     cl = clfactory.GetNextClient()
520     self.assertRaises(IndexError, clfactory.GetNextClient)
521
522     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
523     self.assertEqual(job_id, exp_job_id)
524     self.assertTrue(isinstance(op, opcodes.OpInstanceGrowDisk))
525     self.assertEqual(op.instance_name, "inst10742")
526     self.assertEqual(op.disk, 3)
527     self.assertEqual(op.amount, 1024)
528     self.assertFalse(hasattr(op, "dry_run"))
529     self.assertFalse(hasattr(op, "force"))
530
531     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
532
533
534 class TestBackupPrepare(unittest.TestCase):
535   def test(self):
536     clfactory = _FakeClientFactory(_FakeClient)
537     queryargs = {
538       "mode": constants.EXPORT_MODE_REMOTE,
539       }
540     handler = _CreateHandler(rlib2.R_2_instances_name_prepare_export,
541                              ["inst17925"], queryargs, {}, clfactory)
542     job_id = handler.PUT()
543
544     cl = clfactory.GetNextClient()
545     self.assertRaises(IndexError, clfactory.GetNextClient)
546
547     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
548     self.assertEqual(job_id, exp_job_id)
549     self.assertTrue(isinstance(op, opcodes.OpBackupPrepare))
550     self.assertEqual(op.instance_name, "inst17925")
551     self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
552     self.assertFalse(hasattr(op, "dry_run"))
553     self.assertFalse(hasattr(op, "force"))
554
555     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
556
557
558 class TestGroupRemove(unittest.TestCase):
559   def test(self):
560     clfactory = _FakeClientFactory(_FakeClient)
561     handler = _CreateHandler(rlib2.R_2_groups_name,
562                              ["grp28575"], {}, {}, clfactory)
563     job_id = handler.DELETE()
564
565     cl = clfactory.GetNextClient()
566     self.assertRaises(IndexError, clfactory.GetNextClient)
567
568     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
569     self.assertEqual(job_id, exp_job_id)
570     self.assertTrue(isinstance(op, opcodes.OpGroupRemove))
571     self.assertEqual(op.group_name, "grp28575")
572     self.assertFalse(op.dry_run)
573     self.assertFalse(hasattr(op, "force"))
574
575     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
576
577
578 class TestStorageQuery(unittest.TestCase):
579   def test(self):
580     clfactory = _FakeClientFactory(_FakeClient)
581     queryargs = {
582       "storage_type": constants.ST_LVM_PV,
583       "output_fields": "name,other",
584       }
585     handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
586                              ["node21075"], queryargs, {}, clfactory)
587     job_id = handler.GET()
588
589     cl = clfactory.GetNextClient()
590     self.assertRaises(IndexError, clfactory.GetNextClient)
591
592     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
593     self.assertEqual(job_id, exp_job_id)
594     self.assertTrue(isinstance(op, opcodes.OpNodeQueryStorage))
595     self.assertEqual(op.nodes, ["node21075"])
596     self.assertEqual(op.storage_type, constants.ST_LVM_PV)
597     self.assertEqual(op.output_fields, ["name", "other"])
598     self.assertFalse(hasattr(op, "dry_run"))
599     self.assertFalse(hasattr(op, "force"))
600
601     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
602
603   def testErrors(self):
604     clfactory = _FakeClientFactory(_FakeClient)
605
606     queryargs = {
607       "output_fields": "name,other",
608       }
609     handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
610                              ["node10538"], queryargs, {}, clfactory)
611     self.assertRaises(http.HttpBadRequest, handler.GET)
612
613     queryargs = {
614       "storage_type": constants.ST_LVM_VG,
615       }
616     handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
617                              ["node21273"], queryargs, {}, clfactory)
618     self.assertRaises(http.HttpBadRequest, handler.GET)
619
620     queryargs = {
621       "storage_type": "##unknown_storage##",
622       "output_fields": "name,other",
623       }
624     handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
625                              ["node10315"], queryargs, {}, clfactory)
626     self.assertRaises(http.HttpBadRequest, handler.GET)
627
628
629 class TestStorageModify(unittest.TestCase):
630   def test(self):
631     clfactory = _FakeClientFactory(_FakeClient)
632
633     for allocatable in [None, "1", "0"]:
634       queryargs = {
635         "storage_type": constants.ST_LVM_VG,
636         "name": "pv-a",
637         }
638
639       if allocatable is not None:
640         queryargs["allocatable"] = allocatable
641
642       handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
643                                ["node9292"], queryargs, {}, clfactory)
644       job_id = handler.PUT()
645
646       cl = clfactory.GetNextClient()
647       self.assertRaises(IndexError, clfactory.GetNextClient)
648
649       (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
650       self.assertEqual(job_id, exp_job_id)
651       self.assertTrue(isinstance(op, opcodes.OpNodeModifyStorage))
652       self.assertEqual(op.node_name, "node9292")
653       self.assertEqual(op.storage_type, constants.ST_LVM_VG)
654       self.assertEqual(op.name, "pv-a")
655       if allocatable is None:
656         self.assertFalse(op.changes)
657       else:
658         assert allocatable in ("0", "1")
659         self.assertEqual(op.changes, {
660           constants.SF_ALLOCATABLE: (allocatable == "1"),
661           })
662       self.assertFalse(hasattr(op, "dry_run"))
663       self.assertFalse(hasattr(op, "force"))
664
665       self.assertRaises(IndexError, cl.GetNextSubmittedJob)
666
667   def testErrors(self):
668     clfactory = _FakeClientFactory(_FakeClient)
669
670     # No storage type
671     queryargs = {
672       "name": "xyz",
673       }
674     handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
675                              ["node26016"], queryargs, {}, clfactory)
676     self.assertRaises(http.HttpBadRequest, handler.PUT)
677
678     # No name
679     queryargs = {
680       "storage_type": constants.ST_LVM_VG,
681       }
682     handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
683                              ["node21218"], queryargs, {}, clfactory)
684     self.assertRaises(http.HttpBadRequest, handler.PUT)
685
686     # Invalid value
687     queryargs = {
688       "storage_type": constants.ST_LVM_VG,
689       "name": "pv-b",
690       "allocatable": "noint",
691       }
692     handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
693                              ["node30685"], queryargs, {}, clfactory)
694     self.assertRaises(http.HttpBadRequest, handler.PUT)
695
696
697 class TestStorageRepair(unittest.TestCase):
698   def test(self):
699     clfactory = _FakeClientFactory(_FakeClient)
700     queryargs = {
701       "storage_type": constants.ST_LVM_PV,
702       "name": "pv16611",
703       }
704     handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
705                              ["node19265"], queryargs, {}, clfactory)
706     job_id = handler.PUT()
707
708     cl = clfactory.GetNextClient()
709     self.assertRaises(IndexError, clfactory.GetNextClient)
710
711     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
712     self.assertEqual(job_id, exp_job_id)
713     self.assertTrue(isinstance(op, opcodes.OpRepairNodeStorage))
714     self.assertEqual(op.node_name, "node19265")
715     self.assertEqual(op.storage_type, constants.ST_LVM_PV)
716     self.assertEqual(op.name, "pv16611")
717     self.assertFalse(hasattr(op, "dry_run"))
718     self.assertFalse(hasattr(op, "force"))
719
720     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
721
722   def testErrors(self):
723     clfactory = _FakeClientFactory(_FakeClient)
724
725     # No storage type
726     queryargs = {
727       "name": "xyz",
728       }
729     handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
730                              ["node11275"], queryargs, {}, clfactory)
731     self.assertRaises(http.HttpBadRequest, handler.PUT)
732
733     # No name
734     queryargs = {
735       "storage_type": constants.ST_LVM_VG,
736       }
737     handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
738                              ["node21218"], queryargs, {}, clfactory)
739     self.assertRaises(http.HttpBadRequest, handler.PUT)
740
741
742 class TestTags(unittest.TestCase):
743   TAG_HANDLERS = [
744     rlib2.R_2_instances_name_tags,
745     rlib2.R_2_nodes_name_tags,
746     rlib2.R_2_groups_name_tags,
747     rlib2.R_2_tags,
748     ]
749
750   def testSetAndDelete(self):
751     clfactory = _FakeClientFactory(_FakeClient)
752
753     for method, opcls in [("PUT", opcodes.OpTagsSet),
754                           ("DELETE", opcodes.OpTagsDel)]:
755       for idx, handler in enumerate(self.TAG_HANDLERS):
756         dry_run = bool(idx % 2)
757         name = "test%s" % idx
758         queryargs = {
759           "tag": ["foo", "bar", "baz"],
760           "dry-run": str(int(dry_run)),
761           }
762
763         handler = _CreateHandler(handler, [name], queryargs, {}, clfactory)
764         job_id = getattr(handler, method)()
765
766         cl = clfactory.GetNextClient()
767         self.assertRaises(IndexError, clfactory.GetNextClient)
768
769         (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
770         self.assertEqual(job_id, exp_job_id)
771         self.assertTrue(isinstance(op, opcls))
772         self.assertEqual(op.kind, handler.TAG_LEVEL)
773         if handler.TAG_LEVEL == constants.TAG_CLUSTER:
774           self.assertTrue(op.name is None)
775         else:
776           self.assertEqual(op.name, name)
777         self.assertEqual(op.tags, ["foo", "bar", "baz"])
778         self.assertEqual(op.dry_run, dry_run)
779         self.assertFalse(hasattr(op, "force"))
780
781         self.assertRaises(IndexError, cl.GetNextSubmittedJob)
782
783
784 class TestInstanceCreation(testutils.GanetiTestCase):
785   def test(self):
786     clfactory = _FakeClientFactory(_FakeClient)
787
788     name = "inst863.example.com"
789
790     disk_variants = [
791       # No disks
792       [],
793
794       # Two disks
795       [{"size": 5, }, {"size": 100, }],
796
797       # Disk with mode
798       [{"size": 123, "mode": constants.DISK_RDWR, }],
799       ]
800
801     nic_variants = [
802       # No NIC
803       [],
804
805       # Three NICs
806       [{}, {}, {}],
807
808       # Two NICs
809       [
810         { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
811           "mac": "01:23:45:67:68:9A",
812         },
813         { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
814       ],
815       ]
816
817     beparam_variants = [
818       None,
819       {},
820       { constants.BE_VCPUS: 2, },
821       { constants.BE_MAXMEM: 200, },
822       { constants.BE_MEMORY: 256, },
823       { constants.BE_VCPUS: 2,
824         constants.BE_MAXMEM: 1024,
825         constants.BE_MINMEM: 1024,
826         constants.BE_AUTO_BALANCE: True,
827         constants.BE_ALWAYS_FAILOVER: True, }
828       ]
829
830     hvparam_variants = [
831       None,
832       { constants.HV_BOOT_ORDER: "anc", },
833       { constants.HV_KERNEL_PATH: "/boot/fookernel",
834         constants.HV_ROOT_PATH: "/dev/hda1", },
835       ]
836
837     for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
838       for nics in nic_variants:
839         for disk_template in constants.DISK_TEMPLATES:
840           for disks in disk_variants:
841             for beparams in beparam_variants:
842               for hvparams in hvparam_variants:
843                 for dry_run in [False, True]:
844                   queryargs = {
845                     "dry-run": str(int(dry_run)),
846                     }
847
848                   data = {
849                     rlib2._REQ_DATA_VERSION: 1,
850                     "name": name,
851                     "hypervisor": constants.HT_FAKE,
852                     "disks": disks,
853                     "nics": nics,
854                     "mode": mode,
855                     "disk_template": disk_template,
856                     "os": "debootstrap",
857                     }
858
859                   if beparams is not None:
860                     data["beparams"] = beparams
861
862                   if hvparams is not None:
863                     data["hvparams"] = hvparams
864
865                   handler = _CreateHandler(rlib2.R_2_instances, [],
866                                            queryargs, data, clfactory)
867                   job_id = handler.POST()
868
869                   cl = clfactory.GetNextClient()
870                   self.assertRaises(IndexError, clfactory.GetNextClient)
871
872                   (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
873                   self.assertEqual(job_id, exp_job_id)
874                   self.assertRaises(IndexError, cl.GetNextSubmittedJob)
875
876                   self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
877                   self.assertEqual(op.instance_name, name)
878                   self.assertEqual(op.mode, mode)
879                   self.assertEqual(op.disk_template, disk_template)
880                   self.assertEqual(op.dry_run, dry_run)
881                   self.assertEqual(len(op.disks), len(disks))
882                   self.assertEqual(len(op.nics), len(nics))
883
884                   for opdisk, disk in zip(op.disks, disks):
885                     for key in constants.IDISK_PARAMS:
886                       self.assertEqual(opdisk.get(key), disk.get(key))
887                     self.assertFalse("unknown" in opdisk)
888
889                   for opnic, nic in zip(op.nics, nics):
890                     for key in constants.INIC_PARAMS:
891                       self.assertEqual(opnic.get(key), nic.get(key))
892                     self.assertFalse("unknown" in opnic)
893                     self.assertFalse("foobar" in opnic)
894
895                   if beparams is None:
896                     self.assertFalse(hasattr(op, "beparams"))
897                   else:
898                     self.assertEqualValues(op.beparams, beparams)
899
900                   if hvparams is None:
901                     self.assertFalse(hasattr(op, "hvparams"))
902                   else:
903                     self.assertEqualValues(op.hvparams, hvparams)
904
905   def testLegacyName(self):
906     clfactory = _FakeClientFactory(_FakeClient)
907
908     name = "inst29128.example.com"
909     data = {
910       rlib2._REQ_DATA_VERSION: 1,
911       "name": name,
912       "disks": [],
913       "nics": [],
914       "mode": constants.INSTANCE_CREATE,
915       "disk_template": constants.DT_PLAIN,
916       }
917
918     handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
919     job_id = handler.POST()
920
921     cl = clfactory.GetNextClient()
922     self.assertRaises(IndexError, clfactory.GetNextClient)
923
924     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
925     self.assertEqual(job_id, exp_job_id)
926     self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
927     self.assertEqual(op.instance_name, name)
928     self.assertFalse(hasattr(op, "name"))
929     self.assertFalse(op.dry_run)
930
931     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
932
933     # Define both
934     data["instance_name"] = "other.example.com"
935     assert "name" in data and "instance_name" in data
936     handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
937     self.assertRaises(http.HttpBadRequest, handler.POST)
938     self.assertRaises(IndexError, clfactory.GetNextClient)
939
940   def testLegacyOs(self):
941     clfactory = _FakeClientFactory(_FakeClient)
942
943     name = "inst4673.example.com"
944     os = "linux29206"
945     data = {
946       rlib2._REQ_DATA_VERSION: 1,
947       "name": name,
948       "os_type": os,
949       "disks": [],
950       "nics": [],
951       "mode": constants.INSTANCE_CREATE,
952       "disk_template": constants.DT_PLAIN,
953       }
954
955     handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
956     job_id = handler.POST()
957
958     cl = clfactory.GetNextClient()
959     self.assertRaises(IndexError, clfactory.GetNextClient)
960
961     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
962     self.assertEqual(job_id, exp_job_id)
963     self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
964     self.assertEqual(op.instance_name, name)
965     self.assertEqual(op.os_type, os)
966     self.assertFalse(hasattr(op, "os"))
967     self.assertFalse(op.dry_run)
968
969     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
970
971     # Define both
972     data["os"] = "linux9584"
973     assert "os" in data and "os_type" in data
974     handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
975     self.assertRaises(http.HttpBadRequest, handler.POST)
976
977   def testErrors(self):
978     clfactory = _FakeClientFactory(_FakeClient)
979
980     # Test all required fields
981     reqfields = {
982       rlib2._REQ_DATA_VERSION: 1,
983       "name": "inst1.example.com",
984       "disks": [],
985       "nics": [],
986       "mode": constants.INSTANCE_CREATE,
987       "disk_template": constants.DT_PLAIN,
988       }
989
990     for name in reqfields.keys():
991       data = dict(i for i in reqfields.iteritems() if i[0] != name)
992
993       handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
994       self.assertRaises(http.HttpBadRequest, handler.POST)
995       self.assertRaises(IndexError, clfactory.GetNextClient)
996
997     # Invalid disks and nics
998     for field in ["disks", "nics"]:
999       invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
1000                         [{"_unknown_": 999, }]]
1001
1002       for invvalue in invalid_values:
1003         data = reqfields.copy()
1004         data[field] = invvalue
1005         handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1006         self.assertRaises(http.HttpBadRequest, handler.POST)
1007         self.assertRaises(IndexError, clfactory.GetNextClient)
1008
1009   def testVersion(self):
1010     clfactory = _FakeClientFactory(_FakeClient)
1011
1012     # No version field
1013     data = {
1014       "name": "inst1.example.com",
1015       "disks": [],
1016       "nics": [],
1017       "mode": constants.INSTANCE_CREATE,
1018       "disk_template": constants.DT_PLAIN,
1019       }
1020
1021     handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1022     self.assertRaises(http.HttpBadRequest, handler.POST)
1023
1024     # Old and incorrect versions
1025     for version in [0, -1, 10483, "Hello World"]:
1026       data[rlib2._REQ_DATA_VERSION] = version
1027
1028       handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1029       self.assertRaises(http.HttpBadRequest, handler.POST)
1030
1031       self.assertRaises(IndexError, clfactory.GetNextClient)
1032
1033     # Correct version
1034     data[rlib2._REQ_DATA_VERSION] = 1
1035     handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1036     job_id = handler.POST()
1037
1038     cl = clfactory.GetNextClient()
1039     self.assertRaises(IndexError, clfactory.GetNextClient)
1040
1041     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1042     self.assertEqual(job_id, exp_job_id)
1043     self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
1044     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1045
1046
1047 class TestBackupExport(unittest.TestCase):
1048   def test(self):
1049     clfactory = _FakeClientFactory(_FakeClient)
1050
1051     name = "instmoo"
1052     data = {
1053       "mode": constants.EXPORT_MODE_REMOTE,
1054       "destination": [(1, 2, 3), (99, 99, 99)],
1055       "shutdown": True,
1056       "remove_instance": True,
1057       "x509_key_name": ["name", "hash"],
1058       "destination_x509_ca": "---cert---"
1059       }
1060
1061     handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1062                              data, clfactory)
1063     job_id = handler.PUT()
1064
1065     cl = clfactory.GetNextClient()
1066     self.assertRaises(IndexError, clfactory.GetNextClient)
1067
1068     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1069     self.assertEqual(job_id, exp_job_id)
1070     self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1071     self.assertEqual(op.instance_name, name)
1072     self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
1073     self.assertEqual(op.target_node, [(1, 2, 3), (99, 99, 99)])
1074     self.assertEqual(op.shutdown, True)
1075     self.assertEqual(op.remove_instance, True)
1076     self.assertEqual(op.x509_key_name, ["name", "hash"])
1077     self.assertEqual(op.destination_x509_ca, "---cert---")
1078     self.assertFalse(hasattr(op, "dry_run"))
1079     self.assertFalse(hasattr(op, "force"))
1080
1081     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1082
1083   def testDefaults(self):
1084     clfactory = _FakeClientFactory(_FakeClient)
1085
1086     name = "inst1"
1087     data = {
1088       "destination": "node2",
1089       "shutdown": False,
1090       }
1091
1092     handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1093                              data, clfactory)
1094     job_id = handler.PUT()
1095
1096     cl = clfactory.GetNextClient()
1097     self.assertRaises(IndexError, clfactory.GetNextClient)
1098
1099     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1100     self.assertEqual(job_id, exp_job_id)
1101     self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1102     self.assertEqual(op.instance_name, name)
1103     self.assertEqual(op.target_node, "node2")
1104     self.assertFalse(hasattr(op, "mode"))
1105     self.assertFalse(hasattr(op, "remove_instance"))
1106     self.assertFalse(hasattr(op, "destination"))
1107     self.assertFalse(hasattr(op, "dry_run"))
1108     self.assertFalse(hasattr(op, "force"))
1109
1110     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1111
1112   def testErrors(self):
1113     clfactory = _FakeClientFactory(_FakeClient)
1114
1115     for value in ["True", "False"]:
1116       handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
1117         "remove_instance": value,
1118         }, clfactory)
1119       self.assertRaises(http.HttpBadRequest, handler.PUT)
1120
1121
1122 class TestInstanceMigrate(testutils.GanetiTestCase):
1123   def test(self):
1124     clfactory = _FakeClientFactory(_FakeClient)
1125
1126     name = "instYooho6ek"
1127
1128     for cleanup in [False, True]:
1129       for mode in constants.HT_MIGRATION_MODES:
1130         data = {
1131           "cleanup": cleanup,
1132           "mode": mode,
1133           }
1134
1135         handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
1136                                  data, clfactory)
1137         job_id = handler.PUT()
1138
1139         cl = clfactory.GetNextClient()
1140         self.assertRaises(IndexError, clfactory.GetNextClient)
1141
1142         (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1143         self.assertEqual(job_id, exp_job_id)
1144         self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1145         self.assertEqual(op.instance_name, name)
1146         self.assertEqual(op.mode, mode)
1147         self.assertEqual(op.cleanup, cleanup)
1148         self.assertFalse(hasattr(op, "dry_run"))
1149         self.assertFalse(hasattr(op, "force"))
1150
1151         self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1152
1153   def testDefaults(self):
1154     clfactory = _FakeClientFactory(_FakeClient)
1155
1156     name = "instnohZeex0"
1157
1158     handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
1159                              clfactory)
1160     job_id = handler.PUT()
1161
1162     cl = clfactory.GetNextClient()
1163     self.assertRaises(IndexError, clfactory.GetNextClient)
1164
1165     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1166     self.assertEqual(job_id, exp_job_id)
1167     self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1168     self.assertEqual(op.instance_name, name)
1169     self.assertFalse(hasattr(op, "mode"))
1170     self.assertFalse(hasattr(op, "cleanup"))
1171     self.assertFalse(hasattr(op, "dry_run"))
1172     self.assertFalse(hasattr(op, "force"))
1173
1174     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1175
1176
1177 class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
1178   def test(self):
1179     clfactory = _FakeClientFactory(_FakeClient)
1180
1181     name = "instij0eeph7"
1182
1183     for new_name in ["ua0aiyoo", "fai3ongi"]:
1184       for ip_check in [False, True]:
1185         for name_check in [False, True]:
1186           data = {
1187             "new_name": new_name,
1188             "ip_check": ip_check,
1189             "name_check": name_check,
1190             }
1191
1192           handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1193                                    {}, data, clfactory)
1194           job_id = handler.PUT()
1195
1196           cl = clfactory.GetNextClient()
1197           self.assertRaises(IndexError, clfactory.GetNextClient)
1198
1199           (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1200           self.assertEqual(job_id, exp_job_id)
1201           self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1202           self.assertEqual(op.instance_name, name)
1203           self.assertEqual(op.new_name, new_name)
1204           self.assertEqual(op.ip_check, ip_check)
1205           self.assertEqual(op.name_check, name_check)
1206           self.assertFalse(hasattr(op, "dry_run"))
1207           self.assertFalse(hasattr(op, "force"))
1208
1209           self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1210
1211   def testDefaults(self):
1212     clfactory = _FakeClientFactory(_FakeClient)
1213
1214     name = "instahchie3t"
1215
1216     for new_name in ["thag9mek", "quees7oh"]:
1217       data = {
1218         "new_name": new_name,
1219         }
1220
1221       handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1222                                {}, data, clfactory)
1223       job_id = handler.PUT()
1224
1225       cl = clfactory.GetNextClient()
1226       self.assertRaises(IndexError, clfactory.GetNextClient)
1227
1228       (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1229       self.assertEqual(job_id, exp_job_id)
1230       self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1231       self.assertEqual(op.instance_name, name)
1232       self.assertEqual(op.new_name, new_name)
1233       self.assertFalse(hasattr(op, "ip_check"))
1234       self.assertFalse(hasattr(op, "name_check"))
1235       self.assertFalse(hasattr(op, "dry_run"))
1236       self.assertFalse(hasattr(op, "force"))
1237
1238       self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1239
1240
1241 class TestParseModifyInstanceRequest(unittest.TestCase):
1242   def test(self):
1243     clfactory = _FakeClientFactory(_FakeClient)
1244
1245     name = "instush8gah"
1246
1247     test_disks = [
1248       [],
1249       [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
1250       ]
1251
1252     for osparams in [{}, { "some": "value", "other": "Hello World", }]:
1253       for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
1254         for beparams in [{}, { constants.BE_MAXMEM: 128, }]:
1255           for force in [False, True]:
1256             for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
1257               for disks in test_disks:
1258                 for disk_template in constants.DISK_TEMPLATES:
1259                   data = {
1260                     "osparams": osparams,
1261                     "hvparams": hvparams,
1262                     "beparams": beparams,
1263                     "nics": nics,
1264                     "disks": disks,
1265                     "force": force,
1266                     "disk_template": disk_template,
1267                     }
1268
1269                   handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1270                                            [name], {}, data, clfactory)
1271                   job_id = handler.PUT()
1272
1273                   cl = clfactory.GetNextClient()
1274                   self.assertRaises(IndexError, clfactory.GetNextClient)
1275
1276                   (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1277                   self.assertEqual(job_id, exp_job_id)
1278                   self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1279                   self.assertEqual(op.instance_name, name)
1280                   self.assertEqual(op.hvparams, hvparams)
1281                   self.assertEqual(op.beparams, beparams)
1282                   self.assertEqual(op.osparams, osparams)
1283                   self.assertEqual(op.force, force)
1284                   self.assertEqual(op.nics, nics)
1285                   self.assertEqual(op.disks, disks)
1286                   self.assertEqual(op.disk_template, disk_template)
1287                   self.assertFalse(hasattr(op, "remote_node"))
1288                   self.assertFalse(hasattr(op, "os_name"))
1289                   self.assertFalse(hasattr(op, "force_variant"))
1290                   self.assertFalse(hasattr(op, "dry_run"))
1291
1292                   self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1293
1294   def testDefaults(self):
1295     clfactory = _FakeClientFactory(_FakeClient)
1296
1297     name = "instir8aish31"
1298
1299     handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1300                              [name], {}, {}, clfactory)
1301     job_id = handler.PUT()
1302
1303     cl = clfactory.GetNextClient()
1304     self.assertRaises(IndexError, clfactory.GetNextClient)
1305
1306     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1307     self.assertEqual(job_id, exp_job_id)
1308     self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1309     self.assertEqual(op.instance_name, name)
1310
1311     for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
1312               "disk_template", "remote_node", "os_name", "force_variant"]:
1313       self.assertFalse(hasattr(op, i))
1314
1315
1316 class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1317   def setUp(self):
1318     testutils.GanetiTestCase.setUp(self)
1319
1320     self.Parse = rlib2._ParseInstanceReinstallRequest
1321
1322   def _Check(self, ops, name):
1323     expcls = [
1324       opcodes.OpInstanceShutdown,
1325       opcodes.OpInstanceReinstall,
1326       opcodes.OpInstanceStartup,
1327       ]
1328
1329     self.assert_(compat.all(isinstance(op, exp)
1330                             for op, exp in zip(ops, expcls)))
1331     self.assert_(compat.all(op.instance_name == name for op in ops))
1332
1333   def test(self):
1334     name = "shoo0tihohma"
1335
1336     ops = self.Parse(name, {"os": "sys1", "start": True,})
1337     self.assertEqual(len(ops), 3)
1338     self._Check(ops, name)
1339     self.assertEqual(ops[1].os_type, "sys1")
1340     self.assertFalse(ops[1].osparams)
1341
1342     ops = self.Parse(name, {"os": "sys2", "start": False,})
1343     self.assertEqual(len(ops), 2)
1344     self._Check(ops, name)
1345     self.assertEqual(ops[1].os_type, "sys2")
1346
1347     osparams = {
1348       "reformat": "1",
1349       }
1350     ops = self.Parse(name, {"os": "sys4035", "start": True,
1351                             "osparams": osparams,})
1352     self.assertEqual(len(ops), 3)
1353     self._Check(ops, name)
1354     self.assertEqual(ops[1].os_type, "sys4035")
1355     self.assertEqual(ops[1].osparams, osparams)
1356
1357   def testDefaults(self):
1358     name = "noolee0g"
1359
1360     ops = self.Parse(name, {"os": "linux1"})
1361     self.assertEqual(len(ops), 3)
1362     self._Check(ops, name)
1363     self.assertEqual(ops[1].os_type, "linux1")
1364     self.assertFalse(ops[1].osparams)
1365
1366   def testErrors(self):
1367     self.assertRaises(http.HttpBadRequest, self.Parse,
1368                       "foo", "not a dictionary")
1369
1370
1371 class TestGroupRename(unittest.TestCase):
1372   def test(self):
1373     clfactory = _FakeClientFactory(_FakeClient)
1374
1375     name = "group608242564"
1376     data = {
1377       "new_name": "ua0aiyoo15112",
1378       }
1379
1380     handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1381                              clfactory)
1382     job_id = handler.PUT()
1383
1384     cl = clfactory.GetNextClient()
1385     self.assertRaises(IndexError, clfactory.GetNextClient)
1386
1387     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1388     self.assertEqual(job_id, exp_job_id)
1389
1390     self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1391     self.assertEqual(op.group_name, name)
1392     self.assertEqual(op.new_name, "ua0aiyoo15112")
1393     self.assertFalse(op.dry_run)
1394     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1395
1396   def testDryRun(self):
1397     clfactory = _FakeClientFactory(_FakeClient)
1398
1399     name = "group28548"
1400     data = {
1401       "new_name": "ua0aiyoo",
1402       }
1403
1404     handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
1405       "dry-run": ["1"],
1406       }, data, clfactory)
1407     job_id = handler.PUT()
1408
1409     cl = clfactory.GetNextClient()
1410     self.assertRaises(IndexError, clfactory.GetNextClient)
1411
1412     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1413     self.assertEqual(job_id, exp_job_id)
1414
1415     self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1416     self.assertEqual(op.group_name, name)
1417     self.assertEqual(op.new_name, "ua0aiyoo")
1418     self.assertTrue(op.dry_run)
1419     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1420
1421
1422 class TestInstanceReplaceDisks(unittest.TestCase):
1423   def test(self):
1424     clfactory = _FakeClientFactory(_FakeClient)
1425
1426     name = "inst22568"
1427
1428     for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
1429       data = {
1430         "mode": constants.REPLACE_DISK_SEC,
1431         "disks": disks,
1432         "iallocator": "myalloc",
1433         }
1434
1435       handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1436                                [name], {}, data, clfactory)
1437       job_id = handler.POST()
1438
1439       cl = clfactory.GetNextClient()
1440       self.assertRaises(IndexError, clfactory.GetNextClient)
1441
1442       (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1443       self.assertEqual(job_id, exp_job_id)
1444
1445       self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1446       self.assertEqual(op.instance_name, name)
1447       self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
1448       self.assertEqual(op.disks, [1, 2, 3])
1449       self.assertEqual(op.iallocator, "myalloc")
1450       self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1451
1452   def testDefaults(self):
1453     clfactory = _FakeClientFactory(_FakeClient)
1454
1455     name = "inst11413"
1456     data = {
1457       "mode": constants.REPLACE_DISK_AUTO,
1458       }
1459
1460     handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1461                              [name], {}, data, clfactory)
1462     job_id = handler.POST()
1463
1464     cl = clfactory.GetNextClient()
1465     self.assertRaises(IndexError, clfactory.GetNextClient)
1466
1467     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1468     self.assertEqual(job_id, exp_job_id)
1469
1470     self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1471     self.assertEqual(op.instance_name, name)
1472     self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
1473     self.assertFalse(hasattr(op, "iallocator"))
1474     self.assertFalse(hasattr(op, "disks"))
1475     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1476
1477   def testNoDisks(self):
1478     clfactory = _FakeClientFactory(_FakeClient)
1479
1480     handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1481                              ["inst20661"], {}, {}, clfactory)
1482     self.assertRaises(http.HttpBadRequest, handler.POST)
1483
1484     for disks in [None, "", {}]:
1485       handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1486                                ["inst20661"], {}, {
1487         "disks": disks,
1488         }, clfactory)
1489       self.assertRaises(http.HttpBadRequest, handler.POST)
1490
1491   def testWrong(self):
1492     clfactory = _FakeClientFactory(_FakeClient)
1493
1494     data = {
1495       "mode": constants.REPLACE_DISK_AUTO,
1496       "disks": "hello world",
1497       }
1498
1499     handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1500                              ["foo"], {}, data, clfactory)
1501     self.assertRaises(http.HttpBadRequest, handler.POST)
1502
1503
1504 class TestGroupModify(unittest.TestCase):
1505   def test(self):
1506     clfactory = _FakeClientFactory(_FakeClient)
1507
1508     name = "group6002"
1509
1510     for policy in constants.VALID_ALLOC_POLICIES:
1511       data = {
1512         "alloc_policy": policy,
1513         }
1514
1515       handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1516                                clfactory)
1517       job_id = handler.PUT()
1518
1519       cl = clfactory.GetNextClient()
1520       self.assertRaises(IndexError, clfactory.GetNextClient)
1521
1522       (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1523       self.assertEqual(job_id, exp_job_id)
1524
1525       self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1526       self.assertEqual(op.group_name, name)
1527       self.assertEqual(op.alloc_policy, policy)
1528       self.assertFalse(hasattr(op, "dry_run"))
1529       self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1530
1531   def testUnknownPolicy(self):
1532     clfactory = _FakeClientFactory(_FakeClient)
1533
1534     data = {
1535       "alloc_policy": "_unknown_policy_",
1536       }
1537
1538     handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1539                              clfactory)
1540     self.assertRaises(http.HttpBadRequest, handler.PUT)
1541     self.assertRaises(IndexError, clfactory.GetNextClient)
1542
1543   def testDefaults(self):
1544     clfactory = _FakeClientFactory(_FakeClient)
1545
1546     name = "group6679"
1547
1548     handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1549                              clfactory)
1550     job_id = handler.PUT()
1551
1552     cl = clfactory.GetNextClient()
1553     self.assertRaises(IndexError, clfactory.GetNextClient)
1554
1555     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1556     self.assertEqual(job_id, exp_job_id)
1557
1558     self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1559     self.assertEqual(op.group_name, name)
1560     self.assertFalse(hasattr(op, "alloc_policy"))
1561     self.assertFalse(hasattr(op, "dry_run"))
1562     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1563
1564
1565 class TestGroupAdd(unittest.TestCase):
1566   def test(self):
1567     name = "group3618"
1568     clfactory = _FakeClientFactory(_FakeClient)
1569
1570     for policy in constants.VALID_ALLOC_POLICIES:
1571       data = {
1572         "group_name": name,
1573         "alloc_policy": policy,
1574         }
1575
1576       handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1577                                clfactory)
1578       job_id = handler.POST()
1579
1580       cl = clfactory.GetNextClient()
1581       self.assertRaises(IndexError, clfactory.GetNextClient)
1582
1583       (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1584       self.assertEqual(job_id, exp_job_id)
1585
1586       self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1587       self.assertEqual(op.group_name, name)
1588       self.assertEqual(op.alloc_policy, policy)
1589       self.assertFalse(op.dry_run)
1590       self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1591
1592   def testUnknownPolicy(self):
1593     clfactory = _FakeClientFactory(_FakeClient)
1594
1595     data = {
1596       "alloc_policy": "_unknown_policy_",
1597       }
1598
1599     handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1600     self.assertRaises(http.HttpBadRequest, handler.POST)
1601     self.assertRaises(IndexError, clfactory.GetNextClient)
1602
1603   def testDefaults(self):
1604     clfactory = _FakeClientFactory(_FakeClient)
1605
1606     name = "group15395"
1607     data = {
1608       "group_name": name,
1609       }
1610
1611     handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1612     job_id = handler.POST()
1613
1614     cl = clfactory.GetNextClient()
1615     self.assertRaises(IndexError, clfactory.GetNextClient)
1616
1617     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1618     self.assertEqual(job_id, exp_job_id)
1619
1620     self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1621     self.assertEqual(op.group_name, name)
1622     self.assertFalse(hasattr(op, "alloc_policy"))
1623     self.assertFalse(op.dry_run)
1624
1625   def testLegacyName(self):
1626     clfactory = _FakeClientFactory(_FakeClient)
1627
1628     name = "group29852"
1629     data = {
1630       "name": name,
1631       }
1632
1633     handler = _CreateHandler(rlib2.R_2_groups, [], {
1634       "dry-run": ["1"],
1635       }, data, clfactory)
1636     job_id = handler.POST()
1637
1638     cl = clfactory.GetNextClient()
1639     self.assertRaises(IndexError, clfactory.GetNextClient)
1640
1641     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1642     self.assertEqual(job_id, exp_job_id)
1643
1644     self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1645     self.assertEqual(op.group_name, name)
1646     self.assertFalse(hasattr(op, "alloc_policy"))
1647     self.assertTrue(op.dry_run)
1648
1649
1650 class TestNodeRole(unittest.TestCase):
1651   def test(self):
1652     clfactory = _FakeClientFactory(_FakeClient)
1653
1654     for role in rlib2._NR_MAP.values():
1655       handler = _CreateHandler(rlib2.R_2_nodes_name_role,
1656                                ["node-z"], {}, role, clfactory)
1657       if role == rlib2._NR_MASTER:
1658         self.assertRaises(http.HttpBadRequest, handler.PUT)
1659       else:
1660         job_id = handler.PUT()
1661
1662         cl = clfactory.GetNextClient()
1663         self.assertRaises(IndexError, clfactory.GetNextClient)
1664
1665         (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1666         self.assertEqual(job_id, exp_job_id)
1667         self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
1668         self.assertEqual(op.node_name, "node-z")
1669         self.assertFalse(op.force)
1670         self.assertFalse(hasattr(op, "dry_run"))
1671
1672         if role == rlib2._NR_REGULAR:
1673           self.assertFalse(op.drained)
1674           self.assertFalse(op.offline)
1675           self.assertFalse(op.master_candidate)
1676         elif role == rlib2._NR_MASTER_CANDIDATE:
1677           self.assertFalse(op.drained)
1678           self.assertFalse(op.offline)
1679           self.assertTrue(op.master_candidate)
1680         elif role == rlib2._NR_DRAINED:
1681           self.assertTrue(op.drained)
1682           self.assertFalse(op.offline)
1683           self.assertFalse(op.master_candidate)
1684         elif role == rlib2._NR_OFFLINE:
1685           self.assertFalse(op.drained)
1686           self.assertTrue(op.offline)
1687           self.assertFalse(op.master_candidate)
1688         else:
1689           self.fail("Unknown role '%s'" % role)
1690
1691       self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1692
1693
1694 class TestSimpleResources(unittest.TestCase):
1695   def setUp(self):
1696     self.clfactory = _FakeClientFactory(_FakeClient)
1697
1698   def tearDown(self):
1699     self.assertRaises(IndexError, self.clfactory.GetNextClient)
1700
1701   def testFeatures(self):
1702     handler = _CreateHandler(rlib2.R_2_features, [], {}, None, self.clfactory)
1703     self.assertEqual(set(handler.GET()), rlib2.ALL_FEATURES)
1704
1705   def testEmpty(self):
1706     for cls in [rlib2.R_root, rlib2.R_2]:
1707       handler = _CreateHandler(cls, [], {}, None, self.clfactory)
1708       self.assertTrue(handler.GET() is None)
1709
1710   def testVersion(self):
1711     handler = _CreateHandler(rlib2.R_version, [], {}, None, self.clfactory)
1712     self.assertEqual(handler.GET(), constants.RAPI_VERSION)
1713
1714
1715 class TestClusterInfo(unittest.TestCase):
1716   class _ClusterInfoClient:
1717     def __init__(self):
1718       self.cluster_info = None
1719
1720     def QueryClusterInfo(self):
1721       assert self.cluster_info is None
1722       self.cluster_info = object()
1723       return self.cluster_info
1724
1725   def test(self):
1726     clfactory = _FakeClientFactory(self._ClusterInfoClient)
1727     handler = _CreateHandler(rlib2.R_2_info, [], {}, None, clfactory)
1728     result = handler.GET()
1729     cl = clfactory.GetNextClient()
1730     self.assertRaises(IndexError, clfactory.GetNextClient)
1731     self.assertEqual(result, cl.cluster_info)
1732
1733
1734 if __name__ == '__main__':
1735   testutils.GanetiTestProgram()