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_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)