Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.rlib2_unittest.py @ 132cdb87

History | View | Annotate | Download (53.8 kB)

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 TestStorageQuery(unittest.TestCase):
539
  def test(self):
540
    clfactory = _FakeClientFactory(_FakeClient)
541
    queryargs = {
542
      "storage_type": constants.ST_LVM_PV,
543
      "output_fields": "name,other",
544
      }
545
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
546
                             ["node21075"], queryargs, {}, clfactory)
547
    job_id = handler.GET()
548

    
549
    cl = clfactory.GetNextClient()
550
    self.assertRaises(IndexError, clfactory.GetNextClient)
551

    
552
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
553
    self.assertEqual(job_id, exp_job_id)
554
    self.assertTrue(isinstance(op, opcodes.OpNodeQueryStorage))
555
    self.assertEqual(op.nodes, ["node21075"])
556
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
557
    self.assertEqual(op.output_fields, ["name", "other"])
558
    self.assertFalse(hasattr(op, "dry_run"))
559
    self.assertFalse(hasattr(op, "force"))
560

    
561
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
562

    
563
  def testErrors(self):
564
    clfactory = _FakeClientFactory(_FakeClient)
565

    
566
    queryargs = {
567
      "output_fields": "name,other",
568
      }
569
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
570
                             ["node10538"], queryargs, {}, clfactory)
571
    self.assertRaises(http.HttpBadRequest, handler.GET)
572

    
573
    queryargs = {
574
      "storage_type": constants.ST_LVM_VG,
575
      }
576
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
577
                             ["node21273"], queryargs, {}, clfactory)
578
    self.assertRaises(http.HttpBadRequest, handler.GET)
579

    
580
    queryargs = {
581
      "storage_type": "##unknown_storage##",
582
      "output_fields": "name,other",
583
      }
584
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
585
                             ["node10315"], queryargs, {}, clfactory)
586
    self.assertRaises(http.HttpBadRequest, handler.GET)
587

    
588

    
589
class TestStorageModify(unittest.TestCase):
590
  def test(self):
591
    clfactory = _FakeClientFactory(_FakeClient)
592

    
593
    for allocatable in [None, "1", "0"]:
594
      queryargs = {
595
        "storage_type": constants.ST_LVM_VG,
596
        "name": "pv-a",
597
        }
598

    
599
      if allocatable is not None:
600
        queryargs["allocatable"] = allocatable
601

    
602
      handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
603
                               ["node9292"], queryargs, {}, clfactory)
604
      job_id = handler.PUT()
605

    
606
      cl = clfactory.GetNextClient()
607
      self.assertRaises(IndexError, clfactory.GetNextClient)
608

    
609
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
610
      self.assertEqual(job_id, exp_job_id)
611
      self.assertTrue(isinstance(op, opcodes.OpNodeModifyStorage))
612
      self.assertEqual(op.node_name, "node9292")
613
      self.assertEqual(op.storage_type, constants.ST_LVM_VG)
614
      self.assertEqual(op.name, "pv-a")
615
      if allocatable is None:
616
        self.assertFalse(op.changes)
617
      else:
618
        assert allocatable in ("0", "1")
619
        self.assertEqual(op.changes, {
620
          constants.SF_ALLOCATABLE: (allocatable == "1"),
621
          })
622
      self.assertFalse(hasattr(op, "dry_run"))
623
      self.assertFalse(hasattr(op, "force"))
624

    
625
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
626

    
627
  def testErrors(self):
628
    clfactory = _FakeClientFactory(_FakeClient)
629

    
630
    # No storage type
631
    queryargs = {
632
      "name": "xyz",
633
      }
634
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
635
                             ["node26016"], queryargs, {}, clfactory)
636
    self.assertRaises(http.HttpBadRequest, handler.PUT)
637

    
638
    # No name
639
    queryargs = {
640
      "storage_type": constants.ST_LVM_VG,
641
      }
642
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
643
                             ["node21218"], queryargs, {}, clfactory)
644
    self.assertRaises(http.HttpBadRequest, handler.PUT)
645

    
646
    # Invalid value
647
    queryargs = {
648
      "storage_type": constants.ST_LVM_VG,
649
      "name": "pv-b",
650
      "allocatable": "noint",
651
      }
652
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
653
                             ["node30685"], queryargs, {}, clfactory)
654
    self.assertRaises(http.HttpBadRequest, handler.PUT)
655

    
656

    
657
class TestStorageRepair(unittest.TestCase):
658
  def test(self):
659
    clfactory = _FakeClientFactory(_FakeClient)
660
    queryargs = {
661
      "storage_type": constants.ST_LVM_PV,
662
      "name": "pv16611",
663
      }
664
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
665
                             ["node19265"], queryargs, {}, clfactory)
666
    job_id = handler.PUT()
667

    
668
    cl = clfactory.GetNextClient()
669
    self.assertRaises(IndexError, clfactory.GetNextClient)
670

    
671
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
672
    self.assertEqual(job_id, exp_job_id)
673
    self.assertTrue(isinstance(op, opcodes.OpRepairNodeStorage))
674
    self.assertEqual(op.node_name, "node19265")
675
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
676
    self.assertEqual(op.name, "pv16611")
677
    self.assertFalse(hasattr(op, "dry_run"))
678
    self.assertFalse(hasattr(op, "force"))
679

    
680
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
681

    
682
  def testErrors(self):
683
    clfactory = _FakeClientFactory(_FakeClient)
684

    
685
    # No storage type
686
    queryargs = {
687
      "name": "xyz",
688
      }
689
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
690
                             ["node11275"], queryargs, {}, clfactory)
691
    self.assertRaises(http.HttpBadRequest, handler.PUT)
692

    
693
    # No name
694
    queryargs = {
695
      "storage_type": constants.ST_LVM_VG,
696
      }
697
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
698
                             ["node21218"], queryargs, {}, clfactory)
699
    self.assertRaises(http.HttpBadRequest, handler.PUT)
700

    
701

    
702
class TestTags(unittest.TestCase):
703
  TAG_HANDLERS = [
704
    rlib2.R_2_instances_name_tags,
705
    rlib2.R_2_nodes_name_tags,
706
    rlib2.R_2_groups_name_tags,
707
    rlib2.R_2_tags,
708
    ]
709

    
710
  def testSetAndDelete(self):
711
    clfactory = _FakeClientFactory(_FakeClient)
712

    
713
    for method, opcls in [("PUT", opcodes.OpTagsSet),
714
                          ("DELETE", opcodes.OpTagsDel)]:
715
      for idx, handler in enumerate(self.TAG_HANDLERS):
716
        dry_run = bool(idx % 2)
717
        name = "test%s" % idx
718
        queryargs = {
719
          "tag": ["foo", "bar", "baz"],
720
          "dry-run": str(int(dry_run)),
721
          }
722

    
723
        handler = _CreateHandler(handler, [name], queryargs, {}, clfactory)
724
        job_id = getattr(handler, method)()
725

    
726
        cl = clfactory.GetNextClient()
727
        self.assertRaises(IndexError, clfactory.GetNextClient)
728

    
729
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
730
        self.assertEqual(job_id, exp_job_id)
731
        self.assertTrue(isinstance(op, opcls))
732
        self.assertEqual(op.kind, handler.TAG_LEVEL)
733
        if handler.TAG_LEVEL == constants.TAG_CLUSTER:
734
          self.assertTrue(op.name is None)
735
        else:
736
          self.assertEqual(op.name, name)
737
        self.assertEqual(op.tags, ["foo", "bar", "baz"])
738
        self.assertEqual(op.dry_run, dry_run)
739
        self.assertFalse(hasattr(op, "force"))
740

    
741
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
742

    
743

    
744
class TestInstanceCreation(testutils.GanetiTestCase):
745
  def test(self):
746
    clfactory = _FakeClientFactory(_FakeClient)
747

    
748
    name = "inst863.example.com"
749

    
750
    disk_variants = [
751
      # No disks
752
      [],
753

    
754
      # Two disks
755
      [{"size": 5, }, {"size": 100, }],
756

    
757
      # Disk with mode
758
      [{"size": 123, "mode": constants.DISK_RDWR, }],
759
      ]
760

    
761
    nic_variants = [
762
      # No NIC
763
      [],
764

    
765
      # Three NICs
766
      [{}, {}, {}],
767

    
768
      # Two NICs
769
      [
770
        { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
771
          "mac": "01:23:45:67:68:9A",
772
        },
773
        { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
774
      ],
775
      ]
776

    
777
    beparam_variants = [
778
      None,
779
      {},
780
      { constants.BE_VCPUS: 2, },
781
      { constants.BE_MEMORY: 123, },
782
      { constants.BE_VCPUS: 2,
783
        constants.BE_MEMORY: 1024,
784
        constants.BE_AUTO_BALANCE: True, }
785
      ]
786

    
787
    hvparam_variants = [
788
      None,
789
      { constants.HV_BOOT_ORDER: "anc", },
790
      { constants.HV_KERNEL_PATH: "/boot/fookernel",
791
        constants.HV_ROOT_PATH: "/dev/hda1", },
792
      ]
793

    
794
    for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
795
      for nics in nic_variants:
796
        for disk_template in constants.DISK_TEMPLATES:
797
          for disks in disk_variants:
798
            for beparams in beparam_variants:
799
              for hvparams in hvparam_variants:
800
                for dry_run in [False, True]:
801
                  queryargs = {
802
                    "dry-run": str(int(dry_run)),
803
                    }
804

    
805
                  data = {
806
                    rlib2._REQ_DATA_VERSION: 1,
807
                    "name": name,
808
                    "hypervisor": constants.HT_FAKE,
809
                    "disks": disks,
810
                    "nics": nics,
811
                    "mode": mode,
812
                    "disk_template": disk_template,
813
                    "os": "debootstrap",
814
                    }
815

    
816
                  if beparams is not None:
817
                    data["beparams"] = beparams
818

    
819
                  if hvparams is not None:
820
                    data["hvparams"] = hvparams
821

    
822
                  handler = _CreateHandler(rlib2.R_2_instances, [],
823
                                           queryargs, data, clfactory)
824
                  job_id = handler.POST()
825

    
826
                  cl = clfactory.GetNextClient()
827
                  self.assertRaises(IndexError, clfactory.GetNextClient)
828

    
829
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
830
                  self.assertEqual(job_id, exp_job_id)
831
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
832

    
833
                  self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
834
                  self.assertEqual(op.instance_name, name)
835
                  self.assertEqual(op.mode, mode)
836
                  self.assertEqual(op.disk_template, disk_template)
837
                  self.assertEqual(op.dry_run, dry_run)
838
                  self.assertEqual(len(op.disks), len(disks))
839
                  self.assertEqual(len(op.nics), len(nics))
840

    
841
                  for opdisk, disk in zip(op.disks, disks):
842
                    for key in constants.IDISK_PARAMS:
843
                      self.assertEqual(opdisk.get(key), disk.get(key))
844
                    self.assertFalse("unknown" in opdisk)
845

    
846
                  for opnic, nic in zip(op.nics, nics):
847
                    for key in constants.INIC_PARAMS:
848
                      self.assertEqual(opnic.get(key), nic.get(key))
849
                    self.assertFalse("unknown" in opnic)
850
                    self.assertFalse("foobar" in opnic)
851

    
852
                  if beparams is None:
853
                    self.assertFalse(hasattr(op, "beparams"))
854
                  else:
855
                    self.assertEqualValues(op.beparams, beparams)
856

    
857
                  if hvparams is None:
858
                    self.assertFalse(hasattr(op, "hvparams"))
859
                  else:
860
                    self.assertEqualValues(op.hvparams, hvparams)
861

    
862
  def testLegacyName(self):
863
    clfactory = _FakeClientFactory(_FakeClient)
864

    
865
    name = "inst29128.example.com"
866
    data = {
867
      rlib2._REQ_DATA_VERSION: 1,
868
      "name": name,
869
      "disks": [],
870
      "nics": [],
871
      "mode": constants.INSTANCE_CREATE,
872
      "disk_template": constants.DT_PLAIN,
873
      }
874

    
875
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
876
    job_id = handler.POST()
877

    
878
    cl = clfactory.GetNextClient()
879
    self.assertRaises(IndexError, clfactory.GetNextClient)
880

    
881
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
882
    self.assertEqual(job_id, exp_job_id)
883
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
884
    self.assertEqual(op.instance_name, name)
885
    self.assertFalse(hasattr(op, "name"))
886
    self.assertFalse(op.dry_run)
887

    
888
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
889

    
890
    # Define both
891
    data["instance_name"] = "other.example.com"
892
    assert "name" in data and "instance_name" in data
893
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
894
    self.assertRaises(http.HttpBadRequest, handler.POST)
895
    self.assertRaises(IndexError, clfactory.GetNextClient)
896

    
897
  def testLegacyOs(self):
898
    clfactory = _FakeClientFactory(_FakeClient)
899

    
900
    name = "inst4673.example.com"
901
    os = "linux29206"
902
    data = {
903
      rlib2._REQ_DATA_VERSION: 1,
904
      "name": name,
905
      "os_type": os,
906
      "disks": [],
907
      "nics": [],
908
      "mode": constants.INSTANCE_CREATE,
909
      "disk_template": constants.DT_PLAIN,
910
      }
911

    
912
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
913
    job_id = handler.POST()
914

    
915
    cl = clfactory.GetNextClient()
916
    self.assertRaises(IndexError, clfactory.GetNextClient)
917

    
918
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
919
    self.assertEqual(job_id, exp_job_id)
920
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
921
    self.assertEqual(op.instance_name, name)
922
    self.assertEqual(op.os_type, os)
923
    self.assertFalse(hasattr(op, "os"))
924
    self.assertFalse(op.dry_run)
925

    
926
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
927

    
928
    # Define both
929
    data["os"] = "linux9584"
930
    assert "os" in data and "os_type" in data
931
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
932
    self.assertRaises(http.HttpBadRequest, handler.POST)
933

    
934
  def testErrors(self):
935
    clfactory = _FakeClientFactory(_FakeClient)
936

    
937
    # Test all required fields
938
    reqfields = {
939
      rlib2._REQ_DATA_VERSION: 1,
940
      "name": "inst1.example.com",
941
      "disks": [],
942
      "nics": [],
943
      "mode": constants.INSTANCE_CREATE,
944
      "disk_template": constants.DT_PLAIN,
945
      }
946

    
947
    for name in reqfields.keys():
948
      data = dict(i for i in reqfields.iteritems() if i[0] != name)
949

    
950
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
951
      self.assertRaises(http.HttpBadRequest, handler.POST)
952
      self.assertRaises(IndexError, clfactory.GetNextClient)
953

    
954
    # Invalid disks and nics
955
    for field in ["disks", "nics"]:
956
      invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
957
                        [{"_unknown_": 999, }]]
958

    
959
      for invvalue in invalid_values:
960
        data = reqfields.copy()
961
        data[field] = invvalue
962
        handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
963
        self.assertRaises(http.HttpBadRequest, handler.POST)
964
        self.assertRaises(IndexError, clfactory.GetNextClient)
965

    
966
  def testVersion(self):
967
    clfactory = _FakeClientFactory(_FakeClient)
968

    
969
    # No version field
970
    data = {
971
      "name": "inst1.example.com",
972
      "disks": [],
973
      "nics": [],
974
      "mode": constants.INSTANCE_CREATE,
975
      "disk_template": constants.DT_PLAIN,
976
      }
977

    
978
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
979
    self.assertRaises(http.HttpBadRequest, handler.POST)
980

    
981
    # Old and incorrect versions
982
    for version in [0, -1, 10483, "Hello World"]:
983
      data[rlib2._REQ_DATA_VERSION] = version
984

    
985
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
986
      self.assertRaises(http.HttpBadRequest, handler.POST)
987

    
988
      self.assertRaises(IndexError, clfactory.GetNextClient)
989

    
990
    # Correct version
991
    data[rlib2._REQ_DATA_VERSION] = 1
992
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
993
    job_id = handler.POST()
994

    
995
    cl = clfactory.GetNextClient()
996
    self.assertRaises(IndexError, clfactory.GetNextClient)
997

    
998
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
999
    self.assertEqual(job_id, exp_job_id)
1000
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
1001
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1002

    
1003

    
1004
class TestBackupExport(unittest.TestCase):
1005
  def test(self):
1006
    clfactory = _FakeClientFactory(_FakeClient)
1007

    
1008
    name = "instmoo"
1009
    data = {
1010
      "mode": constants.EXPORT_MODE_REMOTE,
1011
      "destination": [(1, 2, 3), (99, 99, 99)],
1012
      "shutdown": True,
1013
      "remove_instance": True,
1014
      "x509_key_name": ["name", "hash"],
1015
      "destination_x509_ca": "---cert---"
1016
      }
1017

    
1018
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1019
                             data, clfactory)
1020
    job_id = handler.PUT()
1021

    
1022
    cl = clfactory.GetNextClient()
1023
    self.assertRaises(IndexError, clfactory.GetNextClient)
1024

    
1025
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1026
    self.assertEqual(job_id, exp_job_id)
1027
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1028
    self.assertEqual(op.instance_name, name)
1029
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
1030
    self.assertEqual(op.target_node, [(1, 2, 3), (99, 99, 99)])
1031
    self.assertEqual(op.shutdown, True)
1032
    self.assertEqual(op.remove_instance, True)
1033
    self.assertEqual(op.x509_key_name, ["name", "hash"])
1034
    self.assertEqual(op.destination_x509_ca, "---cert---")
1035
    self.assertFalse(hasattr(op, "dry_run"))
1036
    self.assertFalse(hasattr(op, "force"))
1037

    
1038
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1039

    
1040
  def testDefaults(self):
1041
    clfactory = _FakeClientFactory(_FakeClient)
1042

    
1043
    name = "inst1"
1044
    data = {
1045
      "destination": "node2",
1046
      "shutdown": False,
1047
      }
1048

    
1049
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1050
                             data, clfactory)
1051
    job_id = handler.PUT()
1052

    
1053
    cl = clfactory.GetNextClient()
1054
    self.assertRaises(IndexError, clfactory.GetNextClient)
1055

    
1056
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1057
    self.assertEqual(job_id, exp_job_id)
1058
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1059
    self.assertEqual(op.instance_name, name)
1060
    self.assertEqual(op.target_node, "node2")
1061
    self.assertFalse(hasattr(op, "mode"))
1062
    self.assertFalse(hasattr(op, "remove_instance"))
1063
    self.assertFalse(hasattr(op, "destination"))
1064
    self.assertFalse(hasattr(op, "dry_run"))
1065
    self.assertFalse(hasattr(op, "force"))
1066

    
1067
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1068

    
1069
  def testErrors(self):
1070
    clfactory = _FakeClientFactory(_FakeClient)
1071

    
1072
    for value in ["True", "False"]:
1073
      handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
1074
        "remove_instance": value,
1075
        }, clfactory)
1076
      self.assertRaises(http.HttpBadRequest, handler.PUT)
1077

    
1078

    
1079
class TestInstanceMigrate(testutils.GanetiTestCase):
1080
  def test(self):
1081
    clfactory = _FakeClientFactory(_FakeClient)
1082

    
1083
    name = "instYooho6ek"
1084

    
1085
    for cleanup in [False, True]:
1086
      for mode in constants.HT_MIGRATION_MODES:
1087
        data = {
1088
          "cleanup": cleanup,
1089
          "mode": mode,
1090
          }
1091

    
1092
        handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [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.OpInstanceMigrate))
1102
        self.assertEqual(op.instance_name, name)
1103
        self.assertEqual(op.mode, mode)
1104
        self.assertEqual(op.cleanup, cleanup)
1105
        self.assertFalse(hasattr(op, "dry_run"))
1106
        self.assertFalse(hasattr(op, "force"))
1107

    
1108
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1109

    
1110
  def testDefaults(self):
1111
    clfactory = _FakeClientFactory(_FakeClient)
1112

    
1113
    name = "instnohZeex0"
1114

    
1115
    handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
1116
                             clfactory)
1117
    job_id = handler.PUT()
1118

    
1119
    cl = clfactory.GetNextClient()
1120
    self.assertRaises(IndexError, clfactory.GetNextClient)
1121

    
1122
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1123
    self.assertEqual(job_id, exp_job_id)
1124
    self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1125
    self.assertEqual(op.instance_name, name)
1126
    self.assertFalse(hasattr(op, "mode"))
1127
    self.assertFalse(hasattr(op, "cleanup"))
1128
    self.assertFalse(hasattr(op, "dry_run"))
1129
    self.assertFalse(hasattr(op, "force"))
1130

    
1131
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1132

    
1133

    
1134
class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
1135
  def test(self):
1136
    clfactory = _FakeClientFactory(_FakeClient)
1137

    
1138
    name = "instij0eeph7"
1139

    
1140
    for new_name in ["ua0aiyoo", "fai3ongi"]:
1141
      for ip_check in [False, True]:
1142
        for name_check in [False, True]:
1143
          data = {
1144
            "new_name": new_name,
1145
            "ip_check": ip_check,
1146
            "name_check": name_check,
1147
            }
1148

    
1149
          handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1150
                                   {}, data, clfactory)
1151
          job_id = handler.PUT()
1152

    
1153
          cl = clfactory.GetNextClient()
1154
          self.assertRaises(IndexError, clfactory.GetNextClient)
1155

    
1156
          (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1157
          self.assertEqual(job_id, exp_job_id)
1158
          self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1159
          self.assertEqual(op.instance_name, name)
1160
          self.assertEqual(op.new_name, new_name)
1161
          self.assertEqual(op.ip_check, ip_check)
1162
          self.assertEqual(op.name_check, name_check)
1163
          self.assertFalse(hasattr(op, "dry_run"))
1164
          self.assertFalse(hasattr(op, "force"))
1165

    
1166
          self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1167

    
1168
  def testDefaults(self):
1169
    clfactory = _FakeClientFactory(_FakeClient)
1170

    
1171
    name = "instahchie3t"
1172

    
1173
    for new_name in ["thag9mek", "quees7oh"]:
1174
      data = {
1175
        "new_name": new_name,
1176
        }
1177

    
1178
      handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1179
                               {}, data, clfactory)
1180
      job_id = handler.PUT()
1181

    
1182
      cl = clfactory.GetNextClient()
1183
      self.assertRaises(IndexError, clfactory.GetNextClient)
1184

    
1185
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1186
      self.assertEqual(job_id, exp_job_id)
1187
      self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1188
      self.assertEqual(op.instance_name, name)
1189
      self.assertEqual(op.new_name, new_name)
1190
      self.assertFalse(hasattr(op, "ip_check"))
1191
      self.assertFalse(hasattr(op, "name_check"))
1192
      self.assertFalse(hasattr(op, "dry_run"))
1193
      self.assertFalse(hasattr(op, "force"))
1194

    
1195
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1196

    
1197

    
1198
class TestParseModifyInstanceRequest(unittest.TestCase):
1199
  def test(self):
1200
    clfactory = _FakeClientFactory(_FakeClient)
1201

    
1202
    name = "instush8gah"
1203

    
1204
    test_disks = [
1205
      [],
1206
      [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
1207
      ]
1208

    
1209
    for osparams in [{}, { "some": "value", "other": "Hello World", }]:
1210
      for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
1211
        for beparams in [{}, { constants.BE_MEMORY: 128, }]:
1212
          for force in [False, True]:
1213
            for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
1214
              for disks in test_disks:
1215
                for disk_template in constants.DISK_TEMPLATES:
1216
                  data = {
1217
                    "osparams": osparams,
1218
                    "hvparams": hvparams,
1219
                    "beparams": beparams,
1220
                    "nics": nics,
1221
                    "disks": disks,
1222
                    "force": force,
1223
                    "disk_template": disk_template,
1224
                    }
1225

    
1226
                  handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1227
                                           [name], {}, data, clfactory)
1228
                  job_id = handler.PUT()
1229

    
1230
                  cl = clfactory.GetNextClient()
1231
                  self.assertRaises(IndexError, clfactory.GetNextClient)
1232

    
1233
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1234
                  self.assertEqual(job_id, exp_job_id)
1235
                  self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1236
                  self.assertEqual(op.instance_name, name)
1237
                  self.assertEqual(op.hvparams, hvparams)
1238
                  self.assertEqual(op.beparams, beparams)
1239
                  self.assertEqual(op.osparams, osparams)
1240
                  self.assertEqual(op.force, force)
1241
                  self.assertEqual(op.nics, nics)
1242
                  self.assertEqual(op.disks, disks)
1243
                  self.assertEqual(op.disk_template, disk_template)
1244
                  self.assertFalse(hasattr(op, "remote_node"))
1245
                  self.assertFalse(hasattr(op, "os_name"))
1246
                  self.assertFalse(hasattr(op, "force_variant"))
1247
                  self.assertFalse(hasattr(op, "dry_run"))
1248

    
1249
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1250

    
1251
  def testDefaults(self):
1252
    clfactory = _FakeClientFactory(_FakeClient)
1253

    
1254
    name = "instir8aish31"
1255

    
1256
    handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1257
                             [name], {}, {}, clfactory)
1258
    job_id = handler.PUT()
1259

    
1260
    cl = clfactory.GetNextClient()
1261
    self.assertRaises(IndexError, clfactory.GetNextClient)
1262

    
1263
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1264
    self.assertEqual(job_id, exp_job_id)
1265
    self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1266
    self.assertEqual(op.instance_name, name)
1267

    
1268
    for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
1269
              "disk_template", "remote_node", "os_name", "force_variant"]:
1270
      self.assertFalse(hasattr(op, i))
1271

    
1272

    
1273
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1274
  def setUp(self):
1275
    testutils.GanetiTestCase.setUp(self)
1276

    
1277
    self.Parse = rlib2._ParseInstanceReinstallRequest
1278

    
1279
  def _Check(self, ops, name):
1280
    expcls = [
1281
      opcodes.OpInstanceShutdown,
1282
      opcodes.OpInstanceReinstall,
1283
      opcodes.OpInstanceStartup,
1284
      ]
1285

    
1286
    self.assert_(compat.all(isinstance(op, exp)
1287
                            for op, exp in zip(ops, expcls)))
1288
    self.assert_(compat.all(op.instance_name == name for op in ops))
1289

    
1290
  def test(self):
1291
    name = "shoo0tihohma"
1292

    
1293
    ops = self.Parse(name, {"os": "sys1", "start": True,})
1294
    self.assertEqual(len(ops), 3)
1295
    self._Check(ops, name)
1296
    self.assertEqual(ops[1].os_type, "sys1")
1297
    self.assertFalse(ops[1].osparams)
1298

    
1299
    ops = self.Parse(name, {"os": "sys2", "start": False,})
1300
    self.assertEqual(len(ops), 2)
1301
    self._Check(ops, name)
1302
    self.assertEqual(ops[1].os_type, "sys2")
1303

    
1304
    osparams = {
1305
      "reformat": "1",
1306
      }
1307
    ops = self.Parse(name, {"os": "sys4035", "start": True,
1308
                            "osparams": osparams,})
1309
    self.assertEqual(len(ops), 3)
1310
    self._Check(ops, name)
1311
    self.assertEqual(ops[1].os_type, "sys4035")
1312
    self.assertEqual(ops[1].osparams, osparams)
1313

    
1314
  def testDefaults(self):
1315
    name = "noolee0g"
1316

    
1317
    ops = self.Parse(name, {"os": "linux1"})
1318
    self.assertEqual(len(ops), 3)
1319
    self._Check(ops, name)
1320
    self.assertEqual(ops[1].os_type, "linux1")
1321
    self.assertFalse(ops[1].osparams)
1322

    
1323
  def testErrors(self):
1324
    self.assertRaises(http.HttpBadRequest, self.Parse,
1325
                      "foo", "not a dictionary")
1326

    
1327

    
1328
class TestGroupRename(unittest.TestCase):
1329
  def test(self):
1330
    clfactory = _FakeClientFactory(_FakeClient)
1331

    
1332
    name = "group608242564"
1333
    data = {
1334
      "new_name": "ua0aiyoo15112",
1335
      }
1336

    
1337
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1338
                             clfactory)
1339
    job_id = handler.PUT()
1340

    
1341
    cl = clfactory.GetNextClient()
1342
    self.assertRaises(IndexError, clfactory.GetNextClient)
1343

    
1344
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1345
    self.assertEqual(job_id, exp_job_id)
1346

    
1347
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1348
    self.assertEqual(op.group_name, name)
1349
    self.assertEqual(op.new_name, "ua0aiyoo15112")
1350
    self.assertFalse(op.dry_run)
1351
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1352

    
1353
  def testDryRun(self):
1354
    clfactory = _FakeClientFactory(_FakeClient)
1355

    
1356
    name = "group28548"
1357
    data = {
1358
      "new_name": "ua0aiyoo",
1359
      }
1360

    
1361
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
1362
      "dry-run": ["1"],
1363
      }, data, clfactory)
1364
    job_id = handler.PUT()
1365

    
1366
    cl = clfactory.GetNextClient()
1367
    self.assertRaises(IndexError, clfactory.GetNextClient)
1368

    
1369
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1370
    self.assertEqual(job_id, exp_job_id)
1371

    
1372
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1373
    self.assertEqual(op.group_name, name)
1374
    self.assertEqual(op.new_name, "ua0aiyoo")
1375
    self.assertTrue(op.dry_run)
1376
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1377

    
1378

    
1379
class TestInstanceReplaceDisks(unittest.TestCase):
1380
  def test(self):
1381
    clfactory = _FakeClientFactory(_FakeClient)
1382

    
1383
    name = "inst22568"
1384

    
1385
    for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
1386
      data = {
1387
        "mode": constants.REPLACE_DISK_SEC,
1388
        "disks": disks,
1389
        "iallocator": "myalloc",
1390
        }
1391

    
1392
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1393
                               [name], {}, data, clfactory)
1394
      job_id = handler.POST()
1395

    
1396
      cl = clfactory.GetNextClient()
1397
      self.assertRaises(IndexError, clfactory.GetNextClient)
1398

    
1399
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1400
      self.assertEqual(job_id, exp_job_id)
1401

    
1402
      self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1403
      self.assertEqual(op.instance_name, name)
1404
      self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
1405
      self.assertEqual(op.disks, [1, 2, 3])
1406
      self.assertEqual(op.iallocator, "myalloc")
1407
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1408

    
1409
  def testDefaults(self):
1410
    clfactory = _FakeClientFactory(_FakeClient)
1411

    
1412
    name = "inst11413"
1413
    data = {
1414
      "mode": constants.REPLACE_DISK_AUTO,
1415
      }
1416

    
1417
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1418
                             [name], {}, data, clfactory)
1419
    job_id = handler.POST()
1420

    
1421
    cl = clfactory.GetNextClient()
1422
    self.assertRaises(IndexError, clfactory.GetNextClient)
1423

    
1424
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1425
    self.assertEqual(job_id, exp_job_id)
1426

    
1427
    self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1428
    self.assertEqual(op.instance_name, name)
1429
    self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
1430
    self.assertFalse(hasattr(op, "iallocator"))
1431
    self.assertFalse(hasattr(op, "disks"))
1432
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1433

    
1434
  def testWrong(self):
1435
    clfactory = _FakeClientFactory(_FakeClient)
1436

    
1437
    data = {
1438
      "mode": constants.REPLACE_DISK_AUTO,
1439
      "disks": "hello world",
1440
      }
1441

    
1442
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1443
                             ["foo"], {}, data, clfactory)
1444
    self.assertRaises(http.HttpBadRequest, handler.POST)
1445

    
1446

    
1447
class TestGroupModify(unittest.TestCase):
1448
  def test(self):
1449
    clfactory = _FakeClientFactory(_FakeClient)
1450

    
1451
    name = "group6002"
1452

    
1453
    for policy in constants.VALID_ALLOC_POLICIES:
1454
      data = {
1455
        "alloc_policy": policy,
1456
        }
1457

    
1458
      handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1459
                               clfactory)
1460
      job_id = handler.PUT()
1461

    
1462
      cl = clfactory.GetNextClient()
1463
      self.assertRaises(IndexError, clfactory.GetNextClient)
1464

    
1465
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1466
      self.assertEqual(job_id, exp_job_id)
1467

    
1468
      self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1469
      self.assertEqual(op.group_name, name)
1470
      self.assertEqual(op.alloc_policy, policy)
1471
      self.assertFalse(hasattr(op, "dry_run"))
1472
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1473

    
1474
  def testUnknownPolicy(self):
1475
    clfactory = _FakeClientFactory(_FakeClient)
1476

    
1477
    data = {
1478
      "alloc_policy": "_unknown_policy_",
1479
      }
1480

    
1481
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1482
                             clfactory)
1483
    self.assertRaises(http.HttpBadRequest, handler.PUT)
1484
    self.assertRaises(IndexError, clfactory.GetNextClient)
1485

    
1486
  def testDefaults(self):
1487
    clfactory = _FakeClientFactory(_FakeClient)
1488

    
1489
    name = "group6679"
1490

    
1491
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1492
                             clfactory)
1493
    job_id = handler.PUT()
1494

    
1495
    cl = clfactory.GetNextClient()
1496
    self.assertRaises(IndexError, clfactory.GetNextClient)
1497

    
1498
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1499
    self.assertEqual(job_id, exp_job_id)
1500

    
1501
    self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1502
    self.assertEqual(op.group_name, name)
1503
    self.assertFalse(hasattr(op, "alloc_policy"))
1504
    self.assertFalse(hasattr(op, "dry_run"))
1505
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1506

    
1507

    
1508
class TestGroupAdd(unittest.TestCase):
1509
  def test(self):
1510
    name = "group3618"
1511
    clfactory = _FakeClientFactory(_FakeClient)
1512

    
1513
    for policy in constants.VALID_ALLOC_POLICIES:
1514
      data = {
1515
        "group_name": name,
1516
        "alloc_policy": policy,
1517
        }
1518

    
1519
      handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1520
                               clfactory)
1521
      job_id = handler.POST()
1522

    
1523
      cl = clfactory.GetNextClient()
1524
      self.assertRaises(IndexError, clfactory.GetNextClient)
1525

    
1526
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1527
      self.assertEqual(job_id, exp_job_id)
1528

    
1529
      self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1530
      self.assertEqual(op.group_name, name)
1531
      self.assertEqual(op.alloc_policy, policy)
1532
      self.assertFalse(op.dry_run)
1533
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1534

    
1535
  def testUnknownPolicy(self):
1536
    clfactory = _FakeClientFactory(_FakeClient)
1537

    
1538
    data = {
1539
      "alloc_policy": "_unknown_policy_",
1540
      }
1541

    
1542
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1543
    self.assertRaises(http.HttpBadRequest, handler.POST)
1544
    self.assertRaises(IndexError, clfactory.GetNextClient)
1545

    
1546
  def testDefaults(self):
1547
    clfactory = _FakeClientFactory(_FakeClient)
1548

    
1549
    name = "group15395"
1550
    data = {
1551
      "group_name": name,
1552
      }
1553

    
1554
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1555
    job_id = handler.POST()
1556

    
1557
    cl = clfactory.GetNextClient()
1558
    self.assertRaises(IndexError, clfactory.GetNextClient)
1559

    
1560
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1561
    self.assertEqual(job_id, exp_job_id)
1562

    
1563
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1564
    self.assertEqual(op.group_name, name)
1565
    self.assertFalse(hasattr(op, "alloc_policy"))
1566
    self.assertFalse(op.dry_run)
1567

    
1568
  def testLegacyName(self):
1569
    clfactory = _FakeClientFactory(_FakeClient)
1570

    
1571
    name = "group29852"
1572
    data = {
1573
      "name": name,
1574
      }
1575

    
1576
    handler = _CreateHandler(rlib2.R_2_groups, [], {
1577
      "dry-run": ["1"],
1578
      }, data, clfactory)
1579
    job_id = handler.POST()
1580

    
1581
    cl = clfactory.GetNextClient()
1582
    self.assertRaises(IndexError, clfactory.GetNextClient)
1583

    
1584
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1585
    self.assertEqual(job_id, exp_job_id)
1586

    
1587
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1588
    self.assertEqual(op.group_name, name)
1589
    self.assertFalse(hasattr(op, "alloc_policy"))
1590
    self.assertTrue(op.dry_run)
1591

    
1592

    
1593
class TestNodeRole(unittest.TestCase):
1594
  def test(self):
1595
    clfactory = _FakeClientFactory(_FakeClient)
1596

    
1597
    for role in rlib2._NR_MAP.values():
1598
      handler = _CreateHandler(rlib2.R_2_nodes_name_role,
1599
                               ["node-z"], {}, role, clfactory)
1600
      if role == rlib2._NR_MASTER:
1601
        self.assertRaises(http.HttpBadRequest, handler.PUT)
1602
      else:
1603
        job_id = handler.PUT()
1604

    
1605
        cl = clfactory.GetNextClient()
1606
        self.assertRaises(IndexError, clfactory.GetNextClient)
1607

    
1608
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1609
        self.assertEqual(job_id, exp_job_id)
1610
        self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
1611
        self.assertEqual(op.node_name, "node-z")
1612
        self.assertFalse(op.force)
1613
        self.assertFalse(hasattr(op, "dry_run"))
1614

    
1615
        if role == rlib2._NR_REGULAR:
1616
          self.assertFalse(op.drained)
1617
          self.assertFalse(op.offline)
1618
          self.assertFalse(op.master_candidate)
1619
        elif role == rlib2._NR_MASTER_CANDIDATE:
1620
          self.assertFalse(op.drained)
1621
          self.assertFalse(op.offline)
1622
          self.assertTrue(op.master_candidate)
1623
        elif role == rlib2._NR_DRAINED:
1624
          self.assertTrue(op.drained)
1625
          self.assertFalse(op.offline)
1626
          self.assertFalse(op.master_candidate)
1627
        elif role == rlib2._NR_OFFLINE:
1628
          self.assertFalse(op.drained)
1629
          self.assertTrue(op.offline)
1630
          self.assertFalse(op.master_candidate)
1631
        else:
1632
          self.fail("Unknown role '%s'" % role)
1633

    
1634
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1635

    
1636

    
1637
class TestSimpleResources(unittest.TestCase):
1638
  def setUp(self):
1639
    self.clfactory = _FakeClientFactory(_FakeClient)
1640

    
1641
  def tearDown(self):
1642
    self.assertRaises(IndexError, self.clfactory.GetNextClient)
1643

    
1644
  def testFeatures(self):
1645
    handler = _CreateHandler(rlib2.R_2_features, [], {}, None, self.clfactory)
1646
    self.assertEqual(set(handler.GET()), rlib2.ALL_FEATURES)
1647

    
1648
  def testEmpty(self):
1649
    for cls in [rlib2.R_root, rlib2.R_2]:
1650
      handler = _CreateHandler(cls, [], {}, None, self.clfactory)
1651
      self.assertTrue(handler.GET() is None)
1652

    
1653
  def testVersion(self):
1654
    handler = _CreateHandler(rlib2.R_version, [], {}, None, self.clfactory)
1655
    self.assertEqual(handler.GET(), constants.RAPI_VERSION)
1656

    
1657

    
1658
class TestClusterInfo(unittest.TestCase):
1659
  class _ClusterInfoClient:
1660
    def __init__(self):
1661
      self.cluster_info = None
1662

    
1663
    def QueryClusterInfo(self):
1664
      assert self.cluster_info is None
1665
      self.cluster_info = object()
1666
      return self.cluster_info
1667

    
1668
  def test(self):
1669
    clfactory = _FakeClientFactory(self._ClusterInfoClient)
1670
    handler = _CreateHandler(rlib2.R_2_info, [], {}, None, clfactory)
1671
    result = handler.GET()
1672
    cl = clfactory.GetNextClient()
1673
    self.assertRaises(IndexError, clfactory.GetNextClient)
1674
    self.assertEqual(result, cl.cluster_info)
1675

    
1676

    
1677
if __name__ == '__main__':
1678
  testutils.GanetiTestProgram()