Skip to content

Commit

Permalink
Fixed "AVR"/text format parsing.
Browse files Browse the repository at this point in the history
Virtual Radar Server does this thing where it prepends 25 NULs to the
text test cases. I do not know why :(

Added beginnings of text test cases.
  • Loading branch information
wiseman committed May 28, 2016
1 parent 107a6f2 commit 1692650
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.LinkedList;

/**
Expand Down Expand Up @@ -49,7 +49,7 @@ public BeastMessageParser() {
* Scans a byte array for Mode S beast messages. Returns a
* collection of extracted Mode S payloads.
*/
public Collection<ExtractedBytes> parse(byte[] bytes, int offset, int bytesRead) {
public List<ExtractedBytes> parse(byte[] bytes, int offset, int bytesRead) {
LinkedList<ExtractedBytes> result = new LinkedList<>();
int length = readBufferLength + bytesRead;
if (readBuffer == null || length > readBuffer.length) {
Expand All @@ -74,9 +74,6 @@ public Collection<ExtractedBytes> parse(byte[] bytes, int offset, int bytesRead)
int signalLevel = -1;
if (!isBinaryFormat) {
endOfPacket = ArrayUtils.indexOf(readBuffer, (byte) ';', startOfPacket);
if (endOfPacket >= (readBufferLength - startOfPacket)) {
endOfPacket = ArrayUtils.INDEX_NOT_FOUND;
}
} else {
ExtractResult extractResult = extractBinaryPayload(startOfPacket, dataLength);
endOfPacket = extractResult.endOfPacket;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ public class BeastMessageParserTest {
*/
@Parameterized.Parameters
public static Collection<Object[]> loadTests() {
Collection<TestSpec> specs = TestSpec.readFromFile("beast-binary-test-cases.yaml");
Collection<TestSpec> specs = TestSpec.readFromFile("beast-binary-test-cases.yaml", true);
specs.addAll(TestSpec.readFromFile("beast-text-test-cases.yaml", false));
return specs.stream()
.map(s -> new Object[] { s, null })
.collect(Collectors.toList());
// Junit parameters are <?, ?> pairs.
.map(s -> new Object[] { s, null })
.collect(Collectors.toList());
}

public BeastMessageParserTest(TestSpec spec, Object ignore) {
Expand All @@ -41,63 +43,33 @@ public void checkTestSpec() {
TestSpec spec = testSpec;
System.err.println("Test: " + spec.comment);
BeastMessageParser parser = new BeastMessageParser();
ExtractedBytes e1 = null;
List<ExtractedBytes> extracteds = getExtractedBytesForPackets(
parser,
spec.packet1,
spec.packet2);
if (extracteds.size() > 0) {
e1 = extracteds.get(0);
}
if (spec.extracted1 != null) {
assertNotNull(spec.comment, e1);
assertArrayEquals(
desc(spec.comment, spec.extracted1, e1.getByteArray()),
spec.extracted1, e1.getByteArray());
assertEquals(spec.comment, spec.hasParity1, e1.hasParity);
assertEquals(spec.comment, spec.badChecksum1, e1.badChecksum);
if (spec.signalLevel1 != null) {
assertEquals(spec.comment, spec.signalLevel1.intValue(), e1.signalLevel);
} else {
assertEquals(spec.comment, -1, e1.signalLevel);
}
assertEquals(spec.comment, spec.isMlat1, e1.isMlat);
}
ExtractedBytes e2 = null;
if (extracteds.size() > 1) {
e2 = extracteds.get(1);
}
if (spec.extracted2 != null) {
assertNotNull(e2);
assertArrayEquals(
desc(spec.comment, spec.extracted2, e2.getByteArray()),
spec.extracted2, e2.getByteArray());
assertEquals(spec.hasParity2, e2.hasParity);
assertEquals(spec.badChecksum2, e2.badChecksum);
if (spec.signalLevel2 != null) {
assertEquals(spec.signalLevel2.intValue(), e2.signalLevel);
} else {
assertEquals(-1, e2.signalLevel);
}
assertEquals(spec.isMlat2, e2.isMlat);
} else {
assertNull(e2);
List<ExtractedBytes> expectedOutputs = spec.expectedOutputs;
List<ExtractedBytes> outputs = getExtractedBytesForPackets(parser, spec.inputs);
assertEquals(spec.comment, expectedOutputs.size(), outputs.size());

for (int i = 0; i < outputs.size(); i++) {
ExtractedBytes output = outputs.get(i);
ExtractedBytes expectedOutput = expectedOutputs.get(i);
assertArrayEquals(
desc(spec.comment,
expectedOutput.getByteArray(),
output.getByteArray()),
expectedOutput.getByteArray(), output.getByteArray());
assertEquals(spec.comment, expectedOutput.hasParity, output.hasParity);
assertEquals(spec.comment, expectedOutput.badChecksum, output.badChecksum);
assertEquals(spec.comment, expectedOutput.signalLevel, output.signalLevel);
assertEquals(spec.comment, expectedOutput.isMlat, output.isMlat);
}
}

private List<ExtractedBytes> getExtractedBytesForPackets(
BeastMessageParser parser, byte[] packet1, byte[] packet2) {
Collection<ExtractedBytes> extracteds1 = parser.parse(packet1, 0, packet1.length);
Collection<ExtractedBytes> extracteds2 = null;
if (packet2 != null) {
extracteds2 = parser.parse(packet2, 0, packet2.length);
} else {
extracteds2 = new LinkedList<ExtractedBytes>();
}
Stream<ExtractedBytes> extracteds = Stream.concat(
extracteds1.stream(),
extracteds2.stream());
return extracteds.collect(Collectors.toList());
BeastMessageParser parser, Collection<byte[]> packets) {
List<ExtractedBytes> outputs = new LinkedList<>();
for (byte[] packet : packets) {
List<ExtractedBytes> extracteds = parser.parse(packet, 0, packet.length);
outputs.addAll(extracteds);
}
return outputs;
}

private String desc(String comment, byte[] bytes1, byte[] bytes2) {
Expand Down
73 changes: 47 additions & 26 deletions src/test/java/com/lemondronor/modesbeast/TestSpec.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,57 @@

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class TestSpec {
public byte[] packet1;
public byte[] packet2;
public byte[] extracted1;
public Boolean hasParity1;
public Boolean badChecksum1;
public Integer signalLevel1;
public Boolean isMlat1;
public byte[] extracted2;
public Boolean hasParity2;
public Boolean badChecksum2;
public Integer signalLevel2;
public Boolean isMlat2;
public String comment;
public List<byte[]> inputs;
public List<ExtractedBytes> expectedOutputs;

/**
* Reads a test suite from a YAML file.
*/
public static Collection<TestSpec> readFromFile(String path) {
public static Collection<TestSpec> readFromFile(String path, boolean isBinary) {
LinkedList<TestSpec> specs = new LinkedList<>();
Yaml yaml = new Yaml();
Collection<Map<String,Object>> descriptions = (Collection) yaml.load(
TestSpec.class.getClassLoader().getResourceAsStream(path));
System.err.println(descriptions.getClass());
for (Map<String,Object> desc : descriptions) {
TestSpec spec = new TestSpec();
spec.packet1 = parsePacket((String)desc.get("Packet1"));
spec.packet2 = parsePacket((String)desc.get("Packet2"));
spec.extracted1 = parsePacket((String)desc.get("Extracted1"));
spec.hasParity1 = (Boolean)desc.get("HasParity1");
spec.badChecksum1 = (Boolean)desc.get("BadChecksum1");
spec.signalLevel1 = (Integer)desc.get("SignalLevel1");
spec.isMlat1 = (Boolean)desc.get("IsMlat1");
spec.extracted2 = parsePacket((String)desc.get("Extracted2"));
spec.hasParity2 = (Boolean)desc.get("HasParity2");
spec.badChecksum2 = (Boolean)desc.get("BadChecksum2");
spec.signalLevel2 = (Integer)desc.get("SignalLevel2");
spec.isMlat2 = (Boolean)desc.get("IsMlat2");
spec.comment = (String) desc.get("Comment");
LinkedList<byte[]> inputs = new LinkedList<byte[]>();
for (int i = 1; i <= 3; i++) {
String inputSpec = (String)desc.get("Packet" + i);
if (inputSpec != null) {
if (isBinary) {
inputs.add(parsePacket(inputSpec));
} else {
inputs.add(prependPacket(inputSpec.getBytes()));
}
}
}
spec.inputs = inputs;
LinkedList<ExtractedBytes> expectedOutputs = new LinkedList<ExtractedBytes>();
for (int i = 1; i <= 3; i++) {
ExtractedBytes expectedOutput = new ExtractedBytes();
String extracted = (String)desc.get("Extracted" + i);
if (extracted == null) {
break;
}
expectedOutput.bytes(parsePacket(extracted));
expectedOutput.hasParity((Boolean)desc.get("HasParity" + i));
expectedOutput.badChecksum((Boolean)desc.get("BadChecksum" + i));
Integer signalLevel = (Integer)desc.get("SignalLevel" + i);
if (signalLevel != null) {
expectedOutput.signalLevel(signalLevel);
} else {
expectedOutput.signalLevel(-1);
}
expectedOutput.isMlat((Boolean)desc.get("IsMlat" + i));
expectedOutputs.add(expectedOutput);
}
spec.expectedOutputs = expectedOutputs;
specs.add(spec);
}
return specs;
Expand All @@ -57,4 +67,15 @@ private static byte[] parsePacket(String text) {
return BeastMessageParser.hexStringToByteArray(text.replace(" ", ""));
}
}

private static byte[] prependPacket(byte[] bytes) {
byte[] newBytes = new byte[bytes.length + 25];
for (int i = 0; i < 25; i++) {
newBytes[i] = 0;
}
for (int i = 0; i < bytes.length; i++) {
newBytes[i + 25] = bytes[i];
}
return newBytes;
}
}
22 changes: 22 additions & 0 deletions src/test/resources/beast-text-test-cases.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-
Packet1: "*02E99619FACDAE;"
Packet2:
Extracted1: 02 E9 96 19 FA CD AE
HasParity1: true
BadChecksum1: false
IsMlat1: false
Extracted2:
HasParity2:
BadChecksum2:
Comment: Standard AVR format short frame
-
Packet1: "1; *02E99619FACDAE;"
Packet2:
Extracted1: 02 E9 96 19 FA CD AE
HasParity1: true
BadChecksum1: false
IsMlat1: false
Extracted2:
HasParity2:
BadChecksum2:
Comment: Standard AVR format with garbage before start

0 comments on commit 1692650

Please sign in to comment.