123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- # Copyright 2021-2024 Avaiga Private Limited
- #
- # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
- # the License. You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
- # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
- # specific language governing permissions and limitations under the License.
- import filecmp
- import os
- import shutil
- import sys
- from sqlite3 import OperationalError
- from unittest.mock import patch
- import mongomock
- import pytest
- from taipy.core._entity._migrate_cli import _MigrateCLI
- @pytest.fixture(scope="function", autouse=True)
- def clean_data_folder():
- if os.path.exists("tests/core/_entity/.data"):
- shutil.rmtree("tests/core/_entity/.data")
- yield
- def test_migrate_fs_default(caplog):
- _MigrateCLI.create_parser()
- # Test migrate with default .data folder
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "filesystem", "--skip-backup"]):
- _MigrateCLI.parse_arguments()
- assert "Starting entity migration from '.taipy/' folder" in caplog.text
- def test_migrate_fs_specified_folder(caplog):
- _MigrateCLI.create_parser()
- # Copy data_sample to .data folder for testing
- data_sample_path = "tests/core/_entity/data_sample"
- data_path = "tests/core/_entity/.data"
- shutil.copytree(data_sample_path, data_path)
- # Run with --skip-backup to only test the migration
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "filesystem", data_path, "--skip-backup"]):
- _MigrateCLI.parse_arguments()
- assert f"Starting entity migration from '{data_path}' folder" in caplog.text
- # Compare migrated .data folder with data_sample_migrated
- dircmp_result = filecmp.dircmp(data_path, "tests/core/_entity/data_sample_migrated")
- assert not dircmp_result.diff_files and not dircmp_result.left_only and not dircmp_result.right_only
- for subdir in dircmp_result.subdirs.values():
- assert not subdir.diff_files and not subdir.left_only and not subdir.right_only
- def test_migrate_fs_backup_and_remove(caplog):
- _MigrateCLI.create_parser()
- # Copy data_sample to .data folder for testing
- data_sample_path = "tests/core/_entity/data_sample"
- data_path = "tests/core/_entity/.data"
- backup_path = "tests/core/_entity/.data_backup"
- shutil.copytree(data_sample_path, data_path)
- # Remove backup when it does not exist should raise an error
- with pytest.raises(SystemExit) as err:
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "filesystem", data_path, "--remove-backup"]):
- _MigrateCLI.parse_arguments()
- assert err.value.code == 1
- assert f"The backup folder '{backup_path}' does not exist." in caplog.text
- assert not os.path.exists(backup_path)
- # Run without --skip-backup to create the backup folder
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "filesystem", data_path]):
- _MigrateCLI.parse_arguments()
- assert f"Backed up entities from '{data_path}' to '{backup_path}' folder before migration." in caplog.text
- assert os.path.exists(backup_path)
- # Remove backup
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "filesystem", data_path, "--remove-backup"]):
- _MigrateCLI.parse_arguments()
- assert f"Removed backup entities from the backup folder '{backup_path}'." in caplog.text
- assert not os.path.exists(backup_path)
- def test_migrate_fs_backup_and_restore(caplog):
- _MigrateCLI.create_parser()
- # Copy data_sample to .data folder for testing
- data_sample_path = "tests/core/_entity/data_sample"
- data_path = "tests/core/_entity/.data"
- backup_path = "tests/core/_entity/.data_backup"
- shutil.copytree(data_sample_path, data_path)
- # Restore backup when it does not exist should raise an error
- with pytest.raises(SystemExit) as err:
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "filesystem", data_path, "--restore"]):
- _MigrateCLI.parse_arguments()
- assert err.value.code == 1
- assert f"The backup folder '{backup_path}' does not exist." in caplog.text
- assert not os.path.exists(backup_path)
- # Run without --skip-backup to create the backup folder
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "filesystem", data_path]):
- _MigrateCLI.parse_arguments()
- assert os.path.exists(backup_path)
- # restore the backup
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "filesystem", data_path, "--restore"]):
- _MigrateCLI.parse_arguments()
- assert f"Restored entities from the backup folder '{backup_path}' to '{data_path}'." in caplog.text
- assert not os.path.exists(backup_path)
- # Compare migrated .data folder with data_sample to ensure restoring the backup worked
- dircmp_result = filecmp.dircmp(data_path, "tests/core/_entity/data_sample")
- assert not dircmp_result.diff_files and not dircmp_result.left_only and not dircmp_result.right_only
- for subdir in dircmp_result.subdirs.values():
- assert not subdir.diff_files and not subdir.left_only and not subdir.right_only
- def test_migrate_fs_non_existing_folder(caplog):
- _MigrateCLI.create_parser()
- # Test migrate with a non-existing folder
- with pytest.raises(SystemExit) as err:
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "filesystem", "non-existing-folder"]):
- _MigrateCLI.parse_arguments()
- assert err.value.code == 1
- assert "Folder 'non-existing-folder' does not exist." in caplog.text
- @patch("taipy.core._entity._migrate_cli._migrate_sql_entities")
- def test_migrate_sql_specified_path(_migrate_sql_entities_mock, tmp_sqlite):
- _MigrateCLI.create_parser()
- # Test the _migrate_sql_entities is called once with the correct path
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "sql", tmp_sqlite, "--skip-backup"]):
- _MigrateCLI.parse_arguments()
- assert _migrate_sql_entities_mock.assert_called_once_with(path=tmp_sqlite)
- def test_migrate_sql_backup_and_remove(caplog, tmp_sqlite):
- _MigrateCLI.create_parser()
- # Create the .sqlite file to test
- with open(tmp_sqlite, "w") as f:
- f.write("")
- file_name, file_extension = tmp_sqlite.rsplit(".", 1)
- backup_sqlite = f"{file_name}_backup.{file_extension}"
- # Remove backup when it does not exist should raise an error
- with pytest.raises(SystemExit) as err:
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "sql", tmp_sqlite, "--remove-backup"]):
- _MigrateCLI.parse_arguments()
- assert err.value.code == 1
- assert f"The backup database '{backup_sqlite}' does not exist." in caplog.text
- assert not os.path.exists(backup_sqlite)
- # Run without --skip-backup to create the backup database
- with pytest.raises((SystemExit, OperationalError)):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "sql", tmp_sqlite]):
- _MigrateCLI.parse_arguments()
- assert os.path.exists(backup_sqlite)
- # Remove backup
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "sql", tmp_sqlite, "--remove-backup"]):
- _MigrateCLI.parse_arguments()
- assert f"Removed backup entities from the backup database '{backup_sqlite}'." in caplog.text
- assert not os.path.exists(backup_sqlite)
- @pytest.mark.skipif(sys.platform == "win32", reason="Does not run on windows due to PermissionError: [WinError 32]")
- def test_migrate_sql_backup_and_restore(caplog, tmp_sqlite):
- _MigrateCLI.create_parser()
- # Create the .sqlite file to test
- with open(tmp_sqlite, "w") as f:
- f.write("")
- file_name, file_extension = tmp_sqlite.rsplit(".", 1)
- backup_sqlite = f"{file_name}_backup.{file_extension}"
- # Restore backup when it does not exist should raise an error
- with pytest.raises(SystemExit) as err:
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "sql", tmp_sqlite, "--restore"]):
- _MigrateCLI.parse_arguments()
- assert err.value.code == 1
- assert f"The backup database '{backup_sqlite}' does not exist." in caplog.text
- assert not os.path.exists(backup_sqlite)
- # Run without --skip-backup to create the backup database
- with pytest.raises((SystemExit, OperationalError)):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "sql", tmp_sqlite]):
- _MigrateCLI.parse_arguments()
- assert os.path.exists(backup_sqlite)
- # Restore the backup
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "sql", tmp_sqlite, "--restore"]):
- _MigrateCLI.parse_arguments()
- assert f"Restored entities from the backup database '{backup_sqlite}' to '{tmp_sqlite}'." in caplog.text
- assert not os.path.exists(backup_sqlite)
- def test_migrate_sql_non_existing_path(caplog):
- _MigrateCLI.create_parser()
- # Test migrate without providing a path
- with pytest.raises(SystemExit) as err:
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "sql"]):
- _MigrateCLI.parse_arguments()
- assert err.value.code == 1
- assert "Missing the required sqlite path." in caplog.text
- caplog.clear()
- # Test migrate with a non-existing-path.sqlite file
- with pytest.raises(SystemExit) as err:
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "sql", "non-existing-path.sqlite"]):
- _MigrateCLI.parse_arguments()
- assert err.value.code == 1
- assert "File 'non-existing-path.sqlite' does not exist." in caplog.text
- @patch("taipy.core._entity._migrate_cli._migrate_mongo_entities")
- def test_call_to_migrate_mongo(_migrate_mongo_entities_mock):
- _MigrateCLI.create_parser()
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "mongo"]):
- _MigrateCLI.parse_arguments()
- assert _migrate_mongo_entities_mock.assert_called_once_with()
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "mongo", "host", "port", "user", "password"]):
- _MigrateCLI.parse_arguments()
- assert _migrate_mongo_entities_mock.assert_called_once_with("host", "port", "user", "password")
- @mongomock.patch(servers=(("localhost", 27017),))
- def test_migrate_mongo_backup_and_remove(caplog):
- _MigrateCLI.create_parser()
- mongo_backup_path = ".mongo_backup"
- # Remove backup when it does not exist should raise an error
- with pytest.raises(SystemExit) as err:
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "mongo", "--remove-backup"]):
- _MigrateCLI.parse_arguments()
- assert err.value.code == 1
- assert f"The backup folder '{mongo_backup_path}' does not exist." in caplog.text
- assert not os.path.exists(mongo_backup_path)
- # Run without --skip-backup to create the backup database
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "mongo"]):
- _MigrateCLI.parse_arguments()
- assert os.path.exists(mongo_backup_path)
- # Remove backup
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "mongo", "--remove-backup"]):
- _MigrateCLI.parse_arguments()
- assert f"Removed backup entities from the backup folder '{mongo_backup_path}'." in caplog.text
- assert not os.path.exists(mongo_backup_path)
- @mongomock.patch(servers=(("localhost", 27017),))
- def test_migrate_mongo_backup_and_restore(caplog):
- _MigrateCLI.create_parser()
- mongo_backup_path = ".mongo_backup"
- # Restore backup when it does not exist should raise an error
- with pytest.raises(SystemExit) as err:
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "mongo", "--restore"]):
- _MigrateCLI.parse_arguments()
- assert err.value.code == 1
- assert f"The backup folder '{mongo_backup_path}' does not exist." in caplog.text
- assert not os.path.exists(mongo_backup_path)
- # Run without --skip-backup to create the backup database
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "mongo"]):
- _MigrateCLI.parse_arguments()
- assert os.path.exists(mongo_backup_path)
- # Restore the backup
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "mongo", "--restore"]):
- _MigrateCLI.parse_arguments()
- assert f"Restored entities from the backup folder '{mongo_backup_path}'." in caplog.text
- assert not os.path.exists(mongo_backup_path)
- def test_not_provide_valid_repository_type(caplog):
- _MigrateCLI.create_parser()
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate"]):
- _MigrateCLI.parse_arguments()
- assert "the following arguments are required: --repository-type" in caplog.text
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type"]):
- _MigrateCLI.parse_arguments()
- assert "argument --repository-type: expected at least one argument" in caplog.text
- with pytest.raises(SystemExit):
- with patch("sys.argv", ["prog", "migrate", "--repository-type", "invalid-repository-type"]):
- _MigrateCLI.parse_arguments()
- assert "Unknown repository type invalid-repository-type" in caplog.text
|