Statistics
| Branch: | Tag: | Revision:

root / qa / qa_instance.py @ 1c573fb4

History | View | Annotate | Download (18.6 kB)

1
#
2
#
3

    
4
# Copyright (C) 2007, 2011, 2012 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
"""Instance related QA tests.
23

24
"""
25

    
26
import re
27
import time
28

    
29
from ganeti import utils
30
from ganeti import constants
31
from ganeti import query
32

    
33
import qa_config
34
import qa_utils
35
import qa_error
36

    
37
from qa_utils import AssertIn, AssertCommand, AssertEqual
38
from qa_utils import InstanceCheck, INST_DOWN, INST_UP, FIRST_ARG, RETURN_VALUE
39

    
40

    
41
def _GetDiskStatePath(disk):
42
  return "/sys/block/%s/device/state" % disk
43

    
44

    
45
def _GetGenericAddParameters(inst, force_mac=None):
46
  params = ["-B"]
47
  params.append("%s=%s,%s=%s" % (constants.BE_MINMEM,
48
                                 qa_config.get(constants.BE_MINMEM),
49
                                 constants.BE_MAXMEM,
50
                                 qa_config.get(constants.BE_MAXMEM)))
51
  for idx, size in enumerate(qa_config.get("disk")):
52
    params.extend(["--disk", "%s:size=%s" % (idx, size)])
53

    
54
  # Set static MAC address if configured
55
  if force_mac:
56
    nic0_mac = force_mac
57
  else:
58
    nic0_mac = qa_config.GetInstanceNicMac(inst)
59
  if nic0_mac:
60
    params.extend(["--net", "0:mac=%s" % nic0_mac])
61

    
62
  return params
63

    
64

    
65
def _DiskTest(node, disk_template):
66
  instance = qa_config.AcquireInstance()
67
  try:
68
    cmd = (["gnt-instance", "add",
69
            "--os-type=%s" % qa_config.get("os"),
70
            "--disk-template=%s" % disk_template,
71
            "--node=%s" % node] +
72
           _GetGenericAddParameters(instance))
73
    cmd.append(instance["name"])
74

    
75
    AssertCommand(cmd)
76

    
77
    _CheckSsconfInstanceList(instance["name"])
78

    
79
    return instance
80
  except:
81
    qa_config.ReleaseInstance(instance)
82
    raise
83

    
84

    
85
@InstanceCheck(None, INST_UP, RETURN_VALUE)
86
def TestInstanceAddWithPlainDisk(node):
87
  """gnt-instance add -t plain"""
88
  return _DiskTest(node["primary"], "plain")
89

    
90

    
91
@InstanceCheck(None, INST_UP, RETURN_VALUE)
92
def TestInstanceAddWithDrbdDisk(node, node2):
93
  """gnt-instance add -t drbd"""
94
  return _DiskTest("%s:%s" % (node["primary"], node2["primary"]),
95
                   "drbd")
96

    
97

    
98
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
99
def TestInstanceRemove(instance):
100
  """gnt-instance remove"""
101
  AssertCommand(["gnt-instance", "remove", "-f", instance["name"]])
102

    
103
  qa_config.ReleaseInstance(instance)
104

    
105

    
106
@InstanceCheck(INST_DOWN, INST_UP, FIRST_ARG)
107
def TestInstanceStartup(instance):
108
  """gnt-instance startup"""
109
  AssertCommand(["gnt-instance", "startup", instance["name"]])
110

    
111

    
112
@InstanceCheck(INST_UP, INST_DOWN, FIRST_ARG)
113
def TestInstanceShutdown(instance):
114
  """gnt-instance shutdown"""
115
  AssertCommand(["gnt-instance", "shutdown", instance["name"]])
116

    
117

    
118
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
119
def TestInstanceReboot(instance):
120
  """gnt-instance reboot"""
121
  options = qa_config.get("options", {})
122
  reboot_types = options.get("reboot-types", constants.REBOOT_TYPES)
123
  name = instance["name"]
124
  for rtype in reboot_types:
125
    AssertCommand(["gnt-instance", "reboot", "--type=%s" % rtype, name])
126

    
127
  AssertCommand(["gnt-instance", "shutdown", name])
128
  qa_utils.RunInstanceCheck(instance, False)
129
  AssertCommand(["gnt-instance", "reboot", name])
130

    
131
  master = qa_config.GetMasterNode()
132
  cmd = ["gnt-instance", "list", "--no-headers", "-o", "status", name]
133
  result_output = qa_utils.GetCommandOutput(master["primary"],
134
                                            utils.ShellQuoteArgs(cmd))
135
  AssertEqual(result_output.strip(), constants.INSTST_RUNNING)
136

    
137

    
138
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
139
def TestInstanceReinstall(instance):
140
  """gnt-instance reinstall"""
141
  AssertCommand(["gnt-instance", "reinstall", "-f", instance["name"]])
142

    
143

    
144
def _ReadSsconfInstanceList():
145
  """Reads ssconf_instance_list from the master node.
146

147
  """
148
  master = qa_config.GetMasterNode()
149

    
150
  cmd = ["cat", utils.PathJoin(constants.DATA_DIR,
151
                               "ssconf_%s" % constants.SS_INSTANCE_LIST)]
152

    
153
  return qa_utils.GetCommandOutput(master["primary"],
154
                                   utils.ShellQuoteArgs(cmd)).splitlines()
155

    
156

    
157
def _CheckSsconfInstanceList(instance):
158
  """Checks if a certain instance is in the ssconf instance list.
159

160
  @type instance: string
161
  @param instance: Instance name
162

163
  """
164
  AssertIn(qa_utils.ResolveInstanceName(instance),
165
           _ReadSsconfInstanceList())
166

    
167

    
168
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
169
def TestInstanceRenameAndBack(rename_source, rename_target):
170
  """gnt-instance rename
171

172
  This must leave the instance with the original name, not the target
173
  name.
174

175
  """
176
  _CheckSsconfInstanceList(rename_source)
177

    
178
  # first do a rename to a different actual name, expecting it to fail
179
  qa_utils.AddToEtcHosts(["meeeeh-not-exists", rename_target])
180
  try:
181
    AssertCommand(["gnt-instance", "rename", rename_source, rename_target],
182
                  fail=True)
183
    _CheckSsconfInstanceList(rename_source)
184
  finally:
185
    qa_utils.RemoveFromEtcHosts(["meeeeh-not-exists", rename_target])
186

    
187
  # and now rename instance to rename_target...
188
  AssertCommand(["gnt-instance", "rename", rename_source, rename_target])
189
  _CheckSsconfInstanceList(rename_target)
190
  qa_utils.RunInstanceCheck(rename_source, False)
191
  qa_utils.RunInstanceCheck(rename_target, False)
192

    
193
  # and back
194
  AssertCommand(["gnt-instance", "rename", rename_target, rename_source])
195
  _CheckSsconfInstanceList(rename_source)
196
  qa_utils.RunInstanceCheck(rename_target, False)
197

    
198

    
199
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
200
def TestInstanceFailover(instance):
201
  """gnt-instance failover"""
202
  cmd = ["gnt-instance", "failover", "--force", instance["name"]]
203

    
204
  # failover ...
205
  AssertCommand(cmd)
206
  qa_utils.RunInstanceCheck(instance, True)
207

    
208
  # ... and back
209
  AssertCommand(cmd)
210

    
211

    
212
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
213
def TestInstanceMigrate(instance):
214
  """gnt-instance migrate"""
215
  cmd = ["gnt-instance", "migrate", "--force", instance["name"]]
216

    
217
  # migrate ...
218
  AssertCommand(cmd)
219
  qa_utils.RunInstanceCheck(instance, True)
220

    
221
  # ... and back
222
  AssertCommand(cmd)
223

    
224
  # TODO: Split into multiple tests
225
  AssertCommand(["gnt-instance", "shutdown", instance["name"]])
226
  qa_utils.RunInstanceCheck(instance, False)
227
  AssertCommand(cmd, fail=True)
228
  AssertCommand(["gnt-instance", "migrate", "--force", "--allow-failover",
229
                 instance["name"]])
230
  AssertCommand(["gnt-instance", "start", instance["name"]])
231
  AssertCommand(cmd)
232
  qa_utils.RunInstanceCheck(instance, True)
233

    
234
  AssertCommand(["gnt-instance", "modify", "-B",
235
                 ("%s=%s" %
236
                  (constants.BE_ALWAYS_FAILOVER, constants.VALUE_TRUE)),
237
                 instance["name"]])
238

    
239
  AssertCommand(cmd, fail=True)
240
  qa_utils.RunInstanceCheck(instance, True)
241
  AssertCommand(["gnt-instance", "migrate", "--force", "--allow-failover",
242
                 instance["name"]])
243

    
244
  # TODO: Verify whether the default value is restored here (not hardcoded)
245
  AssertCommand(["gnt-instance", "modify", "-B",
246
                 ("%s=%s" %
247
                  (constants.BE_ALWAYS_FAILOVER, constants.VALUE_FALSE)),
248
                 instance["name"]])
249

    
250
  AssertCommand(cmd)
251
  qa_utils.RunInstanceCheck(instance, True)
252

    
253

    
254
def TestInstanceInfo(instance):
255
  """gnt-instance info"""
256
  AssertCommand(["gnt-instance", "info", instance["name"]])
257

    
258

    
259
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
260
def TestInstanceModify(instance):
261
  """gnt-instance modify"""
262
  # Assume /sbin/init exists on all systems
263
  test_kernel = "/sbin/init"
264
  test_initrd = test_kernel
265

    
266
  orig_maxmem = qa_config.get(constants.BE_MAXMEM)
267
  orig_minmem = qa_config.get(constants.BE_MINMEM)
268
  #orig_bridge = qa_config.get("bridge", "xen-br0")
269
  args = [
270
    ["-B", "%s=128" % constants.BE_MINMEM],
271
    ["-B", "%s=128" % constants.BE_MAXMEM],
272
    ["-B", "%s=%s,%s=%s" % (constants.BE_MINMEM, orig_minmem,
273
                            constants.BE_MAXMEM, orig_maxmem)],
274
    ["-B", "%s=2" % constants.BE_VCPUS],
275
    ["-B", "%s=1" % constants.BE_VCPUS],
276
    ["-B", "%s=%s" % (constants.BE_VCPUS, constants.VALUE_DEFAULT)],
277
    ["-B", "%s=%s" % (constants.BE_ALWAYS_FAILOVER, constants.VALUE_TRUE)],
278
    ["-B", "%s=%s" % (constants.BE_ALWAYS_FAILOVER, constants.VALUE_DEFAULT)],
279

    
280
    ["-H", "%s=%s" % (constants.HV_KERNEL_PATH, test_kernel)],
281
    ["-H", "%s=%s" % (constants.HV_KERNEL_PATH, constants.VALUE_DEFAULT)],
282
    ["-H", "%s=%s" % (constants.HV_INITRD_PATH, test_initrd)],
283
    ["-H", "no_%s" % (constants.HV_INITRD_PATH, )],
284
    ["-H", "%s=%s" % (constants.HV_INITRD_PATH, constants.VALUE_DEFAULT)],
285

    
286
    # TODO: bridge tests
287
    #["--bridge", "xen-br1"],
288
    #["--bridge", orig_bridge],
289

    
290
    # TODO: Do these tests only with xen-hvm
291
    #["-H", "%s=acn" % constants.HV_BOOT_ORDER],
292
    #["-H", "%s=%s" % (constants.HV_BOOT_ORDER, constants.VALUE_DEFAULT)],
293
    ]
294
  for alist in args:
295
    AssertCommand(["gnt-instance", "modify"] + alist + [instance["name"]])
296

    
297
  # check no-modify
298
  AssertCommand(["gnt-instance", "modify", instance["name"]], fail=True)
299

    
300
  # Marking offline/online while instance is running must fail
301
  for arg in ["--online", "--offline"]:
302
    AssertCommand(["gnt-instance", "modify", arg, instance["name"]], fail=True)
303

    
304

    
305
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
306
def TestInstanceStoppedModify(instance):
307
  """gnt-instance modify (stopped instance)"""
308
  name = instance["name"]
309

    
310
  # Instance was not marked offline; try marking it online once more
311
  AssertCommand(["gnt-instance", "modify", "--online", name])
312

    
313
  # Mark instance as offline
314
  AssertCommand(["gnt-instance", "modify", "--offline", name])
315

    
316
  # And online again
317
  AssertCommand(["gnt-instance", "modify", "--online", name])
318

    
319

    
320
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
321
def TestInstanceConvertDisk(instance, snode):
322
  """gnt-instance modify -t"""
323
  name = instance["name"]
324
  AssertCommand(["gnt-instance", "modify", "-t", "plain", name])
325
  AssertCommand(["gnt-instance", "modify", "-t", "drbd",
326
                 "-n", snode["primary"], name])
327

    
328

    
329
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
330
def TestInstanceGrowDisk(instance):
331
  """gnt-instance grow-disk"""
332
  name = instance["name"]
333
  all_size = qa_config.get("disk")
334
  all_grow = qa_config.get("disk-growth")
335
  if not all_grow:
336
    # missing disk sizes but instance grow disk has been enabled,
337
    # let's set fixed/nomimal growth
338
    all_grow = ["128M" for _ in all_size]
339
  for idx, (size, grow) in enumerate(zip(all_size, all_grow)):
340
    # succeed in grow by amount
341
    AssertCommand(["gnt-instance", "grow-disk", name, str(idx), grow])
342
    # fail in grow to the old size
343
    AssertCommand(["gnt-instance", "grow-disk", "--absolute", name, str(idx),
344
                   size], fail=True)
345
    # succeed to grow to old size + 2 * growth
346
    int_size = utils.ParseUnit(size)
347
    int_grow = utils.ParseUnit(grow)
348
    AssertCommand(["gnt-instance", "grow-disk", "--absolute", name, str(idx),
349
                   str(int_size + 2 * int_grow)])
350

    
351

    
352
def TestInstanceList():
353
  """gnt-instance list"""
354
  qa_utils.GenericQueryTest("gnt-instance", query.INSTANCE_FIELDS.keys())
355

    
356

    
357
def TestInstanceListFields():
358
  """gnt-instance list-fields"""
359
  qa_utils.GenericQueryFieldsTest("gnt-instance", query.INSTANCE_FIELDS.keys())
360

    
361

    
362
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
363
def TestInstanceConsole(instance):
364
  """gnt-instance console"""
365
  AssertCommand(["gnt-instance", "console", "--show-cmd", instance["name"]])
366

    
367

    
368
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
369
def TestReplaceDisks(instance, pnode, snode, othernode):
370
  """gnt-instance replace-disks"""
371
  # pylint: disable=W0613
372
  # due to unused pnode arg
373
  # FIXME: should be removed from the function completely
374
  def buildcmd(args):
375
    cmd = ["gnt-instance", "replace-disks"]
376
    cmd.extend(args)
377
    cmd.append(instance["name"])
378
    return cmd
379

    
380
  for data in [
381
    ["-p"],
382
    ["-s"],
383
    ["--new-secondary=%s" % othernode["primary"]],
384
    # and restore
385
    ["--new-secondary=%s" % snode["primary"]],
386
    ]:
387
    AssertCommand(buildcmd(data))
388

    
389
  AssertCommand(buildcmd(["-a"]))
390
  AssertCommand(["gnt-instance", "stop", instance["name"]])
391
  AssertCommand(buildcmd(["-a"]), fail=True)
392
  AssertCommand(["gnt-instance", "activate-disks", instance["name"]])
393
  AssertCommand(buildcmd(["-a"]))
394
  AssertCommand(["gnt-instance", "start", instance["name"]])
395

    
396

    
397
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
398
def TestInstanceExport(instance, node):
399
  """gnt-backup export -n ..."""
400
  name = instance["name"]
401
  AssertCommand(["gnt-backup", "export", "-n", node["primary"], name])
402
  return qa_utils.ResolveInstanceName(name)
403

    
404

    
405
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
406
def TestInstanceExportWithRemove(instance, node):
407
  """gnt-backup export --remove-instance"""
408
  AssertCommand(["gnt-backup", "export", "-n", node["primary"],
409
                 "--remove-instance", instance["name"]])
410

    
411

    
412
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
413
def TestInstanceExportNoTarget(instance):
414
  """gnt-backup export (without target node, should fail)"""
415
  AssertCommand(["gnt-backup", "export", instance["name"]], fail=True)
416

    
417

    
418
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
419
def TestInstanceImport(newinst, node, expnode, name):
420
  """gnt-backup import"""
421
  cmd = (["gnt-backup", "import",
422
          "--disk-template=plain",
423
          "--no-ip-check",
424
          "--src-node=%s" % expnode["primary"],
425
          "--src-dir=%s/%s" % (constants.EXPORT_DIR, name),
426
          "--node=%s" % node["primary"]] +
427
         _GetGenericAddParameters(newinst, force_mac=constants.VALUE_GENERATE))
428
  cmd.append(newinst["name"])
429
  AssertCommand(cmd)
430

    
431

    
432
def TestBackupList(expnode):
433
  """gnt-backup list"""
434
  AssertCommand(["gnt-backup", "list", "--node=%s" % expnode["primary"]])
435

    
436
  qa_utils.GenericQueryTest("gnt-backup", query.EXPORT_FIELDS.keys(),
437
                            namefield=None, test_unknown=False)
438

    
439

    
440
def TestBackupListFields():
441
  """gnt-backup list-fields"""
442
  qa_utils.GenericQueryFieldsTest("gnt-backup", query.EXPORT_FIELDS.keys())
443

    
444

    
445
def _TestInstanceDiskFailure(instance, node, node2, onmaster):
446
  """Testing disk failure."""
447
  master = qa_config.GetMasterNode()
448
  sq = utils.ShellQuoteArgs
449

    
450
  instance_full = qa_utils.ResolveInstanceName(instance["name"])
451
  node_full = qa_utils.ResolveNodeName(node)
452
  node2_full = qa_utils.ResolveNodeName(node2)
453

    
454
  print qa_utils.FormatInfo("Getting physical disk names")
455
  cmd = ["gnt-node", "volumes", "--separator=|", "--no-headers",
456
         "--output=node,phys,instance",
457
         node["primary"], node2["primary"]]
458
  output = qa_utils.GetCommandOutput(master["primary"], sq(cmd))
459

    
460
  # Get physical disk names
461
  re_disk = re.compile(r"^/dev/([a-z]+)\d+$")
462
  node2disk = {}
463
  for line in output.splitlines():
464
    (node_name, phys, inst) = line.split("|")
465
    if inst == instance_full:
466
      if node_name not in node2disk:
467
        node2disk[node_name] = []
468

    
469
      m = re_disk.match(phys)
470
      if not m:
471
        raise qa_error.Error("Unknown disk name format: %s" % phys)
472

    
473
      name = m.group(1)
474
      if name not in node2disk[node_name]:
475
        node2disk[node_name].append(name)
476

    
477
  if [node2_full, node_full][int(onmaster)] not in node2disk:
478
    raise qa_error.Error("Couldn't find physical disks used on"
479
                         " %s node" % ["secondary", "master"][int(onmaster)])
480

    
481
  print qa_utils.FormatInfo("Checking whether nodes have ability to stop"
482
                            " disks")
483
  for node_name, disks in node2disk.iteritems():
484
    cmds = []
485
    for disk in disks:
486
      cmds.append(sq(["test", "-f", _GetDiskStatePath(disk)]))
487
    AssertCommand(" && ".join(cmds), node=node_name)
488

    
489
  print qa_utils.FormatInfo("Getting device paths")
490
  cmd = ["gnt-instance", "activate-disks", instance["name"]]
491
  output = qa_utils.GetCommandOutput(master["primary"], sq(cmd))
492
  devpath = []
493
  for line in output.splitlines():
494
    (_, _, tmpdevpath) = line.split(":")
495
    devpath.append(tmpdevpath)
496
  print devpath
497

    
498
  print qa_utils.FormatInfo("Getting drbd device paths")
499
  cmd = ["gnt-instance", "info", instance["name"]]
500
  output = qa_utils.GetCommandOutput(master["primary"], sq(cmd))
501
  pattern = (r"\s+-\s+sd[a-z]+,\s+type:\s+drbd8?,\s+.*$"
502
             r"\s+primary:\s+(/dev/drbd\d+)\s+")
503
  drbddevs = re.findall(pattern, output, re.M)
504
  print drbddevs
505

    
506
  halted_disks = []
507
  try:
508
    print qa_utils.FormatInfo("Deactivating disks")
509
    cmds = []
510
    for name in node2disk[[node2_full, node_full][int(onmaster)]]:
511
      halted_disks.append(name)
512
      cmds.append(sq(["echo", "offline"]) + " >%s" % _GetDiskStatePath(name))
513
    AssertCommand(" && ".join(cmds), node=[node2, node][int(onmaster)])
514

    
515
    print qa_utils.FormatInfo("Write to disks and give some time to notice"
516
                              " to notice the problem")
517
    cmds = []
518
    for disk in devpath:
519
      cmds.append(sq(["dd", "count=1", "bs=512", "conv=notrunc",
520
                      "if=%s" % disk, "of=%s" % disk]))
521
    for _ in (0, 1, 2):
522
      AssertCommand(" && ".join(cmds), node=node)
523
      time.sleep(3)
524

    
525
    print qa_utils.FormatInfo("Debugging info")
526
    for name in drbddevs:
527
      AssertCommand(["drbdsetup", name, "show"], node=node)
528

    
529
    AssertCommand(["gnt-instance", "info", instance["name"]])
530

    
531
  finally:
532
    print qa_utils.FormatInfo("Activating disks again")
533
    cmds = []
534
    for name in halted_disks:
535
      cmds.append(sq(["echo", "running"]) + " >%s" % _GetDiskStatePath(name))
536
    AssertCommand("; ".join(cmds), node=[node2, node][int(onmaster)])
537

    
538
  if onmaster:
539
    for name in drbddevs:
540
      AssertCommand(["drbdsetup", name, "detach"], node=node)
541
  else:
542
    for name in drbddevs:
543
      AssertCommand(["drbdsetup", name, "disconnect"], node=node2)
544

    
545
  # TODO
546
  #AssertCommand(["vgs"], [node2, node][int(onmaster)])
547

    
548
  print qa_utils.FormatInfo("Making sure disks are up again")
549
  AssertCommand(["gnt-instance", "replace-disks", instance["name"]])
550

    
551
  print qa_utils.FormatInfo("Restarting instance")
552
  AssertCommand(["gnt-instance", "shutdown", instance["name"]])
553
  AssertCommand(["gnt-instance", "startup", instance["name"]])
554

    
555
  AssertCommand(["gnt-cluster", "verify"])
556

    
557

    
558
def TestInstanceMasterDiskFailure(instance, node, node2):
559
  """Testing disk failure on master node."""
560
  # pylint: disable=W0613
561
  # due to unused args
562
  print qa_utils.FormatError("Disk failure on primary node cannot be"
563
                             " tested due to potential crashes.")
564
  # The following can cause crashes, thus it's disabled until fixed
565
  #return _TestInstanceDiskFailure(instance, node, node2, True)
566

    
567

    
568
def TestInstanceSecondaryDiskFailure(instance, node, node2):
569
  """Testing disk failure on secondary node."""
570
  return _TestInstanceDiskFailure(instance, node, node2, False)