def test_install(self): charm._host = Mock() harness = Harness(charm.CertbotCharm) self.addCleanup(harness.cleanup) harness.begin() harness.charm.on.install.emit() charm._host.install_packages.assert_called_once_with( "certbot", "python3-certbot-dns-google") charm._host.symlink.assert_called_once_with( os.path.join(harness.charm.charm_dir, "bin/deploy.py"), "/etc/letsencrypt/renewal-hooks/deploy/certbot-charm")
def test_delete_snapshot_action(self, shutil_rmtree): default_config = self.default_config() harness = Harness(SimpleStreamsCharm) harness.begin() harness.charm._stored.config = default_config harness.charm._get_snapshot_name = Mock() snapshot_name = uuid4() action_event = Mock(params={"name": snapshot_name}) harness.charm._on_delete_snapshot_action(action_event) assert shutil_rmtree.call_args == call('{}/{}'.format( default_config['image-dir'], snapshot_name))
def setUp(self): self.harness = Harness(MySQLOperatorCharm) self.addCleanup(self.harness.cleanup) self.harness.begin() self.peer_relation_id = self.harness.add_relation( "database-peers", "database-peers") self.harness.add_relation_unit(self.peer_relation_id, "mysql/1") self.db_router_relation_id = self.harness.add_relation( "db-router", "app") self.harness.add_relation_unit(self.db_router_relation_id, "app/0") self.charm = self.harness.charm
def setUp(self): self.harness = Harness(CharmCinderThreeParCharm) self.addCleanup(self.harness.cleanup) self.harness.begin() self.harness.set_leader(True) self.model = self.harness.model self.storage_backend = \ self.harness.add_relation('storage-backend', 'cinder') self.harness.add_relation_unit(self.storage_backend, 'cinder/0') self.test_config = copy.deepcopy(TEST_3PAR_CONFIG) self.test_changed = copy.deepcopy(TEST_3PAR_CONFIG_CHANGED)
def test_on_start(self): harness = Harness(CharmIscsiConnectorCharm) harness.begin() self.assertFalse(harness.charm.state.started) harness.charm.on.start.emit() # event deferred as charm not configured yet self.assertFalse(harness.charm.state.started) # mock charm as configured harness.charm.state.configured = True harness.charm.on.start.emit() self.assertTrue(harness.charm.state.started)
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() self.peer_rel_id = self.harness.add_relation('mongodb', 'mongodb')
def test_action(self, mock_check_output): harness = Harness(Microk8STestCharm) harness.begin() action_event = Mock(params={}) mock_check_output.return_value = EXAMPLE_STATUS harness.charm._on_status_action(action_event) self.assertTrue(action_event.set_results.called) action_event.set_results.assert_called_with( {'juju_status': EXAMPLE_STATUS})
def setUp(self): self.harness = Harness(CharmBase, meta=''' name: haproxy provides: tcp-lb: interface: tcp-load-balancer ''') self.harness.begin() self.tcp_backend_manager = TCPBackendManager(self.harness.charm, 'tcp-lb')
def test_publish_relation_joined(self, mock_open_call, os_path_isdir, os_makedirs, os_symlink): harness = Harness(SimpleStreamsCharm) harness.begin() default_config = self.default_config() self.assertEqual(harness.charm._stored.config, {}) harness.update_config(default_config) relation_id = harness.add_relation('publish', 'webserver') harness.add_relation_unit(relation_id, 'webserver/0') assert harness.get_relation_data(relation_id, harness._unit_name)\ == {'path': '{}/publish'.format(default_config['image-dir'])}
def setUp(self): self.harness = Harness(MySQLOperatorCharm) self.addCleanup(self.harness.cleanup) self.harness.begin() self.peer_relation_id = self.harness.add_relation( "database-peers", "database-peers") self.harness.add_relation_unit(self.peer_relation_id, "mysql/1") self.shared_db_relation_id = self.harness.add_relation( LEGACY_DB_SHARED, "other-app") self.harness.add_relation_unit(self.shared_db_relation_id, "other-app/0") self.charm = self.harness.charm
def test_add_resource_but_oci(self): harness = Harness(CharmBase, meta=''' name: test-app resources: image: type: oci-image description: "Image to deploy." ''') self.addCleanup(harness.cleanup) with self.assertRaises(RuntimeError): harness.add_resource('image', 'content')
def test_publish_snapshot_action_fail(self, os_unlink, os_symlink, os_path_islink, os_path_isdir): os_path_isdir.return_value = False default_config = self.default_config() harness = Harness(SimpleStreamsCharm) harness.begin() harness.charm._stored.config = default_config harness.charm._get_snapshot_name = Mock() snapshot_name = uuid4() action_event = Mock(params={"name": snapshot_name}) harness.charm._on_publish_snapshot_action(action_event) assert action_event.fail.call_args == call('Snapshot does not exist')
def setUp(self): self.harness = Harness(RedisCharm) self.addCleanup(self.harness.cleanup) redis_resource = { "registrypath": "redis:6.0", # "username" and "password" are useless, but oci-resource # library fetch() fails if we do not provide them ... "username": "", "password": "" } self.harness.add_oci_resource("redis-image", redis_resource) self.harness.begin()
def test_install(self, mock_check_call, write_text): harness = Harness(charm.HaproxyCharm) harness.begin() harness.charm.on.install.emit() mock_check_call.assert_has_calls([ call(['apt', 'update']), call(['apt', 'install', '-yq', 'haproxy']) ]) harness.charm.HAPROXY_ENV_FILE.write_text.assert_called() harness.charm.haproxy_conf_file.write_text.assert_called()
def setUp(self): super().setUp() self.harness = Harness( self.MyCharm, meta=''' name: my-charm requires: ha: interface: hacluster scope: container ''' )
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)
def test_add_relation(self): # language=YAML harness = Harness(CharmBase, meta=''' name: test-app requires: db: interface: pgsql ''') rel_id = harness.add_relation('db', 'postgresql') self.assertIsInstance(rel_id, int) backend = harness._backend self.assertEqual([rel_id], backend.relation_ids('db')) self.assertEqual([], backend.relation_list(rel_id))
def test_publish_snapshot_action_success(self, os_unlink, os_symlink, os_path_islink, os_path_isdir): default_config = self.default_config() harness = Harness(SimpleStreamsCharm) harness.begin() harness.charm._stored.config = default_config harness.charm._get_snapshot_name = Mock() snapshot_name = uuid4() action_event = Mock(params={"name": snapshot_name}) harness.charm._on_publish_snapshot_action(action_event) assert os_symlink.call_args == call( '{}/{}'.format(default_config['image-dir'], snapshot_name), '{}/publish'.format(default_config['image-dir']))
def setUp(self): self.harness = Harness(CharmBase, meta=''' name: mssql peers: cluster: interface: mssql-cluster requires: ha: interface: hacluster scope: container ''') self.addCleanup(self.harness.cleanup)
def test_cli_args(self): harness = Harness(OPAManagerCharm) self.addCleanup(harness.cleanup) harness.begin() model_name = "test-cli-args" os.environ["JUJU_MODEL_NAME"] = model_name args = [ "--logtostderr", "--port=8443", f"--exempt-namespace={model_name}", "--operation=webhook", ] assert args == harness.charm._cli_args()
def test_update_config(self): harness = Harness(RecordingCharm) self.addCleanup(harness.cleanup) harness.begin() harness.update_config(key_values={'a': 'foo', 'b': 2}) self.assertEqual(harness.charm.changes, [{ 'name': 'config', 'data': { 'a': 'foo', 'b': 2 } }]) harness.update_config(key_values={'b': 3}) self.assertEqual(harness.charm.changes, [{ 'name': 'config', 'data': { 'a': 'foo', 'b': 2 } }, { 'name': 'config', 'data': { 'a': 'foo', 'b': 3 } }]) # you can set config values to the empty string, you can use unset to actually remove items harness.update_config(key_values={'a': ''}, unset=set('b')) self.assertEqual(harness.charm.changes, [ { 'name': 'config', 'data': { 'a': 'foo', 'b': 2 } }, { 'name': 'config', 'data': { 'a': 'foo', 'b': 3 } }, { 'name': 'config', 'data': { 'a': '' } }, ])
class TestCharm(unittest.TestCase): subprocess_mock = create_autospec(subprocess.check_call, return_value='True') subprocess.check_call = subprocess_mock def setUp(self): # Setup self.harness = Harness(CharmIscsiConnectorCharm) self.harness.begin() def test__init__works_without_a_hitch(self): # Setup harness = Harness(CharmIscsiConnectorCharm) # Exercise harness.begin() def test_on_install(self): harness = Harness(CharmIscsiConnectorCharm) harness.begin() self.assertFalse(harness.charm.state.installed) harness.charm.on.install.emit() self.assertTrue(harness.charm.state.installed) def test_on_start(self): harness = Harness(CharmIscsiConnectorCharm) harness.begin() self.assertFalse(harness.charm.state.started) harness.charm.on.start.emit() # event deferred as charm not configured yet self.assertFalse(harness.charm.state.started) # mock charm as configured harness.charm.state.configured = True harness.charm.on.start.emit() self.assertTrue(harness.charm.state.started) def test_on_restart_iscsi_services_action(self): harness = Harness(CharmIscsiConnectorCharm) harness.begin() action_event = FakeActionEvent() harness.charm.on_restart_iscsi_services_action(action_event) self.assertEqual(action_event.results['success'], 'True') def test_on_reload_multipathd_service_action(self): harness = Harness(CharmIscsiConnectorCharm) harness.begin() action_event = FakeActionEvent() harness.charm.on_reload_multipathd_service_action(action_event) self.assertEqual(action_event.results['success'], 'True')
def test_add_resource_unknown_filename(self): harness = Harness(CharmBase, meta=''' name: test-app resources: image: type: file description: "Image to deploy." ''') self.addCleanup(harness.cleanup) harness.add_resource('image', 'foo contents\n') path = harness.model.resources.fetch('image') self.assertTrue(str(path).endswith('/image/image'), msg='expected {} to end with /image/image')
def setUp(self): patcher = patch( "charms.grafana_k8s.v0.grafana_dashboard._resolve_dir_against_charm_path" ) self.mock_resolve_dir = patcher.start() self.addCleanup(patcher.stop) self.mock_resolve_dir.return_value = "./tests/unit/dashboard_templates" self.harness = Harness(ProviderCharm, meta=CONSUMER_META) self.harness._backend.model_name = "testing" self.harness._backend.model_uuid = "abcdefgh-1234" self.addCleanup(self.harness.cleanup) self.harness.begin() self.harness.set_leader(True)
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"}
def test_list_snapshots_action(self, os_walk): def a2g(x): return ([n, ['snapshot-{}'.format(n)]] for n in x) rand_n = random.randint(10, 100) os_walk.return_value = a2g([rand_n]) default_config = self.default_config() harness = Harness(SimpleStreamsCharm) harness.begin() harness.charm._stored.config = default_config harness.charm._get_snapshot_name = Mock() action_event = Mock() harness.charm._on_list_snapshots_action(action_event) assert action_event.set_results.call_args == call( {"snapshots": ['snapshot-{}'.format(rand_n)]})
def test_resource_folder_cleanup(self): harness = Harness(CharmBase, meta=''' name: test-app resources: image: type: oci-image description: "Image to deploy." ''') harness.populate_oci_resources() resource = harness._resource_dir / "image" / "contents.yaml" del harness with self.assertRaises(FileNotFoundError): with resource.open('r') as resource_file: print("This shouldn't be here: {}".format(resource_file))
def test_add_relation_with_remote_app_data(self): # language=YAML harness = Harness(CharmBase, meta=''' name: test-app requires: db: interface: pgsql ''') remote_app = 'postgresql' rel_id = harness.add_relation('db', remote_app) harness.update_relation_data(rel_id, 'postgresql', {'app': 'data'}) self.assertIsInstance(rel_id, int) backend = harness._backend self.assertEqual([rel_id], backend.relation_ids('db')) self.assertEqual({'app': 'data'}, backend.relation_get(rel_id, remote_app, is_app=True))
def test_add_relation(self): # language=YAML harness = Harness(CharmBase, meta=''' name: test-app requires: db: interface: pgsql ''') rel_id = harness.add_relation('db', 'postgresql') self.assertIsInstance(rel_id, int) backend = harness._backend self.assertEqual(backend.relation_ids('db'), [rel_id]) self.assertEqual(backend.relation_list(rel_id), []) # Make sure the initial data bags for our app and unit are empty. self.assertEqual(backend.relation_get(rel_id, 'test-app', is_app=True), {}) self.assertEqual(backend.relation_get(rel_id, 'test-app/0', is_app=False), {})
def setUp(self): self.harness = Harness(CharmBase, meta=''' name: mssql provides: db: interface: mssql peers: cluster: interface: mssql-cluster requires: ha: interface: hacluster scope: container ''') self.harness.update_config({'vip': self.TEST_VIP_ADDRESS}) self.addCleanup(self.harness.cleanup)