package gov.nist.registry.common2.testkit; import gov.nist.registry.common2.exception.ExceptionUtil; import gov.nist.registry.common2.exception.XdsInternalException; import gov.nist.registry.common2.io.Io; import gov.nist.registry.common2.registry.MetadataSupport; import gov.nist.registry.common2.xml.Util; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.namespace.QName; import javax.xml.parsers.FactoryConfigurationError; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNode; import org.apache.axiom.om.xpath.AXIOMXPath; import org.jaxen.JaxenException; /** * Build XML file describing structure of testkit. Used to validate * test results. * @author bill * */ public class TestkitStructure extends TestkitWalker { OMElement testkitDesc; static String outputdir; static String toolkit; static String testkit; String testkitVersion; String serverVersion; /** * Used when generating testkit structure * @throws IOException */ public TestkitStructure() throws IOException { testkitDesc = MetadataSupport.om_factory.createOMElement("testkit", null); testkitDesc.addAttribute("serverVersion", loadServerVersion(), null); } /** * Used when reading testkit structure * @param testkitStructFile * @throws XdsInternalException * @throws FactoryConfigurationError * @throws IOException */ public TestkitStructure(File testkitStructFile, String testkitVersion) throws XdsInternalException, FactoryConfigurationError, IOException { System.out.println("TestkitStructure: loading " + testkitStructFile); testkitDesc = Util.parse_xml(testkitStructFile); this.testkitVersion = testkitVersion; serverVersion = testkitDesc.getAttributeValue(new QName("serverVersion")); System.out.println("TestkitStructure: serverVersion = " + serverVersion); if (serverVersion == null || serverVersion.equals("")) throw new XdsInternalException("Error loading testkit definition - serverVersion not present"); } public OMElement getTest(String testnum) { return MetadataSupport.getChild(testkitDesc, "test", testnum); } public List<String> getSectionNames(String testnum) throws Exception { OMElement testEle = getTest(testnum); if (testEle == null) throw new Exception("Test " + testnum + " not found in testkit structure database for testkit version " + testkitVersion); List<String> names = new ArrayList<String>(); for (OMElement sectionEle : MetadataSupport.childrenWithLocalName(testEle, "section")) { names.add(sectionEle.getAttributeValue(MetadataSupport.id_qname)); } return names; } public OMElement getSection(String testnum, String sectionId) throws Exception { OMElement testEle = getTest(testnum); if (testEle == null) throw new Exception("Test " + testnum + " not found in testkit structure database"); if (sectionId == null) return testEle; return MetadataSupport.getChild(testEle, "section", sectionId); } public boolean isServerTest(String testnum) throws Exception { return "server".equals(getArea(testnum)); } public String getArea(String testnum) throws Exception { OMElement testEle = getTest(testnum); if (testEle == null) throw new Exception("Test " + testnum + " not found in testkit structure database"); System.out.println("found test " + testnum); String area = testEle.getAttributeValue(new QName("area")); if (area == null) throw new Exception("Testkit structure error: test " + testnum + " has no area declaration"); System.out.println("area is " + area); return area; } public String getEndpoint(String testnum) throws Exception { OMElement testEle = getTest(testnum); if (testEle == null) throw new Exception("Test " + testnum + " not found in testkit structure database"); String endpoint = testEle.getAttributeValue(new QName("endpoint")); if (endpoint == null) throw new Exception("Testkit structure error: test " + testnum + " has no endpoint declaration"); return endpoint; } public List<String> getStepNames(String testnum) throws Exception { OMElement testEle = getTest(testnum); if (testEle == null) throw new Exception("Test " + testnum + " not found in testkit structure database"); List<String> names = new ArrayList<String>(); for (OMElement stepEle : MetadataSupport.childrenWithLocalName(testEle, "step")) { names.add(stepEle.getAttributeValue(MetadataSupport.id_qname)); } return names; } public List<String> getStepNames(String testnum, String section) throws Exception { OMElement testEle = getTest(testnum); if (testEle == null) throw new Exception("Test " + testnum + " not found in testkit structure database"); List<String> names = new ArrayList<String>(); for (OMElement sectionEle : MetadataSupport.childrenWithLocalName(testEle, "section")) { String sectionName = sectionEle.getAttributeValue(MetadataSupport.id_qname); if (sectionName != null && sectionName.equals(section)) { for (OMElement stepEle : MetadataSupport.childrenWithLocalName(sectionEle, "step")) { names.add(stepEle.getAttributeValue(MetadataSupport.id_qname)); } } } System.out.println("steps for test " + testnum + "/" + section + " are " + names); return names; } String getTestId(File testplan) { String[] filenameElements = testplan.toString().split("\\/"); if (testkitPathElementsToIgnore >= filenameElements.length) { System.out.println("Cannot parse " + testplan.toString() + " looking for testId"); System.exit(-1); } return filenameElements[testkitPathElementsToIgnore]; } // returns null if no section String getSectionId(File testplan) { String[] filenameElements = testplan.toString().split("\\/"); int testIndex = testkitPathElementsToIgnore; int sectionIndex = testIndex + 1; if (sectionIndex >= filenameElements.length) return null; if (filenameElements[sectionIndex].equals("testplan.xml")) return null; return filenameElements[sectionIndex]; } List<String> getStepIds(File testplan) { ArrayList<String> ids = new ArrayList<String>(); OMElement tplan; try { tplan = Util.parse_xml(testplan); AXIOMXPath xpathExpression = new AXIOMXPath ("//TestPlan/TestStep"); List<OMNode> nodes = xpathExpression.selectNodes(tplan); for (int i=0; i<nodes.size(); i++) { OMElement testStep = (OMElement) nodes.get(i); ids.add(testStep.getAttributeValue(MetadataSupport.id_qname)); } } catch (Exception e) { e.printStackTrace(); System.err.println(ExceptionUtil.exception_details(e)); System.exit(-1); } return ids; } public void doStep(String step) throws Exception { } public void endPart(File part) throws Exception { } public void endSection(File section) throws Exception { } public void endTest(File test) throws Exception { } public void endTestPlan(File testplan) throws Exception { } public void startPart(File part) throws Exception { } public void startSection(File section) throws Exception { } public void startTest(File test) throws Exception { } /** * Testkit scanner. */ public void startTestPlan(File testplan) throws Exception { String testId = getTestId(testplan); String sectionId = getSectionId(testplan); List<String> stepIds = getStepIds(testplan); if (testId == null || testId.equals("")) { System.err.println("TestPlan " + testplan.toString() + " cannot find testId"); System.exit(-1); } if (stepIds.size() == 0) { System.err.println("TestPlan " + testplan.toString() + " has no test steps"); System.exit(-1); } OMElement test = MetadataSupport.getChild(testkitDesc, "test", testId); if (test == null) { test = MetadataSupport.om_factory.createOMElement("test", null); test.addAttribute("id", testId, null); test.addAttribute("area", getCurrentArea(), null); testkitDesc.addChild(test); } OMElement section = null; if (sectionId != null) { section = MetadataSupport.om_factory.createOMElement("section", null); section.addAttribute("id", sectionId, null); test.addChild(section); } if (section != null) { // check for endpoint.txt file File endpointFile = new File(testplan.getParentFile() + File.separator + "endpoint.txt"); //System.out.println("endpoint file: " + endpointFile + ( (endpointFile.exists()) ? " exists" : "" )); if (endpointFile.exists()) { String endpointPattern = Io.stringFromFile(endpointFile).trim(); section.addAttribute("endpoint", endpointPattern, null); } } if (sectionId == null) parseValidations(testId, test, testplan); else parseValidations(testId, section, testplan); OMElement stepParent = (section != null) ? section : test; for (int i=0; i<stepIds.size(); i++) { String stepId = stepIds.get(i); OMElement step = MetadataSupport.om_factory.createOMElement("step", null); step.addAttribute("id", stepId, null); stepParent.addChild(step); } } class Att { String name; String value; void addToElement(OMElement e) { e.addAttribute(name, value, null); } } List<Att> parseAtts(String attStr, String testnum) throws Exception { List<Att> atts = new ArrayList<Att>(); String[] atta = attStr.split("\\n"); if (atta == null) throw new Exception("Cannot parse validations.txt from test " + testnum); for (int i=0; i<atta.length; i++) { String[] name_value = atta[i].split("="); if (name_value.length != 2) throw new Exception("Cannot parse validations.txt from test " + testnum); String name = name_value[0].trim(); String value = name_value[1].trim(); if (value.charAt(0) == '"') value = value.substring(1); if (value.charAt(value.length()-1) == '"') value = value.substring(0, value.length()-1); Att a = new Att(); a.name = name; a.value = value; atts.add(a); } return atts; } void parseValidations(String testnum, OMElement test, File testplanFile) throws Exception { // look for validations.txt file in same dir as testplanFile File valFile = new File(testplanFile.getParent() + File.separator + "validations.txt"); if ( !valFile.exists()) return; System.out.println("Validations exist for " + testplanFile); String attstr = Io.stringFromFile(valFile).trim(); // atts is in name="value" format, each 'attribute' should be added to test spec List<Att> atts = parseAtts(attstr, testnum); for (Att a : atts) { a.addToElement(test); } } public void begin() throws Exception { String[] areas = { "tests", "testdata", "server" }; setAreas(areas); } public void end() throws Exception { File outfile = new File(outputdir + File.separator + "testkit_structure." + loadTestkitVersion() + ".xml"); Io.stringToFile(outfile, testkitDesc.toString()); System.out.println("Wrote " + outfile); } public static void main(String[] args) { if (args.length != 3) { System.err.println("Usage: testkitstructure <toolkit_location> <testkit_location> <output_dir>"); System.exit(-1); } toolkit = args[0]; testkit = args[1]; outputdir = args[2]; TestkitStructure tst = null; try { tst = new TestkitStructure(); System.out.println("starting"); tst.walkTree(new File(testkit)); } catch (XdsInternalException e) { e.printStackTrace(); } catch (JaxenException e) { e.printStackTrace(); } catch (FactoryConfigurationError e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } if (tst != null) { System.err.println("Evaluated " + tst.testPlanCount + " testplans"); } System.exit(errors); } String loadTestkitVersion() throws IOException { File versionFile = new File(toolkit + File.separator + "admin" + File.separator + "version"); return Io.stringFromFile(versionFile).trim().replaceAll(" ", "_"); } String loadServerVersion() throws IOException { File versionFile = new File(testkit + File.separator + "admin" + File.separator + "server_version"); return Io.stringFromFile(versionFile).trim(); } public String getServerVersion() { return serverVersion; } public void endServer(File test) throws Exception { } public void startServer(File testDir) throws Exception { String testnum = testDir.getName(); File endpointFile = new File(testDir + File.separator + "endpoint.txt"); if ( !endpointFile.exists()) throw new Exception("No endpoint.txt file found in server test " + testDir); String endpoint = Io.stringFromFile(endpointFile).trim(); if (endpoint == null || endpoint.equals("")) throw new Exception("Empty endpoint.txt file found in server test " + testDir); OMElement test; test = MetadataSupport.om_factory.createOMElement("test", null); test.addAttribute("id", testnum, null); test.addAttribute("area", getCurrentArea(), null); test.addAttribute("endpoint", endpoint, null); testkitDesc.addChild(test); } }