def test_not_ready(self): # When the remote DB stops being ready for some reason, # it counts as gone. master_c = ConnectionString("dbname=master") standby_c = ConnectionString("dbname=standby") self.set_dbs(master_c, standby_c) self.charm.reset() ev_names = [ "master_gone", "standby_gone", "database_gone", "master_changed", "standby_changed", "database_changed", ] # No longer providing the requested extensions, no longer ready. self.harness.update_relation_data(self.relation_id, self.remote_app.name, {"extensions": "foo"}) self.assert_only_events(*ev_names) for ev_name in ev_names: with self.subTest(f"unready relation triggers {ev_name}"): ev = getattr(self.charm, f"{ev_name}_event") self.assertIsNone(ev.master) self.assertEqual(ev.standbys, [])
def test_databases_available(self): # When both master and standby become available, all the # [...]Available events are emitted. self.charm.reset() ev_names = [ "master_available", "standby_available", "database_available", "master_changed", "standby_changed", "database_changed", ] master_c = ConnectionString("dbname=master") standby1_c = ConnectionString("dbname=standby1") standby2_c = ConnectionString("dbname=standby2") self.set_dbs(master_c, standby1_c, standby2_c) self.assert_only_events(*ev_names) for ev_name in ev_names: with self.subTest( f"master & standby available triggers {ev_name}"): ev = getattr(self.charm, f"{ev_name}_event") self.assertEqual(ev.master, master_c) self.assertEqual(ev.standbys, [standby1_c, standby2_c])
def test_standbys_and_master_gone(self): # When both the master and standbys disappear, all of # MasterGoneEvent, StandbyGoneEvent, DatabaseGoneEvent, # MasterChangedEvent, StandbyChangedEvent and # DatabaseChangedEvent are emitted. master_c = ConnectionString("dbname=master") standby_c = ConnectionString("dbname=standby") self.set_dbs(master_c, standby_c) self.charm.reset() ev_names = [ "master_gone", "standby_gone", "database_gone", "master_changed", "standby_changed", "database_changed", ] self.set_dbs(None) self.assert_only_events(*ev_names) for ev_name in ev_names: with self.subTest(f"standby gone triggers {ev_name}"): ev = getattr(self.charm, f"{ev_name}_event") self.assertEqual(ev.master, None) self.assertEqual(ev.standbys, [])
def test_standbys(self, standbys): c1 = "host=standby1 dbname=foo" c2 = "host=standby2 dbname=foo" standbys.return_value = [c1, c2] self.assertEqual( self.ev.standbys, [ConnectionString(c1), ConnectionString(c2)]) standbys.assert_called_once_with(self.ev.log, self.relation, self.local_unit)
def test_relation_broken_full(self): # MasterChanged, DatabaseChanged, MasterGone and DatabaseGone # events are emitted if the master was available when the # relation is lost. self.set_dbs(ConnectionString("dbname=master"), ConnectionString("dbname=standby")) self.charm.reset() self.charm.on.db_relation_broken.emit(self.relation) self.assert_only_events( "database_relation_broken", "master_changed", "standby_changed", "database_changed", "master_gone", "standby_gone", "database_gone", )
def test_standby_changed(self): # When the master connection string is changed, # MasterChangedEvent and DatabaseChangedEvent are emitted. master_c = ConnectionString("dbname=master") standby_c = ConnectionString("dbname=standby") self.set_dbs(master_c, ConnectionString("dbname=org_standby")) self.charm.reset() ev_names = ["standby_changed", "database_changed"] self.set_standbys(standby_c) self.assert_only_events(*ev_names) for ev_name in ev_names: with self.subTest(f"standby change triggers {ev_name}"): ev = getattr(self.charm, f"{ev_name}_event") self.assertEqual(ev.master, master_c) self.assertEqual(ev.standbys, [standby_c])
def test_databases_changed(self): # When the master and standby connection strings are changed, # all the [...]ChangedEvents are emitted. self.set_dbs(ConnectionString("dbname=org_master"), ConnectionString("dbname=org_standby")) self.charm.reset() ev_names = ["master_changed", "standby_changed", "database_changed"] master_c = ConnectionString("dbname=master") standby_c = ConnectionString("dbname=standby") self.set_dbs(master_c, standby_c) self.assert_only_events(*ev_names) for ev_name in ev_names: with self.subTest(f"standby change triggers {ev_name}"): ev = getattr(self.charm, f"{ev_name}_event") self.assertEqual(ev.master, master_c) self.assertEqual(ev.standbys, [standby_c])
def test_standbys_gone_master_remains(self): # When a standby connection string disappears, but the master # remains, all of StandbyGoneEvent, StrandbyChangedEvent, # and DatabaseChangedEvent are emitted. DatabaseGoneEvent is # not emitted. master_c = ConnectionString("dbname=master") standby_c = ConnectionString("dbname=standby") self.set_dbs(master_c, standby_c) self.charm.reset() ev_names = ["standby_gone", "standby_changed", "database_changed"] self.set_standbys() self.assert_only_events(*ev_names) for ev_name in ev_names: with self.subTest(f"standby gone triggers {ev_name}"): ev = getattr(self.charm, f"{ev_name}_event") self.assertEqual(ev.master, master_c) self.assertEqual(ev.standbys, [])
def test_master_gone_standbys_remain(self): # When the master connection string disappears, but standbys # remain, all of MasterGoneEvent, MasterChangedEvent and # DatabaseChangedEvent are emitted. DatabaseGoneEvent is not # emitted. master_c = ConnectionString("dbname=master") standby_c = ConnectionString("dbname=standby") self.set_dbs(master_c, standby_c) self.charm.reset() ev_names = ["master_gone", "master_changed", "database_changed"] self.set_master(None) self.assert_only_events(*ev_names) for ev_name in ev_names: with self.subTest(f"master gone triggers {ev_name}"): ev = getattr(self.charm, f"{ev_name}_event") self.assertIsNone(ev.master) self.assertEqual(ev.standbys, [standby_c])
def test_standby_available(self): # When the standby becomes available, # StandbyAvailableEvent, DatabaseAvailableEvent, # StandbyChangedEvent and DatabaseChangedEvent are emitted. self.charm.reset() ev_names = [ "standby_available", "database_available", "standby_changed", "database_changed" ] standby_c = ConnectionString("dbname=standby") self.set_standbys(standby_c) self.assert_only_events(*ev_names) for ev_name in ev_names: with self.subTest(f"standby available triggers {ev_name}"): ev = getattr(self.charm, f"{ev_name}_event") self.assertEqual(ev.standbys, [standby_c]) self.assertIsNone(ev.master)
def test_master_available(self): # When the master becomes available, # MasterAvailableEvent, DatabaseAvailableEvent, # MasterChangedEvent and DatabaseChangedEvent are emitted. self.charm.reset() ev_names = [ "master_available", "database_available", "master_changed", "database_changed" ] master_c = ConnectionString("dbname=master") self.set_master(master_c) self.assert_only_events(*ev_names) for ev_name in ev_names: with self.subTest(f"master available triggers {ev_name}"): ev = getattr(self.charm, f"{ev_name}_event") self.assertEqual(ev.master, master_c) self.assertEqual(ev.standbys, [])
def test_master_gone_no_standbys(self): # When the master connection string disappears, and there are # no standbys, all of MasterGoneEvent, MasterChangedEvent, # DatabaseGoneEvent and DatabaseChangedEvent are emitted. master_c = ConnectionString("dbname=master") self.set_master(master_c) self.charm.reset() ev_names = [ "master_gone", "database_gone", "master_changed", "database_changed" ] self.set_master(None) self.assert_only_events(*ev_names) for ev_name in ev_names: with self.subTest(f"master gone triggers {ev_name}"): ev = getattr(self.charm, f"{ev_name}_event") self.assertIsNone(ev.master) self.assertEqual(ev.standbys, [])
def test_master(self, master): c = "host=master dbname=foo" master.return_value = c self.assertEqual(self.ev.master, ConnectionString(c)) master.assert_called_once_with(self.ev.log, self.relation, self.local_unit)