From b415736c8d34580aafde7b00784d6297868d4fdd Mon Sep 17 00:00:00 2001 From: Tomas Kukan Date: Thu, 2 May 2024 23:40:50 +0200 Subject: [PATCH 01/10] basic endpoint for triggers --- kbcstorage/base.py | 26 +++++++ kbcstorage/triggers.py | 114 ++++++++++++++++++++++++++++++ tests/mocks/test_triggers.py | 98 +++++++++++++++++++++++++ tests/mocks/triggers_responses.py | 58 +++++++++++++++ 4 files changed, 296 insertions(+) create mode 100644 kbcstorage/triggers.py create mode 100644 tests/mocks/test_triggers.py create mode 100644 tests/mocks/triggers_responses.py diff --git a/kbcstorage/base.py b/kbcstorage/base.py index ab36a00..5b12f53 100644 --- a/kbcstorage/base.py +++ b/kbcstorage/base.py @@ -120,6 +120,32 @@ def _post(self, *args, **kwargs): else: return r.json() + def _put(self, *args, **kwargs): + """ + Construct a requests PUT call with args and kwargs and process the + results. + + Args: + *args: Positional arguments to pass to the post request. + **kwargs: Key word arguments to pass to the post request. + + Returns: + body: Response body parsed from json. + + Raises: + requests.HTTPError: If the API request fails. + """ + headers = kwargs.pop('headers', {}) + headers.update(self._auth_header) + r = requests.put(headers=headers, *args, **kwargs) + try: + r.raise_for_status() + except requests.HTTPError: + # Handle different error codes + raise + else: + return r.json() + def _delete(self, *args, **kwargs): """ Construct a requests DELETE call with args and kwargs and process the diff --git a/kbcstorage/triggers.py b/kbcstorage/triggers.py new file mode 100644 index 0000000..464952d --- /dev/null +++ b/kbcstorage/triggers.py @@ -0,0 +1,114 @@ +""" +Manages calls to the Storage API relating to triggers + +Full documentation `here`. + +.. _here: + http://docs.keboola.apiary.io/#reference/triggers/ +""" +from kbcstorage.base import Endpoint + + +class Triggers(Endpoint): + """ + Triggers Endpoint + """ + + def __init__(self, root_url, token): + """ + Create a Triggers endpoint. + + Args: + root_url (:obj:`str`): The base url for the API. + token (:obj:`str`): A storage API key. + """ + super().__init__(root_url, 'triggers', token) + + def list(self): + """ + List all triggers in project. + + Returns: + response_body: The parsed json from the HTTP response. + + Raises: + requests.HTTPError: If the API request fails. + """ + + return self._get(self.base_url) + + def detail(self, trigger_id): + """ + Retrieves information about a given trigger. + + Args: + trigger_id (str): The id of the trigger. + + Raises: + requests.HTTPError: If the API request fails. + """ + url = '{}/{}'.format(self.base_url, trigger_id) + + return self._get(url) + + def create(self, runWithTokenId, component, configurationId, coolDownPeriodMinutes, tableIds): + """ + Create a new trigger. + + Args: + runWithTokenId (int): ID of token used for running configured component. + component (str): For now we support only 'orchestration'. + configurationId (int): Id of component configuration. + coolDownPeriodMinutes (int): Minimal cool down period before + firing action again in minutes (min is 1 minute). + tableIds (list[str]) IDs of tables. + Returns: + response_body: The parsed json from the HTTP response. + + Raises: + requests.HTTPError: If the API request fails. + """ + # Separating create and link into two distinct functions... + # Need to check args... + body = { + "runWithTokenId": runWithTokenId, + "component": component, + "configurationId": configurationId, + "coolDownPeriodMinutes": coolDownPeriodMinutes, + "tableIds": tableIds + } + + return self._post(self.base_url, data=body) + + def delete(self, trigger_id): + """ + Delete a trigger referenced by ``trigger_id``. + + Args: + trigger_id (int): The id of the trigger to be deleted. + + """ + url = '{}/{}'.format(self.base_url, trigger_id) + self._delete(url) + + def update(self, trigger_id, runWithTokenId=None, component=None, configurationId=None, + coolDownPeriodMinutes=None, tableIds=None): + """ + Delete a trigger referenced by ``trigger_id``. + + Args: + trigger_id (int): The id of the trigger to be deleted. + + """ + url = '{}/{}'.format(self.base_url, trigger_id) + body = { + k: v for k, v in { + "runWithTokenId": runWithTokenId, + "component": component, + "configurationId": configurationId, + "coolDownPeriodMinutes": coolDownPeriodMinutes, + "tableIds": tableIds + }.items() + if v is not None + } + self._put(url, data=body) diff --git a/tests/mocks/test_triggers.py b/tests/mocks/test_triggers.py new file mode 100644 index 0000000..31ef2cb --- /dev/null +++ b/tests/mocks/test_triggers.py @@ -0,0 +1,98 @@ +import unittest +import responses +from kbcstorage.triggers import Triggers +from .triggers_responses import list_response, detail_response, create_response, update_response + + +class TestTriggersWithMocks(unittest.TestCase): + def setUp(self): + token = 'dummy_token' + base_url = 'https://connection.keboola.com/' + self.triggers = Triggers(base_url, token) + + @responses.activate + def test_list(self): + """ + triggers mocks list correctly. + """ + responses.add( + responses.Response( + method='GET', + url='https://connection.keboola.com/v2/storage/triggers', + json=list_response + ) + ) + triggers_list = self.triggers.list() + assert isinstance(triggers_list, list) + + @responses.activate + def test_detail_by_id(self): + """ + triggers mocks detail by integer id correctly. + """ + responses.add( + responses.Response( + method='GET', + url='https://connection.keboola.com/v2/storage/triggers/3', + json=detail_response + ) + ) + trigger_id = '3' + trigger_detail = self.triggers.detail(trigger_id) + assert trigger_detail['id'] == '3' + + @responses.activate + def test_delete(self): + """ + Triggers mock deletes trigger by id. + """ + responses.add( + responses.Response( + method='DELETE', + url='https://connection.keboola.com/v2/storage/triggers/1', + json={} + ) + ) + trigger_id = 1 + deleted_detail = self.triggers.delete(trigger_id) + assert deleted_detail is None + + @responses.activate + def test_update(self): + """ + Triggers mock update trigger by id. + """ + responses.add( + responses.Response( + method='PUT', + url='https://connection.keboola.com/v2/storage/triggers/1', + json=update_response + ) + ) + trigger_id = 1 + deleted_detail = self.triggers.update(trigger_id, runWithTokenId=100) + assert deleted_detail is None + + @responses.activate + def test_create(self): + """ + Triggers mock creates new trigger. + """ + responses.add( + responses.Response( + method='POST', + url='https://connection.keboola.com/v2/storage/triggers', + json=create_response + ) + ) + created_detail = self.triggers.create( + runWithTokenId=123, + component="orchestration", + configurationId=123, + coolDownPeriodMinutes=20, + tableIds=[ + "in.c-test.watched-1", + "in.c-prod.watched-5" + ] + ) + assert created_detail['runWithTokenId'] == 123 diff --git a/tests/mocks/triggers_responses.py b/tests/mocks/triggers_responses.py new file mode 100644 index 0000000..624c1b8 --- /dev/null +++ b/tests/mocks/triggers_responses.py @@ -0,0 +1,58 @@ +list_response = [ + { + "id": "3", + "runWithTokenId": 123, + "component": "orchestration", + "configurationId": "config-100", + "lastRun": "2017-02-13T16:42:00+0100", + "coolDownPeriodMinutes": 20, + "creatorToken": { + "id": 1, + "description": "dev@keboola.com" + }, + "tables": [ + { + "tableId": "in.c-test.watched-1" + }, + { + "tableId": "in.c-prod.watched-5" + } + ] + } +] + +detail_response = { + "id": "3", + "runWithTokenId": 123, + "component": "orchestration", + "configurationId": "config-100", + "lastRun": "2017-02-13T16:42:00+0100", + "coolDownPeriodMinutes": 20, + "creatorToken": { + "id": 1, + "description": "dev@keboola.com" + }, + "tables": [ + { + "tableId": "in.c-test.watched-1" + }, + { + "tableId": "in.c-prod.watched-5" + } + ] +} + +update_response = { + "runWithTokenId": 100 +} + +create_response = { + "runWithTokenId": 123, + "component": "orchestration", + "configurationId": 123, + "coolDownPeriodMinutes": 20, + "tableIds": [ + "in.c-test.watched-1", + "in.c-prod.watched-5" + ] +} From 4b61f5b4d4cb58120bd6d41a14b4af6b07cfe64c Mon Sep 17 00:00:00 2001 From: Tomas Kukan Date: Fri, 3 May 2024 09:25:11 +0200 Subject: [PATCH 02/10] fix --- kbcstorage/triggers.py | 2 +- tests/mocks/test_triggers.py | 4 ++-- tests/mocks/triggers_responses.py | 19 ++++++++++++++++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/kbcstorage/triggers.py b/kbcstorage/triggers.py index 464952d..e48d073 100644 --- a/kbcstorage/triggers.py +++ b/kbcstorage/triggers.py @@ -111,4 +111,4 @@ def update(self, trigger_id, runWithTokenId=None, component=None, configurationI }.items() if v is not None } - self._put(url, data=body) + return self._put(url, data=body) diff --git a/tests/mocks/test_triggers.py b/tests/mocks/test_triggers.py index 31ef2cb..5b67e19 100644 --- a/tests/mocks/test_triggers.py +++ b/tests/mocks/test_triggers.py @@ -70,8 +70,8 @@ def test_update(self): ) ) trigger_id = 1 - deleted_detail = self.triggers.update(trigger_id, runWithTokenId=100) - assert deleted_detail is None + updated_detail = self.triggers.update(trigger_id, runWithTokenId=100) + assert updated_detail['id'] == '3' @responses.activate def test_create(self): diff --git a/tests/mocks/triggers_responses.py b/tests/mocks/triggers_responses.py index 624c1b8..da64214 100644 --- a/tests/mocks/triggers_responses.py +++ b/tests/mocks/triggers_responses.py @@ -43,7 +43,24 @@ } update_response = { - "runWithTokenId": 100 + "id": "3", + "runWithTokenId": 123, + "component": "orchestration", + "configurationId": "config-100", + "lastRun": "2017-02-13T16:42:00+0100", + "coolDownPeriodMinutes": 20, + "creatorToken": { + "id": 1, + "description": "dev@keboola.com" + }, + "tables": [ + { + "tableId": "in.c-test.watched-1" + }, + { + "tableId": "in.c-prod.watched-5" + } + ] } create_response = { From 460879aac946774fca0bfe13281076c1ffab0c4e Mon Sep 17 00:00:00 2001 From: Tomas Kukan Date: Fri, 3 May 2024 15:10:28 +0200 Subject: [PATCH 03/10] add func test --- tests/functional/test_triggers.py | 65 +++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 tests/functional/test_triggers.py diff --git a/tests/functional/test_triggers.py b/tests/functional/test_triggers.py new file mode 100644 index 0000000..7984a0d --- /dev/null +++ b/tests/functional/test_triggers.py @@ -0,0 +1,65 @@ +import os +import warnings + +from kbcstorage.triggers import Triggers +from tests.base_test_case import BaseTestCase + + +class TestEndpoint(BaseTestCase): + def setUp(self): + self.triggers = Triggers(os.getenv('KBC_TEST_API_URL'), os.getenv('KBC_TEST_TOKEN')) + required_envs = ['KBC_TOKEN_ID', 'KBC_COMPONENT', 'KBC_CONFIGURATION_ID', 'KBC_TABLE_ID'] + for env in required_envs: + if os.getenv(env) is None: + print(env + ' is not configured') + exit(1) + self.token_id = int(os.getenv("KBC_TOKEN_ID")) + self.component = os.getenv("KBC_COMPONENT") + self.table_id = os.getenv("KBC_TABLE_ID") + self.configuration_id = int(os.getenv("configurationId")) + + self.created_trigger_ids = [] + # https://github.com/boto/boto3/issues/454 + warnings.simplefilter("ignore", ResourceWarning) + + def test_steps(self): + self.create_trigger() + self.list_triggers() + self.trigger_detail() + self.update_trigger() + self.delete_triggers() + + def create_trigger(self): + trigger_id = self.triggers.create( + runWithTokenId=self.token_id, + component=self.component, + configurationId=self.configuration_id, + coolDownPeriodMinutes=10, + tableIds=[self.table_id] + )['id'] + self.created_trigger_ids.append(trigger_id) + self.assertEqual(trigger_id, self.triggers.detail(trigger_id)['id']) + + def trigger_detail(self): + assert len(self.created_trigger_ids) > 0 + first_id = self.created_trigger_ids[0] + detail = self.triggers.detail(first_id) + assert detail["id"] == first_id + + def list_triggers(self): + assert len(self.created_trigger_ids) > 0 + all_triggers = self.triggers.list() + api_trigger_ids = {x["id"] for x in all_triggers} + created_trigger_ids = {x for x in self.created_trigger_ids} + assert created_trigger_ids.issubset(api_trigger_ids) + + def update_trigger(self): + assert len(self.created_trigger_ids) > 0 + first_id = self.created_trigger_ids[0] + self.triggers.update(first_id, coolDownPeriodMinutes=100) + detail = self.triggers.detail(first_id) + assert detail["coolDownPeriodMinutes"] == 100 + + def delete_triggers(self): + for t_id in self.created_trigger_ids: + self.triggers.delete(t_id) From 0cd6509649435b8d5df10775eb365a5f7a0a1a26 Mon Sep 17 00:00:00 2001 From: Tomas Kukan Date: Sun, 5 May 2024 23:49:51 +0200 Subject: [PATCH 04/10] improve trigger testing --- kbcstorage/triggers.py | 15 +++++-- tests/functional/test_triggers.py | 75 ++++++++++++++++++++++++------- 2 files changed, 71 insertions(+), 19 deletions(-) diff --git a/kbcstorage/triggers.py b/kbcstorage/triggers.py index e48d073..50de5d9 100644 --- a/kbcstorage/triggers.py +++ b/kbcstorage/triggers.py @@ -78,7 +78,7 @@ def create(self, runWithTokenId, component, configurationId, coolDownPeriodMinut "tableIds": tableIds } - return self._post(self.base_url, data=body) + return self._post(self.base_url, json=body) def delete(self, trigger_id): """ @@ -94,11 +94,20 @@ def delete(self, trigger_id): def update(self, trigger_id, runWithTokenId=None, component=None, configurationId=None, coolDownPeriodMinutes=None, tableIds=None): """ - Delete a trigger referenced by ``trigger_id``. + Update a trigger referenced by ``trigger_id``. Args: - trigger_id (int): The id of the trigger to be deleted. + runWithTokenId (int): ID of token used for running configured component. + component (str): For now we support only 'orchestration'. + configurationId (int): Id of component configuration. + coolDownPeriodMinutes (int): Minimal cool down period before + firing action again in minutes (min is 1 minute). + tableIds (list[str]) IDs of tables. + Returns: + response_body: The parsed json from the HTTP response. + Raises: + requests.HTTPError: If the API request fails. """ url = '{}/{}'.format(self.base_url, trigger_id) body = { diff --git a/tests/functional/test_triggers.py b/tests/functional/test_triggers.py index 7984a0d..bb8527e 100644 --- a/tests/functional/test_triggers.py +++ b/tests/functional/test_triggers.py @@ -1,27 +1,70 @@ import os +import tempfile import warnings +from requests import exceptions + +from base import Endpoint +from configurations import Configurations +from jobs import Jobs from kbcstorage.triggers import Triggers +from kbcstorage.tables import Tables +from kbcstorage.buckets import Buckets from tests.base_test_case import BaseTestCase +class Tokens(Endpoint): + """ + Testing class for obtaining token ID from token. + """ + + def __init__(self, root_url, token): + super().__init__(root_url, 'tokens', token) + + def verify(self): + url = '{}/verify'.format(self.base_url) + return self._get(url) + + class TestEndpoint(BaseTestCase): + TEST_BUCKET_NAME = "kbc_trigger_test_bucket" + TEST_BUCKET_ID = f"in.c-{TEST_BUCKET_NAME}" + TEST_TABLE_NAME = "kbc_trigger_test_table" + def setUp(self): - self.triggers = Triggers(os.getenv('KBC_TEST_API_URL'), os.getenv('KBC_TEST_TOKEN')) - required_envs = ['KBC_TOKEN_ID', 'KBC_COMPONENT', 'KBC_CONFIGURATION_ID', 'KBC_TABLE_ID'] - for env in required_envs: - if os.getenv(env) is None: - print(env + ' is not configured') - exit(1) - self.token_id = int(os.getenv("KBC_TOKEN_ID")) - self.component = os.getenv("KBC_COMPONENT") - self.table_id = os.getenv("KBC_TABLE_ID") - self.configuration_id = int(os.getenv("configurationId")) + self.root_url = os.getenv('KBC_TEST_API_URL') + self.token = os.getenv('KBC_TEST_TOKEN') + + self.triggers = Triggers(self.root_url, self.token) + self.tables = Tables(self.root_url, self.token) + self.buckets = Buckets(self.root_url, self.token) + self.jobs = Jobs(self.root_url, self.token) + self.configurations = Configurations(self.root_url, self.token, 'default') + self.tokens = Tokens(self.root_url, self.token) self.created_trigger_ids = [] # https://github.com/boto/boto3/issues/454 warnings.simplefilter("ignore", ResourceWarning) + self.clean() + self.token_id = self.tokens.verify()["id"] + self.buckets.create(self.TEST_BUCKET_NAME) + with tempfile.NamedTemporaryFile(delete=False) as tmp_file: + tmp_file.write(b"a,b,c\n1,2,3\n") + self.table_id = self.tables.create(self.TEST_BUCKET_ID, self.TEST_TABLE_NAME, tmp_file.name) + self.component = self.TEST_COMPONENT_NAME + self.configuration_id = self.configurations.create(self.TEST_COMPONENT_NAME, 'trigger_test_config')["id"] + + def clean(self): + try: + self.buckets.delete(self.TEST_BUCKET_ID, True) + except exceptions.HTTPError as e: + if e.response.status_code != 404: + raise + + def tearDown(self): + self.clean() + def test_steps(self): self.create_trigger() self.list_triggers() @@ -41,24 +84,24 @@ def create_trigger(self): self.assertEqual(trigger_id, self.triggers.detail(trigger_id)['id']) def trigger_detail(self): - assert len(self.created_trigger_ids) > 0 + self.assertTrue(len(self.created_trigger_ids) > 0) first_id = self.created_trigger_ids[0] detail = self.triggers.detail(first_id) - assert detail["id"] == first_id + self.assertTrue(detail["id"] == first_id) def list_triggers(self): - assert len(self.created_trigger_ids) > 0 + self.assertTrue(len(self.created_trigger_ids) > 0) all_triggers = self.triggers.list() api_trigger_ids = {x["id"] for x in all_triggers} created_trigger_ids = {x for x in self.created_trigger_ids} - assert created_trigger_ids.issubset(api_trigger_ids) + self.assertTrue(created_trigger_ids.issubset(api_trigger_ids)) def update_trigger(self): - assert len(self.created_trigger_ids) > 0 + self.assertTrue(len(self.created_trigger_ids) > 0) first_id = self.created_trigger_ids[0] self.triggers.update(first_id, coolDownPeriodMinutes=100) detail = self.triggers.detail(first_id) - assert detail["coolDownPeriodMinutes"] == 100 + self.assertTrue(detail["coolDownPeriodMinutes"] == 100) def delete_triggers(self): for t_id in self.created_trigger_ids: From dff90daa18a5f5963db6e95dc919629e3b908fdb Mon Sep 17 00:00:00 2001 From: Tomas Kukan Date: Mon, 6 May 2024 09:35:46 +0200 Subject: [PATCH 05/10] assert trigger details --- tests/functional/test_triggers.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/functional/test_triggers.py b/tests/functional/test_triggers.py index bb8527e..fce008e 100644 --- a/tests/functional/test_triggers.py +++ b/tests/functional/test_triggers.py @@ -87,6 +87,11 @@ def trigger_detail(self): self.assertTrue(len(self.created_trigger_ids) > 0) first_id = self.created_trigger_ids[0] detail = self.triggers.detail(first_id) + self.assertTrue(detail["runWithTokenId"] == int(self.token_id)) + self.assertTrue(detail["component"] == self.component) + self.assertTrue(detail["configurationId"] == self.configuration_id) + self.assertTrue(detail["coolDownPeriodMinutes"] == 10) + self.assertTrue([t['tableId'] for t in detail["tables"]] == [self.table_id]) self.assertTrue(detail["id"] == first_id) def list_triggers(self): From 94746ba511ff049bf4c62300f1c0f3da62265c03 Mon Sep 17 00:00:00 2001 From: Tomas Kukan Date: Mon, 6 May 2024 09:36:52 +0200 Subject: [PATCH 06/10] fix imports --- tests/functional/test_triggers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/functional/test_triggers.py b/tests/functional/test_triggers.py index fce008e..1b1dd66 100644 --- a/tests/functional/test_triggers.py +++ b/tests/functional/test_triggers.py @@ -4,9 +4,9 @@ from requests import exceptions -from base import Endpoint -from configurations import Configurations -from jobs import Jobs +from kbcstorage.base import Endpoint +from kbcstorage.configurations import Configurations +from kbcstorage.jobs import Jobs from kbcstorage.triggers import Triggers from kbcstorage.tables import Tables from kbcstorage.buckets import Buckets From 489f86a8a6e2d26ac13333a1494a6ee553b0a88f Mon Sep 17 00:00:00 2001 From: Tomas Kukan Date: Tue, 7 May 2024 20:06:21 +0200 Subject: [PATCH 07/10] add triggers to client --- kbcstorage/client.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kbcstorage/client.py b/kbcstorage/client.py index bedc0b3..0e848e8 100644 --- a/kbcstorage/client.py +++ b/kbcstorage/client.py @@ -5,11 +5,12 @@ from kbcstorage.buckets import Buckets from kbcstorage.components import Components from kbcstorage.configurations import Configurations -from kbcstorage.tokens import Tokens -from kbcstorage.workspaces import Workspaces +from kbcstorage.files import Files from kbcstorage.jobs import Jobs from kbcstorage.tables import Tables -from kbcstorage.files import Files +from kbcstorage.tokens import Tokens +from kbcstorage.triggers import Triggers +from kbcstorage.workspaces import Workspaces class Client: @@ -40,6 +41,7 @@ def __init__(self, api_domain, token, branch_id='default'): self.configurations = Configurations(self.root_url, self.token, self.branch_id) self.tokens = Tokens(self.root_url, self.token) self.branches = Branches(self.root_url, self.token) + self.triggers = Triggers(self.root_url, self.token) @property def token(self): From e80acebbe0ec442e2772500d6c9bdf1ab4b790a3 Mon Sep 17 00:00:00 2001 From: Tomas Kukan Date: Thu, 9 May 2024 10:27:53 +0200 Subject: [PATCH 08/10] fix tests --- tests/functional/test_triggers.py | 32 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/functional/test_triggers.py b/tests/functional/test_triggers.py index 1b1dd66..d1470f4 100644 --- a/tests/functional/test_triggers.py +++ b/tests/functional/test_triggers.py @@ -27,9 +27,8 @@ def verify(self): class TestEndpoint(BaseTestCase): - TEST_BUCKET_NAME = "kbc_trigger_test_bucket" - TEST_BUCKET_ID = f"in.c-{TEST_BUCKET_NAME}" - TEST_TABLE_NAME = "kbc_trigger_test_table" + TEST_BUCKET_NAME = "trigger_test_bucket" + TEST_TABLE_NAME = "trigger_test_table" def setUp(self): self.root_url = os.getenv('KBC_TEST_API_URL') @@ -48,16 +47,17 @@ def setUp(self): self.clean() self.token_id = self.tokens.verify()["id"] - self.buckets.create(self.TEST_BUCKET_NAME) + self.test_bucket_id = self.buckets.create(self.TEST_BUCKET_NAME)['id'] with tempfile.NamedTemporaryFile(delete=False) as tmp_file: tmp_file.write(b"a,b,c\n1,2,3\n") - self.table_id = self.tables.create(self.TEST_BUCKET_ID, self.TEST_TABLE_NAME, tmp_file.name) + self.table_id = self.tables.create(self.test_bucket_id, self.TEST_TABLE_NAME, tmp_file.name) self.component = self.TEST_COMPONENT_NAME self.configuration_id = self.configurations.create(self.TEST_COMPONENT_NAME, 'trigger_test_config')["id"] def clean(self): try: - self.buckets.delete(self.TEST_BUCKET_ID, True) + if hasattr(self, "test_bucket_id"): + self.buckets.delete(self.test_bucket_id, True) except exceptions.HTTPError as e: if e.response.status_code != 404: raise @@ -84,29 +84,29 @@ def create_trigger(self): self.assertEqual(trigger_id, self.triggers.detail(trigger_id)['id']) def trigger_detail(self): - self.assertTrue(len(self.created_trigger_ids) > 0) + self.assertEqual(len(self.created_trigger_ids), 0) first_id = self.created_trigger_ids[0] detail = self.triggers.detail(first_id) - self.assertTrue(detail["runWithTokenId"] == int(self.token_id)) - self.assertTrue(detail["component"] == self.component) - self.assertTrue(detail["configurationId"] == self.configuration_id) - self.assertTrue(detail["coolDownPeriodMinutes"] == 10) - self.assertTrue([t['tableId'] for t in detail["tables"]] == [self.table_id]) - self.assertTrue(detail["id"] == first_id) + self.assertEqual(detail["runWithTokenId"], int(self.token_id)) + self.assertEqual(detail["component"], self.component) + self.assertEqual(detail["configurationId"], self.configuration_id) + self.assertEqual(detail["coolDownPeriodMinutes"], 10) + self.assertEqual([t['tableId'] for t in detail["tables"]], [self.table_id]) + self.assertEqual(detail["id"], first_id) def list_triggers(self): - self.assertTrue(len(self.created_trigger_ids) > 0) + self.assertGreater(len(self.created_trigger_ids), 0) all_triggers = self.triggers.list() api_trigger_ids = {x["id"] for x in all_triggers} created_trigger_ids = {x for x in self.created_trigger_ids} self.assertTrue(created_trigger_ids.issubset(api_trigger_ids)) def update_trigger(self): - self.assertTrue(len(self.created_trigger_ids) > 0) + self.assertGreater(len(self.created_trigger_ids), 0) first_id = self.created_trigger_ids[0] self.triggers.update(first_id, coolDownPeriodMinutes=100) detail = self.triggers.detail(first_id) - self.assertTrue(detail["coolDownPeriodMinutes"] == 100) + self.assertEqual(detail["coolDownPeriodMinutes"], 100) def delete_triggers(self): for t_id in self.created_trigger_ids: From 29f03528527b7304afd5b040852ca432649cafb4 Mon Sep 17 00:00:00 2001 From: Tomas Kukan Date: Thu, 9 May 2024 11:08:59 +0200 Subject: [PATCH 09/10] fix tests --- tests/functional/test_triggers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/test_triggers.py b/tests/functional/test_triggers.py index d1470f4..516d641 100644 --- a/tests/functional/test_triggers.py +++ b/tests/functional/test_triggers.py @@ -84,7 +84,7 @@ def create_trigger(self): self.assertEqual(trigger_id, self.triggers.detail(trigger_id)['id']) def trigger_detail(self): - self.assertEqual(len(self.created_trigger_ids), 0) + self.assertGreater(len(self.created_trigger_ids), 0) first_id = self.created_trigger_ids[0] detail = self.triggers.detail(first_id) self.assertEqual(detail["runWithTokenId"], int(self.token_id)) From 2b04f7036fb408e9e011a3dcac6af00776ec89c1 Mon Sep 17 00:00:00 2001 From: Tomas Kukan Date: Thu, 9 May 2024 11:14:02 +0200 Subject: [PATCH 10/10] use already existing impl of Tokens --- tests/functional/test_triggers.py | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/tests/functional/test_triggers.py b/tests/functional/test_triggers.py index 516d641..1141a61 100644 --- a/tests/functional/test_triggers.py +++ b/tests/functional/test_triggers.py @@ -4,28 +4,15 @@ from requests import exceptions -from kbcstorage.base import Endpoint +from kbcstorage.buckets import Buckets from kbcstorage.configurations import Configurations from kbcstorage.jobs import Jobs -from kbcstorage.triggers import Triggers from kbcstorage.tables import Tables -from kbcstorage.buckets import Buckets +from kbcstorage.tokens import Tokens +from kbcstorage.triggers import Triggers from tests.base_test_case import BaseTestCase -class Tokens(Endpoint): - """ - Testing class for obtaining token ID from token. - """ - - def __init__(self, root_url, token): - super().__init__(root_url, 'tokens', token) - - def verify(self): - url = '{}/verify'.format(self.base_url) - return self._get(url) - - class TestEndpoint(BaseTestCase): TEST_BUCKET_NAME = "trigger_test_bucket" TEST_TABLE_NAME = "trigger_test_table"