Skip to content

Commit

Permalink
Update more tests to get rid of NativeAppManager (#1724)
Browse files Browse the repository at this point in the history
Convert package post-deploy tests and one skipped integration tests to remove use of `NativeAppManager`.
  • Loading branch information
sfc-gh-fcampbell authored Oct 15, 2024
1 parent 35e4242 commit 7e0950c
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 53 deletions.
117 changes: 75 additions & 42 deletions tests/nativeapp/test_post_deploy_for_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@
from unittest import mock

import pytest
from snowflake.cli._plugins.nativeapp.entities.application_package import (
ApplicationPackageEntityModel,
)
from snowflake.cli._plugins.nativeapp.exceptions import MissingScriptError
from snowflake.cli._plugins.nativeapp.manager import NativeAppManager
from snowflake.cli.api.console import cli_console as cc
from snowflake.cli.api.entities.utils import execute_post_deploy_hooks
from snowflake.cli.api.exceptions import InvalidTemplate
from snowflake.cli.api.project.definition_manager import DefinitionManager
from snowflake.cli.api.project.errors import SchemaValidationError
Expand Down Expand Up @@ -47,15 +51,20 @@ def test_package_post_deploy_scripts(
project_directory,
):
mock_conn.return_value = MockConnectionCtx()
with project_directory("napp_post_deploy") as project_dir:
with project_directory("napp_post_deploy_v2") as project_dir:
dm = DefinitionManager(project_dir)
manager = NativeAppManager(
project_definition=dm.project_definition.native_app,
project_root=dm.project_root,
)
pkg_model: ApplicationPackageEntityModel = dm.project_definition.entities[
"myapp_pkg"
]
mock_cli_ctx.return_value = dm.template_context

manager.execute_package_post_deploy_hooks()
execute_post_deploy_hooks(
console=cc,
project_root=project_dir,
post_deploy_hooks=pkg_model.meta.post_deploy,
deployed_object_type=pkg_model.get_type(),
database_name=pkg_model.fqn.name,
)

assert mock_execute_query.mock_calls == [
mock.call("use database myapp_pkg_test_user"),
Expand Down Expand Up @@ -90,15 +99,23 @@ def test_package_post_deploy_scripts_with_no_scripts(
project_directory,
):
mock_conn.return_value = MockConnectionCtx()
with project_directory("napp_project_1") as project_dir:
with project_directory(
"napp_project_2",
{"entities": {"myapp_pkg_polly": {"meta": {"post_deploy": []}}}},
) as project_dir:
dm = DefinitionManager(project_dir)
manager = NativeAppManager(
project_definition=dm.project_definition.native_app,
project_root=dm.project_root,
)
pkg_model: ApplicationPackageEntityModel = dm.project_definition.entities[
"myapp_pkg_polly"
]
mock_cli_ctx.return_value = dm.template_context

manager.execute_package_post_deploy_hooks()
execute_post_deploy_hooks(
console=cc,
project_root=project_dir,
post_deploy_hooks=pkg_model.meta.post_deploy,
deployed_object_type=pkg_model.get_type(),
database_name=pkg_model.fqn.name,
)

assert mock_execute_query.mock_calls == []
assert mock_execute_queries.mock_calls == []
Expand All @@ -113,16 +130,21 @@ def test_package_post_deploy_scripts_with_non_existing_scripts(
project_directory,
):
mock_conn.return_value = MockConnectionCtx()
with project_directory("napp_post_deploy_missing_file") as project_dir:
with project_directory("napp_post_deploy_missing_file_v2") as project_dir:
dm = DefinitionManager(project_dir)
manager = NativeAppManager(
project_definition=dm.project_definition.native_app,
project_root=dm.project_root,
)
pkg_model: ApplicationPackageEntityModel = dm.project_definition.entities[
"myapp_pkg"
]
mock_cli_ctx.return_value = dm.template_context

with pytest.raises(MissingScriptError) as err:
manager.execute_package_post_deploy_hooks()
execute_post_deploy_hooks(
console=cc,
project_root=project_dir,
post_deploy_hooks=pkg_model.meta.post_deploy,
deployed_object_type=pkg_model.get_type(),
database_name=pkg_model.fqn.name,
)

assert (
err.value.message
Expand All @@ -141,17 +163,22 @@ def test_package_post_deploy_scripts_with_sql_error(
project_directory,
):
mock_conn.return_value = MockConnectionCtx()
with project_directory("napp_post_deploy") as project_dir:
with project_directory("napp_post_deploy_v2") as project_dir:
dm = DefinitionManager(project_dir)
manager = NativeAppManager(
project_definition=dm.project_definition.native_app,
project_root=dm.project_root,
)
pkg_model: ApplicationPackageEntityModel = dm.project_definition.entities[
"myapp_pkg"
]
mock_cli_ctx.return_value = dm.template_context
mock_execute_query.side_effect = ProgrammingError()

with pytest.raises(ProgrammingError):
manager.execute_package_post_deploy_hooks()
execute_post_deploy_hooks(
console=cc,
project_root=project_dir,
post_deploy_hooks=pkg_model.meta.post_deploy,
deployed_object_type=pkg_model.get_type(),
database_name=pkg_model.fqn.name,
)


@mock.patch.dict(os.environ, {"USER": "test_user"})
Expand All @@ -164,11 +191,7 @@ def test_package_scripts_and_post_deploy_found(
) as project_dir:

with pytest.raises(SchemaValidationError) as err:
dm = DefinitionManager(project_dir)
NativeAppManager(
project_definition=dm.project_definition.native_app,
project_root=dm.project_root,
)
DefinitionManager(project_dir).project_definition # noqa

assert (
"package.scripts and package.post_deploy fields cannot be used together"
Expand All @@ -193,7 +216,7 @@ def test_package_post_deploy_scripts_with_templates(
template_syntax,
):
mock_conn.return_value = MockConnectionCtx()
with project_directory("napp_post_deploy") as project_dir:
with project_directory("napp_post_deploy_v2") as project_dir:
# edit scripts/package_post_deploy1.sql to include template variables
with open(project_dir / "scripts" / "package_post_deploy1.sql", "w") as f:
f.write(
Expand All @@ -207,13 +230,18 @@ def test_package_post_deploy_scripts_with_templates(
)

dm = DefinitionManager(project_dir, {"ctx": {"env": {"test": "test_value"}}})
manager = NativeAppManager(
project_definition=dm.project_definition.native_app,
project_root=dm.project_root,
)
pkg_model: ApplicationPackageEntityModel = dm.project_definition.entities[
"myapp_pkg"
]
mock_cli_ctx.return_value = dm.template_context

manager.execute_package_post_deploy_hooks()
execute_post_deploy_hooks(
console=cc,
project_root=project_dir,
post_deploy_hooks=pkg_model.meta.post_deploy,
deployed_object_type=pkg_model.get_type(),
database_name=pkg_model.fqn.name,
)

assert mock_execute_query.mock_calls == [
mock.call("use database myapp_pkg_test_user"),
Expand Down Expand Up @@ -247,7 +275,7 @@ def test_package_post_deploy_scripts_with_mix_syntax_templates(
project_directory,
):
mock_conn.return_value = MockConnectionCtx()
with project_directory("napp_post_deploy") as project_dir:
with project_directory("napp_post_deploy_v2") as project_dir:
# edit scripts/package_post_deploy1.sql to include template variables
with open(project_dir / "scripts" / "package_post_deploy1.sql", "w") as f:
f.write(
Expand All @@ -262,14 +290,19 @@ def test_package_post_deploy_scripts_with_mix_syntax_templates(
)

dm = DefinitionManager(project_dir, {"ctx": {"env": {"test": "test_value"}}})
manager = NativeAppManager(
project_definition=dm.project_definition.native_app,
project_root=dm.project_root,
)
pkg_model: ApplicationPackageEntityModel = dm.project_definition.entities[
"myapp_pkg"
]
mock_cli_ctx.return_value = dm.template_context

with pytest.raises(InvalidTemplate) as err:
manager.execute_package_post_deploy_hooks()
execute_post_deploy_hooks(
console=cc,
project_root=project_dir,
post_deploy_hooks=pkg_model.meta.post_deploy,
deployed_object_type=pkg_model.get_type(),
database_name=pkg_model.fqn.name,
)

assert (
"The SQL query in scripts/package_post_deploy1.sql mixes &{ ... } syntax and <% ... %> syntax."
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
definition_version: '2'
entities:
myapp_pkg:
type: application package
identifier: <% fn.concat_ids('myapp', '_pkg_', fn.sanitize_id(fn.get_username('unknown_user')) | lower) %>
artifacts:
- src: app/*
dest: ./
manifest: app/manifest.yml
meta:
post_deploy:
- sql_script: scripts/package_missing_script.sql
myapp:
type: application
identifier: <% fn.concat_ids('myapp', '_', fn.sanitize_id(fn.get_username('unknown_user')) | lower) %>
from:
target: myapp_pkg
meta:
post_deploy:
- sql_script: scripts/missing.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- app post-deploy script (1/2)

select <% ctx.entities.myapp.identifier %>;
select <% ctx.env.foo %>;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- app post-deploy script (2/2)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- package post-deploy script (1/2)

select <% ctx.entities.myapp.identifier %>;
select <% ctx.env.package_foo %>;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- package post-deploy script (2/2)
25 changes: 25 additions & 0 deletions tests/test_data/projects/napp_post_deploy_v2/snowflake.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
definition_version: 2
entities:
myapp_pkg:
type: application package
identifier: <% fn.concat_ids('myapp', '_pkg_', fn.sanitize_id(fn.get_username('unknown_user')) | lower) %>
artifacts:
- src: app/*
dest: ./
manifest: app/manifest.yml
meta:
post_deploy:
- sql_script: scripts/package_post_deploy1.sql
- sql_script: scripts/package_post_deploy2.sql
myapp:
type: application
identifier: myapp
from:
target: myapp_pkg
meta:
post_deploy:
- sql_script: scripts/app_post_deploy1.sql
- sql_script: scripts/app_post_deploy2.sql
env:
foo: bar
package_foo: package_bar
16 changes: 5 additions & 11 deletions tests_integration/nativeapp/test_large_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@

import os

from snowflake.cli._plugins.nativeapp.entities.application_package import (
ApplicationPackageEntityModel,
)
from snowflake.cli.api.secure_path import SecurePath
from snowflake.cli.api.project.definition_manager import DefinitionManager
from snowflake.cli._plugins.nativeapp.manager import NativeAppManager
from snowflake.cli._plugins.stage.md5 import parse_multipart_md5sum

from tests.project.fixtures import *
Expand All @@ -40,20 +42,12 @@ def test_large_upload_skips_reupload(
Ensure that files uploaded in multiple parts are not re-uploaded unnecessarily.
This test will currently fail when run on a non-AWS deployment.
"""
from snowflake.cli._plugins.nativeapp.v2_conversions.compat import (
_pdf_v2_to_v1,
)

project_dir = project_definition_files[0].parent
with pushd(project_dir):
# figure out what the source stage is resolved to
dm = DefinitionManager(project_dir)
native_app = (
dm.project_definition.native_app
if hasattr(dm.project_definition, "native_app")
else _pdf_v2_to_v1(dm.project_definition).native_app
)
stage_fqn = NativeAppManager(native_app, project_dir).stage_fqn
pkg_model: ApplicationPackageEntityModel = dm.project_definition.entities["pkg"]
stage_fqn = f"{pkg_model.fqn.name}.{pkg_model.stage}"

# deploy the application package
result = runner.invoke_with_connection_json(["app", "deploy"])
Expand Down

0 comments on commit 7e0950c

Please sign in to comment.