@Override
    public List<UsbSerialPort> getPorts() {
        return mPorts;
    }
@Test
    public void multiPortDevice() throws Exception {
        int n = 2;
        UsbDeviceConnection usbDeviceConnection = mock(UsbDeviceConnection.class);
        UsbDevice usbDevice = mock(UsbDevice.class);
        UsbInterface[] controlInterfaces = new UsbInterface[n];
        UsbInterface[] dataInterfaces = new UsbInterface[n];
        UsbEndpoint[] controlEndpoints = new UsbEndpoint[n];
        UsbEndpoint[] readEndpoints = new UsbEndpoint[n];
        UsbEndpoint[] writeEndpoints = new UsbEndpoint[n];

        /*
         * pi zero - dual port
         *   UsbInterface[mId=0,mAlternateSetting=0,mName=TinyUSB CDC,mClass=2,mSubclass=2,mProtocol=0,mEndpoints=[
         *     UsbEndpoint[mAddress=129,mAttributes=3,mMaxPacketSize=8,mInterval=16]]
         *   UsbInterface[mId=1,mAlternateSetting=0,mName=null,mClass=10,mSubclass=0,mProtocol=0,mEndpoints=[
         *     UsbEndpoint[mAddress=2,mAttributes=2,mMaxPacketSize=64,mInterval=0]
         *     UsbEndpoint[mAddress=130,mAttributes=2,mMaxPacketSize=64,mInterval=0]]
         *   UsbInterface[mId=2,mAlternateSetting=0,mName=TinyUSB CDC,mClass=2,mSubclass=2,mProtocol=0,mEndpoints=[
         *     UsbEndpoint[mAddress=131,mAttributes=3,mMaxPacketSize=8,mInterval=16]]
         *   UsbInterface[mId=3,mAlternateSetting=0,mName=null,mClass=10,mSubclass=0,mProtocol=0,mEndpoints=[
         *     UsbEndpoint[mAddress=4,mAttributes=2,mMaxPacketSize=64,mInterval=0]
         *      UsbEndpoint[mAddress=132,mAttributes=2,mMaxPacketSize=64,mInterval=0]]
         */
        when(usbDeviceConnection.getRawDescriptors()).thenReturn(HexDump.hexStringToByteArray(
                "12 01 00 02 EF 02 01 40 FE CA 02 40 00 01 01 02 03 01\n" +
                "09 02 8D 00 04 01 00 80 32\n" +
                "08 0B 00 02 02 02 00 00\n" +
                "09 04 00 00 01 02 02 00 04\n" +
                "05 24 00 20 01\n" +
                "05 24 01 00 01\n" +
                "04 24 02 02\n" +
                "05 24 06 00 01\n" +
                "07 05 81 03 08 00 10\n" +
                "09 04 01 00 02 0A 00 00 00\n" +
                "07 05 02 02 40 00 00\n" +
                "07 05 82 02 40 00 00\n" +
                "08 0B 02 02 02 02 00 00\n" +
                "09 04 02 00 01 02 02 00 04\n" +
                "05 24 00 20 01\n" +
                "05 24 01 00 03\n" +
                "04 24 02 02\n" +
                "05 24 06 02 03\n" +
                "07 05 83 03 08 00 10\n" +
                "09 04 03 00 02 0A 00 00 00\n" +
                "07 05 04 02 40 00 00\n" +
                "07 05 84 02 40 00 00\n"));
        when(usbDevice.getInterfaceCount()).thenReturn(2*n);
        for(int i=0; i<n; i++) {
            controlInterfaces[i] = mock(UsbInterface.class);
            dataInterfaces[i] = mock(UsbInterface.class);
            controlEndpoints[i] = mock(UsbEndpoint.class);
            readEndpoints[i] = mock(UsbEndpoint.class);
            writeEndpoints[i] = mock(UsbEndpoint.class);
            when(usbDeviceConnection.claimInterface(controlInterfaces[i], true)).thenReturn(true);
            when(usbDeviceConnection.claimInterface(dataInterfaces[i], true)).thenReturn(true);
            when(usbDevice.getInterface(2*i  )).thenReturn(controlInterfaces[i]);
            when(usbDevice.getInterface(2*i+1)).thenReturn(dataInterfaces[i]);
            when(controlInterfaces[i].getId()).thenReturn(2*i);
            when(controlInterfaces[i].getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_COMM);
            when(controlInterfaces[i].getInterfaceSubclass()).thenReturn(USB_SUBCLASS_ACM);
            when(controlInterfaces[i].getEndpointCount()).thenReturn(1);
            when(controlInterfaces[i].getEndpoint(0)).thenReturn(controlEndpoints[i]);
            when(dataInterfaces[i].getId()).thenReturn(2*i+1);
            when(dataInterfaces[i].getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
            when(dataInterfaces[i].getEndpointCount()).thenReturn(2);
            when(dataInterfaces[i].getEndpoint(0)).thenReturn(writeEndpoints[i]);
            when(dataInterfaces[i].getEndpoint(1)).thenReturn(readEndpoints[i]);
            when(controlEndpoints[i].getDirection()).thenReturn(UsbConstants.USB_DIR_IN);
            when(controlEndpoints[i].getType()).thenReturn(UsbConstants.USB_ENDPOINT_XFER_INT);
            when(readEndpoints[i].getDirection()).thenReturn(UsbConstants.USB_DIR_IN);
            when(readEndpoints[i].getType()).thenReturn(UsbConstants.USB_ENDPOINT_XFER_BULK);
            when(writeEndpoints[i].getDirection()).thenReturn(UsbConstants.USB_DIR_OUT);
            when(writeEndpoints[i].getType()).thenReturn(UsbConstants.USB_ENDPOINT_XFER_BULK);
        }
        int i = 1;
        CdcAcmSerialDriver driver = new CdcAcmSerialDriver(usbDevice);
        CdcAcmSerialDriver.CdcAcmSerialPort port = (CdcAcmSerialDriver.CdcAcmSerialPort) driver.getPorts().get(i);
        port.mConnection = usbDeviceConnection;
        // reset invocations from countPorts()
        clearInvocations(controlInterfaces[0]);
        clearInvocations(controlInterfaces[1]);

        port.openInt();
        assertEquals(readEndpoints[i], port.mReadEndpoint);
        assertEquals(writeEndpoints[i], port.mWriteEndpoint);
        verify(controlInterfaces[0], times(0)).getInterfaceClass(); // not openInterface with 'no IAD fallback'
        verify(controlInterfaces[1], times(2)).getInterfaceClass(); // openInterface with IAD
        port.closeInt();
        clearInvocations(controlInterfaces[0]);
        clearInvocations(controlInterfaces[1]);

        when(usbDeviceConnection.getRawDescriptors()).thenReturn(null);
        port.openInt();
        verify(controlInterfaces[0], times(2)).getInterfaceClass(); // openInterface with 'no IAD fallback'
        verify(controlInterfaces[1], times(2)).getInterfaceClass(); // openInterface with 'no IAD fallback'
        port.closeInt();
        clearInvocations(controlInterfaces[0]);
        clearInvocations(controlInterfaces[1]);

        when(usbDeviceConnection.getRawDescriptors()).thenReturn(HexDump.hexStringToByteArray("01 02 02 82 02")); // truncated descriptor
        port.openInt();
        verify(controlInterfaces[0], times(2)).getInterfaceClass(); // openInterface with 'no IAD fallback'
        verify(controlInterfaces[1], times(2)).getInterfaceClass(); // openInterface with 'no IAD fallback'
    }