Skip to content

Commit

Permalink
DAOS-14542 test: replace check_container_info with verify_query (#13219)
Browse files Browse the repository at this point in the history
- Replace TestContainer.check_container_info with verify_query
  - More generic and uses daos instead of API
- Update callers appropriately
- Remove now unused TestContainer.get_info()
- Remove now unused TestContainer.info
  - Just the same as TestContainer.container.info anyway

Signed-off-by: Dalton Bohning <[email protected]>
  • Loading branch information
daltonbohning authored Feb 1, 2024
1 parent 0c3ebbd commit 9ff43c8
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 74 deletions.
39 changes: 20 additions & 19 deletions src/tests/ftest/ior/crash.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
"""
(C) Copyright 2020-2023 Intel Corporation.
(C) Copyright 2020-2024 Intel Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
"""

import time

from dmg_utils import check_system_query_status
from general_utils import wait_for_result
from ior_test_base import IorTestBase


Expand All @@ -15,20 +16,18 @@ class IorCrash(IorTestBase):
Verify DAOS server does not need to be restarted when an application crashes.
:avocado: recursive
"""
def verify_cont_handles(self, expected_handles=1):
"""Verify number of container handles. If needed, perform multiple queries (with delay).
def setUp(self):
"""Set up test before executing."""
super().setUp()
self.dmg = self.get_dmg_command()
Args:
expected_handles (int): expected number of container handles. Defaults to 1.
def cont_nhandles_match(self, exp_nhandles=1, attempts=5, delay_sec=2):
"""Verify container number of handles. If needed, perform multiple queries (with delay)."""
for _ in range(attempts):
if self.container.check_container_info(ci_nhandles=exp_nhandles):
return True
self.log.info("check_container_info does not match yet, sleep %d sec", delay_sec)
time.sleep(delay_sec)
return False
Returns:
bool: whether expected matches actual
"""
return wait_for_result(
self.log, self.container.verify_query, timeout=10, delay=2,
expected_response={'num_handles': expected_handles})

def test_ior_crash(self):
"""Jira ID: DAOS-4332.
Expand All @@ -52,6 +51,8 @@ def test_ior_crash(self):
:avocado: tags=daosio,ior,dfs
:avocado: tags=IorCrash,test_ior_crash
"""
dmg = self.get_dmg_command()

# Create pool and container
self.pool = self.get_pool(connect=False)
self.container = self.get_container(self.pool)
Expand All @@ -66,13 +67,13 @@ def test_ior_crash(self):
self.stop_ior()

# Verify engines did not crash
scan_info = self.dmg.system_query(verbose=True)
scan_info = dmg.system_query(verbose=True)
if not check_system_query_status(scan_info):
self.fail("One or more engines crashed")

# Verify container handle opened by ior is closed (by daos_agent after ior crash).
# Expect to find one open handle now (a handle opened for this check)
self.assertTrue(self.cont_nhandles_match(), "Error confirming container info nhandles")
self.assertTrue(self.verify_cont_handles(), "Error confirming container info nhandles")

# Run IOR and crash it in the middle of Read.
# Must wait for Write to complete first.
Expand All @@ -82,23 +83,23 @@ def test_ior_crash(self):
self.stop_ior()

# Verify engines did not crash
scan_info = self.dmg.system_query(verbose=True)
scan_info = dmg.system_query(verbose=True)
if not check_system_query_status(scan_info):
self.fail("One or more engines crashed")

# Verify container handle opened by ior is closed (by daos_agent after ior crash).
self.assertTrue(self.cont_nhandles_match(), "Error confirming container info nhandles")
self.assertTrue(self.verify_cont_handles(), "Error confirming container info nhandles")

# Run IOR and verify it completes successfully
self.run_ior_with_pool(create_pool=False, create_cont=False)

# Verify engines did not crash
scan_info = self.dmg.system_query(verbose=True)
scan_info = dmg.system_query(verbose=True)
if not check_system_query_status(scan_info):
self.fail("One or more engines crashed")

# Verify container handle opened by ior is closed (by ior before its graceful exit)
# Give ior some time to get started and open the container!
# And, expect 2 open handles, one for this container open/query, and another for ior itself
self.assertTrue(self.cont_nhandles_match(exp_nhandles=2, attempts=5, delay_sec=2),
self.assertTrue(self.verify_cont_handles(expected_handles=2),
"Error confirming container info nhandles")
2 changes: 1 addition & 1 deletion src/tests/ftest/util/container_rf_test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def execute_cont_rf_test(self, create_container=True, mode=None):
# Refresh local pool and container
self.log.info("==>(6)Check for pool and container info after rebuild.")
self.pool.check_pool_info()
self.container.check_container_info()
self.container.query()
# Verify the excluded rank is no longer used with the objects
self.verify_rank_has_no_objects()
# Verify the pool information after rebuild
Expand Down
2 changes: 1 addition & 1 deletion src/tests/ftest/util/rebuild_test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def execute_rebuild_test(self, create_container=True):

# Refresh local pool and container
self.pool.check_pool_info()
self.container.check_container_info()
self.container.query()

# Verify the excluded rank is no longer used with the objects
self.verify_rank_has_no_objects()
Expand Down
72 changes: 19 additions & 53 deletions src/tests/ftest/util/test_utils_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from command_utils_base import BasicParameter
from exception_utils import CommandFailure
from general_utils import DaosTestError, get_random_bytes
from pydaos.raw import DaosApiError, DaosContainer, DaosInputParams, c_uuid_to_str, str_to_c_uuid
from pydaos.raw import DaosApiError, DaosContainer, DaosInputParams, str_to_c_uuid
from test_utils_base import TestDaosApiBase


Expand Down Expand Up @@ -278,7 +278,6 @@ def __init__(self, pool, daos_command=None, label_generator=None):

self.container = None
self.uuid = None
self.info = None
self.opened = False
self.written_data = []
self.epoch = None
Expand Down Expand Up @@ -565,61 +564,10 @@ def destroy(self, force=1):

self.container = None
self.uuid = None
self.info = None
self.written_data = []

return status

@fail_on(DaosApiError)
def get_info(self, coh=None):
"""Query the container for information.
Sets the self.info attribute.
Args:
coh (str, optional): container handle override. Defaults to None.
"""
if self.container:
self.open()
self.log.info("Querying container %s", str(self))
self._call_method(self.container.query, {"coh": coh})
self.info = self.container.info

def check_container_info(self, ci_uuid=None, ci_nsnapshots=None, ci_nhandles=None):
# pylint: disable=unused-argument
"""Check the container info attributes.
Note:
Arguments may also be provided as a string with a number preceded
by '<', '<=', '>', or '>=' for other comparisons besides the
default '=='.
Args:
ci_uuid (str, optional): container uuid. Defaults to None.
ci_nsnapshots (int, optional): number of snapshots.
Defaults to None.
Note:
Arguments may also be provided as a string with a number preceded
by '<', '<=', '>', or '>=' for other comparisons besides the
default '=='.
Returns:
bool: True if at least one expected value is specified and all the
specified values match; False otherwise
"""
self.get_info()
checks = [
(key,
c_uuid_to_str(getattr(self.info, key))
if key == "ci_uuid" else getattr(self.info, key),
val)
for key, val in list(locals().items())
if key != "self" and val is not None]
return self._check_info(checks)

def write_objects(self, rank=None, obj_class=None):
"""Write objects to the container.
Expand Down Expand Up @@ -1036,6 +984,24 @@ def query(self, *args, **kwargs):
return self.daos.container_query(
pool=self.pool.identifier, cont=self.identifier, *args, **kwargs)

def verify_query(self, expected_response):
"""Verify daos container query returns expected response values.
Args:
expected_response (dict): expected response values
Returns:
bool: whether response values from daos container query match expected values
"""
response = self.query()['response']
for expected_key, expected_val in expected_response.items():
if expected_key not in response:
return False
if response[expected_key] != expected_val:
return False
return True

def set_attr(self, *args, **kwargs):
"""Call daos container set-attr.
Expand Down

0 comments on commit 9ff43c8

Please sign in to comment.