コード例 #1
0
    def test_add_peer_relation_with_initial_data_leader(self):
        class InitialDataTester(CharmBase):
            """Record the relation-changed events."""
            def __init__(self, framework):
                super().__init__(framework)
                self.observed_events = []
                self.framework.observe(self.on.cluster_relation_changed,
                                       self._on_cluster_relation_changed)

            def _on_cluster_relation_changed(self, event):
                self.observed_events.append(event)

        # language=YAML
        harness = Harness(InitialDataTester,
                          meta='''
            name: test-app
            peers:
                cluster:
                    interface: cluster
            ''')
        self.addCleanup(harness.cleanup)
        # TODO: dmitriis 2020-04-07 test a minion unit and initial peer relation app data
        # events when the harness begins to emit events for initial data.
        harness.set_leader(is_leader=True)
        rel_id = harness.add_relation('cluster', 'test-app')
        harness.update_relation_data(rel_id, 'test-app', {'k': 'v'})
        harness.update_relation_data(rel_id, 'test-app/0',
                                     {'ingress-address': '192.0.2.1'})
        backend = harness._backend
        self.assertEqual({'k': 'v'},
                         backend.relation_get(rel_id, 'test-app', is_app=True))
        self.assertEqual({'ingress-address': '192.0.2.1'},
                         backend.relation_get(rel_id,
                                              'test-app/0',
                                              is_app=False))

        harness.begin()
        self.assertEqual({'k': 'v'},
                         backend.relation_get(rel_id, 'test-app', is_app=True))
        self.assertEqual({'ingress-address': '192.0.2.1'},
                         backend.relation_get(rel_id,
                                              'test-app/0',
                                              is_app=False))
        # Make sure no relation-changed events are emitted for our own data bags.
        self.assertEqual([], harness.charm.observed_events)

        # Updating our app relation data bag and our unit data bag does not trigger events
        harness.update_relation_data(rel_id, 'test-app', {'k': 'v2'})
        harness.update_relation_data(rel_id, 'test-app/0',
                                     {'ingress-address': '192.0.2.2'})
        self.assertEqual([], harness.charm.observed_events)

        # If our unit becomes a minion, updating app relation data indirectly becomes possible
        # and our charm gets notifications.
        harness.set_leader(False)
        harness.update_relation_data(rel_id, 'test-app', {'k': 'v3'})
        self.assertEqual({'k': 'v3'},
                         backend.relation_get(rel_id, 'test-app', is_app=True))
        self.assertTrue(len(harness.charm.observed_events), 1)
        self.assertIsInstance(harness.charm.observed_events[0], RelationEvent)
コード例 #2
0
ファイル: test_testing.py プロジェクト: gnuoy/operator
    def test_update_peer_relation_no_local_unit_change_event(self):
        # language=YAML
        harness = Harness(CharmBase, meta='''
            name: postgresql
            peers:
              db:
                interface: pgsql
            ''')
        harness.begin()
        helper = DBRelationChangedHelper(harness.charm, "helper")
        rel_id = harness.add_relation('db', 'postgresql')

        rel = harness.charm.model.get_relation('db')
        rel.data[harness.charm.model.unit]['key'] = 'value'
        rel = harness.charm.model.get_relation('db')
        harness.update_relation_data(rel_id, 'postgresql/0', {'key': 'v1'})
        self.assertEqual({'key': 'v1'}, rel.data[harness.charm.model.unit])
        # Make sure there was no event
        self.assertEqual([], helper.changes)

        rel.data[harness.charm.model.unit]['key'] = 'v2'
        # Our unit data bag got updated.
        self.assertEqual({'key': 'v2'}, dict(rel.data[harness.charm.model.unit]))
        # But there were no changed events registered by our unit.
        self.assertEqual([], helper.changes)

        # Same for when our unit is a leader.
        harness.set_leader(is_leader=True)
        harness.update_relation_data(rel_id, 'postgresql/0', {'key': 'v3'})
        self.assertEqual({'key': 'v3'}, dict(rel.data[harness.charm.model.unit]))
        self.assertEqual([], helper.changes)

        rel.data[harness.charm.model.unit]['key'] = 'v4'
        self.assertEqual(rel.data[harness.charm.model.unit]['key'], 'v4')
        self.assertEqual([], helper.changes)
コード例 #3
0
class TestMySQLProvider(unittest.TestCase):
    def setup_harness(self, config: dict, meta: dict) -> None:
        config_yaml = CONFIG_YAML.format(**config)
        meta_yaml = PROVIDER_META.format(**meta)
        self.harness = Harness(MySQLCharm, meta=meta_yaml, config=config_yaml)
        self.addCleanup(self.harness.cleanup)
        self.harness.set_leader(True)
        self.harness.begin()

    def test_databases_are_created_when_requested(self):
        config = CONFIG.copy()
        meta = METADATA.copy()
        self.setup_harness(config, meta)

        requested_database = ["mysql_database"]
        json_request = json.dumps(requested_database)
        consumer_data = {"databases": json_request}

        rel_id = self.harness.add_relation("database", "consumer")
        data = self.harness.get_relation_data(rel_id,
                                              self.harness.model.app.name)
        self.assertDictEqual(data, {})
        self.harness.add_relation_unit(rel_id, "consumer/0")
        self.harness.update_relation_data(rel_id, "consumer", consumer_data)
        data = self.harness.get_relation_data(rel_id,
                                              self.harness.model.app.name)
        databases = json.loads(data["databases"])
        self.assertListEqual(databases, requested_database)
コード例 #4
0
    def test_update_peer_relation_app_data(self):
        # language=YAML
        harness = Harness(CharmBase,
                          meta='''
            name: postgresql
            peers:
              db:
                interface: pgsql
            ''')
        harness.begin()
        harness.set_leader(is_leader=True)
        helper = DBRelationChangedHelper(harness.charm, "helper")
        rel_id = harness.add_relation('db', 'postgresql')
        rel = harness.charm.model.get_relation('db')
        rel.data[harness.charm.app]['key'] = 'value'
        harness.update_relation_data(rel_id, 'postgresql', {'key': 'v1'})
        self.assertEqual({'key': 'v1'}, rel.data[harness.charm.app])
        self.assertEqual([], helper.changes)

        rel.data[harness.charm.app]['key'] = 'v2'
        # Our unit data bag got updated.
        self.assertEqual(rel.data[harness.charm.model.app]['key'], 'v2')
        # But there were no changed events registered by our unit.
        self.assertEqual([], helper.changes)

        # If our unit is not a leader unit we get an update about peer app relation data changes.
        harness.set_leader(is_leader=False)
        harness.update_relation_data(rel_id, 'postgresql', {'k2': 'v2'})
        self.assertEqual(rel.data[harness.charm.model.app]['k2'], 'v2')
        self.assertEqual(helper.changes, [(0, 'postgresql')])
コード例 #5
0
 def test_get_backend_calls_with_kwargs(self):
     harness = Harness(CharmBase,
                       meta='''
         name: test-charm
         requires:
             db:
                 interface: pgsql
         ''')
     self.addCleanup(harness.cleanup)
     harness.begin()
     unit = harness.charm.model.unit
     # Reset the list, because we don't care what it took to get here
     harness._get_backend_calls(reset=True)
     unit.status = ActiveStatus()
     self.assertEqual([('status_set', 'active', '', {
         'is_app': False
     })], harness._get_backend_calls())
     harness.set_leader(True)
     app = harness.charm.model.app
     harness._get_backend_calls(reset=True)
     app.status = ActiveStatus('message')
     self.assertEqual([('is_leader', ),
                       ('status_set', 'active', 'message', {
                           'is_app': True
                       })], harness._get_backend_calls())
コード例 #6
0
class TestCharm(unittest.TestCase):
    """MetalLB Controller Charm Unit Tests."""

    @patch.dict('charm.os.environ', {'JUJU_MODEL_NAME': 'unit-test-metallb'})
    def setUp(self):
        """Test setup."""
        self.harness = Harness(MetalLBSpeakerCharm)
        self.harness.set_leader(is_leader=True)
        self.harness.begin()

    @patch.dict('charm.os.environ', {'JUJU_MODEL_NAME': 'unit-test-metallb'})
    @patch("utils.create_namespaced_role_binding_with_api")
    @patch("utils.create_namespaced_role_with_api")
    @patch("utils.create_pod_security_policy_with_api")
    def test_on_start(self, create_psp, create_ns_role, create_ns_role_binding):
        """Test installation."""
        mock_pod_spec = self.harness.charm.set_pod_spec = Mock()
        self.assertFalse(self.harness.charm._stored.started)
        self.harness.charm.on.start.emit()
        mock_pod_spec.assert_called_once()
        create_psp.assert_called_once()
        self.assertEqual(create_ns_role.call_count, 2)
        self.assertEqual(create_ns_role_binding.call_count, 2)
        self.assertTrue(self.harness.charm._stored.started)

    @patch("utils.delete_namespaced_role_with_api")
    @patch("utils.delete_namespaced_role_binding_with_api")
    @patch("utils.delete_pod_security_policy_with_api")
    def test_on_remove(self, delete_psp, delete_ns_role_binding, delete_ns_role):
        """Test remove hook."""
        self.harness.charm.on.remove.emit()
        delete_psp.assert_called_once()
        self.assertEqual(delete_ns_role.call_count, 2)
        self.assertEqual(delete_ns_role_binding.call_count, 2)
        self.assertFalse(self.harness.charm._stored.started)
コード例 #7
0
class TestConsumer(unittest.TestCase):
    def setUp(self):
        self.harness = Harness(DummyCharmForTestingConsumer)
        self.addCleanup(self.harness.cleanup)
        self.harness.set_leader(True)
        self.harness.begin()

    def test_relation_changed(self):
        # container name has to be `alertmanager` because that's what the harness expects based on
        # metadata.yaml
        container = self.harness.model.unit.get_container("alertmanager")

        # Emit the PebbleReadyEvent carrying the alertmanager container

        self.harness.charm.on.alertmanager_pebble_ready.emit(container)

        rel_id = self.harness.add_relation(relation_name="alerting",
                                           remote_app="alertmanager-k8s")
        # self.harness.add_relation_unit(rel_id, "alertmanager-k8s/0")
        self.harness.add_relation_unit(rel_id, "prometheus-k8s/0")
        rel = self.harness.charm.framework.model.get_relation(
            "alerting", rel_id)

        self.assertEqual(0, self.harness.charm._stored.on_available_emitted)
        self.harness.update_relation_data(rel_id, "prometheus-k8s/0",
                                          {"public_address": "1.1.1.1"})
        self.harness.charm.on["alerting"].relation_changed.emit(rel)
        self.assertEqual(1, self.harness.charm._stored.on_available_emitted)
コード例 #8
0
class TestCharm(unittest.TestCase):
    """Prometheus Charm unit tests."""
    def setUp(self) -> NoReturn:
        """Test setup"""
        self.image_info = sys.modules["oci_image"].OCIImageResource().fetch()
        self.harness = Harness(CharmedOsmBase)
        self.harness.set_leader(is_leader=True)
        self.harness.begin()

    def test_config_changed_non_leader(self, ) -> NoReturn:
        self.harness.set_leader(is_leader=False)
        self.harness.charm.on.config_changed.emit()
        self.assertIsInstance(self.harness.charm.unit.status, ActiveStatus)

    @mock.patch("opslib.osm.charm.CharmedOsmBase.build_pod_spec")
    def test_config_changed_leader(self, mock_build_pod_spec) -> NoReturn:
        mock_build_pod_spec.return_value = {
            "version": 3,
            "containers": [{
                "name": "c1"
            }, {
                "name": "c2"
            }],
        }
        self.harness.charm.on.config_changed.emit()
        self.assertIsInstance(self.harness.charm.unit.status, ActiveStatus)
コード例 #9
0
def test_provide_one_relation():
    harness = Harness(
        ProvideCharm,
        meta="""
        name: test-app
        requires:
            app-provides:
                interface: serialized-data
        """,
    )
    harness.set_leader(True)
    rel_id = harness.add_relation("app-provides", "foo")
    harness.add_relation_unit(rel_id, "foo/0")
    harness.update_relation_data(
        rel_id,
        "foo",
        {"_supported_versions": yaml.dump(["v1"])},
    )
    harness.begin()
    assert harness.charm.interface.get_data() == {}

    data = {
        "service": "my-service",
        "port": 4242,
        "access-key": "my-access-key",
        "secret-key": "my-secret-key",
    }
    harness.charm.interface.send_data(data)
    rel_data = harness.charm.interface.get_data()
    assert rel_data == {(rel, app): data
                        for rel in harness.model.relations["app-provides"]
                        for app, bag in rel.data.items()
                        if isinstance(app, Application) and "data" in bag}
コード例 #10
0
    def test_update_relation_no_local_app_change_event(self):
        # language=YAML
        harness = Harness(CharmBase,
                          meta='''
            name: my-charm
            requires:
              db:
                interface: pgsql
            ''')
        harness.begin()
        harness.set_leader(False)
        helper = DBRelationChangedHelper(harness.charm, "helper")
        rel_id = harness.add_relation('db', 'postgresql')
        # TODO: remove this as soon as https://github.com/canonical/operator/issues/175 is fixed.
        harness.add_relation_unit(rel_id, 'postgresql/0')
        self.assertEqual(helper.changes, [])

        harness.update_relation_data(rel_id, 'my-charm', {'new': 'value'})
        rel = harness.charm.model.get_relation('db')
        self.assertEqual(rel.data[harness.charm.app]['new'], 'value')

        # Our app data bag got updated.
        self.assertEqual(rel.data[harness.charm.model.app]['new'], 'value')
        # But there were no changed events registered by our unit.
        self.assertEqual(helper.changes, [])
コード例 #11
0
class TestNonStandardProviders(unittest.TestCase):
    def setup(self, **kwargs):
        bad_provider_charm = customize_endpoint_provider(
            alert_rules_path=kwargs["alert_rules_path"])
        self.harness = Harness(bad_provider_charm, meta=PROVIDER_META)
        self.addCleanup(self.harness.cleanup)
        self.harness.set_leader(True)
        self.harness.begin()

    @patch("ops.testing._TestingModelBackend.network_get")
    def test_a_bad_alert_expression_logs_an_error(self, _):
        self.setup(alert_rules_path="./tests/unit/bad_alert_expressions")

        with self.assertLogs(level="ERROR") as logger:
            rel_id = self.harness.add_relation(RELATION_NAME, "provider")
            self.harness.add_relation_unit(rel_id, "provider/0")
            messages = sorted(logger.output)
            self.assertEqual(len(messages), 1)
            self.assertIn("Invalid rules file: missing_expr.rule", messages[0])

    @patch("ops.testing._TestingModelBackend.network_get")
    def test_a_bad_alert_rules_logs_an_error(self, _):
        self.setup(alert_rules_path="./tests/unit/bad_alert_rules")

        with self.assertLogs(level="ERROR") as logger:
            rel_id = self.harness.add_relation(RELATION_NAME, "provider")
            self.harness.add_relation_unit(rel_id, "provider/0")
            messages = sorted(logger.output)
            self.assertEqual(len(messages), 1)
            self.assertIn("Failed to read alert rules from bad_yaml.rule",
                          messages[0])
コード例 #12
0
class TestCharm(unittest.TestCase):
    def setUp(self):
        self.harness = Harness(MongoDBCharm)
        self.addCleanup(self.harness.cleanup)
        mongo_resource = {
            "registrypath": "mongodb:4.4.1",
            "username": "******",
            "password": "******"
        }
        self.harness.add_oci_resource("mongodb-image", mongo_resource)
        self.harness.begin()

    def test_replica_set_name_can_be_changed(self):
        self.harness.set_leader(True)

        # check default replica set name
        self.harness.charm.on.config_changed.emit()
        pod_spec = self.harness.get_pod_spec()
        self.assertEqual(replica_set_name(pod_spec), "rs0")

        # check replica set name can be changed
        self.harness.update_config({"replica_set_name": "new_name"})
        pod_spec = self.harness.get_pod_spec()
        self.assertEqual(replica_set_name(pod_spec), "new_name")

    @patch("mongo.Mongo.reconfigure_replica_set")
    def test_replica_set_is_reconfigured_when_peer_joins(self, mock_reconf):
        self.harness.set_leader(True)
        rel_id = self.harness.add_relation('mongodb', 'mongodb')
        self.harness.add_relation_unit(rel_id, 'mongodb/1')
        self.harness.update_relation_data(rel_id, 'mongodb/1',
                                          {'private-address': '10.0.0.1'})
        self.assertEqual(self.harness.charm.num_peers, 2)
        peers = ['mongodb-0.mongodb-endpoints', 'mongodb-1.mongodb-endpoints']
        mock_reconf.assert_called_once_with(peers)
コード例 #13
0
def test_dual_interface_charm():
    harness = Harness(
        RequiresCharm,
        meta="""
        name: test-app
        requires:
            app-requires:
                interface: serialized-data
        """,
    )
    harness.set_leader(True)
    rel_id = harness.add_relation("app-requires", "foo")
    harness.add_relation_unit(rel_id, "foo/0")
    harness.update_relation_data(
        rel_id,
        "foo",
        {"_supported_versions": yaml.dump(["v2"])},
    )
    harness.update_relation_data(
        rel_id,
        "foo",
        {"data": "foo: bar"},
    )
    harness.begin()
    harness.charm.interface.send_data({"bar": None})

    rel_data = harness.charm.interface.get_data()
    assert rel_data == {(rel, app): {
        "bar": None
    } if app._is_our_app else {
        "foo": "bar"
    }
                        for rel in harness.model.relations["app-requires"]
                        for app, bag in rel.data.items()
                        if isinstance(app, Application) and "data" in bag}
コード例 #14
0
    def test_touch_action_fail(self):
        harness = Harness(SshproxyCharm)
        harness.set_leader(is_leader=False)
        harness.begin()
        action_event = Mock(params={"filename": "/home/ubuntu/asd"})
        harness.charm.on_touch_action(action_event)

        self.assertEqual(action_event.fail.call_args, [("Unit is not leader",)])
コード例 #15
0
    def test_add_relation_with_our_initial_data(self):
        class InitialDataTester(CharmBase):
            """Record the relation-changed events."""
            def __init__(self, framework):
                super().__init__(framework)
                self.observed_events = []
                self.framework.observe(self.on.db_relation_changed,
                                       self._on_db_relation_changed)

            def _on_db_relation_changed(self, event):
                self.observed_events.append(event)

        # language=YAML
        harness = Harness(InitialDataTester,
                          meta='''
            name: test-app
            requires:
                db:
                    interface: pgsql
            ''')
        self.addCleanup(harness.cleanup)
        rel_id = harness.add_relation('db', 'postgresql')
        harness.update_relation_data(rel_id, 'test-app', {'k': 'v1'})
        harness.update_relation_data(rel_id, 'test-app/0',
                                     {'ingress-address': '192.0.2.1'})
        backend = harness._backend
        self.assertEqual({'k': 'v1'},
                         backend.relation_get(rel_id, 'test-app', is_app=True))
        self.assertEqual({'ingress-address': '192.0.2.1'},
                         backend.relation_get(rel_id,
                                              'test-app/0',
                                              is_app=False))

        harness.begin()
        self.assertEqual({'k': 'v1'},
                         backend.relation_get(rel_id, 'test-app', is_app=True))
        self.assertEqual({'ingress-address': '192.0.2.1'},
                         backend.relation_get(rel_id,
                                              'test-app/0',
                                              is_app=False))
        # Make sure no relation-changed events are emitted for our own data bags.
        self.assertEqual([], harness.charm.observed_events)

        # A remote unit can still update our app relation data bag since our unit is not a leader.
        harness.update_relation_data(rel_id, 'test-app', {'k': 'v2'})
        # And we get an event
        self.assertEqual([], harness.charm.observed_events)
        # We can also update our own relation data, even if it is a bit 'cheaty'
        harness.update_relation_data(rel_id, 'test-app/0',
                                     {'ingress-address': '192.0.2.2'})
        # But no event happens

        # Updating our data app relation data bag and our unit data bag does not generate events.
        harness.set_leader(True)
        harness.update_relation_data(rel_id, 'test-app', {'k': 'v3'})
        harness.update_relation_data(rel_id, 'test-app/0',
                                     {'ingress-address': '192.0.2.2'})
        self.assertEqual([], harness.charm.observed_events)
コード例 #16
0
 def test_app_status(self):
     harness = Harness(CharmBase, meta='name: test-app')
     harness.set_leader(True)
     harness.begin()
     # default status
     self.assertEqual(harness.model.app.status, UnknownStatus())
     status = ActiveStatus('message')
     harness.model.app.status = status
     self.assertEqual(harness.model.app.status, status)
コード例 #17
0
class TestCharm(unittest.TestCase):
    def setUp(self):
        self.harness = Harness(CassandraStressOperatorCharm)
        self.addCleanup(self.harness.cleanup)
        self.harness.set_leader(True)
        self.harness.begin_with_initial_hooks()

    def test_pass(self):
        pass
コード例 #18
0
ファイル: test_charm.py プロジェクト: charmed-osm/5g-core
class TestCharm(unittest.TestCase):
    """Test script for checking relations"""

    def setUp(self) -> NoReturn:
        """Test setup."""
        self.harness = Harness(MongodbCharm)
        self.harness.set_leader(is_leader=True)
        self.harness.begin()

    def test_on_configure_pod(self) -> NoReturn:
        """Test installation without any relation."""
        self.harness.charm.on.config_changed.emit()
        expected_result = {
            "version": 3,
            "containers": [
                {
                    "name": "mongodb",
                    "imageDetails": self.harness.charm.image.fetch(),
                    "imagePullPolicy": "Always",
                    "ports": [
                        {
                            "name": "mongodb",
                            "containerPort": 27017,
                            "protocol": "TCP",
                        }
                    ],
                    "command": [
                        "mongod",
                        "--bind_ip",
                        "mongodb-endpoints",
                        "--port",
                        "27017",
                    ],
                }
            ],
        }

        # Verifying status
        self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus)

        # Verifying status message
        self.assertGreater(len(self.harness.charm.unit.status.message), 0)

        pod_spec, _ = self.harness.get_pod_spec()
        self.assertDictEqual(expected_result, pod_spec)

    def test_publish_mongodb_info(self) -> NoReturn:
        """Test to see if mongodb relation is updated."""
        expected_result = {
            "hostname": "mongodb",
            "mongodb_uri": "mongodb://mongodb:27017",
        }
        relation_id = self.harness.add_relation("mongodb", "nrf")
        self.harness.add_relation_unit(relation_id, "nrf/0")
        relation_data = self.harness.get_relation_data(relation_id, "mongodb")
        print("relation_data", relation_data)
        self.assertDictEqual(expected_result, relation_data)
コード例 #19
0
 def test_unit_status(self):
     harness = Harness(CharmBase, meta='name: test-app')
     harness.set_leader(True)
     harness.begin()
     # default status
     self.assertEqual(harness.model.unit.status, MaintenanceStatus(''))
     status = ActiveStatus('message')
     harness.model.unit.status = status
     self.assertEqual(harness.model.unit.status, status)
コード例 #20
0
def test_provide_no_relation():
    harness = Harness(
        ProvideCharm,
        meta="""
        name: test-app
        requires:
            app-provides:
                interface: serialized-data
        """,
    )
    harness.set_leader(True)
    harness.begin()
コード例 #21
0
class TestCharm(unittest.TestCase):
    def setUp(self) -> None:
        self.harness = Harness(TrainingCharm)
        self.addCleanup(self.harness.cleanup)
        self.harness.begin()

    def test__grafana_port_config_changed(self):
        self.harness.set_leader(True)
        self.harness.update_config({"grafana_port": 4000})
        pod_spec = self.harness.get_pod_spec()[0]
        self.assertEqual(pod_spec["containers"][0]["ports"][0]["containerPort"], 4000)
        self.assertEqual(pod_spec["containers"][0]["readinessProbe"]["httpGet"]["port"], 4000)
コード例 #22
0
class TestBusyboxCharm(unittest.TestCase):
    """Charm test class."""

    def setUp(self):
        """Setup tests."""
        self.harness = Harness(BusyboxCharm)

    def test_harness(self):
        """Verify harness."""
        self.harness.begin()
        self.assertFalse(self.harness.charm.state.installed)

    def test_install(self):
        """Test response to an install event."""
        self.harness.begin()
        self.harness.charm.on.install.emit()
        self.assertTrue(self.harness.charm.state.installed)

    # This pattern can't work before juju 2.8
    # def test_config_changed_not_installed(self):
    #     """Test response to config changed event without install state."""
    #     self.harness.begin()
    #     self.harness.charm.on.config_changed.emit()
    #     self.assertFalse(self.harness.charm.state.configured)

    def test_config_changed(self):
        """Test response to config changed event."""
        self.harness.set_leader(True)
        self.harness.begin()
        self.harness.charm.state.installed = True
        self.harness.charm.on.config_changed.emit()
        self.assertTrue(self.harness.charm.state.configured)

    def test_start_not_installed(self):
        """Test response to start event without install state."""
        self.harness.begin()
        self.harness.charm.on.start.emit()
        self.assertFalse(self.harness.charm.state.started)

    def test_start_not_configured(self):
        """Test response to start event without configured state."""
        self.harness.begin()
        self.harness.charm.state.installed = True
        self.harness.charm.on.start.emit()
        self.assertFalse(self.harness.charm.state.started)

    def test_start(self):
        """Test response to start event."""
        self.harness.begin()
        self.harness.charm.state.installed = True
        self.harness.charm.state.configured = True
        self.harness.charm.on.start.emit()
        self.assertTrue(self.harness.charm.state.started)
def test_send_data_multiple_versions():
    harness = Harness(
        ProvideCharm,
        meta="""
        name: test-app
        provides:
            app-provides:
                interface: serialized-data
        """,
    )
    harness.set_leader(True)

    rel_id1 = harness.add_relation("app-provides", "appv1")
    harness.add_relation_unit(rel_id1, "appv1/0")
    harness.update_relation_data(
        rel_id1,
        "appv1",
        {"_supported_versions": "- v1"},
    )

    rel_id2 = harness.add_relation("app-provides", "appv2")
    harness.add_relation_unit(rel_id2, "appv2/0")
    harness.update_relation_data(
        rel_id2,
        "appv2",
        {"_supported_versions": "- v2"},
    )

    harness.begin()
    data = {
        "service": "my-service",
        "port": 4242,
        "access-key": "my-access-key",
        "secret-key": "my-secret-key",
    }
    harness.update_relation_data(rel_id1, "appv1", {"data": yaml.dump(data)})
    harness.update_relation_data(rel_id2, "appv2",
                                 {"data": yaml.dump({"bar": None})})

    harness.charm.interface.send_data(data, "appv1")
    harness.charm.interface.send_data(
        {"foo": "sillema sillema nika su"},
        app_name="appv2",
    )

    # Can't send for an invalid app
    with pytest.raises(sdi.errors.InvalidAppNameError):
        harness.charm.interface.send_data({}, "invalid-app")

    # Can't send invalid data
    with pytest.raises(sdi.errors.RelationDataError):
        harness.charm.interface.send_data({"bad": "guy"}, "appv2")
コード例 #24
0
    def test_touch_action(self, mock_ssh_proxy):
        mock_ssh_proxy.return_value = ("stdout", None)
        harness = Harness(SshproxyCharm)
        harness.set_leader(is_leader=True)
        harness.begin()
        action_event = Mock(params={"filename": "/home/ubuntu/asd"})
        harness.charm.on_touch_action(action_event)

        self.assertTrue(action_event.set_results.called)
        self.assertEqual(
            action_event.set_results.call_args,
            call({"output": "stdout"}),
        )
class TestProxyListenTcpInterfaceProvides(unittest.TestCase):

    def setUp(self):
        self.harness = Harness(CharmBase, meta='''
            name: tcp-server
            requires:
              proxy-listen-tcp:
                interface: proxy-listen-tcp
        ''')

        self.harness.begin()
        self.tcp_load_balancer = ProxyListenTcpInterfaceProvides(self.harness.charm,
                                                                 'proxy-listen-tcp')

    def test_expose_server(self):
        relation_id = self.harness.add_relation('proxy-listen-tcp', 'tcp-server')
        self.harness.update_relation_data(
            relation_id, 'tcp-server/0', {'ingress-address': '192.0.2.1'})

        self.tcp_load_balancer.expose_server(
            26257,
            ["bind :26257", "option httpchk GET /health?ready=1"],
            'server tcp-server-0.example 192.0.2.1:26257 check port 8080'
        )

        rel = self.harness.charm.model.get_relation('proxy-listen-tcp')
        self.assertEqual(
            rel.data[self.harness.charm.unit]['server_option'],
            'server tcp-server-0.example 192.0.2.1:26257 check port 8080'
        )
        with self.assertRaises(KeyError):
            rel.data[self.harness.charm.app]['frontend_port']
        with self.assertRaises(KeyError):
            rel.data[self.harness.charm.app]['listen_options'],

        self.harness.set_leader()
        self.tcp_load_balancer.expose_server(
            26258,
            ["bind :26258", "option httpchk GET /health?ready=1"],
            'server tcp-server-0.example 192.0.2.1:26258 check port 8080'
        )
        self.assertEqual(
            rel.data[self.harness.charm.unit]['server_option'],
            'server tcp-server-0.example 192.0.2.1:26258 check port 8080'
        )
        self.assertEqual(rel.data[self.harness.charm.app]['frontend_port'], '26258')
        self.assertEqual(
            rel.data[self.harness.charm.app]['listen_options'],
            '["bind :26258", "option httpchk GET /health?ready=1"]'
        )
コード例 #26
0
def test_mrrm(role):
    if role == "provides":
        harness = Harness(ProviderCharm, meta=ProviderCharm.META)
        harness.begin_with_initial_hooks()
        provider = harness.charm.rel
        requirer = MockRequirer(harness)
        local, remote = provider, requirer
    elif role == "requires":
        harness = Harness(RequirerCharm, meta=RequirerCharm.META)
        harness.begin_with_initial_hooks()
        provider = MockProvider(harness)
        requirer = harness.charm.rel
        local, remote = requirer, provider

    assert not provider.is_available()
    assert not provider.is_ready()
    assert not requirer.is_available()
    assert not requirer.is_ready()

    relation = remote.relate()
    # mock remote is always leader, so their versions will be sent to the local charm
    assert local.is_available()
    assert not local.is_ready()
    # local charm under test is not leader yet, so its will not be sent to the remote
    assert not remote.is_available()
    assert not remote.is_ready()

    harness.set_leader(True)
    assert provider.is_available()
    assert not provider.is_ready()
    assert requirer.is_available()
    assert not requirer.is_ready()

    requirer.wrap(relation, {requirer.unit: {"request": "foo"}})
    assert provider.is_available()
    assert provider.is_ready()
    assert requirer.is_available()
    assert not requirer.is_ready()

    data = provider.unwrap(relation)
    assert data[requirer.unit] == {"request": "foo"}

    provider.wrap(relation, {provider.app: {"response": "bar"}})
    assert provider.is_available()
    assert provider.is_ready()
    assert requirer.is_available()
    assert requirer.is_ready()
    data = requirer.unwrap(relation)
    assert data[provider.app] == {"response": "bar"}
コード例 #27
0
class TestCharm(unittest.TestCase):
    def setUp(self):
        self.harness = Harness(MongoDBCharm)
        self.addCleanup(self.harness.cleanup)
        mongo_resource = {
            "registrypath": "mongodb:4.4.1",
            "username": "******",
            "password": "******"
        }
        self.harness.add_oci_resource("mongodb-image", mongo_resource)
        self.harness.begin()

    def test_replica_set_name_can_be_changed(self):
        self.harness.set_leader(True)

        # check default replica set name
        self.harness.charm.on.config_changed.emit()
        pod_spec = self.harness.get_pod_spec()
        self.assertEqual(replica_set_name(pod_spec), "rs0")

        # check replica set name can be changed
        self.harness.update_config({"replica_set_name": "new_name"})
        pod_spec = self.harness.get_pod_spec()
        self.assertEqual(replica_set_name(pod_spec), "new_name")

    @patch("mongoserver.MongoDB.reconfigure_replica_set")
    def test_replica_set_is_reconfigured_when_peer_joins(self, mock_reconf):
        self.harness.set_leader(True)
        rel_id = self.harness.add_relation('mongodb', 'mongodb')
        self.harness.add_relation_unit(rel_id, 'mongodb/1')
        self.harness.update_relation_data(rel_id,
                                          'mongodb/1',
                                          {'private-address': '10.0.0.1'})
        peers = ['mongodb-0.mongodb-endpoints',
                 'mongodb-1.mongodb-endpoints']
        mock_reconf.assert_called_once_with(peers)

    def test_uri_data_is_generated_correctly(self):
        self.harness.set_leader(True)
        standalone_uri = self.harness.charm.mongo.standalone_uri
        replica_set_uri = self.harness.charm.mongo.replica_set_uri
        self.assertEqual(standalone_uri, 'mongodb://mongodb:27017/')
        self.assertEqual(replica_set_uri, 'mongodb://mongodb-0.mongodb-endpoints:27017/')

    def test_database_relation_data_is_set_correctly(self):
        self.harness.set_leader(True)
        rel_id = self.harness.add_relation('database', 'client')
        self.harness.add_relation_unit(rel_id, 'client/1')
        rel = self.harness.framework.model.get_relation('database', rel_id)
        unit = self.harness.framework.model.get_unit('client/1')
        self.harness.charm.on['database'].relation_changed.emit(rel, unit)
        got = self.harness.get_relation_data(rel_id, self.harness.framework.model.unit.name)
        expected = {
            'replicated': 'False',
            'replica_set_name': 'rs0',
            'standalone_uri': 'mongodb://mongodb:27017/',
            'replica_set_uri': 'mongodb://mongodb-0.mongodb-endpoints:27017/'
        }
        self.assertDictEqual(got, expected)
コード例 #28
0
 def test_relation_set_deletes(self):
     harness = Harness(CharmBase,
                       meta='''
         name: test-charm
         requires:
             db:
                 interface: pgsql
         ''')
     harness.begin()
     harness.set_leader(False)
     rel_id = harness.add_relation('db', 'postgresql')
     harness.update_relation_data(rel_id, 'test-charm/0', {'foo': 'bar'})
     harness.add_relation_unit(rel_id, 'postgresql/0')
     rel = harness.charm.model.get_relation('db', rel_id)
     del rel.data[harness.charm.model.unit]['foo']
     self.assertEqual({}, harness.get_relation_data(rel_id, 'test-charm/0'))
コード例 #29
0
class TestRemoteWriteConsumer(unittest.TestCase):
    def setUp(self):
        self.harness = Harness(RemoteWriteConsumerCharm, meta=METADATA)
        self.harness.add_resource(
            "promql-transform-amd64",
            open("./promql-transform", "rb").read(),
        )
        self.addCleanup(self.harness.cleanup)
        self.harness.set_leader(True)
        self.harness.begin_with_initial_hooks()

    def test_address_is_set(self):
        rel_id = self.harness.add_relation(RELATION_NAME, "provider")
        self.harness.add_relation_unit(rel_id, "provider/0")
        self.harness.update_relation_data(
            rel_id,
            "provider/0",
            {"remote_write": json.dumps({"url": "http://1.1.1.1:9090/api/v1/write"})},
        )
        assert list(self.harness.charm.remote_write_consumer.endpoints) == [
            {"url": "http://1.1.1.1:9090/api/v1/write"}
        ]

    @patch.object(RemoteWriteConsumerCharm, "_handle_endpoints_changed")
    def test_config_is_set(self, mock_handle_endpoints_changed):
        rel_id = self.harness.add_relation(RELATION_NAME, "provider")

        self.harness.add_relation_unit(rel_id, "provider/0")
        self.harness.update_relation_data(
            rel_id,
            "provider/0",
            {"remote_write": json.dumps({"url": "http://1.1.1.1:9090/api/v1/write"})},
        )

        mock_handle_endpoints_changed.assert_called()
        event = mock_handle_endpoints_changed.call_args.args[0]
        self.assertEqual(rel_id, event.relation_id)

        assert list(self.harness.charm.remote_write_consumer.endpoints) == [
            {"url": "http://1.1.1.1:9090/api/v1/write"}
        ]

    def test_no_remote_write_endpoint_provided(self):
        rel_id = self.harness.add_relation(RELATION_NAME, "provider")
        self.harness.add_relation_unit(rel_id, "provider/0")
        self.harness.update_relation_data(rel_id, "provider/0", {})
        assert list(self.harness.charm.remote_write_consumer.endpoints) == []
コード例 #30
0
class TestCharm(unittest.TestCase):
    def setUp(self):
        self.harness = Harness(CassandraOperatorCharm)
        self.addCleanup(self.harness.cleanup)
        self.harness.begin()
        self.harness.set_leader(True)

    def test_relation_is_set(self):
        rel_id = self.harness.add_relation("cql", "otherapp")
        self.assertIsInstance(rel_id, int)
        self.harness.add_relation_unit(rel_id, "otherapp/0")
        self.harness.update_relation_data(rel_id, "otherapp", {})
        self.assertEqual(
            self.harness.get_relation_data(
                rel_id, self.harness.model.app.name)["port"],
            "9042",
        )