Skip to content

Commit

Permalink
Merge branch 'develop' into ADCM-6210-3
Browse files Browse the repository at this point in the history
  • Loading branch information
Sealwing authored Dec 26, 2024
2 parents 65d2d8f + 65642e9 commit f87a42e
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 0 deletions.
5 changes: 5 additions & 0 deletions tests/integration/bundles/complex_cluster/actions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@
msg: "failed step"
tags: [fail]

- name: Change
fail:
msg: "Expected value is changed, actual value is {{ job.config.very_important_flag }}"
when: "{{ job.config.very_important_flag != 'changed' }}"
tags: [change]
38 changes: 38 additions & 0 deletions tests/integration/bundles/complex_cluster/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -292,3 +292,41 @@
- name: justhere
type: integer
required: false

- type: service
name: with_host_actions
version: 2.3
components:
c1:
display_name: c1
config:
- name: very_important_flag
display_name: Set me
type: string
required: true
default: default

actions: &component_actions
host_action_config_hc_acl:
display_name: acl_host_action
type: job
script_type: ansible
script: ./actions.yaml
host_action: true
allow_to_terminate: true
config:
- name: very_important_flag
type: string
hc_acl:
- service: with_host_actions
component: c2
action: add
- service: with_host_actions
component: c1
action: remove
params:
ansible_tags: change
masking: {}

c2:
actions: *component_actions
138 changes: 138 additions & 0 deletions tests/integration/test_actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
from collections.abc import Iterable
from itertools import chain
from pathlib import Path
import asyncio

import pytest
import pytest_asyncio

from adcm_aio_client.core.client import ADCMClient
from adcm_aio_client.core.config import Parameter
from adcm_aio_client.core.filters import Filter
from adcm_aio_client.core.mapping.types import MappingPair
from adcm_aio_client.core.objects.cm import Bundle, Cluster, Host, Job
from tests.integration.bundle import pack_bundle
from tests.integration.conftest import BUNDLES

pytestmark = [pytest.mark.asyncio]

type TwoHosts = tuple[Host, Host]


async def is_success(job: Job) -> bool:
return await job.get_status() == "success"


async def is_aborted(job: Job) -> bool:
return await job.get_status() == "aborted"


async def is_running(job: Job) -> bool:
return await job.get_status() == "running"


def build_name_mapping(*iterables: Iterable[MappingPair]) -> set[tuple[str, str, str]]:
return {(c.service.name, c.name, h.name) for c, h in chain.from_iterable(iterables)}


@pytest_asyncio.fixture()
async def cluster_bundle(adcm_client: ADCMClient, tmp_path: Path) -> Bundle:
bundle_path = pack_bundle(from_dir=BUNDLES / "complex_cluster", to=tmp_path)
return await adcm_client.bundles.create(source=bundle_path, accept_license=True)


@pytest_asyncio.fixture()
async def hostprovider_bundle(adcm_client: ADCMClient, tmp_path: Path) -> Bundle:
bundle_path = pack_bundle(from_dir=BUNDLES / "simple_hostprovider", to=tmp_path)
return await adcm_client.bundles.create(source=bundle_path, accept_license=True)


@pytest_asyncio.fixture()
async def cluster(adcm_client: ADCMClient, cluster_bundle: Bundle) -> Cluster:
cluster = await adcm_client.clusters.create(bundle=cluster_bundle, name="Awesome Cluster")
await cluster.services.add(filter_=Filter(attr="name", op="eq", value="with_host_actions"))
return cluster


@pytest_asyncio.fixture()
async def hosts(adcm_client: ADCMClient, hostprovider_bundle: Bundle) -> TwoHosts:
hp = await adcm_client.hostproviders.create(bundle=hostprovider_bundle, name="Awesome HostProvider")
coros = (adcm_client.hosts.create(hostprovider=hp, name=f"host-{i+1}") for i in range(2))
await asyncio.gather(*coros)
hosts = await adcm_client.hosts.all()
return tuple(hosts) # type: ignore[reportReturnType]


async def test_run_action_with_mapping_and_config(adcm_client: ADCMClient, cluster: Cluster, hosts: TwoHosts) -> None:
mapping = await cluster.mapping

assert len(mapping.all()) == 0
assert len(await mapping.hosts.all()) == 0
assert len(await mapping.components.all()) == 2

await cluster.hosts.add(host=hosts)
host_1, host_2 = await mapping.hosts.all()

service_1 = await cluster.services.get(display_name__eq="with_host_actions")
component_1_s1 = await service_1.components.get(name__eq="c1")
component_2_s1 = await service_1.components.get(name__eq="c2")

await mapping.add(component=component_1_s1, host=(host_1, host_2))
assert len(tuple(mapping.iter())) == 2
await mapping.save()

## run action host_action_config_hc_acl

host_action = await host_1.actions.get(name__eq="host_action_config_hc_acl")

action_mapping = await host_action.mapping
await action_mapping.remove(component=component_1_s1, host=host_1)
await action_mapping.add(component=component_2_s1, host=host_1)

action_config = await host_action.config
action_config["very_important_flag", Parameter].set("changed")

job = await host_action.run()
assert await job.get_status() in ("created", "running")
await job.wait(exit_condition=is_success, timeout=30, poll_interval=1)

## check mapping after action

cluster_alt = await adcm_client.clusters.get(name__eq=cluster.name)
mapping_alt = await cluster_alt.mapping

expected_mapping = build_name_mapping(((component_1_s1, host_2), (component_2_s1, host_1)))
actual_mapping = build_name_mapping(mapping_alt.iter())
assert actual_mapping == expected_mapping


async def test_terminate_action_with_config(cluster: Cluster, hosts: TwoHosts) -> None:
mapping = await cluster.mapping
await cluster.hosts.add(host=hosts)
host_1, host_2 = await mapping.hosts.all()

service_1 = await cluster.services.get(display_name__eq="with_host_actions")
component_1_s1 = await service_1.components.get(name__eq="c1")
component_2_s1 = await service_1.components.get(name__eq="c2")

await mapping.add(component=component_1_s1, host=(host_1, host_2))
assert len(tuple(mapping.iter())) == 2
await mapping.save()

## terminate host_action_config_hc_acl

host_1, host_2 = await mapping.hosts.all()
host_action = await host_2.actions.get(name__eq="host_action_config_hc_acl")

action_mapping = await host_action.mapping
await action_mapping.remove(component=component_1_s1, host=host_2)
await action_mapping.remove(component=component_2_s1, host=host_2)

action_config = await host_action.config
action_config["very_important_flag", Parameter].set("will be terminated")

job = await host_action.run()
await job.wait(exit_condition=is_running, timeout=10, poll_interval=1)
await job.terminate()

await job.wait(exit_condition=is_aborted, timeout=30, poll_interval=1)

0 comments on commit f87a42e

Please sign in to comment.