def process_update(self, stream_name: str, updates: List[DataUpdate], resync: bool): logging.info('Processing %d basename -> policy updates', len(updates)) for update in updates: basename = ChargingRuleNameSet() basename.ParseFromString(update.value) self._basenames[update.key] = basename
def setUp(self): rating_groups_by_id = { 1: RatingGroup( id=1, limit_type=RatingGroup.INFINITE_UNMETERED, ), 2: RatingGroup( id=2, limit_type=RatingGroup.INFINITE_METERED, ), } basenames_dict = { 'bn1': ChargingRuleNameSet(RuleNames=['p5']), 'bn2': ChargingRuleNameSet(RuleNames=['p6']), } apn_rules_by_sid = { "IMSI1234": SubscriberPolicySet(rules_per_apn=[ ApnPolicySet( apn="apn1", assigned_base_names=[], assigned_policies=["redirect"], ), ], ), "IMSI2345": SubscriberPolicySet(rules_per_apn=[ ApnPolicySet( apn="apn1", assigned_base_names=["bn1"], assigned_policies=[], ), ApnPolicySet( apn="apn2", assigned_base_names=["bn2"], assigned_policies=[], ), ], ), "IMSI3456": SubscriberPolicySet( global_base_names=["bn1"], global_policies=[], rules_per_apn=[ ApnPolicySet( apn="apn1", assigned_base_names=[], assigned_policies=[], ), ], ), } self.servicer = SessionRpcServicer( self._get_mconfig(), rating_groups_by_id, basenames_dict, apn_rules_by_sid, )
def test_SuccessfulUpdate(self): """ Test the happy path where updates come in for added rules, and sessiond accepts the RAR without issue. """ assignments_dict = {} basenames_dict = { 'bn1': ChargingRuleNameSet(RuleNames=['p5']), 'bn2': ChargingRuleNameSet(RuleNames=['p6']), } callback = RuleMappingsStreamerCallback( ReAuthHandler(assignments_dict, MockSessionProxyResponderStub1()), basenames_dict, assignments_dict, ) # Construct a set of updates, keyed by subscriber ID updates = [ DataUpdate( key="s1", value=AssignedPolicies( assigned_policies=["p1", "p2"], assigned_base_names=["bn1"], ).SerializeToString(), ), DataUpdate( key="s2", value=AssignedPolicies( assigned_policies=["p2", "p3"], ).SerializeToString(), ), ] callback.process_update("stream", updates, False) # Since we used a stub which always succeeds when a RAR is made, # We should expect the assignments_dict to be updated s1_policies = assignments_dict["s1"].installed_policies expected = 3 self.assertEqual(len(s1_policies), expected, 'There should be 3 active ' 'policies for s1') self.assertTrue("p1" in s1_policies, 'Policy p1 should be active for ' 'subscriber s1') self.assertTrue("p5" in s1_policies, 'Policy p5 should be active for ' 'subscriber s1') s2_policies = assignments_dict["s2"].installed_policies expected = 2 self.assertEqual(len(s2_policies), expected, 'There should be 2 active ' 'policies for s2') self.assertTrue("p3" in s2_policies, 'Policy p3 should be active for ' 'subscriber s2')
def test_EnableStaticRules(self): """ Check the happy path where everything succeeds. """ rules_by_sid = {} rules_by_basename = { "bn1": ChargingRuleNameSet(RuleNames=["p4", "p5"], ), } reauth_handler = ReAuthHandler( rules_by_sid, MockSessionProxyResponderStub(), ) servicer = PolicyRpcServicer( reauth_handler, rules_by_basename, MockPolicyAssignmentControllerStub(), ) # Bind the rpc server to a free port thread_pool = futures.ThreadPoolExecutor(max_workers=10) rpc_server = grpc.server(thread_pool) port = rpc_server.add_insecure_port('0.0.0.0:0') # Create a mock "mconfig" for the servicer to use mconfig = unittest.mock.Mock() mconfig.ip_block = None # Add the servicer servicer.add_to_server(rpc_server) rpc_server.start() # Create a rpc stub channel = grpc.insecure_channel('0.0.0.0:{}'.format(port)) stub = PolicyDBStub(channel) rules_by_basename["bn1"] = ChargingRuleNameSet(RuleNames=["p4", "p5"], ) req = EnableStaticRuleRequest( imsi="s1", rule_ids=["p1", "p2", "p3"], base_names=["bn1"], ) stub.EnableStaticRules(req) self.assertEqual( len(rules_by_sid["s1"].installed_policies), 5, 'After a successful update, Redis should be tracking ' '5 active rules.', )
def test_FailOrc8r(self): """ Check that nothing is updated if orc8r is unreachable """ rules_by_sid = {} rules_by_basename = { "bn1": ChargingRuleNameSet(RuleNames=["p4", "p5"], ), } reauth_handler = ReAuthHandler( rules_by_sid, MockSessionProxyResponderStub(), ) servicer = PolicyRpcServicer( reauth_handler, rules_by_basename, MockPolicyAssignmentControllerStub2(), ) # Bind the rpc server to a free port thread_pool = futures.ThreadPoolExecutor(max_workers=10) rpc_server = grpc.server(thread_pool) port = rpc_server.add_insecure_port('0.0.0.0:0') # Create a mock "mconfig" for the servicer to use mconfig = unittest.mock.Mock() mconfig.ip_block = None # Add the servicer servicer.add_to_server(rpc_server) rpc_server.start() # Create a rpc stub channel = grpc.insecure_channel('0.0.0.0:{}'.format(port)) stub = PolicyDBStub(channel) req = EnableStaticRuleRequest( imsi="s1", rule_ids=["p1", "p2", "p3"], base_names=["bn1"], ) with self.assertRaises(grpc.RpcError): stub.EnableStaticRules(req) self.assertFalse( "s1" in rules_by_sid, "There should be no installed policies for s1", )
def test_Update(self): """ Test the happy path where updates come in for rules, and sessiond accepts the SessionRules without issue. """ # Expected call arguments to SetSessionRules allow_all_flow_list = [ FlowDescription( match=FlowMatch( direction=FlowMatch.Direction.Value("UPLINK"), ), action=FlowDescription.Action.Value("PERMIT"), ), FlowDescription( match=FlowMatch( direction=FlowMatch.Direction.Value("DOWNLINK"), ), action=FlowDescription.Action.Value("PERMIT"), ), ] # type: List[FlowDescription] no_tracking_type = PolicyRule.TrackingType.Value("NO_TRACKING") expected = SessionRules(rules_per_subscriber=[ RulesPerSubscriber( imsi='imsi_1', rule_set=[ RuleSet( apply_subscriber_wide=False, apn="apn1", static_rules=[ StaticRuleInstall(rule_id="p1"), ], dynamic_rules=[ DynamicRuleInstall(policy_rule=PolicyRule( id="allowlist_sid-imsi_1-apn1", priority=2, flow_list=allow_all_flow_list, tracking_type=no_tracking_type, )) ], ), ]), RulesPerSubscriber( imsi='imsi_2', rule_set=[ RuleSet( apply_subscriber_wide=False, apn="apn1", static_rules=[ StaticRuleInstall(rule_id="p5"), ], dynamic_rules=[ DynamicRuleInstall(policy_rule=PolicyRule( id="allowlist_sid-imsi_2-apn1", priority=2, flow_list=allow_all_flow_list, tracking_type=no_tracking_type, )) ], ), ]) ]) # Setup the test apn_rules_dict = {} basenames_dict = { 'bn1': ChargingRuleNameSet(RuleNames=['p5']), 'bn2': ChargingRuleNameSet(RuleNames=['p6']), } stub = MockLocalSessionManagerStub() stub_call_args = [] # type: List[SessionRules] side_effect = get_SetSessionRules_side_effect(stub_call_args) stub.SetSessionRules = Mock(side_effect=side_effect) callback = ApnRuleMappingsStreamerCallback( stub, basenames_dict, apn_rules_dict, ) # Construct a set of updates, keyed by subscriber ID updates = [ DataUpdate( key="imsi_1", value=SubscriberPolicySet(rules_per_apn=[ ApnPolicySet( apn="apn1", assigned_base_names=[], assigned_policies=["p1"], ), ], ).SerializeToString(), ), DataUpdate( key="imsi_2", value=SubscriberPolicySet(rules_per_apn=[ ApnPolicySet( apn="apn1", assigned_base_names=["bn1"], assigned_policies=[], ), ], ).SerializeToString(), ), ] callback.process_update("stream", updates, False) # Since we used a stub which always succeeds when a RAR is made, # We should expect the assignments_dict to be updated imsi_1_policies = apn_rules_dict["imsi_1"] self.assertEqual(len(imsi_1_policies.rules_per_apn), 1, 'There should be 1 active APNs for imsi_1') self.assertEqual(len(stub_call_args), 1, 'Stub should have been called once') called_with = stub_call_args[0].SerializeToString() self.assertEqual(called_with, expected.SerializeToString(), 'SetSessionRules call has incorrect arguments') # Stream down a second update, and now IMSI_1 gets access to a new APN updates_2 = [ DataUpdate( key="imsi_1", value=SubscriberPolicySet(rules_per_apn=[ ApnPolicySet( apn="apn2", assigned_base_names=["bn1"], assigned_policies=[], ), ], ).SerializeToString(), ), DataUpdate( key="imsi_2", value=SubscriberPolicySet( global_base_names=["bn2"], global_policies=[], rules_per_apn=[ ApnPolicySet( apn="apn1", assigned_base_names=[], assigned_policies=[], ), ], ).SerializeToString(), ), ] expected_2 = SessionRules(rules_per_subscriber=[ RulesPerSubscriber( imsi='imsi_1', rule_set=[ RuleSet( apply_subscriber_wide=False, apn="apn2", static_rules=[ StaticRuleInstall(rule_id="p5"), ], dynamic_rules=[ DynamicRuleInstall(policy_rule=PolicyRule( id="allowlist_sid-imsi_1-apn2", priority=2, flow_list=allow_all_flow_list, tracking_type=no_tracking_type, )) ], ), ]), RulesPerSubscriber( imsi='imsi_2', rule_set=[ RuleSet( apply_subscriber_wide=False, apn="apn1", static_rules=[ StaticRuleInstall(rule_id="p6"), ], dynamic_rules=[ DynamicRuleInstall(policy_rule=PolicyRule( id="allowlist_sid-imsi_2-apn1", priority=2, flow_list=allow_all_flow_list, tracking_type=no_tracking_type, )) ], ), ]), ]) callback.process_update("stream", updates_2, False) imsi_1_policies = apn_rules_dict["imsi_1"] self.assertEqual(len(imsi_1_policies.rules_per_apn), 1, 'There should be 1 active APNs for imsi_1') self.assertEqual(len(stub_call_args), 2, 'Stub should have been called twice') called_with = stub_call_args[1].SerializeToString() self.assertEqual(called_with, expected_2.SerializeToString(), 'SetSessionRules call has incorrect arguments')