]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: az: add archive zone tests 29359/head
authorJavier M. Mellid <jmunhoz@igalia.com>
Fri, 26 Jul 2019 15:33:03 +0000 (17:33 +0200)
committerJavier M. Mellid <jmunhoz@igalia.com>
Fri, 26 Jul 2019 15:53:20 +0000 (17:53 +0200)
Signed-off-by: Javier M. Mellid <jmunhoz@igalia.com>
src/test/rgw/rgw_multi/tests_az.py [new file with mode: 0644]
src/test/rgw/rgw_multi/zone_az.py [new file with mode: 0644]
src/test/rgw/test_multi.md
src/test/rgw/test_multi.py

diff --git a/src/test/rgw/rgw_multi/tests_az.py b/src/test/rgw/rgw_multi/tests_az.py
new file mode 100644 (file)
index 0000000..1a1434a
--- /dev/null
@@ -0,0 +1,597 @@
+import logging
+
+from nose import SkipTest
+from nose.tools import assert_not_equal, assert_equal
+
+from boto.s3.deletemarker import DeleteMarker
+
+from .tests import get_realm, \
+    ZonegroupConns, \
+    zonegroup_meta_checkpoint, \
+    zone_meta_checkpoint, \
+    zone_bucket_checkpoint, \
+    zone_data_checkpoint, \
+    zonegroup_bucket_checkpoint, \
+    check_bucket_eq, \
+    gen_bucket_name, \
+    get_user, \
+    get_tenant
+
+from .zone_az import print_connection_info
+
+
+# configure logging for the tests module
+log = logging.getLogger(__name__)
+
+
+##########################################
+# utility functions for archive zone tests
+##########################################
+
+def check_az_configured():
+    """check if at least one archive zone exist"""
+    realm = get_realm()
+    zonegroup = realm.master_zonegroup()
+
+    az_zones = zonegroup.zones_by_type.get("archive")
+    if az_zones is None or len(az_zones) != 1:
+        raise SkipTest("Requires one archive zone")
+
+
+def is_az_zone(zone_conn):
+    """check if a specific zone is archive zone"""
+    if not zone_conn:
+        return False
+    return zone_conn.zone.tier_type() == "archive"
+
+
+def init_env():
+    """initialize the environment"""
+    check_az_configured()
+
+    realm = get_realm()
+    zonegroup = realm.master_zonegroup()
+    zonegroup_conns = ZonegroupConns(zonegroup)
+
+    zonegroup_meta_checkpoint(zonegroup)
+
+    az_zones = []
+    zones = []
+    for conn in zonegroup_conns.zones:
+        if is_az_zone(conn):
+            zone_meta_checkpoint(conn.zone)
+            az_zones.append(conn)
+        elif not conn.zone.is_read_only():
+            zones.append(conn)
+
+    assert_not_equal(len(zones), 0)
+    assert_not_equal(len(az_zones), 0)
+    return zones, az_zones
+
+
+def zone_full_checkpoint(target_zone, source_zone):
+    zone_meta_checkpoint(target_zone)
+    zone_data_checkpoint(target_zone, source_zone)
+
+
+def check_bucket_exists_on_zone(zone, bucket_name):
+    try:
+        zone.conn.get_bucket(bucket_name)
+    except:
+        return False
+    return True
+
+
+def check_key_exists(key):
+    try:
+        key.get_contents_as_string()
+    except:
+        return False
+    return True
+
+
+def get_versioning_status(bucket):
+    res = bucket.get_versioning_status()
+    key = 'Versioning'
+    if not key in res:
+        return None
+    else:
+        return res[key]
+
+
+def get_versioned_objs(bucket):
+    b = []
+    for b_entry in bucket.list_versions():
+        if isinstance(b_entry, DeleteMarker):
+            continue
+        d = {}
+        d['version_id'] = b_entry.version_id
+        d['size'] = b_entry.size
+        d['etag'] = b_entry.etag
+        d['is_latest'] = b_entry.is_latest
+        b.append({b_entry.key:d})
+    return b
+
+
+def get_versioned_entries(bucket):
+    dm = []
+    ver = []
+    for b_entry in bucket.list_versions():
+        if isinstance(b_entry, DeleteMarker):
+            d = {}
+            d['version_id'] = b_entry.version_id
+            d['is_latest'] = b_entry.is_latest
+            dm.append({b_entry.name:d})
+        else:
+            d = {}
+            d['version_id'] = b_entry.version_id
+            d['size'] = b_entry.size
+            d['etag'] = b_entry.etag
+            d['is_latest'] = b_entry.is_latest
+            ver.append({b_entry.key:d})
+    return (dm, ver)
+
+
+def get_number_buckets_by_zone(zone):
+    return len(zone.conn.get_all_buckets())
+
+
+def get_bucket_names_by_zone(zone):
+    return [b.name for b in zone.conn.get_all_buckets()]
+
+
+def get_full_bucket_name(partial_bucket_name, bucket_names_az):
+    full_bucket_name = None
+    for bucket_name in bucket_names_az:
+        if bucket_name.startswith(partial_bucket_name):
+            full_bucket_name = bucket_name
+            break
+    return full_bucket_name
+
+
+####################
+# archive zone tests
+####################
+
+
+def test_az_info():
+    """ log information for manual testing """
+    return SkipTest("only used in manual testing")
+    zones, az_zones = init_env()
+    realm = get_realm()
+    zonegroup = realm.master_zonegroup()
+    bucket_name = gen_bucket_name()
+    # create bucket on the first of the rados zones
+    bucket = zones[0].create_bucket(bucket_name)
+    # create objects in the bucket
+    number_of_objects = 3
+    for i in range(number_of_objects):
+        key = bucket.new_key(str(i))
+        key.set_contents_from_string('bar')
+    print('Zonegroup: ' + zonegroup.name)
+    print('user: ' + get_user())
+    print('tenant: ' + get_tenant())
+    print('Master Zone')
+    print_connection_info(zones[0].conn)
+    print('Archive Zone')
+    print_connection_info(az_zones[0].conn)
+    print('Bucket: ' + bucket_name)
+
+
+def test_az_create_empty_bucket():
+     """ test empty bucket replication """
+     zones, az_zones = init_env()
+     bucket_name = gen_bucket_name()
+     # create bucket on the non archive zone
+     zones[0].create_bucket(bucket_name)
+     # sync
+     zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+     # bucket exist on the archive zone
+     p = check_bucket_exists_on_zone(az_zones[0], bucket_name)
+     assert_equal(p, True)
+
+
+def test_az_check_empty_bucket_versioning():
+     """ test bucket vesioning with empty bucket """
+     zones, az_zones = init_env()
+     bucket_name = gen_bucket_name()
+     # create bucket on the non archive zone
+     bucket = zones[0].create_bucket(bucket_name)
+     # sync
+     zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+     # get bucket on archive zone
+     bucket_az = az_zones[0].conn.get_bucket(bucket_name)
+     # check for non bucket versioning
+     p1 = get_versioning_status(bucket) is None
+     assert_equal(p1, True)
+     p2 = get_versioning_status(bucket_az) is None
+     assert_equal(p2, True)
+
+
+def test_az_object_replication():
+    """ test object replication """
+    zones, az_zones = init_env()
+    bucket_name = gen_bucket_name()
+    # create bucket on the non archive zone
+    bucket = zones[0].create_bucket(bucket_name)
+    key = bucket.new_key("foo")
+    key.set_contents_from_string("bar")
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check object on archive zone
+    bucket_az = az_zones[0].conn.get_bucket(bucket_name)
+    key_az = bucket_az.get_key("foo")
+    p1 = key_az.get_contents_as_string() == "bar"
+    assert_equal(p1, True)
+
+
+def test_az_object_replication_versioning():
+    """ test object replication versioning """
+    zones, az_zones = init_env()
+    bucket_name = gen_bucket_name()
+    # create object on the non archive zone
+    bucket = zones[0].create_bucket(bucket_name)
+    key = bucket.new_key("foo")
+    key.set_contents_from_string("bar")
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check object content on archive zone
+    bucket_az = az_zones[0].conn.get_bucket(bucket_name)
+    key_az = bucket_az.get_key("foo")
+    p1 = key_az.get_contents_as_string() == "bar"
+    assert_equal(p1, True)
+    # grab object versioning and etag
+    for b_version in bucket.list_versions():
+        b_version_id = b_version.version_id
+        b_version_etag = b_version.etag
+    for b_az_version in bucket_az.list_versions():
+        b_az_version_id = b_az_version.version_id
+        b_az_version_etag = b_az_version.etag
+    # check
+    p2 = b_version_id == 'null'
+    assert_equal(p2, True)
+    p3 = b_az_version_id != 'null'
+    assert_equal(p3, True)
+    p4 = b_version_etag == b_az_version_etag
+    assert_equal(p4, True)
+
+
+def test_az_lazy_activation_of_versioned_bucket():
+    """ test lazy activation of versioned bucket """
+    zones, az_zones = init_env()
+    bucket_name = gen_bucket_name()
+    # create object on the non archive zone
+    bucket = zones[0].create_bucket(bucket_name)
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # get bucket on archive zone
+    bucket_az = az_zones[0].conn.get_bucket(bucket_name)
+    # check for non bucket versioning
+    p1 = get_versioning_status(bucket) is None
+    assert_equal(p1, True)
+    p2 = get_versioning_status(bucket_az) is None
+    assert_equal(p2, True)
+    # create object on non archive zone
+    key = bucket.new_key("foo")
+    key.set_contents_from_string("bar")
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check lazy versioned buckets
+    p3 = get_versioning_status(bucket) is None
+    assert_equal(p3, True)
+    p4 = get_versioning_status(bucket_az) == 'Enabled'
+    assert_equal(p4, True)
+
+
+def test_az_archive_zone_double_object_replication_versioning():
+    """ test archive zone double object replication versioning """
+    zones, az_zones = init_env()
+    bucket_name = gen_bucket_name()
+    # create object on the non archive zone
+    bucket = zones[0].create_bucket(bucket_name)
+    key = bucket.new_key("foo")
+    key.set_contents_from_string("bar")
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # get bucket on archive zone
+    bucket_az = az_zones[0].conn.get_bucket(bucket_name)
+    # check for non bucket versioning
+    p1 = get_versioning_status(bucket) is None
+    assert_equal(p1, True)
+    p2 = get_versioning_status(bucket_az) == 'Enabled'
+    assert_equal(p2, True)
+    # overwrite object on non archive zone
+    key = bucket.new_key("foo")
+    key.set_contents_from_string("ouch")
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check lazy versioned buckets
+    p3 = get_versioning_status(bucket) is None
+    assert_equal(p3, True)
+    p4 = get_versioning_status(bucket_az) == 'Enabled'
+    assert_equal(p4, True)
+    # get versioned objects
+    objs = get_versioned_objs(bucket)
+    objs_az = get_versioned_objs(bucket_az)
+    # check version_id, size, and is_latest on non archive zone
+    p5 = objs[0]['foo']['version_id'] == 'null'
+    assert_equal(p5, True)
+    p6 = objs[0]['foo']['size'] == 4
+    assert_equal(p6, True)
+    p7 = objs[0]['foo']['is_latest'] == True
+    assert_equal(p7, True)
+    # check version_id, size, is_latest on archive zone
+    latest_obj_az_etag = None
+    for obj_az  in objs_az:
+        current_obj_az = obj_az['foo']
+        if current_obj_az['is_latest'] == True:
+            p8 = current_obj_az['size'] == 4
+            assert_equal(p8, True)
+            latest_obj_az_etag = current_obj_az['etag']
+        else:
+            p9 = current_obj_az['size'] == 3
+            assert_equal(p9, True)
+        assert_not_equal(current_obj_az['version_id'], 'null')
+    # check last versions' etags
+    p10 = objs[0]['foo']['etag'] == latest_obj_az_etag
+    assert_equal(p10, True)
+
+
+def test_az_deleted_object_replication():
+    """ test zone deleted object replication """
+    zones, az_zones = init_env()
+    bucket_name = gen_bucket_name()
+    # create object on the non archive zone
+    bucket = zones[0].create_bucket(bucket_name)
+    key = bucket.new_key("foo")
+    key.set_contents_from_string("bar")
+    p1 = key.get_contents_as_string() == "bar"
+    assert_equal(p1, True)
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # update object on non archive zone
+    key.set_contents_from_string("soup")
+    p2 = key.get_contents_as_string() == "soup"
+    assert_equal(p2, True)
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # delete object on non archive zone
+    key.delete()
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check object on non archive zone
+    p3 = check_key_exists(key) == False
+    assert_equal(p3, True)
+    # check objects on archive zone
+    bucket_az = az_zones[0].conn.get_bucket(bucket_name)
+    key_az = bucket_az.get_key("foo")
+    p4 = check_key_exists(key_az) == True
+    assert_equal(p4, True)
+    p5 = key_az.get_contents_as_string() == "soup"
+    assert_equal(p5, True)
+    b_ver_az = get_versioned_objs(bucket_az)
+    p6 = len(b_ver_az) == 2
+    assert_equal(p6, True)
+
+
+def test_az_bucket_renaming_on_empty_bucket_deletion():
+    """ test bucket renaming on empty bucket deletion """
+    zones, az_zones = init_env()
+    bucket_name = gen_bucket_name()
+    # grab number of buckets on non archive zone
+    num_buckets = get_number_buckets_by_zone(zones[0])
+    # grab number of buckets on archive zone
+    num_buckets_az = get_number_buckets_by_zone(az_zones[0])
+    # create bucket on non archive zone
+    bucket = zones[0].create_bucket(bucket_name)
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # delete bucket in non archive zone
+    zones[0].delete_bucket(bucket_name)
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check no new buckets on non archive zone
+    p1 = get_number_buckets_by_zone(zones[0]) == num_buckets
+    assert_equal(p1, True)
+    # check non deletion on bucket on archive zone
+    p2 = get_number_buckets_by_zone(az_zones[0]) == (num_buckets_az + 1)
+    assert_equal(p2, True)
+    # check bucket renaming
+    bucket_names_az = get_bucket_names_by_zone(az_zones[0])
+    new_bucket_name = bucket_name + '-deleted-'
+    p3 = any(bucket_name.startswith(new_bucket_name) for bucket_name in bucket_names_az)
+    assert_equal(p3, True)
+
+
+def test_az_old_object_version_in_archive_zone():
+    """ test old object version in archive zone """
+    zones, az_zones = init_env()
+    bucket_name = gen_bucket_name()
+    # grab number of buckets on non archive zone
+    num_buckets = get_number_buckets_by_zone(zones[0])
+    # grab number of buckets on archive zone
+    num_buckets_az = get_number_buckets_by_zone(az_zones[0])
+    # create bucket on non archive zone
+    bucket = zones[0].create_bucket(bucket_name)
+    # create object on non archive zone
+    key = bucket.new_key("foo")
+    key.set_contents_from_string("zero")
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # save object version on archive zone
+    bucket_az = az_zones[0].conn.get_bucket(bucket_name)
+    b_ver_az = get_versioned_objs(bucket_az)
+    obj_az_version_id = b_ver_az[0]['foo']['version_id']
+    # update object on non archive zone
+    key.set_contents_from_string("one")
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # delete object on non archive zone
+    key.delete()
+    # delete bucket on non archive zone
+    zones[0].delete_bucket(bucket_name)
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check same buckets on non archive zone
+    p1 = get_number_buckets_by_zone(zones[0]) == num_buckets
+    assert_equal(p1, True)
+    # check for new bucket on archive zone
+    p2 = get_number_buckets_by_zone(az_zones[0]) == (num_buckets_az + 1)
+    assert_equal(p2, True)
+    # get new bucket name on archive zone
+    bucket_names_az = get_bucket_names_by_zone(az_zones[0])
+    new_bucket_name_az = get_full_bucket_name(bucket_name + '-deleted-', bucket_names_az)
+    p3 = new_bucket_name_az is not None
+    assert_equal(p3, True)
+    # check number of objects on archive zone
+    new_bucket_az = az_zones[0].conn.get_bucket(new_bucket_name_az)
+    new_b_ver_az = get_versioned_objs(new_bucket_az)
+    p4 = len(new_b_ver_az) == 2
+    assert_equal(p4, True)
+    # check versioned objects on archive zone
+    new_key_az = new_bucket_az.get_key("foo", version_id=obj_az_version_id)
+    p5 = new_key_az.get_contents_as_string() == "zero"
+    assert_equal(p5, True)
+    new_key_latest_az = new_bucket_az.get_key("foo")
+    p6 = new_key_latest_az.get_contents_as_string() == "one"
+    assert_equal(p6, True)
+
+
+def test_az_force_bucket_renaming_if_same_bucket_name():
+    """ test force bucket renaming if same bucket name """
+    zones, az_zones = init_env()
+    bucket_name = gen_bucket_name()
+    # grab number of buckets on non archive zone
+    num_buckets = get_number_buckets_by_zone(zones[0])
+    # grab number of buckets on archive zone
+    num_buckets_az = get_number_buckets_by_zone(az_zones[0])
+    # create bucket on non archive zone
+    bucket = zones[0].create_bucket(bucket_name)
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check same buckets on non archive zone
+    p1 = get_number_buckets_by_zone(zones[0]) == (num_buckets + 1)
+    assert_equal(p1, True)
+    # check for new bucket on archive zone
+    p2 = get_number_buckets_by_zone(az_zones[0]) == (num_buckets_az + 1)
+    assert_equal(p2, True)
+    # delete bucket on non archive zone
+    zones[0].delete_bucket(bucket_name)
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check number of buckets on non archive zone
+    p3 = get_number_buckets_by_zone(zones[0]) == num_buckets
+    assert_equal(p3, True)
+    # check number of buckets on archive zone
+    p4 = get_number_buckets_by_zone(az_zones[0]) == (num_buckets_az + 1)
+    assert_equal(p4, True)
+    # get new bucket name on archive zone
+    bucket_names_az = get_bucket_names_by_zone(az_zones[0])
+    new_bucket_name_az = get_full_bucket_name(bucket_name + '-deleted-', bucket_names_az)
+    p5 = new_bucket_name_az is not None
+    assert_equal(p5, True)
+    # create bucket on non archive zone
+    _ = zones[0].create_bucket(new_bucket_name_az)
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check number of buckets on non archive zone
+    p6 = get_number_buckets_by_zone(zones[0]) == (num_buckets + 1)
+    assert_equal(p6, True)
+    # check number of buckets on archive zone
+    p7 = get_number_buckets_by_zone(az_zones[0]) == (num_buckets_az + 2)
+    assert_equal(p7, True)
+
+
+def test_az_versioning_support_in_zones():
+    """ test versioning support on zones """
+    zones, az_zones = init_env()
+    bucket_name = gen_bucket_name()
+    # create bucket on non archive zone
+    bucket = zones[0].create_bucket(bucket_name)
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # get bucket on archive zone
+    bucket_az = az_zones[0].conn.get_bucket(bucket_name)
+    # check non versioned buckets
+    p1 = get_versioning_status(bucket) is None
+    assert_equal(p1, True)
+    p2 = get_versioning_status(bucket_az) is None
+    assert_equal(p2, True)
+    # create object on non archive zone
+    key = bucket.new_key("foo")
+    key.set_contents_from_string("zero")
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check bucket versioning
+    p3 = get_versioning_status(bucket) is None
+    assert_equal(p3, True)
+    p4 = get_versioning_status(bucket_az) == 'Enabled'
+    assert_equal(p4, True)
+    # enable bucket versioning on non archive zone
+    bucket.configure_versioning(True)
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check bucket versioning
+    p5 = get_versioning_status(bucket) == 'Enabled'
+    assert_equal(p5, True)
+    p6 = get_versioning_status(bucket_az) == 'Enabled'
+    assert_equal(p6, True)
+    # delete object on non archive zone
+    key.delete()
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check delete-markers and versions on non archive zone
+    (b_dm, b_ver) = get_versioned_entries(bucket)
+    p7 = len(b_dm) == 1
+    assert_equal(p7, True)
+    p8 = len(b_ver) == 1
+    assert_equal(p8, True)
+    # check delete-markers and versions on archive zone
+    (b_dm_az, b_ver_az) = get_versioned_entries(bucket_az)
+    p9 = len(b_dm_az) == 1
+    assert_equal(p9, True)
+    p10 = len(b_ver_az) == 1
+    assert_equal(p10, True)
+    # delete delete-marker on non archive zone
+    dm_version_id = b_dm[0]['foo']['version_id']
+    bucket.delete_key("foo", version_id=dm_version_id)
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check delete-markers and versions on non archive zone
+    (b_dm, b_ver) = get_versioned_entries(bucket)
+    p11 = len(b_dm) == 0
+    assert_equal(p11, True)
+    p12 = len(b_ver) == 1
+    assert_equal(p12, True)
+    # check delete-markers and versions on archive zone
+    (b_dm_az, b_ver_az) = get_versioned_entries(bucket_az)
+    p13 = len(b_dm_az) == 1
+    assert_equal(p13, True)
+    p14 = len(b_ver_az) == 1
+    assert_equal(p14, True)
+    # delete delete-marker on archive zone
+    dm_az_version_id = b_dm_az[0]['foo']['version_id']
+    bucket_az.delete_key("foo", version_id=dm_az_version_id)
+    # sync
+    zone_full_checkpoint(az_zones[0].zone, zones[0].zone)
+    # check delete-markers and versions on non archive zone
+    (b_dm, b_ver) = get_versioned_entries(bucket)
+    p15 = len(b_dm) == 0
+    assert_equal(p15, True)
+    p16 = len(b_ver) == 1
+    assert_equal(p16, True)
+    # check delete-markers and versions on archive zone
+    (b_dm_az, b_ver_az) = get_versioned_entries(bucket_az)
+    p17 = len(b_dm_az) == 0
+    assert_equal(p17, True)
+    p17 = len(b_ver_az) == 1
+    assert_equal(p17, True)
+    # check body in zones
+    obj_version_id = b_ver[0]['foo']['version_id']
+    key = bucket.get_key("foo", version_id=obj_version_id)
+    p18 = key.get_contents_as_string() == "zero"
+    assert_equal(p18, True)
+    obj_az_version_id = b_ver_az[0]['foo']['version_id']
+    key_az = bucket_az.get_key("foo", version_id=obj_az_version_id)
+    p19 = key_az.get_contents_as_string() == "zero"
+    assert_equal(p19, True)
diff --git a/src/test/rgw/rgw_multi/zone_az.py b/src/test/rgw/rgw_multi/zone_az.py
new file mode 100644 (file)
index 0000000..aaab3ef
--- /dev/null
@@ -0,0 +1,40 @@
+import logging
+
+from .multisite import Zone
+
+
+log = logging.getLogger('rgw_multi.tests')
+
+
+class AZone(Zone):  # pylint: disable=too-many-ancestors
+    """ archive zone class """
+    def __init__(self, name, zonegroup=None, cluster=None, data=None, zone_id=None, gateways=None):
+        super(AZone, self).__init__(name, zonegroup, cluster, data, zone_id, gateways)
+
+    def is_read_only(self):
+        return False
+
+    def tier_type(self):
+        return "archive"
+
+    def create(self, cluster, args=None, **kwargs):
+        if args is None:
+            args = ''
+        args += ['--tier-type', self.tier_type()]
+        return self.json_command(cluster, 'create', args)
+
+    def has_buckets(self):
+        return False
+
+
+class AZoneConfig:
+    """ archive zone configuration """
+    def __init__(self, cfg, section):
+        pass
+
+
+def print_connection_info(conn):
+    """print info of connection"""
+    print("Host: " + conn.host+':'+str(conn.port))
+    print("AWS Secret Key: " + conn.aws_secret_access_key)
+    print("AWS Access Key: " + conn.aws_access_key_id)
index 9be658b7ff4126caf675ca23b11a8082fdad27d3..18a2f428aa58af390db5d2ba4ef78fca396149f5 100644 (file)
@@ -23,6 +23,7 @@ This section holds the following parameters:
  - `num_zonegroups`: number of zone groups (integer, default 1)
  - `num_zones`: number of regular zones in each group (integer, default 3)
  - `num_ps_zones`: number of pubsub zones in each group (integer, default 0)         
+ - `num_az_zones`: number of archive zones (integer, default 0, max value 1)
  - `gateways_per_zone`: number of RADOS gateways per zone (integer, default 2)
  - `no_bootstrap`: whether to assume that the cluster is already up and does not need to be setup again. If set to "false", it will try to re-run the cluster, so, `mstop.sh` must be called beforehand. Should be set to false, anytime the configuration is changed. Otherwise, and assuming the cluster is already up, it should be set to "true" to save on execution time (boolean, default false)
  - `log_level`: console log level of the logs in the tests, note that any program invoked from the test my emit logs regardless of that setting (integer, default 20)
index b65e320b073fe3fcb2a42071f572ff3e554c252b..45482ea281f49d59b68b964c0d3d121ce523ff41 100644 (file)
@@ -20,11 +20,14 @@ from rgw_multi.zone_cloud import CloudZone as CloudZone
 from rgw_multi.zone_cloud import CloudZoneConfig as CloudZoneConfig
 from rgw_multi.zone_ps import PSZone as PSZone
 from rgw_multi.zone_ps import PSZoneConfig as PSZoneConfig
+from rgw_multi.zone_az import AZone as AZone
+from rgw_multi.zone_az import AZoneConfig as AZoneConfig
 
 # make tests from rgw_multi.tests available to nose
 from rgw_multi.tests import *
 from rgw_multi.tests_es import *
 from rgw_multi.tests_ps import *
+from rgw_multi.tests_az import *
 
 mstart_path = os.getenv('MSTART_PATH')
 if mstart_path is None:
@@ -165,6 +168,7 @@ def init(parse_args):
                                          'num_zonegroups': 1,
                                          'num_zones': 3,
                                          'num_ps_zones': 0,
+                                         'num_az_zones': 0,
                                          'gateways_per_zone': 2,
                                          'no_bootstrap': 'false',
                                          'log_level': 20,
@@ -205,9 +209,11 @@ def init(parse_args):
     parser.add_argument('--reconfigure-delay', type=int, default=cfg.getint(section, 'reconfigure_delay'))
     parser.add_argument('--num-ps-zones', type=int, default=cfg.getint(section, 'num_ps_zones'))
 
+
     es_cfg = []
     cloud_cfg = []
     ps_cfg = []
+    az_cfg = []
 
     for s in cfg.sections():
         if s.startswith('elasticsearch'):
@@ -216,6 +222,8 @@ def init(parse_args):
             cloud_cfg.append(CloudZoneConfig(cfg, s))
         elif s.startswith('pubsub'):
             ps_cfg.append(PSZoneConfig(cfg, s))
+        elif s.startswith('archive'):
+            az_cfg.append(AZoneConfig(cfg, s))
 
 
     argv = []
@@ -253,11 +261,12 @@ def init(parse_args):
     num_es_zones = len(es_cfg)
     num_cloud_zones = len(cloud_cfg)
     num_ps_zones_from_conf = len(ps_cfg)
+    num_az_zones = cfg.getint(section, 'num_az_zones')
 
     num_ps_zones = args.num_ps_zones if num_ps_zones_from_conf == 0 else num_ps_zones_from_conf 
     print 'num_ps_zones = ' + str(num_ps_zones)
 
-    num_zones = args.num_zones + num_es_zones + num_cloud_zones + num_ps_zones
+    num_zones = args.num_zones + num_es_zones + num_cloud_zones + num_ps_zones + num_az_zones
 
     for zg in range(0, args.num_zonegroups):
         zonegroup = multisite.ZoneGroup(zonegroup_name(zg), period)
@@ -297,7 +306,8 @@ def init(parse_args):
 
             es_zone = (z >= args.num_zones and z < args.num_zones + num_es_zones)
             cloud_zone = (z >= args.num_zones + num_es_zones and z < args.num_zones + num_es_zones + num_cloud_zones)
-            ps_zone = (z >= args.num_zones + num_es_zones + num_cloud_zones)
+            ps_zone = (z >= args.num_zones + num_es_zones + num_cloud_zones and z < args.num_zones + num_es_zones + num_cloud_zones + num_ps_zones)
+            az_zone = (z >= args.num_zones + num_es_zones + num_cloud_zones + num_ps_zones)
 
             # create the zone in its zonegroup
             zone = multisite.Zone(zone_name(zg, z), zonegroup, cluster)
@@ -317,6 +327,9 @@ def init(parse_args):
                     pscfg = ps_cfg[zone_index]
                     zone = PSZone(zone_name(zg, z), zonegroup, cluster,
                                   full_sync=pscfg.full_sync, retention_days=pscfg.retention_days)
+            elif az_zone:
+                zone_index = z - args.num_zones - num_es_zones - num_cloud_zones - num_ps_zones
+                zone = AZone(zone_name(zg, z), zonegroup, cluster)
             else:
                 zone = RadosZone(zone_name(zg, z), zonegroup, cluster)