From 843388fff1748f2baae30cd96bed75fc327251c7 Mon Sep 17 00:00:00 2001 From: Ken Payne Date: Tue, 7 Feb 2023 13:25:48 +0000 Subject: [PATCH 01/10] set max_records_limit during tap testing --- singer_sdk/testing/config.py | 2 ++ singer_sdk/testing/runners.py | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/singer_sdk/testing/config.py b/singer_sdk/testing/config.py index f6e010d36..87708bf13 100644 --- a/singer_sdk/testing/config.py +++ b/singer_sdk/testing/config.py @@ -10,11 +10,13 @@ class SuiteConfig: """Test Suite Config, passed to each test. Args: + max_records_limit: Max records to fetch during tap testing. ignore_no_records: Ignore stream test failures if stream returns no records, for all streams. ignore_no_records_for_streams: Ignore stream test failures if stream returns no records, for named streams. """ + max_records_limit: int | None = 5 ignore_no_records: bool = False ignore_no_records_for_streams: list[str] = field(default_factory=list) diff --git a/singer_sdk/testing/runners.py b/singer_sdk/testing/runners.py index 67519b51d..d8a900ca2 100644 --- a/singer_sdk/testing/runners.py +++ b/singer_sdk/testing/runners.py @@ -112,7 +112,12 @@ def tap(self) -> Tap: Returns: A configured Tap instance. """ - return cast(Tap, self.create()) + new_tap = cast(Tap, self.create()) + # apply max_records_limit if set + if self.suite_config.max_records_limit is not None: + for stream in new_tap.streams.values(): + stream._MAX_RECORDS_LIMIT = self.suite_config.max_records_limit + return new_tap def run_discovery(self) -> str: """Run tap discovery. From 3047aa0d6b5ffa4db4ae907be8b673a39f11250d Mon Sep 17 00:00:00 2001 From: Ken Payne Date: Tue, 7 Feb 2023 13:29:41 +0000 Subject: [PATCH 02/10] make default max_records_limit None. --- singer_sdk/testing/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/singer_sdk/testing/config.py b/singer_sdk/testing/config.py index 87708bf13..ebdc81ff7 100644 --- a/singer_sdk/testing/config.py +++ b/singer_sdk/testing/config.py @@ -17,6 +17,6 @@ class SuiteConfig: no records, for named streams. """ - max_records_limit: int | None = 5 + max_records_limit: int | None = None ignore_no_records: bool = False ignore_no_records_for_streams: list[str] = field(default_factory=list) From c688d76f23f948b49a59fac1aec80910b38f9b62 Mon Sep 17 00:00:00 2001 From: Ken Payne Date: Tue, 7 Feb 2023 13:36:54 +0000 Subject: [PATCH 03/10] unblock ci From e5d45764c2405fade6dabce53c164ae0d91d89e2 Mon Sep 17 00:00:00 2001 From: Ken Payne Date: Tue, 7 Feb 2023 14:53:22 +0000 Subject: [PATCH 04/10] apply suite_config to runners --- singer_sdk/testing/factory.py | 16 ++++++++-------- singer_sdk/testing/runners.py | 2 +- tests/samples/test_tap_countries.py | 4 +++- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/singer_sdk/testing/factory.py b/singer_sdk/testing/factory.py index 8c2a63d8b..71380299b 100644 --- a/singer_sdk/testing/factory.py +++ b/singer_sdk/testing/factory.py @@ -33,7 +33,6 @@ def get_test_class( Returns: A test class usable by pytest. """ - suite_config = suite_config or SuiteConfig() class BaseTestClass: """Base test class.""" @@ -43,7 +42,7 @@ class BaseTestClass: @pytest.fixture def config(self) -> SuiteConfig: - return suite_config or SuiteConfig() + return suite_config if suite_config is not None else SuiteConfig() @pytest.fixture def resource(self) -> Any: # noqa: ANN401 @@ -190,10 +189,10 @@ def get_tap_test_class( if "parse_env_config" not in kwargs: kwargs["parse_env_config"] = True - suite_config = suite_config or SuiteConfig() - return get_test_class( - test_runner=TapTestRunner(tap_class=tap_class, config=config, **kwargs), + test_runner=TapTestRunner( + tap_class=tap_class, config=config, suite_config=suite_config, **kwargs + ), test_suites=suites, suite_config=suite_config, ) @@ -226,11 +225,12 @@ def get_target_test_class( if "parse_env_config" not in kwargs: kwargs["parse_env_config"] = True - suite_config = suite_config or SuiteConfig() - return get_test_class( test_runner=TargetTestRunner( - target_class=target_class, config=config, **kwargs + target_class=target_class, + config=config, + suite_config=suite_config, + **kwargs, ), test_suites=suites, suite_config=suite_config, diff --git a/singer_sdk/testing/runners.py b/singer_sdk/testing/runners.py index d8a900ca2..bff170a3f 100644 --- a/singer_sdk/testing/runners.py +++ b/singer_sdk/testing/runners.py @@ -42,7 +42,7 @@ def __init__( self.singer_class = singer_class self.config = config or {} self.default_kwargs = kwargs - self.suite_config = suite_config or SuiteConfig() + self.suite_config = suite_config if suite_config is not None else SuiteConfig() @staticmethod def _clean_sync_output(raw_records: str) -> list[dict]: diff --git a/tests/samples/test_tap_countries.py b/tests/samples/test_tap_countries.py index 9077a7152..4168799ec 100644 --- a/tests/samples/test_tap_countries.py +++ b/tests/samples/test_tap_countries.py @@ -13,13 +13,15 @@ pop_deselected_record_properties, ) from singer_sdk.testing import get_tap_test_class +from singer_sdk.testing.config import SuiteConfig SAMPLE_CONFIG = {} SAMPLE_CONFIG_BAD = {"not": "correct"} # standard tap tests TestSampleTapCountries = get_tap_test_class( - tap_class=SampleTapCountries, config=SAMPLE_CONFIG + tap_class=SampleTapCountries, + config=SAMPLE_CONFIG, ) From 24a61635bc97dc104d571528bafd566f0830e013 Mon Sep 17 00:00:00 2001 From: Ken Payne Date: Tue, 7 Feb 2023 15:28:29 +0000 Subject: [PATCH 05/10] syntax --- singer_sdk/testing/factory.py | 2 +- singer_sdk/testing/runners.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/singer_sdk/testing/factory.py b/singer_sdk/testing/factory.py index 71380299b..758eb68e8 100644 --- a/singer_sdk/testing/factory.py +++ b/singer_sdk/testing/factory.py @@ -42,7 +42,7 @@ class BaseTestClass: @pytest.fixture def config(self) -> SuiteConfig: - return suite_config if suite_config is not None else SuiteConfig() + return suite_config or SuiteConfig() @pytest.fixture def resource(self) -> Any: # noqa: ANN401 diff --git a/singer_sdk/testing/runners.py b/singer_sdk/testing/runners.py index bff170a3f..d8a900ca2 100644 --- a/singer_sdk/testing/runners.py +++ b/singer_sdk/testing/runners.py @@ -42,7 +42,7 @@ def __init__( self.singer_class = singer_class self.config = config or {} self.default_kwargs = kwargs - self.suite_config = suite_config if suite_config is not None else SuiteConfig() + self.suite_config = suite_config or SuiteConfig() @staticmethod def _clean_sync_output(raw_records: str) -> list[dict]: From 01ffdc289c0e6fe83cc6b8c460075b035b8ad877 Mon Sep 17 00:00:00 2001 From: Ken Payne Date: Tue, 7 Feb 2023 15:30:28 +0000 Subject: [PATCH 06/10] unused import --- tests/samples/test_tap_countries.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/samples/test_tap_countries.py b/tests/samples/test_tap_countries.py index 4168799ec..585654983 100644 --- a/tests/samples/test_tap_countries.py +++ b/tests/samples/test_tap_countries.py @@ -13,7 +13,6 @@ pop_deselected_record_properties, ) from singer_sdk.testing import get_tap_test_class -from singer_sdk.testing.config import SuiteConfig SAMPLE_CONFIG = {} SAMPLE_CONFIG_BAD = {"not": "correct"} From ce0adb6a8a4c7d58d0160e12a1599cc48b10976e Mon Sep 17 00:00:00 2001 From: Ken Payne Date: Wed, 8 Feb 2023 11:24:42 +0000 Subject: [PATCH 07/10] use partitioned stream state when checking max records --- singer_sdk/streams/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/singer_sdk/streams/core.py b/singer_sdk/streams/core.py index dff5e0364..0b35972b1 100644 --- a/singer_sdk/streams/core.py +++ b/singer_sdk/streams/core.py @@ -1034,7 +1034,7 @@ def _sync_records( ) raise ex - self._check_max_record_limit(record_count) + self._check_max_record_limit(partition_record_count) if selected: if ( From 63a60513803b4de78c8cd9f8f45334c919407277 Mon Sep 17 00:00:00 2001 From: Ken Payne Date: Wed, 8 Feb 2023 12:25:15 +0000 Subject: [PATCH 08/10] exclude testing from coverage --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index f1a48407b..d86213b10 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -173,6 +173,7 @@ omit = [ "tests/*", "samples/*", "singer_sdk/helpers/_compat.py", + "singer_sdk/testing/*", ] [tool.coverage.report] From 936ffeb53c343cd4e8e2890c1a4026ee6975e9bf Mon Sep 17 00:00:00 2001 From: Ken Payne Date: Tue, 14 Feb 2023 16:13:15 +0000 Subject: [PATCH 09/10] Update pyproject.toml --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7b3d5ed6b..48de72854 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -175,7 +175,6 @@ omit = [ "tests/*", "samples/*", "singer_sdk/helpers/_compat.py", - "singer_sdk/testing/*", ] [tool.coverage.report] From a92f23b5c094eea62b4742e8f25bacbccd7c8e12 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 30 Mar 2023 14:34:53 +0000 Subject: [PATCH 10/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- singer_sdk/testing/factory.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/singer_sdk/testing/factory.py b/singer_sdk/testing/factory.py index e45b29ea4..17b782b93 100644 --- a/singer_sdk/testing/factory.py +++ b/singer_sdk/testing/factory.py @@ -189,7 +189,10 @@ def get_tap_test_class( return get_test_class( test_runner=TapTestRunner( - tap_class=tap_class, config=config, suite_config=suite_config, **kwargs + tap_class=tap_class, + config=config, + suite_config=suite_config, + **kwargs, ), test_suites=suites, suite_config=suite_config,