rlib2: Convert /2/groups/[group_name] to OpcodeResource
[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 TestGroupAssignNodes(unittest.TestCase):
276   def test(self):
277     clfactory = _FakeClientFactory(_FakeClient)
278     handler = _CreateHandler(rlib2.R_2_groups_name_assign_nodes, ["grp-a"], {
279       "dry-run": ["1"],
280       "force": ["1"],
281       }, {
282       "nodes": ["n2", "n3"],
283       }, clfactory)
284     job_id = handler.PUT()
285
286     cl = clfactory.GetNextClient()
287     self.assertRaises(IndexError, clfactory.GetNextClient)
288
289     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
290     self.assertEqual(job_id, exp_job_id)
291     self.assertTrue(isinstance(op, opcodes.OpGroupAssignNodes))
292     self.assertEqual(op.group_name, "grp-a")
293     self.assertEqual(op.nodes, ["n2", "n3"])
294     self.assertTrue(op.dry_run)
295     self.assertTrue(op.force)
296
297     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
298
299
300 class TestInstanceDelete(unittest.TestCase):
301   def test(self):
302     clfactory = _FakeClientFactory(_FakeClient)
303     handler = _CreateHandler(rlib2.R_2_instances_name, ["inst30965"], {
304       "dry-run": ["1"],
305       }, {}, clfactory)
306     job_id = handler.DELETE()
307
308     cl = clfactory.GetNextClient()
309     self.assertRaises(IndexError, clfactory.GetNextClient)
310
311     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
312     self.assertEqual(job_id, exp_job_id)
313     self.assertTrue(isinstance(op, opcodes.OpInstanceRemove))
314     self.assertEqual(op.instance_name, "inst30965")
315     self.assertTrue(op.dry_run)
316     self.assertFalse(op.ignore_failures)
317
318     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
319
320
321 class TestInstanceInfo(unittest.TestCase):
322   def test(self):
323     clfactory = _FakeClientFactory(_FakeClient)
324     handler = _CreateHandler(rlib2.R_2_instances_name_info, ["inst31217"], {
325       "static": ["1"],
326       }, {}, clfactory)
327     job_id = handler.GET()
328
329     cl = clfactory.GetNextClient()
330     self.assertRaises(IndexError, clfactory.GetNextClient)
331
332     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
333     self.assertEqual(job_id, exp_job_id)
334     self.assertTrue(isinstance(op, opcodes.OpInstanceQueryData))
335     self.assertEqual(op.instances, ["inst31217"])
336     self.assertTrue(op.static)
337
338     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
339
340
341 class TestInstanceReboot(unittest.TestCase):
342   def test(self):
343     clfactory = _FakeClientFactory(_FakeClient)
344     handler = _CreateHandler(rlib2.R_2_instances_name_reboot, ["inst847"], {
345       "dry-run": ["1"],
346       "ignore_secondaries": ["1"],
347       }, {}, clfactory)
348     job_id = handler.POST()
349
350     cl = clfactory.GetNextClient()
351     self.assertRaises(IndexError, clfactory.GetNextClient)
352
353     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
354     self.assertEqual(job_id, exp_job_id)
355     self.assertTrue(isinstance(op, opcodes.OpInstanceReboot))
356     self.assertEqual(op.instance_name, "inst847")
357     self.assertEqual(op.reboot_type, constants.INSTANCE_REBOOT_HARD)
358     self.assertTrue(op.ignore_secondaries)
359     self.assertTrue(op.dry_run)
360
361     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
362
363
364 class TestInstanceStartup(unittest.TestCase):
365   def test(self):
366     clfactory = _FakeClientFactory(_FakeClient)
367     handler = _CreateHandler(rlib2.R_2_instances_name_startup, ["inst31083"], {
368       "force": ["1"],
369       "no_remember": ["1"],
370       }, {}, clfactory)
371     job_id = handler.PUT()
372
373     cl = clfactory.GetNextClient()
374     self.assertRaises(IndexError, clfactory.GetNextClient)
375
376     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
377     self.assertEqual(job_id, exp_job_id)
378     self.assertTrue(isinstance(op, opcodes.OpInstanceStartup))
379     self.assertEqual(op.instance_name, "inst31083")
380     self.assertTrue(op.no_remember)
381     self.assertTrue(op.force)
382     self.assertFalse(op.dry_run)
383
384     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
385
386
387 class TestInstanceShutdown(unittest.TestCase):
388   def test(self):
389     clfactory = _FakeClientFactory(_FakeClient)
390     handler = _CreateHandler(rlib2.R_2_instances_name_shutdown, ["inst26791"], {
391       "no_remember": ["0"],
392       }, {}, clfactory)
393     job_id = handler.PUT()
394
395     cl = clfactory.GetNextClient()
396     self.assertRaises(IndexError, clfactory.GetNextClient)
397
398     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
399     self.assertEqual(job_id, exp_job_id)
400     self.assertTrue(isinstance(op, opcodes.OpInstanceShutdown))
401     self.assertEqual(op.instance_name, "inst26791")
402     self.assertFalse(op.no_remember)
403     self.assertFalse(op.dry_run)
404
405     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
406
407
408 class TestInstanceActivateDisks(unittest.TestCase):
409   def test(self):
410     clfactory = _FakeClientFactory(_FakeClient)
411     handler = _CreateHandler(rlib2.R_2_instances_name_activate_disks, ["xyz"], {
412       "ignore_size": ["1"],
413       }, {}, clfactory)
414     job_id = handler.PUT()
415
416     cl = clfactory.GetNextClient()
417     self.assertRaises(IndexError, clfactory.GetNextClient)
418
419     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
420     self.assertEqual(job_id, exp_job_id)
421     self.assertTrue(isinstance(op, opcodes.OpInstanceActivateDisks))
422     self.assertEqual(op.instance_name, "xyz")
423     self.assertTrue(op.ignore_size)
424     self.assertFalse(hasattr(op, "dry_run"))
425
426     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
427
428
429 class TestInstanceDeactivateDisks(unittest.TestCase):
430   def test(self):
431     clfactory = _FakeClientFactory(_FakeClient)
432     handler = _CreateHandler(rlib2.R_2_instances_name_deactivate_disks,
433                              ["inst22357"], {}, {}, 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.OpInstanceDeactivateDisks))
442     self.assertEqual(op.instance_name, "inst22357")
443     self.assertFalse(hasattr(op, "dry_run"))
444     self.assertFalse(hasattr(op, "force"))
445
446     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
447
448
449 class TestInstanceFailover(unittest.TestCase):
450   def test(self):
451     clfactory = _FakeClientFactory(_FakeClient)
452     handler = _CreateHandler(rlib2.R_2_instances_name_failover,
453                              ["inst12794"], {}, {}, 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.OpInstanceFailover))
462     self.assertEqual(op.instance_name, "inst12794")
463     self.assertFalse(hasattr(op, "dry_run"))
464     self.assertFalse(hasattr(op, "force"))
465
466     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
467
468
469 class TestInstanceDiskGrow(unittest.TestCase):
470   def test(self):
471     clfactory = _FakeClientFactory(_FakeClient)
472     data = {
473       "amount": 1024,
474       }
475     handler = _CreateHandler(rlib2.R_2_instances_name_disk_grow,
476                              ["inst10742", "3"], {}, data, clfactory)
477     job_id = handler.POST()
478
479     cl = clfactory.GetNextClient()
480     self.assertRaises(IndexError, clfactory.GetNextClient)
481
482     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
483     self.assertEqual(job_id, exp_job_id)
484     self.assertTrue(isinstance(op, opcodes.OpInstanceGrowDisk))
485     self.assertEqual(op.instance_name, "inst10742")
486     self.assertEqual(op.disk, 3)
487     self.assertEqual(op.amount, 1024)
488     self.assertFalse(hasattr(op, "dry_run"))
489     self.assertFalse(hasattr(op, "force"))
490
491     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
492
493
494 class TestBackupPrepare(unittest.TestCase):
495   def test(self):
496     clfactory = _FakeClientFactory(_FakeClient)
497     queryargs = {
498       "mode": constants.EXPORT_MODE_REMOTE,
499       }
500     handler = _CreateHandler(rlib2.R_2_instances_name_prepare_export,
501                              ["inst17925"], queryargs, {}, clfactory)
502     job_id = handler.PUT()
503
504     cl = clfactory.GetNextClient()
505     self.assertRaises(IndexError, clfactory.GetNextClient)
506
507     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
508     self.assertEqual(job_id, exp_job_id)
509     self.assertTrue(isinstance(op, opcodes.OpBackupPrepare))
510     self.assertEqual(op.instance_name, "inst17925")
511     self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
512     self.assertFalse(hasattr(op, "dry_run"))
513     self.assertFalse(hasattr(op, "force"))
514
515     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
516
517
518 class TestGroupRemove(unittest.TestCase):
519   def test(self):
520     clfactory = _FakeClientFactory(_FakeClient)
521     handler = _CreateHandler(rlib2.R_2_groups_name,
522                              ["grp28575"], {}, {}, clfactory)
523     job_id = handler.DELETE()
524
525     cl = clfactory.GetNextClient()
526     self.assertRaises(IndexError, clfactory.GetNextClient)
527
528     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
529     self.assertEqual(job_id, exp_job_id)
530     self.assertTrue(isinstance(op, opcodes.OpGroupRemove))
531     self.assertEqual(op.group_name, "grp28575")
532     self.assertFalse(op.dry_run)
533     self.assertFalse(hasattr(op, "force"))
534
535     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
536
537
538 class TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase):
539   def setUp(self):
540     testutils.GanetiTestCase.setUp(self)
541
542     self.Parse = rlib2._ParseInstanceCreateRequestVersion1
543
544   def test(self):
545     disk_variants = [
546       # No disks
547       [],
548
549       # Two disks
550       [{"size": 5, }, {"size": 100, }],
551
552       # Disk with mode
553       [{"size": 123, "mode": constants.DISK_RDWR, }],
554       ]
555
556     nic_variants = [
557       # No NIC
558       [],
559
560       # Three NICs
561       [{}, {}, {}],
562
563       # Two NICs
564       [
565         { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
566           "mac": "01:23:45:67:68:9A",
567         },
568         { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
569       ],
570       ]
571
572     beparam_variants = [
573       None,
574       {},
575       { constants.BE_VCPUS: 2, },
576       { constants.BE_MEMORY: 123, },
577       { constants.BE_VCPUS: 2,
578         constants.BE_MEMORY: 1024,
579         constants.BE_AUTO_BALANCE: True, }
580       ]
581
582     hvparam_variants = [
583       None,
584       { constants.HV_BOOT_ORDER: "anc", },
585       { constants.HV_KERNEL_PATH: "/boot/fookernel",
586         constants.HV_ROOT_PATH: "/dev/hda1", },
587       ]
588
589     for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
590       for nics in nic_variants:
591         for disk_template in constants.DISK_TEMPLATES:
592           for disks in disk_variants:
593             for beparams in beparam_variants:
594               for hvparams in hvparam_variants:
595                 data = {
596                   "name": "inst1.example.com",
597                   "hypervisor": constants.HT_FAKE,
598                   "disks": disks,
599                   "nics": nics,
600                   "mode": mode,
601                   "disk_template": disk_template,
602                   "os": "debootstrap",
603                   }
604
605                 if beparams is not None:
606                   data["beparams"] = beparams
607
608                 if hvparams is not None:
609                   data["hvparams"] = hvparams
610
611                 for dry_run in [False, True]:
612                   op = self.Parse(data, dry_run)
613                   self.assert_(isinstance(op, opcodes.OpInstanceCreate))
614                   self.assertEqual(op.mode, mode)
615                   self.assertEqual(op.disk_template, disk_template)
616                   self.assertEqual(op.dry_run, dry_run)
617                   self.assertEqual(len(op.disks), len(disks))
618                   self.assertEqual(len(op.nics), len(nics))
619
620                   for opdisk, disk in zip(op.disks, disks):
621                     for key in constants.IDISK_PARAMS:
622                       self.assertEqual(opdisk.get(key), disk.get(key))
623                     self.assertFalse("unknown" in opdisk)
624
625                   for opnic, nic in zip(op.nics, nics):
626                     for key in constants.INIC_PARAMS:
627                       self.assertEqual(opnic.get(key), nic.get(key))
628                     self.assertFalse("unknown" in opnic)
629                     self.assertFalse("foobar" in opnic)
630
631                   if beparams is None:
632                     self.assertFalse(hasattr(op, "beparams"))
633                   else:
634                     self.assertEqualValues(op.beparams, beparams)
635
636                   if hvparams is None:
637                     self.assertFalse(hasattr(op, "hvparams"))
638                   else:
639                     self.assertEqualValues(op.hvparams, hvparams)
640
641   def testLegacyName(self):
642     name = "inst29128.example.com"
643     data = {
644       "name": name,
645       "disks": [],
646       "nics": [],
647       "mode": constants.INSTANCE_CREATE,
648       "disk_template": constants.DT_PLAIN,
649       }
650     op = self.Parse(data, False)
651     self.assert_(isinstance(op, opcodes.OpInstanceCreate))
652     self.assertEqual(op.instance_name, name)
653     self.assertFalse(hasattr(op, "name"))
654
655     # Define both
656     data = {
657       "name": name,
658       "instance_name": "other.example.com",
659       "disks": [],
660       "nics": [],
661       "mode": constants.INSTANCE_CREATE,
662       "disk_template": constants.DT_PLAIN,
663       }
664     self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
665
666   def testLegacyOs(self):
667     name = "inst4673.example.com"
668     os = "linux29206"
669     data = {
670       "name": name,
671       "os_type": os,
672       "disks": [],
673       "nics": [],
674       "mode": constants.INSTANCE_CREATE,
675       "disk_template": constants.DT_PLAIN,
676       }
677     op = self.Parse(data, False)
678     self.assert_(isinstance(op, opcodes.OpInstanceCreate))
679     self.assertEqual(op.instance_name, name)
680     self.assertEqual(op.os_type, os)
681     self.assertFalse(hasattr(op, "os"))
682
683     # Define both
684     data = {
685       "instance_name": name,
686       "os": os,
687       "os_type": "linux9584",
688       "disks": [],
689       "nics": [],
690       "mode": constants.INSTANCE_CREATE,
691       "disk_template": constants.DT_PLAIN,
692       }
693     self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
694
695   def testErrors(self):
696     # Test all required fields
697     reqfields = {
698       "name": "inst1.example.com",
699       "disks": [],
700       "nics": [],
701       "mode": constants.INSTANCE_CREATE,
702       "disk_template": constants.DT_PLAIN,
703       }
704
705     for name in reqfields.keys():
706       self.assertRaises(http.HttpBadRequest, self.Parse,
707                         dict(i for i in reqfields.iteritems() if i[0] != name),
708                         False)
709
710     # Invalid disks and nics
711     for field in ["disks", "nics"]:
712       invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
713                         [{"_unknown_": 999, }]]
714
715       for invvalue in invalid_values:
716         data = reqfields.copy()
717         data[field] = invvalue
718         self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
719
720
721 class TestBackupExport(unittest.TestCase):
722   def test(self):
723     clfactory = _FakeClientFactory(_FakeClient)
724
725     name = "instmoo"
726     data = {
727       "mode": constants.EXPORT_MODE_REMOTE,
728       "destination": [(1, 2, 3), (99, 99, 99)],
729       "shutdown": True,
730       "remove_instance": True,
731       "x509_key_name": ["name", "hash"],
732       "destination_x509_ca": "---cert---"
733       }
734
735     handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
736                              data, clfactory)
737     job_id = handler.PUT()
738
739     cl = clfactory.GetNextClient()
740     self.assertRaises(IndexError, clfactory.GetNextClient)
741
742     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
743     self.assertEqual(job_id, exp_job_id)
744     self.assertTrue(isinstance(op, opcodes.OpBackupExport))
745     self.assertEqual(op.instance_name, name)
746     self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
747     self.assertEqual(op.target_node, [(1, 2, 3), (99, 99, 99)])
748     self.assertEqual(op.shutdown, True)
749     self.assertEqual(op.remove_instance, True)
750     self.assertEqual(op.x509_key_name, ["name", "hash"])
751     self.assertEqual(op.destination_x509_ca, "---cert---")
752     self.assertFalse(hasattr(op, "dry_run"))
753     self.assertFalse(hasattr(op, "force"))
754
755     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
756
757   def testDefaults(self):
758     clfactory = _FakeClientFactory(_FakeClient)
759
760     name = "inst1"
761     data = {
762       "destination": "node2",
763       "shutdown": False,
764       }
765
766     handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
767                              data, clfactory)
768     job_id = handler.PUT()
769
770     cl = clfactory.GetNextClient()
771     self.assertRaises(IndexError, clfactory.GetNextClient)
772
773     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
774     self.assertEqual(job_id, exp_job_id)
775     self.assertTrue(isinstance(op, opcodes.OpBackupExport))
776     self.assertEqual(op.instance_name, name)
777     self.assertEqual(op.target_node, "node2")
778     self.assertFalse(hasattr(op, "mode"))
779     self.assertFalse(hasattr(op, "remove_instance"))
780     self.assertFalse(hasattr(op, "destination"))
781     self.assertFalse(hasattr(op, "dry_run"))
782     self.assertFalse(hasattr(op, "force"))
783
784     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
785
786   def testErrors(self):
787     clfactory = _FakeClientFactory(_FakeClient)
788
789     for value in ["True", "False"]:
790       handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
791         "remove_instance": value,
792         }, clfactory)
793       self.assertRaises(http.HttpBadRequest, handler.PUT)
794
795
796 class TestInstanceMigrate(testutils.GanetiTestCase):
797   def test(self):
798     clfactory = _FakeClientFactory(_FakeClient)
799
800     name = "instYooho6ek"
801
802     for cleanup in [False, True]:
803       for mode in constants.HT_MIGRATION_MODES:
804         data = {
805           "cleanup": cleanup,
806           "mode": mode,
807           }
808
809         handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
810                                  data, clfactory)
811         job_id = handler.PUT()
812
813         cl = clfactory.GetNextClient()
814         self.assertRaises(IndexError, clfactory.GetNextClient)
815
816         (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
817         self.assertEqual(job_id, exp_job_id)
818         self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
819         self.assertEqual(op.instance_name, name)
820         self.assertEqual(op.mode, mode)
821         self.assertEqual(op.cleanup, cleanup)
822         self.assertFalse(hasattr(op, "dry_run"))
823         self.assertFalse(hasattr(op, "force"))
824
825         self.assertRaises(IndexError, cl.GetNextSubmittedJob)
826
827   def testDefaults(self):
828     clfactory = _FakeClientFactory(_FakeClient)
829
830     name = "instnohZeex0"
831
832     handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
833                              clfactory)
834     job_id = handler.PUT()
835
836     cl = clfactory.GetNextClient()
837     self.assertRaises(IndexError, clfactory.GetNextClient)
838
839     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
840     self.assertEqual(job_id, exp_job_id)
841     self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
842     self.assertEqual(op.instance_name, name)
843     self.assertFalse(hasattr(op, "mode"))
844     self.assertFalse(hasattr(op, "cleanup"))
845     self.assertFalse(hasattr(op, "dry_run"))
846     self.assertFalse(hasattr(op, "force"))
847
848     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
849
850
851 class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
852   def test(self):
853     clfactory = _FakeClientFactory(_FakeClient)
854
855     name = "instij0eeph7"
856
857     for new_name in ["ua0aiyoo", "fai3ongi"]:
858       for ip_check in [False, True]:
859         for name_check in [False, True]:
860           data = {
861             "new_name": new_name,
862             "ip_check": ip_check,
863             "name_check": name_check,
864             }
865
866           handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
867                                    {}, data, clfactory)
868           job_id = handler.PUT()
869
870           cl = clfactory.GetNextClient()
871           self.assertRaises(IndexError, clfactory.GetNextClient)
872
873           (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
874           self.assertEqual(job_id, exp_job_id)
875           self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
876           self.assertEqual(op.instance_name, name)
877           self.assertEqual(op.new_name, new_name)
878           self.assertEqual(op.ip_check, ip_check)
879           self.assertEqual(op.name_check, name_check)
880           self.assertFalse(hasattr(op, "dry_run"))
881           self.assertFalse(hasattr(op, "force"))
882
883           self.assertRaises(IndexError, cl.GetNextSubmittedJob)
884
885   def testDefaults(self):
886     clfactory = _FakeClientFactory(_FakeClient)
887
888     name = "instahchie3t"
889
890     for new_name in ["thag9mek", "quees7oh"]:
891       data = {
892         "new_name": new_name,
893         }
894
895       handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
896                                {}, data, clfactory)
897       job_id = handler.PUT()
898
899       cl = clfactory.GetNextClient()
900       self.assertRaises(IndexError, clfactory.GetNextClient)
901
902       (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
903       self.assertEqual(job_id, exp_job_id)
904       self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
905       self.assertEqual(op.instance_name, name)
906       self.assertEqual(op.new_name, new_name)
907       self.assertFalse(hasattr(op, "ip_check"))
908       self.assertFalse(hasattr(op, "name_check"))
909       self.assertFalse(hasattr(op, "dry_run"))
910       self.assertFalse(hasattr(op, "force"))
911
912       self.assertRaises(IndexError, cl.GetNextSubmittedJob)
913
914
915 class TestParseModifyInstanceRequest(unittest.TestCase):
916   def test(self):
917     clfactory = _FakeClientFactory(_FakeClient)
918
919     name = "instush8gah"
920
921     test_disks = [
922       [],
923       [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
924       ]
925
926     for osparams in [{}, { "some": "value", "other": "Hello World", }]:
927       for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
928         for beparams in [{}, { constants.BE_MEMORY: 128, }]:
929           for force in [False, True]:
930             for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
931               for disks in test_disks:
932                 for disk_template in constants.DISK_TEMPLATES:
933                   data = {
934                     "osparams": osparams,
935                     "hvparams": hvparams,
936                     "beparams": beparams,
937                     "nics": nics,
938                     "disks": disks,
939                     "force": force,
940                     "disk_template": disk_template,
941                     }
942
943                   handler = _CreateHandler(rlib2.R_2_instances_name_modify,
944                                            [name], {}, data, clfactory)
945                   job_id = handler.PUT()
946
947                   cl = clfactory.GetNextClient()
948                   self.assertRaises(IndexError, clfactory.GetNextClient)
949
950                   (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
951                   self.assertEqual(job_id, exp_job_id)
952                   self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
953                   self.assertEqual(op.instance_name, name)
954                   self.assertEqual(op.hvparams, hvparams)
955                   self.assertEqual(op.beparams, beparams)
956                   self.assertEqual(op.osparams, osparams)
957                   self.assertEqual(op.force, force)
958                   self.assertEqual(op.nics, nics)
959                   self.assertEqual(op.disks, disks)
960                   self.assertEqual(op.disk_template, disk_template)
961                   self.assertFalse(hasattr(op, "remote_node"))
962                   self.assertFalse(hasattr(op, "os_name"))
963                   self.assertFalse(hasattr(op, "force_variant"))
964                   self.assertFalse(hasattr(op, "dry_run"))
965
966                   self.assertRaises(IndexError, cl.GetNextSubmittedJob)
967
968   def testDefaults(self):
969     clfactory = _FakeClientFactory(_FakeClient)
970
971     name = "instir8aish31"
972
973     handler = _CreateHandler(rlib2.R_2_instances_name_modify,
974                              [name], {}, {}, clfactory)
975     job_id = handler.PUT()
976
977     cl = clfactory.GetNextClient()
978     self.assertRaises(IndexError, clfactory.GetNextClient)
979
980     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
981     self.assertEqual(job_id, exp_job_id)
982     self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
983     self.assertEqual(op.instance_name, name)
984
985     for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
986               "disk_template", "remote_node", "os_name", "force_variant"]:
987       self.assertFalse(hasattr(op, i))
988
989
990 class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
991   def setUp(self):
992     testutils.GanetiTestCase.setUp(self)
993
994     self.Parse = rlib2._ParseInstanceReinstallRequest
995
996   def _Check(self, ops, name):
997     expcls = [
998       opcodes.OpInstanceShutdown,
999       opcodes.OpInstanceReinstall,
1000       opcodes.OpInstanceStartup,
1001       ]
1002
1003     self.assert_(compat.all(isinstance(op, exp)
1004                             for op, exp in zip(ops, expcls)))
1005     self.assert_(compat.all(op.instance_name == name for op in ops))
1006
1007   def test(self):
1008     name = "shoo0tihohma"
1009
1010     ops = self.Parse(name, {"os": "sys1", "start": True,})
1011     self.assertEqual(len(ops), 3)
1012     self._Check(ops, name)
1013     self.assertEqual(ops[1].os_type, "sys1")
1014     self.assertFalse(ops[1].osparams)
1015
1016     ops = self.Parse(name, {"os": "sys2", "start": False,})
1017     self.assertEqual(len(ops), 2)
1018     self._Check(ops, name)
1019     self.assertEqual(ops[1].os_type, "sys2")
1020
1021     osparams = {
1022       "reformat": "1",
1023       }
1024     ops = self.Parse(name, {"os": "sys4035", "start": True,
1025                             "osparams": osparams,})
1026     self.assertEqual(len(ops), 3)
1027     self._Check(ops, name)
1028     self.assertEqual(ops[1].os_type, "sys4035")
1029     self.assertEqual(ops[1].osparams, osparams)
1030
1031   def testDefaults(self):
1032     name = "noolee0g"
1033
1034     ops = self.Parse(name, {"os": "linux1"})
1035     self.assertEqual(len(ops), 3)
1036     self._Check(ops, name)
1037     self.assertEqual(ops[1].os_type, "linux1")
1038     self.assertFalse(ops[1].osparams)
1039
1040
1041 class TestGroupRename(unittest.TestCase):
1042   def test(self):
1043     clfactory = _FakeClientFactory(_FakeClient)
1044
1045     name = "group608242564"
1046     data = {
1047       "new_name": "ua0aiyoo15112",
1048       }
1049
1050     handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1051                              clfactory)
1052     job_id = handler.PUT()
1053
1054     cl = clfactory.GetNextClient()
1055     self.assertRaises(IndexError, clfactory.GetNextClient)
1056
1057     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1058     self.assertEqual(job_id, exp_job_id)
1059
1060     self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1061     self.assertEqual(op.group_name, name)
1062     self.assertEqual(op.new_name, "ua0aiyoo15112")
1063     self.assertFalse(op.dry_run)
1064     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1065
1066   def testDryRun(self):
1067     clfactory = _FakeClientFactory(_FakeClient)
1068
1069     name = "group28548"
1070     data = {
1071       "new_name": "ua0aiyoo",
1072       }
1073
1074     handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
1075       "dry-run": ["1"],
1076       }, data, clfactory)
1077     job_id = handler.PUT()
1078
1079     cl = clfactory.GetNextClient()
1080     self.assertRaises(IndexError, clfactory.GetNextClient)
1081
1082     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1083     self.assertEqual(job_id, exp_job_id)
1084
1085     self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1086     self.assertEqual(op.group_name, name)
1087     self.assertEqual(op.new_name, "ua0aiyoo")
1088     self.assertTrue(op.dry_run)
1089     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1090
1091
1092 class TestInstanceReplaceDisks(unittest.TestCase):
1093   def test(self):
1094     clfactory = _FakeClientFactory(_FakeClient)
1095
1096     name = "inst22568"
1097
1098     for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
1099       data = {
1100         "mode": constants.REPLACE_DISK_SEC,
1101         "disks": disks,
1102         "iallocator": "myalloc",
1103         }
1104
1105       handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1106                                [name], {}, data, clfactory)
1107       job_id = handler.POST()
1108
1109       cl = clfactory.GetNextClient()
1110       self.assertRaises(IndexError, clfactory.GetNextClient)
1111
1112       (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1113       self.assertEqual(job_id, exp_job_id)
1114
1115       self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1116       self.assertEqual(op.instance_name, name)
1117       self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
1118       self.assertEqual(op.disks, [1, 2, 3])
1119       self.assertEqual(op.iallocator, "myalloc")
1120       self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1121
1122   def testDefaults(self):
1123     clfactory = _FakeClientFactory(_FakeClient)
1124
1125     name = "inst11413"
1126     data = {
1127       "mode": constants.REPLACE_DISK_AUTO,
1128       }
1129
1130     handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1131                              [name], {}, data, clfactory)
1132     job_id = handler.POST()
1133
1134     cl = clfactory.GetNextClient()
1135     self.assertRaises(IndexError, clfactory.GetNextClient)
1136
1137     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1138     self.assertEqual(job_id, exp_job_id)
1139
1140     self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1141     self.assertEqual(op.instance_name, name)
1142     self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
1143     self.assertFalse(hasattr(op, "iallocator"))
1144     self.assertFalse(hasattr(op, "disks"))
1145     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1146
1147   def testWrong(self):
1148     clfactory = _FakeClientFactory(_FakeClient)
1149
1150     data = {
1151       "mode": constants.REPLACE_DISK_AUTO,
1152       "disks": "hello world",
1153       }
1154
1155     handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1156                              ["foo"], {}, data, clfactory)
1157     self.assertRaises(http.HttpBadRequest, handler.POST)
1158
1159
1160 class TestGroupModify(unittest.TestCase):
1161   def test(self):
1162     clfactory = _FakeClientFactory(_FakeClient)
1163
1164     name = "group6002"
1165
1166     for policy in constants.VALID_ALLOC_POLICIES:
1167       data = {
1168         "alloc_policy": policy,
1169         }
1170
1171       handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1172                                clfactory)
1173       job_id = handler.PUT()
1174
1175       cl = clfactory.GetNextClient()
1176       self.assertRaises(IndexError, clfactory.GetNextClient)
1177
1178       (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1179       self.assertEqual(job_id, exp_job_id)
1180
1181       self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1182       self.assertEqual(op.group_name, name)
1183       self.assertEqual(op.alloc_policy, policy)
1184       self.assertFalse(hasattr(op, "dry_run"))
1185       self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1186
1187   def testUnknownPolicy(self):
1188     clfactory = _FakeClientFactory(_FakeClient)
1189
1190     data = {
1191       "alloc_policy": "_unknown_policy_",
1192       }
1193
1194     handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1195                              clfactory)
1196     self.assertRaises(http.HttpBadRequest, handler.PUT)
1197     self.assertRaises(IndexError, clfactory.GetNextClient)
1198
1199   def testDefaults(self):
1200     clfactory = _FakeClientFactory(_FakeClient)
1201
1202     name = "group6679"
1203
1204     handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1205                              clfactory)
1206     job_id = handler.PUT()
1207
1208     cl = clfactory.GetNextClient()
1209     self.assertRaises(IndexError, clfactory.GetNextClient)
1210
1211     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1212     self.assertEqual(job_id, exp_job_id)
1213
1214     self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1215     self.assertEqual(op.group_name, name)
1216     self.assertFalse(hasattr(op, "alloc_policy"))
1217     self.assertFalse(hasattr(op, "dry_run"))
1218     self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1219
1220
1221 class TestGroupAdd(unittest.TestCase):
1222   def test(self):
1223     name = "group3618"
1224     clfactory = _FakeClientFactory(_FakeClient)
1225
1226     for policy in constants.VALID_ALLOC_POLICIES:
1227       data = {
1228         "group_name": name,
1229         "alloc_policy": policy,
1230         }
1231
1232       handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1233                                clfactory)
1234       job_id = handler.POST()
1235
1236       cl = clfactory.GetNextClient()
1237       self.assertRaises(IndexError, clfactory.GetNextClient)
1238
1239       (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1240       self.assertEqual(job_id, exp_job_id)
1241
1242       self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1243       self.assertEqual(op.group_name, name)
1244       self.assertEqual(op.alloc_policy, policy)
1245       self.assertFalse(op.dry_run)
1246       self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1247
1248   def testUnknownPolicy(self):
1249     clfactory = _FakeClientFactory(_FakeClient)
1250
1251     data = {
1252       "alloc_policy": "_unknown_policy_",
1253       }
1254
1255     handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1256     self.assertRaises(http.HttpBadRequest, handler.POST)
1257     self.assertRaises(IndexError, clfactory.GetNextClient)
1258
1259   def testDefaults(self):
1260     clfactory = _FakeClientFactory(_FakeClient)
1261
1262     name = "group15395"
1263     data = {
1264       "group_name": name,
1265       }
1266
1267     handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1268     job_id = handler.POST()
1269
1270     cl = clfactory.GetNextClient()
1271     self.assertRaises(IndexError, clfactory.GetNextClient)
1272
1273     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1274     self.assertEqual(job_id, exp_job_id)
1275
1276     self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1277     self.assertEqual(op.group_name, name)
1278     self.assertFalse(hasattr(op, "alloc_policy"))
1279     self.assertFalse(op.dry_run)
1280
1281   def testLegacyName(self):
1282     clfactory = _FakeClientFactory(_FakeClient)
1283
1284     name = "group29852"
1285     data = {
1286       "name": name,
1287       }
1288
1289     handler = _CreateHandler(rlib2.R_2_groups, [], {
1290       "dry-run": ["1"],
1291       }, data, clfactory)
1292     job_id = handler.POST()
1293
1294     cl = clfactory.GetNextClient()
1295     self.assertRaises(IndexError, clfactory.GetNextClient)
1296
1297     (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1298     self.assertEqual(job_id, exp_job_id)
1299
1300     self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1301     self.assertEqual(op.group_name, name)
1302     self.assertFalse(hasattr(op, "alloc_policy"))
1303     self.assertTrue(op.dry_run)
1304
1305
1306 class TestNodeRole(unittest.TestCase):
1307   def test(self):
1308     clfactory = _FakeClientFactory(_FakeClient)
1309
1310     for role in rlib2._NR_MAP.values():
1311       handler = _CreateHandler(rlib2.R_2_nodes_name_role,
1312                                ["node-z"], {}, role, clfactory)
1313       if role == rlib2._NR_MASTER:
1314         self.assertRaises(http.HttpBadRequest, handler.PUT)
1315       else:
1316         job_id = handler.PUT()
1317
1318         cl = clfactory.GetNextClient()
1319         self.assertRaises(IndexError, clfactory.GetNextClient)
1320
1321         (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1322         self.assertEqual(job_id, exp_job_id)
1323         self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
1324         self.assertEqual(op.node_name, "node-z")
1325         self.assertFalse(op.force)
1326         self.assertFalse(hasattr(op, "dry_run"))
1327
1328         if role == rlib2._NR_REGULAR:
1329           self.assertFalse(op.drained)
1330           self.assertFalse(op.offline)
1331           self.assertFalse(op.master_candidate)
1332         elif role == rlib2._NR_MASTER_CANDIDATE:
1333           self.assertFalse(op.drained)
1334           self.assertFalse(op.offline)
1335           self.assertTrue(op.master_candidate)
1336         elif role == rlib2._NR_DRAINED:
1337           self.assertTrue(op.drained)
1338           self.assertFalse(op.offline)
1339           self.assertFalse(op.master_candidate)
1340         elif role == rlib2._NR_OFFLINE:
1341           self.assertFalse(op.drained)
1342           self.assertTrue(op.offline)
1343           self.assertFalse(op.master_candidate)
1344         else:
1345           self.fail("Unknown role '%s'" % role)
1346
1347       self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1348
1349
1350 if __name__ == '__main__':
1351   testutils.GanetiTestProgram()