Exemple #1
0
    def test_deploy_regular_with_instance_resume_running(self):
        """Tests the deploy mechanism in regular mode with instance
        within resume action for running service."""

        instances = {"crypto": {"artifact": "cryptocurrency"}}
        cryptocurrency_advanced_config_dict = generate_config(self.network, instances=instances)

        cryptocurrency_advanced_config = Configuration(cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            explorer = launcher.explorer()

            launcher.deploy_all()
            launcher.wait_for_deploy()
            launcher.start_all()
            launcher.wait_for_start()

            self.wait_for_api_restart()
            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.is_deployed(artifact)
                self.assertEqual(deployed, True)

            self.assertEqual(len(launcher.launch_state.completed_configs()), 1)

        # try to resume running service
        instances = {"crypto": {"artifact": "cryptocurrency", "action": "resume"}}
        cryptocurrency_advanced_config_dict = generate_config(self.network, instances=instances, artifact_action="none")

        cryptocurrency_advanced_config = Configuration(cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            launcher.deploy_all()
            launcher.wait_for_deploy()
            launcher.start_all()
            with self.assertRaises(NotCommittedError):
                launcher.wait_for_start()
Exemple #2
0
    def test_deploy_run_dev(self):
        """Tests the deploy mechanism in run-dev mode."""

        cryptocurrency_advanced_config_dict = {
            "networks": launcher_networks(self.network),
            "deadline_height": 10000,
            "artifacts": {
                "cryptocurrency": {
                    "runtime": "rust",
                    "name": "exonum-cryptocurrency-advanced:0.13.0-rc.2"
                }
            },
            # We aren't testing initialization here.
            "instances": {},
        }

        cryptocurrency_advanced_config = Configuration(
            cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            explorer = launcher.explorer()

            launcher.deploy_all()
            launcher.wait_for_deploy()

            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.check_deployed(artifact)
                self.assertEqual(deployed, True)
Exemple #3
0
    def test_deploy_regular_invalid_artifact_name(self):
        """Tests the deploy mechanism in regular mode with invalid artifact"""

        cryptocurrency_advanced_config_dict = {
            "networks": launcher_networks(self.network),
            "deadline_height": 10000,
            "artifacts": {
                "cryptocurrency": {
                    "runtime": "rust",
                    "name": "test-service:0.13.0-rc.2"
                }
            },
            # We aren't testing initialization here.
            "instances": {},
        }

        cryptocurrency_advanced_config = Configuration(
            cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            explorer = launcher.explorer()

            launcher.deploy_all()
            launcher.wait_for_deploy()

            # invalid artifact should not be deployed
            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.check_deployed(artifact)
                self.assertEqual(deployed, False)
Exemple #4
0
    def test_deploy_regular_exceed_deadline_height(self):
        """Tests the deploy mechanism in regular mode with exceeded deadline height"""

        cryptocurrency_advanced_config_dict = {
            "networks": launcher_networks(self.network),
            "deadline_height": 0,
            "artifacts": {
                "cryptocurrency": {
                    "runtime": "rust",
                    "name": "exonum-cryptocurrency-advanced",
                    "version": "0.13.0-rc.2",
                }
            },
            # We aren't testing initialization here.
            "instances": {},
        }

        cryptocurrency_advanced_config = Configuration(
            cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            explorer = launcher.explorer()

            launcher.deploy_all()
            launcher.wait_for_deploy()

            # artifact should not be deployed because of exceeded deadline height
            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.check_deployed(artifact)
                self.assertEqual(deployed, False)
Exemple #5
0
    def test_deploy_regular_with_instance_stop_action_before_start(self):
        """Tests the deploy mechanism in regular mode with instance
        within stop action before start."""

        cryptocurrency_advanced_config_dict = {
            "networks": launcher_networks(self.network),
            "deadline_height": 10000,
            "artifacts": {
                "cryptocurrency": {
                    "runtime": "rust",
                    "name": "exonum-cryptocurrency-advanced",
                    "version": "0.13.0-rc.2",
                }
            },
            "instances": {"crypto": {"artifact": "cryptocurrency", "action": "stop"}},
        }

        cryptocurrency_advanced_config = Configuration(
            cryptocurrency_advanced_config_dict
        )
        with Launcher(cryptocurrency_advanced_config) as launcher:

            launcher.deploy_all()
            launcher.wait_for_deploy()
            with self.assertRaises(RuntimeError):
                launcher.start_all()
Exemple #6
0
    def setUp(self):
        try:
            self.network = run_4_nodes("exonum-cryptocurrency-advanced")
            wait_network_to_start(self.network)

            instances = {"crypto": {"artifact": "cryptocurrency"}}
            cryptocurrency_advanced_config_dict = generate_config(
                self.network, instances=instances)

            cryptocurrency_advanced_config = Configuration(
                cryptocurrency_advanced_config_dict)
            with Launcher(cryptocurrency_advanced_config) as launcher:
                explorer = launcher.explorer()

                launcher.deploy_all()
                launcher.wait_for_deploy()
                launcher.start_all()
                launcher.wait_for_start()

                for artifact in launcher.launch_state.completed_deployments():
                    deployed = explorer.check_deployed(artifact)
                    self.assertEqual(deployed, True)

                # Launcher checks that config is applied, no need to check it again.
        except Exception as error:
            # If exception is raise in `setUp`, `tearDown` won't be called,
            # thus here we ensure that network is stopped and temporary data is removed.
            # Then we re-raise exception, since the test should fail.
            self.network.stop()
            self.network.deinitialize()
            raise error
Exemple #7
0
    def test_deploy_dev_with_instance(self):
        """Tests the deploy mechanism in dev mode with instance."""

        cryptocurrency_advanced_config_dict = {
            "networks": launcher_networks(self.network),
            "deadline_height": 10000,
            "artifacts": {
                "cryptocurrency": {
                    "runtime": "rust",
                    "name": "exonum-cryptocurrency-advanced",
                    "version": "0.13.0-rc.2",
                }
            },
            "instances": {"crypto": {"artifact": "cryptocurrency"}},
        }

        cryptocurrency_advanced_config = Configuration(
            cryptocurrency_advanced_config_dict
        )
        with Launcher(cryptocurrency_advanced_config) as launcher:
            explorer = launcher.explorer()

            launcher.deploy_all()
            launcher.wait_for_deploy()
            launcher.start_all()
            launcher.wait_for_start()

            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.check_deployed(artifact)
                self.assertEqual(deployed, True)

            self.assertEqual(len(launcher.launch_state.completed_configs()), 1)
Exemple #8
0
    def setUp(self):
        self.network = run_4_nodes("exonum-cryptocurrency-advanced")
        time.sleep(3)
        cryptocurrency_advanced_config_dict = {
            "networks": launcher_networks(self.network),
            "deadline_height": 10000,
            "artifacts": {
                "cryptocurrency": {
                    "runtime": "rust",
                    "name": "exonum-cryptocurrency-advanced:0.13.0-rc.2"
                }
            },
            "instances": {
                "crypto": {
                    "artifact": "cryptocurrency"
                }
            },
        }

        cryptocurrency_advanced_config = Configuration(
            cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            explorer = launcher.explorer()

            launcher.deploy_all()
            launcher.wait_for_deploy()
            launcher.start_all()
            launcher.wait_for_start()

            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.check_deployed(artifact)
                self.assertEqual(deployed, True)

            for instance in launcher.launch_state.completed_initializations():
                explorer.wait_for_start(instance)
    def test_load_plugins_runtime_only(self) -> None:
        """Tests that plugins are loaded as expected if only the runtime plugins are present: no artifact plugins"""
        config = TestConfiguration.load_config(
            "custom_plugins_runtime_only.yml")

        launcher = Launcher(config)
        self.assertEqual(type(launcher._runtime_plugins["rust"]),
                         RustSpecLoader)
        self.assertEqual(type(launcher._runtime_plugins["sample3"]),
                         TestRuntimeSpecLoader)
Exemple #10
0
    def test_unload_artifact_of_running_service(self):
        """Tests unload logic when running service references to an artifact."""

        # Deploy a service with 0.2.0 version.
        instances = {INSTANCE_NAME: {"artifact": "cryptocurrency"}}
        config_dict = generate_config(self.network, instances=instances)
        deploy_config = Configuration(config_dict)

        with Launcher(deploy_config) as launcher:
            launcher.deploy_all()
            launcher.wait_for_deploy()

            self.wait_for_api_restart()
            explorer = launcher.explorer()
            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.is_deployed(artifact)
                self.assertTrue(deployed)

        # Try to unload artifact with version 0.1.0
        unload_config_dict = generate_config(self.network,
                                             instances=instances,
                                             artifact_action="unload",
                                             artifact_version="0.1.0")
        unload_config = Configuration(unload_config_dict)

        with Launcher(unload_config) as launcher:
            launcher.unload_all()
            launcher.wait_for_unload()

            self.wait_for_api_restart()
            explorer = launcher.explorer()

            for artifact in unload_config.artifacts.values():
                deployed = explorer.is_deployed(artifact)
                self.assertTrue(deployed)  # Not False !!!

            status, message = launcher.launch_state.unload_status
            self.assertEqual(status, ActionResult.Fail)
            self.assertIn(
                "service `101:cryptocurrency` references it as the current artifact",
                message)
Exemple #11
0
    def test_deploy_all(self) -> None:
        """Tests that deploy method uses supervisor to deploy all artifacts from config."""
        config = TestConfiguration.load_config("sample_config.yml")
        launcher = Launcher(config)

        # Build a list of expected arguements for method calls.
        create_calls_sequence = []
        send_calls_sequence = []
        for artifact in config.artifacts.values():
            # Skip artifacts that should not be deployed
            if not artifact.deploy:
                continue

            create_calls_sequence.append(
                call(artifact, launcher._runtime_plugins[artifact.runtime]))
            send_calls_sequence.append(call(b"123"))

        # Mock methods.
        launcher._supervisor.create_deploy_request = MagicMock(
            return_value=b"123")  # type: ignore
        launcher._supervisor.send_deploy_request = MagicMock(
            return_value=["123"])  # type: ignore

        # Call deploy.
        launcher.deploy_all()

        # Check that methods were invoked with the expected arguments and in the expected order.
        launcher._supervisor.create_deploy_request.assert_has_calls(
            create_calls_sequence)  # type: ignore
        launcher._supervisor.send_deploy_request.assert_has_calls(
            send_calls_sequence)  # type: ignore

        # Check that results were added to the pending deployments.
        for artifact in config.artifacts.values():
            if artifact.deploy:
                self.assertEqual(
                    launcher.launch_state._pending_deployments[artifact],
                    ["123"])
            else:
                self.assertTrue(
                    artifact not in launcher.launch_state._pending_deployments)
Exemple #12
0
    def test_deploy_regular_with_consensus_config(self):
        """Tests the deploy mechanism in regular mode with consensus config."""

        pub_configs = self.network._public_configs().split()
        validator_keys = []
        for pub_config in pub_configs:
            keys = []
            with open(pub_config, "r") as file:
                data = file.read()
                keys.append(re.search('consensus_key = "(.+?)"', data).group(1))
                keys.append(re.search('service_key = "(.+?)"', data).group(1))
            validator_keys.append(keys)

        consensus = {
            "validator_keys": validator_keys,
            "first_round_timeout": 3000,
            "status_timeout": 5000,
            "peers_timeout": 10000,
            "txs_block_limit": 5000,
            "max_message_len": 1048576,
            "min_propose_timeout": 10,
            "max_propose_timeout": 200,
            "propose_timeout_threshold": 500,
        }
        instances = {"crypto": {"artifact": "cryptocurrency"}}
        cryptocurrency_advanced_config_dict = generate_config(
            self.network, consensus=consensus, instances=instances
        )

        cryptocurrency_advanced_config = Configuration(
            cryptocurrency_advanced_config_dict
        )
        with Launcher(cryptocurrency_advanced_config) as launcher:
            explorer = launcher.explorer()

            launcher.deploy_all()
            launcher.wait_for_deploy()
            launcher.start_all()
            launcher.wait_for_start()

            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.check_deployed(artifact)
                self.assertEqual(deployed, True)

            self.assertEqual(len(launcher.launch_state.completed_configs()), 1)

        for validator_id in range(self.network.validators_count()):
            host, public_port, private_port = self.network.api_address(validator_id)
            client = ExonumClient(host, public_port, private_port)
            supervisor_api = client.service_apis("supervisor")
            consensus_config = supervisor_api[0].get_service("consensus-config").json()
            # check that initial config has been applied
            self.assertEqual(consensus_config["txs_block_limit"], 5000)
Exemple #13
0
    def test_deinitialize(self) -> None:
        """Tests that deinitialize deinitializes Supervisor."""
        config = TestConfiguration.load_config("sample_config.yml")
        launcher = Launcher(config)

        # Create mock OK response.
        response = Response()
        response.status_code = 200

        # Setup init mocks.
        launcher._supervisor.initialize = MagicMock(
            return_value=None)  # type: ignore
        for client in launcher.clients:
            client.public_api.stats = MagicMock(return_value=response)

        # Initialize launcher.
        launcher.initialize()

        # Setup deinit mock.
        launcher._supervisor.deinitialize = MagicMock(
            return_value=None)  # type: ignore

        # Deinitialize
        launcher.deinitialize()

        launcher._supervisor.deinitialize.assert_called()  # type: ignore
Exemple #14
0
    def test_start_all(self) -> None:
        """Tests that deploy method uses supervisor to deploy all artifacts from config."""
        config = TestConfiguration.load_config("sample_config.yml")
        launcher = Launcher(config)

        # Mark all the artifacts as successfully deployed.
        for artifact in config.artifacts.values():
            launcher.launch_state._completed_deployments[
                artifact] = ActionResult.Success

        # Build a list of expected arguements for method calls.
        start_calls_sequence = []
        send_calls_sequence = []
        spec_loaders = [
            launcher._artifact_plugins.get(instance.artifact,
                                           MockDefaultInstanceSpecLoader())
            for instance in config.instances
        ]
        start_calls_sequence.append(
            call(None, config.instances, spec_loaders, config.actual_from))
        send_calls_sequence.append(call(b"123"))

        # Mock methods.
        launcher._supervisor.create_config_change_request = MagicMock(
            return_value=b"123")  # type: ignore
        launcher._supervisor.send_propose_config_request = MagicMock(
            return_value=["123"])  # type: ignore

        # Call start.
        launcher.start_all()

        # Check that methods were invoked with the expected arguments and in the expected order.
        launcher._supervisor.create_config_change_request.assert_has_calls(
            start_calls_sequence)  # type: ignore
        launcher._supervisor.send_propose_config_request.assert_has_calls(
            send_calls_sequence)  # type: ignore

        # Check that results were added to the pending configs.
        self.assertEqual(
            launcher.launch_state._pending_configs[launcher.config], ["123"])
Exemple #15
0
    def test_load_plugins(self) -> None:
        """Tests that plugins are loaded as expected."""
        config = TestConfiguration.load_config("custom_plugins.yml")

        cryptocurrency = config.artifacts["cryptocurrency"]

        launcher = Launcher(config)
        self.assertEqual(type(launcher._runtime_plugins["rust"]),
                         RustSpecLoader)
        self.assertEqual(type(launcher._runtime_plugins["sample"]),
                         TestRuntimeSpecLoader)
        self.assertEqual(type(launcher._artifact_plugins[cryptocurrency]),
                         TestInstanceSpecLoader)
Exemple #16
0
    def test_migrate_running_service(self):
        """Tests migration flow when the migrating service is running."""

        # Deploy a service with 0.2.0 version.
        instances = {INSTANCE_NAME: {"artifact": "cryptocurrency"}}
        config_dict = generate_config(self.network, instances=instances)
        deploy_config = Configuration(config_dict)

        with Launcher(deploy_config) as launcher:
            launcher.deploy_all()
            launcher.wait_for_deploy()

            self.wait_for_api_restart()
            explorer = launcher.explorer()
            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.is_deployed(artifact)
                self.assertTrue(deployed)

        # Migrate service data from 0.1.0 to 0.2.0 version
        migrations = {
            INSTANCE_NAME: {
                "runtime": "rust",
                "name": "exonum-cryptocurrency",
                "version": "0.2.0"
            }
        }
        migrations_dict = generate_migration_config(self.network, migrations)
        migration_config = Configuration(migrations_dict)

        with Launcher(migration_config) as launcher:
            launcher.migrate_all()
            launcher.wait_for_migration()

            for instance, (
                    status, message
            ) in launcher.launch_state.completed_migrations().items():
                if instance == INSTANCE_NAME:
                    self.assertEqual(status, ActionResult.Fail)
                    self.assertIn("is not stopped or frozen", message)
Exemple #17
0
    def test_deploy_regular_with_instance_resume_action_before_start(self):
        """Tests the deploy mechanism in regular mode with instance
        within resume action before start."""

        instances = {"crypto": {"artifact": "cryptocurrency", "action": "resume"}}
        cryptocurrency_advanced_config_dict = generate_config(self.network, instances=instances)

        cryptocurrency_advanced_config = Configuration(cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            launcher.deploy_all()
            launcher.wait_for_deploy()
            with self.assertRaises(RuntimeError):
                launcher.start_all()
Exemple #18
0
    def test_initialize(self) -> None:
        """Tests that on initialize launcher initializes Supervisor and verifies clients."""
        config = TestConfiguration.load_config("sample_config.yml")
        launcher = Launcher(config)

        # Create mock OK response.
        response = Response()
        response.status_code = 200

        # Setup mocks.
        launcher._supervisor.initialize = MagicMock(
            return_value=None)  # type: ignore
        for client in launcher.clients:
            client.public_api.stats = MagicMock(return_value=response)

        # Initialize launcher.
        launcher.initialize()

        # Check that expected methods are called
        launcher._supervisor.initialize.assert_called()  # type: ignore
        for client in launcher.clients:
            client.public_api.stats.assert_called()
Exemple #19
0
    def test_creation(self) -> None:
        """Tests the creation of the launcher"""
        config = TestConfiguration.load_config("sample_config.yml")
        launcher = Launcher(config)

        self.assertEqual(len(launcher.clients), len(config.networks))
        for i, network in enumerate(config.networks):
            self.assertEqual(launcher.clients[i].hostname, network["host"])
            self.assertEqual(launcher.clients[i].public_api_port,
                             network["public-api-port"])
            self.assertEqual(launcher.clients[i].private_api_port,
                             network["private-api-port"])
            schema = "https" if network["ssl"] else "http"
            self.assertEqual(launcher.clients[i].schema, schema)
Exemple #20
0
    def test_freeze_service(self):
        host, public_port, private_port = self.network.api_address(0)
        client = ExonumClient(host, public_port, private_port)

        # Create wallet
        alice_keys = KeyPair.generate()
        with ExonumCryptoAdvancedClient(client) as crypto_client:
            crypto_client.create_wallet(alice_keys, "Alice")
            with client.create_subscriber("transactions") as subscriber:
                subscriber.wait_for_new_event()
                alice_balance = crypto_client.get_balance(alice_keys)
                self.assertEqual(alice_balance, 100)

        # Freeze the service
        instances = {
            "crypto": {
                "artifact": "cryptocurrency",
                "action": "freeze"
            }
        }
        cryptocurrency_advanced_config_dict = generate_config(
            self.network, instances=instances, artifact_action="none")

        cryptocurrency_advanced_config = Configuration(
            cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            launcher.deploy_all()
            launcher.wait_for_deploy()
            launcher.start_all()
            launcher.wait_for_start()

        # Check that the service status has been changed to `frozen`.
        for service in client.public_api.available_services().json(
        )["services"]:
            if service["spec"]["name"] == "crypto":
                self.assertEqual(service["status"]["type"], "frozen")

        # Try to create a new wallet. The operation should fail.
        with ExonumCryptoAdvancedClient(client) as crypto_client:
            bob_keys = KeyPair.generate()
            response = crypto_client.create_wallet(bob_keys, "Bob")
            self.assertEqual(response.status_code, 400)
            # Because the service is frozen, transaction should be inadmissible.
            self.assertEqual(response.json()["title"],
                             "Failed to add transaction to memory pool")

        # Check that we can use service endpoints for data retrieving. Check wallet once again.
        with ExonumCryptoAdvancedClient(client) as crypto_client:
            alice_balance = crypto_client.get_balance(alice_keys)
            self.assertEqual(alice_balance, 100)
Exemple #21
0
    def test_deploy_run_dev(self):
        """Tests the deploy mechanism in run-dev mode."""

        cryptocurrency_advanced_config_dict = generate_config(self.network)

        cryptocurrency_advanced_config = Configuration(cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            explorer = launcher.explorer()

            launcher.deploy_all()
            launcher.wait_for_deploy()

            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.is_deployed(artifact)
                self.assertTrue(deployed)
Exemple #22
0
    def test_deploy_regular_without_instance(self):
        """Tests the deploy mechanism in regular mode
        without instance"""

        cryptocurrency_advanced_config_dict = generate_config(self.network)

        cryptocurrency_advanced_config = Configuration(cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            launcher.deploy_all()
            launcher.wait_for_deploy()

            explorer = launcher.explorer()
            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.is_deployed(artifact)
                self.assertEqual(deployed, True)
Exemple #23
0
    def test_deploy_regular_exceed_deadline_height(self):
        """Tests the deploy mechanism in regular mode with exceeded deadline height"""

        cryptocurrency_advanced_config_dict = generate_config(self.network, deadline_height=0)
        cryptocurrency_advanced_config = Configuration(cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            launcher.deploy_all()
            with self.assertRaises(NotCommittedError):
                launcher.wait_for_deploy()

            # artifact should not be deployed because of exceeded deadline height
            explorer = launcher.explorer()
            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.is_deployed(artifact)
                self.assertEqual(deployed, False)
Exemple #24
0
    def test_deploy_regular_invalid_artifact_name(self):
        """Tests the deploy mechanism in regular mode with invalid artifact"""

        cryptocurrency_advanced_config_dict = generate_config(self.network, artifact_name="test-artifact")

        cryptocurrency_advanced_config = Configuration(cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            launcher.deploy_all()
            launcher.wait_for_deploy()

            # invalid artifact should not be deployed
            explorer = launcher.explorer()
            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.is_deployed(artifact)
                self.assertEqual(deployed, False)
Exemple #25
0
    def test_deploy_regular_exceed_deadline_height(self):
        """Tests the deploy mechanism in regular mode with exceeded deadline height"""

        cryptocurrency_advanced_config_dict = generate_config(self.network, deadline_height=0)
        cryptocurrency_advanced_config = Configuration(cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            launcher.deploy_all()
            launcher.wait_for_deploy()

            # artifact should not be deployed because of exceeded deadline height
            explorer = launcher.explorer()
            for artifact, (action_result, message) in launcher.launch_state.completed_deployments().items():
                deployed = explorer.is_deployed(artifact)
                self.assertFalse(deployed)
                self.assertEqual(action_result, ActionResult.Fail)
                self.assertIn("Actual height for transaction is in the past", message)
Exemple #26
0
    def setUp(self):
        self.network = run_4_nodes("exonum-cryptocurrency-advanced")
        self.addCleanup(self._tear_down, False)
        wait_network_to_start(self.network)

        instances = {"crypto": {"artifact": "cryptocurrency"}}
        cryptocurrency_advanced_config_dict = generate_config(
            self.network, instances=instances)
        cryptocurrency_advanced_config = Configuration(
            cryptocurrency_advanced_config_dict)

        with Launcher(cryptocurrency_advanced_config) as launcher:
            explorer = launcher.explorer()
            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.is_deployed(artifact)
                self.assertEqual(deployed, True)
Exemple #27
0
    def test_deploy_regular_with_invalid_instance(self):
        """Tests the deploy mechanism in regular mode with invalid instance."""

        instances = {"": {"artifact": "cryptocurrency"}}
        cryptocurrency_advanced_config_dict = generate_config(self.network, instances=instances)

        cryptocurrency_advanced_config = Configuration(cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            explorer = launcher.explorer()

            launcher.deploy_all()
            launcher.wait_for_deploy()
            launcher.start_all()
            with self.assertRaises(NotCommittedError):
                launcher.wait_for_start()

            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.is_deployed(artifact)
                self.assertEqual(deployed, True)
Exemple #28
0
    def test_deploy_dev_with_instance(self):
        """Tests the deploy mechanism in dev mode with instance."""

        instances = {"crypto": {"artifact": "cryptocurrency"}}
        cryptocurrency_advanced_config_dict = generate_config(self.network, instances=instances)

        cryptocurrency_advanced_config = Configuration(cryptocurrency_advanced_config_dict)
        with Launcher(cryptocurrency_advanced_config) as launcher:
            explorer = launcher.explorer()

            launcher.deploy_all()
            launcher.wait_for_deploy()
            launcher.start_all()
            launcher.wait_for_start()

            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.is_deployed(artifact)
                self.assertEqual(deployed, True)

            self.assertEqual(len(launcher.launch_state.completed_configs()), 1)
Exemple #29
0
    def test_context_manager(self) -> None:
        """Tests that creation via `with` calls initialize and deinitialize"""
        config = TestConfiguration.load_config("sample_config.yml")

        old_init = Launcher.initialize
        old_deinit = Launcher.deinitialize

        # Setup mocks.
        Launcher.initialize = MagicMock(return_value=None)  # type: ignore
        Launcher.deinitialize = MagicMock(return_value=None)  # type: ignore

        # Create launcher.
        with Launcher(config) as _:
            pass

        # Check that everything was called.
        # pylint: disable=no-member
        Launcher.initialize.assert_called()  # type: ignore
        Launcher.deinitialize.assert_called()  # type: ignore

        # Restore methods.
        Launcher.initialize = old_init  # type: ignore
        Launcher.deinitialize = old_deinit  # type: ignore
Exemple #30
0
    def full_migration_flow(self, action: str):
        host, public_port, private_port = self.network.api_address(0)
        client = ExonumClient(host, public_port, private_port)

        # Deploy a service with 0.2.0 version.
        instances = {INSTANCE_NAME: {"artifact": "cryptocurrency"}}
        config_dict = generate_config(self.network, instances=instances)
        deploy_config = Configuration(config_dict)

        with Launcher(deploy_config) as launcher:
            launcher.deploy_all()
            launcher.wait_for_deploy()

            self.wait_for_api_restart()
            explorer = launcher.explorer()
            for artifact in launcher.launch_state.completed_deployments():
                deployed = explorer.is_deployed(artifact)
                self.assertTrue(deployed)

        # Create Alice's wallet with 0.1.0 version of the service
        alice_keys = self._create_wallet(client, "Alice", "0.1.0")

        # Stop the working service with version 0.1.0.
        instances = {
            INSTANCE_NAME: {
                "artifact": "cryptocurrency",
                "action": action
            }
        }
        stop_config_dict = generate_config(self.network,
                                           instances=instances,
                                           artifact_action="none",
                                           artifact_version="0.1.0")
        stop_config = Configuration(stop_config_dict)

        with Launcher(stop_config) as launcher:
            launcher.start_all()
            launcher.wait_for_start()

            self.wait_for_api_restart()
            # Check that the service status has been changed to `stopped`.
            for service in client.public_api.available_services().json(
            )["services"]:
                if service["spec"]["name"] == INSTANCE_NAME:
                    self.assertEqual(
                        service["status"]["type"],
                        "stopped" if action == "stop" else "frozen")

        # Migrate service data from 0.1.0 to 0.2.0 version
        migrations = {
            INSTANCE_NAME: {
                "runtime": "rust",
                "name": "exonum-cryptocurrency",
                "version": "0.2.0"
            }
        }
        migrations_dict = generate_migration_config(self.network, migrations)
        migration_config = Configuration(migrations_dict)

        with Launcher(migration_config) as launcher:
            launcher.migrate_all()
            launcher.wait_for_migration()

            for service in client.public_api.available_services().json(
            )["services"]:
                if service["spec"]["name"] == INSTANCE_NAME:
                    self.assertEqual(service["data_version"], "0.2.0")

        # Switch service artifact from 0.1.0 to 0.2.0 version
        with Launcher(migration_config) as launcher:
            launcher.migrate_all()
            launcher.wait_for_migration()

            for service in client.public_api.available_services().json(
            )["services"]:
                if service["spec"]["name"] == INSTANCE_NAME:
                    self.assertEqual(service["spec"]["artifact"]["version"],
                                     "0.2.0")

        # Resume service with a new logic version 0.2.0
        instances = {
            INSTANCE_NAME: {
                "artifact": "cryptocurrency",
                "action": "resume"
            }
        }
        resume_config_dict = generate_config(self.network,
                                             instances=instances,
                                             artifact_action="none")
        resume_config = Configuration(resume_config_dict)

        with Launcher(resume_config) as launcher:
            launcher.start_all()
            launcher.wait_for_start()

            self.wait_for_api_restart()
            # Check that the service status has been changed to `active`.
            for service in client.public_api.available_services().json(
            )["services"]:
                if service["spec"]["name"] == INSTANCE_NAME:
                    self.assertEqual(service["status"]["type"], "active")
                    self.assertEqual(service["spec"]["artifact"]["version"],
                                     "0.2.0")

        # Unload artifact with version 0.1.0
        unload_config_dict = generate_config(self.network,
                                             instances=instances,
                                             artifact_action="unload",
                                             artifact_version="0.1.0")
        unload_config = Configuration(unload_config_dict)

        with Launcher(unload_config) as launcher:
            launcher.unload_all()
            launcher.wait_for_unload()

            self.wait_for_api_restart()
            explorer = launcher.explorer()

            for artifact in unload_config.artifacts.values():
                deployed = explorer.is_deployed(artifact)
                self.assertFalse(deployed)

        # Create Bob's wallet with version 0.2.0 of the service.
        bob_keys = self._create_wallet(client, "Bob", "0.2.0")

        # Transfer some coins and check balances and history length.
        with ExonumCryptoAdvancedClient(
                client, instance_name=INSTANCE_NAME) as crypto_client:
            alice_balance = crypto_client.get_balance(alice_keys)
            self.assertEqual(alice_balance, 100)
            alice_history_len = crypto_client.get_history_len(alice_keys)
            self.assertEqual(alice_history_len, 0)
            bob_balance = crypto_client.get_balance(bob_keys)
            self.assertEqual(bob_balance, 100)
            crypto_client.transfer(20, alice_keys, bob_keys.public_key)
            with client.create_subscriber("transactions") as subscriber:
                subscriber.wait_for_new_event()
                alice_balance = crypto_client.get_balance(alice_keys)
                self.assertEqual(alice_balance, 80)
                # Get a value from the new field `history_len`.
                alice_history_len = crypto_client.get_history_len(alice_keys)
                self.assertEqual(alice_history_len, 1)
                bob_balance = crypto_client.get_balance(bob_keys)
                self.assertEqual(bob_balance, 120)