From 8092725461945ded58fb0a12a894bab6c2a36843 Mon Sep 17 00:00:00 2001 From: blee Date: Fri, 22 Sep 2023 17:14:21 -0400 Subject: [PATCH 1/4] add helper method for updating ignored links; use chain data to provide list of potential skipped abilities --- app/api/v2/managers/operation_api_manager.py | 2 ++ app/objects/c_operation.py | 15 ++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/api/v2/managers/operation_api_manager.py b/app/api/v2/managers/operation_api_manager.py index 368661f8e..d5eece127 100644 --- a/app/api/v2/managers/operation_api_manager.py +++ b/app/api/v2/managers/operation_api_manager.py @@ -87,6 +87,8 @@ async def update_operation_link(self, operation_id: str, link_id: str, link_data if not link.is_valid_status(link_status): raise JsonHttpBadRequest(f'Cannot update link {link_id} due to invalid link status.') link.status = link_status + if link.can_ignore(): + operation.add_ignored_link(link.id) return link.display async def create_potential_link(self, operation_id: str, data: dict, access: BaseWorld.Access): diff --git a/app/objects/c_operation.py b/app/objects/c_operation.py index 647a3437e..579824725 100644 --- a/app/objects/c_operation.py +++ b/app/objects/c_operation.py @@ -234,7 +234,7 @@ async def wait_for_links_completion(self, link_ids): for link_id in link_ids: link = [link for link in self.chain if link.id == link_id][0] if link.can_ignore(): - self.ignored_links.add(link.id) + self.add_ignored_link(link.id) member = [member for member in self.agents if member.paw == link.paw][0] while not (link.finish or link.can_ignore()): await asyncio.sleep(5) @@ -256,6 +256,9 @@ async def is_finished(self): def link_status(self): return -3 if self.autonomous else -1 + def add_ignored_link(self, link_id): + self.ignored_links.add(link_id) + async def active_agents(self): active = [] for agent in self.agents: @@ -272,7 +275,7 @@ async def get_skipped_abilities_by_agent(self, data_svc): for agent in self.agents: agent_skipped = defaultdict(dict) agent_executors = agent.executors - agent_ran = set([link.ability.ability_id for link in self.chain if link.paw == agent.paw]) + agent_ran = set([link.ability.ability_id for link in self.chain if link.paw == agent.paw and link.finish]) for ab in abilities_by_agent[agent.paw]['all_abilities']: skipped = self._check_reason_skipped(agent=agent, ability=ab, agent_executors=agent_executors, op_facts=[f.trait for f in await self.all_facts()], @@ -437,9 +440,11 @@ async def _unfinished_links_for_agent(self, paw): return [link for link in self.chain if link.paw == paw and not link.finish and not link.can_ignore()] async def _get_all_possible_abilities_by_agent(self, data_svc): - abilities = {'all_abilities': [ab for ab_id in self.adversary.atomic_ordering - for ab in await data_svc.locate('abilities', match=dict(ability_id=ab_id))]} - return {a.paw: abilities for a in self.agents} + abilities_by_agent = {a.paw: {'all_abilities': []} for a in self.agents} + for link in self.chain: + matching_abilities = await data_svc.locate('abilities', match=dict(ability_id=link.ability.ability_id)) + abilities_by_agent[link.paw]['all_abilities'].extend(matching_abilities) + return abilities_by_agent def _check_reason_skipped(self, agent, ability, op_facts, state, agent_executors, agent_ran): if ability.ability_id in agent_ran: From d2d55663db8a2a19840b1b690e4df36a99680816 Mon Sep 17 00:00:00 2001 From: blee Date: Mon, 25 Sep 2023 09:17:12 -0400 Subject: [PATCH 2/4] add test for new helper method --- tests/objects/test_operation.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/objects/test_operation.py b/tests/objects/test_operation.py index 3a84c085f..65f18923a 100644 --- a/tests/objects/test_operation.py +++ b/tests/objects/test_operation.py @@ -587,3 +587,12 @@ async def test_check_reason_skipped_other(self, custom_agent, test_ability, mock assert reason['reason_id'] == Operation.Reason.OTHER.value assert reason['ability_id'] == test_ability.ability_id assert reason['ability_name'] == test_ability.name + + async def test_add_ignored_link(self, make_test_link, operation_agent): + test_agent = operation_agent + test_link = make_test_link(9876, test_agent.paw, Link().states['DISCARD']) + op = Operation(name='test', agents=[test_agent], state='running') + op.add_ignored_link(test_link) + assert op.ignored_links + assert test_link in op.ignored_links + assert len(op.ignored_links) == 1 From 78c3dc7cc1b24749af1fe4a388ee263208c2cd13 Mon Sep 17 00:00:00 2001 From: blee Date: Mon, 25 Sep 2023 09:40:47 -0400 Subject: [PATCH 3/4] consider both adversary profile and operation chain when creating list of all possible agent abilities --- app/objects/c_operation.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/objects/c_operation.py b/app/objects/c_operation.py index 579824725..5efdfc9fb 100644 --- a/app/objects/c_operation.py +++ b/app/objects/c_operation.py @@ -440,10 +440,13 @@ async def _unfinished_links_for_agent(self, paw): return [link for link in self.chain if link.paw == paw and not link.finish and not link.can_ignore()] async def _get_all_possible_abilities_by_agent(self, data_svc): - abilities_by_agent = {a.paw: {'all_abilities': []} for a in self.agents} + abilities = {'all_abilities': [ab for ab_id in self.adversary.atomic_ordering + for ab in await data_svc.locate('abilities', match=dict(ability_id=ab_id))]} + abilities_by_agent = {a.paw: abilities for a in self.agents} for link in self.chain: - matching_abilities = await data_svc.locate('abilities', match=dict(ability_id=link.ability.ability_id)) - abilities_by_agent[link.paw]['all_abilities'].extend(matching_abilities) + if link.ability.ability_id not in self.adversary.atomic_ordering: + matching_abilities = await data_svc.locate('abilities', match=dict(ability_id=link.ability.ability_id)) + abilities_by_agent[link.paw]['all_abilities'].extend(matching_abilities) return abilities_by_agent def _check_reason_skipped(self, agent, ability, op_facts, state, agent_executors, agent_ran): From 5b3610ec9f38e505b91a9bb5961de8d7fe70dc6f Mon Sep 17 00:00:00 2001 From: blee Date: Fri, 13 Oct 2023 13:17:21 -0400 Subject: [PATCH 4/4] fix operation tests --- tests/objects/test_operation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/objects/test_operation.py b/tests/objects/test_operation.py index 65f18923a..d3d4ecc8a 100644 --- a/tests/objects/test_operation.py +++ b/tests/objects/test_operation.py @@ -592,7 +592,7 @@ async def test_add_ignored_link(self, make_test_link, operation_agent): test_agent = operation_agent test_link = make_test_link(9876, test_agent.paw, Link().states['DISCARD']) op = Operation(name='test', agents=[test_agent], state='running') - op.add_ignored_link(test_link) + op.add_ignored_link(test_link.id) assert op.ignored_links - assert test_link in op.ignored_links + assert test_link.id in op.ignored_links assert len(op.ignored_links) == 1