Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.rlib2_unittest.py @ a52978c7

History | View | Annotate | Download (54.5 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 TestInstanceRecreateDisks(unittest.TestCase):
450
  def test(self):
451
    clfactory = _FakeClientFactory(_FakeClient)
452
    handler = _CreateHandler(rlib2.R_2_instances_name_recreate_disks,
453
                             ["inst22357"], {}, {}, clfactory)
454
    job_id = handler.POST()
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.OpInstanceRecreateDisks))
462
    self.assertEqual(op.instance_name, "inst22357")
463
    self.assertFalse(hasattr(op, "dry_run"))
464
    self.assertFalse(hasattr(op, "force"))
465

    
466
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
467

    
468

    
469
class TestInstanceFailover(unittest.TestCase):
470
  def test(self):
471
    clfactory = _FakeClientFactory(_FakeClient)
472
    handler = _CreateHandler(rlib2.R_2_instances_name_failover,
473
                             ["inst12794"], {}, {}, clfactory)
474
    job_id = handler.PUT()
475

    
476
    cl = clfactory.GetNextClient()
477
    self.assertRaises(IndexError, clfactory.GetNextClient)
478

    
479
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
480
    self.assertEqual(job_id, exp_job_id)
481
    self.assertTrue(isinstance(op, opcodes.OpInstanceFailover))
482
    self.assertEqual(op.instance_name, "inst12794")
483
    self.assertFalse(hasattr(op, "dry_run"))
484
    self.assertFalse(hasattr(op, "force"))
485

    
486
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
487

    
488

    
489
class TestInstanceDiskGrow(unittest.TestCase):
490
  def test(self):
491
    clfactory = _FakeClientFactory(_FakeClient)
492
    data = {
493
      "amount": 1024,
494
      }
495
    handler = _CreateHandler(rlib2.R_2_instances_name_disk_grow,
496
                             ["inst10742", "3"], {}, data, clfactory)
497
    job_id = handler.POST()
498

    
499
    cl = clfactory.GetNextClient()
500
    self.assertRaises(IndexError, clfactory.GetNextClient)
501

    
502
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
503
    self.assertEqual(job_id, exp_job_id)
504
    self.assertTrue(isinstance(op, opcodes.OpInstanceGrowDisk))
505
    self.assertEqual(op.instance_name, "inst10742")
506
    self.assertEqual(op.disk, 3)
507
    self.assertEqual(op.amount, 1024)
508
    self.assertFalse(hasattr(op, "dry_run"))
509
    self.assertFalse(hasattr(op, "force"))
510

    
511
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
512

    
513

    
514
class TestBackupPrepare(unittest.TestCase):
515
  def test(self):
516
    clfactory = _FakeClientFactory(_FakeClient)
517
    queryargs = {
518
      "mode": constants.EXPORT_MODE_REMOTE,
519
      }
520
    handler = _CreateHandler(rlib2.R_2_instances_name_prepare_export,
521
                             ["inst17925"], queryargs, {}, clfactory)
522
    job_id = handler.PUT()
523

    
524
    cl = clfactory.GetNextClient()
525
    self.assertRaises(IndexError, clfactory.GetNextClient)
526

    
527
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
528
    self.assertEqual(job_id, exp_job_id)
529
    self.assertTrue(isinstance(op, opcodes.OpBackupPrepare))
530
    self.assertEqual(op.instance_name, "inst17925")
531
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
532
    self.assertFalse(hasattr(op, "dry_run"))
533
    self.assertFalse(hasattr(op, "force"))
534

    
535
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
536

    
537

    
538
class TestGroupRemove(unittest.TestCase):
539
  def test(self):
540
    clfactory = _FakeClientFactory(_FakeClient)
541
    handler = _CreateHandler(rlib2.R_2_groups_name,
542
                             ["grp28575"], {}, {}, clfactory)
543
    job_id = handler.DELETE()
544

    
545
    cl = clfactory.GetNextClient()
546
    self.assertRaises(IndexError, clfactory.GetNextClient)
547

    
548
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
549
    self.assertEqual(job_id, exp_job_id)
550
    self.assertTrue(isinstance(op, opcodes.OpGroupRemove))
551
    self.assertEqual(op.group_name, "grp28575")
552
    self.assertFalse(op.dry_run)
553
    self.assertFalse(hasattr(op, "force"))
554

    
555
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
556

    
557

    
558
class TestStorageQuery(unittest.TestCase):
559
  def test(self):
560
    clfactory = _FakeClientFactory(_FakeClient)
561
    queryargs = {
562
      "storage_type": constants.ST_LVM_PV,
563
      "output_fields": "name,other",
564
      }
565
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
566
                             ["node21075"], queryargs, {}, clfactory)
567
    job_id = handler.GET()
568

    
569
    cl = clfactory.GetNextClient()
570
    self.assertRaises(IndexError, clfactory.GetNextClient)
571

    
572
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
573
    self.assertEqual(job_id, exp_job_id)
574
    self.assertTrue(isinstance(op, opcodes.OpNodeQueryStorage))
575
    self.assertEqual(op.nodes, ["node21075"])
576
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
577
    self.assertEqual(op.output_fields, ["name", "other"])
578
    self.assertFalse(hasattr(op, "dry_run"))
579
    self.assertFalse(hasattr(op, "force"))
580

    
581
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
582

    
583
  def testErrors(self):
584
    clfactory = _FakeClientFactory(_FakeClient)
585

    
586
    queryargs = {
587
      "output_fields": "name,other",
588
      }
589
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
590
                             ["node10538"], queryargs, {}, clfactory)
591
    self.assertRaises(http.HttpBadRequest, handler.GET)
592

    
593
    queryargs = {
594
      "storage_type": constants.ST_LVM_VG,
595
      }
596
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
597
                             ["node21273"], queryargs, {}, clfactory)
598
    self.assertRaises(http.HttpBadRequest, handler.GET)
599

    
600
    queryargs = {
601
      "storage_type": "##unknown_storage##",
602
      "output_fields": "name,other",
603
      }
604
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
605
                             ["node10315"], queryargs, {}, clfactory)
606
    self.assertRaises(http.HttpBadRequest, handler.GET)
607

    
608

    
609
class TestStorageModify(unittest.TestCase):
610
  def test(self):
611
    clfactory = _FakeClientFactory(_FakeClient)
612

    
613
    for allocatable in [None, "1", "0"]:
614
      queryargs = {
615
        "storage_type": constants.ST_LVM_VG,
616
        "name": "pv-a",
617
        }
618

    
619
      if allocatable is not None:
620
        queryargs["allocatable"] = allocatable
621

    
622
      handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
623
                               ["node9292"], queryargs, {}, clfactory)
624
      job_id = handler.PUT()
625

    
626
      cl = clfactory.GetNextClient()
627
      self.assertRaises(IndexError, clfactory.GetNextClient)
628

    
629
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
630
      self.assertEqual(job_id, exp_job_id)
631
      self.assertTrue(isinstance(op, opcodes.OpNodeModifyStorage))
632
      self.assertEqual(op.node_name, "node9292")
633
      self.assertEqual(op.storage_type, constants.ST_LVM_VG)
634
      self.assertEqual(op.name, "pv-a")
635
      if allocatable is None:
636
        self.assertFalse(op.changes)
637
      else:
638
        assert allocatable in ("0", "1")
639
        self.assertEqual(op.changes, {
640
          constants.SF_ALLOCATABLE: (allocatable == "1"),
641
          })
642
      self.assertFalse(hasattr(op, "dry_run"))
643
      self.assertFalse(hasattr(op, "force"))
644

    
645
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
646

    
647
  def testErrors(self):
648
    clfactory = _FakeClientFactory(_FakeClient)
649

    
650
    # No storage type
651
    queryargs = {
652
      "name": "xyz",
653
      }
654
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
655
                             ["node26016"], queryargs, {}, clfactory)
656
    self.assertRaises(http.HttpBadRequest, handler.PUT)
657

    
658
    # No name
659
    queryargs = {
660
      "storage_type": constants.ST_LVM_VG,
661
      }
662
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
663
                             ["node21218"], queryargs, {}, clfactory)
664
    self.assertRaises(http.HttpBadRequest, handler.PUT)
665

    
666
    # Invalid value
667
    queryargs = {
668
      "storage_type": constants.ST_LVM_VG,
669
      "name": "pv-b",
670
      "allocatable": "noint",
671
      }
672
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
673
                             ["node30685"], queryargs, {}, clfactory)
674
    self.assertRaises(http.HttpBadRequest, handler.PUT)
675

    
676

    
677
class TestStorageRepair(unittest.TestCase):
678
  def test(self):
679
    clfactory = _FakeClientFactory(_FakeClient)
680
    queryargs = {
681
      "storage_type": constants.ST_LVM_PV,
682
      "name": "pv16611",
683
      }
684
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
685
                             ["node19265"], queryargs, {}, clfactory)
686
    job_id = handler.PUT()
687

    
688
    cl = clfactory.GetNextClient()
689
    self.assertRaises(IndexError, clfactory.GetNextClient)
690

    
691
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
692
    self.assertEqual(job_id, exp_job_id)
693
    self.assertTrue(isinstance(op, opcodes.OpRepairNodeStorage))
694
    self.assertEqual(op.node_name, "node19265")
695
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
696
    self.assertEqual(op.name, "pv16611")
697
    self.assertFalse(hasattr(op, "dry_run"))
698
    self.assertFalse(hasattr(op, "force"))
699

    
700
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
701

    
702
  def testErrors(self):
703
    clfactory = _FakeClientFactory(_FakeClient)
704

    
705
    # No storage type
706
    queryargs = {
707
      "name": "xyz",
708
      }
709
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
710
                             ["node11275"], queryargs, {}, clfactory)
711
    self.assertRaises(http.HttpBadRequest, handler.PUT)
712

    
713
    # No name
714
    queryargs = {
715
      "storage_type": constants.ST_LVM_VG,
716
      }
717
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
718
                             ["node21218"], queryargs, {}, clfactory)
719
    self.assertRaises(http.HttpBadRequest, handler.PUT)
720

    
721

    
722
class TestTags(unittest.TestCase):
723
  TAG_HANDLERS = [
724
    rlib2.R_2_instances_name_tags,
725
    rlib2.R_2_nodes_name_tags,
726
    rlib2.R_2_groups_name_tags,
727
    rlib2.R_2_tags,
728
    ]
729

    
730
  def testSetAndDelete(self):
731
    clfactory = _FakeClientFactory(_FakeClient)
732

    
733
    for method, opcls in [("PUT", opcodes.OpTagsSet),
734
                          ("DELETE", opcodes.OpTagsDel)]:
735
      for idx, handler in enumerate(self.TAG_HANDLERS):
736
        dry_run = bool(idx % 2)
737
        name = "test%s" % idx
738
        queryargs = {
739
          "tag": ["foo", "bar", "baz"],
740
          "dry-run": str(int(dry_run)),
741
          }
742

    
743
        handler = _CreateHandler(handler, [name], queryargs, {}, clfactory)
744
        job_id = getattr(handler, method)()
745

    
746
        cl = clfactory.GetNextClient()
747
        self.assertRaises(IndexError, clfactory.GetNextClient)
748

    
749
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
750
        self.assertEqual(job_id, exp_job_id)
751
        self.assertTrue(isinstance(op, opcls))
752
        self.assertEqual(op.kind, handler.TAG_LEVEL)
753
        if handler.TAG_LEVEL == constants.TAG_CLUSTER:
754
          self.assertTrue(op.name is None)
755
        else:
756
          self.assertEqual(op.name, name)
757
        self.assertEqual(op.tags, ["foo", "bar", "baz"])
758
        self.assertEqual(op.dry_run, dry_run)
759
        self.assertFalse(hasattr(op, "force"))
760

    
761
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
762

    
763

    
764
class TestInstanceCreation(testutils.GanetiTestCase):
765
  def test(self):
766
    clfactory = _FakeClientFactory(_FakeClient)
767

    
768
    name = "inst863.example.com"
769

    
770
    disk_variants = [
771
      # No disks
772
      [],
773

    
774
      # Two disks
775
      [{"size": 5, }, {"size": 100, }],
776

    
777
      # Disk with mode
778
      [{"size": 123, "mode": constants.DISK_RDWR, }],
779
      ]
780

    
781
    nic_variants = [
782
      # No NIC
783
      [],
784

    
785
      # Three NICs
786
      [{}, {}, {}],
787

    
788
      # Two NICs
789
      [
790
        { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
791
          "mac": "01:23:45:67:68:9A",
792
        },
793
        { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
794
      ],
795
      ]
796

    
797
    beparam_variants = [
798
      None,
799
      {},
800
      { constants.BE_VCPUS: 2, },
801
      { constants.BE_MEMORY: 123, },
802
      { constants.BE_VCPUS: 2,
803
        constants.BE_MEMORY: 1024,
804
        constants.BE_AUTO_BALANCE: True, }
805
      ]
806

    
807
    hvparam_variants = [
808
      None,
809
      { constants.HV_BOOT_ORDER: "anc", },
810
      { constants.HV_KERNEL_PATH: "/boot/fookernel",
811
        constants.HV_ROOT_PATH: "/dev/hda1", },
812
      ]
813

    
814
    for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
815
      for nics in nic_variants:
816
        for disk_template in constants.DISK_TEMPLATES:
817
          for disks in disk_variants:
818
            for beparams in beparam_variants:
819
              for hvparams in hvparam_variants:
820
                for dry_run in [False, True]:
821
                  queryargs = {
822
                    "dry-run": str(int(dry_run)),
823
                    }
824

    
825
                  data = {
826
                    rlib2._REQ_DATA_VERSION: 1,
827
                    "name": name,
828
                    "hypervisor": constants.HT_FAKE,
829
                    "disks": disks,
830
                    "nics": nics,
831
                    "mode": mode,
832
                    "disk_template": disk_template,
833
                    "os": "debootstrap",
834
                    }
835

    
836
                  if beparams is not None:
837
                    data["beparams"] = beparams
838

    
839
                  if hvparams is not None:
840
                    data["hvparams"] = hvparams
841

    
842
                  handler = _CreateHandler(rlib2.R_2_instances, [],
843
                                           queryargs, data, clfactory)
844
                  job_id = handler.POST()
845

    
846
                  cl = clfactory.GetNextClient()
847
                  self.assertRaises(IndexError, clfactory.GetNextClient)
848

    
849
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
850
                  self.assertEqual(job_id, exp_job_id)
851
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
852

    
853
                  self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
854
                  self.assertEqual(op.instance_name, name)
855
                  self.assertEqual(op.mode, mode)
856
                  self.assertEqual(op.disk_template, disk_template)
857
                  self.assertEqual(op.dry_run, dry_run)
858
                  self.assertEqual(len(op.disks), len(disks))
859
                  self.assertEqual(len(op.nics), len(nics))
860

    
861
                  for opdisk, disk in zip(op.disks, disks):
862
                    for key in constants.IDISK_PARAMS:
863
                      self.assertEqual(opdisk.get(key), disk.get(key))
864
                    self.assertFalse("unknown" in opdisk)
865

    
866
                  for opnic, nic in zip(op.nics, nics):
867
                    for key in constants.INIC_PARAMS:
868
                      self.assertEqual(opnic.get(key), nic.get(key))
869
                    self.assertFalse("unknown" in opnic)
870
                    self.assertFalse("foobar" in opnic)
871

    
872
                  if beparams is None:
873
                    self.assertFalse(hasattr(op, "beparams"))
874
                  else:
875
                    self.assertEqualValues(op.beparams, beparams)
876

    
877
                  if hvparams is None:
878
                    self.assertFalse(hasattr(op, "hvparams"))
879
                  else:
880
                    self.assertEqualValues(op.hvparams, hvparams)
881

    
882
  def testLegacyName(self):
883
    clfactory = _FakeClientFactory(_FakeClient)
884

    
885
    name = "inst29128.example.com"
886
    data = {
887
      rlib2._REQ_DATA_VERSION: 1,
888
      "name": name,
889
      "disks": [],
890
      "nics": [],
891
      "mode": constants.INSTANCE_CREATE,
892
      "disk_template": constants.DT_PLAIN,
893
      }
894

    
895
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
896
    job_id = handler.POST()
897

    
898
    cl = clfactory.GetNextClient()
899
    self.assertRaises(IndexError, clfactory.GetNextClient)
900

    
901
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
902
    self.assertEqual(job_id, exp_job_id)
903
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
904
    self.assertEqual(op.instance_name, name)
905
    self.assertFalse(hasattr(op, "name"))
906
    self.assertFalse(op.dry_run)
907

    
908
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
909

    
910
    # Define both
911
    data["instance_name"] = "other.example.com"
912
    assert "name" in data and "instance_name" in data
913
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
914
    self.assertRaises(http.HttpBadRequest, handler.POST)
915
    self.assertRaises(IndexError, clfactory.GetNextClient)
916

    
917
  def testLegacyOs(self):
918
    clfactory = _FakeClientFactory(_FakeClient)
919

    
920
    name = "inst4673.example.com"
921
    os = "linux29206"
922
    data = {
923
      rlib2._REQ_DATA_VERSION: 1,
924
      "name": name,
925
      "os_type": os,
926
      "disks": [],
927
      "nics": [],
928
      "mode": constants.INSTANCE_CREATE,
929
      "disk_template": constants.DT_PLAIN,
930
      }
931

    
932
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
933
    job_id = handler.POST()
934

    
935
    cl = clfactory.GetNextClient()
936
    self.assertRaises(IndexError, clfactory.GetNextClient)
937

    
938
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
939
    self.assertEqual(job_id, exp_job_id)
940
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
941
    self.assertEqual(op.instance_name, name)
942
    self.assertEqual(op.os_type, os)
943
    self.assertFalse(hasattr(op, "os"))
944
    self.assertFalse(op.dry_run)
945

    
946
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
947

    
948
    # Define both
949
    data["os"] = "linux9584"
950
    assert "os" in data and "os_type" in data
951
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
952
    self.assertRaises(http.HttpBadRequest, handler.POST)
953

    
954
  def testErrors(self):
955
    clfactory = _FakeClientFactory(_FakeClient)
956

    
957
    # Test all required fields
958
    reqfields = {
959
      rlib2._REQ_DATA_VERSION: 1,
960
      "name": "inst1.example.com",
961
      "disks": [],
962
      "nics": [],
963
      "mode": constants.INSTANCE_CREATE,
964
      "disk_template": constants.DT_PLAIN,
965
      }
966

    
967
    for name in reqfields.keys():
968
      data = dict(i for i in reqfields.iteritems() if i[0] != name)
969

    
970
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
971
      self.assertRaises(http.HttpBadRequest, handler.POST)
972
      self.assertRaises(IndexError, clfactory.GetNextClient)
973

    
974
    # Invalid disks and nics
975
    for field in ["disks", "nics"]:
976
      invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
977
                        [{"_unknown_": 999, }]]
978

    
979
      for invvalue in invalid_values:
980
        data = reqfields.copy()
981
        data[field] = invvalue
982
        handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
983
        self.assertRaises(http.HttpBadRequest, handler.POST)
984
        self.assertRaises(IndexError, clfactory.GetNextClient)
985

    
986
  def testVersion(self):
987
    clfactory = _FakeClientFactory(_FakeClient)
988

    
989
    # No version field
990
    data = {
991
      "name": "inst1.example.com",
992
      "disks": [],
993
      "nics": [],
994
      "mode": constants.INSTANCE_CREATE,
995
      "disk_template": constants.DT_PLAIN,
996
      }
997

    
998
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
999
    self.assertRaises(http.HttpBadRequest, handler.POST)
1000

    
1001
    # Old and incorrect versions
1002
    for version in [0, -1, 10483, "Hello World"]:
1003
      data[rlib2._REQ_DATA_VERSION] = version
1004

    
1005
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1006
      self.assertRaises(http.HttpBadRequest, handler.POST)
1007

    
1008
      self.assertRaises(IndexError, clfactory.GetNextClient)
1009

    
1010
    # Correct version
1011
    data[rlib2._REQ_DATA_VERSION] = 1
1012
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1013
    job_id = handler.POST()
1014

    
1015
    cl = clfactory.GetNextClient()
1016
    self.assertRaises(IndexError, clfactory.GetNextClient)
1017

    
1018
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1019
    self.assertEqual(job_id, exp_job_id)
1020
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
1021
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1022

    
1023

    
1024
class TestBackupExport(unittest.TestCase):
1025
  def test(self):
1026
    clfactory = _FakeClientFactory(_FakeClient)
1027

    
1028
    name = "instmoo"
1029
    data = {
1030
      "mode": constants.EXPORT_MODE_REMOTE,
1031
      "destination": [(1, 2, 3), (99, 99, 99)],
1032
      "shutdown": True,
1033
      "remove_instance": True,
1034
      "x509_key_name": ["name", "hash"],
1035
      "destination_x509_ca": "---cert---"
1036
      }
1037

    
1038
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1039
                             data, clfactory)
1040
    job_id = handler.PUT()
1041

    
1042
    cl = clfactory.GetNextClient()
1043
    self.assertRaises(IndexError, clfactory.GetNextClient)
1044

    
1045
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1046
    self.assertEqual(job_id, exp_job_id)
1047
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1048
    self.assertEqual(op.instance_name, name)
1049
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
1050
    self.assertEqual(op.target_node, [(1, 2, 3), (99, 99, 99)])
1051
    self.assertEqual(op.shutdown, True)
1052
    self.assertEqual(op.remove_instance, True)
1053
    self.assertEqual(op.x509_key_name, ["name", "hash"])
1054
    self.assertEqual(op.destination_x509_ca, "---cert---")
1055
    self.assertFalse(hasattr(op, "dry_run"))
1056
    self.assertFalse(hasattr(op, "force"))
1057

    
1058
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1059

    
1060
  def testDefaults(self):
1061
    clfactory = _FakeClientFactory(_FakeClient)
1062

    
1063
    name = "inst1"
1064
    data = {
1065
      "destination": "node2",
1066
      "shutdown": False,
1067
      }
1068

    
1069
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1070
                             data, clfactory)
1071
    job_id = handler.PUT()
1072

    
1073
    cl = clfactory.GetNextClient()
1074
    self.assertRaises(IndexError, clfactory.GetNextClient)
1075

    
1076
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1077
    self.assertEqual(job_id, exp_job_id)
1078
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1079
    self.assertEqual(op.instance_name, name)
1080
    self.assertEqual(op.target_node, "node2")
1081
    self.assertFalse(hasattr(op, "mode"))
1082
    self.assertFalse(hasattr(op, "remove_instance"))
1083
    self.assertFalse(hasattr(op, "destination"))
1084
    self.assertFalse(hasattr(op, "dry_run"))
1085
    self.assertFalse(hasattr(op, "force"))
1086

    
1087
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1088

    
1089
  def testErrors(self):
1090
    clfactory = _FakeClientFactory(_FakeClient)
1091

    
1092
    for value in ["True", "False"]:
1093
      handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
1094
        "remove_instance": value,
1095
        }, clfactory)
1096
      self.assertRaises(http.HttpBadRequest, handler.PUT)
1097

    
1098

    
1099
class TestInstanceMigrate(testutils.GanetiTestCase):
1100
  def test(self):
1101
    clfactory = _FakeClientFactory(_FakeClient)
1102

    
1103
    name = "instYooho6ek"
1104

    
1105
    for cleanup in [False, True]:
1106
      for mode in constants.HT_MIGRATION_MODES:
1107
        data = {
1108
          "cleanup": cleanup,
1109
          "mode": mode,
1110
          }
1111

    
1112
        handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
1113
                                 data, clfactory)
1114
        job_id = handler.PUT()
1115

    
1116
        cl = clfactory.GetNextClient()
1117
        self.assertRaises(IndexError, clfactory.GetNextClient)
1118

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

    
1128
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1129

    
1130
  def testDefaults(self):
1131
    clfactory = _FakeClientFactory(_FakeClient)
1132

    
1133
    name = "instnohZeex0"
1134

    
1135
    handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
1136
                             clfactory)
1137
    job_id = handler.PUT()
1138

    
1139
    cl = clfactory.GetNextClient()
1140
    self.assertRaises(IndexError, clfactory.GetNextClient)
1141

    
1142
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1143
    self.assertEqual(job_id, exp_job_id)
1144
    self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1145
    self.assertEqual(op.instance_name, name)
1146
    self.assertFalse(hasattr(op, "mode"))
1147
    self.assertFalse(hasattr(op, "cleanup"))
1148
    self.assertFalse(hasattr(op, "dry_run"))
1149
    self.assertFalse(hasattr(op, "force"))
1150

    
1151
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1152

    
1153

    
1154
class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
1155
  def test(self):
1156
    clfactory = _FakeClientFactory(_FakeClient)
1157

    
1158
    name = "instij0eeph7"
1159

    
1160
    for new_name in ["ua0aiyoo", "fai3ongi"]:
1161
      for ip_check in [False, True]:
1162
        for name_check in [False, True]:
1163
          data = {
1164
            "new_name": new_name,
1165
            "ip_check": ip_check,
1166
            "name_check": name_check,
1167
            }
1168

    
1169
          handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1170
                                   {}, data, clfactory)
1171
          job_id = handler.PUT()
1172

    
1173
          cl = clfactory.GetNextClient()
1174
          self.assertRaises(IndexError, clfactory.GetNextClient)
1175

    
1176
          (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1177
          self.assertEqual(job_id, exp_job_id)
1178
          self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1179
          self.assertEqual(op.instance_name, name)
1180
          self.assertEqual(op.new_name, new_name)
1181
          self.assertEqual(op.ip_check, ip_check)
1182
          self.assertEqual(op.name_check, name_check)
1183
          self.assertFalse(hasattr(op, "dry_run"))
1184
          self.assertFalse(hasattr(op, "force"))
1185

    
1186
          self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1187

    
1188
  def testDefaults(self):
1189
    clfactory = _FakeClientFactory(_FakeClient)
1190

    
1191
    name = "instahchie3t"
1192

    
1193
    for new_name in ["thag9mek", "quees7oh"]:
1194
      data = {
1195
        "new_name": new_name,
1196
        }
1197

    
1198
      handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1199
                               {}, data, clfactory)
1200
      job_id = handler.PUT()
1201

    
1202
      cl = clfactory.GetNextClient()
1203
      self.assertRaises(IndexError, clfactory.GetNextClient)
1204

    
1205
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1206
      self.assertEqual(job_id, exp_job_id)
1207
      self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1208
      self.assertEqual(op.instance_name, name)
1209
      self.assertEqual(op.new_name, new_name)
1210
      self.assertFalse(hasattr(op, "ip_check"))
1211
      self.assertFalse(hasattr(op, "name_check"))
1212
      self.assertFalse(hasattr(op, "dry_run"))
1213
      self.assertFalse(hasattr(op, "force"))
1214

    
1215
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1216

    
1217

    
1218
class TestParseModifyInstanceRequest(unittest.TestCase):
1219
  def test(self):
1220
    clfactory = _FakeClientFactory(_FakeClient)
1221

    
1222
    name = "instush8gah"
1223

    
1224
    test_disks = [
1225
      [],
1226
      [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
1227
      ]
1228

    
1229
    for osparams in [{}, { "some": "value", "other": "Hello World", }]:
1230
      for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
1231
        for beparams in [{}, { constants.BE_MEMORY: 128, }]:
1232
          for force in [False, True]:
1233
            for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
1234
              for disks in test_disks:
1235
                for disk_template in constants.DISK_TEMPLATES:
1236
                  data = {
1237
                    "osparams": osparams,
1238
                    "hvparams": hvparams,
1239
                    "beparams": beparams,
1240
                    "nics": nics,
1241
                    "disks": disks,
1242
                    "force": force,
1243
                    "disk_template": disk_template,
1244
                    }
1245

    
1246
                  handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1247
                                           [name], {}, data, clfactory)
1248
                  job_id = handler.PUT()
1249

    
1250
                  cl = clfactory.GetNextClient()
1251
                  self.assertRaises(IndexError, clfactory.GetNextClient)
1252

    
1253
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1254
                  self.assertEqual(job_id, exp_job_id)
1255
                  self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1256
                  self.assertEqual(op.instance_name, name)
1257
                  self.assertEqual(op.hvparams, hvparams)
1258
                  self.assertEqual(op.beparams, beparams)
1259
                  self.assertEqual(op.osparams, osparams)
1260
                  self.assertEqual(op.force, force)
1261
                  self.assertEqual(op.nics, nics)
1262
                  self.assertEqual(op.disks, disks)
1263
                  self.assertEqual(op.disk_template, disk_template)
1264
                  self.assertFalse(hasattr(op, "remote_node"))
1265
                  self.assertFalse(hasattr(op, "os_name"))
1266
                  self.assertFalse(hasattr(op, "force_variant"))
1267
                  self.assertFalse(hasattr(op, "dry_run"))
1268

    
1269
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1270

    
1271
  def testDefaults(self):
1272
    clfactory = _FakeClientFactory(_FakeClient)
1273

    
1274
    name = "instir8aish31"
1275

    
1276
    handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1277
                             [name], {}, {}, clfactory)
1278
    job_id = handler.PUT()
1279

    
1280
    cl = clfactory.GetNextClient()
1281
    self.assertRaises(IndexError, clfactory.GetNextClient)
1282

    
1283
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1284
    self.assertEqual(job_id, exp_job_id)
1285
    self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1286
    self.assertEqual(op.instance_name, name)
1287

    
1288
    for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
1289
              "disk_template", "remote_node", "os_name", "force_variant"]:
1290
      self.assertFalse(hasattr(op, i))
1291

    
1292

    
1293
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1294
  def setUp(self):
1295
    testutils.GanetiTestCase.setUp(self)
1296

    
1297
    self.Parse = rlib2._ParseInstanceReinstallRequest
1298

    
1299
  def _Check(self, ops, name):
1300
    expcls = [
1301
      opcodes.OpInstanceShutdown,
1302
      opcodes.OpInstanceReinstall,
1303
      opcodes.OpInstanceStartup,
1304
      ]
1305

    
1306
    self.assert_(compat.all(isinstance(op, exp)
1307
                            for op, exp in zip(ops, expcls)))
1308
    self.assert_(compat.all(op.instance_name == name for op in ops))
1309

    
1310
  def test(self):
1311
    name = "shoo0tihohma"
1312

    
1313
    ops = self.Parse(name, {"os": "sys1", "start": True,})
1314
    self.assertEqual(len(ops), 3)
1315
    self._Check(ops, name)
1316
    self.assertEqual(ops[1].os_type, "sys1")
1317
    self.assertFalse(ops[1].osparams)
1318

    
1319
    ops = self.Parse(name, {"os": "sys2", "start": False,})
1320
    self.assertEqual(len(ops), 2)
1321
    self._Check(ops, name)
1322
    self.assertEqual(ops[1].os_type, "sys2")
1323

    
1324
    osparams = {
1325
      "reformat": "1",
1326
      }
1327
    ops = self.Parse(name, {"os": "sys4035", "start": True,
1328
                            "osparams": osparams,})
1329
    self.assertEqual(len(ops), 3)
1330
    self._Check(ops, name)
1331
    self.assertEqual(ops[1].os_type, "sys4035")
1332
    self.assertEqual(ops[1].osparams, osparams)
1333

    
1334
  def testDefaults(self):
1335
    name = "noolee0g"
1336

    
1337
    ops = self.Parse(name, {"os": "linux1"})
1338
    self.assertEqual(len(ops), 3)
1339
    self._Check(ops, name)
1340
    self.assertEqual(ops[1].os_type, "linux1")
1341
    self.assertFalse(ops[1].osparams)
1342

    
1343
  def testErrors(self):
1344
    self.assertRaises(http.HttpBadRequest, self.Parse,
1345
                      "foo", "not a dictionary")
1346

    
1347

    
1348
class TestGroupRename(unittest.TestCase):
1349
  def test(self):
1350
    clfactory = _FakeClientFactory(_FakeClient)
1351

    
1352
    name = "group608242564"
1353
    data = {
1354
      "new_name": "ua0aiyoo15112",
1355
      }
1356

    
1357
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1358
                             clfactory)
1359
    job_id = handler.PUT()
1360

    
1361
    cl = clfactory.GetNextClient()
1362
    self.assertRaises(IndexError, clfactory.GetNextClient)
1363

    
1364
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1365
    self.assertEqual(job_id, exp_job_id)
1366

    
1367
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1368
    self.assertEqual(op.group_name, name)
1369
    self.assertEqual(op.new_name, "ua0aiyoo15112")
1370
    self.assertFalse(op.dry_run)
1371
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1372

    
1373
  def testDryRun(self):
1374
    clfactory = _FakeClientFactory(_FakeClient)
1375

    
1376
    name = "group28548"
1377
    data = {
1378
      "new_name": "ua0aiyoo",
1379
      }
1380

    
1381
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
1382
      "dry-run": ["1"],
1383
      }, data, clfactory)
1384
    job_id = handler.PUT()
1385

    
1386
    cl = clfactory.GetNextClient()
1387
    self.assertRaises(IndexError, clfactory.GetNextClient)
1388

    
1389
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1390
    self.assertEqual(job_id, exp_job_id)
1391

    
1392
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1393
    self.assertEqual(op.group_name, name)
1394
    self.assertEqual(op.new_name, "ua0aiyoo")
1395
    self.assertTrue(op.dry_run)
1396
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1397

    
1398

    
1399
class TestInstanceReplaceDisks(unittest.TestCase):
1400
  def test(self):
1401
    clfactory = _FakeClientFactory(_FakeClient)
1402

    
1403
    name = "inst22568"
1404

    
1405
    for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
1406
      data = {
1407
        "mode": constants.REPLACE_DISK_SEC,
1408
        "disks": disks,
1409
        "iallocator": "myalloc",
1410
        }
1411

    
1412
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1413
                               [name], {}, data, clfactory)
1414
      job_id = handler.POST()
1415

    
1416
      cl = clfactory.GetNextClient()
1417
      self.assertRaises(IndexError, clfactory.GetNextClient)
1418

    
1419
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1420
      self.assertEqual(job_id, exp_job_id)
1421

    
1422
      self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1423
      self.assertEqual(op.instance_name, name)
1424
      self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
1425
      self.assertEqual(op.disks, [1, 2, 3])
1426
      self.assertEqual(op.iallocator, "myalloc")
1427
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1428

    
1429
  def testDefaults(self):
1430
    clfactory = _FakeClientFactory(_FakeClient)
1431

    
1432
    name = "inst11413"
1433
    data = {
1434
      "mode": constants.REPLACE_DISK_AUTO,
1435
      }
1436

    
1437
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1438
                             [name], {}, data, clfactory)
1439
    job_id = handler.POST()
1440

    
1441
    cl = clfactory.GetNextClient()
1442
    self.assertRaises(IndexError, clfactory.GetNextClient)
1443

    
1444
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1445
    self.assertEqual(job_id, exp_job_id)
1446

    
1447
    self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1448
    self.assertEqual(op.instance_name, name)
1449
    self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
1450
    self.assertFalse(hasattr(op, "iallocator"))
1451
    self.assertFalse(hasattr(op, "disks"))
1452
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1453

    
1454
  def testWrong(self):
1455
    clfactory = _FakeClientFactory(_FakeClient)
1456

    
1457
    data = {
1458
      "mode": constants.REPLACE_DISK_AUTO,
1459
      "disks": "hello world",
1460
      }
1461

    
1462
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1463
                             ["foo"], {}, data, clfactory)
1464
    self.assertRaises(http.HttpBadRequest, handler.POST)
1465

    
1466

    
1467
class TestGroupModify(unittest.TestCase):
1468
  def test(self):
1469
    clfactory = _FakeClientFactory(_FakeClient)
1470

    
1471
    name = "group6002"
1472

    
1473
    for policy in constants.VALID_ALLOC_POLICIES:
1474
      data = {
1475
        "alloc_policy": policy,
1476
        }
1477

    
1478
      handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1479
                               clfactory)
1480
      job_id = handler.PUT()
1481

    
1482
      cl = clfactory.GetNextClient()
1483
      self.assertRaises(IndexError, clfactory.GetNextClient)
1484

    
1485
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1486
      self.assertEqual(job_id, exp_job_id)
1487

    
1488
      self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1489
      self.assertEqual(op.group_name, name)
1490
      self.assertEqual(op.alloc_policy, policy)
1491
      self.assertFalse(hasattr(op, "dry_run"))
1492
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1493

    
1494
  def testUnknownPolicy(self):
1495
    clfactory = _FakeClientFactory(_FakeClient)
1496

    
1497
    data = {
1498
      "alloc_policy": "_unknown_policy_",
1499
      }
1500

    
1501
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1502
                             clfactory)
1503
    self.assertRaises(http.HttpBadRequest, handler.PUT)
1504
    self.assertRaises(IndexError, clfactory.GetNextClient)
1505

    
1506
  def testDefaults(self):
1507
    clfactory = _FakeClientFactory(_FakeClient)
1508

    
1509
    name = "group6679"
1510

    
1511
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1512
                             clfactory)
1513
    job_id = handler.PUT()
1514

    
1515
    cl = clfactory.GetNextClient()
1516
    self.assertRaises(IndexError, clfactory.GetNextClient)
1517

    
1518
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1519
    self.assertEqual(job_id, exp_job_id)
1520

    
1521
    self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1522
    self.assertEqual(op.group_name, name)
1523
    self.assertFalse(hasattr(op, "alloc_policy"))
1524
    self.assertFalse(hasattr(op, "dry_run"))
1525
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1526

    
1527

    
1528
class TestGroupAdd(unittest.TestCase):
1529
  def test(self):
1530
    name = "group3618"
1531
    clfactory = _FakeClientFactory(_FakeClient)
1532

    
1533
    for policy in constants.VALID_ALLOC_POLICIES:
1534
      data = {
1535
        "group_name": name,
1536
        "alloc_policy": policy,
1537
        }
1538

    
1539
      handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1540
                               clfactory)
1541
      job_id = handler.POST()
1542

    
1543
      cl = clfactory.GetNextClient()
1544
      self.assertRaises(IndexError, clfactory.GetNextClient)
1545

    
1546
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1547
      self.assertEqual(job_id, exp_job_id)
1548

    
1549
      self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1550
      self.assertEqual(op.group_name, name)
1551
      self.assertEqual(op.alloc_policy, policy)
1552
      self.assertFalse(op.dry_run)
1553
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1554

    
1555
  def testUnknownPolicy(self):
1556
    clfactory = _FakeClientFactory(_FakeClient)
1557

    
1558
    data = {
1559
      "alloc_policy": "_unknown_policy_",
1560
      }
1561

    
1562
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1563
    self.assertRaises(http.HttpBadRequest, handler.POST)
1564
    self.assertRaises(IndexError, clfactory.GetNextClient)
1565

    
1566
  def testDefaults(self):
1567
    clfactory = _FakeClientFactory(_FakeClient)
1568

    
1569
    name = "group15395"
1570
    data = {
1571
      "group_name": name,
1572
      }
1573

    
1574
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1575
    job_id = handler.POST()
1576

    
1577
    cl = clfactory.GetNextClient()
1578
    self.assertRaises(IndexError, clfactory.GetNextClient)
1579

    
1580
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1581
    self.assertEqual(job_id, exp_job_id)
1582

    
1583
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1584
    self.assertEqual(op.group_name, name)
1585
    self.assertFalse(hasattr(op, "alloc_policy"))
1586
    self.assertFalse(op.dry_run)
1587

    
1588
  def testLegacyName(self):
1589
    clfactory = _FakeClientFactory(_FakeClient)
1590

    
1591
    name = "group29852"
1592
    data = {
1593
      "name": name,
1594
      }
1595

    
1596
    handler = _CreateHandler(rlib2.R_2_groups, [], {
1597
      "dry-run": ["1"],
1598
      }, data, clfactory)
1599
    job_id = handler.POST()
1600

    
1601
    cl = clfactory.GetNextClient()
1602
    self.assertRaises(IndexError, clfactory.GetNextClient)
1603

    
1604
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1605
    self.assertEqual(job_id, exp_job_id)
1606

    
1607
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1608
    self.assertEqual(op.group_name, name)
1609
    self.assertFalse(hasattr(op, "alloc_policy"))
1610
    self.assertTrue(op.dry_run)
1611

    
1612

    
1613
class TestNodeRole(unittest.TestCase):
1614
  def test(self):
1615
    clfactory = _FakeClientFactory(_FakeClient)
1616

    
1617
    for role in rlib2._NR_MAP.values():
1618
      handler = _CreateHandler(rlib2.R_2_nodes_name_role,
1619
                               ["node-z"], {}, role, clfactory)
1620
      if role == rlib2._NR_MASTER:
1621
        self.assertRaises(http.HttpBadRequest, handler.PUT)
1622
      else:
1623
        job_id = handler.PUT()
1624

    
1625
        cl = clfactory.GetNextClient()
1626
        self.assertRaises(IndexError, clfactory.GetNextClient)
1627

    
1628
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1629
        self.assertEqual(job_id, exp_job_id)
1630
        self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
1631
        self.assertEqual(op.node_name, "node-z")
1632
        self.assertFalse(op.force)
1633
        self.assertFalse(hasattr(op, "dry_run"))
1634

    
1635
        if role == rlib2._NR_REGULAR:
1636
          self.assertFalse(op.drained)
1637
          self.assertFalse(op.offline)
1638
          self.assertFalse(op.master_candidate)
1639
        elif role == rlib2._NR_MASTER_CANDIDATE:
1640
          self.assertFalse(op.drained)
1641
          self.assertFalse(op.offline)
1642
          self.assertTrue(op.master_candidate)
1643
        elif role == rlib2._NR_DRAINED:
1644
          self.assertTrue(op.drained)
1645
          self.assertFalse(op.offline)
1646
          self.assertFalse(op.master_candidate)
1647
        elif role == rlib2._NR_OFFLINE:
1648
          self.assertFalse(op.drained)
1649
          self.assertTrue(op.offline)
1650
          self.assertFalse(op.master_candidate)
1651
        else:
1652
          self.fail("Unknown role '%s'" % role)
1653

    
1654
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1655

    
1656

    
1657
class TestSimpleResources(unittest.TestCase):
1658
  def setUp(self):
1659
    self.clfactory = _FakeClientFactory(_FakeClient)
1660

    
1661
  def tearDown(self):
1662
    self.assertRaises(IndexError, self.clfactory.GetNextClient)
1663

    
1664
  def testFeatures(self):
1665
    handler = _CreateHandler(rlib2.R_2_features, [], {}, None, self.clfactory)
1666
    self.assertEqual(set(handler.GET()), rlib2.ALL_FEATURES)
1667

    
1668
  def testEmpty(self):
1669
    for cls in [rlib2.R_root, rlib2.R_2]:
1670
      handler = _CreateHandler(cls, [], {}, None, self.clfactory)
1671
      self.assertTrue(handler.GET() is None)
1672

    
1673
  def testVersion(self):
1674
    handler = _CreateHandler(rlib2.R_version, [], {}, None, self.clfactory)
1675
    self.assertEqual(handler.GET(), constants.RAPI_VERSION)
1676

    
1677

    
1678
class TestClusterInfo(unittest.TestCase):
1679
  class _ClusterInfoClient:
1680
    def __init__(self):
1681
      self.cluster_info = None
1682

    
1683
    def QueryClusterInfo(self):
1684
      assert self.cluster_info is None
1685
      self.cluster_info = object()
1686
      return self.cluster_info
1687

    
1688
  def test(self):
1689
    clfactory = _FakeClientFactory(self._ClusterInfoClient)
1690
    handler = _CreateHandler(rlib2.R_2_info, [], {}, None, clfactory)
1691
    result = handler.GET()
1692
    cl = clfactory.GetNextClient()
1693
    self.assertRaises(IndexError, clfactory.GetNextClient)
1694
    self.assertEqual(result, cl.cluster_info)
1695

    
1696

    
1697
if __name__ == '__main__':
1698
  testutils.GanetiTestProgram()