def run_asserts_parallel( asserts: List[Assert], state: defaultdict, test_name: str, hostnames: List[str], seconds_between_asserts: float, ) -> Statuses: """ Runs each assert in provided list on each of the provided hosts. For example, if two asserts are provided and there are two hosts, each assert will be run twice (once on each host) Args: asserts: List of asserts to run state: Initial state of test to provide to asserts test_name: Name of test hostnames: List of host addresses seconds_between_asserts: Seconds to wait on host before running the next assert Returns: Status of each assert after being run """ asserts_task = ( bag.from_sequence(hostnames) .map( lambda hostname: run_asserts( get_remaining_asserts(asserts, state[test_name].get("asserts", {})), {**state}, hostname, seconds_between_asserts, ) ) .fold(combine_data_by_key, initial=state[test_name].get("asserts", {})) ) return asserts_task.compute()
def test_run_asserts(mock_send_assert): mock_send_assert.return_value = AssertResult( passed=True, actual="foo", expected="foo", description="good" ) test_asserts = [ {"name": "A", "type": "SQLAssert", "params": {}, "executionsPerCycle": 2}, {"name": "B", "type": "NullAssert", "passed": True, "params": {}}, {"name": "C", "type": "NullAssert", "params": {}}, ] statuses = asserts.run_asserts(test_asserts, {}, "", 0) assert statuses["A"] == [ AssertResult(passed=True, actual="foo", expected="foo", description="good"), AssertResult(passed=True, actual="foo", expected="foo", description="good"), ] assert statuses["B"] == [ AssertResult(passed=True, actual="", expected="", description="") ] assert statuses["C"] == [ AssertResult(passed=False, actual="", expected="", description="") ]
def test_asserts_non_versioned(mock_send_assert): mock_send_assert.return_value = AssertResult( passed=True, actual="foo", expected="foo", description="good" ) test_asserts = [ {"name": "A", "type": "SQLAssert", "storeVersions": False, "params": {}}, { "name": "B", "type": "NullAssert", "passed": True, "storeVersions": False, "params": {}, }, {"name": "C", "type": "NullAssert", "params": {}}, ] statuses = asserts.run_asserts(test_asserts, {}, "", 0) assert statuses["A"] == AssertResult( passed=True, actual="foo", expected="foo", description="good" ) assert statuses["B"] == AssertResult( passed=True, actual="", expected="", description="" ) assert statuses["C"] == [ AssertResult(passed=False, actual="", expected="", description="") ]
def run_asserts_series( asserts: List[Assert], state: defaultdict, test_name: str, hostnames: List[str], seconds_between_asserts: float, ) -> Statuses: """ Runs each assert distributed into each host. For example, If there are two hosts and two asserts, each assert will be run once, one assert per host Args: asserts: List of asserts to run state: Initial state of test to provide to asserts test_name: Name of test hostnames: List of host addresses seconds_between_asserts: Seconds to wait on host before running the next assert Returns: Status of each assert after being run """ hostname_asserts_map: Dict[str, List[Assert]] = {} for hostname_assert in zip( cycle(hostnames), get_remaining_asserts(asserts, state[test_name].get("asserts", {})), ): hostname = hostname_assert[0] asrt = hostname_assert[1] if hostname not in hostname_asserts_map: hostname_asserts_map[hostname] = [asrt] else: hostname_asserts_map[hostname] += [asrt] asserts_task = ( bag.from_sequence(hostname_asserts_map) .map( lambda h_name: run_asserts( hostname_asserts_map[h_name], {**state}, h_name, seconds_between_asserts ) ) .fold(combine_data_by_key, initial=state[test_name].get("asserts", {})) ) return asserts_task.compute()
def test_run_asserts_negate(mock_get_assert_sender): mock_get_assert_sender.return_value.__enter__.return_value.return_value = ( AssertResult(passed=False, actual="foo", expected="foo", description="bad")) test_asserts = [{ "name": "A", "type": "SQLAssert", "params": {}, "negate": True }] statuses = asserts.run_asserts(test_asserts, {}, "", 0) assert statuses["A"] == [ AssertResult( passed=True, actual="foo", expected="foo", description="passed; negated: bad", ), ]