diff --git a/__main__.py b/__main__.py index 9939195e2928140fde7176c927841a62ac07ac94..f9e72a897a76a2b004c5d458ac01ec7cbc05d0d6 100755 --- a/__main__.py +++ b/__main__.py @@ -79,6 +79,8 @@ from .tests.basic.basic import BASIC_TESTS from .tests.asgn3.availability.availability_basic import AVAILABILITY_TESTS from .tests.asgn3.causal_consistency.causal_basic import CAUSAL_TESTS from .tests.asgn3.eventual_consistency.convergence_basic import CONVERGENCE_TESTS +# from .tests.asgn3.view_change.view_change_basic import VIEW_CHANGE_TESTS +from .tests.proxy.basic_proxy import PROXY_TESTS TEST_SET = [] TEST_SET.append(TestCase("hello_cluster", hello_cluster)) @@ -86,6 +88,8 @@ TEST_SET.extend(BASIC_TESTS) TEST_SET.extend(AVAILABILITY_TESTS) TEST_SET.extend(CAUSAL_TESTS) TEST_SET.extend(CONVERGENCE_TESTS) +TEST_SET.extend(PROXY_TESTS) +# TEST_SET.extend(VIEW_CHANGE_TESTS) # set to True to stop at the first failing test FAIL_FAST = True diff --git a/tests/proxy/basic_proxy.py b/tests/proxy/basic_proxy.py new file mode 100644 index 0000000000000000000000000000000000000000..3dd87d3fa06d9fad19b432b129ee340bcec4827f --- /dev/null +++ b/tests/proxy/basic_proxy.py @@ -0,0 +1,43 @@ +from ...utils.containers import ClusterConductor +from ...utils.testcase import TestCase +from ...utils.util import Logger +from ..helper import KVSMultiClient, KVSTestFixture +from ...utils.kvs_api import DEFAULT_TIMEOUT + +def basic_proxy(conductor: ClusterConductor, dir, log: Logger): + with KVSTestFixture(conductor, dir, log, node_count=4) as fx: + c = KVSMultiClient(fx.clients, "client", log) + conductor.add_shard("shard1", conductor.get_nodes([0, 1])) + conductor.add_shard("shard2", conductor.get_nodes([2, 3])) + fx.broadcast_view(conductor.get_shard_view()) + # test 1 + # put 50 keys (at least one proxy expected here) + # get_all() on one shard + # then ask the other shard for that key (proxy MUST happen here) + + node_to_put = 0 + base_key = "key" + for i in range(0, 51): + r = c.put(node_to_put, f"{base_key}{i}", f"{i}", timeout=10) + assert r.ok, f"expected ok for new key, got {r.status_code}" + node_to_put += 1 + node_to_put = node_to_put % 4 + + r = c.get_all(0, timeout=10) # should get all of shard 1's keys + assert r.ok, f"expected ok for get, got {r.status_code}" + res = r.json()["items"] + print("res-- {}", res) + + return True, "ok" + +def partitioned_shards(conductor: ClusterConductor, dir, log: Logger): + with KVSTestFixture(conductor, dir, log, node_count=4) as fx: + ### + # test 2 + # partition the shards + # put a bunch of keys + # we MUST probablistically encounter some hanging there. + # have a time out where if it doesnt hang after like 50 keys, then its just wrong. + return True, "ok" + +PROXY_TESTS = [TestCase("basic_proxy", basic_proxy)] \ No newline at end of file diff --git a/utils/containers.py b/utils/containers.py index dae84e411e8ef06906d47d7c8e99eea63d8a3ae8..894dbd281f25808892f6ba59dd3900f949b644ea 100644 --- a/utils/containers.py +++ b/utils/containers.py @@ -107,7 +107,7 @@ class ClusterConductor: def dump_all_container_logs(self, dir): self.log("dumping logs of kvs containers") - container_pattern = "^kvs_.*" + container_pattern = f"^kvs_{self.group_id}_.*" container_regex = re.compile(container_pattern) containers = self._list_containers() @@ -143,6 +143,17 @@ class ClusterConductor: error_prefix=f"failed to remove container {name}", ) + def _remove_containers(self, names: list[str]) -> None: + if len(names) == 0: + return + self.log(f"removing containers {names}") + run_cmd_bg( + self._make_remove_cmd(names[0]) + names[1:], + verbose=True, + error_prefix=f"failed to remove containers {names}", + ) + + def _remove_network(self, name: str) -> None: # remove a single network self.log(f"removing network {name}") @@ -184,10 +195,12 @@ class ClusterConductor: # cleanup containers self.log(f" cleaning up {'group' if group_only else 'all'} containers") containers = self._list_containers() - for container in containers: - if container and container_regex.match(container): - self._remove_container(container) - + containers_to_remove = [ + container + for container in containers + if container and container_regex.match(container) + ] + self._remove_containers(containers_to_remove) # cleanup networks self.log(f" cleaning up {'group' if group_only else 'all'} networks") networks = self._list_networks()