Example #1
0
    def test_ocs_failure(self):
        """
        Test that when the OCS fails to respond to an update request, the service
        is cut off until the update can be completed
        """
        sub1 = SubContextConfig('IMSI001010000088888', '192.168.128.74', default_ambr_config, 4)
        quota = 1024

        self.test_util.controller.mock_create_session = Mock(
            return_value=session_manager_pb2.CreateSessionResponse(
                credits=[create_update_response(sub1.imsi, 1, quota)],
                static_rules=[session_manager_pb2.StaticRuleInstall(
                    rule_id="simple_match"
                )],
            ),
        )

        update_complete = hub.Queue()
        self.test_util.controller.mock_update_session = Mock(
            side_effect=get_standard_update_response(
                update_complete, None, quota, success=False),
        )

        self.test_util.controller.mock_terminate_session = Mock(
            return_value=session_manager_pb2.SessionTerminateResponse(),
        )

        self.test_util.sessiond.CreateSession(
            session_manager_pb2.LocalCreateSessionRequest(
                sid=SubscriberID(id=sub1.imsi),
                ue_ipv4=sub1.ip,
            ),
        )
        self.assertEqual(self.test_util.controller.mock_create_session.call_count, 1)

        packets = get_packets_for_flows(
            sub1, self.test_util.static_rules["simple_match"].flow_list)
        packet_count = int(quota / len(packets[0])) + 1
        sender = self.test_util.get_packet_sender([sub1], packets, packet_count)

        # assert after session init, data can flow
        self.assertGreater(self.test_util.thread.run_in_greenthread(sender), 0)

        # wait for failed update
        self.assertIsNotNone(get_from_queue(update_complete))
        hub.sleep(2)

        # assert that no data can be sent anymore
        self.assertEqual(self.test_util.thread.run_in_greenthread(sender), 0)

        self.test_util.controller.mock_update_session = Mock(
            side_effect=get_standard_update_response(
                update_complete, None, quota, success=True),
        )
        # wait for second update cycle to reactivate
        hub.sleep(4)
        self.assertGreater(self.test_util.thread.run_in_greenthread(sender), 0)

        self.test_util.sessiond.EndSession(SubscriberID(id=sub1.imsi))
        self.assertEqual(self.test_util.controller.mock_terminate_session.call_count, 1)
Example #2
0
    def test_basic_init(self):
        """
        Initiate subscriber, return 1 static policy with monitoring key, send
        traffic to match the policy, verify monitoring update is sent, terminate
        subscriber
        """
        sub1 = SubContextConfig('IMSI001010000088888', '192.168.128.74', default_ambr_config, 4)
        quota = 1024  # bytes

        self.test_util.controller.mock_create_session = Mock(
            return_value=session_manager_pb2.CreateSessionResponse(
                credits=[],
                static_rules=[
                    session_manager_pb2.StaticRuleInstall(
                        rule_id="monitor_rule",
                    ),
                ],
                dynamic_rules=[],
                usage_monitors=[
                    create_monitor_response(
                        sub1.imsi, "mkey1", quota, session_manager_pb2.PCC_RULE_LEVEL,
                    ),
                ],
            ),
        )

        self.test_util.controller.mock_terminate_session = Mock(
            return_value=session_manager_pb2.SessionTerminateResponse(),
        )

        monitor_complete = hub.Queue()
        self.test_util.controller.mock_update_session = Mock(
            side_effect=get_standard_update_response(
                None, monitor_complete, quota,
            ),
        )

        self.test_util.sessiond.CreateSession(
            session_manager_pb2.LocalCreateSessionRequest(
                sid=SubscriberID(id=sub1.imsi),
                ue_ipv4=sub1.ip,
            ),
        )

        self.assertEqual(self.test_util.controller.mock_create_session.call_count, 1)

        packets = get_packets_for_flows(
            sub1, self.test_util.static_rules["monitor_rule"].flow_list,
        )
        packet_count = int(quota / len(packets[0])) + 1

        self.test_util.thread.run_in_greenthread(
            self.test_util.get_packet_sender([sub1], packets, packet_count),
        )
        self.assertIsNotNone(get_from_queue(monitor_complete))
        self.assertEqual(self.test_util.controller.mock_update_session.call_count, 1)

        self.test_util.sessiond.EndSession(SubscriberID(id=sub1.imsi))
        self.assertEqual(self.test_util.controller.mock_terminate_session.call_count, 1)
Example #3
0
    def test_rules_with_failed_credit(self):
        """
        Test that when a session is initialized but the OCS either errored out or
        returned 0 GSUs, data is not allowed to flow
        """
        sub1 = SubContextConfig('IMSI001010000088888', '192.168.128.74', default_ambr_config, 4)

        rule2 = create_uplink_rule("rule2", 2, '46.10.0.1')
        rule3 = create_uplink_rule("rule3", 3, '47.10.0.1')
        self.test_util.controller.mock_create_session = Mock(
            return_value=session_manager_pb2.CreateSessionResponse(
                credits=[
                    # failed update
                    create_update_response(sub1.imsi, 1, 0, success=False),
                    # successful update, no credit
                    create_update_response(sub1.imsi, 1, 0, success=True),
                ],
                static_rules=[session_manager_pb2.StaticRuleInstall(
                    rule_id="simple_match"
                )],  # no credit for RG 1
                dynamic_rules=[
                    session_manager_pb2.DynamicRuleInstall(
                        policy_rule=rule2
                    ),
                    session_manager_pb2.DynamicRuleInstall(
                        policy_rule=rule3
                    )
                ],
            ),
        )

        self.test_util.controller.mock_terminate_session = Mock(
            return_value=session_manager_pb2.SessionTerminateResponse(),
        )

        self.test_util.sessiond.CreateSession(
            session_manager_pb2.LocalCreateSessionRequest(
                sid=SubscriberID(id=sub1.imsi),
                ue_ipv4=sub1.ip,
            ),
        )
        self.assertEqual(self.test_util.controller.mock_create_session.call_count, 1)

        flows = [rule.flow_list[0] for rule in [rule2, rule3]]
        packets = get_packets_for_flows(sub1, flows)
        pkt_diff = self.test_util.thread.run_in_greenthread(
            self.test_util.get_packet_sender([sub1], packets, 1),
        )
        self.assertEqual(pkt_diff, 0)

        self.test_util.sessiond.EndSession(SubscriberID(id=sub1.imsi))
        self.assertEqual(self.test_util.controller.mock_terminate_session.call_count, 1)
    def test_rule_with_no_credit(self):
        """
        Test that when a rule is returned that requires OCS tracking but has
        no credit, data is not allowed to pass
        """
        sub1 = SubContextConfig('IMSI001010000088888', '192.168.128.74',
                                default_ambr_config, 4)

        self.test_util.controller.mock_create_session = Mock(
            return_value=session_manager_pb2.CreateSessionResponse(
                static_rules=[
                    session_manager_pb2.StaticRuleInstall(
                        rule_id="simple_match", ),
                ],  # no credit for RG 1
            ), )

        self.test_util.controller.mock_terminate_session = Mock(
            return_value=session_manager_pb2.SessionTerminateResponse(), )

        self.test_util.sessiond.CreateSession(
            session_manager_pb2.LocalCreateSessionRequest(
                sid=SubscriberID(id=sub1.imsi),
                ue_ipv4=sub1.ip,
            ), )
        self.assertEqual(
            self.test_util.controller.mock_create_session.call_count, 1)

        packets = get_packets_for_flows(
            sub1,
            self.test_util.static_rules["simple_match"].flow_list,
        )

        pkt_diff = self.test_util.thread.run_in_greenthread(
            self.test_util.get_packet_sender([sub1], packets, 1), )
        self.assertEqual(pkt_diff, 0)

        self.test_util.sessiond.EndSession(SubscriberID(id=sub1.imsi))
        self.assertEqual(
            self.test_util.controller.mock_terminate_session.call_count, 1)
    def test_mixed_monitors_and_updates(self):
        """
        Test a mix of usage monitors, session monitors, and charging credits to
        PCRF and OCS.
        """
        sub1 = SubContextConfig('IMSI001010000088888', '192.168.128.74', 4)
        quota = 1024  # bytes

        pcrf_rule = create_uplink_rule("pcrf_rule", 0, '46.10.0.1',
                                                m_key="key1",
                                                tracking=PolicyRule.ONLY_PCRF)
        ocs_rule = create_uplink_rule("ocs_rule", 1, '47.10.0.1',
                                               tracking=PolicyRule.ONLY_OCS)
        both_rule = create_uplink_rule("both_rule", 2, '48.10.0.1',
                                                m_key="key2",
                                                tracking=PolicyRule.OCS_AND_PCRF)

        self.test_util.controller.mock_create_session = Mock(
            return_value=session_manager_pb2.CreateSessionResponse(
                credits=[
                    create_update_response("", 1, quota),
                    create_update_response("", 2, quota),
                ],
                dynamic_rules=[
                    session_manager_pb2.DynamicRuleInstall(
                        policy_rule=pcrf_rule,
                    ),
                    session_manager_pb2.DynamicRuleInstall(
                        policy_rule=ocs_rule,
                    ),
                    session_manager_pb2.DynamicRuleInstall(
                        policy_rule=both_rule,
                    ),
                ],
                usage_monitors=[
                    create_monitor_response(
                        sub1.imsi,
                        "key1",
                        quota,
                        session_manager_pb2.PCC_RULE_LEVEL,
                    ),
                    create_monitor_response(
                        sub1.imsi,
                        "key2",
                        quota,
                        session_manager_pb2.PCC_RULE_LEVEL,
                    ),
                    create_monitor_response(
                        sub1.imsi,
                        "key3",
                        quota,
                        session_manager_pb2.SESSION_LEVEL,
                    ),
                ],
            ),
        )

        self.test_util.controller.mock_terminate_session = Mock(
            return_value=session_manager_pb2.SessionTerminateResponse(),
        )

        charging_complete = hub.Queue()
        monitor_complete = hub.Queue()
        self.test_util.controller.mock_update_session = Mock(
            side_effect=get_standard_update_response(
                charging_complete, monitor_complete, quota),
        )

        self.test_util.sessiond.CreateSession(
            session_manager_pb2.LocalCreateSessionRequest(
                sid=SubscriberID(id=sub1.imsi),
                ue_ipv4=sub1.ip,
            ),
        )

        self.assertEqual(self.test_util.controller.mock_create_session.call_count, 1)
        flows = [rule.flow_list[0] for rule in [pcrf_rule, ocs_rule, both_rule]]
        packets = get_packets_for_flows(sub1, flows)
        packet_count = int(quota / len(packets[0])) + 1
        self.test_util.thread.run_in_greenthread(
            self.test_util.get_packet_sender([sub1], packets, packet_count),
        )

        # Wait for responses for keys 1 and 2 (ocs_rule and both_rule)
        charging_keys = {1, 2}
        for _ in range(len(charging_keys)):
            update = get_from_queue(charging_complete)
            self.assertTrue(update.usage.charging_key in charging_keys)
            charging_keys.remove(update.usage.charging_key)

        # Wait for responses for mkeys key1 (pcrf_rule), key2 (both_rule),
        # key3 (session rule)
        monitoring_keys = ["key1", "key2", "key3"]
        for _ in range(len(monitoring_keys)):
            monitor = get_from_queue(monitor_complete)
            self.assertTrue(monitor.update.monitoring_key in monitoring_keys)
            monitoring_keys.remove(monitor.update.monitoring_key)

        self.test_util.sessiond.EndSession(SubscriberID(id=sub1.imsi))
        self.assertEqual(self.test_util.controller.mock_terminate_session.call_count, 1)
    def test_input_output(self):
        """
        """
        sub1 = SubContextConfig('IMSI001010000088888', '192.168.128.74', 4)
        quota = 1024  # bytes

        # return only rx (downlink) packets
        self.test_util.controller.mock_create_session = Mock(
            return_value=session_manager_pb2.CreateSessionResponse(
                credits=[
                    session_manager_pb2.CreditUpdateResponse(
                        success=True,
                        sid=sub1.imsi,
                        charging_key=1,
                        credit=session_manager_pb2.ChargingCredit(
                            granted_units=session_manager_pb2.GrantedUnits(
                                rx=session_manager_pb2.CreditUnit(
                                    is_valid=True,
                                    volume=quota,
                                ), ), ),
                    )
                ],
                static_rules=[
                    session_manager_pb2.StaticRuleInstall(
                        rule_id="simple_match")
                ],
            ), )

        self.test_util.controller.mock_terminate_session = Mock(
            return_value=session_manager_pb2.SessionTerminateResponse(), )

        update_complete = hub.Queue()
        self.test_util.controller.mock_update_session = Mock(
            side_effect=get_standard_update_response(update_complete,
                                                     None,
                                                     quota,
                                                     is_final=False), )

        self.test_util.sessiond.CreateSession(
            session_manager_pb2.LocalCreateSessionRequest(
                sid=SubscriberID(id=sub1.imsi),
                ue_ipv4=sub1.ip,
            ), )
        self.assertEqual(
            self.test_util.controller.mock_create_session.call_count, 1)

        packets = get_packets_for_flows(
            sub1, self.test_util.static_rules["simple_match"].flow_list)
        packet_count = int(quota / len(packets[0])) + 1

        self.test_util.thread.run_in_greenthread(
            self.test_util.get_packet_sender([sub1], packets, packet_count), )
        self.assertIsNone(get_from_queue(update_complete))
        self.assertEqual(
            self.test_util.controller.mock_update_session.call_count, 0)

        self.test_util.sessiond.EndSession(SubscriberID(id=sub1.imsi))
        self.assertEqual(
            self.test_util.controller.mock_terminate_session.call_count, 1)

        # now attach with tx (uplink packets)
        self.test_util.controller.mock_create_session = Mock(
            return_value=session_manager_pb2.CreateSessionResponse(
                credits=[
                    session_manager_pb2.CreditUpdateResponse(
                        success=True,
                        sid=sub1.imsi,
                        charging_key=1,
                        credit=session_manager_pb2.ChargingCredit(
                            granted_units=session_manager_pb2.GrantedUnits(
                                tx=session_manager_pb2.CreditUnit(
                                    is_valid=True,
                                    volume=quota,
                                ), ), ),
                    )
                ],
                static_rules=[
                    session_manager_pb2.StaticRuleInstall(
                        rule_id="simple_match")
                ],
            ), )
        self.test_util.sessiond.CreateSession(
            session_manager_pb2.LocalCreateSessionRequest(
                sid=SubscriberID(id=sub1.imsi),
                ue_ipv4=sub1.ip,
            ), )
        self.test_util.thread.run_in_greenthread(
            self.test_util.get_packet_sender([sub1], packets, packet_count), )
        self.assertIsNotNone(get_from_queue(update_complete))
        self.assertEqual(
            self.test_util.controller.mock_update_session.call_count, 1)
        self.test_util.sessiond.EndSession(SubscriberID(id=sub1.imsi))
        self.assertEqual(
            self.test_util.controller.mock_terminate_session.call_count, 2)
    def test_multiple_subscribers(self):
        """
        Test credit tracking with multiple rules and 32 subscribers, each using
        up their quota and reporting to the OCS
        """
        subs = [
            SubContextConfig(
                'IMSI0010100000888{}'.format(i),
                '192.168.128.{}'.format(i),
                4,
            ) for i in range(32)
        ]
        quota = 1024  # bytes

        # create some rules
        rule1 = create_uplink_rule("rule1", 2, '46.10.0.1')
        rule2 = create_uplink_rule("rule2",
                                   0,
                                   '47.10.0.1',
                                   tracking=PolicyRule.NO_TRACKING)
        rule3 = create_uplink_rule("rule3", 3, '49.10.0.1')
        self.test_util.static_rules["rule1"] = rule1
        self.test_util.static_rules["rule2"] = rule2
        hub.sleep(2)  # wait for policies

        # set up mocks
        self.test_util.controller.mock_create_session = Mock(
            return_value=session_manager_pb2.CreateSessionResponse(
                credits=[
                    create_update_response("", 2, quota),
                    create_update_response("", 3, quota),
                ],
                static_rules=[
                    session_manager_pb2.StaticRuleInstall(rule_id="rule1"),
                    session_manager_pb2.StaticRuleInstall(rule_id="rule2"),
                ],
                dynamic_rules=[
                    session_manager_pb2.DynamicRuleInstall(policy_rule=rule3)
                ],
            ), )
        self.test_util.controller.mock_terminate_session = Mock(
            return_value=session_manager_pb2.SessionTerminateResponse(), )
        update_complete = hub.Queue()
        self.test_util.controller.mock_update_session = Mock(
            side_effect=get_standard_update_response(update_complete,
                                                     None,
                                                     quota,
                                                     is_final=True), )

        # initiate sessions
        for sub in subs:
            self.test_util.sessiond.CreateSession(
                session_manager_pb2.LocalCreateSessionRequest(
                    sid=SubscriberID(id=sub.imsi),
                    ue_ipv4=sub.ip,
                ), )
        self.assertEqual(
            self.test_util.controller.mock_create_session.call_count,
            len(subs))

        # send packets towards all 3 rules
        flows = [rule.flow_list[0] for rule in [rule1, rule2, rule3]]
        packets = []
        for sub in subs:
            packets.extend(get_packets_for_flows(sub, flows))
        packet_count = int(quota / len(packets[0])) + 1
        self.test_util.thread.run_in_greenthread(
            self.test_util.get_packet_sender(subs, packets, packet_count), )

        # wait for responses for keys 2 and 3 (key 1 is not tracked)
        expected_keys = {(sub.imsi, key) for sub in subs for key in [2, 3]}
        for _ in range(len(expected_keys)):
            update = get_from_queue(update_complete)
            self.assertIsNotNone(update)
            imsiKey = (update.sid, update.usage.charging_key)
            self.assertTrue(imsiKey in expected_keys)
            expected_keys.remove(imsiKey)

        for sub in subs:
            self.test_util.sessiond.EndSession(SubscriberID(id=sub.imsi))
        self.assertEqual(
            self.test_util.controller.mock_terminate_session.call_count,
            len(subs))
    def test_out_of_credit(self):
        """
        Initiate subscriber, return 1 static policy, send traffic to match the
        policy, verify update is sent, return final credits, use up final
        credits, ensure that no traffic can be sent
        """
        sub1 = SubContextConfig('IMSI001010000088888', '192.168.128.74', 4)
        quota = 1024  # bytes

        self.test_util.controller.mock_create_session = Mock(
            return_value=session_manager_pb2.CreateSessionResponse(
                credits=[
                    session_manager_pb2.CreditUpdateResponse(
                        success=True,
                        sid=sub1.imsi,
                        charging_key=1,
                        credit=session_manager_pb2.ChargingCredit(
                            granted_units=session_manager_pb2.GrantedUnits(
                                total=session_manager_pb2.CreditUnit(
                                    is_valid=True,
                                    volume=quota,
                                ), ), ),
                    )
                ],
                static_rules=[
                    session_manager_pb2.StaticRuleInstall(
                        rule_id="simple_match")
                ],
                dynamic_rules=[],
                usage_monitors=[],
            ), )

        self.test_util.controller.mock_terminate_session = Mock(
            return_value=session_manager_pb2.SessionTerminateResponse(), )

        update_complete = hub.Queue()
        self.test_util.controller.mock_update_session = Mock(
            side_effect=get_standard_update_response(update_complete,
                                                     None,
                                                     quota,
                                                     is_final=True), )

        self.test_util.sessiond.CreateSession(
            session_manager_pb2.LocalCreateSessionRequest(
                sid=SubscriberID(id=sub1.imsi),
                ue_ipv4=sub1.ip,
            ), )
        self.assertEqual(
            self.test_util.controller.mock_create_session.call_count, 1)

        packets = get_packets_for_flows(
            sub1, self.test_util.static_rules["simple_match"].flow_list)
        packet_count = int(quota / len(packets[0])) + 1
        send_packets = self.test_util.get_packet_sender([sub1], packets,
                                                        packet_count)

        self.test_util.thread.run_in_greenthread(send_packets)
        self.assertIsNotNone(get_from_queue(update_complete))
        self.assertEqual(
            self.test_util.controller.mock_update_session.call_count, 1)

        # use up last credits
        self.test_util.thread.run_in_greenthread(send_packets)
        hub.sleep(3)  # wait for sessiond to terminate rule after update

        pkt_diff = self.test_util.thread.run_in_greenthread(send_packets)
        self.assertEqual(pkt_diff, 0)

        self.test_util.proxy_responder.ChargingReAuth(
            session_manager_pb2.ChargingReAuthRequest(
                charging_key=1,
                sid=sub1.imsi,
            ), )
        get_from_queue(update_complete)
        self.assertEqual(
            self.test_util.controller.mock_update_session.call_count, 2)
        # wait for 1 update to trigger credit request, another to trigger
        # rule activation
        # TODO Add future to track when flows are added/deleted
        hub.sleep(5)
        pkt_diff = self.test_util.thread.run_in_greenthread(send_packets)
        self.assertGreater(pkt_diff, 0)

        self.test_util.sessiond.EndSession(SubscriberID(id=sub1.imsi))
        self.assertEqual(
            self.test_util.controller.mock_terminate_session.call_count, 1)