1
0
mirror of https://github.com/mik3y/usb-serial-for-android synced 2025-06-07 07:56:20 +00:00

slightly more coverage, local coverage report, dependency update

This commit is contained in:
kai-morich 2020-10-12 21:14:06 +02:00
parent 08a93ec530
commit 1e75f91467
8 changed files with 100 additions and 63 deletions

View File

@ -6,7 +6,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath 'com.android.tools.build:gradle:4.0.2'
}
}

View File

@ -11,7 +11,7 @@ android {
defaultConfig {
minSdkVersion 17
targetSdkVersion 28
targetSdkVersion 29
vectorDrawables.useSupportLibrary = true
testInstrumentationRunner "android.test.InstrumentationTestRunner"
@ -27,6 +27,6 @@ android {
dependencies {
implementation project(':usbSerialForAndroid')
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
}

View File

@ -6,7 +6,7 @@ android {
defaultConfig {
minSdkVersion 17
targetSdkVersion 28
targetSdkVersion 29
consumerProguardFiles 'proguard-rules.pro'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
@ -26,7 +26,7 @@ dependencies {
androidTestImplementation 'com.android.support:support-annotations:28.0.0'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'commons-net:commons-net:3.6'
androidTestImplementation 'org.apache.commons:commons-lang3:3.8.1' // starting with 3.9 requires min-api 26
androidTestImplementation 'org.apache.commons:commons-lang3:3.11'
}
//apply from: 'publishToMavenLocal.gradle'

View File

@ -1,3 +1,4 @@
// see https://github.com/mik3y/usb-serial-for-android/wiki/Device-Tests-&-Coverage-Report for instructions
apply plugin: 'jacoco'
android {
@ -43,9 +44,27 @@ android {
}
}
}
// create report even if tests fail
project.gradle.taskGraph.whenReady {
-> project.tasks.findAll { it.name =~ /connected.+AndroidTest/ }.each {
it.ignoreFailures = true
}
}
task jacocoTestReport(type: JacocoReport /*, dependsOn: ['testDebugUnitTest', 'createAnyDeviceDebugCoverageReport']*/) {
reports {
xml.enabled = false
html.enabled = true
}
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*']
def debugTree = fileTree(dir: "$project.buildDir/intermediates/javac/debug", excludes: fileFilter)
def mainSrc = "$project.projectDir/src/main/java"
sourceDirectories.from files([mainSrc])
classDirectories.from files([debugTree])
executionData.from fileTree(dir: project.buildDir, includes: [
'jacoco/testDebugUnitTest.exec', 'outputs/code_coverage/*AndroidTest/connected/*.ec'
])
}

View File

@ -62,12 +62,12 @@ public class CrossoverTest {
if (availableDrivers.size() == 0) {
fail("no USB device found");
} else if (availableDrivers.size() == 1) {
assertEquals(2, availableDrivers.get(0).getPorts().size());
assertEquals("expected device with 2 ports.", 2, availableDrivers.get(0).getPorts().size());
usb1 = new UsbWrapper(context, availableDrivers.get(0), 0);
usb2 = new UsbWrapper(context, availableDrivers.get(0), 1);
} else {
assertEquals(1, availableDrivers.get(0).getPorts().size());
assertEquals(1, availableDrivers.get(1).getPorts().size());
assertEquals("expected 2 devices with 1 port.", 1, availableDrivers.get(0).getPorts().size());
assertEquals("expected 2 devices with 1 port.", 1, availableDrivers.get(1).getPorts().size());
usb1 = new UsbWrapper(context, availableDrivers.get(0), 0);
usb2 = new UsbWrapper(context, availableDrivers.get(1), 0);
}

View File

@ -364,7 +364,7 @@ public class DeviceTest {
try {
usb.setParameters(183, 8, 1, UsbSerialPort.PARITY_NONE);
fail("baud rate to low expected");
} catch (IOException ignored) {
} catch (UnsupportedOperationException ignored) {
}
usb.setParameters(184, 8, 1, UsbSerialPort.PARITY_NONE);
usb.setParameters( 960000, 8, 1, UsbSerialPort.PARITY_NONE);
@ -380,7 +380,7 @@ public class DeviceTest {
try {
usb.setParameters((int)(2000000/1.04), 8, 1, UsbSerialPort.PARITY_NONE);
fail("baud rate error expected");
} catch (IOException ignored) {
} catch (UnsupportedOperationException ignored) {
}
usb.setParameters((int)(2000000/1.03), 8, 1, UsbSerialPort.PARITY_NONE);
usb.setParameters(2000000, 8, 1, UsbSerialPort.PARITY_NONE);
@ -388,14 +388,14 @@ public class DeviceTest {
try {
usb.setParameters((int)(2000000*1.04), 8, 1, UsbSerialPort.PARITY_NONE);
fail("baud rate error expected");
} catch (IOException ignored) {
} catch (UnsupportedOperationException ignored) {
}
usb.setParameters(2000000, 8, 1, UsbSerialPort.PARITY_NONE);
usb.setParameters(3000000, 8, 1, UsbSerialPort.PARITY_NONE);
try {
usb.setParameters(4000000, 8, 1, UsbSerialPort.PARITY_NONE);
fail("baud rate to high expected");
} catch (IOException ignored) {
} catch (UnsupportedOperationException ignored) {
}
}
@ -922,7 +922,7 @@ public class DeviceTest {
if (usb.serialDriver instanceof Cp21xxSerialDriver && usb.serialDriver.getPorts().size() == 1)
Assert.assertNotEquals(0, data.length); // can be shorter or full length
else if (usb.serialDriver instanceof ProlificSerialDriver)
Assert.assertTrue("expected > 0 and < 16 byte, got " + data.length, data.length > 0 && data.length < 16);
Assert.assertTrue("sporadic issue! expected > 0 and < 16 byte, got " + data.length, data.length > 0 && data.length < 16);
else // ftdi, ch340, cp2105
Assert.assertEquals(0, data.length);
telnet.write("2ccc".getBytes());
@ -998,7 +998,7 @@ public class DeviceTest {
public void readSpeed() throws Exception {
// see logcat for performance results
//
// CDC arduino_leonardo_bridge.ini has transfer speed ~ 100 byte/sec
// CDC arduino_leonardo_bridge.ino has transfer speed ~ 100 byte/sec
// all other devices are near physical limit with ~ 10-12k/sec
//
// readBufferOverflow provokes read errors, but they can also happen here where the data is actually read fast enough.
@ -1068,7 +1068,7 @@ public class DeviceTest {
public void writeSpeed() throws Exception {
// see logcat for performance results
//
// CDC arduino_leonardo_bridge.ini has transfer speed ~ 100 byte/sec
// CDC arduino_leonardo_bridge.ino has transfer speed ~ 100 byte/sec
// all other devices can get near physical limit:
// longlines=true:, speed is near physical limit at 11.5k
// longlines=false: speed is 3-4k for all devices, as more USB packets are required
@ -1194,8 +1194,6 @@ public class DeviceTest {
usb.ioManager = new SerialInputOutputManager(usb.serialPort, usb);
assertEquals(usb, usb.ioManager.getListener());
usb.ioManager.setThreadPriority(Process.THREAD_PRIORITY_AUDIO);
assertEquals(0, usb.ioManager.getReadTimeout());
usb.ioManager.setReadTimeout(10);
assertEquals(10, usb.ioManager.getReadTimeout());
@ -1210,10 +1208,22 @@ public class DeviceTest {
usb.ioManager.setWriteBufferSize(13);
assertEquals(13, usb.ioManager.getWriteBufferSize());
usb.open(); // creates new IoManager
usb.ioManager.setReadBufferSize(usb.ioManager.getReadBufferSize());
usb.ioManager.setWriteBufferSize(usb.ioManager.getWriteBufferSize());
usb.ioManager.setReadTimeout(usb.ioManager.getReadTimeout());
usb.ioManager.setWriteTimeout(usb.ioManager.getWriteTimeout());
usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_START)); // creates new IoManager
usb.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
telnet.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
usb.ioManager.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
usb.startIoManager();
usb.waitForIoManagerStarted();
try {
usb.ioManager.run();
fail("already running error expected");
} catch (IllegalStateException ignored) {
}
try {
usb.ioManager.setThreadPriority(Process.THREAD_PRIORITY_LOWEST);
fail("setThreadPriority IllegalStateException expected");
@ -1384,7 +1394,7 @@ public class DeviceTest {
// date loss with high transfer rate and short read timeout !!!
diffLen = readSpeedInt(5, -1, shortTimeout);
assertNotEquals(0, diffLen);
assertNotEquals("sporadic issue!", 0, diffLen);
// data loss observed with read timeout up to 200 msec, e.g.
// difference at 181 len 64
@ -1791,9 +1801,15 @@ public class DeviceTest {
} catch (UnsupportedOperationException ignored) {
}
if(purged) {
usb.serialPort.purgeHwBuffers(false, false);
try {
usb.serialPort.purgeHwBuffers(true, true);
fail("purgeHwBuffers error expected");
usb.serialPort.purgeHwBuffers(true, false);
fail("purgeHwBuffers(write) error expected");
} catch (IOException ignored) {
}
try {
usb.serialPort.purgeHwBuffers(false, true);
fail("purgeHwBuffers(read) error expected");
} catch (IOException ignored) {
}
}
@ -1845,10 +1861,10 @@ public class DeviceTest {
} catch (IOException ignored) {
}
try {
usb.ioManager.run();
fail("already running error expected");
} catch (IllegalStateException ignored) {
}
byte[] buffer = new byte[0];
usb.serialPort.read(buffer, UsbWrapper.USB_READ_WAIT);
fail("read buffer to small expected");
} catch(IllegalArgumentException ignored) {}
}
@Test
@ -1876,5 +1892,16 @@ public class DeviceTest {
ftdiSerialPort.setLatencyTimer(lt);
assertEquals("latency 1", 99, Math.max(t2-t1, 99)); // looks strange, but shows actual value
assertEquals("latency 100", 99, Math.min(t3-t2, 99));
usb.deviceConnection.close();
try {
ftdiSerialPort.getLatencyTimer();
fail("getLatencyTimer error expected");
} catch (IOException ignored) {}
usb.deviceConnection.close();
try {
ftdiSerialPort.setLatencyTimer(1);
fail("setLatencyTimer error expected");
} catch (IOException ignored) {}
}
}

View File

@ -9,6 +9,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import static org.junit.Assert.assertEquals;
@ -31,7 +32,7 @@ public class TelnetWrapper {
private TelnetClient telnetClient;
private InputStream readStream;
private OutputStream writeStream;
private Integer[] comPortOptionCounter = {0};
private ArrayList<int[]> commandResponse = new ArrayList<>();
public int writeDelay = 0;
public TelnetWrapper(String host, int port) {
@ -47,7 +48,9 @@ public class TelnetWrapper {
telnetClient.addOptionHandler(new TelnetOptionHandler(RFC2217_COM_PORT_OPTION, false, false, false, false) {
@Override
public int[] answerSubnegotiation(int[] suboptionData, int suboptionLength) {
comPortOptionCounter[0] += 1;
int[] data = new int[suboptionLength];
System.arraycopy(suboptionData, 0, data, 0, suboptionLength);
commandResponse.add(data);
return super.answerSubnegotiation(suboptionData, suboptionLength);
}
});
@ -59,18 +62,25 @@ public class TelnetWrapper {
readStream = telnetClient.getInputStream();
}
private int[] doCommand(String name, byte[] command) throws IOException, InterruptedException {
commandResponse.clear();
telnetClient.sendCommand((byte) TelnetCommand.SB);
writeStream.write(command);
telnetClient.sendCommand((byte)TelnetCommand.SE);
for(int i=0; i<TELNET_COMMAND_WAIT; i++) {
if(commandResponse.size() > 0) break;
Thread.sleep(1);
}
assertEquals("RFC2217 " + name+ " w/o response.", 1, commandResponse.size());
//Log.d(TAG, name + " -> " + Arrays.toString(commandResponse.get(0)));
return commandResponse.get(0);
}
public void setUp() throws Exception {
setUpFixtureInt();
telnetClient.sendAYT(1000); // not correctly handled by rfc2217_server.py, but WARNING output "ignoring Telnet command: '\xf6'" is a nice separator between tests
comPortOptionCounter[0] = 0;
telnetClient.sendCommand((byte)TelnetCommand.SB);
writeStream.write(new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_PURGE_DATA, 3});
telnetClient.sendCommand((byte)TelnetCommand.SE);
for(int i=0; i<TELNET_COMMAND_WAIT; i++) {
if(comPortOptionCounter[0] == 1) break;
Thread.sleep(1);
}
assertEquals("telnet connection lost", 1, comPortOptionCounter[0].intValue());
doCommand("purge-data", new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_PURGE_DATA, 3});
writeDelay = 0;
}
@ -131,29 +141,10 @@ public class TelnetWrapper {
}
public void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException, InterruptedException, InvalidTelnetOptionException {
comPortOptionCounter[0] = 0;
telnetClient.sendCommand((byte) TelnetCommand.SB);
writeStream.write(new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_SET_BAUDRATE, (byte)(baudRate>>24), (byte)(baudRate>>16), (byte)(baudRate>>8), (byte)baudRate});
telnetClient.sendCommand((byte)TelnetCommand.SE);
telnetClient.sendCommand((byte)TelnetCommand.SB);
writeStream.write(new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_SET_DATASIZE, (byte)dataBits});
telnetClient.sendCommand((byte)TelnetCommand.SE);
telnetClient.sendCommand((byte)TelnetCommand.SB);
writeStream.write(new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_SET_STOPSIZE, (byte)stopBits});
telnetClient.sendCommand((byte)TelnetCommand.SE);
telnetClient.sendCommand((byte)TelnetCommand.SB);
writeStream.write(new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_SET_PARITY, (byte)(parity+1)});
telnetClient.sendCommand((byte)TelnetCommand.SE);
// windows does not like nonstandard baudrates. rfc2217_server.py terminates w/o response
for(int i=0; i<TELNET_COMMAND_WAIT; i++) {
if(comPortOptionCounter[0] == 4) break;
Thread.sleep(1);
}
assertEquals("telnet connection lost", 4, comPortOptionCounter[0].intValue());
doCommand("set-baudrate", new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_SET_BAUDRATE, (byte)(baudRate>>24), (byte)(baudRate>>16), (byte)(baudRate>>8), (byte)baudRate});
doCommand("set-datasize", new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_SET_DATASIZE, (byte)dataBits});
doCommand("set-stopsize", new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_SET_STOPSIZE, (byte)stopBits});
doCommand("set-parity", new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_SET_PARITY, (byte)(parity+1)});
}
}

View File

@ -33,8 +33,8 @@ import static org.junit.Assert.fail;
public class UsbWrapper implements SerialInputOutputManager.Listener {
private final static int USB_READ_WAIT = 500;
private final static int USB_WRITE_WAIT = 500;
public final static int USB_READ_WAIT = 500;
public final static int USB_WRITE_WAIT = 500;
private static final String TAG = UsbWrapper.class.getSimpleName();
public enum OpenCloseFlags { NO_IOMANAGER_THREAD, NO_IOMANAGER_START, NO_CONTROL_LINE_INIT, NO_DEVICE_CONNECTION };