From ffd1e0da6b73e2737f5cad0a6d3e82dbc3de206f Mon Sep 17 00:00:00 2001
From: Andreas Fitzek Throwable
-object as fail cause. The directory name is used,
+ * because it uniquely defines the test, as there is only one test per
+ * directory and it is encoded in display name of the test.
+ *
+ * @param directoryName
+ * the name of the directory of the test
+ * @param e
+ * the cause of the fail
+ */
+ public void setFailed(String directoryName, Throwable e) {
+ TestInfo testInfo = getTestInfoForDirectory(directoryName);
+ if (testInfo != null) {
+ testInfo.setVerdict(TestVerdict.FAILED);
+ testInfo.setFailCause(e);
+ }
+ }
+
+ /**
+ * Serializes all test results including a summary. After a call to this
+ * function there will be an index file with the summary in the root test
+ * directory and a test results file in all directories containing tests.
+ */
+ public void serializeAll() {
+ testSummaryWriter.init();
+ testSummaryWriter.writeHeader();
+ Collections.sort(serializers,
+ new ComparatorTestSummaryWriter
+ */
+ public void setTestSummaryWriter(TestSummaryWriter testSummaryWriter) {
+ this.testSummaryWriter = testSummaryWriter;
+ }
+
+ /**
+ * Sets the content which was written to the standard output during a test
+ * for a test.
+ *
+ * @param directoryName
+ * the directory name of the test
+ * @param stdOutFromTest
+ * the standard output content
+ */
+ public void setStdOut(String directoryName, String stdOutFromTest) {
+ TestInfo testInfo = getTestInfoForDirectory(directoryName);
+ testInfo.setStdOut(stdOutFromTest);
+ }
+
+ /**
+ * Sets the content which was written to the standard error during a test
+ * for a test.
+ *
+ * @param directoryName
+ * the directory name of the test
+ * @param stdErrFromTest
+ * the standard error content
+ */
+ public void setStdErr(String directoryName, String stdErrFromTest) {
+ TestInfo testInfo = getTestInfoForDirectory(directoryName);
+ testInfo.setStdErr(stdErrFromTest);
+ }
+
+ /**
+ * Sets a test given its directory name as inconclusive and sets a
+ * AssumptionViolatedException
-object as cause for the verdict.
+ * The directory name is used, because it uniquely defines the test, as
+ * there is only one test per directory and it is encoded in display name of
+ * the test. A test may be inconclusive if an assumption is violated,e.g. if
+ * PDF-A conformance should be checked after signing and the input file does
+ * not conform to the PDF-A standard then the test cannot perform any
+ * meaningful checks.
+ *
+ * @param directoryName
+ * the name of the directory of the test
+ * @param e
+ * the cause of the fail
+ */
+ public void setInconclusive(String directoryName,
+ AssumptionViolatedException e) {
+ TestInfo testInfo = getTestInfoForDirectory(directoryName);
+ testInfo.setVerdict(TestVerdict.INCONCLUSIVE);
+ testInfo.setFailCause(e);
+ }
+
+}
diff --git a/pdf-as-tests/src/test/java/at/gv/egiz/param_tests/serialization/TestInfoSerializer.java b/pdf-as-tests/src/test/java/at/gv/egiz/param_tests/serialization/TestInfoSerializer.java
new file mode 100644
index 00000000..a3014b86
--- /dev/null
+++ b/pdf-as-tests/src/test/java/at/gv/egiz/param_tests/serialization/TestInfoSerializer.java
@@ -0,0 +1,170 @@
+package at.gv.egiz.param_tests.serialization;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.param_tests.testinfo.TestInfo;
+
+/**
+ * Base for all test information serializer. It uses template method pattern,
+ * fixing an algorithm for serialization, but delegating the actual steps to the
+ * subclasses. A two-step hierarchy shall be formed, with this class at the
+ * upper-most level, technology-specific (like HTML) serializer at the next and
+ * technology- and test-type-specific serializer at the lowest level.
+ *
+ * @author mtappler
+ *
+ * @param TestInfo
. The test
+ * information created using this method shall be retrieved, when
+ * getBaseTestInfo()
is called.
+ *
+ * @return instance of a TestInfo
-subclass
+ */
+ public abstract T createTestInfo();
+
+ /**
+ * Clone method for serializer, it shall create a shallow copy of
+ * this
and return it. It does not use
+ * Object.clone()
for type safety, because this method returns
+ * an Object
-instance.
+ *
+ * @return a clone of this
+ */
+ public abstract TestInfoSerializer
+ *
+ */
+ public void serialize() {
+ File outputFile = new File(baseTestInfo.getBaseTestData()
+ .getTestDirectory() + "/test_result." + fileEnding());
+ FileOutputStream os = null;
+ try {
+ os = new FileOutputStream(outputFile);
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(os, "UTF8"));
+ writeHeader(pw);
+ writeTestSpecificParameters(pw);
+ writeTestResult(pw);
+ writeTestData(pw);
+ writeFooter(pw);
+ pw.flush();
+ } catch (FileNotFoundException e) {
+ logger.warn("File not found for test info serialization.", e);
+ } catch (UnsupportedEncodingException e) {
+ logger.warn("Use unsupported encoding for serialization.", e);
+ } finally {
+ if (os != null)
+ IOUtils.closeQuietly(os);
+ }
+ }
+
+ /**
+ * This writes the test result in some format like HTML to the provided
+ * PrintWriter
-object.
+ *
+ * @param pw
+ * the PrintWriter
-object whill shall be used for
+ * serialization
+ */
+ protected abstract void writeTestResult(PrintWriter pw);
+
+ /**
+ * This writes test specific parameters in some format like HTML to the
+ * provided PrintWriter
-object.
+ *
+ * @param pw
+ * the PrintWriter
-object whill shall be used for
+ * serialization
+ */
+ protected abstract void writeTestSpecificParameters(PrintWriter pw);
+
+ /**
+ * This writes the file header in some format like HTML to the provided
+ * PrintWriter
-object.
+ *
+ * @param pw
+ * the PrintWriter
-object whill shall be used for
+ * serialization
+ */
+ protected abstract void writeHeader(PrintWriter pw);
+
+ /**
+ * This writes test specific data in some format like HTML to the provided
+ * PrintWriter
-object.
+ *
+ * @param pw
+ * the PrintWriter
-object whill shall be used for
+ * serialization
+ */
+ protected abstract void writeTestData(PrintWriter pw);
+
+ /**
+ * This writes the file footer in some format like HTML to the provided
+ * PrintWriter
-object.
+ *
+ * @param pw
+ * the PrintWriter
-object whill shall be used for
+ * serialization
+ */
+ protected abstract void writeFooter(PrintWriter pw);
+
+ /**
+ * This method returns the file ending used for the test result file, like
+ * "html" or "xml".
+ *
+ * @return the file ending string
+ */
+ public abstract String fileEnding();
+
+ /**
+ * This method returns a description of the concrete test type, which a
+ * concrete implementation of this class serializes.
+ *
+ * @return a test type description
+ */
+ public abstract String getTestType();
+}
diff --git a/pdf-as-tests/src/test/java/at/gv/egiz/param_tests/serialization/TestSummaryWriter.java b/pdf-as-tests/src/test/java/at/gv/egiz/param_tests/serialization/TestSummaryWriter.java
new file mode 100644
index 00000000..ad0dff7d
--- /dev/null
+++ b/pdf-as-tests/src/test/java/at/gv/egiz/param_tests/serialization/TestSummaryWriter.java
@@ -0,0 +1,45 @@
+package at.gv.egiz.param_tests.serialization;
+
+import at.gv.egiz.param_tests.testinfo.TestInfo;
+
+/**
+ * interface defining methods for a test summary writer. This shall be
+ * implemented in a technology-dependent way, like for HTML.
+ *
+ * @author mtappler
+ *
+ */
+public interface TestSummaryWriter {
+
+ /**
+ * This method shall write a header to a file.
+ */
+ public void writeHeader();
+
+ /**
+ * This method shall write a short summary of a test to a file.
+ *
+ * @param tInfo
+ * test information for the test
+ * @param testType
+ * the type of the test
+ */
+ public void writeSummaryOfTest(TestInfo tInfo, String testType);
+
+ /**
+ * This method shall write a footer to the file.
+ */
+ public void writeFooter();
+
+ /**
+ * This method shall initialize the writing process, e.g. by creating and
+ * opening a file, to which the summary is written.
+ */
+ public void init();
+
+ /**
+ * This method shall terminate the writing process, e.g. by closing the
+ * summary file.
+ */
+ public void close();
+}
diff --git a/pdf-as-tests/src/test/java/at/gv/egiz/param_tests/serialization/html/HTMLSerializer.java b/pdf-as-tests/src/test/java/at/gv/egiz/param_tests/serialization/html/HTMLSerializer.java
new file mode 100644
index 00000000..9bbb0497
--- /dev/null
+++ b/pdf-as-tests/src/test/java/at/gv/egiz/param_tests/serialization/html/HTMLSerializer.java
@@ -0,0 +1,204 @@
+package at.gv.egiz.param_tests.serialization.html;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Map.Entry;
+
+import at.gv.egiz.param_tests.provider.BaseSignatureTestData;
+import at.gv.egiz.param_tests.serialization.TestInfoSerializer;
+import at.gv.egiz.param_tests.testinfo.TestInfo;
+import at.gv.egiz.param_tests.testinfo.TestVerdict;
+
+/**
+ * A subclass implementing some methods, which can be implemented independent of
+ * concrete test type. It uses the Twitter-bootstrap framework, which must be
+ * provided for the files to be correctly displayed in a browser.
+ *
+ * @author mtappler
+ *
+ * @param Detailed test results " + baseData.getTestName()
+ + "
");
+ pw.println("");
+ basicTestDataPanel
+ .append("
");
+ basicTestDataPanel
+ .append(""
+ + baseTestInfo.getStdOut() + "
");
+ basicTestDataPanel.append(""
+ + baseTestInfo.getStdErr() + "
");
+ basicTestDataPanel.append("");
+ sb.append(createDescription("Input file", baseData.getPdfFile()));
+ sb.append(createDescription("Output file", baseData.getOutputFile()));
+ sb.append(createDescription("Signature profile", baseData.getProfilID()));
+ sb.append(createDescription("Connector Type", baseData
+ .getConnectorData().getConnectorType()));
+ if (baseData.getConnectorData().getConnectorParameters().size() > 0) {
+ StringBuilder connectorParameters = new StringBuilder();
+ connectorParameters.append("
");
+ return sb.toString();
+ }
+
+ /**
+ * Helper for writing a bootstrap panel with some title and content.
+ *
+ * @param pw
+ * ");
+ for (Entry
");
+ sb.append(createDescription("Connector Parameters",
+ connectorParameters.toString()));
+ }
+ sb.append(createDescription("Test Type", getTestType()));
+ sb.append("PrintWriter
-object to which the panel should be
+ * written
+ * @param panelTitle
+ * title of the panel
+ * @param panelBody
+ * panel content
+ */
+ protected void writePanel(PrintWriter pw, String panelTitle,
+ String panelBody) {
+ pw.println("" + panelTitle + "
");
+ pw.println(""
+ + HTMLTestSummaryWriter.verdictToLabel(baseTestInfo
+ .getVerdict()) + "
");
+ if (baseTestInfo.getVerdict().equals(TestVerdict.FAILED)
+ || baseTestInfo.getVerdict().equals(TestVerdict.INCONCLUSIVE)) {
+ panelBody.append(createExceptionDataString(baseTestInfo
+ .getFailCause()));
+ }
+ writePanel(pw, "Test result", panelBody.toString());
+
+ }
+
+ /**
+ * This method creates a HTML-representation for data contained in a
+ * throwable.
+ *
+ * @param t
+ * Throwable
-object which should be displayed
+ * @return HTML-string for the throwable
+ */
+ protected String createExceptionDataString(Throwable t) {
+ StringBuilder exceptionData = new StringBuilder();
+ exceptionData.append("");
+ exceptionData.append(createDescription("Cause", t.toString()));
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ t.printStackTrace(pw);
+ exceptionData.append(createDescription("Stacktrace", sw.toString()));
+ exceptionData.append("
");
+ return exceptionData.toString();
+ }
+
+ /**
+ * Helper method for creating an item of a definition list.
+ *
+ * @param term
+ * the term of the item (the key)
+ * @param definition
+ * the definition of the item (the value)
+ * @return an HTML-string for the definition list item
+ */
+ protected String createDescription(String term, String definition) {
+ return String.format("TestSummaryWriter
, which creates
+ * HTML output and uses the Twitter-bootstrap framework.
+ *
+ * @author mtappler
+ *
+ */
+public class HTMLTestSummaryWriter implements TestSummaryWriter {
+
+ /**
+ * the location of the test directory
+ */
+ private String testDir;
+ /**
+ * the print writer which is used for writing
+ */
+ private PrintWriter pw;
+ /**
+ * the logger for this class
+ */
+ private static final Logger logger = LoggerFactory
+ .getLogger(HTMLTestSummaryWriter.class);
+
+ /**
+ * Constructor which sets the test directory.
+ *
+ * @param testDir
+ * location of the test directory
+ */
+ public HTMLTestSummaryWriter(String testDir) {
+ this.testDir = testDir;
+ }
+
+ public void writeHeader() {
+ if (pw == null)
+ return;
+ pw.println("");
+ pw.println("");
+ pw.println("");
+ pw.println("Test result summary
");
+ pw.println("");
+ pw.println("");
+ pw.println("
");
+ pw.println("");
+ pw.println("");
+ pw.println("");
+ pw.println(" ");
+ pw.println("");
+
+ }
+
+ public void writeSummaryOfTest(TestInfo tInfo, String testType) {
+ if (pw == null)
+ return;
+ pw.println("Test name ");
+ pw.println("Test directory ");
+ pw.println("Test type ");
+ pw.println("Verdict ");
+ pw.println("");
+ pw.println(String.format(
+ " ");
+ }
+
+ // intentionally package protected
+ /**
+ * Static method for creating bootstrap label for a test verdict. Since it
+ * is technology dependent (HTML + bootstrap) it is defined as package
+ * protected.
+ *
+ * @param verdict
+ * the verdict of a test
+ * @return HTML-string for a verdict label
+ */
+ static String verdictToLabel(TestVerdict verdict) {
+ switch (verdict) {
+ case FAILED:
+ return "Fail";
+ case INCONCLUSIVE:
+ return "Inconclusive";
+ case SUCCEEDED:
+ return "Success";
+ default:
+ return "Unknown";
+ }
+ }
+
+ public void writeFooter() {
+ if (pw == null)
+ return;
+
+ pw.println("%s ", tInfo
+ .getBaseTestData().getTestDirectory(), tInfo
+ .getBaseTestData().getTestName()));
+ pw.println(String.format("%s ", tInfo.getBaseTestData()
+ .getTestDirectory()));
+ pw.println(String.format("%s ", testType));
+ pw.println(String.format("%s ",
+ verdictToLabel(tInfo.getVerdict())));
+ pw.println("TestInfoSerializer.baseTestInfo
+ */
+ private PDFATestInfo testInfo;
+
+ /**
+ * Default contructor used for registering it as prototype.
+ */
+ public PDFAHTMLSerizalier() {
+ this(null);
+ }
+
+ /**
+ * Package protected constructor used for cloning
+ *
+ * @param testInfo
+ */
+ PDFAHTMLSerizalier(PDFATestInfo testInfo) {
+ this.testInfo = testInfo;
+ }
+
+ @Override
+ public PDFATestInfo createTestInfo() {
+ testInfo = new PDFATestInfo();
+ baseTestInfo = testInfo;
+ return testInfo;
+ }
+
+ @Override
+ public TestInfoSerializerValidation status before signing
");
+ writeValidationResult(pw, testInfo.getResultBeforeSign());
+ if (testInfo.getResultAfterSign() != null) {
+ pw.println("Validation status after signing
");
+ writeValidationResult(pw, testInfo.getResultAfterSign());
+ }
+ }
+
+ /**
+ * This method writes the validation result to the given print writer, i.e.
+ * an information about the success of the validation or an exception which
+ * was thrown during the validation or a list of validation errors.
+ *
+ * @param pw
+ * the PrintWriter
-object to which the HTML-code is
+ * written
+ * @param validationResult
+ * the pair which defines the result of a validation
+ */
+ private void writeValidationResult(PrintWriter pw,
+ Pair
The document conforms to the PDF-A standard.
"); + } else { + ListWith to the PDF-A standard, " + + "the document contains the following errors:
"); + conformanceString + .append("Error code | "); + conformanceString.append("Error details | "); + conformanceString.append("Warning | "); + conformanceString.append("
---|
TestInfoSerializer.baseTestInfo
+ */
+ private SignaturePositionTestInfo testInfo;
+
+ /**
+ * Default contructor used for registering it as prototype.
+ */
+ public SignaturePositionHTMLSerializer() {
+ this(null);
+ }
+
+ /**
+ * Package protected constructor used for cloning
+ *
+ * @param testInfo
+ */
+ SignaturePositionHTMLSerializer(SignaturePositionTestInfo testInfo) {
+ this.testInfo = testInfo;
+ }
+
+ @Override
+ public SignaturePositionTestInfo createTestInfo() {
+ testInfo = new SignaturePositionTestInfo();
+ baseTestInfo = testInfo;
+ return testInfo;
+ }
+
+ @Override
+ public TestInfoSerializerThis image was not captured correctly. " + + "The test may have been aborted before because of an IO error.
"; + return imageString; + } + + @Override + public String getTestType() { + return "Signature Position"; + } + + @Override + protected void writeTestSpecificParameters(PrintWriter pw) { + + SignaturePositionParameters additionalParameters = testInfo + .getAdditionParameters(); + StringBuilder panelBody = new StringBuilder(); + + panelBody.append("