From 404f39e417012409876af887d3d6d690c23402d0 Mon Sep 17 00:00:00 2001 From: Tomasz Urbaszek Date: Fri, 20 Sep 2024 11:36:16 +0200 Subject: [PATCH] fixup! fixup! Rename ws migrate to migrate-definition --- RELEASE-NOTES.md | 2 +- .../cli/_plugins/helpers/commands.py | 2 +- tests/helpers/__init__.py | 0 tests/helpers/test_v1_to_v2.py | 143 ++++++++++++++++++ tests/workspace/test_manager.py | 140 ----------------- 5 files changed, 145 insertions(+), 142 deletions(-) create mode 100644 tests/helpers/__init__.py create mode 100644 tests/helpers/test_v1_to_v2.py diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 48b9850e8..c69bacbcc 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -39,7 +39,7 @@ * Added support for external access (api integrations and secrets) in Streamlit. * Added support for `<% ... %>` syntax in SQL templating. * Support multiple Streamlit application in single snowflake.yml project definition file. -* Added `snow migrate-defintion` command to migrate `snowflake.yml` file from V1 to V2. +* Added `snow helpers v1-to-v2` command to migrate `snowflake.yml` file from V1 to V2. * Added `--package-entity-id` and `--app-entity-id` options to `snow app` commands to allow targeting specific entities when the `definition_version` in `snowflake.yml` is `2` or higher and it contains multiple `application package` or `application` entities. * Added templates expansion of arbitrary files for Native Apps through `templates` processor. * Added `SNOWFLAKE_..._PRIVATE_KEY_RAW` environment variable to pass private key as a raw string. diff --git a/src/snowflake/cli/_plugins/helpers/commands.py b/src/snowflake/cli/_plugins/helpers/commands.py index 9e70eb903..4799f2936 100644 --- a/src/snowflake/cli/_plugins/helpers/commands.py +++ b/src/snowflake/cli/_plugins/helpers/commands.py @@ -30,7 +30,7 @@ ) -@app.command(no_args_is_help=True) +@app.command() def v1_to_v2( accept_templates: bool = typer.Option( False, "-t", "--accept-templates", help="Allows the migration of templates." diff --git a/tests/helpers/__init__.py b/tests/helpers/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/helpers/test_v1_to_v2.py b/tests/helpers/test_v1_to_v2.py new file mode 100644 index 000000000..6a230dac9 --- /dev/null +++ b/tests/helpers/test_v1_to_v2.py @@ -0,0 +1,143 @@ +import logging +from pathlib import Path +from textwrap import dedent + +import pytest +import yaml + + +def test_migration_already_v2( + runner, + project_directory, +): + with project_directory("migration_already_v2"): + result = runner.invoke(["helpers", "v1-to-v2"]) + + assert result.exit_code == 0 + assert "Project definition is already at version 2." in result.output + + +def test_migrations_with_multiple_entities( + runner, project_directory, os_agnostic_snapshot +): + with project_directory("migration_multiple_entities"): + result = runner.invoke(["helpers", "v1-to-v2"]) + assert result.exit_code == 0 + assert Path("snowflake.yml").read_text() == os_agnostic_snapshot + assert Path("snowflake_V1.yml").read_text() == os_agnostic_snapshot + + +def test_migration_native_app_missing_manifest(runner, project_directory): + with project_directory("migration_multiple_entities") as project_dir: + (project_dir / "app" / "manifest.yml").unlink() + result = runner.invoke(["helpers", "v1-to-v2"]) + assert result.exit_code == 1 + assert "manifest.yml file not found" in result.output + + +def test_migration_native_app_no_artifacts(runner, project_directory): + with project_directory("migration_multiple_entities") as project_dir: + with (project_dir / "snowflake.yml").open("r+") as snowflake_yml: + pdf = yaml.safe_load(snowflake_yml) + pdf["native_app"]["artifacts"] = [] + snowflake_yml.seek(0) + yaml.safe_dump(pdf, snowflake_yml) + snowflake_yml.truncate() + result = runner.invoke(["helpers", "v1-to-v2"]) + assert result.exit_code == 1 + assert "No artifacts mapping found in project definition" in result.output + assert "Could not bundle Native App artifacts" in result.output + + +def test_migration_native_app_package_scripts(runner, project_directory): + with project_directory("migration_package_scripts") as project_dir: + result = runner.invoke(["helpers", "v1-to-v2"]) + assert result.exit_code == 0 + package_scripts_dir = project_dir / "package_scripts" + for file in package_scripts_dir.iterdir(): + assert file.read_text() == dedent( + """\ + -- Just a demo package script, won't actually be executed in tests + select * from <% ctx.entities.pkg.identifier %>.my_schema.my_table + """ + ) + + +@pytest.mark.parametrize( + "project_directory_name", ["snowpark_templated_v1", "streamlit_templated_v1"] +) +def test_if_template_is_not_rendered_during_migration_with_option_checked( + runner, project_directory, project_directory_name, os_agnostic_snapshot, caplog +): + with project_directory(project_directory_name): + with caplog.at_level(logging.WARNING): + result = runner.invoke(["helpers", "v1-to-v2", "--accept-templates"]) + + assert result.exit_code == 0 + assert Path("snowflake.yml").read_text() == os_agnostic_snapshot + assert Path("snowflake_V1.yml").read_text() == os_agnostic_snapshot + assert ( + "Your V1 definition contains templates. We cannot guarantee the correctness of the migration." + in caplog.text + ) + + +@pytest.mark.parametrize( + "project_directory_name", ["snowpark_templated_v1", "streamlit_templated_v1"] +) +def test_if_template_raises_error_during_migrations( + runner, project_directory, project_directory_name, os_agnostic_snapshot +): + with project_directory(project_directory_name): + result = runner.invoke(["helpers", "v1-to-v2"]) + assert result.exit_code == 1, result.output + assert "Project definition contains templates" in result.output + + +def test_migration_with_only_envs(project_directory, runner): + with project_directory("sql_templating"): + result = runner.invoke(["helpers", "v1-to-v2"]) + + assert result.exit_code == 0 + + +@pytest.mark.parametrize( + "duplicated_entity", + [ + """ + - name: test + handler: "test" + signature: "" + returns: string + runtime: "3.10" + """, + """ +streamlit: + name: test + stage: streamlit + query_warehouse: test_warehouse + main_file: "streamlit_app.py" + title: "My Fancy Streamlit" + """, + """ + - name: test + handler: "test" + signature: "" + returns: string + handler: test + runtime: "3.10" + """, + ], +) +def test_migrating_a_file_with_duplicated_keys_raises_an_error( + runner, project_directory, os_agnostic_snapshot, duplicated_entity +): + with project_directory("snowpark_procedures") as pd: + definition_path = pd / "snowflake.yml" + + with open(definition_path, "a") as definition_file: + definition_file.write(duplicated_entity) + + result = runner.invoke(["helpers", "v1-to-v2"]) + assert result.exit_code == 1, result.output + assert result.output == os_agnostic_snapshot diff --git a/tests/workspace/test_manager.py b/tests/workspace/test_manager.py index 8ede31faa..f4ecfbf58 100644 --- a/tests/workspace/test_manager.py +++ b/tests/workspace/test_manager.py @@ -13,10 +13,7 @@ # limitations under the License. from __future__ import annotations -import logging import os -from pathlib import Path -from textwrap import dedent from unittest import mock import pytest @@ -86,143 +83,6 @@ def test_bundle_of_invalid_entity_type(temp_dir): ws_manager.perform_action("app", EntityActions.BUNDLE) -def test_migration_already_v2( - runner, - project_directory, -): - with project_directory("migration_already_v2"): - result = runner.invoke(["helpers", "v1-to-v2"]) - - assert result.exit_code == 0 - assert "Project definition is already at version 2." in result.output - - -def test_migrations_with_multiple_entities( - runner, project_directory, os_agnostic_snapshot -): - with project_directory("migration_multiple_entities"): - result = runner.invoke(["helpers", "v1-to-v2"]) - assert result.exit_code == 0 - assert Path("snowflake.yml").read_text() == os_agnostic_snapshot - assert Path("snowflake_V1.yml").read_text() == os_agnostic_snapshot - - -def test_migration_native_app_missing_manifest(runner, project_directory): - with project_directory("migration_multiple_entities") as project_dir: - (project_dir / "app" / "manifest.yml").unlink() - result = runner.invoke(["helpers", "v1-to-v2"]) - assert result.exit_code == 1 - assert "manifest.yml file not found" in result.output - - -def test_migration_native_app_no_artifacts(runner, project_directory): - with project_directory("migration_multiple_entities") as project_dir: - with (project_dir / "snowflake.yml").open("r+") as snowflake_yml: - pdf = yaml.safe_load(snowflake_yml) - pdf["native_app"]["artifacts"] = [] - snowflake_yml.seek(0) - yaml.safe_dump(pdf, snowflake_yml) - snowflake_yml.truncate() - result = runner.invoke(["helpers", "v1-to-v2"]) - assert result.exit_code == 1 - assert "No artifacts mapping found in project definition" in result.output - assert "Could not bundle Native App artifacts" in result.output - - -def test_migration_native_app_package_scripts(runner, project_directory): - with project_directory("migration_package_scripts") as project_dir: - result = runner.invoke(["helpers", "v1-to-v2"]) - assert result.exit_code == 0 - package_scripts_dir = project_dir / "package_scripts" - for file in package_scripts_dir.iterdir(): - assert file.read_text() == dedent( - """\ - -- Just a demo package script, won't actually be executed in tests - select * from <% ctx.entities.pkg.identifier %>.my_schema.my_table - """ - ) - - -@pytest.mark.parametrize( - "project_directory_name", ["snowpark_templated_v1", "streamlit_templated_v1"] -) -def test_if_template_is_not_rendered_during_migration_with_option_checked( - runner, project_directory, project_directory_name, os_agnostic_snapshot, caplog -): - with project_directory(project_directory_name): - with caplog.at_level(logging.WARNING): - result = runner.invoke(["helpers", "v1-to-v2", "--accept-templates"]) - - assert result.exit_code == 0 - assert Path("snowflake.yml").read_text() == os_agnostic_snapshot - assert Path("snowflake_V1.yml").read_text() == os_agnostic_snapshot - assert ( - "Your V1 definition contains templates. We cannot guarantee the correctness of the migration." - in caplog.text - ) - - -@pytest.mark.parametrize( - "project_directory_name", ["snowpark_templated_v1", "streamlit_templated_v1"] -) -def test_if_template_raises_error_during_migrations( - runner, project_directory, project_directory_name, os_agnostic_snapshot -): - with project_directory(project_directory_name): - result = runner.invoke(["helpers", "v1-to-v2"]) - assert result.exit_code == 1 - assert "Project definition contains templates" in result.output - - -def test_migration_with_only_envs(project_directory, runner): - with project_directory("sql_templating"): - result = runner.invoke(["helpers", "v1-to-v2"]) - - assert result.exit_code == 0 - - -@pytest.mark.parametrize( - "duplicated_entity", - [ - """ - - name: test - handler: "test" - signature: "" - returns: string - runtime: "3.10" - """, - """ -streamlit: - name: test - stage: streamlit - query_warehouse: test_warehouse - main_file: "streamlit_app.py" - title: "My Fancy Streamlit" - """, - """ - - name: test - handler: "test" - signature: "" - returns: string - handler: test - runtime: "3.10" - """, - ], -) -def test_migrating_a_file_with_duplicated_keys_raises_an_error( - runner, project_directory, os_agnostic_snapshot, duplicated_entity -): - with project_directory("snowpark_procedures") as pd: - definition_path = pd / "snowflake.yml" - - with open(definition_path, "a") as definition_file: - definition_file.write(duplicated_entity) - - result = runner.invoke(["helpers", "v1-to-v2"]) - assert result.exit_code == 1 - assert result.output == os_agnostic_snapshot - - @pytest.mark.parametrize("definition_version", [1, "1.1"]) def test_migrate_nativeapp_fields_with_username( runner, project_directory, definition_version