/*
* TeleStax, Open Source Cloud Communications
* Copyright 2012, Telestax Inc and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
/**
* Start time:09:16:42 2009-04-22<br>
* Project: mobicents-isup-stack<br>
*
* @author <a href="mailto:baranowb@gmail.com">Bartosz Baranowski
* </a>
*
*/
package org.mobicents.protocols.ss7.isup.impl.message.parameter;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.mobicents.protocols.ss7.isup.ParameterException;
import org.testng.annotations.Test;
/**
* Start time:09:16:42 2009-04-22<br>
* Project: mobicents-isup-stack<br>
*
* @author <a href="mailto:baranowb@gmail.com">Bartosz Baranowski </a>
*/
public abstract class ParameterHarness {
// 21 10000011 Address....................... 83
// 22 01100000 Address....................... 60
// 23 00111000 Address....................... 38
// NOTE: now see how nice digits swap can come out with conversion, lol
private static final byte[] sixDigits = new byte[] { (byte) 0x83, 0x60, 0x38 };
private static final byte[] fiveDigits = new byte[] { (byte) 0x83, 0x60, 0x08 };
private static final byte[] sevenDigits = new byte[] { (byte) 0x83, 0x60, 0x33, 0x08 };
private static final byte[] eightDigits = new byte[] { (byte) 0x83, 0x60, 0x33, 0x48 };
private static final byte[] threeDigits = new byte[] { (byte) 0x83, 0x0 };;
private static final String sixDigitsString = "380683";
private static final String fiveDigitsString = "38068";
private static final String sevenDigitsString = "3806338";
private static final String eightDigitsString = "38063384";
private static final String threeDigitsString = "380";
// FIXME: add code to check values :)
protected List<byte[]> goodBodies = new ArrayList<byte[]>();
protected List<byte[]> badBodies = new ArrayList<byte[]>();
protected String dumpData(byte[] b) {
String s = "\n";
for (byte bb : b) {
s += Integer.toHexString(bb & 0xFF)+"\n";
}
return s;
}
protected String makeCompare(byte[] hardcodedBody, byte[] elementEncoded) {
int totalLength = 0;
if (hardcodedBody == null || elementEncoded == null) {
return "One arg is null";
}
if (hardcodedBody.length >= elementEncoded.length) {
totalLength = hardcodedBody.length;
} else {
totalLength = elementEncoded.length;
}
String out = "";
for (int index = 0; index < totalLength; index++) {
if (hardcodedBody.length > index) {
out += "hardcodedBody[" + Integer.toHexString(hardcodedBody[index]) + "]";
} else {
out += "hardcodedBody[NOP]";
}
if (elementEncoded.length > index) {
out += "elementEncoded[" + Integer.toHexString(elementEncoded[index]) + "]";
} else {
out += "elementEncoded[NOP]";
}
out += "\n";
}
return out;
}
public String makeCompare(int[] hardcodedBody, int[] elementEncoded) {
int totalLength = 0;
if (hardcodedBody == null || elementEncoded == null) {
return "One arg is null";
}
if (hardcodedBody.length >= elementEncoded.length) {
totalLength = hardcodedBody.length;
} else {
totalLength = elementEncoded.length;
}
String out = "";
for (int index = 0; index < totalLength; index++) {
if (hardcodedBody.length > index) {
out += "hardcodedBody[" + Integer.toHexString(hardcodedBody[index]) + "]";
} else {
out += "hardcodedBody[NOP]";
}
if (elementEncoded.length > index) {
out += "elementEncoded[" + Integer.toHexString(elementEncoded[index]) + "]";
} else {
out += "elementEncoded[NOP]";
}
out += "\n";
}
return out;
}
protected String makeCompare(Object hardcodedBody, Object elementEncoded) {
int totalLength = 0;
if (hardcodedBody == null || elementEncoded == null) {
return "One arg is null";
}
if (Array.getLength(hardcodedBody) >= Array.getLength(elementEncoded)) {
totalLength = Array.getLength(hardcodedBody);
} else {
totalLength = Array.getLength(elementEncoded);
}
String out = "";
for (int index = 0; index < totalLength; index++) {
if (Array.getLength(hardcodedBody) > index) {
out += "hardcodedBody[" + Array.get(hardcodedBody, index) + "]";
} else {
out += "hardcodedBody[NOP]";
}
if (Array.getLength(elementEncoded) > index) {
out += "elementEncoded[" + Array.get(elementEncoded, index) + "]";
} else {
out += "elementEncoded[NOP]";
}
out += "\n";
}
return out;
}
@Test(groups = { "functional.encode", "functional.decode", "parameter" })
public void testDecodeEncode() throws IOException, ParameterException {
for (int index = 0; index < this.goodBodies.size(); index++) {
byte[] goodBody = this.goodBodies.get(index);
AbstractISUPParameter component = this.getTestedComponent();
doTestDecode(goodBody, true, component, index);
byte[] encodedBody = component.encode();
boolean equal = Arrays.equals(goodBody, encodedBody);
assertTrue(equal, "Body index: " + index + "\n" + makeCompare(goodBody, encodedBody));
}
for (int index = 0; index < this.badBodies.size(); index++) {
byte[] badBody = this.badBodies.get(index);
AbstractISUPParameter component = this.getTestedComponent();
doTestDecode(badBody, false, component, index);
// TODO: make some tests here?
}
}
public abstract AbstractISUPParameter getTestedComponent() throws ParameterException;
protected void doTestDecode(byte[] presumableBody, boolean shouldPass, AbstractISUPParameter component, int index)
throws ParameterException {
try {
component.decode(presumableBody);
if (!shouldPass) {
fail("Decoded[" + index + "] parameter[" + component.getClass() + "], should not pass. Passed data: "
+ dumpData(presumableBody));
}
} catch (IllegalArgumentException iae) {
if (shouldPass) {
fail("Failed to decode[" + index + "] parameter[" + component.getClass() + "], should not happen. " + iae
+ ".Passed data: " + dumpData(presumableBody));
iae.printStackTrace();
}
} catch (ParameterException iae) {
if (shouldPass) {
fail("Failed to decode[" + index + "] parameter[" + component.getClass() + "], should not happen. " + iae
+ ".Passed data: " + dumpData(presumableBody));
throw iae;
}
} catch (Exception e) {
e.printStackTrace();
fail("Failed to decode[" + index + "] parameter[" + component.getClass() + "]." + e + ". Passed data: "
+ dumpData(presumableBody));
}
}
public void testValues(final Object component, final String getMethodName, final String[] getterMethodNames,
final Object[][] expectedValues) {
try {
Method m = component.getClass().getMethod(getMethodName);
Object[] parts = (Object[]) m.invoke(component, null);
for (int index = 0; index < parts.length; index++) {
testValues(parts[index], getterMethodNames, expectedValues[index]);
}
} catch (Exception e) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(baos);
e.printStackTrace();
e.printStackTrace(pw);
fail("Failed to check values on component: " + component.getClass().getName() + ", due to: "
+ new String(baos.toByteArray()));
}
}
public void testValues(final Object component, final String[] getterMethodNames, final Object[] expectedValues) {
try {
Class cClass = component.getClass();
for (int index = 0; index < getterMethodNames.length; index++) {
Method m = cClass.getMethod(getterMethodNames[index], null);
// Should not be null by now
Object v = m.invoke(component, null);
if (v == null && expectedValues[index] != null) {
fail("Failed to validate values in component: " + component.getClass().getName() + ". Value of: "
+ getterMethodNames[index] + " is null, but test values is not.");
}
if (expectedValues[index] != null && expectedValues[index].getClass().isArray()) {
assertTrue(
Arrays.deepEquals(new Object[] { expectedValues[index] }, new Object[] { v }),
"Failed to validate values in component: " + component.getClass().getName() + ". Value of: "
+ getterMethodNames[index] + ":\n"
+ makeCompare( expectedValues[index],v));
} else {
assertEquals(v, expectedValues[index], "Failed to validate values in component: "
+ component.getClass().getName() + ". Value of: " + getterMethodNames[index]);
}
}
} catch (Exception e) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(baos);
e.printStackTrace();
e.printStackTrace(pw);
fail("Failed to check values on component: " + component.getClass().getName() + ", due to: "
+ new String(baos.toByteArray()));
}
}
public static byte[] getSixDigits() {
return sixDigits;
}
public static byte[] getFiveDigits() {
return fiveDigits;
}
public static byte[] getThreeDigits() {
return threeDigits;
}
public static byte[] getSevenDigits() {
return sevenDigits;
}
public static byte[] getEightDigits() {
return eightDigits;
}
public static String getSixDigitsString() {
return sixDigitsString;
}
public static String getFiveDigitsString() {
return fiveDigitsString;
}
public static String getThreeDigitsString() {
return threeDigitsString;
}
public static String getSevenDigitsString() {
return sevenDigitsString;
}
public static String getEightDigitsString() {
return eightDigitsString;
}
}