Exemplo n.º 1
0
def test_lv_reload_for_stale_vg(fake_devices, no_delay):
    fake_runner = FakeRunner()
    lc = lvm.LVMCache(fake_runner, cache_lvs=True)

    assert lc._lvs_needs_reload("vg")

    # getLv call should call reload lvs.
    lc.getLv("vg")
    assert not lc._lvs_needs_reload("vg")
Exemplo n.º 2
0
def test_suppress_warnings(fake_devices, fake_runner):
    fake_runner.err = [
        b"  before",
        b"  WARNING: This metadata update is NOT backed up.",
        b"  after",
    ]
    lc = lvm.LVMCache()
    rc, out, err = lc.cmd(["fake"])
    assert rc == 0
    assert err == [b"  before", b"  after"]
Exemplo n.º 3
0
def test_build_command_read_only(fake_devices):
    # When cache in read-write mode, use locking_type=1
    lc = lvm.LVMCache()
    cmd = lc._addExtraCfg(["lvs", "-o", "+tags"])
    assert " locking_type=1 " in cmd[3]

    # When cache in read-only mode, use locking_type=4
    lc.set_read_only(True)
    cmd = lc._addExtraCfg(["lvs", "-o", "+tags"])
    assert " locking_type=4 " in cmd[3]
Exemplo n.º 4
0
def test_cmd_read_only_max_retries(fake_devices, fake_runner):
    lc = lvm.LVMCache()
    lc.set_read_only(True)

    # Require max retries to succeed.
    fake_runner.retries = lc.READ_ONLY_RETRIES
    rc, out, err = lc.cmd(["fake"])

    # Call should succeed (1 call + max retries).
    assert rc == 0
    assert len(fake_runner.calls) == lc.READ_ONLY_RETRIES + 1
    assert len(set(repr(c) for c in fake_runner.calls)) == 1
Exemplo n.º 5
0
def test_suppress_warnings(fake_devices, fake_runner):
    fake_runner.err = [
        b"  before",
        b"  WARNING: This metadata update is NOT backed up.",
        b"  WARNING: Combining activation change with other commands is "
        b"not advised.",
        b"  after",
    ]
    lc = lvm.LVMCache()
    rc, out, err = lc.cmd(["fake"])
    assert rc == 0
    assert err == [b"  before", b"  after"]
Exemplo n.º 6
0
def test_suppress_warnings(fake_devices, no_delay):
    fake_runner = FakeRunner()
    fake_runner.err = b"""\
  before
  WARNING: This metadata update is NOT backed up.
  WARNING: Combining activation change with other commands is not advised.
  after"""

    lc = lvm.LVMCache(fake_runner)
    rc, out, err = lc.cmd(["fake"])
    assert rc == 0
    assert err == [u"  before", u"  after"]
Exemplo n.º 7
0
def test_lv_reload_error_one(fake_devices, no_delay):
    fake_runner = FakeRunner(rc=5, err=b"Fake lvm error")
    lc = lvm.LVMCache(fake_runner)

    other_lv = make_lv("other-lv", "vg-name")
    lc._lvs = {("vg-name", "other-lv"): other_lv}

    # Should raise, but currently return None.
    assert lc.getLv("vg-name", "lv-name") is None

    # Other lv is not affected since it was not a stale.
    assert lc._lvs == {("vg-name", "other-lv"): other_lv}
Exemplo n.º 8
0
def test_lv_reload_error_all_stale_other_vgs(fake_devices, no_delay):
    fake_runner = FakeRunner(rc=5, err=b"Fake lvm error")
    lc = lvm.LVMCache(fake_runner)
    lc._lvs = {
        ("vg-name", "lv-name"): lvm.Stale("lv-name"),
        ("other-vg", "other-lv"): lvm.Stale("other-lv"),
    }
    lc.getLv("vg-name")

    # Should not affect other vg lvs.
    other_lv = lc._lvs[("other-vg", "other-lv")]
    assert not isinstance(other_lv, lvm.Unreadable)
Exemplo n.º 9
0
def test_rebuild_filter_after_invaliation(fake_devices):
    # Check that adding a device and invalidating the filter rebuilds the
    # config with the correct filter.
    lc = lvm.LVMCache()
    lc._addExtraCfg(["lvs"])

    fake_devices.append("/dev/mapper/c")
    lc.invalidateFilter()

    cmd = lc._addExtraCfg(["lvs"])
    assert cmd[3] == lvm._buildConfig(
        dev_filter=lvm._buildFilter(fake_devices), locking_type="1")
Exemplo n.º 10
0
def test_lv_reload_error_all_other_vg(fake_devices, no_delay):
    fake_runner = FakeRunner(rc=5, err=b"Fake lvm error")
    lc = lvm.LVMCache(fake_runner)
    lc._lvs = {("vg-name", "lv-name"): lvm.Stale("lv-name")}
    lvs = lc.getLv("vg-name")

    # Mark lv as unreadable.
    assert lc._lvs == {("vg-name", "lv-name"): lvm.Unreadable("lv-name")}

    # Currnetly we don't report stales or unreadables lvs. This is not
    # consistent with getLv(vg_name, lv_name).
    assert lvs == []
Exemplo n.º 11
0
def test_cmd_read_only_max_retries_fail(fake_devices, fake_runner):
    lc = lvm.LVMCache()
    lc.set_read_only(True)

    # Require max retries + 1 to succeed.
    fake_runner.retries = lc.READ_ONLY_RETRIES + 1

    rc, out, err = lc.cmd(["fake"])

    # Call should fail (1 call + max retries).
    assert rc == 1
    assert len(fake_runner.calls) == lc.READ_ONLY_RETRIES + 1
Exemplo n.º 12
0
def test_suppress_multiple_lvm_warnings(fake_devices, no_delay):
    fake_runner = FakeRunner()
    fake_runner.err = b"""\
  before
  Configuration setting "global/event_activation" unknown.
  Configuration setting "global/event_activation" unknown.
  Configuration setting "global/event_activation" unknown.
  after"""

    lc = lvm.LVMCache(fake_runner)
    rc, out, err = lc.cmd(["fake"])
    assert rc == 0
    assert err == [u"  before", u"  after"]
Exemplo n.º 13
0
def test_cmd_error(fake_devices, fake_runner):
    lc = lvm.LVMCache()

    # Require 2 calls to succeed.
    assert lc.READ_ONLY_RETRIES > 1
    fake_runner.retries = 1

    # Since the filter is correct, the error should be propagated to the caller
    # after the first call.
    rc, out, err = lc.cmd(["lvs", "-o", "+tags"])

    assert rc == 1
    assert len(fake_runner.calls) == 1
Exemplo n.º 14
0
def test_suppress_multiple_lvm_warnings(fake_devices, no_delay):
    fake_runner = FakeRunner()
    fake_runner.err = b"""\
  before
  WARNING: This metadata update is NOT backed up.
  WARNING: This metadata update is NOT backed up.
  WARNING: This metadata update is NOT backed up.
  after"""

    lc = lvm.LVMCache(fake_runner)
    rc, out, err = lc.cmd(["fake"])
    assert rc == 0
    assert err == [u"  before", u"  after"]
Exemplo n.º 15
0
def test_cmd_read_only(fake_devices, fake_runner):
    lc = lvm.LVMCache()
    lc.set_read_only(True)

    # Require 3 calls to succeed.
    assert lc.READ_ONLY_RETRIES > 2
    fake_runner.retries = 2

    rc, out, err = lc.cmd(["fake"])

    # Call should succeed after 3 identical calls.
    assert rc == 0
    assert len(fake_runner.calls) == 3
    assert len(set(repr(c) for c in fake_runner.calls)) == 1
Exemplo n.º 16
0
def test_build_command_long_filter(fake_devices):
    # If the devices are not specified, include all devices reported by
    # multipath.
    lc = lvm.LVMCache()
    cmd = lc._addExtraCfg(["lvs", "-o", "+tags"])

    assert cmd == [
        constants.EXT_LVM,
        "lvs",
        "--config",
        lvm._buildConfig(
            dev_filter=lvm._buildFilter(fake_devices),
            locking_type="1"),
        "-o", "+tags",
    ]
Exemplo n.º 17
0
def test_cmd_read_only_filter_stale(fake_devices, fake_runner):
    # Make a call to load the cache.
    initial_devices = fake_devices[:]
    lc = lvm.LVMCache()
    lc.cmd(["fake"])
    del fake_runner.calls[:]

    # Add a new device to the system. This will makes the cached filter stale,
    # so the command will be retried with a new filter.
    fake_devices.append("/dev/mapper/c")

    # Require max retries + 1 calls to succeed.
    fake_runner.retries = lc.READ_ONLY_RETRIES + 1

    lc.set_read_only(True)
    rc, out, err = lc.cmd(["fake"])

    # Call should succeed after one call with stale filter, one call with wider
    # filter and max retries identical calls.
    assert rc == 0
    assert len(fake_runner.calls) == lc.READ_ONLY_RETRIES + 2

    # The first call used the stale cache filter.
    cmd, kwargs = fake_runner.calls[0]
    assert cmd == [
        constants.EXT_LVM,
        "fake",
        "--config",
        lvm._buildConfig(
            dev_filter=lvm._buildFilter(initial_devices),
            locking_type="4"),
    ]
    assert kwargs == {"sudo": True}

    # The seocnd call used a wider filter.
    cmd, kwargs = fake_runner.calls[1]
    assert cmd == [
        constants.EXT_LVM,
        "fake",
        "--config",
        lvm._buildConfig(
            dev_filter=lvm._buildFilter(fake_devices),
            locking_type="4"),
    ]
    assert kwargs == {"sudo": True}

    # And then indentical retries with the wider filter.
    assert len(set(repr(c) for c in fake_runner.calls[1:])) == 1
Exemplo n.º 18
0
def test_cmd_success(fake_devices, no_delay):
    fake_runner = FakeRunner()
    lc = lvm.LVMCache(fake_runner)
    rc, out, err = lc.cmd(["lvs", "-o", "+tags"])

    assert rc == 0
    assert len(fake_runner.calls) == 1

    cmd = fake_runner.calls[0]
    assert cmd == [
        constants.EXT_LVM,
        "lvs",
        "--config",
        lvm._buildConfig(
            dev_filter=lvm._buildFilter(fake_devices),
            locking_type="1"),
        "-o", "+tags",
    ]
Exemplo n.º 19
0
def test_lv_reload_error_one_stale(fake_devices, no_delay):
    fake_runner = FakeRunner(rc=5, err=b"Fake lvm error")
    lc = lvm.LVMCache(fake_runner)
    lc._lvs = {
        ("vg-name", "lv-name"): lvm.Stale("lv-name"),
        ("vg-name", "other-lv"): lvm.Stale("other-lv"),
    }
    lv = lc.getLv("vg-name", "lv-name")

    # Mark lv as unreadable. Because we always reload all lvs, the other lvs is
    # also marked as unreadable.
    assert lc._lvs == {
        ("vg-name", "lv-name"): lvm.Unreadable("lv-name"),
        ("vg-name", "other-lv"): lvm.Unreadable("other-lv"),
    }

    # Report the unreadbale lv.
    assert lv.name == "lv-name"
    assert isinstance(lv, lvm.Unreadable)
Exemplo n.º 20
0
def test_cmd_retry_filter_stale(fake_devices, fake_runner):
    # Make a call to load the cache.
    initial_devices = fake_devices[:]
    lc = lvm.LVMCache()
    lc.cmd(["fake"])
    del fake_runner.calls[:]

    # Add a new device to the system. This will makes the cached filter stale,
    # so the command will be retried with a new filter.
    fake_devices.append("/dev/mapper/c")

    # Require 2 calls to succeed.
    assert lc.READ_ONLY_RETRIES > 1
    fake_runner.retries = 1

    rc, out, err = lc.cmd(["fake"])

    assert rc == 0
    assert len(fake_runner.calls) == 2

    # The first call used the stale cache filter.
    cmd, kwargs = fake_runner.calls[0]
    assert cmd == [
        constants.EXT_LVM,
        "fake",
        "--config",
        lvm._buildConfig(
            dev_filter=lvm._buildFilter(initial_devices),
            locking_type="1"),
    ]
    assert kwargs == {"sudo": True}

    # The seocnd call used a wider filter.
    cmd, kwargs = fake_runner.calls[1]
    assert cmd == [
        constants.EXT_LVM,
        "fake",
        "--config",
        lvm._buildConfig(
            dev_filter=lvm._buildFilter(fake_devices),
            locking_type="1"),
    ]
    assert kwargs == {"sudo": True}
Exemplo n.º 21
0
def test_cmd_success(fake_devices, fake_runner):
    lc = lvm.LVMCache()
    rc, out, err = lc.cmd(["lvs", "-o", "+tags"])

    assert rc == 0
    assert len(fake_runner.calls) == 1

    cmd, kwargs = fake_runner.calls[0]
    assert cmd == [
        constants.EXT_LVM,
        "lvs",
        "--config",
        lvm._buildConfig(
            dev_filter=lvm._buildFilter(fake_devices),
            locking_type="1"),
        "-o", "+tags",
    ]

    assert kwargs == {"sudo": True}
Exemplo n.º 22
0
def test_cmd_read_only_filter_stale_fail(fake_devices, fake_runner):
    # Make a call to load the cache.
    lc = lvm.LVMCache()
    lc.cmd(["fake"])
    del fake_runner.calls[:]

    # Add a new device to the system. This will makes the cached filter stale,
    # so the command will be retried with a new filter.
    fake_devices.append("/dev/mapper/c")

    # Require max retries + 2 calls to succeed.
    fake_runner.retries = lc.READ_ONLY_RETRIES + 2

    lc.set_read_only(True)
    rc, out, err = lc.cmd(["fake"])

    # Call should fail after max retries + 2 calls.
    assert rc == 1
    assert len(fake_runner.calls) == lc.READ_ONLY_RETRIES + 2
Exemplo n.º 23
0
def test_change_read_only_mode(fake_devices, no_delay, workers):
    # Test that changing read only wait for running commands, and new commands
    # wait for the read only change.
    fake_runner = FakeRunner()
    lc = lvm.LVMCache(fake_runner)

    def run_after(delay, func, *args):
        time.sleep(delay)
        func(*args)

    fake_runner.delay = 0.3
    start = time.time()
    try:
        # Start few commands in read-write mode.
        for i in range(2):
            workers.start_thread(run_after, 0.0, lc.cmd, ["read-write"])

        # After 0.1 seconds change read only mode to True. Should wait for the
        # running commands before changing the mode.
        workers.start_thread(run_after, 0.1, lc.set_read_only, True)

        # After 0.2 seconds, start new commands. Should wait until the mode is
        # changed and run in read-only mode.
        for i in range(2):
            workers.start_thread(run_after, 0.2, lc.cmd, ["read-only"])
    finally:
        workers.join()

    elapsed = time.time() - start

    assert len(fake_runner.calls) == 4

    # The first 2 commands should run in read-write mode.
    for cmd in fake_runner.calls[:2]:
        assert " locking_type=1 " in cmd[3]

    # The last 2 command should run in not read-only mode.
    for cmd in fake_runner.calls[2:]:
        assert " locking_type=4 " in cmd[3]

    # The last 2 command can start only after the first 2 command finished.
    assert elapsed > fake_runner.delay * 2
Exemplo n.º 24
0
def test_command_concurrency(fake_devices, fake_runner, workers, read_only):
    # Test concurrent commands to reveal locking issues.
    lc = lvm.LVMCache()
    lc.set_read_only(read_only)

    fake_runner.delay = 0.2
    count = 50
    start = time.time()
    try:
        for i in range(count):
            workers.start_thread(lc.cmd, ["fake", i])
    finally:
        workers.join()

    elapsed = time.time() - start
    assert len(fake_runner.calls) == count

    # This takes about 1 second on my idle laptop. Add more time to avoid
    # failures on overloaded slave.
    assert elapsed < fake_runner.delay * count / lc.MAX_COMMANDS + 1.0
Exemplo n.º 25
0
def test_suppress_warnings(fake_devices, no_delay):
    fake_runner = FakeRunner()
    fake_runner.err = b"""\
  before
  WARNING: This metadata update is NOT backed up.
  WARNING: Combining activation change with other commands is not advised.
  Configuration setting "global/event_activation" unknown.
  WARNING: ignoring metadata seqno 1566 on /dev/mapper/3600a098038304437415d4b6a59684474 for seqno 1567 on /dev/mapper/3600a098038304437415d4b6a59684474 for VG Bug."
  WARNING: Inconsistent metadata found for VG Bug."
  after"""  # NOQA: E501 (potentially long line)

    lc = lvm.LVMCache(fake_runner)
    rc, out, err = lc.cmd(["fake"])
    assert rc == 0
    assert err == [
        u"  before",
        (u"  WARNING: Combining activation change with other commands is "
         "not advised."),
        u"  Configuration setting \"global/event_activation\" unknown.",
        u"  after"
    ]
Exemplo n.º 26
0
def test_lv_reload_fresh_vg(fake_devices, no_delay):
    fake_runner = FakeRunner()
    lc = lvm.LVMCache(fake_runner, cache_lvs=True)
    lv1 = make_lv("lv1", "vg1")

    # vg1's lvs are fresh, vg2's lvs were invalidated.
    lc._freshlv = {"vg1", "vg2"}
    lc._lvs = {
        ("vg1", "lv1"): lv1,
        ("vg2", "lv2"): lvm.Stale("lv2"),
    }

    assert not lc._lvs_needs_reload("vg1")
    assert lc._lvs_needs_reload("vg2")

    # getLv for vg1 should use cache without reload lvs.
    assert lc.getLv("vg1") == [lv1]
    assert not lc._lvs_needs_reload("vg1")
    assert lc._lvs_needs_reload("vg2")

    # getLv for vg2 should reload lvs.
    assert lc.getLv("vg2") == []
    assert not lc._lvs_needs_reload("vg1")
    assert not lc._lvs_needs_reload("vg2")
Exemplo n.º 27
0
def test_lv_reload_error_all(fake_devices, no_delay):
    fake_runner = FakeRunner(rc=5, err=b"Fake lvm error")
    lc = lvm.LVMCache(fake_runner)
    assert lc.getLv("vg-name") == []