//------------------------------------------------------------------------------ // Copyright (c) 2005, 2006 IBM Corporation and others. // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // which accompanies this distribution, and is available at // http://www.eclipse.org/legal/epl-v10.html // // Contributors: // IBM Corporation - initial implementation //------------------------------------------------------------------------------ package org.eclipse.epf.library.tester.impl; import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.epf.common.utils.XMLUtil; import org.eclipse.epf.importing.services.PluginImportingService; import org.eclipse.epf.library.edit.util.LibraryEditUtil; import org.eclipse.epf.library.project.MethodLibraryProject; import org.eclipse.epf.library.tester.LibraryDiffAnalyzor; import org.eclipse.epf.library.tester.LibraryTestService; import org.eclipse.epf.library.tester.iface.LibraryJunitTest; import org.eclipse.epf.library.tester.iface.TCExeReply; import org.eclipse.epf.library.tester.iface.TCExeReplyList; import org.eclipse.epf.library.tester.iface.TestCommand; import org.eclipse.epf.library.tester.iface.TestTracer; import org.eclipse.epf.library.tester.impl.testcommands.TCCircularDependencyCheck; import org.eclipse.epf.library.tester.impl.testcommands.TCCompareToGoldenFile; import org.eclipse.epf.library.tester.impl.testcommands.TCCompareToLibrary; import org.eclipse.epf.library.tester.impl.testcommands.TCCopyLibrary; import org.eclipse.epf.library.tester.impl.testcommands.TCEditMethodElement; import org.eclipse.epf.library.tester.impl.testcommands.TCExeReplyImpl; import org.eclipse.epf.library.tester.impl.testcommands.TCExeReplyListImpl; import org.eclipse.epf.library.tester.impl.testcommands.TCExportConfiguration; import org.eclipse.epf.library.tester.impl.testcommands.TCExportPlugins; import org.eclipse.epf.library.tester.impl.testcommands.TCExportXml; import org.eclipse.epf.library.tester.impl.testcommands.TCImportConfiguration; import org.eclipse.epf.library.tester.impl.testcommands.TCImportPlugins; import org.eclipse.epf.library.tester.impl.testcommands.TCImportXml; import org.eclipse.epf.library.tester.impl.testcommands.TCNewMethodConfiguration; import org.eclipse.epf.library.tester.impl.testcommands.TCNewMethodElement; import org.eclipse.epf.library.tester.impl.testcommands.TCNewMethodPlugin; import org.eclipse.epf.library.tester.impl.testcommands.TCOpenLibrary; import org.eclipse.epf.library.tester.impl.testcommands.TCOutputMethodElement; import org.eclipse.epf.library.tests.LibraryTestHelper; import org.eclipse.epf.library.util.LibraryUtil; import org.eclipse.epf.library.xmi.XMILibraryUtil; import org.eclipse.epf.uma.CapabilityPattern; import org.eclipse.epf.uma.ContentPackage; import org.eclipse.epf.uma.MethodConfiguration; import org.eclipse.epf.uma.MethodLibrary; import org.eclipse.epf.uma.MethodPlugin; import org.eclipse.epf.uma.ProcessComponent; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * Used in JUnit tests * * @author Weiping Lu * @since 1.0 * */ public class TestCommandMgr implements TestTracer { //All the tags will be formally specified and read from //a schema later. private static String TCCopyLibrary = "CopyLibrary"; private static String TCOpenLibrary = "OpenLibrary"; private static String TCExportPlugins = "ExportPlugins"; private static String TCImportPlugins = "ImportPlugins"; private static String TCExportConfiguration = "ExportConfiguration"; private static String TCImportConfiguration = "ImportConfiguration"; private static String TCExportXml = "ExportXml"; private static String TCImportXml = "ImportXml"; private static String TCCompareToLibrary = "CompareToLibrary"; private static String TCCompareToGoldenFile = "CompareToGoldenFile"; private static String TCNewMethodPlugin = "NewMethodPlugin"; private static String TCNewMethodConfiguration = "NewMethodConfiguration"; private static String TCNewMethodElement = "NewMethodElement"; private static String TCEditMethodElement = "EditMethodElement"; private static String TCCircularDependencyCheck = "CircularDependencyCheck"; private static String TCEnd = "End"; private static String TCEditPlugin="EditPlugin"; private static String TCEditConfiguration="EditConfiguration"; private static String TCEditContentPackage="EditContentPackage"; public static String TCOutputLibrary="OutputLibrary"; public static String TCOutputPlugin="OutputPlugin"; public static String TCOutputConfiguration="OutputConfiguration"; public static String TCOutputMethodElement="OutputMethodElement"; private boolean trace = false; private boolean removeFiles = true; private File testRootSource; private File testRootWorking; private File currTestDir; private String outputPath; private Document outputDocument; private PrintStream testRootOut; private PrintStream currTestOut; private int executedTestCount = 0; private static LibraryTestService service = LibraryTestService.getInstance(); private File testFile; private List testCommandList = new ArrayList(); private LibraryJunitTest junitTestCase; private MethodLibrary currentBaseLib; private Map allLibs = new LinkedHashMap(); private Map allExports = new LinkedHashMap(); private static Map tcClassMap = new HashMap(); private static Map tcTagNameMap = new HashMap(); private PrintStream logPS = System.out; static { addToTcClassMap(TCCopyLibrary, TCCopyLibrary.class); addToTcClassMap(TCOpenLibrary, TCOpenLibrary.class); addToTcClassMap(TCExportPlugins, TCExportPlugins.class); addToTcClassMap(TCImportPlugins, TCImportPlugins.class); addToTcClassMap(TCExportConfiguration, TCExportConfiguration.class); addToTcClassMap(TCImportConfiguration, TCImportConfiguration.class); addToTcClassMap(TCExportXml, TCExportXml.class); addToTcClassMap(TCImportXml, TCImportXml.class); addToTcClassMap(TCCompareToLibrary, TCCompareToLibrary.class); addToTcClassMap(TCCompareToGoldenFile, TCCompareToGoldenFile.class); addToTcClassMap(TCNewMethodPlugin, TCNewMethodPlugin.class); addToTcClassMap(TCNewMethodConfiguration, TCNewMethodConfiguration.class); addToTcClassMap(TCNewMethodElement, TCNewMethodElement.class); addToTcClassMap(TCEditMethodElement, TCEditMethodElement.class); addToTcClassMap(TCEditPlugin, TCEditMethodElement.class); addToTcClassMap(TCEditConfiguration, TCEditMethodElement.class); addToTcClassMap(TCEditContentPackage, TCEditMethodElement.class); addToTcClassMap(TCOutputLibrary, TCOutputMethodElement.class); addToTcClassMap(TCOutputPlugin, TCOutputMethodElement.class); addToTcClassMap(TCOutputConfiguration, TCOutputMethodElement.class); addToTcClassMap(TCOutputMethodElement, TCOutputMethodElement.class); addToTcClassMap(TCCircularDependencyCheck, TCCircularDependencyCheck.class); } private static void addToTcClassMap(String elementName, Class cls) { Object instance = null; try { instance = cls.newInstance(); } catch (Exception e){ e.printStackTrace(); } if (instance instanceof TestCommand) { tcClassMap.put(elementName, instance); tcTagNameMap.put(cls, elementName); } } public TestCommandMgr(boolean trace) { if (trace) { this.trace = trace; this.removeFiles = !trace; } LibraryEditUtil.getInstance().setJunitTest(true); } public String getTagName(TestCommand tcInstance) { return (String) tcTagNameMap.get(tcInstance.getClass()); } public void setTestRootSource(File dirFile) { testRootSource = dirFile; } public void setTestRootWorking(File dirFile) { boolean needToCreateOutputFile = testRootWorking == null || ! testRootWorking.equals(dirFile); testRootWorking = dirFile; if (trace && needToCreateOutputFile) { try { if (! testRootWorking.exists()) { if (! mkDir(testRootWorking)) { return; } } if (testRootOut != null) { testRootOut.close(); } String path = testRootWorking.getAbsolutePath() + File.separator + "traces.out"; testRootOut = new PrintStream(new FileOutputStream(path)); } catch (Exception e) { e.printStackTrace(); } } } private boolean mkDir(File file) { File pFile = file.getParentFile(); if (! pFile.exists()) { if (! mkDir(pFile)) { return false; } } return file.mkdir(); } public void openCurrTestDir(File dirFile) { currTestDir = dirFile; try { if (! currTestDir.exists()) { currTestDir.mkdir(); } String path = currTestDir.getAbsolutePath() + File.separator; if (trace) { currTestOut = new PrintStream(new FileOutputStream(path + "trace.out")); } outputPath = path + "output.xml"; } catch (Exception e) { e.printStackTrace(); } } public void closeCurrTestDir() { closeLibrary(getCurrentBaseLib()); if (currTestOut != null) { currTestOut.close(); currTestOut = null; } clearOutputDocument(); allLibs = new LinkedHashMap(); allExports = new LinkedHashMap(); closeFolder(currTestDir); } public void doneWithAllTests(File topCleanUpFolder) { closeAllExportProjects(); if (testRootOut != null) { testRootOut.close(); } closeFolder(topCleanUpFolder); } public File getCurrTestDir() { return currTestDir; } public void setTest(File testFile) { this.testFile = testFile; } public File getTestFile() { return testFile; } public LibraryTestService getService() { return service; } public TCExeReplyList execute() { trace("Begin executing: " + testFile); TCExeReplyList result = null; boolean loaded = false; Exception loadException = null; try { loaded = loadTest(); } catch (Exception e) { loadException = e; e.printStackTrace(); } if (loaded) { String path = testRootWorking.getAbsolutePath() + File.separator + testFile.getName() + ".dir"; openCurrTestDir(new File (path)); result = executeCommands(); closeCurrTestDir(); } else { result = new TCExeReplyListImpl(); if (loadException != null) { String msg = "Test load failed: " + loadException.getMessage(); ((TCExeReplyListImpl) result).add(new TCExeReplyImpl(msg, false)); trace(msg); } else { trace("Test disabled"); } } trace("End executing : " + testFile); return result; } private boolean loadTest() throws Exception { testCommandList.clear(); Document document = XMLUtil.loadXml(testFile); Element root = document.getDocumentElement(); if (root.getAttribute(TestCommand.AT_Disable).equals("true")) { return false; } boolean verbose = root.getAttribute(TestCommand.AT_Verbose).equalsIgnoreCase("true"); NodeList nodes = root.getChildNodes(); int sz = nodes == null ? 0 : nodes.getLength(); for (int i=0; i<sz; i++) { Node node = nodes.item(i); if (node instanceof Element) { Element element = (Element) node; if (verbose) { element.setAttribute(TestCommand.AT_Verbose, "true"); } if (element.getTagName().equalsIgnoreCase(TCEnd)) { break; } addCommand(node); } } return true; } public TCExeReplyList executeCommands() { TCExeReplyListImpl result = new TCExeReplyListImpl(); for (int i=0; i<testCommandList.size(); i++) { TestCommandImpl command = (TestCommandImpl) testCommandList.get(i); TCExeReply reply = null; try { reply = command.execute(); } catch (Exception e) { e.printStackTrace(); reply = new TCExeReplyImpl(e.getMessage(), false); } if (reply != null) { result.add(reply); if (!reply.passing()) { log("\nThe following command is not passing: \n" + command.getElement() + "\n"); } } } String line = testFile.getName() + " is "; String dirStr = "testRootSource: " + testRootSource + ", testRootWorking: " + testRootWorking; if (result.passing()) { line += "passing. " + dirStr; } else { line += "failing! " + dirStr; } result.setSummaryReply(line); return result; } public void trace(String line) { if (testRootOut != null) { testRootOut.println(line); } if (currTestOut != null) { currTestOut.println(line); } } private void addCommand(Node node) { if ( !(node instanceof Element)) { return; } Element element = (Element) node; if (! element.getAttribute(TestCommand.AT_Disable).equals("true")) { TestCommand command = newTestCommand(element.getTagName()); if (command != null) { command.parse(element); testCommandList.add(command); } } } private TestCommand newTestCommand(String comandName) { Object obj = tcClassMap.get(comandName); return obj == null ? null : newTestCommand(obj.getClass()); } public TestCommand newTestCommand(Class cls) { TestCommand ret = null; try { ret = (TestCommand) cls.newInstance(); ((TestCommandImpl) ret).setOwner(this); } catch (Exception e) { e.printStackTrace(); } return ret; } private MethodLibrary loadBaseLib(String name, boolean ifNewThenBuildDeafaultLib) { if (currentBaseLib != null) { File file = new File(currentBaseLib.eResource().getURI().toFileString()).getParentFile(); if (file.getName().equals(name)) { return currentBaseLib; } } if (allExports.containsKey(name)) { throw new UnsupportedOperationException(); } service.closeLibrary(currentBaseLib); currentBaseLib = null; String libPath = (String) allLibs.get(name); if (libPath == null) { libPath = currTestDir.getAbsolutePath() + File.separator + name; try { currentBaseLib = copyFromTestLibs(libPath, name) ? XMILibraryUtil.openMethodLibrary(libPath) : null; } catch (Exception e) { } if (currentBaseLib == null) { currentBaseLib = service.createLibrary(libPath, name); if (ifNewThenBuildDeafaultLib) { buildDefaultLibrary(); } trace("Base lib \"" + name + "\" is created."); } else { trace("Base lib \"" + name + "\" is copied from testLibs and laoded."); } allLibs.put(name, libPath); } else { try { currentBaseLib = XMILibraryUtil.openMethodLibrary(libPath); trace("Base lib \"" + name + "\" is loaded."); } catch (Exception e) { trace(e.getMessage()); } } return currentBaseLib; } public MethodLibrary loadNonBaseLib(String name) { String libPath = (String) allLibs.get(name); if (libPath == null) { throw new UnsupportedOperationException(); } return service.loadLibrary(libPath); } public MethodLibrary getCurrentBaseLib() { return currentBaseLib; } public void setCurrentBaseLib(MethodLibrary lib) { currentBaseLib = lib; } public MethodLibrary loadBaseLib(String name) { return loadBaseLib(name, false); } public MethodLibrary loadBaseLibOrBuildBaseWithDefault(String name) { return loadBaseLib(name, true); } public File getImportFile(String importFolderName) { File file = (File) allExports.get(importFolderName); if (file == null) { file = new File(testRootSource.getAbsolutePath() + File.separator + importFolderName); if (file.exists() && file.isDirectory()) { return file; } return null; } return file; } public File registerExportDestination(String name, boolean isXML) { if (allLibs.containsKey(name)) { throw new UnsupportedOperationException(); } File file = (File) allExports.get(name); if (file == null) { String path = currTestDir.getAbsolutePath() + File.separator + name; if (isXML) { path += File.separator + name + ".xml"; } file = new File(path); allExports.put(name, file); } return file; } public void closeLibrary(MethodLibrary lib) { service.closeLibrary(lib); setCurrentBaseLib(null); } public void closeFolder(File folder) { if (removeFiles) { service.deleteFolder(folder); } } public int incExecutedTestCount() { return ++executedTestCount; } public void closeAllExportProjects() { for (Iterator it = allExports.values().iterator(); it.hasNext();) { File file = (File) it.next(); try { MethodLibraryProject.closeProject(file.getAbsolutePath(), new NullProgressMonitor()); } catch (Throwable e){ } } } public boolean compareLibs(MethodLibrary lib1, MethodLibrary lib2) { return compareLibs(lib1, lib2, false); } public boolean compareLibs(MethodLibrary lib1, MethodLibrary lib2, boolean useNameAs2ndId) { LibraryDiffAnalyzor analyzor = new LibraryDiffAnalyzor(this, lib1, lib2); analyzor.setGreedy(trace); analyzor.setUseNameAs2ndId(useNameAs2ndId); return analyzor.compare(); } public boolean compareLibs(MethodLibrary lib1, MethodLibrary lib2, int diffCount, int elemComparedCount, boolean useNameAs2ndId) { if (diffCount == 0 && elemComparedCount == 0) { return compareLibs(lib1, lib2, useNameAs2ndId); } LibraryDiffAnalyzor analyzor = new LibraryDiffAnalyzor(this, lib1, lib2); analyzor.setGreedy(true); analyzor.setUseNameAs2ndId(useNameAs2ndId); analyzor.compare(); return analyzor.getDiffCount() == diffCount && analyzor.getElemComparedCount() == elemComparedCount; } public void buildDefaultLibrary() { trace("buildDefaultLibrary ->"); MethodPlugin plugin = LibraryTestHelper.createMethodPlugin("Plug_A"); ContentPackage pkg = LibraryTestHelper.createContentPackage(plugin, "p1"); MethodConfiguration config = LibraryTestHelper.createConfiguration("Config_A"); CapabilityPattern cp1 = LibraryTestHelper.createCapabilityPattern(plugin, "CP1", config); CapabilityPattern cp2 = LibraryTestHelper.createCapabilityPattern(plugin, "CP2", config); LibraryTestHelper.setContributes(cp2, cp1); // update the configuration config.getMethodPluginSelection().add(plugin); config.getMethodPackageSelection().add(pkg); config.getMethodPackageSelection().add((ProcessComponent)cp1.eContainer()); config.getMethodPackageSelection().add((ProcessComponent)cp2.eContainer()); LibraryUtil.validateMethodConfiguration(config); final String cp1_text = "cp1 main desc"; final String cp2_text = "cp2 main desc"; cp1.getPresentation().setMainDescription(cp1_text); cp2.getPresentation().setMainDescription(cp2_text); trace("buildDefaultLibrary <-"); } public boolean copyFromTestLibs(String libPath, String relLibNamePath) { File source = new File(testRootSource.getAbsolutePath() + File.separator + relLibNamePath); String libName = source.getName(); File libList[] = source.getParentFile().listFiles(); for (int i=0; i<libList.length; i++) { File file = libList[i]; if (libName.equals(file.getName())) { File target = new File(libPath); PluginImportingService.copyDir(source, target); allLibs.put(libName, libPath); return true; } } return false; } public Document getOutputDocument() { if (outputDocument == null) { try { outputDocument = XMLUtil.createDocument(); Element root = outputDocument.createElement("TesterOutput"); outputDocument.appendChild(root); } catch (Exception e) { e.printStackTrace(); } } return outputDocument; } private void clearOutputDocument() { outputDocument = null; } public String getOutputPath() { return outputPath; } public void log(String line) { logPS.println(line); } }