From 87544b65654f43dc531788e735c7dc48de27271d Mon Sep 17 00:00:00 2001 From: Bryan White Date: Thu, 22 Dec 2022 09:40:19 +0100 Subject: [PATCH] fixup: resolutions tests --- src/genesis/helpers/field_enums.py | 20 +++-- tests/e2e/entities/test_almanac.py | 132 ++++++++++++++++++++++++----- 2 files changed, 123 insertions(+), 29 deletions(-) diff --git a/src/genesis/helpers/field_enums.py b/src/genesis/helpers/field_enums.py index 99d4c18c7..41b64581d 100644 --- a/src/genesis/helpers/field_enums.py +++ b/src/genesis/helpers/field_enums.py @@ -324,11 +324,12 @@ class AlmanacRegistrations(NamedFields): signature = 2 sequence = 3 agent_id = 4 - record_id = 5 - transaction_id = 6 - block_id = 7 - # event_id = 8 - # record_id = 9 + contract_id = 5 + record_id = 6 + transaction_id = 7 + block_id = 8 + # event_id = 9 + # record_id = 10 @classmethod def get_table(self): @@ -337,12 +338,13 @@ def get_table(self): class AlmanacResolutions(NamedFields): id = 0 - address = 1 - record_id = 2 + agent_id = 1 + contract_id = 2 + record_id = 3 @classmethod def get_table(self): - return "almanac_registrations" + return "almanac_resolutions" class AlmanacRecords(NamedFields): @@ -350,7 +352,7 @@ class AlmanacRecords(NamedFields): service = 1 transaction_id = 2 block_id = 3 - # event_id = 4 + # event_id = 4 @classmethod def get_table(self): diff --git a/tests/e2e/entities/test_almanac.py b/tests/e2e/entities/test_almanac.py index 4ccae9745..543d38857 100644 --- a/tests/e2e/entities/test_almanac.py +++ b/tests/e2e/entities/test_almanac.py @@ -7,7 +7,12 @@ from cosmpy.aerial.tx_helpers import SubmittedTx from gql import gql -from src.genesis.helpers.field_enums import Agents, AlmanacRecords, AlmanacRegistrations +from src.genesis.helpers.field_enums import ( + Agents, + AlmanacRecords, + AlmanacRegistrations, + AlmanacResolutions, +) from tests.helpers.contracts import AlmanacContract, DefaultAlmanacContractConfig from tests.helpers.entity_test import EntityTest from tests.helpers.graphql import filtered_test_query @@ -15,6 +20,10 @@ from uagents.src.nexus.crypto import Identity +def gql_by_endpoint_port(resolution_node: Dict) -> int: + return int(resolution_node["record"]["service"]["endpoints"][0]["url"][-4:]) + + def gql_by_expiry_height(registration_node: Dict) -> int: return int(registration_node["expiryHeight"]) @@ -32,13 +41,14 @@ class Scenario: class TestAlmanac(EntityTest): test_registrations_endpoints = [ - "127.0.0.1:9999", - "127.0.0.1:8888", - "127.0.0.1:7777", "127.0.0.1:6666", + "127.0.0.1:7777", + "127.0.0.1:8888", + "127.0.0.1:9999", ] submitted_txs: List[SubmittedTx] = [] expected_registrations: List[Dict] = [] + expected_resolutions: List[Dict] = [] expected_records: List[Dict] = [ { "service": { @@ -92,6 +102,7 @@ def setUpClass(cls): cls.expected_registrations.append( { "agentId": agent_address, + "contractId": str(cls._contract.address), "expiryHeight": tx.response.height + DefaultAlmanacContractConfig.expiry_height, "sequence": sequence, @@ -99,9 +110,106 @@ def setUpClass(cls): "record": expected_record, } ) + cls.expected_resolutions.append( + { + "agentId": agent_address, + "contractId": str(cls._contract.address), + "record": expected_record, + } + ) # NB: wait for the indexer time.sleep(7) + # NB: test resolutions first as it's sensitive to the current height + def test_resolutions_sql(self): + resolutions = self.db_cursor.execute( + AlmanacResolutions.select_query() + ).fetchall() + actual_resolution_count = len(resolutions) + + current_height = int( + self.db_cursor.execute( + """SELECT b.height FROM app.blocks b + ORDER BY b.height + LIMIT 1""" + ).fetchone()[0] + ) + + last_expired_height = ( + current_height - DefaultAlmanacContractConfig.expiry_height + ) + first_unexpired = next( + tx for tx in self.submitted_txs if tx.response.height >= last_expired_height + ) + last_expired_index = self.submitted_txs.index(first_unexpired) - 1 + expected_resolutions = resolutions[last_expired_index + 1 :] + expected_resolutions_count = len(expected_resolutions) + + self.assertEqual(expected_resolutions_count, actual_resolution_count) + # TODO: more assertions + + def test_resolutions_gql(self): + resolutions_query = gql( + """ + query { + almanacResolutions { + nodes { + id + agentId + contractId + record { + id + service + # registrationId + # eventId + transactionId + blockId + } + } + } + } + """ + ) + + current_height = int( + self.db_cursor.execute( + """SELECT b.height FROM app.blocks b + ORDER BY b.height DESC + LIMIT 1""" + ).fetchone()[0] + ) + last_expired_height = ( + current_height - DefaultAlmanacContractConfig.expiry_height + ) + first_unexpired = next( + r for r in self.submitted_txs if r.response.height > last_expired_height + ) + first_unexpired_index = self.submitted_txs.index(first_unexpired) + expected_resolutions = self.expected_resolutions[first_unexpired_index:] + + gql_result = self.gql_client.execute(resolutions_query) + resolutions = gql_result["almanacResolutions"]["nodes"] + self.assertEqual(len(expected_resolutions), len(resolutions)) + + # TODO: use respective gql order by when available + # NB: sort by expiry height so that indexes match + # their respective expected_resolutions index + list.sort(resolutions, key=gql_by_endpoint_port) + self.assertEqual(len(expected_resolutions), len(resolutions)) + + for (i, resolution) in enumerate(resolutions): + self.assertRegex(resolution["id"], msg_id_regex) + self.assertEqual(expected_resolutions[i]["agentId"], resolution["agentId"]) + self.assertEqual(str(self._contract.address), resolution["contractId"]) + record = resolution["record"] + self.assertEqual( + record["service"], + resolution["record"]["service"], + ) + self.assertRegex(record["transactionId"], tx_id_regex) + self.assertRegex(record["blockId"], block_id_regex) + # TODO: assert record equality + def test_registrations_sql(self): registrations = self.db_cursor.execute( AlmanacRegistrations.select_query() @@ -254,22 +362,6 @@ def test_registrations_gql(self): self.assertRegex(registration["blockId"], block_id_regex) # TODO: assert record equality - # GQL query - # - historical registrations: where expired - # - resolutions success - # - resolutions expired (empty result) - # assertions - - def test_resolutions_sql(self): - pass - # SQL query - # assertions - - def test_resolutions_gql(self): - pass - # GQL query - # assertions - if __name__ == "__main__": unittest.main()