Exemple #1
0
def get_mobilityd_gw_info() -> GWInfo:
    """
    Make RPC call to 'GetGatewayInfo' method of local mobilityD service
    """
    try:
        chan = ServiceRegistry.get_rpc_channel(SERVICE_NAME,
                                               ServiceRegistry.LOCAL)
    except ValueError:
        logging.error('Cant get RPC channel to %s', SERVICE_NAME)
        return GWInfo()

    client = MobilityServiceStub(chan)
    try:
        return client.GetGatewayInfo(Void())
    except grpc.RpcError as err:
        logging.error("GetGatewayInfoRequest error[%s] %s", err.code(),
                      err.details())
Exemple #2
0
class RpcTests(unittest.TestCase):
    """
    Tests for the IPAllocator rpc servicer and stub
    """
    def setUp(self):
        # Bind the rpc server to a free port
        thread_pool = futures.ThreadPoolExecutor(max_workers=10)
        self._rpc_server = grpc.server(thread_pool)
        port = self._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
        mconfig.ip_allocator_type = MobilityD.IP_POOL

        # Add the servicer
        config = {
            'persist_to_redis': False,
            'redis_port': None,
            'allocator_type': "ip_pool"
        }
        self._servicer = MobilityServiceRpcServicer(mconfig, config)
        self._servicer.add_to_server(self._rpc_server)
        self._rpc_server.start()

        # Create a rpc stub
        channel = grpc.insecure_channel('0.0.0.0:{}'.format(port))
        self._stub = MobilityServiceStub(channel)

        # variables shared across tests
        self._netaddr = '192.168.0.0'
        self._prefix_len = 28
        ip_bytes = bytes(map(int, self._netaddr.split('.')))
        self._block_msg = IPBlock(version=IPBlock.IPV4,
                                  net_address=ip_bytes,
                                  prefix_len=self._prefix_len)
        self._block = ipaddress.ip_network("%s/%s" %
                                           (self._netaddr, self._prefix_len))
        self._sid0 = SIDUtils.to_pb('IMSI0')
        self._sid1 = SIDUtils.to_pb('IMSI1')
        self._sid2 = SIDUtils.to_pb('IMSI2')
        self._apn0 = 'Internet'
        self._apn1 = 'IMS'

    def tearDown(self):
        self._rpc_server.stop(0)

    def test_add_ipv6_block_to_servicer(self):
        """ add IPv6 block (ipaddress.ipblock) directly to servicer should
        raise IPVersionNotSupportedError
        """
        ip = ipaddress.ip_address("fc::")
        with self.assertRaises(IPVersionNotSupportedError):
            self._servicer.add_ip_block(ip)

    def test_add_invalid_ip_block(self):
        """ adding invalid ipblock should raise INVALID_ARGUMENT """
        block_msg = IPBlock()
        with self.assertRaises(grpc.RpcError) as err:
            self._stub.AddIPBlock(block_msg)
        self.assertEqual(err.exception.code(),
                         grpc.StatusCode.INVALID_ARGUMENT)

    def test_list_invalid_ip_block(self):
        """ listing invalid ipblock should raise INVALID_ARGUMENT """
        block_msg = IPBlock()
        with self.assertRaises(grpc.RpcError) as err:
            self._stub.ListAllocatedIPs(block_msg)
        self.assertEqual(err.exception.code(),
                         grpc.StatusCode.INVALID_ARGUMENT)

    def test_add_overlapped_ip_block(self):
        """ overlaping IPBlocks should raise FAILED_PRECONDITION """
        self._stub.AddIPBlock(self._block_msg)

        # overlaped block
        ip_bytes = bytes(map(int, self._netaddr.split('.')))
        block_msg = IPBlock(version=IPBlock.IPV4,
                            net_address=ip_bytes,
                            prefix_len=30)
        with self.assertRaises(grpc.RpcError) as err:
            self._stub.AddIPBlock(block_msg)
        self.assertEqual(err.exception.code(),
                         grpc.StatusCode.FAILED_PRECONDITION)

    def test_list_added_ip_blocks(self):
        """ List IP blocks added to the allocator """
        # return empty list before adding an IP block
        resp = self._stub.ListAddedIPv4Blocks(Void())
        self.assertEqual(len(resp.ip_block_list), 0)

        # list one assigned IP blocks
        self._stub.AddIPBlock(self._block_msg)
        resp = self._stub.ListAddedIPv4Blocks(Void())
        self.assertEqual(len(resp.ip_block_list), 1)
        self.assertEqual(resp.ip_block_list[0], self._block_msg)

    def test_list_allocated_ips(self):
        """ test list allocated IPs from a IP block """
        self._stub.AddIPBlock(self._block_msg)

        # list empty allocated IPs
        resp = self._stub.ListAllocatedIPs(self._block_msg)
        self.assertEqual(len(resp.ip_list), 0)

        # list after allocating one IP
        request = AllocateIPRequest(sid=self._sid0,
                                    version=AllocateIPRequest.IPV4,
                                    apn=self._apn0)
        ip_msg0 = self._stub.AllocateIPAddress(request)
        resp = self._stub.ListAllocatedIPs(self._block_msg)
        self.assertNotEqual(resp, None)
        tmp = ListAllocatedIPsResponse()
        tmp.ip_list.extend([ip_msg0])
        self.assertEqual(resp, tmp)

    def test_list_allocated_ips_from_unknown_ipblock(self):
        """ test list allocated IPs from an unknown IP block """
        self._stub.AddIPBlock(self._block_msg)

        ip_bytes = bytes(map(int, '10.0.0.0'.split('.')))
        block_msg = IPBlock(version=IPBlock.IPV4,
                            net_address=ip_bytes,
                            prefix_len=30)
        with self.assertRaises(grpc.RpcError) as err:
            self._stub.ListAllocatedIPs(block_msg)
        self.assertEqual(err.exception.code(),
                         grpc.StatusCode.FAILED_PRECONDITION)

    def test_allocate_ip_address(self):
        """ test AllocateIPAddress and ListAllocatedIPs """
        self._stub.AddIPBlock(self._block_msg)

        # allocate 1st IP
        request = AllocateIPRequest(sid=self._sid0,
                                    version=AllocateIPRequest.IPV4,
                                    apn=self._apn0)
        ip_msg0 = self._stub.AllocateIPAddress(request)
        self.assertEqual(ip_msg0.version, AllocateIPRequest.IPV4)
        ip0 = ipaddress.ip_address(ip_msg0.address)
        self.assertTrue(ip0 in self._block)

        # TODO: uncomment the code below when ip_allocator
        # actually rejects with DuplicatedIPAllocationError

        # with self.assertRaises(grpc.RpcError) as err:
        #     self._stub.AllocateIPAddress(request)
        # self.assertEqual(err.exception.code(),
        #                  grpc.StatusCode.ALREADY_EXISTS)

        # allocate 2nd IP
        request.sid.CopyFrom(self._sid1)
        ip_msg2 = self._stub.AllocateIPAddress(request)
        self.assertEqual(ip_msg2.version, AllocateIPRequest.IPV4)
        ip2 = ipaddress.ip_address(ip_msg2.address)
        self.assertTrue(ip2 in self._block)

    def test_multiple_apn_ipallocation(self):
        """ test AllocateIPAddress for multiple APNs """
        self._stub.AddIPBlock(self._block_msg)

        # allocate 1st IP
        request = AllocateIPRequest(sid=self._sid0,
                                    version=AllocateIPRequest.IPV4,
                                    apn=self._apn0)
        ip_msg0 = self._stub.AllocateIPAddress(request)
        self.assertEqual(ip_msg0.version, AllocateIPRequest.IPV4)
        ip0 = ipaddress.ip_address(ip_msg0.address)
        self.assertTrue(ip0 in self._block)

        # allocate 2nd IP from another APN to the same user
        request.apn = self._apn1
        ip_msg1 = self._stub.AllocateIPAddress(request)
        self.assertEqual(ip_msg1.version, AllocateIPRequest.IPV4)
        ip1 = ipaddress.ip_address(ip_msg1.address)
        self.assertTrue(ip1 in self._block)

    def test_run_out_of_ip(self):
        """ should raise RESOURCE_EXHAUSTED when running out of IP """
        #  The subnet is provisioned with 16 addresses
        #  Inside ip_address_man.py 11 addresses are reserved,
        #  2 addresses are not usable (all zeros and all ones)
        #  Thus, we have a usable pool of 3 IP addresses;
        #  first three allocations should succeed, while the fourth
        #  request should raise RESOURCE_EXHAUSTED error
        self._stub.AddIPBlock(self._block_msg)

        request = AllocateIPRequest(sid=self._sid0,
                                    version=AllocateIPRequest.IPV4,
                                    apn=self._apn0)
        self._stub.AllocateIPAddress(request)
        request.apn = self._apn1
        self._stub.AllocateIPAddress(request)

        request.sid.CopyFrom(self._sid1)
        self._stub.AllocateIPAddress(request)

        request.sid.CopyFrom(self._sid2)

        with self.assertRaises(grpc.RpcError) as err:
            self._stub.AllocateIPAddress(request)
        self.assertEqual(err.exception.code(),
                         grpc.StatusCode.RESOURCE_EXHAUSTED)

    def test_release_ip_address(self):
        """ test ReleaseIPAddress """
        self._stub.AddIPBlock(self._block_msg)

        alloc_request0 = AllocateIPRequest(sid=self._sid0,
                                           version=AllocateIPRequest.IPV4,
                                           apn=self._apn0)
        ip_msg0 = self._stub.AllocateIPAddress(alloc_request0)
        alloc_request1 = AllocateIPRequest(sid=self._sid1,
                                           version=AllocateIPRequest.IPV4,
                                           apn=self._apn0)
        ip_msg1 = self._stub.AllocateIPAddress(alloc_request1)

        # release ip_msg0
        release_request0 = ReleaseIPRequest(sid=self._sid0,
                                            ip=ip_msg0,
                                            apn=self._apn0)
        resp = self._stub.ReleaseIPAddress(release_request0)
        self.assertEqual(resp, Void())
        resp = self._stub.ListAllocatedIPs(self._block_msg)
        tmp = ListAllocatedIPsResponse()
        tmp.ip_list.extend([ip_msg1])
        self.assertEqual(resp, tmp)

        # release ip_msg1
        release_request1 = ReleaseIPRequest(sid=self._sid1,
                                            ip=ip_msg1,
                                            apn=self._apn0)
        resp = self._stub.ReleaseIPAddress(release_request1)
        resp = self._stub.ListAllocatedIPs(self._block_msg)
        self.assertEqual(len(resp.ip_list), 0)

    def test_release_unknown_sid_apn_ip_tuple(self):
        """ releasing unknown sid-apn-ip tuple should raise NOT_FOUND """
        self._stub.AddIPBlock(self._block_msg)

        alloc_request0 = AllocateIPRequest(sid=self._sid0,
                                           version=AllocateIPRequest.IPV4,
                                           apn=self._apn0)
        ip_msg0 = self._stub.AllocateIPAddress(alloc_request0)

        request = ReleaseIPRequest(sid=SIDUtils.to_pb("IMSI12345"),
                                   ip=ip_msg0,
                                   apn=self._apn0)
        with self.assertRaises(grpc.RpcError) as err:
            self._stub.ReleaseIPAddress(request)
        self.assertEqual(err.exception.code(), grpc.StatusCode.NOT_FOUND)

        ip_bytes = bytes(map(int, '10.0.0.0'.split('.')))
        request.ip.CopyFrom(IPAddress(version=IPAddress.IPV4,
                                      address=ip_bytes))
        with self.assertRaises(grpc.RpcError) as err:
            self._stub.ReleaseIPAddress(request)
        self.assertEqual(err.exception.code(), grpc.StatusCode.NOT_FOUND)

        request = ReleaseIPRequest(sid=self._sid0, ip=ip_msg0, apn=self._apn1)
        with self.assertRaises(grpc.RpcError) as err:
            self._stub.ReleaseIPAddress(request)
        self.assertEqual(err.exception.code(), grpc.StatusCode.NOT_FOUND)

    def test_get_ip_for_subscriber(self):
        """ test GetIPForSubscriber """
        self._stub.AddIPBlock(self._block_msg)

        alloc_request0 = AllocateIPRequest(sid=self._sid0,
                                           version=AllocateIPRequest.IPV4,
                                           apn=self._apn0)
        ip_msg0 = self._stub.AllocateIPAddress(alloc_request0)
        ip0 = ipaddress.ip_address(ip_msg0.address)

        lookup_request0 = IPLookupRequest(sid=self._sid0, apn=self._apn0)
        ip_msg0_returned = self._stub.GetIPForSubscriber(lookup_request0)
        ip0_returned = ipaddress.ip_address(ip_msg0_returned.address)
        self.assertEqual(ip0, ip0_returned)

    def test_get_ip_for_unknown_subscriber(self):
        """ Getting ip for non existent subscriber should return NOT_FOUND
        status code """
        lookup_request0 = IPLookupRequest(sid=self._sid0, apn=self._apn0)
        with self.assertRaises(grpc.RpcError) as err:
            self._stub.GetIPForSubscriber(lookup_request0)
        self.assertEqual(err.exception.code(), grpc.StatusCode.NOT_FOUND)

    def test_get_gw_info(self):
        gw_info = self._stub.GetGatewayInfo(Void())
        gw_ip_get = str(ipaddress.ip_address(gw_info.ip.address))

        def_gw_cmd = shlex.split("ip route show")
        p = subprocess.Popen(def_gw_cmd, stdout=subprocess.PIPE)
        output = p.stdout.read().decode("utf-8")
        def_ip = None
        for line in output.splitlines():
            if 'default ' in line:
                tokens = line.split()
                def_ip = tokens[2]
                break

        self.assertEqual(def_ip, gw_ip_get)

    def test_set_gw_info(self):
        mac1 = "22:22:c6:d0:02:3c"
        ipaddr1 = ipaddress.ip_address("10.1.1.11")
        gwinfo_msg = GWInfo()
        gwinfo_msg.ip.version = IPBlock.IPV4
        gwinfo_msg.ip.address = ipaddr1.packed
        gwinfo_msg.mac = mac1

        self._stub.SetGatewayInfo(gwinfo_msg)
        gw_info = self._stub.GetGatewayInfo(Void())
        gw_ip_get = ipaddress.ip_address(gw_info.ip.address)

        self.assertEqual(ipaddr1, gw_ip_get)
        self.assertEqual(mac1, gw_info.mac)

    def test_get_subscriber_id_from_ip(self):
        """ test GetSubscriberIDFromIP """
        self._stub.AddIPBlock(self._block_msg)
        alloc_request0 = AllocateIPRequest(sid=self._sid0,
                                           version=AllocateIPRequest.IPV4,
                                           apn=self._apn0)
        ip_msg0 = self._stub.AllocateIPAddress(alloc_request0)
        sid_pb_returned = self._stub.GetSubscriberIDFromIP(ip_msg0)
        self.assertEqual(SIDUtils.to_str(self._sid0),
                         SIDUtils.to_str(sid_pb_returned))

    def test_get_subscriber_id_from_unknown_ip(self):
        """
        Getting subscriber id for non-allocated ip address should return
        NOT_FOUND error code
        """
        ip_pb = IPAddress(version=IPAddress.IPV4,
                          address=ipaddress.ip_address('1.1.1.1').packed)
        with self.assertRaises(grpc.RpcError) as err:
            self._stub.GetSubscriberIDFromIP(ip_pb)
        self.assertEqual(err.exception.code(), grpc.StatusCode.NOT_FOUND)

    def test_get_subscriber_ip_table(self):
        """ test GetSubscriberIPTable """
        self._stub.AddIPBlock(self._block_msg)

        resp = self._stub.GetSubscriberIPTable(Void())
        self.assertEqual(len(resp.entries), 0)

        alloc_request0 = AllocateIPRequest(sid=self._sid0,
                                           version=AllocateIPRequest.IPV4,
                                           apn=self._apn0)
        ip_msg0 = self._stub.AllocateIPAddress(alloc_request0)
        entry0 = SubscriberIPTableEntry(sid=self._sid0,
                                        ip=ip_msg0,
                                        apn=self._apn0)
        resp = self._stub.GetSubscriberIPTable(Void())
        self.assertTrue(entry0 in resp.entries)

        alloc_request1 = AllocateIPRequest(sid=self._sid1,
                                           version=AllocateIPRequest.IPV4,
                                           apn=self._apn1)
        ip_msg1 = self._stub.AllocateIPAddress(alloc_request1)
        entry1 = SubscriberIPTableEntry(sid=self._sid1,
                                        ip=ip_msg1,
                                        apn=self._apn1)
        resp = self._stub.GetSubscriberIPTable(Void())
        self.assertTrue(entry0 in resp.entries)
        self.assertTrue(entry1 in resp.entries)

        # keep in table after in release
        release_request0 = ReleaseIPRequest(sid=self._sid0,
                                            ip=ip_msg0,
                                            apn=self._apn0)
        resp = self._stub.ReleaseIPAddress(release_request0)
        resp = self._stub.GetSubscriberIPTable(Void())
        self.assertTrue(entry0 in resp.entries)
        self.assertTrue(entry1 in resp.entries)

    def test_remove_no_assigned_blocks(self):
        """ remove should return nothing """
        remove_request0 = RemoveIPBlockRequest(ip_blocks=[self._block_msg],
                                               force=False)
        resp = self._stub.RemoveIPBlock(remove_request0)

        expect = RemoveIPBlockResponse()
        self.assertEqual(expect, resp)

        resp = self._stub.ListAddedIPv4Blocks(Void())
        expect = ListAddedIPBlocksResponse()
        self.assertEqual(expect, resp)

    def test_remove_unallocated_assigned_block(self):
        """ remove should return nothing """
        self._stub.AddIPBlock(self._block_msg)

        remove_request0 = RemoveIPBlockRequest(ip_blocks=[self._block_msg],
                                               force=False)
        resp = self._stub.RemoveIPBlock(remove_request0)

        expect = RemoveIPBlockResponse()
        expect.ip_blocks.extend([self._block_msg])
        self.assertEqual(expect, resp)

        resp = self._stub.ListAddedIPv4Blocks(Void())
        expect = ListAddedIPBlocksResponse()
        self.assertEqual(expect, resp)

    def test_remove_allocated_assigned_block_without_force(self):
        """ remove should return nothing """
        self._stub.AddIPBlock(self._block_msg)

        alloc_request0 = AllocateIPRequest(sid=self._sid0,
                                           version=AllocateIPRequest.IPV4,
                                           apn=self._apn0)
        self._stub.AllocateIPAddress(alloc_request0)

        remove_request0 = RemoveIPBlockRequest(ip_blocks=[self._block_msg],
                                               force=False)
        resp = self._stub.RemoveIPBlock(remove_request0)

        expect = RemoveIPBlockResponse()
        self.assertEqual(expect, resp)

        resp = self._stub.ListAddedIPv4Blocks(Void())
        expect = ListAddedIPBlocksResponse()
        expect.ip_block_list.extend([self._block_msg])
        self.assertEqual(expect, resp)

    def test_remove_allocated_assigned_block_with_force(self):
        """ remove should return nothing """
        self._stub.AddIPBlock(self._block_msg)

        alloc_request0 = AllocateIPRequest(sid=self._sid0,
                                           version=AllocateIPRequest.IPV4,
                                           apn=self._apn0)
        self._stub.AllocateIPAddress(alloc_request0)

        remove_request0 = RemoveIPBlockRequest(ip_blocks=[self._block_msg],
                                               force=True)
        resp = self._stub.RemoveIPBlock(remove_request0)

        expect = RemoveIPBlockResponse()
        expect.ip_blocks.extend([self._block_msg])
        self.assertEqual(expect, resp)

        resp = self._stub.ListAddedIPv4Blocks(Void())
        expect = ListAddedIPBlocksResponse()
        self.assertEqual(expect, resp)

    def test_remove_after_releasing_all_addresses(self):
        """ remove after releasing all addresses should remove block """
        # Assign IP block
        self._stub.AddIPBlock(self._block_msg)

        # Allocate 2 IPs
        alloc_request0 = AllocateIPRequest(sid=self._sid0,
                                           version=AllocateIPRequest.IPV4,
                                           apn=self._apn0)
        ip_msg0 = self._stub.AllocateIPAddress(alloc_request0)

        alloc_request1 = AllocateIPRequest(sid=self._sid1,
                                           version=AllocateIPRequest.IPV4,
                                           apn=self._apn0)
        ip_msg1 = self._stub.AllocateIPAddress(alloc_request1)

        # Test remove without force -- should not remove block
        remove_request0 = RemoveIPBlockRequest(ip_blocks=[self._block_msg],
                                               force=False)
        resp = self._stub.RemoveIPBlock(remove_request0)

        expect = RemoveIPBlockResponse()
        self.assertEqual(expect, resp)

        # Ensure that block has not been removed
        resp = self._stub.ListAddedIPv4Blocks(Void())
        expect = ListAddedIPBlocksResponse()
        expect.ip_block_list.extend([self._block_msg])
        self.assertEqual(expect, resp)

        # Release the allocated IPs
        release_request0 = ReleaseIPRequest(sid=self._sid0,
                                            ip=ip_msg0,
                                            apn=self._apn0)
        resp = self._stub.ReleaseIPAddress(release_request0)
        self.assertEqual(resp, Void())

        release_request1 = ReleaseIPRequest(sid=self._sid1,
                                            ip=ip_msg1,
                                            apn=self._apn0)
        resp = self._stub.ReleaseIPAddress(release_request1)
        self.assertEqual(resp, Void())

        # Test remove without force -- should remove block
        remove_request1 = RemoveIPBlockRequest(ip_blocks=[self._block_msg],
                                               force=False)
        resp = self._stub.RemoveIPBlock(remove_request1)

        expect = RemoveIPBlockResponse()
        expect.ip_blocks.extend([self._block_msg])
        self.assertEqual(expect, resp)

        # Ensure that block has been removed
        resp = self._stub.ListAddedIPv4Blocks(Void())
        expect = ListAddedIPBlocksResponse()
        self.assertEqual(expect, resp)

    def test_remove_after_releasing_some_addresses(self):
        """ remove after releasing some addresses shouldn't remove block """
        # Assign IP block
        self._stub.AddIPBlock(self._block_msg)

        # Allocate 2 IPs
        alloc_request0 = AllocateIPRequest(sid=self._sid0,
                                           version=AllocateIPRequest.IPV4,
                                           apn=self._apn0)
        ip_msg0 = self._stub.AllocateIPAddress(alloc_request0)

        alloc_request1 = AllocateIPRequest(sid=self._sid1,
                                           version=AllocateIPRequest.IPV4,
                                           apn=self._apn0)
        self._stub.AllocateIPAddress(alloc_request1)

        # Test remove without force -- should not remove block
        remove_request0 = RemoveIPBlockRequest(ip_blocks=[self._block_msg],
                                               force=False)
        resp = self._stub.RemoveIPBlock(remove_request0)

        expect = RemoveIPBlockResponse()
        self.assertEqual(expect, resp)

        # Ensure that block has not been removed
        resp = self._stub.ListAddedIPv4Blocks(Void())
        expect = ListAddedIPBlocksResponse()
        expect.ip_block_list.extend([self._block_msg])
        self.assertEqual(expect, resp)

        # Release the allocated IPs
        release_request0 = ReleaseIPRequest(sid=self._sid0,
                                            ip=ip_msg0,
                                            apn=self._apn0)
        resp = self._stub.ReleaseIPAddress(release_request0)
        self.assertEqual(resp, Void())

        # Test remove without force -- should not remove block
        remove_request1 = RemoveIPBlockRequest(ip_blocks=[self._block_msg],
                                               force=False)
        resp = self._stub.RemoveIPBlock(remove_request1)

        expect = RemoveIPBlockResponse()
        self.assertEqual(expect, resp)

        # Ensure that block has not been removed
        resp = self._stub.ListAddedIPv4Blocks(Void())
        expect = ListAddedIPBlocksResponse()
        expect.ip_block_list.extend([self._block_msg])
        self.assertEqual(expect, resp)

    def test_ipv6_unimplemented(self):
        """ ipv6 requests should raise UNIMPLEMENTED """
        ip = ipaddress.ip_address("fc::")
        block = IPBlock(version=IPBlock.IPV6,
                        net_address=ip.packed,
                        prefix_len=120)
        # AddIPBlock
        with self.assertRaises(grpc.RpcError) as err:
            self._stub.AddIPBlock(block)
        self.assertEqual(err.exception.code(), grpc.StatusCode.UNIMPLEMENTED)
        # ListAllocatedIPs
        with self.assertRaises(grpc.RpcError) as err:
            self._stub.ListAllocatedIPs(block)
        self.assertEqual(err.exception.code(), grpc.StatusCode.UNIMPLEMENTED)

        # AllocateIPAddress
        request = AllocateIPRequest(sid=self._sid1,
                                    version=AllocateIPRequest.IPV6,
                                    apn=self._apn0)
        with self.assertRaises(grpc.RpcError) as err:
            self._stub.AllocateIPAddress(request)
        self.assertEqual(err.exception.code(), grpc.StatusCode.UNIMPLEMENTED)

        # ReleaseIPAddress
        release_request = ReleaseIPRequest(
            sid=self._sid0,
            ip=IPAddress(version=IPAddress.IPV6),
            apn=self._apn0)
        with self.assertRaises(grpc.RpcError) as err:
            self._stub.ReleaseIPAddress(release_request)
        self.assertEqual(err.exception.code(), grpc.StatusCode.UNIMPLEMENTED)