diff --git a/doc/changes/changelog.md b/doc/changes/changelog.md index 387930a..d20c016 100644 --- a/doc/changes/changelog.md +++ b/doc/changes/changelog.md @@ -1,3 +1,4 @@ # Changelog +* [0.1.1](changes_0.1.1.md) * [0.1.0](changes_0.1.0.md) \ No newline at end of file diff --git a/doc/changes/changes_0.1.1.md b/doc/changes/changes_0.1.1.md new file mode 100644 index 0000000..9b6e426 --- /dev/null +++ b/doc/changes/changes_0.1.1.md @@ -0,0 +1,14 @@ +# advanced-analytics-framework 0.1.1, released ????-??-?? + +Code name: + +## Summary + +## Bugfixes + +* #206: Fixed download URL of SLC from GitHub releases + +## Refactorings + +* #188: Renamed global pytest fixtures to avoid name clashes +* #208: Replaced access to private attribute by public diff --git a/doc/user_guide/example-udf-script/create.sql b/doc/user_guide/example-udf-script/create.sql index 8a0e1dd..c26c364 100644 --- a/doc/user_guide/example-udf-script/create.sql +++ b/doc/user_guide/example-udf-script/create.sql @@ -40,7 +40,7 @@ class ExampleQueryHandler(UDFQueryHandler): return f"{timestamp} {key} {self.parameter}" def table_query_string(statement: str, **kwargs): - table_name = self.db_table_proxy._db_object_name.fully_qualified + table_name = self.db_table_proxy.fully_qualified return statement.format(table_name=table_name, **kwargs) def table_query(statement: str, **kwargs): diff --git a/exasol/analytics/slc.py b/exasol/analytics/slc.py index 9e0947e..dfa3c44 100644 --- a/exasol/analytics/slc.py +++ b/exasol/analytics/slc.py @@ -7,7 +7,7 @@ LANGUAGE_ALIAS = "PYTHON3_AAF" SLC_NAME = "exasol_advanced_analytics_framework_container" SLC_FILE_NAME = SLC_NAME + "_release.tar.gz" -SLC_URL_FORMATTER = "https://github.com/exasol/advanced_analytics_framework/releases/download/{version}/" + SLC_FILE_NAME +SLC_URL_FORMATTER = "https://github.com/exasol/advanced-analytics-framework/releases/download/{version}/" + SLC_FILE_NAME @contextmanager diff --git a/tests/integration_tests/with_db/fixtures/setup_database_fixture.py b/tests/integration_tests/with_db/fixtures/setup_database_fixture.py index e29bad3..f932d7f 100644 --- a/tests/integration_tests/with_db/fixtures/setup_database_fixture.py +++ b/tests/integration_tests/with_db/fixtures/setup_database_fixture.py @@ -10,7 +10,7 @@ @pytest.fixture(scope="session") -def db_schema_name() -> str: +def itest_db_schema() -> str: """ Overrides default fixture from pytest-exasol-extension. """ @@ -18,11 +18,11 @@ def db_schema_name() -> str: @pytest.fixture(scope="module") -def deployed_scripts(pyexasol_connection, db_schema_name, language_alias) -> None: +def deployed_scripts(pyexasol_connection, itest_db_schema, language_alias) -> None: save_aaf_query_loop_lua_script() ScriptsDeployer( language_alias, - db_schema_name, + itest_db_schema, pyexasol_connection, ).deploy_scripts() @@ -30,9 +30,9 @@ def deployed_scripts(pyexasol_connection, db_schema_name, language_alias) -> Non @pytest.fixture(scope="module") def database_with_slc( deployed_scripts, - db_schema_name, + itest_db_schema, bucketfs_connection_factory, deployed_slc, ) -> Tuple[str, str]: bucketfs_connection_factory(BUCKETFS_CONNECTION_NAME, "my-folder") - return BUCKETFS_CONNECTION_NAME, db_schema_name + return BUCKETFS_CONNECTION_NAME, itest_db_schema diff --git a/tests/unit_tests/query_handler/fixtures.py b/tests/unit_tests/query_handler/fixtures.py index 154df82..2a916ba 100644 --- a/tests/unit_tests/query_handler/fixtures.py +++ b/tests/unit_tests/query_handler/fixtures.py @@ -12,16 +12,16 @@ @pytest.fixture -def prefix() -> str: +def tmp_db_obj_prefix() -> str: return PREFIX @pytest.fixture -def schema() -> str: +def aaf_pytest_db_schema() -> str: return SCHEMA -class TestConnection(Connection): +class ConnectionMock(Connection): @property def name(self) -> str: @@ -41,15 +41,15 @@ def password(self) -> str: @pytest.fixture -def test_connection() -> Connection: - return TestConnection() +def connection_mock() -> Connection: + return ConnectionMock() @pytest.fixture -def test_connection_lookup(test_connection) -> ConnectionLookup: +def connection_lookup_mock(connection_mock) -> ConnectionLookup: def lookup(name: str) -> Connection: - if name == test_connection.name: - return test_connection + if name == connection_mock.name: + return connection_mock else: raise KeyError() @@ -62,7 +62,7 @@ def sample_mounted_bucket(tmp_path): @pytest.fixture -def bucketfs_location(sample_mounted_bucket): +def sample_bucketfs_location(sample_mounted_bucket): return bfs.path.BucketPath("a/b", sample_mounted_bucket) @@ -73,25 +73,25 @@ def mocked_temporary_bucketfs_location(tmp_path): @pytest.fixture -def top_level_query_handler_context( - bucketfs_location: bfs.path.PathLike, - prefix: str, - schema: str, - test_connection_lookup: ConnectionLookup) -> TopLevelQueryHandlerContext: +def top_level_query_handler_context_mock( + sample_bucketfs_location: bfs.path.PathLike, + tmp_db_obj_prefix: str, + aaf_pytest_db_schema: str, + connection_lookup_mock: ConnectionLookup) -> TopLevelQueryHandlerContext: query_handler_context = TopLevelQueryHandlerContext( - temporary_bucketfs_location=bucketfs_location, - temporary_db_object_name_prefix=prefix, - connection_lookup=test_connection_lookup, - temporary_schema_name=schema + temporary_bucketfs_location=sample_bucketfs_location, + temporary_db_object_name_prefix=tmp_db_obj_prefix, + connection_lookup=connection_lookup_mock, + temporary_schema_name=aaf_pytest_db_schema, ) return query_handler_context @pytest.fixture(params=["top", "child"]) -def scope_query_handler_context( - top_level_query_handler_context: TopLevelQueryHandlerContext, +def scope_query_handler_context_mock( + top_level_query_handler_context_mock: TopLevelQueryHandlerContext, request) -> ScopeQueryHandlerContext: if request.param == "top": - return top_level_query_handler_context + return top_level_query_handler_context_mock else: - return top_level_query_handler_context.get_child_query_handler_context() + return top_level_query_handler_context_mock.get_child_query_handler_context() diff --git a/tests/unit_tests/query_handler/test_scope_query_handler_context.py b/tests/unit_tests/query_handler/test_scope_query_handler_context.py index 678fcd9..fdf73da 100644 --- a/tests/unit_tests/query_handler/test_scope_query_handler_context.py +++ b/tests/unit_tests/query_handler/test_scope_query_handler_context.py @@ -19,156 +19,161 @@ ChildContextNotReleasedError -def test_temporary_table_prefix_in_name(scope_query_handler_context: ScopeQueryHandlerContext, - prefix: str): - proxy = scope_query_handler_context.get_temporary_table_name() +@pytest.fixture +def context_mock(scope_query_handler_context_mock) -> ScopeQueryHandlerContext: + return scope_query_handler_context_mock + + +@pytest.fixture +def prefix(tmp_db_obj_prefix: str) -> str: + return tmp_db_obj_prefix + + +def test_temporary_table_prefix_in_name(context_mock, prefix): + proxy = context_mock.get_temporary_table_name() assert proxy.name.startswith(prefix) -def test_temporary_table_temporary_schema(scope_query_handler_context: ScopeQueryHandlerContext, - schema: str): - proxy = scope_query_handler_context.get_temporary_table_name() - assert proxy.schema_name.name == schema +def test_temporary_table_temporary_schema(context_mock, aaf_pytest_db_schema: str): + proxy = context_mock.get_temporary_table_name() + assert proxy.schema_name.name == aaf_pytest_db_schema -def test_temporary_view_prefix_in_name(scope_query_handler_context: ScopeQueryHandlerContext, - prefix: str): - proxy = scope_query_handler_context.get_temporary_view_name() +def test_temporary_view_prefix_in_name(context_mock,prefix): + proxy = context_mock.get_temporary_view_name() assert proxy.name.startswith(prefix) -def test_temporary_view_temporary_schema(scope_query_handler_context: ScopeQueryHandlerContext, - schema: str): - proxy = scope_query_handler_context.get_temporary_view_name() - assert proxy.schema_name.name == schema +def test_temporary_view_temporary_schema(context_mock, aaf_pytest_db_schema: str): + proxy = context_mock.get_temporary_view_name() + assert proxy.schema_name.name == aaf_pytest_db_schema -def test_temporary_connection_temporary(scope_query_handler_context: ScopeQueryHandlerContext, - schema: str): - proxy = scope_query_handler_context.get_temporary_connection_name() +def test_temporary_connection_temporary(context_mock: ScopeQueryHandlerContext): + proxy = context_mock.get_temporary_connection_name() assert isinstance(proxy, ConnectionName) def test_temporary_udf_temporary( - scope_query_handler_context: ScopeQueryHandlerContext, - schema: str): - proxy = scope_query_handler_context.get_temporary_udf_name() + context_mock: ScopeQueryHandlerContext, + aaf_pytest_db_schema: str): + proxy = context_mock.get_temporary_udf_name() assert isinstance(proxy, UDFName) and \ - proxy.schema_name == SchemaName(schema) + proxy.schema_name == SchemaName(aaf_pytest_db_schema) -def test_temporary_bucketfs_file_prefix_in_name(bucketfs_location: bfs.path.PathLike, - scope_query_handler_context: ScopeQueryHandlerContext): - proxy = scope_query_handler_context.get_temporary_bucketfs_location() +def test_temporary_bucketfs_file_prefix_in_name(sample_bucketfs_location: bfs.path.PathLike, + context_mock: ScopeQueryHandlerContext): + proxy = context_mock.get_temporary_bucketfs_location() actual_path = proxy.bucketfs_location().as_udf_path() - expected_prefix_path = bucketfs_location.as_udf_path() + expected_prefix_path = sample_bucketfs_location.as_udf_path() assert actual_path.startswith(expected_prefix_path) -def test_two_temporary_table_are_not_equal(scope_query_handler_context: ScopeQueryHandlerContext): - proxy1 = scope_query_handler_context.get_temporary_table_name() - proxy2 = scope_query_handler_context.get_temporary_table_name() +def test_two_temporary_table_are_not_equal(context_mock: ScopeQueryHandlerContext): + proxy1 = context_mock.get_temporary_table_name() + proxy2 = context_mock.get_temporary_table_name() assert proxy1.name != proxy2.name -def test_two_temporary_view_are_not_equal(scope_query_handler_context: ScopeQueryHandlerContext): - proxy1 = scope_query_handler_context.get_temporary_view_name() - proxy2 = scope_query_handler_context.get_temporary_view_name() +def test_two_temporary_view_are_not_equal(context_mock: ScopeQueryHandlerContext): + proxy1 = context_mock.get_temporary_view_name() + proxy2 = context_mock.get_temporary_view_name() assert proxy1.name != proxy2.name -def test_two_temporary_bucketfs_files_are_not_equal(scope_query_handler_context: ScopeQueryHandlerContext): - proxy1 = scope_query_handler_context.get_temporary_bucketfs_location() - proxy2 = scope_query_handler_context.get_temporary_bucketfs_location() +def test_two_temporary_bucketfs_files_are_not_equal(context_mock: ScopeQueryHandlerContext): + proxy1 = context_mock.get_temporary_bucketfs_location() + proxy2 = context_mock.get_temporary_bucketfs_location() path1 = proxy1.bucketfs_location().as_udf_path() path2 = proxy2.bucketfs_location().as_udf_path() assert path1 != path2 -def test_temporary_table_name_proxy_use_name_after_release_fails(scope_query_handler_context: ScopeQueryHandlerContext): - proxy = scope_query_handler_context.get_temporary_table_name() - scope_query_handler_context.release() +def test_temporary_table_name_proxy_use_name_after_release_fails(context_mock: ScopeQueryHandlerContext): + proxy = context_mock.get_temporary_table_name() + context_mock.release() with pytest.raises(RuntimeError, match="TableNameProxy.* already released."): proxy_name = proxy.name -def test_temporary_view_name_proxy_use_name_after_release_fails(scope_query_handler_context: ScopeQueryHandlerContext): - proxy = scope_query_handler_context.get_temporary_view_name() - scope_query_handler_context.release() +def test_temporary_view_name_proxy_use_name_after_release_fails(context_mock: ScopeQueryHandlerContext): + proxy = context_mock.get_temporary_view_name() + context_mock.release() with pytest.raises(RuntimeError, match="ViewNameProxy.* already released."): proxy_name = proxy.name def test_temporary_table_name_proxy_use_schema_after_release_fails( - scope_query_handler_context: ScopeQueryHandlerContext): - proxy = scope_query_handler_context.get_temporary_table_name() - scope_query_handler_context.release() + context_mock: ScopeQueryHandlerContext): + proxy = context_mock.get_temporary_table_name() + context_mock.release() with pytest.raises(RuntimeError, match="TableNameProxy.* already released."): proxy_name = proxy.schema_name def test_temporary_view_name_proxy_use_schema_after_release_fails( - scope_query_handler_context: ScopeQueryHandlerContext): - proxy = scope_query_handler_context.get_temporary_view_name() - scope_query_handler_context.release() + context_mock: ScopeQueryHandlerContext): + proxy = context_mock.get_temporary_view_name() + context_mock.release() with pytest.raises(RuntimeError, match="ViewNameProxy.* already released."): proxy_name = proxy.schema_name def test_temporary_table_name_proxy_use_quoted_name_after_release_fails( - scope_query_handler_context: ScopeQueryHandlerContext): - proxy = scope_query_handler_context.get_temporary_table_name() - scope_query_handler_context.release() + context_mock: ScopeQueryHandlerContext): + proxy = context_mock.get_temporary_table_name() + context_mock.release() with pytest.raises(RuntimeError, match="TableNameProxy.* already released."): proxy_name = proxy.quoted_name def test_temporary_view_name_proxy_use_quoted_name_after_release_fails( - scope_query_handler_context: ScopeQueryHandlerContext): - proxy = scope_query_handler_context.get_temporary_view_name() - scope_query_handler_context.release() + context_mock: ScopeQueryHandlerContext): + proxy = context_mock.get_temporary_view_name() + context_mock.release() with pytest.raises(RuntimeError, match="ViewNameProxy.* already released."): proxy_name = proxy.quoted_name def test_temporary_table_name_proxy_use_fully_qualified_after_release_fails( - scope_query_handler_context: ScopeQueryHandlerContext): - proxy = scope_query_handler_context.get_temporary_table_name() - scope_query_handler_context.release() + context_mock: ScopeQueryHandlerContext): + proxy = context_mock.get_temporary_table_name() + context_mock.release() with pytest.raises(RuntimeError, match="TableNameProxy.* already released."): proxy_name = proxy.fully_qualified def test_temporary_view_name_proxy_use_fully_qualified_after_release_fails( - scope_query_handler_context: ScopeQueryHandlerContext): - proxy = scope_query_handler_context.get_temporary_view_name() - scope_query_handler_context.release() + context_mock: ScopeQueryHandlerContext): + proxy = context_mock.get_temporary_view_name() + context_mock.release() with pytest.raises(RuntimeError, match="ViewNameProxy.* already released."): proxy_name = proxy.fully_qualified -def test_get_temporary_view_after_release_fails(scope_query_handler_context: ScopeQueryHandlerContext): - scope_query_handler_context.release() +def test_get_temporary_view_after_release_fails(context_mock: ScopeQueryHandlerContext): + context_mock.release() with pytest.raises(RuntimeError, match="Context already released."): - proxy = scope_query_handler_context.get_temporary_view_name() + proxy = context_mock.get_temporary_view_name() -def test_get_temporary_table_after_release_fails(scope_query_handler_context: ScopeQueryHandlerContext): - scope_query_handler_context.release() +def test_get_temporary_table_after_release_fails(context_mock: ScopeQueryHandlerContext): + context_mock.release() with pytest.raises(RuntimeError, match="Context already released."): - proxy = scope_query_handler_context.get_temporary_table_name() + proxy = context_mock.get_temporary_table_name() -def test_get_temporary_bucketfs_file_after_release_fails(scope_query_handler_context: ScopeQueryHandlerContext): - scope_query_handler_context.release() +def test_get_temporary_bucketfs_file_after_release_fails(context_mock: ScopeQueryHandlerContext): + context_mock.release() with pytest.raises(RuntimeError, match="Context already released."): - proxy = scope_query_handler_context.get_temporary_bucketfs_location() + proxy = context_mock.get_temporary_bucketfs_location() -def test_use_child_context_after_release_fails(scope_query_handler_context: ScopeQueryHandlerContext): - child = scope_query_handler_context.get_child_query_handler_context() +def test_use_child_context_after_release_fails(context_mock: ScopeQueryHandlerContext): + child = context_mock.get_child_query_handler_context() try: - scope_query_handler_context.release() + context_mock.release() except: pass with pytest.raises(RuntimeError, match="Context already released."): @@ -183,9 +188,9 @@ def not_raises(exception): raise pytest.fail("DID RAISE {0}".format(exception)) -def test_transfer_between_siblings(scope_query_handler_context: ScopeQueryHandlerContext): - child1 = scope_query_handler_context.get_child_query_handler_context() - child2 = scope_query_handler_context.get_child_query_handler_context() +def test_transfer_between_siblings(context_mock: ScopeQueryHandlerContext): + child1 = context_mock.get_child_query_handler_context() + child2 = context_mock.get_child_query_handler_context() object_proxy1 = child1.get_temporary_table_name() object_proxy2 = child1.get_temporary_table_name() child1.transfer_object_to(object_proxy1, child2) @@ -197,9 +202,9 @@ def test_transfer_between_siblings(scope_query_handler_context: ScopeQueryHandle _ = object_proxy2.name -def test_transfer_siblings_check_ownership_transfer_to_target(scope_query_handler_context: ScopeQueryHandlerContext): - child1 = scope_query_handler_context.get_child_query_handler_context() - child2 = scope_query_handler_context.get_child_query_handler_context() +def test_transfer_siblings_check_ownership_transfer_to_target(context_mock: ScopeQueryHandlerContext): + child1 = context_mock.get_child_query_handler_context() + child2 = context_mock.get_child_query_handler_context() object_proxy1 = child1.get_temporary_table_name() object_proxy2 = child2.get_temporary_table_name() child1.transfer_object_to(object_proxy1, child2) @@ -213,8 +218,8 @@ def test_transfer_siblings_check_ownership_transfer_to_target(scope_query_handle def test_transfer_child_parent_check_ownership_transfer_to_target( - scope_query_handler_context: ScopeQueryHandlerContext): - parent = scope_query_handler_context + context_mock: ScopeQueryHandlerContext): + parent = context_mock child1 = parent.get_child_query_handler_context() child2 = parent.get_child_query_handler_context() object_proxy1 = child1.get_temporary_table_name() @@ -224,8 +229,8 @@ def test_transfer_child_parent_check_ownership_transfer_to_target( def test_transfer_parent_child_check_ownership_transfer_to_target( - scope_query_handler_context: ScopeQueryHandlerContext): - parent = scope_query_handler_context + context_mock: ScopeQueryHandlerContext): + parent = context_mock child1 = parent.get_child_query_handler_context() child2 = parent.get_child_query_handler_context() object_proxy1 = parent.get_temporary_table_name() @@ -234,10 +239,10 @@ def test_transfer_parent_child_check_ownership_transfer_to_target( parent.transfer_object_to(object_proxy1, child2) -def test_transfer_siblings_checK_losing_ownership(scope_query_handler_context: ScopeQueryHandlerContext): - child1 = scope_query_handler_context.get_child_query_handler_context() - child2 = scope_query_handler_context.get_child_query_handler_context() - child3 = scope_query_handler_context.get_child_query_handler_context() +def test_transfer_siblings_checK_losing_ownership(context_mock: ScopeQueryHandlerContext): + child1 = context_mock.get_child_query_handler_context() + child2 = context_mock.get_child_query_handler_context() + child3 = context_mock.get_child_query_handler_context() object_proxy1 = child1.get_temporary_table_name() child1.transfer_object_to(object_proxy1, child2) @@ -246,9 +251,9 @@ def test_transfer_siblings_checK_losing_ownership(scope_query_handler_context: S def test_transfer_between_siblings_object_from_different_context( - scope_query_handler_context: ScopeQueryHandlerContext): - child1 = scope_query_handler_context.get_child_query_handler_context() - child2 = scope_query_handler_context.get_child_query_handler_context() + context_mock: ScopeQueryHandlerContext): + child1 = context_mock.get_child_query_handler_context() + child2 = context_mock.get_child_query_handler_context() grand_child1 = child1.get_child_query_handler_context() object_proxy = grand_child1.get_temporary_table_name() with pytest.raises(RuntimeError, @@ -256,9 +261,9 @@ def test_transfer_between_siblings_object_from_different_context( child1.transfer_object_to(object_proxy, child2) -def test_transfer_between_child_and_parent(scope_query_handler_context: ScopeQueryHandlerContext): - parent = scope_query_handler_context - child = scope_query_handler_context.get_child_query_handler_context() +def test_transfer_between_child_and_parent(context_mock: ScopeQueryHandlerContext): + parent = context_mock + child = context_mock.get_child_query_handler_context() object_proxy1 = child.get_temporary_table_name() object_proxy2 = child.get_temporary_table_name() child.transfer_object_to(object_proxy1, parent) @@ -270,9 +275,9 @@ def test_transfer_between_child_and_parent(scope_query_handler_context: ScopeQue _ = object_proxy2.name -def test_transfer_between_parent_and_child(scope_query_handler_context: ScopeQueryHandlerContext): - parent = scope_query_handler_context - child = scope_query_handler_context.get_child_query_handler_context() +def test_transfer_between_parent_and_child(context_mock: ScopeQueryHandlerContext): + parent = context_mock + child = context_mock.get_child_query_handler_context() object_proxy = parent.get_temporary_table_name() parent.transfer_object_to(object_proxy, child) child.release() @@ -282,9 +287,9 @@ def test_transfer_between_parent_and_child(scope_query_handler_context: ScopeQue def test_illegal_transfer_between_grand_child_and_parent( - scope_query_handler_context: ScopeQueryHandlerContext): - parent = scope_query_handler_context - child = scope_query_handler_context.get_child_query_handler_context() + context_mock: ScopeQueryHandlerContext): + parent = context_mock + child = context_mock.get_child_query_handler_context() grand_child = child.get_child_query_handler_context() object_proxy = grand_child.get_temporary_table_name() with pytest.raises(RuntimeError, match="Given ScopeQueryHandlerContext not a child, parent or sibling."): @@ -292,9 +297,9 @@ def test_illegal_transfer_between_grand_child_and_parent( def test_illegal_transfer_between_parent_and_grand_child( - scope_query_handler_context: ScopeQueryHandlerContext): - parent = scope_query_handler_context - child = scope_query_handler_context.get_child_query_handler_context() + context_mock: ScopeQueryHandlerContext): + parent = context_mock + child = context_mock.get_child_query_handler_context() grand_child = child.get_child_query_handler_context() object_proxy = parent.get_temporary_table_name() with pytest.raises(RuntimeError, @@ -304,26 +309,26 @@ def test_illegal_transfer_between_parent_and_grand_child( def test_release_parent_before_child_with_temporary_object_expect_exception( - scope_query_handler_context: ScopeQueryHandlerContext): - parent = scope_query_handler_context - child = scope_query_handler_context.get_child_query_handler_context() + context_mock: ScopeQueryHandlerContext): + parent = context_mock + child = context_mock.get_child_query_handler_context() _ = child.get_temporary_table_name() with pytest.raises(ChildContextNotReleasedError): parent.release() def test_release_parent_before_child_without_temporary_object_expect_exception( - scope_query_handler_context: ScopeQueryHandlerContext): - parent = scope_query_handler_context - _ = scope_query_handler_context.get_child_query_handler_context() + context_mock: ScopeQueryHandlerContext): + parent = context_mock + _ = context_mock.get_child_query_handler_context() with pytest.raises(ChildContextNotReleasedError): parent.release() def test_release_parent_before_grand_child_with_temporary_object_expect_exception( - scope_query_handler_context: ScopeQueryHandlerContext): - parent = scope_query_handler_context - child = scope_query_handler_context.get_child_query_handler_context() + context_mock: ScopeQueryHandlerContext): + parent = context_mock + child = context_mock.get_child_query_handler_context() grand_child = child.get_child_query_handler_context() _ = grand_child.get_temporary_table_name() with pytest.raises(ChildContextNotReleasedError): @@ -331,32 +336,32 @@ def test_release_parent_before_grand_child_with_temporary_object_expect_exceptio def test_release_parent_before_grand_child_without_temporary_object_expect_exception( - scope_query_handler_context: ScopeQueryHandlerContext): - parent = scope_query_handler_context - child = scope_query_handler_context.get_child_query_handler_context() + context_mock: ScopeQueryHandlerContext): + parent = context_mock + child = context_mock.get_child_query_handler_context() _ = child.get_child_query_handler_context() with pytest.raises(ChildContextNotReleasedError): parent.release() def test_cleanup_parent_before_grand_child_without_temporary_objects( - scope_query_handler_context: ScopeQueryHandlerContext): - child1 = scope_query_handler_context.get_child_query_handler_context() - child2 = scope_query_handler_context.get_child_query_handler_context() + context_mock: ScopeQueryHandlerContext): + child1 = context_mock.get_child_query_handler_context() + child2 = context_mock.get_child_query_handler_context() _ = child1.get_child_query_handler_context() _ = child2.get_child_query_handler_context() _ = child1.get_child_query_handler_context() _ = child2.get_child_query_handler_context() with pytest.raises(ChildContextNotReleasedError) as e: - scope_query_handler_context.release() + context_mock.release() not_released_contexts = e.value.get_all_not_released_contexts() f = "f" assert len(not_released_contexts) == 6 -def test_using_table_name_proxy_in_table(scope_query_handler_context: ScopeQueryHandlerContext): - table_name = scope_query_handler_context.get_temporary_table_name() +def test_using_table_name_proxy_in_table(context_mock: ScopeQueryHandlerContext): + table_name = context_mock.get_temporary_table_name() table = Table(table_name, columns=[ ( @@ -369,8 +374,8 @@ def test_using_table_name_proxy_in_table(scope_query_handler_context: ScopeQuery assert table.name is not None -def test_using_view_name_proxy_in_view(scope_query_handler_context: ScopeQueryHandlerContext): - view_name = scope_query_handler_context.get_temporary_view_name() +def test_using_view_name_proxy_in_view(context_mock: ScopeQueryHandlerContext): + view_name = context_mock.get_temporary_view_name() view = View(view_name, columns=[ ( ColumnBuilder(). @@ -382,14 +387,14 @@ def test_using_view_name_proxy_in_view(scope_query_handler_context: ScopeQueryHa def test_get_connection_existing_connection( - scope_query_handler_context: ScopeQueryHandlerContext, - test_connection: Connection + context_mock: ScopeQueryHandlerContext, + connection_mock: Connection ): - connection = scope_query_handler_context.get_connection("existing") + connection = context_mock.get_connection("existing") assert connection == connection def test_get_connection_not_existing_connection( - scope_query_handler_context: ScopeQueryHandlerContext): + context_mock: ScopeQueryHandlerContext): with pytest.raises(KeyError): - scope_query_handler_context.get_connection("not_existing") + context_mock.get_connection("not_existing") diff --git a/tests/unit_tests/query_handler/test_top_level_query_handler_context.py b/tests/unit_tests/query_handler/test_top_level_query_handler_context.py index d6c95e2..981dabe 100644 --- a/tests/unit_tests/query_handler/test_top_level_query_handler_context.py +++ b/tests/unit_tests/query_handler/test_top_level_query_handler_context.py @@ -7,74 +7,73 @@ from exasol.analytics.query_handler.query.drop_view_query import DropViewQuery -def test_cleanup_released_temporary_table_proxies( - top_level_query_handler_context: TopLevelQueryHandlerContext): - proxy = top_level_query_handler_context.get_temporary_table_name() +@pytest.fixture +def context_mock(top_level_query_handler_context_mock) -> TopLevelQueryHandlerContext: + return top_level_query_handler_context_mock + + +def test_cleanup_released_temporary_table_proxies(context_mock): + proxy = context_mock.get_temporary_table_name() proxy_fully_qualified = proxy.fully_qualified - top_level_query_handler_context.release() - queries = top_level_query_handler_context.cleanup_released_object_proxies() + context_mock.release() + queries = context_mock.cleanup_released_object_proxies() assert len(queries) == 1 and isinstance(queries[0], DropTableQuery) \ and queries[0].query_string == f"DROP TABLE IF EXISTS {proxy_fully_qualified};" -def test_cleanup_released_temporary_view_proxies( - top_level_query_handler_context: TopLevelQueryHandlerContext): - proxy = top_level_query_handler_context.get_temporary_view_name() +def test_cleanup_released_temporary_view_proxies(context_mock): + proxy = context_mock.get_temporary_view_name() proxy_fully_qualified = proxy.fully_qualified - top_level_query_handler_context.release() - queries = top_level_query_handler_context.cleanup_released_object_proxies() + context_mock.release() + queries = context_mock.cleanup_released_object_proxies() assert len(queries) == 1 and isinstance(queries[0], DropViewQuery) \ and queries[0].query_string == f"DROP VIEW IF EXISTS {proxy_fully_qualified};" -def test_cleanup_released_bucketfs_object_with_uploaded_file_proxies( - top_level_query_handler_context: TopLevelQueryHandlerContext, - bucketfs_location: bfs.path.PathLike): - proxy = top_level_query_handler_context.get_temporary_bucketfs_location() +def test_cleanup_released_bucketfs_object_with_uploaded_file_proxies(context_mock, + sample_bucketfs_location: bfs.path.PathLike): + proxy = context_mock.get_temporary_bucketfs_location() # create dummy file with content "test" (proxy.bucketfs_location() / "test_file.txt").write(b"test") - top_level_query_handler_context.release() - top_level_query_handler_context.cleanup_released_object_proxies() - assert not bucketfs_location.is_dir() + context_mock.release() + context_mock.cleanup_released_object_proxies() + assert not sample_bucketfs_location.is_dir() -def test_cleanup_released_bucketfs_object_without_uploaded_file_proxies_after_release( - top_level_query_handler_context: TopLevelQueryHandlerContext): - _ = top_level_query_handler_context.get_temporary_bucketfs_location() - top_level_query_handler_context.release() - top_level_query_handler_context.cleanup_released_object_proxies() +def test_cleanup_released_bucketfs_object_without_uploaded_file_proxies_after_release(context_mock): + _ = context_mock.get_temporary_bucketfs_location() + context_mock.release() + context_mock.cleanup_released_object_proxies() -def test_cleanup_release_in_reverse_order_at_top_level( - top_level_query_handler_context: TopLevelQueryHandlerContext): - proxies = [top_level_query_handler_context.get_temporary_table_name() for _ in range(10)] +def test_cleanup_release_in_reverse_order_at_top_level(context_mock): + proxies = [context_mock.get_temporary_table_name() for _ in range(10)] table_names = [proxy.fully_qualified for proxy in proxies] - top_level_query_handler_context.release() - query_objects = top_level_query_handler_context.cleanup_released_object_proxies() + context_mock.release() + query_objects = context_mock.cleanup_released_object_proxies() actual_queries = [query.query_string for query in query_objects] expected_queries = [f"DROP TABLE IF EXISTS {table_name};" for table_name in reversed(table_names)] assert expected_queries == actual_queries -def test_cleanup_release_in_reverse_order_at_child( - top_level_query_handler_context: TopLevelQueryHandlerContext): - parent_proxies = [top_level_query_handler_context.get_temporary_table_name() for _ in range(10)] +def test_cleanup_release_in_reverse_order_at_child(context_mock): + parent_proxies = [context_mock.get_temporary_table_name() for _ in range(10)] - child = top_level_query_handler_context.get_child_query_handler_context() + child = context_mock.get_child_query_handler_context() child_proxies = [child.get_temporary_table_name() for _ in range(10)] child_table_names = [proxy.fully_qualified for proxy in child_proxies] child.release() - child_query_objects = top_level_query_handler_context.cleanup_released_object_proxies() + child_query_objects = context_mock.cleanup_released_object_proxies() child_actual_queries = [query.query_string for query in child_query_objects] child_expected_queries = [f"DROP TABLE IF EXISTS {table_name};" for table_name in reversed(child_table_names)] - parent_proxies.extend([top_level_query_handler_context.get_temporary_table_name() for _ in range(10)]) + parent_proxies.extend([context_mock.get_temporary_table_name() for _ in range(10)]) parent_table_names = [proxy.fully_qualified for proxy in parent_proxies] - top_level_query_handler_context.release() - parent_query_objects = top_level_query_handler_context.cleanup_released_object_proxies() + context_mock.release() + parent_query_objects = context_mock.cleanup_released_object_proxies() parent_actual_queries = [query.query_string for query in parent_query_objects] parent_expected_queries = [f"DROP TABLE IF EXISTS {table_name};" for table_name in reversed(parent_table_names)] @@ -82,12 +81,11 @@ def test_cleanup_release_in_reverse_order_at_child( parent_expected_queries == parent_actual_queries -def test_cleanup_parent_before_grand_child_with_temporary_objects( - top_level_query_handler_context: TopLevelQueryHandlerContext): - _ = top_level_query_handler_context.get_temporary_table_name() - child1 = top_level_query_handler_context.get_child_query_handler_context() +def test_cleanup_parent_before_grand_child_with_temporary_objects(context_mock): + _ = context_mock.get_temporary_table_name() + child1 = context_mock.get_child_query_handler_context() _ = child1.get_temporary_table_name() - child2 = top_level_query_handler_context.get_child_query_handler_context() + child2 = context_mock.get_child_query_handler_context() _ = child2.get_temporary_table_name() grand_child11 = child1.get_child_query_handler_context() _ = grand_child11.get_temporary_table_name() @@ -99,6 +97,6 @@ def test_cleanup_parent_before_grand_child_with_temporary_objects( _ = grand_child22.get_temporary_table_name() with pytest.raises(ChildContextNotReleasedError): - top_level_query_handler_context.release() - cleanup_queries = top_level_query_handler_context.cleanup_released_object_proxies() + context_mock.release() + cleanup_queries = context_mock.cleanup_released_object_proxies() assert len(cleanup_queries) == 7 diff --git a/tests/unit_tests/query_handler_runner/test_python_query_handler_runner.py b/tests/unit_tests/query_handler_runner/test_python_query_handler_runner.py index 0eb1885..2ca8183 100644 --- a/tests/unit_tests/query_handler_runner/test_python_query_handler_runner.py +++ b/tests/unit_tests/query_handler_runner/test_python_query_handler_runner.py @@ -39,21 +39,13 @@ def create_sql_executor(schema: str, *args): ]) @pytest.fixture() -def temporary_schema_name(): - return "temp_schema_name" +def prefix(tmp_db_obj_prefix): + return tmp_db_obj_prefix @pytest.fixture -def top_level_query_handler_context(mocked_temporary_bucketfs_location, - temporary_schema_name, - test_connection_lookup): - top_level_query_handler_context = TopLevelQueryHandlerContext( - temporary_bucketfs_location=mocked_temporary_bucketfs_location, - temporary_db_object_name_prefix="temp_db_object", - connection_lookup=test_connection_lookup, - temporary_schema_name=temporary_schema_name, - ) - return top_level_query_handler_context +def context_mock(top_level_query_handler_context_mock) -> TopLevelQueryHandlerContext: + return top_level_query_handler_context_mock class TestInput: @@ -78,7 +70,7 @@ def handle_query_result(self, query_result: QueryResult) -> Union[Continue, Fini pass -def test_start_finish(top_level_query_handler_context): +def test_start_finish(context_mock): """ This tests runs a query handler which returns a Finish result from the start method. We expect no queries to be executed and result of the Finish object returned. @@ -87,7 +79,7 @@ def test_start_finish(top_level_query_handler_context): test_input = TestInput() query_handler_runner = PythonQueryHandlerRunner[TestInput, TestOutput]( sql_executor=sql_executor, - top_level_query_handler_context=top_level_query_handler_context, + top_level_query_handler_context=context_mock, parameter=test_input, query_handler_factory=StartFinishTestQueryHandler ) @@ -108,7 +100,8 @@ def start(self) -> Union[Continue, Finish[TestOutput]]: def handle_query_result(self, query_result: QueryResult) -> Union[Continue, Finish[TestOutput]]: pass -def test_start_finish_cleanup_queries(temporary_schema_name, top_level_query_handler_context): + +def test_start_finish_cleanup_queries(aaf_pytest_db_schema, prefix, context_mock): """ This tests runs a query handler which registers a temporary table in the start method and then directly returns a Finish result. We expect a cleanup query for the temporary @@ -119,7 +112,7 @@ def test_start_finish_cleanup_queries(temporary_schema_name, top_level_query_han test_input = TestInput() query_handler_runner = PythonQueryHandlerRunner[TestInput, TestOutput]( sql_executor=sql_executor, - top_level_query_handler_context=top_level_query_handler_context, + top_level_query_handler_context=context_mock, parameter=test_input, query_handler_factory=StartFinishCleanupQueriesTestQueryHandler ) @@ -140,7 +133,7 @@ def handle_query_result(self, query_result: QueryResult) -> Union[Continue, Fini pass -def test_start_error_cleanup_queries(temporary_schema_name, top_level_query_handler_context): +def test_start_error_cleanup_queries(aaf_pytest_db_schema, prefix, context_mock): """ This tests runs a query handler which registers a temporary table in the start method and then directly raise an exception. We expect a cleanup query for the temporary @@ -155,7 +148,7 @@ def test_start_error_cleanup_queries(temporary_schema_name, top_level_query_hand test_input = TestInput() query_handler_runner = PythonQueryHandlerRunner[TestInput, TestOutput]( sql_executor=sql_executor, - top_level_query_handler_context=top_level_query_handler_context, + top_level_query_handler_context=context_mock, parameter=test_input, query_handler_factory=StartErrorCleanupQueriesTestQueryHandler ) @@ -184,7 +177,7 @@ def handle_query_result(self, query_result: QueryResult) -> Union[Continue, Fini return Finish[TestOutput](TestOutput(self._parameter)) -def test_continue_finish(temporary_schema_name, top_level_query_handler_context): +def test_continue_finish(aaf_pytest_db_schema, prefix, context_mock): """ This tests runs a query handler which returns Continue result from the start method and expect handle_query_result to be called. Further, it expects that @@ -218,7 +211,7 @@ def test_continue_finish(temporary_schema_name, top_level_query_handler_context) test_input = TestInput() query_handler_runner = PythonQueryHandlerRunner[TestInput, TestOutput]( sql_executor=sql_executor, - top_level_query_handler_context=top_level_query_handler_context, + top_level_query_handler_context=context_mock, parameter=test_input, query_handler_factory=ContinueFinishTestQueryHandler ) @@ -240,7 +233,7 @@ def handle_query_result(self, query_result: QueryResult) -> Union[Continue, Fini raise AssertionError("handle_query_result shouldn't be called") -def test_continue_wrong_columns(temporary_schema_name, top_level_query_handler_context): +def test_continue_wrong_columns(aaf_pytest_db_schema, context_mock): """ This tests runs a query handler which returns Continue result with mismatching column definition between the input query and its column definition. We expect the query handler runner to raise @@ -273,7 +266,7 @@ def test_continue_wrong_columns(temporary_schema_name, top_level_query_handler_c test_input = TestInput() query_handler_runner = PythonQueryHandlerRunner[TestInput, TestOutput]( sql_executor=sql_executor, - top_level_query_handler_context=top_level_query_handler_context, + top_level_query_handler_context=context_mock, parameter=test_input, query_handler_factory=ContinueWrongColumnsTestQueryHandler ) @@ -301,7 +294,7 @@ def handle_query_result(self, query_result: QueryResult) -> Union[Continue, Fini return Finish[TestOutput](TestOutput(self._parameter)) -def test_continue_query_list(temporary_schema_name, top_level_query_handler_context): +def test_continue_query_list(aaf_pytest_db_schema, prefix, context_mock): """ This tests runs a query handler which returns Continue result from the start method which contains a query list. We expect to be handle_query_result to be called and @@ -339,7 +332,7 @@ def test_continue_query_list(temporary_schema_name, top_level_query_handler_cont test_input = TestInput() query_handler_runner = PythonQueryHandlerRunner[TestInput, TestOutput]( sql_executor=sql_executor, - top_level_query_handler_context=top_level_query_handler_context, + top_level_query_handler_context=context_mock, parameter=test_input, query_handler_factory=ContinueQueryListTestQueryHandler ) @@ -366,7 +359,7 @@ def handle_query_result(self, query_result: QueryResult) -> Union[Continue, Fini raise Exception("Start failed") -def test_continue_error_cleanup_queries(temporary_schema_name, top_level_query_handler_context): +def test_continue_error_cleanup_queries(aaf_pytest_db_schema, prefix, context_mock): """ This tests runs a query handler which registers a temporary table in the handle_query_result method and then directly raise an exception. We expect a cleanup query for the temporary @@ -397,7 +390,7 @@ def test_continue_error_cleanup_queries(temporary_schema_name, top_level_query_h test_input = TestInput() query_handler_runner = PythonQueryHandlerRunner[TestInput, TestOutput]( sql_executor=sql_executor, - top_level_query_handler_context=top_level_query_handler_context, + top_level_query_handler_context=context_mock, parameter=test_input, query_handler_factory=ContinueErrorCleanupQueriesTestQueryHandler ) @@ -437,7 +430,7 @@ def handle_query_result(self, query_result: QueryResult) -> Union[Continue, Fini return Finish[TestOutput](TestOutput(self._parameter)) -def test_continue_continue_finish(temporary_schema_name, top_level_query_handler_context): +def test_continue_continue_finish(aaf_pytest_db_schema, prefix, context_mock): """ This tests runs a query handler which returns Continue from the first call to handle_query_result method and the second time it returns Finish. We expect two input queries to be executed; one per Continue and @@ -487,7 +480,7 @@ def test_continue_continue_finish(temporary_schema_name, top_level_query_handler test_input = TestInput() query_handler_runner = PythonQueryHandlerRunner[TestInput, TestOutput]( sql_executor=sql_executor, - top_level_query_handler_context=top_level_query_handler_context, + top_level_query_handler_context=context_mock, parameter=test_input, query_handler_factory=ContinueContinueFinishTestQueryHandler ) @@ -527,7 +520,7 @@ def handle_query_result(self, query_result: QueryResult) -> Union[Continue, Fini return Finish[TestOutput](TestOutput(self._parameter)) -def test_continue_cleanup_continue_finish(temporary_schema_name, top_level_query_handler_context): +def test_continue_cleanup_continue_finish(aaf_pytest_db_schema, prefix, context_mock): """ This tests runs a query handler which creates the temporary table of a child query context manager. Then it returns a Continue result, such that handle_query_result will be called. During the call to @@ -583,7 +576,7 @@ def test_continue_cleanup_continue_finish(temporary_schema_name, top_level_query test_input = TestInput() query_handler_runner = PythonQueryHandlerRunner[TestInput, TestOutput]( sql_executor=sql_executor, - top_level_query_handler_context=top_level_query_handler_context, + top_level_query_handler_context=context_mock, parameter=test_input, query_handler_factory=ContinueContinueCleanupFinishTestQueryHandler ) @@ -605,13 +598,12 @@ def handle_query_result(self, query_result: QueryResult) -> Union[Continue, Fini pass -def test_fail_in_cleanup(temporary_schema_name, top_level_query_handler_context): +def test_fail_in_cleanup(aaf_pytest_db_schema, context_mock): sql_executor = MockSQLExecutor() - temporary_schema_name = "temp_schema_name" test_input = TestInput() query_handler_runner = PythonQueryHandlerRunner[TestInput, TestOutput]( sql_executor=sql_executor, - top_level_query_handler_context=top_level_query_handler_context, + top_level_query_handler_context=context_mock, parameter=test_input, query_handler_factory=FailInCleanupAfterException ) diff --git a/tests/unit_tests/udf_framework/test_json_udf_query_handler.py b/tests/unit_tests/udf_framework/test_json_udf_query_handler.py index 0e83262..6757103 100644 --- a/tests/unit_tests/udf_framework/test_json_udf_query_handler.py +++ b/tests/unit_tests/udf_framework/test_json_udf_query_handler.py @@ -31,23 +31,23 @@ def handle_query_result(self, query_result: QueryResult) -> Union[Continue, Fini raise AssertionError("Should not be called") -def test_constructor_valid_json(top_level_query_handler_context): +def test_constructor_valid_json(top_level_query_handler_context_mock): parameter = { "test_key": "test_value" } json_str_parameter = json.dumps(parameter) query_handler = JsonUDFQueryHandler( parameter=json_str_parameter, - query_handler_context=top_level_query_handler_context, + query_handler_context=top_level_query_handler_context_mock, wrapped_json_query_handler_class=ConstructorTestJSONQueryHandler ) -def test_constructor_invalid_json(top_level_query_handler_context): +def test_constructor_invalid_json(top_level_query_handler_context_mock): with pytest.raises(JSONDecodeError): query_handler = JsonUDFQueryHandler( parameter="'abc'='ced'", - query_handler_context=top_level_query_handler_context, + query_handler_context=top_level_query_handler_context_mock, wrapped_json_query_handler_class=ConstructorTestJSONQueryHandler ) @@ -65,14 +65,14 @@ def handle_query_result(self, query_result: QueryResult) -> Union[Continue, Fini raise AssertionError("Should not be called") -def test_start_return_parameter(top_level_query_handler_context): +def test_start_return_parameter(top_level_query_handler_context_mock): parameter = { "test_key": "test_value" } json_str_parameter = json.dumps(parameter) query_handler = JsonUDFQueryHandler( parameter=json_str_parameter, - query_handler_context=top_level_query_handler_context, + query_handler_context=top_level_query_handler_context_mock, wrapped_json_query_handler_class=StartReturnParameterTestJSONQueryHandler ) result = query_handler.start() @@ -93,14 +93,14 @@ def handle_query_result(self, query_result: QueryResult) -> Union[Continue, Fini return Finish[JSONType]({"a": a}) -def test_handle_query_result_check_query_result(top_level_query_handler_context): +def test_handle_query_result_check_query_result(top_level_query_handler_context_mock): parameter = { "test_key": "test_value" } json_str_parameter = json.dumps(parameter) query_handler = JsonUDFQueryHandler( parameter=json_str_parameter, - query_handler_context=top_level_query_handler_context, + query_handler_context=top_level_query_handler_context_mock, wrapped_json_query_handler_class=HandleQueryResultCheckQueryResultTestJSONQueryHandler ) result = query_handler.handle_query_result( diff --git a/tests/unit_tests/udf_framework/test_json_udf_query_handler_factory.py b/tests/unit_tests/udf_framework/test_json_udf_query_handler_factory.py index b69f7e3..0dbdc60 100644 --- a/tests/unit_tests/udf_framework/test_json_udf_query_handler_factory.py +++ b/tests/unit_tests/udf_framework/test_json_udf_query_handler_factory.py @@ -37,10 +37,10 @@ def __init__(self): super().__init__(TestJSONQueryHandler) -def test(top_level_query_handler_context): +def test(top_level_query_handler_context_mock): test_input = {"a": 1} json_str = json.dumps(test_input) - query_handler = TestJsonUDFQueryHandlerFactory().create(json_str, top_level_query_handler_context) + query_handler = TestJsonUDFQueryHandlerFactory().create(json_str, top_level_query_handler_context_mock) start_result = query_handler.start() handle_query_result = query_handler.handle_query_result( PythonQueryResult(data=[(1,)],