/*
* Copyright (c) 2012 Chris Ellison, Mike Deats, Liron Yahdav, Ryan Neal,
* Brandon Sutherlin, Scott Griffin
*
* This software is released under the MIT license
* (http://www.opensource.org/licenses/mit-license.php)
*
* Created on Feb 12, 2012
*/
package edu.cmu.sv.arinc838.validation;
import static org.testng.AssertJUnit.*;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import edu.cmu.sv.arinc838.dao.FileDefinitionDao;
import edu.cmu.sv.arinc838.dao.IntegrityDefinitionDao.IntegrityType;
import edu.cmu.sv.arinc838.dao.SoftwareDefinitionFileDao;
import edu.cmu.sv.arinc838.util.Converter;
public class DataValidatorTest {
private String str64kMax = "";
@BeforeTest
public void beforeTest() {
for (int i = 0; i < 65535; i++) {
str64kMax += "X";
}
}
@Test
public void testValidateUint32() {
assertEquals((long) 0, new DataValidator().validateUint32(0));
assertEquals((long) 1234, new DataValidator().validateUint32(1234));
long max = (long) Math.pow(2, 32);
assertEquals(max, new DataValidator().validateUint32(max));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testValidateUint32Negative() {
new DataValidator().validateUint32(-1);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testValidateUint32OutOfRange() {
new DataValidator().validateUint32(Long.MAX_VALUE);
}
@Test
public void testValidateStr64kBinary() {
String inputStr = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789 -_=+`~'\"[]{}\\|;:,./?!@#$%^*()";
assertTrue(new DataValidator().validateStr64kBinary(inputStr).isEmpty());
assertTrue(str64kMax,
new DataValidator().validateStr64kBinary(str64kMax).isEmpty());
assertTrue(new DataValidator().validateStr64kBinary("").isEmpty());
assertTrue(new DataValidator().validateStr64kBinary("<").isEmpty());
assertTrue(new DataValidator().validateStr64kBinary("hello<")
.isEmpty());
assertTrue(new DataValidator().validateStr64kBinary(">").isEmpty());
assertTrue(new DataValidator().validateStr64kBinary(">there")
.isEmpty());
assertTrue(new DataValidator().validateStr64kBinary("&").isEmpty());
assertTrue(new DataValidator().validateStr64kBinary(
"hello&&there").isEmpty());
}
@Test
public void testValidateStr64kBinaryNonASCII() {
assertEquals(1, new DataValidator().validateStr64kBinary("abc" + (char) 255).size());
}
@Test
public void testValidateStr64kXmlMaxSizeWithEscapedChars() {
// this creates a max-sized string, with an escaped '&' as the last
// character.This will make the absolute length > than the max string
// length, but the true length will be = the max length, and should
// still be valid
String str64kMaxWithEscaped = str64kMax.substring(0,
str64kMax.length() - 1) + "&";
assertTrue(new DataValidator().validateStr64kXml(str64kMaxWithEscaped)
.isEmpty());
}
@Test
public void testValidateStr64kXml() {
String inputStr = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789 -_=+`~'\"[]{}\\|;:,./?!@#$%^*()";
assertTrue(new DataValidator().validateStr64kXml(inputStr).isEmpty());
assertTrue(new DataValidator().validateStr64kXml(str64kMax).isEmpty());
assertTrue(new DataValidator().validateStr64kXml("").isEmpty());
assertTrue(new DataValidator().validateStr64kXml("<").isEmpty());
assertTrue(new DataValidator().validateStr64kXml("hello<").isEmpty());
assertTrue(new DataValidator().validateStr64kXml(">").isEmpty());
assertTrue(new DataValidator().validateStr64kXml(">there").isEmpty());
assertTrue(new DataValidator().validateStr64kXml("&").isEmpty());
assertTrue(new DataValidator().validateStr64kXml("hello&&there")
.isEmpty());
}
@Test
public void testValidateStr64kXmlNonASCII() {
assertEquals(1,
new DataValidator().validateStr64kXml("abc" + (char) 255)
.size());
}
@Test
public void testValidateStr64kXmlWithNonEscapedChars() {
assertEquals(
"Did not throw IllegalArgumentException for non-escaped >", 1,
new DataValidator().validateStr64kXml("1 > 2").size());
assertEquals(
"Did not throw IllegalArgumentException for non-escaped <", 1,
new DataValidator().validateStr64kXml("1 < 2").size());
assertEquals(
"Did not throw IllegalArgumentException for non-escaped &", 1,
new DataValidator().validateStr64kXml("Mumford & Sons").size());
}
@Test
public void testValidateStr64kXmlTooLarge() {
assertEquals(1, new DataValidator().validateStr64kXml(str64kMax + "Y")
.size());
}
@Test
public void testValidateStr64kXmlMultipleErrors() {
// too large, and unescaped XML
assertEquals(2, new DataValidator().validateStr64kXml(str64kMax + "&")
.size());
}
@Test
public void testValidateStr64kBinaryTooLarge() {
assertEquals(1, new DataValidator().validateStr64kBinary(str64kMax + "Y").size());
}
@Test
public void testValidateStr64kBinaryMultipleErrors() {
assertEquals(2, new DataValidator().validateStr64kBinary(str64kMax + (char)255).size());
}
@Test
public void testValidateStr64kXmlNull() {
assertEquals(1, new DataValidator().validateStr64kXml(null).size());
}
@Test
public void testValidateStr64kBinaryNull() {
assertEquals(1, new DataValidator().validateStr64kBinary(null).size());
}
@Test
public void testValidateFileFormatVersion() {
assertEquals(
SoftwareDefinitionFileDao.DEFAULT_FILE_FORMAT_VERSION,
new DataValidator()
.validateFileFormatVersion(SoftwareDefinitionFileDao.DEFAULT_FILE_FORMAT_VERSION
.clone()));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testValidateFileFormatVersionInvalid() {
new DataValidator()
.validateFileFormatVersion(new byte[] { 1, 2, 3, 4 });
}
@Test
public void testValidateIntegrityType() {
assertEquals(IntegrityType.CRC16.getType(),
new DataValidator().validateIntegrityType(IntegrityType.CRC16
.getType()));
assertEquals(IntegrityType.CRC32.getType(),
new DataValidator().validateIntegrityType(IntegrityType.CRC32
.getType()));
assertEquals(IntegrityType.CRC64.getType(),
new DataValidator().validateIntegrityType(IntegrityType.CRC64
.getType()));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testValidateIntegrityTypeInvalid() {
new DataValidator().validateIntegrityType(-1);
}
@Test
public void testValidateIntegrityValue() {
assertEquals(Converter.hexToBytes("ABCD"),
new DataValidator().validateIntegrityValue(Converter
.hexToBytes("ABCD")));
assertEquals(Converter.hexToBytes("ABCDEF01"),
new DataValidator().validateIntegrityValue(Converter
.hexToBytes("ABCDEF01")));
assertEquals(Converter.hexToBytes("DEADBEEFDEADBEEF"),
new DataValidator().validateIntegrityValue(Converter
.hexToBytes("DEADBEEFDEADBEEF")));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testValidateIntegrityValueNull() {
new DataValidator().validateIntegrityValue(null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testValidateIntegrityValueWrongSize() {
new DataValidator().validateIntegrityValue(Converter.hexToBytes("ABC"));
}
@Test
public void testValidateList1() {
List<String> list1 = new ArrayList<String>();
list1.add("hello");
assertEquals(list1, new DataValidator().validateList1(list1));
list1.add("world");
list1.add("!");
assertEquals(list1, new DataValidator().validateList1(list1));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testValidateList1Null() {
new DataValidator().validateList1(null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testValidateList1EmptyList() {
new DataValidator().validateList1(new ArrayList<String>());
}
@Test
public void testValidateSoftwarePartNumber() {
assertEquals("ACM47-1234-5678",
new DataValidator()
.validateSoftwarePartNumber("ACM47-1234-5678"));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testValidateSoftwarePartNumberNull() {
new DataValidator().validateSoftwarePartNumber(null);
}
@Test
public void testValidateSoftwarePartNumberInvalidFormat() {
try {
new DataValidator().validateSoftwarePartNumber("ACM4-7-1234-5678");
fail("Did not fail on invalid format");
} catch (IllegalArgumentException e) {
}
try {
new DataValidator().validateSoftwarePartNumber("ACm47-1234-5678");
fail("Did not fail on lower case letter");
} catch (IllegalArgumentException e) {
}
try {
new DataValidator().validateSoftwarePartNumber("1CM37-1234-5678");
} catch (IllegalArgumentException e) {
fail("Failed incorrectly with a number first " + e.toString());
}
try {
new DataValidator().validateSoftwarePartNumber("ACM23-1234-5678");
fail("Did not fail on invalid check characters");
} catch (IllegalArgumentException e) {
}
try {
new DataValidator().validateSoftwarePartNumber("ACM47-12 34-5678");
fail("Did not fail on embedded spaces");
} catch (IllegalArgumentException e) {
}
try {
new DataValidator().validateSoftwarePartNumber("ACM47-123I-5678");
fail("Did not fail on illegal character I");
} catch (IllegalArgumentException e) {
}
try {
new DataValidator().validateSoftwarePartNumber("ACM47-123Q-5678");
fail("Did not fail on illegal character Q");
} catch (IllegalArgumentException e) {
}
try {
new DataValidator().validateSoftwarePartNumber("ACM47-O234-5678");
fail("Did not fail on illegal character O");
} catch (IllegalArgumentException e) {
}
try {
new DataValidator().validateSoftwarePartNumber("ACM47-1234-5Z78");
fail("Did not fail on illegal character Z");
} catch (IllegalArgumentException e) {
}
}
@Test
public void generateSoftwarePartNumber() {
assertEquals("ACM47-1234-5678",
new DataValidator()
.generateSoftwarePartNumber("ACM??-1234-5678"));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void generateSoftwarePartNumberNull() {
new DataValidator().generateSoftwarePartNumber(null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void generateSoftwarePartNumberInvalid() {
new DataValidator().generateSoftwarePartNumber("ACM47-O234-5678");
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testValidateHexbin32Null() {
new DataValidator().validateHexbin32((byte[]) null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testValidateHexbin32Not4Bytes() {
new DataValidator().validateHexbin32(new byte[] { 1, 2, 3 });
}
@Test
public void testValidateHexbin32() {
byte[] hexBin32 = new byte[] { 1, 2, 3, 4 };
assertEquals(hexBin32, new DataValidator().validateHexbin32(hexBin32));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testValidateHexbin64kNull() {
new DataValidator().validateHexbin64k((byte[]) null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testValidateHexbin64kOutOfRange() {
new DataValidator()
.validateHexbin64k(new byte[DataValidator.HEXBIN64K_MAX_LENGTH + 1]);
}
@Test
public void testValidateHexbin64k() {
byte[] hexBin64k = new byte[DataValidator.HEXBIN64K_MAX_LENGTH];
Arrays.fill(hexBin64k, (byte) 0xAB);
assertEquals(hexBin64k,
new DataValidator().validateHexbin64k(hexBin64k));
}
@Test
public void testValidateDataFileNameNull() {
assertEquals(1, new DataValidator().validateDataFileName(null).size());
}
@Test
public void testValidateDataFileNameTooLong() {
String longName = "";
for (int i = 0; i <= 251; i++) {
longName += "A";
}
longName += ".bin";
assertEquals(1, new DataValidator().validateDataFileName(longName)
.size());
}
@Test
public void testValidateDataFileName() {
assertTrue(new DataValidator().validateDataFileName("someFile.txt")
.isEmpty());
}
@Test
public void testValidateDataFileNameInvalidExtensions() {
DataValidator dataVal = new DataValidator();
for (String extension : DataValidator.INVALID_DATA_FILE_EXTENSIONS) {
assertEquals(
"Did not throw exception for invalid data file extension '"
+ extension.toLowerCase() + "'",
1,
dataVal.validateDataFileName(
"bad_file." + extension.toLowerCase()).size());
assertEquals(
"Did not throw exception for invalid data file extension '"
+ extension.toUpperCase() + "'",
1,
dataVal.validateDataFileName(
"bad_file." + extension.toUpperCase()).size());
}
}
@Test
public void testValidateDataFileNameInvalidCharacters() {
DataValidator dataVal = new DataValidator();
// check invalid characters
for (char invalid : new char[] { '"', '\'', '`', '*', '<', '>', ':',
';', '#', '?', '/', '\\', '|', '~', '!', '@', '$', '%', '^',
'&', '+', '=', ',' }) {
assertEquals("Did not throw exception for invalid character ' "
+ invalid + " '", 1,
dataVal.validateDataFileName("bad" + invalid + "file.txt")
.size());
}
// check whitespace
assertEquals("Did not throw exception for whitespace character", 1,
dataVal.validateDataFileName("bad file.txt").size());
assertEquals("Did not throw exception for whitespace character", 1,
dataVal.validateDataFileName("bad\tfile.txt").size());
assertEquals("Did not throw exception for whitespace character", 1,
dataVal.validateDataFileName("bad \nfile.txt").size());
assertEquals("Did not throw exception for whitespace character", 1,
dataVal.validateDataFileName("bad\rfile.txt").size());
assertEquals("Did not throw exception for whitespace character", 1,
dataVal.validateDataFileName("bad\ffile.txt").size());
}
@Test
public void testValidateDataFileNamesAreUniqueDuplicateNames() {
ArrayList<FileDefinitionDao> files = new ArrayList<FileDefinitionDao>();
FileDefinitionDao f1 = new FileDefinitionDao();
f1.setFileName("abc1.txt");
files.add(f1);
FileDefinitionDao f2 = new FileDefinitionDao();
f2.setFileName("abc2.txt");
files.add(f2);
FileDefinitionDao f3 = new FileDefinitionDao();
f3.setFileName("abc1.txt");
files.add(f3);
List<Exception> errors = new DataValidator()
.validateDataFileNamesAreUnique(files);
assertEquals(1, errors.size());
}
@Test
public void testValidateDataFileNamesAreUnique() {
ArrayList<FileDefinitionDao> files = new ArrayList<FileDefinitionDao>();
FileDefinitionDao f1 = new FileDefinitionDao();
f1.setFileName("abc1.txt");
files.add(f1);
FileDefinitionDao f2 = new FileDefinitionDao();
f2.setFileName("abc2.txt");
files.add(f2);
FileDefinitionDao f3 = new FileDefinitionDao();
f3.setFileName("abc3.txt");
files.add(f3);
List<Exception> errors = new DataValidator()
.validateDataFileNamesAreUnique(files);
assertTrue(errors.isEmpty());
}
@Test
public void testValidateXmlHeaderNamespacesNoErrors () throws Exception {
String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<sdf:sdf-file xmlns:sdf=\"http://www.arinc.com/arinc838\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xsi:schemaLocation=\"http://www.arinc.com/arinc838\"/>";
InputStream inStream = new ByteArrayInputStream(header.getBytes());
XMLStreamReader xsr = XMLInputFactory.newInstance().createXMLStreamReader(inStream);
xsr.nextTag();
List<Exception> errors = new DataValidator().validateXmlHeaderNamespaces(xsr);
assertEquals(0, errors.size());
}
@Test(expectedExceptions = XMLStreamException.class)
public void testValidateXmlHeaderNamespacesTooFew () throws Exception {
String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<sdf:sdf-file xmlns:sdf=\"http://www.arinc.com/arinc838\"" +
" xsi:schemaLocation=\"http://www.arinc.com/arinc838\"/>";
InputStream inStream = new ByteArrayInputStream(header.getBytes());
XMLStreamReader xsr = XMLInputFactory.newInstance().createXMLStreamReader(inStream);
xsr.nextTag();
}
@Test
public void testValidateXmlHeaderNamespacesTooMany () throws Exception {
String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<sdf:sdf-file xmlns:sdf=\"http://www.arinc.com/arinc838\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xmlns:vamps=\"http://www.nosferatu.com\"" +
" xsi:schemaLocation=\"http://www.arinc.com/arinc838\"/>";
InputStream inStream = new ByteArrayInputStream(header.getBytes());
XMLStreamReader xsr = XMLInputFactory.newInstance().createXMLStreamReader(inStream);
xsr.nextTag();
List<Exception> errors = new DataValidator().validateXmlHeaderNamespaces(xsr);
assertEquals(1, errors.size());
assertEquals(IllegalArgumentException.class, errors.get(0).getClass());
}
@Test
public void testValidateXmlHeaderHasStandaloneAttribute() throws Exception {
String header = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<sdf:sdf-file xmlns:sdf=\"http://www.arinc.com/arinc838\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xsi:schemaLocation=\"http://www.arinc.com\"/>";
InputStream inStream = new ByteArrayInputStream(header.getBytes());
XMLStreamReader xsr = XMLInputFactory.newInstance().createXMLStreamReader(inStream);
xsr.nextTag();
List<Exception> errors = new DataValidator().validateXmlHeaderAttributes(xsr);
assertEquals(1, errors.size());
assertEquals(IllegalArgumentException.class, errors.get(0).getClass());
}
@Test
public void testValidateXmlHeaderHasNoStandaloneAttribute() throws Exception {
String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<sdf:sdf-file xmlns:sdf=\"http://www.arinc.com/arinc838\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xsi:schemaLocation=\"http://www.arinc.com\"/>";
InputStream inStream = new ByteArrayInputStream(header.getBytes());
XMLStreamReader xsr = XMLInputFactory.newInstance().createXMLStreamReader(inStream);
xsr.nextTag();
List<Exception> errors = new DataValidator().validateXmlHeaderAttributes(xsr);
assertEquals(0, errors.size());
}
@Test(expectedExceptions = XMLStreamException.class)
public void testValidateXmlHeaderHasBadVersion() throws Exception {
String header = "<?xml version=\"2.0\" encoding=\"UTF-8\"?>" +
"<sdf:sdf-file xmlns:sdf=\"http://www.arinc.com/arinc838\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xsi:schemaLocation=\"http://www.arinc.com\"/>";
InputStream inStream = new ByteArrayInputStream(header.getBytes());
XMLStreamReader xsr = XMLInputFactory.newInstance().createXMLStreamReader(inStream);
xsr.nextTag();
new DataValidator().validateXmlHeaderAttributes(xsr);
}
@Test
public void testValidateXmlHeaderHasBadEncoding() throws Exception {
String header = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" +
"<sdf:sdf-file xmlns:sdf=\"http://www.arinc.com/arinc838\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xsi:schemaLocation=\"http://www.arinc.com\"/>";
InputStream inStream = new ByteArrayInputStream(header.getBytes());
XMLStreamReader xsr = XMLInputFactory.newInstance().createXMLStreamReader(inStream);
xsr.nextTag();
List<Exception> errors = new DataValidator().validateXmlHeaderAttributes(xsr);
assertEquals(1, errors.size());
assertEquals(IllegalArgumentException.class, errors.get(0).getClass());
}
@Test
public void testValidateXmlHeaderAttributesNoErrors () throws Exception {
String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<sdf:sdf-file xmlns:sdf=\"http://www.arinc.com/arinc838\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xsi:schemaLocation=\"http://www.arinc.com\"/>";
InputStream inStream = new ByteArrayInputStream(header.getBytes());
XMLStreamReader xsr = XMLInputFactory.newInstance().createXMLStreamReader(inStream);
xsr.nextTag();
List<Exception> errors = new DataValidator().validateXmlHeaderAttributes(xsr);
assertEquals(0, errors.size());
}
@Test
public void testValidateXmlHeaderAttributesTooFew () throws Exception {
String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<sdf:sdf-file xmlns:sdf=\"http://www.arinc.com/arinc838\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>";
InputStream inStream = new ByteArrayInputStream(header.getBytes());
XMLStreamReader xsr = XMLInputFactory.newInstance().createXMLStreamReader(inStream);
xsr.nextTag();
List<Exception> errors = new DataValidator().validateXmlHeaderAttributes(xsr);
assertEquals(1, errors.size());
}
}