class TestIpsetActor(BaseTestCase): def setUp(self): super(TestIpsetActor, self).setUp() self.ipset = Mock(spec=Ipset) self.ipset.max_elem = 1234 self.ipset.set_name = "felix-a_set_name" self.ipset.temp_set_name = "felix-a_set_name-tmp" self.actor = IpsetActor(self.ipset) def test_sync_to_ipset(self): members1 = ["1.2.3.4", "2.3.4.5"] members2 = ["1.2.3.6", "2.3.4.5"] # Each call to replace members causes a full update. _log.info("Calling replace_members() once...") self.actor.replace_members(members1, async=True) self.step_actor(self.actor) self.ipset.replace_members.assert_called_once_with(set(members1)) self.assertFalse(self.ipset.apply_changes.called) self.assertEqual(self.actor.members, set(members1)) self.assertFalse(self.actor._force_reprogram) self.ipset.reset_mock() _log.info("Calling replace_members() second time..") self.actor.replace_members(members2, async=True) self.step_actor(self.actor) self.ipset.replace_members.assert_called_once_with(set(members2)) self.assertFalse(self.ipset.apply_changes.called) self.assertEqual(self.actor.members, set(members2)) self.assertFalse(self.actor._force_reprogram) self.ipset.reset_mock() _log.info("Calling replace_members() third time with mixed " "add/remove..") self.actor.add_members(["5.6.7.8"], async=True) # Ignored self.actor.remove_members(["1.2.3.6"], async=True) self.actor.replace_members(members1, async=True) self.actor.add_members(["6.7.8.9"], async=True) # Should apply self.actor.remove_members(["2.3.4.5"], async=True) self.step_actor(self.actor) self.ipset.replace_members.assert_called_once_with(set([ "6.7.8.9", "1.2.3.4", ])) self.assertFalse(self.ipset.apply_changes.called) self.assertEqual(self.actor.members, set([ "6.7.8.9", "1.2.3.4", ])) self.assertFalse(self.actor._force_reprogram) self.ipset.reset_mock() _log.info("Calling add/remove.") self.actor.add_members(["5.6.7.8"], async=True) self.actor.remove_members(["1.2.3.4"], async=True) self.step_actor(self.actor) self.assertFalse(self.ipset.replace_members.called) self.assertEqual(self.ipset.apply_changes.mock_calls, [ call(set(["5.6.7.8"]), set(["1.2.3.4"])) ]) self.assertEqual(self.actor.members, set([ "6.7.8.9", "5.6.7.8", ])) self.assertFalse(self.actor._force_reprogram) self.ipset.reset_mock() _log.info("Calling add/remove with failure.") self.ipset.apply_changes.side_effect = FailedSystemCall( "", [], 1, "", "" ) self.actor.add_members(["6.7.8.10"], async=True) self.actor.remove_members(["5.6.7.8"], async=True) self.step_actor(self.actor) self.assertEqual(self.ipset.replace_members.mock_calls, [ call(set(["6.7.8.9", "6.7.8.10"])) ]) self.assertEqual(self.actor.members, set(["6.7.8.9", "6.7.8.10"])) self.assertFalse(self.actor._force_reprogram) self.ipset.reset_mock() def test_members_too_big(self): members = set([str(IPAddress(x)) for x in range(2000)]) self.actor.replace_members(members, async=True) self.step_actor(self.actor) # Check we return early without updating programmed_members. self.assertTrue(self.actor._force_reprogram) def test_owned_ipset_names(self): self.assertEqual(self.actor.owned_ipset_names(), set(["felix-a_set_name", "felix-a_set_name-tmp"]))
class TestIpsetActor(BaseTestCase): def setUp(self): super(TestIpsetActor, self).setUp() self.ipset = Mock(spec=Ipset) self.ipset.max_elem = 1234 self.ipset.set_name = "felix-a_set_name" self.ipset.temp_set_name = "felix-a_set_name-tmp" self.actor = IpsetActor(self.ipset) def test_sync_to_ipset(self): members1 = set(["1.2.3.4", "2.3.4.5"]) members2 = set(["10.1.2.3"]) members3 = set(["9.9.9.9"]) # Cause a full update - first time. _log.debug("Initial resync of ipset will happen") self.actor.members = members1 self.actor._sync_to_ipset() self.ipset.replace_members.assert_called_once_with(members1) self.assertFalse(self.ipset.update_members.called) self.assertEqual(self.actor.members, members1) self.assertEqual(self.actor.programmed_members, self.actor.members) self.assertFalse(self.actor._force_reprogram) self.ipset.reset_mock() # Calls update_members _log.debug("Call to update_members should happen") self.actor.programmed_members = members1 self.actor.members = members2 self.actor._sync_to_ipset() self.assertFalse(self.ipset.replace_members.called) self.ipset.update_members.assert_called_once_with(members1, members2) self.assertEqual(self.actor.members, members2) self.assertEqual(self.actor.programmed_members, self.actor.members) self.assertFalse(self.actor._force_reprogram) self.ipset.reset_mock() # Does nothing - already in correct state _log.debug("Already in correct state (programmed_members matches)") self.actor.programmed_members = members2 self.actor.members = members2 self.actor._sync_to_ipset() self.assertFalse(self.ipset.replace_members.called) self.assertFalse(self.ipset.update_members.called) self.assertEqual(self.actor.members, members2) self.assertEqual(self.actor.programmed_members, self.actor.members) self.assertFalse(self.actor._force_reprogram) self.ipset.reset_mock() # Cause a full update - forced. _log.debug("Force a full ipset update") self.actor._force_reprogram = True self.actor.members = members3 self.actor._sync_to_ipset() self.ipset.replace_members.assert_called_once_with(members3) self.assertFalse(self.ipset.update_members.called) self.assertEqual(self.actor.members, members3) self.assertEqual(self.actor.programmed_members, self.actor.members) self.assertFalse(self.actor._force_reprogram) self.ipset.reset_mock() # Cause an assert - programmed_members is None, but no resync required. _log.debug("Force a full ipset update") self.actor._force_reprogram = False self.actor.members = members3 self.actor.programmed_members = None with self.assertRaises(AssertionError): self.actor._sync_to_ipset() self.ipset.reset_mock() def test_members_too_big(self): members = set([str(IPAddress(x)) for x in range(2000)]) self.actor.replace_members(members, async=True) self.step_actor(self.actor) # Check we return early without updating programmed_members. self.assertEqual(self.actor.programmed_members, None) def test_owned_ipset_names(self): self.assertEqual(self.actor.owned_ipset_names(), set(["felix-a_set_name", "felix-a_set_name-tmp"]))