Skip to content

Commit

Permalink
feat(topology): add python test for pool labels
Browse files Browse the repository at this point in the history
Signed-off-by: sinhaashish <[email protected]>
  • Loading branch information
sinhaashish committed Aug 2, 2024
1 parent f87c28c commit c0a4373
Show file tree
Hide file tree
Showing 3 changed files with 282 additions and 1 deletion.
2 changes: 1 addition & 1 deletion tests/bdd/features/node/label/test_label_unlabel_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
# Fixtures
@pytest.fixture(scope="module")
def init():
Deployer.start(NUM_IO_ENGINES, io_engine_env="MAYASTOR_HB_INTERVAL_SEC=0")
Deployer.start(NUM_IO_ENGINES)
yield
Deployer.stop()

Expand Down
30 changes: 30 additions & 0 deletions tests/bdd/features/pool/label/pool-label.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Feature: Label a pool, this will be used while scheduling replica of volume considering the
pool topology

Background:
Given a control plane, two Io-Engine instances, two pools

Scenario: Label a pool
Given an unlabeled pool
When the user issues a label command with a label to the pool
Then the given pool should be labeled with the given label

Scenario: Label a pool when label key already exist and overwrite is false
Given a labeled pool
When the user attempts to label the same pool with the same label key with overwrite as false
Then the pool label should fail with error "PRECONDITION_FAILED"

Scenario: Label a pool when label key already exist and overwrite is true
Given a labeled pool
When the user attempts to label the same pool with the same label key and overwrite as true
Then the given pool should be labeled with the new given label

Scenario: Unlabel a pool
Given a labeled pool
When the user issues a unlabel command with a label key present as label for the pool
Then the given pool should remove the label with the given key

Scenario: Unlabel a pool when the label key is not present
Given a labeled pool
When the user issues an unlabel command with a label key that is not currently associated with the pool
Then the unlabel operation for the pool should fail with error PRECONDITION_FAILED
251 changes: 251 additions & 0 deletions tests/bdd/features/pool/label/test_label_unlabel_pool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
"""Label a pool, this will be used while scheduling replica of volume considering the feature tests."""

from pytest_bdd import (
given,
scenario,
then,
when,
)


import docker
import pytest
import sys
import http


from pytest_bdd import given, scenario, then, when
from common.deployer import Deployer
from common.apiclient import ApiClient
from common.docker import Docker
from common.etcd import Etcd
from common.operations import Cluster, wait_node_online
from openapi.model.node import Node
from openapi.exceptions import ApiException
from openapi.model.create_pool_body import CreatePoolBody
from openapi.model.pool import Pool




NUM_IO_ENGINES = 2
LABEL1 = "KEY1=VALUE1"
LABEL1_NEW = "KEY1=NEW_LABEL"
LABEL2_NEW = "KEY2=NEW_LABEL"
LABEL1_MAP = "{'KEY1': 'VALUE1'}"
LABEL2 = "KEY2=VALUE2"
LABEL_1_NEW = "KEY1=NEW_LABEL"
LABEL_KEY_TO_DELETE = "KEY2"
LABEL_KEY_TO_DELETE_ABSENT = "ABSENT_KEY"



VOLUME_SIZE = 10485761
NUM_VOLUME_REPLICAS = 1
CREATE_REQUEST_KEY = "create_request"
POOL_1_UUID = "4cc6ee64-7232-497d-a26f-38284a444980"
NODE_1_NAME = "io-engine-1"
POOL_2_UUID = "24d36c1a-3e6c-4e05-893d-917ec9f4c1bb"
NODE_2_NAME = "io-engine-2"
REPLICA_CONTEXT_KEY = "replica"
REPLICA_ERROR = "replica_error"

@pytest.fixture(scope="module")
def init():
Deployer.start(NUM_IO_ENGINES, io_engine_env="MAYASTOR_HB_INTERVAL_SEC=0")
ApiClient.pools_api().put_node_pool(
NODE_1_NAME,
POOL_1_UUID,
CreatePoolBody(
["malloc:///disk?size_mb=50"]
),
)
ApiClient.pools_api().put_node_pool(
NODE_2_NAME,
POOL_2_UUID,
CreatePoolBody(
["malloc:///disk?size_mb=50"],
labels={
"KEY2": "VALUE2",
},
),
)
yield
Deployer.stop()

@pytest.fixture(scope="function")
def context():
return {}


@pytest.fixture(scope="function")
def pool(context):
yield context["pool"]



@scenario('pool-label.feature', 'Label a pool')
def test_label_a_pool():
"""Label a pool."""

@scenario('pool-label.feature', 'Label a pool when label key already exist and overwrite is false')
def test_label_a_pool_when_label_key_already_exist_and_overwrite_is_false():
"""Label a pool when label key already exist and overwrite is false."""


@scenario('pool-label.feature', 'Label a pool when label key already exist and overwrite is true')
def test_label_a_pool_when_label_key_already_exist_and_overwrite_is_true():
"""Label a pool when label key already exist and overwrite is true."""

@scenario('pool-label.feature', 'Unlabel a pool')
def test_unlabel_a_pool():
"""Unlabel a pool."""

@scenario('pool-label.feature', 'Unlabel a pool when the label key is not present')
def test_unlabel_a_pool_when_the_label_key_is_not_present():
"""Unlabel a pool when the label key is not present."""


@given('a control plane, two Io-Engine instances, two pools')
def a_control_plane_two_ioengine_instances_two_pools(init):
"""a control plane, two Io-Engine instances, two pools."""
docker_client = docker.from_env()

# The control plane comprises the core agents, rest server and etcd instance.
for component in ["core", "rest", "etcd"]:
Docker.check_container_running(component)

# Check all Io-Engine instances are running
try:
io_engines = docker_client.containers.list(
all=True, filters={"name": "io-engine"}
)

except docker.errors.NotFound:
raise Exception("No Io-Engine instances")

for io_engine in io_engines:
Docker.check_container_running(io_engine.attrs["Name"])

# Check for a pools
pools = ApiClient.pools_api().get_pools()
assert len(pools) == 2
Cluster.cleanup(pools=False)


@given('an unlabeled pool')
def an_unlabeled_pool():
"""an unlabeled pool."""
pool = ApiClient.pools_api().get_pool(POOL_1_UUID)
assert not "labels" in pool.spec

@given('a labeled pool')
def a_labeled_pool(context):
"""a labeled pool."""
pool = ApiClient.pools_api().get_pool(POOL_2_UUID)
assert "labels" in pool.spec
context["pool"] = pool


@when('the user issues a label command with a label to the pool')
def the_user_issues_a_label_command_with_a_label_to_the_pool(attempt_add_label_pool):
"""the user issues a label command with a label to the pool."""


@when('the user attempts to label the same pool with the same label key with overwrite as false')
def the_user_attempts_to_label_the_same_pool_with_the_same_label_key_with_overwrite_as_false(context, pool):
"""the user attempts to label the same pool with the same label key with overwrite as false."""
attempt_add_label(pool.id, LABEL2_NEW, False, context)

@when('the user attempts to label the same pool with the same label key and overwrite as true')
def the_user_attempts_to_label_the_same_pool_with_the_same_label_key_and_overwrite_as_true(context, pool):
"""the user attempts to label the same pool with the same label key and overwrite as true."""
attempt_add_label(pool.id, LABEL2_NEW, True, context)


@when('the user issues a unlabel command with a label key present as label for the pool')
def the_user_issues_a_unlabel_command_with_a_label_key_present_as_label_for_the_pool(context, pool):
"""the user issues a unlabel command with a label key present as label for the pool."""

@when('the user issues an unlabel command with a label key that is not currently associated with the pool')
def the_user_issues_an_unlabel_command_with_a_label_key_that_is_not_currently_associated_with_the_pool(context, pool):
"""the user issues an unlabel command with a label key that is not currently associated with the pool."""
attempt_delete_label(pool.id, LABEL_KEY_TO_DELETE_ABSENT, context)

@then('the given pool should be labeled with the given label')
def the_given_pool_should_be_labeled_with_the_given_label(attempt_add_label_pool, context):
"""the given pool should be labeled with the given label."""
labelling_succeeds(attempt_add_label_pool, context)

@then('the pool label should fail with error "PRECONDITION_FAILED"')
def the_pool_label_should_fail_with_error_precondition_failed(pool_attempt):
"""the pool label should fail with error "PRECONDITION_FAILED"."""
assert pool_attempt.status == http.HTTPStatus.PRECONDITION_FAILED
assert ApiClient.exception_to_error(pool_attempt).kind == "FailedPrecondition"


@then('the given pool should be labeled with the new given label')
def the_given_pool_should_be_labeled_with_the_new_given_label( attempt_add_label_one_with_overwrite, context):
"""the given pool should be labeled with the new given label."""
labelling_succeeds(attempt_add_label_one_with_overwrite, context)


@then('the given pool should remove the label with the given key')
def the_given_pool_should_remove_the_label_with_the_given_key( attempt_delete_label_of_pool, context):
"""the given pool should remove the label with the given key."""
labelling_succeeds(attempt_delete_label_of_pool, context)

@then('the unlabel operation for the pool should fail with error PRECONDITION_FAILED')
def the_unlabel_operation_for_the_pool_should_fail_with_error_precondition_failed(pool_attempt):
"""the unlabel operation for the pool should fail with error PRECONDITION_FAILED."""
assert pool_attempt.status == http.HTTPStatus.PRECONDITION_FAILED
assert ApiClient.exception_to_error(pool_attempt).kind == "FailedPrecondition"



@pytest.fixture(scope="function")
def pool_attempt(context):
return context["attempt_result"]

@pytest.fixture
def attempt_add_label_pool(context):
yield attempt_add_label(POOL_1_UUID, LABEL1, False, context)

@pytest.fixture
def attempt_add_label_one_with_overwrite(context):
yield attempt_add_label(POOL_2_UUID, LABEL2_NEW, True, context)


@pytest.fixture
def attempt_delete_label_of_pool(context):
yield attempt_delete_label(POOL_2_UUID, LABEL_KEY_TO_DELETE, context)


def attempt_add_label(pool_name, label, overwrite, context):
try:
[key, value] = label.split("=")
overwrite = "true" if overwrite else "false"
pool = ApiClient.pools_api().put_pool_label(
pool_name, key, value, overwrite=overwrite
)
context["pool"] = pool
return pool
except ApiException as exception:
context["attempt_result"] = exception
return exception

def attempt_delete_label(pool_name, label, context):
try:
pool = ApiClient.pools_api().del_pool_label(pool_name, label)
context["pool"] = pool
return pool
except ApiException as exception:
context["attempt_result"] = exception
return exception


def labelling_succeeds(result, context):
# raise result for exception information
assert isinstance(result, Pool)
ApiClient.pools_api().get_pool(result.id)
context["pool"] = result

0 comments on commit c0a4373

Please sign in to comment.