Example #1
0
def test_volume_info_all(tmp_db):
    expected = [{
        "vol_id": "vol-id-1",
        "connection_info": {
            "connection": 1
        }
    }, {
        "vol_id": "vol-id-2",
        "exists": False,
        "connection_info": {
            "connection": 2
        },
        "path": "/dev/mapper/fakemultipathid",
        "attachment": {
            "attachment": 2
        }
    }]

    db = managedvolumedb.open()
    with closing(db):
        for vol in expected:
            db.add_volume(vol["vol_id"], vol["connection_info"])
            if "path" in vol:
                db.update_volume(vol["vol_id"], vol["path"], vol["attachment"],
                                 "fakemultipathid")

    assert expected == managedvolume.volumes_info()["result"]
Example #2
0
def attach_volume(vol_id, connection_info):
    """
    Attach volume with os-brick.
    """
    if os_brick is None:
        raise se.ManagedVolumeNotSupported("Cannot import os_brick.initiator")

    db = managedvolumedb.open()
    with closing(db):
        _add_volume(db, vol_id, connection_info)

        log.debug("Starting attach volume %s connection_info=%s", vol_id,
                  connection_info)

        try:
            attachment = run_helper("attach", connection_info)
            try:
                path = _resolve_path(vol_id, connection_info, attachment)
                db.update_volume(vol_id,
                                 path=path,
                                 attachment=attachment,
                                 multipath_id=attachment.get("multipath_id"))
                _invalidate_lvm_filter(attachment)
            except:
                _silent_detach(connection_info, attachment)
                raise
        except:
            _silent_remove(db, vol_id)
            raise

    log.debug("Attached volume %s attachment=%s", vol_id, attachment)

    return {"result": {'attachment': attachment, 'path': path}}
Example #3
0
def test_get_volumes_by_id(tmp_db):
    vol1 = {"vol_id": "vol-id-1", "connection_info": {"connection": 1}}
    vol2 = {
        "vol_id": "vol-id-2",
        "connection_info": {
            "connection": 2
        },
        "path": "/dev/mapper/36001405376e34ea70384de7a34a2854d",
        "attachment": {
            "attachment": 2
        },
        "multipath_id": "36001405376e34ea70384de7a34a2854d"
    }
    vol3 = {"vol_id": "vol-id-3", "connection_info": {"connection": 3}}
    expected = [vol1, vol2, vol3]

    db = managedvolumedb.open()
    with closing(db):
        for vol in expected:
            db.add_volume(vol["vol_id"], vol["connection_info"])
            if "path" in vol:
                db.update_volume(vol["vol_id"], vol["path"], vol["attachment"],
                                 vol["multipath_id"])

        actual = list(db.iter_volumes(["vol-id-1", "vol-id-2", "vol-id-3"]))
        assert expected == actual

        actual = list(db.iter_volumes(["vol-id-1", "vol-id-3"]))
        assert [vol1, vol3] == actual
Example #4
0
def volumes_info(vol_ids=()):
    """
    Lookup volumes information in managed volume database.

    Lookup volumes info in managed volume database for all volume IDs in the
    vol_ids list and returns a list with volume information for each volume ID
    which is present in the database. Each record contains connection info.
    Path and attachment info of the volume is contained only when the resource
    is attached. Dictionary can also contain 'exists' item, which is set to
    True if the volume is connected and to False otherwise. Empty list is
    returned if any of IDs are not in the database.

    If the list of requested volume IDs is not specified or empty, list of all
    volumes info in the DB is returned.

    Arguments:
            vol_ids (list): list of queried volume IDs.

    Returns:
            List of managed volumes information.
    """
    db = managedvolumedb.open()
    with closing(db):
        result = []
        for vol_info in db.iter_volumes(vol_ids):
            if "path" in vol_info:
                vol_info["exists"] = os.path.exists(vol_info["path"])
            vol_info.pop("multipath_id", None)
            result.append(vol_info)

    return {"result": result}
Example #5
0
def attach_volume(vol_id, connection_info):
    """
    Attach volume with os-brick.
    """
    db = managedvolumedb.open()
    with closing(db):
        _add_volume(db, vol_id, connection_info)

        log.debug("Starting attach volume %s connection_info=%s",
                  vol_id, connection_info)

        try:
            attachment = run_helper("attach", connection_info)
            try:
                path = _resolve_path(vol_id, connection_info, attachment)
                db.update_volume(
                    vol_id,
                    path=path,
                    attachment=attachment,
                    multipath_id=attachment.get("multipath_id"))
                _invalidate_lvm_filter(attachment)
            except:
                _silent_detach(connection_info, attachment)
                raise
        except:
            _silent_remove(db, vol_id)
            raise

    log.debug("Attached volume %s attachment=%s", vol_id, attachment)

    return {"result": {'attachment': attachment, 'path': path,
                       'vol_id': vol_id}}
Example #6
0
def tmp_db(tmpdir, monkeypatch):
    db_file = str(tmpdir.join("managedvolumes.db"))
    monkeypatch.setattr(managedvolumedb, "DB_FILE", db_file)
    managedvolumedb.create_db()
    db = managedvolumedb.open()
    with closing(db):
        yield db
Example #7
0
def volumes_info(vol_ids=()):
    """
    Lookup volumes information in managed volume database.

    Lookup volumes info in managed volume database for all volume IDs in the
    vol_ids list and returns a list with volume information for each volume ID
    which is present in the database. Each record contains connection info.
    Path and attachment info of the volume is contained only when the resource
    is attached. Dictionary can also contain 'exists' item, which is set to
    True if the volume is connected and to False otherwise. Empty list is
    returned if any of IDs are not in the database.

    If the list of requested volume IDs is not specified or empty, list of all
    volumes info in the DB is returned.

    Arguments:
            vol_ids (list): list of queried volume IDs.

    Returns:
            List of managed volumes information.
    """
    db = managedvolumedb.open()
    with closing(db):
        result = []
        for vol_info in db.iter_volumes(vol_ids):
            if "path" in vol_info:
                vol_info["exists"] = os.path.exists(vol_info["path"])
            vol_info.pop("multipath_id", None)
            result.append(vol_info)

    return {"result": result}
Example #8
0
def tmp_db(tmpdir, monkeypatch):
    db_file = str(tmpdir.join("managedvolumes.db"))
    monkeypatch.setattr(managedvolumedb, "DB_FILE", db_file)
    managedvolumedb.create_db()
    db = managedvolumedb.open()
    with closing(db):
        yield db
Example #9
0
def test_create_db(db_path):
    managedvolumedb.create_db()
    # Now try some select from database. If we get NotFound, it means db file
    # and volumes db were created, which is what we want to test
    db = managedvolumedb.open()
    with closing(db):
        with pytest.raises(managedvolumedb.NotFound):
            db.get_volume("something")
Example #10
0
def test_close(tmp_db):
    db = managedvolumedb.open()
    db.close()

    # tests that the connection is really close and no other operations
    # can be execute
    with pytest.raises(managedvolumedb.Closed):
        db.get_volume("something")
Example #11
0
def test_create_db(db_path):
    managedvolumedb.create_db()
    # Now try some select from database. If we get NotFound, it means db file
    # and volumes db were created, which is what we want to test
    db = managedvolumedb.open()
    with closing(db):
        with pytest.raises(managedvolumedb.NotFound):
            db.get_volume("something")
Example #12
0
def test_close(tmp_db):
    db = managedvolumedb.open()
    db.close()

    # tests that the connection is really close and no other operations
    # can be execute
    with pytest.raises(managedvolumedb.Closed):
        db.get_volume("something")
Example #13
0
def test_lookup_benchmark(tmp_db):
    count = 500

    # Sort for fastest insertion.
    volumes = sorted((str(uuid.uuid4()), make_multipath_id())
                     for i in range(count))

    def iter_volumes():
        for vol_id, multipath_id in volumes:
            path = "/dev/mapper/" + multipath_id
            connection_info = json.dumps({"connection": vol_id})
            attachment = json.dumps({"attachment": multipath_id})
            yield vol_id, path, connection_info, attachment, multipath_id

    db = managedvolumedb.open()
    with closing(db):
        # Access db._conn directly for faster import with single transaction.
        insert_volume = """
            INSERT INTO volumes (
                vol_id,
                path,
                connection_info,
                attachment,
                multipath_id,
                updated
            )
            VALUES (
                ?, ?, ?, ?, ?, datetime("now")
            )
        """
        with db._conn:
            db._conn.executemany(insert_volume, iter_volumes())

    start = time.time()

    db = managedvolumedb.open()
    with closing(db):
        for _, multipath_id in volumes:
            db.owns_multipath(multipath_id)

    elapsed = time.time() - start

    print("Lookup %d multipath ids in %.6f seconds (%.6f seconds/op)"
          % (count, elapsed, elapsed / count))
Example #14
0
def test_lookup_benchmark(tmp_db):
    count = 500

    # Sort for fastest insertion.
    volumes = sorted(
        (str(uuid.uuid4()), make_multipath_id()) for i in range(count))

    def iter_volumes():
        for vol_id, multipath_id in volumes:
            path = "/dev/mapper/" + multipath_id
            connection_info = json.dumps({"connection": vol_id})
            attachment = json.dumps({"attachment": multipath_id})
            yield vol_id, path, connection_info, attachment, multipath_id

    db = managedvolumedb.open()
    with closing(db):
        # Access db._conn directly for faster import with single transaction.
        insert_volume = """
            INSERT INTO volumes (
                vol_id,
                path,
                connection_info,
                attachment,
                multipath_id,
                updated
            )
            VALUES (
                ?, ?, ?, ?, ?, datetime("now")
            )
        """
        with db._conn:
            db._conn.executemany(insert_volume, iter_volumes())

    start = time.time()

    db = managedvolumedb.open()
    with closing(db):
        for _, multipath_id in volumes:
            db.owns_multipath(multipath_id)

    elapsed = time.time() - start

    print("Lookup %d multipath ids in %.6f seconds (%.6f seconds/op)" %
          (count, elapsed, elapsed / count))
Example #15
0
def test_insert_select(tmp_db):
    db = managedvolumedb.open()
    with closing(db):
        connection_info = {"key": "value"}
        test_id = str(uuid.uuid4())

        db.add_volume(test_id, connection_info)
        res = db.get_volume(test_id)

        assert res == {"vol_id": test_id, "connection_info": connection_info}
Example #16
0
def test_insert_select(tmp_db):
    db = managedvolumedb.open()
    with closing(db):
        connection_info = {"key": "value"}
        test_id = str(uuid.uuid4())

        db.add_volume(test_id, connection_info)
        res = db.get_volume(test_id)

        assert res == {"vol_id": test_id, "connection_info": connection_info}
Example #17
0
def test_insert_existing(tmp_db):
    connection_info = {"key": "value"}
    test_id = str(uuid.uuid4())

    db = managedvolumedb.open()
    with closing(db):
        db.add_volume(test_id, connection_info)

        connection_info2 = {"key2": "value2"}
        with pytest.raises(managedvolumedb.VolumeAlreadyExists):
            db.add_volume(test_id, connection_info2)
Example #18
0
def _db_version_correct():
    db = mvdb.open()
    with closing(db):
        version = db.version_info()

    if mvdb.VERSION == version["version"]:
        return True
    else:
        sys.stdout.write("Database version (%s) is not the same as expected "
                         "one (%s)\n" % (version["version"], mvdb.VERSION))
        return False
Example #19
0
def test_insert_existing(tmp_db):
    connection_info = {"key": "value"}
    test_id = str(uuid.uuid4())

    db = managedvolumedb.open()
    with closing(db):
        db.add_volume(test_id, connection_info)

        connection_info2 = {"key2": "value2"}
        with pytest.raises(managedvolumedb.VolumeAlreadyExists):
            db.add_volume(test_id, connection_info2)
Example #20
0
def test_partial_iteration(tmp_db):
    db = managedvolumedb.open()
    with closing(db):
        db.add_volume("vol-1", {})
        db.add_volume("vol-2", {})

        # This triggers OperationalError if we use don't use fetchall() inside
        # iter_volumes().
        volumes1 = db.iter_volumes()
        next(volumes1)
        volumes2 = db.iter_volumes()
        next(volumes2)
        db.close()
Example #21
0
def test_partial_iteration(tmp_db):
    db = managedvolumedb.open()
    with closing(db):
        db.add_volume("vol-1", {})
        db.add_volume("vol-2", {})

        # This triggers OperationalError if we use don't use fetchall() inside
        # iter_volumes().
        volumes1 = db.iter_volumes()
        next(volumes1)
        volumes2 = db.iter_volumes()
        next(volumes2)
        db.close()
Example #22
0
def test_delete(tmp_db):
    connection_info = {"key": "value"}
    test_id = str(uuid.uuid4())

    db = managedvolumedb.open()
    with closing(db):
        db.add_volume(test_id, connection_info)
        res = db.get_volume(test_id)

        assert res["connection_info"]["key"] == "value"

        db.remove_volume(test_id)
        with pytest.raises(managedvolumedb.NotFound):
            db.get_volume(test_id)
Example #23
0
def test_version_info(db_path):
    # sqlite doesn't store microseconds, so any non-zero value here can fail
    # the test
    start = datetime.utcnow().replace(microsecond=0)

    managedvolumedb.create_db()
    db = managedvolumedb.open()
    with closing(db):
        curr_version = db.version_info()

    assert managedvolumedb.VERSION == curr_version["version"]
    assert "Initial version" == curr_version["description"]
    assert start <= datetime.strptime(curr_version["updated"],
                                      "%Y-%m-%d %H:%M:%S")
Example #24
0
def test_version_info(db_path):
    # sqlite doesn't store microseconds, so any non-zero value here can fail
    # the test
    start = datetime.utcnow().replace(microsecond=0)

    managedvolumedb.create_db()
    db = managedvolumedb.open()
    with closing(db):
        curr_version = db.version_info()

    assert managedvolumedb.VERSION == curr_version["version"]
    assert "Initial version" == curr_version["description"]
    assert start <= datetime.strptime(curr_version["updated"],
                                      "%Y-%m-%d %H:%M:%S")
Example #25
0
def test_delete(tmp_db):
    connection_info = {"key": "value"}
    test_id = str(uuid.uuid4())

    db = managedvolumedb.open()
    with closing(db):
        db.add_volume(test_id, connection_info)
        res = db.get_volume(test_id)

        assert res["connection_info"]["key"] == "value"

        db.remove_volume(test_id)
        with pytest.raises(managedvolumedb.NotFound):
            db.get_volume(test_id)
Example #26
0
def detach_volume(vol_id):
    """
    Detach volume with os-brick.
    """
    db = managedvolumedb.open()
    with closing(db):
        try:
            vol_info = db.get_volume(vol_id)
        except managedvolumedb.NotFound:
            return

        log.debug("Starting detach volume %s vol_info=%s", vol_id, vol_info)

        if "path" in vol_info and os.path.exists(vol_info["path"]):
            run_helper("detach", vol_info)

        db.remove_volume(vol_id)
Example #27
0
def detach_volume(vol_id):
    """
    Detach volume with os-brick.
    """
    db = managedvolumedb.open()
    with closing(db):
        try:
            vol_info = db.get_volume(vol_id)
        except managedvolumedb.NotFound:
            return

        log.debug("Starting detach volume %s vol_info=%s", vol_id, vol_info)

        if "path" in vol_info and os.path.exists(vol_info["path"]):
            run_helper("detach", vol_info)

        db.remove_volume(vol_id)
Example #28
0
def test_volume_info_all(tmp_db):
    expected = [{"vol_id": "vol-id-1",
                 "connection_info": {"connection": 1}},
                {"vol_id": "vol-id-2",
                 "exists": False,
                 "connection_info": {"connection": 2},
                 "path": "/dev/mapper/fakemultipathid",
                 "attachment": {"attachment": 2}}]

    db = managedvolumedb.open()
    with closing(db):
        for vol in expected:
            db.add_volume(vol["vol_id"], vol["connection_info"])
            if "path" in vol:
                db.update_volume(vol["vol_id"], vol["path"], vol["attachment"],
                                 "fakemultipathid")

    assert expected == managedvolume.volumes_info()["result"]
Example #29
0
def test_get_all_volumes(tmp_db):
    expected = [{"vol_id": "vol-id-1",
                 "connection_info": {"connection": 1}},
                {"vol_id": "vol-id-2",
                 "connection_info": {"connection": 2},
                 "path": "/dev/mapper/36001405376e34ea70384de7a34a2854d",
                 "attachment": {"attachment": 2},
                 "multipath_id": "36001405376e34ea70384de7a34a2854d"}]

    db = managedvolumedb.open()
    with closing(db):
        for vol in expected:
            db.add_volume(vol["vol_id"], vol["connection_info"])
            if "path" in vol:
                db.update_volume(vol["vol_id"], vol["path"], vol["attachment"],
                                 vol["multipath_id"])

        actual = list(db.iter_volumes())
        assert expected == actual
Example #30
0
def attach_volume(vol_id, connection_info):
    """
    Attach volume with os-brick.
    """
    db = managedvolumedb.open()
    with closing(db):
        _add_volume(db, vol_id, connection_info)

        log.debug("Starting attach volume %s connection_info=%s", vol_id,
                  connection_info)

        try:
            attachment = run_helper("attach", connection_info)
            try:
                path = _resolve_path(vol_id, connection_info, attachment)
                db.update_volume(vol_id,
                                 path=path,
                                 attachment=attachment,
                                 multipath_id=attachment.get("multipath_id"))
                _invalidate_lvm_filter(attachment)
                volume_type = connection_info["driver_volume_type"]
                if volume_type not in ("rbd", "iscsi"):
                    raise se.UnsupportedOperation(
                        "Unsupported volume type, supported types are: "
                        "rbd, iscsi")

                _add_udev_rule(vol_id, path)
            except:
                _silent_detach(connection_info, attachment)
                raise
        except:
            _silent_remove(db, vol_id)
            raise

    log.debug("Attached volume %s attachment=%s", vol_id, attachment)

    return {
        "result": {
            'attachment': attachment,
            'path': path,
            'vol_id': vol_id
        }
    }
Example #31
0
def test_update(tmp_db):
    connection_info = {"key": "value"}
    test_id = str(uuid.uuid4())

    db = managedvolumedb.open()
    with closing(db):
        db.add_volume(test_id, connection_info)

        path = "/dev/mapper/36001405376e34ea70384de7a34a2854d"
        multipath_id = "36001405376e34ea70384de7a34a2854d"
        attachment = {"attachment": 2}
        db.update_volume(test_id, path, attachment, multipath_id)
        res = db.get_volume(test_id)

        expected = {"vol_id": test_id,
                    "connection_info": connection_info,
                    "path": path,
                    "attachment": attachment,
                    "multipath_id": multipath_id}
        assert res == expected
Example #32
0
def detach_volume(vol_id):
    """
    Detach volume with os-brick.
    """
    if os_brick is None:
        raise se.ManagedVolumeNotSupported("Cannot import os_brick.initiator")

    db = managedvolumedb.open()
    with closing(db):
        try:
            vol_info = db.get_volume(vol_id)
        except managedvolumedb.NotFound:
            return

        log.debug("Starting detach volume %s vol_info=%s", vol_id, vol_info)

        if "path" in vol_info and os.path.exists(vol_info["path"]):
            run_helper("detach", vol_info)

        db.remove_volume(vol_id)
Example #33
0
def getMPDevsIter():
    """
    Collect the list of all the multipath block devices, except devices
    blacklisted in vdsm configuration, and devices owned by managed volumes.

    Return the list of device identifiers w/o "/dev/mapper" prefix
    """
    db = managedvolumedb.open()
    with closing(db):
        for dmInfoDir in glob(SYS_BLOCK + "/dm-*/dm/"):
            uuidFile = os.path.join(dmInfoDir, "uuid")
            try:
                with open(uuidFile, "r") as uf:
                    uuid = uf.read().strip()
            except (OSError, IOError):
                continue

            if not uuid.startswith("mpath-"):
                continue

            nameFile = os.path.join(dmInfoDir, "name")
            try:
                with open(nameFile, "r") as nf:
                    guid = nf.read().rstrip("\n")
            except (OSError, IOError):
                continue

            if guid in BLACKLIST:
                log.debug("Blacklisted device %r discarded", guid)
                continue

            if TOXIC_REGEX.match(guid):
                log.info("Device with unsupported GUID %s discarded", guid)
                continue

            if db.owns_multipath(guid):
                log.debug("Managed volume device %r discarded", guid)
                continue

            yield dmInfoDir.split("/")[3], guid
Example #34
0
    def run(worker_id):
        for i in range(iterations):
            vol_id = vol_id_tmp % (worker_id, i)

            db = managedvolumedb.open()
            with closing(db):
                # Simulate attach volume flow.

                db.add_volume(vol_id, {"connection": vol_id})

                # Switch to another thread. Real code will wait for os_brick
                # several seconds here.
                time.sleep(delay)

                db.update_volume(vol_id,
                                 path="/dev/mapper/" + vol_id,
                                 multipath_id=vol_id,
                                 attachment={"attachment": vol_id})

            # Switch to another thread. Real code will process another
            # unrelated request here.
            time.sleep(delay)
Example #35
0
def test_update(tmp_db):
    connection_info = {"key": "value"}
    test_id = str(uuid.uuid4())

    db = managedvolumedb.open()
    with closing(db):
        db.add_volume(test_id, connection_info)

        path = "/dev/mapper/36001405376e34ea70384de7a34a2854d"
        multipath_id = "36001405376e34ea70384de7a34a2854d"
        attachment = {"attachment": 2}
        db.update_volume(test_id, path, attachment, multipath_id)
        res = db.get_volume(test_id)

        expected = {
            "vol_id": test_id,
            "connection_info": connection_info,
            "path": path,
            "attachment": attachment,
            "multipath_id": multipath_id
        }
        assert res == expected
Example #36
0
def test_owns_multipath(tmp_db):
    vol_id = str(uuid.uuid4())
    connection_info = {"connection": 1}
    attachment = {"attachment": 2}
    path = "/dev/mapper/36001405376e34ea70384de7a34a2854d"
    multipath_id = "36001405376e34ea70384de7a34a2854d"

    db = managedvolumedb.open()
    with closing(db):
        # Empty db does not own any device.
        assert not db.owns_multipath(multipath_id)

        # Volume does not own (yet) multipath_id.
        db.add_volume(vol_id, connection_info)
        assert not db.owns_multipath(multipath_id)

        # Volume owns multipath_id.
        db.update_volume(vol_id, path, attachment, multipath_id)
        assert db.owns_multipath(multipath_id)

        # Nothing owns multipath_id now.
        db.remove_volume(vol_id)
        assert not db.owns_multipath(multipath_id)
Example #37
0
def test_owns_multipath(tmp_db):
    vol_id = str(uuid.uuid4())
    connection_info = {"connection": 1}
    attachment = {"attachment": 2}
    path = "/dev/mapper/36001405376e34ea70384de7a34a2854d"
    multipath_id = "36001405376e34ea70384de7a34a2854d"

    db = managedvolumedb.open()
    with closing(db):
        # Empty db does not own any device.
        assert not db.owns_multipath(multipath_id)

        # Volume does not own (yet) multipath_id.
        db.add_volume(vol_id, connection_info)
        assert not db.owns_multipath(multipath_id)

        # Volume owns multipath_id.
        db.update_volume(vol_id, path, attachment, multipath_id)
        assert db.owns_multipath(multipath_id)

        # Nothing owns multipath_id now.
        db.remove_volume(vol_id)
        assert not db.owns_multipath(multipath_id)
Example #38
0
    def run(worker_id):
        for i in range(iterations):
            vol_id = vol_id_tmp % (worker_id, i)

            db = managedvolumedb.open()
            with closing(db):
                # Simulate attach volume flow.

                db.add_volume(vol_id, {"connection": vol_id})

                # Switch to another thread. Real code will wait for os_brick
                # several seconds here.
                time.sleep(delay)

                db.update_volume(
                    vol_id,
                    path="/dev/mapper/" + vol_id,
                    multipath_id=vol_id,
                    attachment={"attachment": vol_id})

            # Switch to another thread. Real code will process another
            # unrelated request here.
            time.sleep(delay)
Example #39
0
def test_close_twice(tmp_db):
    db = managedvolumedb.open()
    db.close()
    # Closing twice does nothing.
    db.close()
Example #40
0
def test_close_twice(tmp_db):
    db = managedvolumedb.open()
    db.close()
    # Closing twice does nothing.
    db.close()
Example #41
0
def test_get_non_existing(tmp_db):
    db = managedvolumedb.open()
    with closing(db):
        with pytest.raises(managedvolumedb.NotFound):
            db.get_volume("this doesn't exists")
Example #42
0
def test_concurrency(tmp_db):

    concurrency = 10
    iterations = 10

    # Sleeping this interval is enough to switch to another thread most of the
    # time based on the test logs.
    delay = 0.005

    vol_id_tmp = "%06d-%06d"

    def run(worker_id):
        for i in range(iterations):
            vol_id = vol_id_tmp % (worker_id, i)

            db = managedvolumedb.open()
            with closing(db):
                # Simulate attach volume flow.

                db.add_volume(vol_id, {"connection": vol_id})

                # Switch to another thread. Real code will wait for os_brick
                # several seconds here.
                time.sleep(delay)

                db.update_volume(vol_id,
                                 path="/dev/mapper/" + vol_id,
                                 multipath_id=vol_id,
                                 attachment={"attachment": vol_id})

            # Switch to another thread. Real code will process another
            # unrelated request here.
            time.sleep(delay)

    start = time.time()

    workers = []
    try:
        for i in range(concurrency):
            t = concurrent.thread(run, args=(i, ))
            t.start()
            workers.append(t)
    finally:
        for t in workers:
            t.join()

    elapsed = time.time() - start

    volumes = concurrency * iterations
    print("Added %d volumes with %s concurrent threads in %.6f seconds "
          "(%.6f seconds/op)" %
          (volumes, concurrency, elapsed, elapsed / volumes))

    db = managedvolumedb.open()
    with closing(db):
        for i in range(concurrency):
            for j in range(iterations):
                vol_id = vol_id_tmp % (i, j)

                # Verify volume was added.
                vol_info = db.get_volume(vol_id)
                assert "connection_info" in vol_info

                # Verify volume was updated.
                assert "path" in vol_info
                assert "multipath_id" in vol_info
                assert "attachment" in vol_info
Example #43
0
def test_concurrency(tmp_db):

    concurrency = 10
    iterations = 10

    # Sleeping this interval is enough to switch to another thread most of the
    # time based on the test logs.
    delay = 0.005

    vol_id_tmp = "%06d-%06d"

    def run(worker_id):
        for i in range(iterations):
            vol_id = vol_id_tmp % (worker_id, i)

            db = managedvolumedb.open()
            with closing(db):
                # Simulate attach volume flow.

                db.add_volume(vol_id, {"connection": vol_id})

                # Switch to another thread. Real code will wait for os_brick
                # several seconds here.
                time.sleep(delay)

                db.update_volume(
                    vol_id,
                    path="/dev/mapper/" + vol_id,
                    multipath_id=vol_id,
                    attachment={"attachment": vol_id})

            # Switch to another thread. Real code will process another
            # unrelated request here.
            time.sleep(delay)

    start = time.time()

    workers = []
    try:
        for i in range(concurrency):
            t = concurrent.thread(run, args=(i,))
            t.start()
            workers.append(t)
    finally:
        for t in workers:
            t.join()

    elapsed = time.time() - start

    volumes = concurrency * iterations
    print("Added %d volumes with %s concurrent threads in %.6f seconds "
          "(%.6f seconds/op)"
          % (volumes, concurrency, elapsed, elapsed / volumes))

    db = managedvolumedb.open()
    with closing(db):
        for i in range(concurrency):
            for j in range(iterations):
                vol_id = vol_id_tmp % (i, j)

                # Verify volume was added.
                vol_info = db.get_volume(vol_id)
                assert "connection_info" in vol_info

                # Verify volume was updated.
                assert "path" in vol_info
                assert "multipath_id" in vol_info
                assert "attachment" in vol_info
Example #44
0
def test_get_non_existing(tmp_db):
    db = managedvolumedb.open()
    with closing(db):
        with pytest.raises(managedvolumedb.NotFound):
            db.get_volume("this doesn't exists")