--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry kind="src" output="target/classes" path="src/main/java"/>\r
+ <classpathentry kind="src" output="target/classes" path="src/main/resources"/>\r
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>\r
+ <classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>\r
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>\r
+ <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>\r
+ <classpathentry kind="output" path="target/classes"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.slc.core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+#Fri Aug 29 11:10:18 CEST 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
--- /dev/null
+<project xmlns:artifact="urn:maven-artifact-ant" default="deploy">\r
+\r
+ <path id="maven-ant-tasks.classpath"\r
+ path="D:\dev\tools\maven-2.0.7\lib\maven-ant-tasks-2.0.7.jar" />\r
+ <typedef resource="org/apache/maven/artifact/ant/antlib.xml"\r
+ uri="urn:maven-artifact-ant"\r
+ classpathref="maven-ant-tasks.classpath" />\r
+\r
+ <property name="local" location="D:/dev/mavenLocal/" />\r
+ <property name="local.argeo" location="${local}/org/argeo/slc/" />\r
+ <property name="repo.argeo"\r
+ value="file:///D:/dev/test/mavenArgeoLocalRep/" />\r
+\r
+ <target name="deploy">\r
+ <deploy artifact="argeo-slc-core" version="0.6.0" />\r
+ </target>\r
+\r
+ <!-- Macrodefs -->\r
+ <macrodef name="deploy">\r
+ <attribute name="artifact" />\r
+ <attribute name="version" />\r
+ <sequential>\r
+ <artifact:install-provider artifactId="wagon-file"\r
+ version="1.0-beta-2" />\r
+ <artifact:deploy file="${local.argeo}/@{artifact}/@{version}/@{artifact}-@{version}.jar">\r
+ <artifact:pom file="pom.xml" />\r
+ <remoterepository url="${repo.argeo}" />\r
+ <attach classifier="sources"\r
+ file="${local.argeo}/@{artifact}/@{version}/@{artifact}-@{version}-sources.jar" />\r
+ <attach classifier="javadoc"\r
+ file="${local.argeo}/@{artifact}/@{version}/@{artifact}-@{version}-javadoc.jar" />\r
+ </artifact:deploy>\r
+ </sequential>\r
+ </macrodef>\r
+</project>
\ No newline at end of file
--- /dev/null
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.argeo.slc</groupId>
+ <artifactId>argeo-slc</artifactId>
+ <version>0.11.2-SNAPSHOT</version>
+ <relativePath>../org.argeo.slc</relativePath>
+ </parent>
+ <artifactId>org.argeo.slc.core</artifactId>
+ <name>Argeo SLC Core</name>
+ <description>SLC Core</description>
+ <scm>
+ <connection>
+ scm:svn:https://www.argeo.org/svn/slc/trunk/org.argeo.slc.core
+ </connection>
+ <url>
+ https://www.argeo.org/svn/slc/trunk/org.argeo.slc.core
+ </url>
+ </scm>
+ <build>
+ <plugins>
+ <!-- Look to parent pom for inheritances -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.argeo.slc.*
+ </Export-Package>
+ <Import-Package>*,org.apache.commons.logging;version="1.1"</Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>com.springsource.org.apache.commons.logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.log4j</groupId>
+ <artifactId>
+ com.springsource.org.apache.log4j
+ </artifactId>
+ </dependency>
+ <!--
+ <dependency> <groupId>org.slf4j</groupId>
+ <artifactId>com.springsource.slf4j.log4j</artifactId>
+ <version>1.5.3</version> </dependency> <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
+ <version>1.5.3</version> </dependency>
+ -->
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>org.springframework.context</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.ws</groupId>
+ <artifactId>org.springframework.oxm</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.castor</groupId>
+ <artifactId>com.springsource.org.castor</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.xerces</groupId>
+ <artifactId>com.springsource.org.apache.xerces</artifactId>
+ </dependency>
+ <!--
+ <dependency>
+ <groupId>org.apache.xalan</groupId>
+ <artifactId>com.springsource.org.apache.xalan</artifactId>
+ </dependency>
+ -->
+ <dependency>
+ <groupId>edu.emory.mathcs.backport</groupId>
+ <artifactId>
+ com.springsource.edu.emory.mathcs.backport
+ </artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.xml.stream</groupId>
+ <artifactId>com.springsource.javax.xml.stream</artifactId>
+ </dependency>
+ <!--
+ <dependency> <groupId>javax.xml.stream</groupId>
+ <artifactId>stax-api</artifactId> </dependency>
+ -->
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>
+ com.springsource.org.apache.commons.io
+ </artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.dbunit</groupId>
+ <artifactId>com.springsource.org.dbunit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.junit</groupId>
+ <artifactId>com.springsource.junit</artifactId>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.castor.structure.tree;
+
+import org.exolab.castor.mapping.AbstractFieldHandler;
+import org.exolab.castor.mapping.MapItem;
+
+import org.argeo.slc.core.structure.tree.TreeSPath;
+
+public class TreeSPathFieldHandler extends AbstractFieldHandler {
+
+ @Override
+ public Object getValue(Object object) throws IllegalStateException {
+ MapItem part = (MapItem) object;
+ return ((TreeSPath) part.getKey()).getAsUniqueString();
+ }
+
+ @Override
+ public Object newInstance(Object parent) throws IllegalStateException {
+ return null;
+ }
+
+ @Override
+ public Object newInstance(Object parent, Object[] args)
+ throws IllegalStateException {
+ return null;
+ }
+
+ @Override
+ public void resetValue(Object object) throws IllegalStateException,
+ IllegalArgumentException {
+ MapItem part = (MapItem) object;
+ part.setKey(null);
+ }
+
+ @Override
+ public void setValue(Object object, Object value)
+ throws IllegalStateException, IllegalArgumentException {
+ MapItem part = (MapItem) object;
+ part.setKey(TreeSPath.parseToCreatePath(value.toString()));
+ }
+
+}
--- /dev/null
+package org.argeo.slc.castor.test.tree;
+
+import org.argeo.slc.core.test.SimpleResultPart;
+import org.argeo.slc.core.test.SlcTestUtils;
+import org.argeo.slc.core.test.TestStatus;
+import org.exolab.castor.mapping.AbstractFieldHandler;
+
+public class StatusFieldHandler extends AbstractFieldHandler {
+
+ @Override
+ public Object getValue(Object object) throws IllegalStateException {
+ SimpleResultPart part = (SimpleResultPart) object;
+ return SlcTestUtils.statusToString(part.getStatus());
+ }
+
+ @Override
+ public Object newInstance(Object parent) throws IllegalStateException {
+ return null;
+ }
+
+ @Override
+ public Object newInstance(Object parent, Object[] args)
+ throws IllegalStateException {
+ return null;
+ }
+
+ @Override
+ public void resetValue(Object object) throws IllegalStateException,
+ IllegalArgumentException {
+ SimpleResultPart part = (SimpleResultPart) object;
+ // ERROR by default since it should be explicitely set
+ part.setStatus(TestStatus.ERROR);
+ }
+
+ @Override
+ public void setValue(Object object, Object value)
+ throws IllegalStateException, IllegalArgumentException {
+ SimpleResultPart part = (SimpleResultPart) object;
+ Integer status = SlcTestUtils.stringToStatus((String) value);
+ part.setStatus(status);
+ }
+
+}
--- /dev/null
+package org.argeo.slc.core;\r
+\r
+/** Basis for all SLC exceptions. This is an unchecked exception. */\r
+public class SlcException extends RuntimeException {\r
+ static final long serialVersionUID = 1l;\r
+\r
+ /** Constructor. */\r
+ public SlcException(String message) {\r
+ super(message);\r
+ }\r
+\r
+ /** Constructor. */\r
+ public SlcException(String message, Throwable cause) {\r
+ super(message, cause);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core;\r
+\r
+/** Exception for unsupported features or actions. */\r
+public class UnsupportedException extends SlcException {\r
+ static final long serialVersionUID = 1l;\r
+\r
+ /** Action not supported. */\r
+ public UnsupportedException() {\r
+ this("Action not supported");\r
+ }\r
+\r
+ /** Constructor with a message. */\r
+ public UnsupportedException(String message) {\r
+ super(message);\r
+ }\r
+\r
+ /**\r
+ * Constructor generating a message.\r
+ * \r
+ * @param nature\r
+ * the nature of the unsupported object\r
+ * @param obj\r
+ * the object itself (its class name will be used in message)\r
+ */\r
+ public UnsupportedException(String nature, Object obj) {\r
+ super("Unsupported " + nature + ": "\r
+ + (obj != null ? obj.getClass() : "[object is null]"));\r
+ }\r
+\r
+ /**\r
+ * Constructor generating a message.\r
+ * \r
+ * @param nature\r
+ * the nature of the unsupported object\r
+ * @param clss\r
+ * the class itself (will be used in message)\r
+ */\r
+ public UnsupportedException(String nature, Class<?> clss) {\r
+ super("Unsupported " + nature + ": " + clss);\r
+ }\r
+\r
+ /**\r
+ * Constructor generating a message.\r
+ * \r
+ * @param nature\r
+ * the nature of the unsupported object\r
+ * @param value\r
+ * the problematic value itself\r
+ */\r
+ public UnsupportedException(String nature, String value) {\r
+ super("Unsupported " + nature + ": " + value);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.build;\r
+\r
+public interface Distribution {\r
+ public String getDistributionId();\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.build;\r
+\r
+import java.util.StringTokenizer;\r
+\r
+/**\r
+ * <p>\r
+ * An implementation of the distribution id using the standard\r
+ * Major.Minor.Release notation. And additional arbitrary string can also be\r
+ * added.\r
+ * </p>\r
+ * \r
+ * <p>\r
+ * <b>Examples:</b><br>\r
+ * 0.2.6<br>\r
+ * 2.4.12.RC1\r
+ * </p>\r
+ */\r
+public class VersionDistributionId {\r
+\r
+ private Integer major;\r
+ private Integer minor;\r
+ private Integer release;\r
+ private String additional;\r
+\r
+ /** Parse the provided string in order to set the various components. */\r
+ public void setVersionString(String str) {\r
+ StringTokenizer st = new StringTokenizer(str, ".");\r
+ if (st.hasMoreTokens())\r
+ major = Integer.parseInt(st.nextToken());\r
+ if (st.hasMoreTokens())\r
+ minor = Integer.parseInt(st.nextToken());\r
+ if (st.hasMoreTokens())\r
+ release = Integer.parseInt(st.nextToken());\r
+ if (st.hasMoreTokens())\r
+ additional = st.nextToken();\r
+ }\r
+\r
+ public Integer getMajor() {\r
+ return major;\r
+ }\r
+\r
+ public void setMajor(Integer major) {\r
+ this.major = major;\r
+ }\r
+\r
+ public Integer getMinor() {\r
+ return minor;\r
+ }\r
+\r
+ public void setMinor(Integer minor) {\r
+ this.minor = minor;\r
+ }\r
+\r
+ public Integer getRelease() {\r
+ return release;\r
+ }\r
+\r
+ public void setRelease(Integer release) {\r
+ this.release = release;\r
+ }\r
+\r
+ public String getAdditional() {\r
+ return additional;\r
+ }\r
+\r
+ public void setAdditional(String additional) {\r
+ this.additional = additional;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ // TODO Auto-generated method stub\r
+ return super.equals(obj);\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return major + "." + minor + "." + release\r
+ + (additional != null ? "." + additional : "");\r
+ }\r
+\r
+}\r
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+SLC Build: building of software systems.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.core.deploy;
+
+import org.argeo.slc.core.UnsupportedException;
+import org.argeo.slc.core.build.Distribution;
+
+public abstract class AbstractDeployedSystem implements DeployedSystem {
+ public String getDeployedSystemId() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public DeploymentData getDeploymentData() {
+ throw new UnsupportedException("Method not supported");
+ }
+
+ public Distribution getDistribution() {
+ throw new UnsupportedException("Method not supported");
+ }
+
+ public TargetData getTargetData() {
+ throw new UnsupportedException("Method not supported");
+ }
+
+}
--- /dev/null
+package org.argeo.slc.core.deploy;
+
+import java.io.File;
+import java.util.Map;
+
+public interface DeployEnvironment {
+ public void unpackTo(Object packg, File targetLocation,
+ Map<String, String> filter);
+}
--- /dev/null
+package org.argeo.slc.core.deploy;\r
+\r
+import org.argeo.slc.core.build.Distribution;\r
+\r
+/** An instance of a software system. */\r
+public interface DeployedSystem extends TargetData {\r
+ public String getDeployedSystemId();\r
+\r
+ public Distribution getDistribution();\r
+\r
+ public DeploymentData getDeploymentData();\r
+\r
+ public TargetData getTargetData();\r
+}\r
--- /dev/null
+package org.argeo.slc.core.deploy;
+
+public interface DeployedSystemManager<T extends DeployedSystem> {
+ public void setDeployedSystem(T deployedSystem);
+}
--- /dev/null
+package org.argeo.slc.core.deploy;\r
+\r
+import org.argeo.slc.core.build.Distribution;\r
+\r
+public interface Deployment {\r
+ public DeployedSystem getDeployedSystem();\r
+\r
+ public void setTargetData(TargetData targetData);\r
+\r
+ public void setDeploymentData(DeploymentData deploymentData);\r
+\r
+ public void setDistribution(Distribution distribution);\r
+\r
+ public void execute();\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.deploy;\r
+\r
+public interface DeploymentData {\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.deploy;
+
+public interface InstalledExecutables extends DeployedSystem {
+ public String getExecutablePath(String key);
+}
--- /dev/null
+package org.argeo.slc.core.deploy;
+
+import java.io.File;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.core.build.Distribution;
+
+public class SimpleExecutables implements InstalledExecutables {
+ private final static Log log = LogFactory.getLog(SimpleExecutables.class);
+
+ private String baseDir;
+ private Map<String, String> paths = new TreeMap<String, String>();
+
+ private Distribution distribution;
+
+ public String getExecutablePath(String key) {
+ String path = paths.get(key);
+ if (path == null) {
+ if (log.isDebugEnabled())
+ log.debug("No executable path found for key " + key
+ + ", using the key as executable name.");
+ path = key;
+ }
+
+ if (baseDir != null)
+ path = baseDir + File.separator + path;
+ return path;
+ }
+
+ public String getDeployedSystemId() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public DeploymentData getDeploymentData() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Distribution getDistribution() {
+ return distribution;
+ }
+
+ public TargetData getTargetData() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getBaseDir() {
+ return baseDir;
+ }
+
+ public void setBaseDir(String baseDir) {
+ this.baseDir = baseDir;
+ }
+
+ public Map<String, String> getPaths() {
+ return paths;
+ }
+
+ public void setPaths(Map<String, String> paths) {
+ this.paths = paths;
+ }
+
+ public void setDistribution(Distribution distribution) {
+ this.distribution = distribution;
+ }
+
+}
--- /dev/null
+package org.argeo.slc.core.deploy;\r
+\r
+public interface TargetData {\r
+\r
+}\r
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+SLC Deploy: deployment of software systems.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+Common classes of teh SLC framework.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.core.process;\r
+\r
+import java.io.File;\r
+import java.io.FileWriter;\r
+import java.text.SimpleDateFormat;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import javax.xml.transform.stream.StreamResult;\r
+\r
+import org.apache.commons.io.IOUtils;\r
+import org.argeo.slc.core.SlcException;\r
+import org.springframework.oxm.Marshaller;\r
+\r
+public class FileSlcExecutionNotifier implements SlcExecutionNotifier {\r
+ private final static SimpleDateFormat sdf = new SimpleDateFormat(\r
+ "yyyyMMdd-HHmmss");\r
+\r
+ private String basePath;\r
+ private Marshaller marshaller;\r
+\r
+ private Map<String, String> uuidToDir = new HashMap<String, String>();\r
+\r
+ public void addSteps(SlcExecution slcExecution,\r
+ List<SlcExecutionStep> additionalSteps) {\r
+ writeSlcExecution(slcExecution);\r
+ }\r
+\r
+ public void newExecution(SlcExecution slcExecution) {\r
+ String dirPath = basePath + File.separator + sdf.format(new Date())\r
+ + '-' + slcExecution.getUuid();\r
+ File dir = new File(dirPath);\r
+ dir.mkdirs();\r
+\r
+ uuidToDir.put(slcExecution.getUuid(), dirPath);\r
+\r
+ writeSlcExecution(slcExecution);\r
+ }\r
+\r
+ public void updateExecution(SlcExecution slcExecution) {\r
+ writeSlcExecution(slcExecution);\r
+ }\r
+\r
+ public void updateStatus(SlcExecution slcExecution, String oldStatus,\r
+ String newStatus) {\r
+ writeSlcExecution(slcExecution);\r
+ }\r
+\r
+ protected void writeSlcExecution(SlcExecution slcExecution) {\r
+ FileWriter out = null;\r
+ try {\r
+ out = new FileWriter(getFilePath(slcExecution));\r
+ marshaller.marshal(slcExecution, new StreamResult(out));\r
+ } catch (Exception e) {\r
+ throw new SlcException("Cannot marshall SlcExecution to "\r
+ + getFilePath(slcExecution), e);\r
+ } finally {\r
+ IOUtils.closeQuietly(out);\r
+ }\r
+ }\r
+\r
+ protected String getFileName(SlcExecution slcExecution) {\r
+ return "SlcExecution-" + slcExecution.getUuid() + ".xml";\r
+ }\r
+\r
+ protected String getFilePath(SlcExecution slcExecution) {\r
+ String dirPath = uuidToDir.get(slcExecution.getUuid());\r
+ return dirPath + File.separator + "SlcExecution-"\r
+ + slcExecution.getUuid() + ".xml";\r
+ }\r
+\r
+ public void setBasePath(String basePath) {\r
+ this.basePath = basePath;\r
+ }\r
+\r
+ public void setMarshaller(Marshaller marshaller) {\r
+ this.marshaller = marshaller;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.process;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+import java.util.Vector;\r
+\r
+public class SlcExecution {\r
+ public final static String STATUS_SCHEDULED = "SCHEDULED";\r
+ public final static String STATUS_RUNNING = "RUNNING";\r
+ public final static String STATUS_FINISHED = "FINISHED";\r
+ public final static String STATUS_ERROR = "ERROR";\r
+ public final static String STATUS_CLEANED = "CLEANED";\r
+\r
+ public final static String UNKOWN_HOST = "UNKOWN_HOST";\r
+\r
+ private String uuid;\r
+ private String host;\r
+ private String user;\r
+ private String type;\r
+ private String status;\r
+ private Map<String, String> attributes = new TreeMap<String, String>();\r
+\r
+ private List<SlcExecutionStep> steps = new Vector<SlcExecutionStep>();\r
+\r
+ public List<SlcExecutionStep> getSteps() {\r
+ return steps;\r
+ }\r
+\r
+ public void setSteps(List<SlcExecutionStep> steps) {\r
+ this.steps = steps;\r
+ }\r
+\r
+ public String getUuid() {\r
+ return uuid;\r
+ }\r
+\r
+ public void setUuid(String uuid) {\r
+ this.uuid = uuid;\r
+ }\r
+\r
+ public String getHost() {\r
+ return host;\r
+ }\r
+\r
+ public void setHost(String host) {\r
+ this.host = host;\r
+ }\r
+\r
+ public String getUser() {\r
+ return user;\r
+ }\r
+\r
+ public void setUser(String user) {\r
+ this.user = user;\r
+ }\r
+\r
+ public String getType() {\r
+ return type;\r
+ }\r
+\r
+ public void setType(String type) {\r
+ this.type = type;\r
+ }\r
+\r
+ public String getStatus() {\r
+ return status;\r
+ }\r
+\r
+ public void setStatus(String status) {\r
+ this.status = status;\r
+ }\r
+\r
+ public SlcExecutionStep currentStep() {\r
+ if (steps.size() > 0)\r
+ return steps.get(steps.size() - 1);\r
+ else\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (obj instanceof SlcExecution) {\r
+ return getUuid().equals(((SlcExecution) obj).getUuid());\r
+ }\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public int hashCode() {\r
+ return getUuid().hashCode();\r
+ }\r
+\r
+ public Map<String, String> getAttributes() {\r
+ return attributes;\r
+ }\r
+\r
+ public void setAttributes(Map<String, String> attributes) {\r
+ this.attributes = attributes;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.process;\r
+\r
+public interface SlcExecutionAware {\r
+ public void notifySlcExecution(SlcExecution slcExecution);\r
+}\r
--- /dev/null
+package org.argeo.slc.core.process;\r
+\r
+import java.util.List;\r
+\r
+public interface SlcExecutionNotifier {\r
+ public void newExecution(SlcExecution slcExecution);\r
+\r
+ public void addSteps(SlcExecution slcExecution,\r
+ List<SlcExecutionStep> additionalSteps);\r
+\r
+ public void updateExecution(SlcExecution slcExecution);\r
+\r
+ public void updateStatus(SlcExecution slcExecution, String oldStatus,\r
+ String newStatus);\r
+}\r
--- /dev/null
+package org.argeo.slc.core.process;\r
+\r
+import java.io.IOException;\r
+import java.io.StringReader;\r
+import java.io.StringWriter;\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.UUID;\r
+import java.util.Vector;\r
+\r
+import org.apache.commons.io.IOUtils;\r
+\r
+public class SlcExecutionStep {\r
+ public final static String TYPE_LOG = "LOG";\r
+\r
+ private String uuid;\r
+ private String type;\r
+ private Date begin;\r
+ private List<String> logLines = new Vector<String>();\r
+\r
+ /** Empty constructor */\r
+ public SlcExecutionStep() {\r
+ }\r
+\r
+ public SlcExecutionStep(String log) {\r
+ this.type = TYPE_LOG;\r
+ this.begin = new Date();\r
+ this.uuid = UUID.randomUUID().toString();\r
+ addLog(log);\r
+ }\r
+\r
+ public String getUuid() {\r
+ return uuid;\r
+ }\r
+\r
+ public void setUuid(String uuid) {\r
+ this.uuid = uuid;\r
+ }\r
+\r
+ public String getType() {\r
+ return type;\r
+ }\r
+\r
+ public void setType(String type) {\r
+ this.type = type;\r
+ }\r
+\r
+ public Date getBegin() {\r
+ return begin;\r
+ }\r
+\r
+ public void setBegin(Date begin) {\r
+ this.begin = begin;\r
+ }\r
+\r
+ public List<String> getLogLines() {\r
+ return logLines;\r
+ }\r
+\r
+ public void setLogLines(List<String> logLines) {\r
+ this.logLines = logLines;\r
+ }\r
+\r
+ public String logAsString() {\r
+ StringWriter writer = new StringWriter();\r
+ String log = writer.toString();\r
+ IOUtils.closeQuietly(writer);\r
+ return log;\r
+ }\r
+\r
+ public void addLog(String log) {\r
+ if (log == null)\r
+ return;\r
+\r
+ try {\r
+ List<String> lines = IOUtils.readLines(new StringReader(log));\r
+ logLines.addAll(lines);\r
+ } catch (IOException e) {\r
+ throw new RuntimeException("Cannot add log", e);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return getClass().getSimpleName() + "#" + uuid;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.structure;\r
+\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+\r
+import org.argeo.slc.core.structure.tree.TreeSPath;\r
+\r
+/**\r
+ * Basic implementation of <code>StructureElement</code>.\r
+ * \r
+ * @see TreeSPath\r
+ */\r
+public class SimpleSElement implements StructureElement {\r
+ /** For ORM */\r
+ private Long tid;\r
+ private String label;\r
+ private Map<String, String> tags = new TreeMap<String, String>();\r
+\r
+ /** For ORM */\r
+ public SimpleSElement() {\r
+ }\r
+\r
+ /** Constructor */\r
+ public SimpleSElement(String label) {\r
+ this.label = label;\r
+ }\r
+\r
+ /** Constructor */\r
+ public SimpleSElement(String label, String defaultLabel) {\r
+ this(label != null ? label : defaultLabel);\r
+ }\r
+\r
+ /** Constructor */\r
+ public SimpleSElement(SimpleSElement sElement) {\r
+ setLabel(sElement.getLabel());\r
+ setTags(new TreeMap<String, String>(sElement.getTags()));\r
+ }\r
+\r
+ public String getLabel() {\r
+ return label;\r
+ }\r
+\r
+ /** Sets the label. */\r
+ public void setLabel(String label) {\r
+ this.label = label;\r
+ }\r
+\r
+ public Long getTid() {\r
+ return tid;\r
+ }\r
+\r
+ void setTid(Long tid) {\r
+ this.tid = tid;\r
+ }\r
+\r
+ public Map<String, String> getTags() {\r
+ return tags;\r
+ }\r
+\r
+ public void setTags(Map<String, String> tags) {\r
+ this.tags = tags;\r
+ }\r
+\r
+ @Override\r
+ public SimpleSElement clone() {\r
+ return new SimpleSElement(this);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.structure;\r
+\r
+/**\r
+ * Wrapper for an element, which is able to propagate registration to\r
+ * sub-elements.\r
+ */\r
+public interface StructureAware<T extends StructurePath> {\r
+ /** Called <b>after</b> registration. */\r
+ public void notifyCurrentPath(StructureRegistry<T> registry, T path);\r
+}\r
--- /dev/null
+package org.argeo.slc.core.structure;\r
+\r
+/**\r
+ * Atomic element holding metadata such as description about the element which\r
+ * registered.\r
+ */\r
+public interface StructureElement {\r
+ /** Label of this element. */\r
+ public String getLabel();\r
+}\r
--- /dev/null
+package org.argeo.slc.core.structure;\r
+\r
+public interface StructureElementProvider {\r
+ public StructureElement createStructureElement();\r
+}\r
--- /dev/null
+package org.argeo.slc.core.structure;\r
+\r
+/**\r
+ * Path allowing to uniquely identify a <code>StructureElement</code> within a\r
+ * registry.\r
+ * \r
+ * @see StructureElement\r
+ * @see StructurePath\r
+ */\r
+public interface StructurePath {\r
+ /**\r
+ * Unique representation as a string. Most implementation will also provide\r
+ * a mean to interpret this string.\r
+ */\r
+ public String getAsUniqueString();\r
+}\r
--- /dev/null
+package org.argeo.slc.core.structure;\r
+\r
+import java.util.List;\r
+\r
+/** Registry where the whole structure is stored. */\r
+public interface StructureRegistry<P extends StructurePath> {\r
+ /** Read mode: the structure is only read. */\r
+ public static String READ = "READ";\r
+ /** All mode: everything is executed regardless of the active paths. */\r
+ public static String ALL = "ALL";\r
+ /** Active mode: only the active paths are executed. */\r
+ public static String ACTIVE = "ACTIVE";\r
+\r
+ /** Adds an element to the registry. */\r
+ public void register(P path, StructureElement element);\r
+\r
+ /** Lists <b>all</b> registered elements. */\r
+ public List<StructureElement> listElements();\r
+\r
+ /** Lists <b>all</b> registered elements. */\r
+ public List<P> listPaths();\r
+\r
+ /** Gets a element based on its path. */\r
+ public <T extends StructureElement> T getElement(P path);\r
+\r
+ /**\r
+ * Set the interpreter mode: read, all or active.\r
+ * \r
+ * @see #READ\r
+ * @see #ALL\r
+ * @see #STATUS_ACTIVE\r
+ */\r
+ public void setMode(String mode);\r
+\r
+ /**\r
+ * Gets the current interpreter mode.\r
+ * \r
+ * @see #READ\r
+ * @see #ALL\r
+ * @see #STATUS_ACTIVE\r
+ */\r
+ public String getMode();\r
+\r
+ /**\r
+ * Gets the list of active paths, which will be run if executed in\r
+ * <code>STATUS_ACTIVE</code> mode.\r
+ */\r
+ public List<P> getActivePaths();\r
+\r
+ /**\r
+ * Sets the list of active path, which will be run if executed in\r
+ * <code>STATUS_ACTIVE</code> mode.\r
+ */\r
+ public void setActivePaths(List<P> activePaths);\r
+}\r
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+SLC Structure framework allowing to uniquely reference actions.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.core.structure.tree;\r
+\r
+import java.util.List;\r
+import java.util.StringTokenizer;\r
+import java.util.Vector;\r
+\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.core.structure.StructurePath;\r
+import org.argeo.slc.core.structure.StructureRegistry;\r
+\r
+/**\r
+ * Path for tree based <code>StructureRegistry</code> implementations.\r
+ */\r
+public class TreeSPath implements StructurePath, Comparable<StructurePath> {\r
+ /** Default character to use a separator: /. */\r
+ private static Character DEFAULT_SEPARATOR = '/';\r
+\r
+ private Character separator = DEFAULT_SEPARATOR;\r
+\r
+ private String asUniqueString;\r
+\r
+ /** For ORM */\r
+ private Long tid;\r
+\r
+ public TreeSPath() {\r
+\r
+ }\r
+\r
+ public TreeSPath(String asUniqueString) {\r
+ this.asUniqueString = checkAndFormatPath(asUniqueString);\r
+ }\r
+\r
+ public String getAsUniqueString() {\r
+ return asUniqueString;\r
+ }\r
+\r
+ /**\r
+ * Sets all the required data from a string. <b>ATTENTION</b>: the path is\r
+ * not checked for performance reason. This method should be used only by\r
+ * ORM/OXM frameworks. Use constructor to create immutable tree structure\r
+ * paths.\r
+ */\r
+ public void setAsUniqueString(String str) {\r
+ this.asUniqueString = str;\r
+ }\r
+\r
+ /** The separator actually used by this path. */\r
+ public Character getSeparator() {\r
+ return separator;\r
+ }\r
+\r
+ /** Gets the parent path. */\r
+ public TreeSPath getParent() {\r
+ int lastSep = getAsUniqueString().lastIndexOf(separator);\r
+ if (lastSep < 1) {\r
+ return null;\r
+ }\r
+ String parentUniqueString = getAsUniqueString().substring(0, lastSep);\r
+ return new TreeSPath(parentUniqueString);\r
+ }\r
+\r
+ /** Gets the name part of the path. */\r
+ public String getName() {\r
+ int lastSep = getAsUniqueString().lastIndexOf(separator);\r
+ return getAsUniqueString().substring(lastSep + 1);\r
+ }\r
+\r
+ /** Create a path without parent. */\r
+ public static TreeSPath createRootPath(String name) {\r
+ if (name.indexOf(DEFAULT_SEPARATOR) >= 0) {\r
+ throw new SlcException("Name cannot contain " + DEFAULT_SEPARATOR);\r
+ }\r
+ return new TreeSPath('/' + name);\r
+ }\r
+\r
+ /** Create a child . */\r
+ public TreeSPath createChild(String name) {\r
+ if (name.indexOf(separator) > -1) {\r
+ throw new SlcException("Tree path name '" + name\r
+ + "' contains separator character " + separator);\r
+ }\r
+ return new TreeSPath(getAsUniqueString() + '/' + name);\r
+ }\r
+\r
+ /**\r
+ * Parses a string to a path.\r
+ * \r
+ * @deprecated use constructor instead\r
+ */\r
+ public static TreeSPath parseToCreatePath(String path) {\r
+ return parseToCreatePath(path, DEFAULT_SEPARATOR);\r
+ }\r
+\r
+ protected String checkAndFormatPath(String str) {\r
+ if (str.length() < 2) {\r
+ throw new SlcException("Path " + str + " is not short");\r
+ }\r
+ if (str.charAt(0) != separator) {\r
+ throw new SlcException("Path " + str + " have to start with "\r
+ + separator);\r
+ }\r
+\r
+ StringBuffer buf = new StringBuffer(str.length() + 5);\r
+ StringTokenizer st = new StringTokenizer(str, separator.toString());\r
+ while (st.hasMoreTokens()) {\r
+ buf.append(separator).append(st.nextToken());\r
+ }\r
+ return buf.toString();\r
+ }\r
+\r
+ /**\r
+ * Parses a string to a path.\r
+ * \r
+ * @deprecated use constructor instead\r
+ */\r
+ public static TreeSPath parseToCreatePath(String path, Character separator) {\r
+ return new TreeSPath(path);\r
+ }\r
+\r
+ /** Lists the children from a registry. */\r
+ public List<TreeSPath> listChildren(StructureRegistry<TreeSPath> registry) {\r
+ return listChildrenPaths(registry, this);\r
+ }\r
+\r
+ /** Lists the children from a given path from a registry. */\r
+ public static List<TreeSPath> listChildrenPaths(\r
+ StructureRegistry<TreeSPath> registry, TreeSPath path) {\r
+ List<TreeSPath> paths = new Vector<TreeSPath>();\r
+ List<TreeSPath> allPaths = registry.listPaths();\r
+ for (TreeSPath pathT : allPaths) {\r
+ if (pathT.getParent() != null && pathT.getParent().equals(path)) {\r
+ paths.add(pathT);\r
+ }\r
+ }\r
+ return paths;\r
+ }\r
+\r
+ /** Gets the root tree path of this path. */\r
+ public TreeSPath getRoot() {\r
+ TreeSPath root = this;\r
+ while (root.getParent() != null) {\r
+ root = root.getParent();\r
+ }\r
+ return root;\r
+ }\r
+\r
+ /** Depth of this path. */\r
+ public Integer getDepth() {\r
+ return depthImpl(this);\r
+ }\r
+\r
+ protected int depthImpl(TreeSPath path) {\r
+ if (path.getParent() == null) {\r
+ return 1;\r
+ } else {\r
+ return depthImpl(path.getParent()) + 1;\r
+ }\r
+ }\r
+\r
+ public List<TreeSPath> getHierarchyAsList() {\r
+ List<TreeSPath> lst = new Vector<TreeSPath>();\r
+ addParentToList(lst, this);\r
+ lst.add(this);\r
+ return lst;\r
+ }\r
+\r
+ protected void addParentToList(List<TreeSPath> lst, TreeSPath current) {\r
+ TreeSPath parent = current.getParent();\r
+ if (parent != null) {\r
+ addParentToList(lst, parent);\r
+ lst.add(parent);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return getAsUniqueString();\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (obj instanceof StructurePath) {\r
+ StructurePath path = (StructurePath) obj;\r
+ return getAsUniqueString().equals(path.getAsUniqueString());\r
+ }\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public int hashCode() {\r
+ return getAsUniqueString().hashCode();\r
+ }\r
+\r
+ public int compareTo(StructurePath o) {\r
+ return getAsUniqueString().compareTo(o.getAsUniqueString());\r
+ }\r
+\r
+ public Long getTid() {\r
+ return tid;\r
+ }\r
+\r
+ void setTid(Long tid) {\r
+ this.tid = tid;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.structure.tree;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+import java.util.Vector;\r
+\r
+import org.argeo.slc.core.UnsupportedException;\r
+import org.argeo.slc.core.structure.SimpleSElement;\r
+import org.argeo.slc.core.structure.StructureElement;\r
+import org.argeo.slc.core.structure.StructureRegistry;\r
+\r
+/** Tree based implementation of a structure registry. */\r
+public class TreeSRegistry implements StructureRegistry<TreeSPath> {\r
+ /** For ORM */\r
+ private Long tid;\r
+ private Map<TreeSPath, SimpleSElement> elements = new TreeMap<TreeSPath, SimpleSElement>();\r
+\r
+ private String mode = StructureRegistry.ALL;\r
+\r
+ private List<TreeSPath> activePaths;\r
+\r
+ public <T extends StructureElement> T getElement(TreeSPath path) {\r
+ return (T) elements.get(path);\r
+ }\r
+\r
+ public List<StructureElement> listElements() {\r
+ return new Vector<StructureElement>(elements.values());\r
+ }\r
+\r
+ public List<TreeSPath> listPaths() {\r
+ return new Vector<TreeSPath>(elements.keySet());\r
+ }\r
+\r
+ public void register(TreeSPath path, StructureElement element) {\r
+ if (path == null)\r
+ throw new UnsupportedException("Cannot register under a null path.");\r
+ if (element == null)\r
+ throw new UnsupportedException(\r
+ "Cannot register null element for path " + path);\r
+ if (element.getLabel() == null)\r
+ throw new UnsupportedException(\r
+ "Cannot register an element with null label for path "\r
+ + path);\r
+\r
+ final SimpleSElement simpleSElement;\r
+ if (element instanceof SimpleSElement) {\r
+ simpleSElement = (SimpleSElement) element;\r
+ } else {\r
+ simpleSElement = new SimpleSElement(element.getLabel());\r
+ }\r
+\r
+ elements.put(path, simpleSElement);\r
+ }\r
+\r
+ public String getMode() {\r
+ return mode;\r
+ }\r
+\r
+ public void setMode(String mode) {\r
+ this.mode = mode;\r
+ }\r
+\r
+ public List<TreeSPath> getActivePaths() {\r
+ return activePaths;\r
+ }\r
+\r
+ public void setActivePaths(List<TreeSPath> activePaths) {\r
+ this.activePaths = activePaths;\r
+ }\r
+\r
+ /** Gets the elements. */\r
+ public Map<TreeSPath, SimpleSElement> getElements() {\r
+ return elements;\r
+ }\r
+\r
+ /** Sets the elements (for ORM). */\r
+ public void setElements(Map<TreeSPath, SimpleSElement> elements) {\r
+ this.elements = elements;\r
+ }\r
+\r
+ Long getTid() {\r
+ return tid;\r
+ }\r
+\r
+ void setTid(Long tid) {\r
+ this.tid = tid;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.structure.tree;\r
+\r
+import org.argeo.slc.core.structure.StructureAware;\r
+import org.argeo.slc.core.structure.StructureElement;\r
+import org.argeo.slc.core.structure.StructureRegistry;\r
+\r
+public interface TreeSRelated extends StructureAware<TreeSPath> {\r
+ public TreeSPath getBasePath();\r
+\r
+ public StructureRegistry<TreeSPath> getRegistry();\r
+\r
+ public StructureElement getStructureElement(String key);\r
+}\r
--- /dev/null
+package org.argeo.slc.core.structure.tree;\r
+\r
+import org.argeo.slc.core.structure.SimpleSElement;\r
+import org.argeo.slc.core.structure.StructureElement;\r
+import org.argeo.slc.core.structure.StructureRegistry;\r
+\r
+/**\r
+ * Provides default implementations of some methods of <code>TreeSRelated</code>.\r
+ */\r
+public abstract class TreeSRelatedHelper implements TreeSRelated {\r
+ private TreeSPath basePath;\r
+ private StructureRegistry<TreeSPath> registry;\r
+\r
+ public TreeSPath getBasePath() {\r
+ return basePath;\r
+ }\r
+\r
+ public StructureRegistry<TreeSPath> getRegistry() {\r
+ return registry;\r
+ }\r
+\r
+ public void notifyCurrentPath(StructureRegistry<TreeSPath> registry,\r
+ TreeSPath path) {\r
+ basePath = path;\r
+ this.registry = registry;\r
+ }\r
+\r
+ public StructureElement getStructureElement(String key) {\r
+ return new SimpleSElement(key);\r
+ }\r
+\r
+}\r
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+Tree-based implementation of the SLC structure framework.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+public class BasicTestData implements TestData {\r
+ private Object expected;\r
+ private Object reached;\r
+\r
+ public Object getExpected() {\r
+ return expected;\r
+ }\r
+\r
+ public void setExpected(Object expected) {\r
+ this.expected = expected;\r
+ }\r
+\r
+ public Object getReached() {\r
+ return reached;\r
+ }\r
+\r
+ public void setReached(Object reached) {\r
+ this.reached = reached;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.core.structure.tree.TreeSRelatedHelper;\r
+import org.argeo.slc.core.test.context.ContextAware;\r
+import org.argeo.slc.core.test.context.ContextUtils;\r
+\r
+/** Understands basic test data and context aware test data. */\r
+public class BasicTestDefinition extends TreeSRelatedHelper implements\r
+ TestDefinition {\r
+\r
+ public void execute(TestRun testRun) {\r
+ if (testRun.<TestData> getTestData() instanceof BasicTestData) {\r
+ BasicTestData testData = testRun.getTestData();\r
+ TestResult result = testRun.getTestResult();\r
+\r
+ try {\r
+ if (testData.getExpected().equals(testData.getReached())) {\r
+ result.addResultPart(new SimpleResultPart(\r
+ TestStatus.PASSED, "Reached and expected equals"));\r
+ } else {\r
+ result.addResultPart(new SimpleResultPart(\r
+ TestStatus.FAILED, "Expected "\r
+ + testData.getExpected() + " but reched "\r
+ + testData.getReached()));\r
+ }\r
+ } catch (Exception e) {\r
+ result.addResultPart(new SimpleResultPart(TestStatus.ERROR,\r
+ "Could not compare", e));\r
+ }\r
+ } else if (testRun.<TestData> getTestData() instanceof ContextAware) {\r
+ TestData testData = testRun.getTestData();\r
+ ContextUtils.compareReachedExpected((ContextAware) testData,\r
+ testRun.getTestResult(), this);\r
+ } else {\r
+ throw new SlcException("No test data defined.");\r
+ }\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+/** A test run that can be executed */\r
+public interface ExecutableTestRun extends TestRun {\r
+\r
+ /** Executes this test run. */\r
+ public void execute();\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+import org.argeo.slc.core.SlcException;\r
+\r
+/**\r
+ * Exception to throw when a test definition cannot interpret the provided test\r
+ * data.\r
+ */\r
+public class IncompatibleTestDataException extends SlcException {\r
+ static final long serialVersionUID = 1l;\r
+\r
+ public IncompatibleTestDataException(TestData testData,\r
+ TestDefinition testDefinition) {\r
+ super("TestData " + testData.getClass()\r
+ + " is not compatible with TestDefinition "\r
+ + testDefinition.getClass());\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+/**\r
+ * <p>\r
+ * Basic implementation of a result part, implementing the standard three status\r
+ * approach for test results.\r
+ * </p>\r
+ * \r
+ * @see TestStatus\r
+ */\r
+public class SimpleResultPart implements TestResultPart, TestStatus,\r
+ TestRunAware {\r
+\r
+ private Long tid;\r
+\r
+ private String testRunUuid;\r
+\r
+ /** The status. Default to ERROR since it should always be explicitely set. */\r
+ private Integer status = ERROR;\r
+ private String message;\r
+ private String exceptionMessage;\r
+\r
+ public SimpleResultPart() {\r
+ }\r
+\r
+ public SimpleResultPart(Integer status, String message) {\r
+ this(status, message, null);\r
+ }\r
+\r
+ public SimpleResultPart(Integer status, String message, Exception exception) {\r
+ this.status = status;\r
+ this.message = message;\r
+ setException(exception);\r
+ }\r
+\r
+ public String getMessage() {\r
+ return message;\r
+ }\r
+\r
+ public void setMessage(String message) {\r
+ this.message = message;\r
+ }\r
+\r
+ public void setStatus(Integer status) {\r
+ this.status = status;\r
+ }\r
+\r
+ public Integer getStatus() {\r
+ return status;\r
+ }\r
+\r
+ public String getExceptionMessage() {\r
+ return exceptionMessage;\r
+ }\r
+\r
+ public void setException(Exception exception) {\r
+ if (exception == null)\r
+ return;\r
+\r
+ StringBuffer buf = new StringBuffer("");\r
+ buf.append(exception.toString());\r
+ buf.append('\n');\r
+ for (StackTraceElement elem : exception.getStackTrace()) {\r
+ buf.append('\t').append(elem.toString()).append('\n');\r
+ }\r
+\r
+ if (exception.getCause() != null)\r
+ addRootCause(buf, exception.getCause());\r
+\r
+ this.exceptionMessage = buf.toString();\r
+ }\r
+\r
+ protected void addRootCause(StringBuffer buf, Throwable cause) {\r
+ if (cause == null)\r
+ return;\r
+\r
+ buf.append("Caused by: " + cause.getMessage());\r
+ for (StackTraceElement elem : cause.getStackTrace()) {\r
+ buf.append('\t').append(elem.toString()).append('\n');\r
+ }\r
+\r
+ if (cause.getCause() != null) {\r
+ addRootCause(buf, cause.getCause());\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ StringBuffer buf = new StringBuffer("");\r
+ buf.append(SlcTestUtils.statusToString(status));\r
+ if (status == PASSED || status == FAILED) {\r
+ buf.append(' ');\r
+ } else if (status == ERROR) {\r
+ buf.append(" ");\r
+ }\r
+ buf.append(message);\r
+ return buf.toString();\r
+ }\r
+\r
+ /** @deprecated */\r
+ Long getTid() {\r
+ return tid;\r
+ }\r
+\r
+ /** @deprecated */\r
+ void setTid(Long tid) {\r
+ this.tid = tid;\r
+ }\r
+\r
+ public String getTestRunUuid() {\r
+ return testRunUuid;\r
+ }\r
+\r
+ /** For ORM */\r
+ public void setTestRunUuid(String testRunUuid) {\r
+ this.testRunUuid = testRunUuid;\r
+ }\r
+\r
+ public void notifyTestRun(TestRun testRun) {\r
+ testRunUuid = testRun.getUuid();\r
+ }\r
+\r
+ public void setExceptionMessage(String exceptionMessage) {\r
+ this.exceptionMessage = exceptionMessage;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+import java.util.UUID;\r
+import java.util.Vector;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+\r
+import org.argeo.slc.core.SlcException;\r
+\r
+/**\r
+ * Basic implementation of a test result containing only a list of result parts.\r
+ */\r
+public class SimpleTestResult implements TestResult {\r
+ private static Log log = LogFactory.getLog(SimpleTestResult.class);\r
+\r
+ private String uuid;\r
+ private String currentTestRunUuid;\r
+\r
+ private Boolean throwError = true;\r
+\r
+ private Date closeDate;\r
+ private List<TestResultPart> parts = new Vector<TestResultPart>();\r
+\r
+ private Map<String, String> attributes = new TreeMap<String, String>();\r
+\r
+ public void addResultPart(TestResultPart part) {\r
+ if (throwError && part.getStatus() == ERROR) {\r
+ throw new SlcException(\r
+ "There was an error in the underlying test: "\r
+ + part.getExceptionMessage());\r
+ }\r
+ parts.add(part);\r
+ if (log.isDebugEnabled())\r
+ log.debug(part);\r
+ }\r
+\r
+ public void close() {\r
+ parts.clear();\r
+ closeDate = new Date();\r
+ }\r
+\r
+ public List<TestResultPart> getParts() {\r
+ return parts;\r
+ }\r
+\r
+ public Date getCloseDate() {\r
+ return closeDate;\r
+ }\r
+\r
+ public void setThrowError(Boolean throwError) {\r
+ this.throwError = throwError;\r
+ }\r
+\r
+ public void notifyTestRun(TestRun testRun) {\r
+ currentTestRunUuid = testRun.getUuid();\r
+ }\r
+\r
+ public String getUuid() {\r
+ if (uuid == null) {\r
+ uuid = UUID.randomUUID().toString();\r
+ }\r
+ return uuid;\r
+ }\r
+\r
+ public void setUuid(String uuid) {\r
+ this.uuid = uuid;\r
+ }\r
+\r
+ public String getCurrentTestRunUuid() {\r
+ return currentTestRunUuid;\r
+ }\r
+\r
+ public Map<String, String> getAttributes() {\r
+ return attributes;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+import java.util.UUID;\r
+\r
+import org.argeo.slc.core.deploy.DeployedSystem;\r
+import org.argeo.slc.core.process.SlcExecution;\r
+import org.argeo.slc.core.process.SlcExecutionStep;\r
+\r
+/**\r
+ * A basic bean implementation of a <code>WritableTestRun</code>, holding\r
+ * references to the various parts of a test run.\r
+ */\r
+public class SimpleTestRun implements WritableTestRun, ExecutableTestRun {\r
+ private String uuid;\r
+\r
+ private String slcExecutionUuid;\r
+ private String slcExecutionStepUuid;\r
+\r
+ private DeployedSystem deployedSystem;\r
+ private TestData testData;\r
+ private TestDefinition testDefinition;\r
+ private TestResult testResult;\r
+\r
+ /** Executes the underlying test definition. */\r
+ public void execute() {\r
+ uuid = UUID.randomUUID().toString();\r
+ if (testResult != null)\r
+ testResult.notifyTestRun(this);\r
+ testDefinition.execute(this);\r
+ }\r
+\r
+ public <T extends DeployedSystem> T getDeployedSystem() {\r
+ return (T) deployedSystem;\r
+ }\r
+\r
+ public void setDeployedSystem(DeployedSystem deployedSystem) {\r
+ this.deployedSystem = deployedSystem;\r
+ }\r
+\r
+ public <T extends TestData> T getTestData() {\r
+ return (T) testData;\r
+ }\r
+\r
+ public void setTestData(TestData testData) {\r
+ this.testData = testData;\r
+ }\r
+\r
+ public <T extends TestDefinition> T getTestDefinition() {\r
+ return (T) testDefinition;\r
+ }\r
+\r
+ public void setTestDefinition(TestDefinition testDefinition) {\r
+ this.testDefinition = testDefinition;\r
+ }\r
+\r
+ public <T extends TestResult> T getTestResult() {\r
+ return (T) testResult;\r
+ }\r
+\r
+ public void setTestResult(TestResult testResult) {\r
+ this.testResult = testResult;\r
+ }\r
+\r
+ public String getUuid() {\r
+ return uuid;\r
+ }\r
+\r
+ public void setUuid(String uuid) {\r
+ this.uuid = uuid;\r
+ }\r
+\r
+ public String getSlcExecutionUuid() {\r
+ return slcExecutionUuid;\r
+ }\r
+\r
+ public void setSlcExecutionUuid(String slcExecutionUuid) {\r
+ this.slcExecutionUuid = slcExecutionUuid;\r
+ }\r
+\r
+ public String getSlcExecutionStepUuid() {\r
+ return slcExecutionStepUuid;\r
+ }\r
+\r
+ public void setSlcExecutionStepUuid(String slcExecutionStepUuid) {\r
+ this.slcExecutionStepUuid = slcExecutionStepUuid;\r
+ }\r
+\r
+ public void notifySlcExecution(SlcExecution slcExecution) {\r
+ if (slcExecution != null) {\r
+ slcExecutionUuid = slcExecution.getUuid();\r
+ SlcExecutionStep step = slcExecution.currentStep();\r
+ if (step != null) {\r
+ slcExecutionStepUuid = step.getUuid();\r
+ }\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;
+
+import org.argeo.slc.core.SlcException;
+
+public abstract class SlcTestUtils {
+ public static String statusToString(Integer status) {
+ if (status.equals(TestStatus.PASSED)) {
+ return TestStatus.STATUSSTR_PASSED;
+ } else if (status.equals(TestStatus.FAILED)) {
+ return TestStatus.STATUSSTR_FAILED;
+ } else if (status.equals(TestStatus.ERROR)) {
+ return TestStatus.STATUSSTR_ERROR;
+ } else {
+ throw new SlcException("Unrecognized status " + status);
+ }
+ }
+
+ public static Integer stringToStatus(String statusStr) {
+ if (statusStr.equals(TestStatus.STATUSSTR_PASSED)) {
+ return TestStatus.PASSED;
+ } else if (statusStr.equals(TestStatus.STATUSSTR_FAILED)) {
+ return TestStatus.FAILED;
+ } else if (statusStr.equals(TestStatus.STATUSSTR_ERROR)) {
+ return TestStatus.ERROR;
+ } else {
+ throw new SlcException("Unrecognized status string " + statusStr);
+ }
+ }
+
+ private SlcTestUtils() {
+
+ }
+
+}
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+/**\r
+ * Any data required by a test in order to run: configuration, expected,\r
+ * reached, etc.\r
+ */\r
+public interface TestData {\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+public interface TestDataProvider {\r
+ public <T extends TestData> T getTestData(Class<T> clss, String key);\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+import org.argeo.slc.core.UnsupportedException;\r
+\r
+/** Utilities for dealing with test datas. */\r
+public class TestDataUtils {\r
+ /** Extracts the test data from the given provider. */\r
+ public static <T extends TestData> T getFromProvider(Object obj,\r
+ Class<T> clss, String key) {\r
+ if (obj instanceof TestDataProvider) {\r
+ TestDataProvider testDataProvider = (TestDataProvider) obj;\r
+ return testDataProvider.getTestData(clss, key);\r
+ } else {\r
+ throw new UnsupportedException("test data provider", obj);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Extracts the test data from the given provider using <code>null</code>\r
+ * as key.\r
+ */\r
+ public static <T extends TestData> T getFromProvider(Object obj,\r
+ Class<T> clss) {\r
+ return getFromProvider(obj, clss, null);\r
+ }\r
+\r
+ /**\r
+ * Returns it self after making the proper checks. Used for test data being\r
+ * their own data providers.\r
+ */\r
+ public static <T extends TestData> T getItSelf(Class<T> clss,\r
+ TestData testDataObject) {\r
+ if (clss.isAssignableFrom(testDataObject.getClass())) {\r
+ return (T) testDataObject;\r
+ } else {\r
+ throw new UnsupportedException("test data", testDataObject);\r
+ }\r
+\r
+ }\r
+\r
+ /** Makes sure this is an utility class. */\r
+ private TestDataUtils() {\r
+\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+/**\r
+ * The programmatic definition of a test, which will be associated with\r
+ * transient objects within a test run.\r
+ */\r
+public interface TestDefinition extends TestStatus {\r
+ /** Performs the test. */\r
+ public void execute(TestRun testRun);\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+/**\r
+ * A report that can be generated based on a given test result. <b>This\r
+ * interface may change in the future.</b>\r
+ */\r
+public interface TestReport {\r
+ /** Performs the actions necessary to generate a report. */\r
+ public void generateTestReport(TestResult result);\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+import java.util.Date;\r
+import java.util.Map;\r
+\r
+/** The result of a test */\r
+public interface TestResult extends TestStatus, TestRunAware {\r
+ public String getUuid();\r
+\r
+ /** Adds a part of the result. */\r
+ public void addResultPart(TestResultPart part);\r
+\r
+ /**\r
+ * Marks that the collection of test results is completed and free the\r
+ * related resources (also closing listeners).\r
+ */\r
+ public void close();\r
+\r
+ /**\r
+ * The date when this test result was closed. Can be null, which means the\r
+ * result is not closed.\r
+ */\r
+ public Date getCloseDate();\r
+\r
+ /** Additional arbitrary meta data */\r
+ public Map<String, String> getAttributes();\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+/** Listener to the operations on a test result. */\r
+public interface TestResultListener<T extends TestResult> {\r
+ /** Notified when a part was added to a test result. */\r
+ public void resultPartAdded(T testResult, TestResultPart testResultPart);\r
+\r
+ /** Stops listening and release the related resources. */\r
+ public void close(T testResult);\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+/**\r
+ * Part of a test result.\r
+ * \r
+ * @see TestResult\r
+ */\r
+public interface TestResultPart {\r
+ /** The status, as defined in {@link TestStatus}. */\r
+ public Integer getStatus();\r
+\r
+ /** The related message. */\r
+ public String getMessage();\r
+\r
+ /** The underlying <code>Exception</code>. Can be null. */\r
+ public String getExceptionMessage();\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+import org.argeo.slc.core.deploy.DeployedSystem;\r
+import org.argeo.slc.core.process.SlcExecutionAware;\r
+\r
+/** The actual run of a test */\r
+public interface TestRun extends SlcExecutionAware {\r
+ /** Gets UUID */\r
+ public String getUuid();\r
+\r
+ /** Gets the related test definition. */\r
+ public <T extends TestDefinition> T getTestDefinition();\r
+\r
+ /** Gets the related test data */\r
+ public <T extends TestData> T getTestData();\r
+\r
+ /** Gets the related deployed system. */\r
+ public <T extends DeployedSystem> T getDeployedSystem();\r
+\r
+ /** Gets the related result where to record results. */\r
+ public <T extends TestResult> T getTestResult();\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+public interface TestRunAware {\r
+ /** Notifies the current test run. */\r
+ public void notifyTestRun(TestRun testRun);\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+import org.argeo.slc.core.deploy.DeployedSystem;\r
+\r
+public class TestRunDescriptor {\r
+ private String testRunUuid;\r
+ private String slcExecutionUuid;\r
+ private String slcExecutionStepUuid;\r
+ private String testResultUuid;\r
+ private String deployedSytemId;\r
+\r
+ public TestRunDescriptor() {\r
+\r
+ }\r
+\r
+ public TestRunDescriptor(TestRun testRun) {\r
+ testRunUuid = testRun.getUuid();\r
+\r
+ if (testRun.getTestResult() != null)\r
+ testResultUuid = testRun.<TestResult> getTestResult().getUuid();\r
+\r
+ if (testRun.getDeployedSystem() != null)\r
+ deployedSytemId = testRun.<DeployedSystem> getDeployedSystem()\r
+ .getDeployedSystemId();\r
+\r
+ if (testRun instanceof SimpleTestRun) {\r
+ slcExecutionUuid = ((SimpleTestRun) testRun).getSlcExecutionUuid();\r
+ slcExecutionStepUuid = ((SimpleTestRun) testRun)\r
+ .getSlcExecutionStepUuid();\r
+ }\r
+ }\r
+\r
+ public String getTestRunUuid() {\r
+ return testRunUuid;\r
+ }\r
+\r
+ public void setTestRunUuid(String testRunUuid) {\r
+ this.testRunUuid = testRunUuid;\r
+ }\r
+\r
+ public String getSlcExecutionUuid() {\r
+ return slcExecutionUuid;\r
+ }\r
+\r
+ public void setSlcExecutionUuid(String slcExecutionUuid) {\r
+ this.slcExecutionUuid = slcExecutionUuid;\r
+ }\r
+\r
+ public String getSlcExecutionStepUuid() {\r
+ return slcExecutionStepUuid;\r
+ }\r
+\r
+ public void setSlcExecutionStepUuid(String slcExecutionStepUuid) {\r
+ this.slcExecutionStepUuid = slcExecutionStepUuid;\r
+ }\r
+\r
+ public String getTestResultUuid() {\r
+ return testResultUuid;\r
+ }\r
+\r
+ public void setTestResultUuid(String testResultUuid) {\r
+ this.testResultUuid = testResultUuid;\r
+ }\r
+\r
+ public String getDeployedSytemId() {\r
+ return deployedSytemId;\r
+ }\r
+\r
+ public void setDeployedSytemId(String deploymentId) {\r
+ this.deployedSytemId = deploymentId;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (obj instanceof TestRunDescriptor) {\r
+ return getTestRunUuid().equals(\r
+ ((TestRunDescriptor) obj).getTestRunUuid());\r
+ }\r
+ return false;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+/**\r
+ * Simple statuses.\r
+ * <p>\r
+ * <ul>\r
+ * <li>{@link #PASSED}: the test succeeded</li>\r
+ * <li>{@link #FAILED}: the test could run, but did not reach the expected\r
+ * result</li>\r
+ * <li>{@link #ERROR}: an error during the test run prevented to get a\r
+ * significant information on the tested system.</li>\r
+ * </ul>\r
+ * </p>\r
+ */\r
+public interface TestStatus {\r
+ /** The flag for a passed test: 0 */\r
+ public final static Integer PASSED = 0;\r
+ /** The flag for a failed test: 1 */\r
+ public final static Integer FAILED = 1;\r
+ /**\r
+ * The flag for a test which could not properly run because of an error\r
+ * (there is no feedback on the behavior of the tested component): 2\r
+ */\r
+ public final static Integer ERROR = 2;\r
+ public final static String STATUSSTR_PASSED = "PASSED";\r
+ public final static String STATUSSTR_FAILED = "FAILED";\r
+ public final static String STATUSSTR_ERROR = "ERROR";\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+import org.argeo.slc.core.deploy.DeployedSystem;\r
+\r
+/** Test run whose various components can be externally set. */\r
+public interface WritableTestRun extends ExecutableTestRun {\r
+ public void setDeployedSystem(DeployedSystem deployedSystem);\r
+\r
+ public void setTestData(TestData testData);\r
+\r
+ public void setTestDefinition(TestDefinition testDefinition);\r
+\r
+ public void setTestResult(TestResult testResult);\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.Map;\r
+\r
+public interface ContextAware {\r
+ public final static String DEFAULT_SKIP_FLAG = "!";\r
+ public final static String DEFAULT_ANY_FLAG = "*";\r
+\r
+ public Map<String, Object> getValues();\r
+\r
+ public void setValues(Map<String, Object> values);\r
+\r
+ public Map<String, Object> getExpectedValues();\r
+\r
+ public String getContextSkipFlag();\r
+\r
+ public String getContextAnyFlag();\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+\r
+import org.argeo.slc.core.structure.StructureAware;\r
+import org.argeo.slc.core.structure.StructureElement;\r
+import org.argeo.slc.core.structure.StructureRegistry;\r
+import org.argeo.slc.core.structure.tree.TreeSPath;\r
+import org.argeo.slc.core.structure.tree.TreeSRelated;\r
+import org.argeo.slc.core.test.SimpleResultPart;\r
+import org.argeo.slc.core.test.TestResult;\r
+import org.argeo.slc.core.test.TestStatus;\r
+\r
+public class ContextUtils {\r
+ private final static Log log = LogFactory.getLog(ContextUtils.class);\r
+\r
+ public static void compareReachedExpected(ContextAware contextAware,\r
+ TestResult testResult, TreeSRelated treeSRelated) {\r
+ for (String key : contextAware.getExpectedValues().keySet()) {\r
+\r
+ // Compare expected values with reached ones\r
+ Object expectedValue = contextAware.getExpectedValues().get(key);\r
+\r
+ if (expectedValue.toString().equals(\r
+ contextAware.getContextSkipFlag())) {\r
+ if (log.isDebugEnabled())\r
+ log.debug("Skipped check for key '" + key + "'");\r
+ continue;\r
+ }\r
+\r
+ // Register in structure\r
+ registerInStructure(testResult, treeSRelated, key);\r
+\r
+ if (contextAware.getValues().containsKey(key)) {\r
+ Object reachedValue = contextAware.getValues().get(key);\r
+\r
+ if (expectedValue.equals(contextAware.getContextAnyFlag())) {\r
+ testResult.addResultPart(new SimpleResultPart(\r
+ TestStatus.PASSED, "Expected any value for key '"\r
+ + key + "'"));\r
+ } else if (expectedValue.equals(reachedValue)) {\r
+ testResult.addResultPart(new SimpleResultPart(\r
+ TestStatus.PASSED, "Values matched for key '" + key\r
+ + "'"));\r
+ } else {\r
+ testResult.addResultPart(new SimpleResultPart(\r
+ TestStatus.FAILED, "Mismatch for key '" + key\r
+ + "': expected '" + expectedValue\r
+ + "' but reached '" + reachedValue + "'"));\r
+ }\r
+ } else {\r
+ testResult.addResultPart(new SimpleResultPart(\r
+ TestStatus.FAILED, "No value reached for key '" + key\r
+ + "'"));\r
+ }\r
+ resetStructure(testResult, treeSRelated);\r
+ }\r
+ }\r
+\r
+ private static void registerInStructure(TestResult testResult,\r
+ TreeSRelated treeSRelated, String key) {\r
+ if (treeSRelated != null) {\r
+ if (treeSRelated.getBasePath() != null) {\r
+ TreeSPath path = treeSRelated.getBasePath().createChild(key);\r
+ StructureRegistry<TreeSPath> registry = treeSRelated\r
+ .getRegistry();\r
+ final StructureElement element = treeSRelated\r
+ .getStructureElement(key);\r
+ registry.register(path, element);\r
+ if (testResult instanceof StructureAware)\r
+ ((StructureAware<TreeSPath>) testResult).notifyCurrentPath(\r
+ registry, path);\r
+\r
+ if (log.isDebugEnabled())\r
+ log.debug("Checking key " + key + " for path " + path);\r
+ }\r
+ }\r
+ }\r
+\r
+ private static void resetStructure(TestResult testResult,\r
+ TreeSRelated treeSRelated) {\r
+ if (treeSRelated != null) {\r
+ if (treeSRelated.getBasePath() != null) {\r
+ if (testResult instanceof StructureAware) {\r
+ ((StructureAware<TreeSPath>) testResult).notifyCurrentPath(\r
+ treeSRelated.getRegistry(), treeSRelated\r
+ .getBasePath());\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Makes sure that all children and sub-children of parent share the same\r
+ * maps for values and expected values.\r
+ */\r
+ public static void synchronize(ParentContextAware parent) {\r
+ Map<String, Object> expectedValuesCommon = new TreeMap<String, Object>(\r
+ parent.getExpectedValues());\r
+ synchronize(parent, expectedValuesCommon);\r
+ if (log.isDebugEnabled())\r
+ log.debug("Synchonized context " + parent);\r
+\r
+ }\r
+\r
+ private static void synchronize(ParentContextAware parent,\r
+ Map<String, Object> expectedValuesCommon) {\r
+ for (ContextAware child : parent.getChildContexts()) {\r
+ // Values\r
+ putNotContained(parent.getValues(), child.getValues());\r
+ child.setValues(parent.getValues());\r
+\r
+ // Expected Values\r
+ // Expected values reference is not overridden: each child has its\r
+ // own expected values map.\r
+ overrideContained(expectedValuesCommon, child.getExpectedValues());\r
+\r
+ // Creates a new Map in order not to disturb other context using the\r
+ // same keys\r
+ Map<String, Object> expectedValuesCommonChild = new TreeMap<String, Object>(\r
+ expectedValuesCommon);\r
+ putNotContained(expectedValuesCommonChild, child\r
+ .getExpectedValues());\r
+\r
+ if (child instanceof ParentContextAware) {\r
+ // Recursive sync\r
+ synchronize((ParentContextAware) child,\r
+ expectedValuesCommonChild);\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * Put into common map the values from child map which are not already\r
+ * defined in common map.\r
+ */\r
+ public static void putNotContained(Map<String, Object> commonMap,\r
+ Map<String, Object> childMap) {\r
+ for (String key : childMap.keySet()) {\r
+ if (!commonMap.containsKey(key)) {\r
+ commonMap.put(key, childMap.get(key));\r
+ }\r
+ }\r
+ }\r
+\r
+ /** Overrides child map values with the values already set in common map */\r
+ public static void overrideContained(Map<String, Object> commonMap,\r
+ Map<String, Object> childMap) {\r
+ for (String key : childMap.keySet()) {\r
+ if (commonMap.containsKey(key)) {\r
+ childMap.put(key, commonMap.get(key));\r
+ }\r
+ }\r
+ }\r
+\r
+ /** Makes sure this cannot be instantiated. */\r
+ private ContextUtils() {\r
+\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.context;\r
+\r
+import org.argeo.slc.core.test.TestData;\r
+import org.argeo.slc.core.test.TestDataProvider;\r
+import org.argeo.slc.core.test.TestDataUtils;\r
+\r
+public class DefaultContextTestData extends SimpleContextAware implements\r
+ TestData, TestDataProvider {\r
+\r
+ public <T extends TestData> T getTestData(Class<T> clss, String key) {\r
+ return TestDataUtils.getItSelf(clss, this);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.Collection;\r
+\r
+public interface ParentContextAware extends ContextAware {\r
+ public Collection<ContextAware> getChildContexts();\r
+\r
+ public void addChildContext(ContextAware contextAware);\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+\r
+import org.springframework.beans.factory.InitializingBean;\r
+\r
+import org.argeo.slc.core.SlcException;\r
+\r
+public class SimpleContextAware implements ContextAware, InitializingBean {\r
+ private ParentContextAware parentContext;\r
+\r
+ private Map<String, Object> values = new TreeMap<String, Object>();\r
+ private Map<String, Object> expectedValues = new TreeMap<String, Object>();\r
+\r
+ private String contextSkipFlag = DEFAULT_SKIP_FLAG;\r
+ private String contextAnyFlag = DEFAULT_ANY_FLAG;\r
+\r
+ public Map<String, Object> getValues() {\r
+ return values;\r
+ }\r
+\r
+ public void setValues(Map<String, Object> values) {\r
+ this.values = values;\r
+ }\r
+\r
+ public Map<String, Object> getExpectedValues() {\r
+ return expectedValues;\r
+ }\r
+\r
+ public void setExpectedValues(Map<String, Object> expectedValues) {\r
+ this.expectedValues = expectedValues;\r
+ }\r
+\r
+ /** Used to add this context as a child by setting a property. */\r
+ public void setParentContext(ParentContextAware parentContextAware) {\r
+ if (parentContext != null)\r
+ throw new SlcException("Parent context already set");\r
+ this.parentContext = parentContextAware;\r
+ this.parentContext.addChildContext(this);\r
+ }\r
+\r
+ protected ParentContextAware getParentContext() {\r
+ return parentContext;\r
+ }\r
+\r
+ public void afterPropertiesSet() throws Exception {\r
+ if (parentContext != null) {\r
+ ContextUtils.synchronize(parentContext);\r
+ }\r
+ }\r
+\r
+ public String getContextSkipFlag() {\r
+ return contextSkipFlag;\r
+ }\r
+\r
+ public void setContextSkipFlag(String contextSkipFlag) {\r
+ this.contextSkipFlag = contextSkipFlag;\r
+ }\r
+\r
+ public String getContextAnyFlag() {\r
+ return contextAnyFlag;\r
+ }\r
+\r
+ public void setContextAnyFlag(String contextAnyFlag) {\r
+ this.contextAnyFlag = contextAnyFlag;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.Collection;\r
+import java.util.List;\r
+import java.util.Vector;\r
+\r
+import org.springframework.beans.factory.InitializingBean;\r
+\r
+public class SimpleParentContextAware extends SimpleContextAware implements\r
+ ParentContextAware, InitializingBean {\r
+ private List<ContextAware> children = new Vector<ContextAware>();\r
+\r
+ public Collection<ContextAware> getChildContexts() {\r
+ return children;\r
+ }\r
+\r
+ public void addChildContext(ContextAware contextAware) {\r
+ children.add(contextAware);\r
+ }\r
+\r
+ @Override\r
+ public void afterPropertiesSet() throws Exception {\r
+ if (getParentContext() != null) {\r
+ // If has a parent, sync it.\r
+ super.afterPropertiesSet();\r
+ } else {\r
+ if (children.size() > 0) {\r
+ // No need to synchronize if no children\r
+ ContextUtils.synchronize(this);\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+Context variables to be passed between parts of tests.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+SLC Test: test of software systems.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.core.test.tree;\r
+\r
+import java.util.List;\r
+import java.util.Vector;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.core.structure.SimpleSElement;\r
+import org.argeo.slc.core.structure.StructureAware;\r
+import org.argeo.slc.core.structure.StructureElement;\r
+import org.argeo.slc.core.structure.StructureElementProvider;\r
+import org.argeo.slc.core.structure.StructureRegistry;\r
+import org.argeo.slc.core.structure.tree.TreeSPath;\r
+import org.argeo.slc.core.test.TestDefinition;\r
+import org.argeo.slc.core.test.TestResult;\r
+import org.argeo.slc.core.test.TestRun;\r
+\r
+/**\r
+ * Collection of test definitions propagating tree structure information to its\r
+ * children.\r
+ */\r
+public class CompositeTreeTestDefinition implements TestDefinition,\r
+ StructureAware<TreeSPath> {\r
+ private Log log = LogFactory.getLog(CompositeTreeTestDefinition.class);\r
+\r
+ private List<TestDefinition> tasks = null;\r
+ private List<TreeSPath> taskPaths = null;\r
+ private TreeSPath path;\r
+ private StructureRegistry<TreeSPath> registry;\r
+\r
+ public void execute(TestRun testRun) {\r
+ if (log.isTraceEnabled())\r
+ log.trace("Execute sequence of test definitions...");\r
+\r
+ int i = 0;\r
+ for (TestDefinition task : tasks) {\r
+ TestResult result = testRun.getTestResult();\r
+ if (result instanceof StructureAware) {\r
+ ((StructureAware) result).notifyCurrentPath(registry, taskPaths\r
+ .get(i));\r
+ }\r
+\r
+ task.execute(testRun);\r
+\r
+ // Reset current path in case it has been changed\r
+ if (result instanceof StructureAware) {\r
+ ((StructureAware) result).notifyCurrentPath(registry, path);\r
+ }\r
+ i++;\r
+ }\r
+ }\r
+\r
+ /** Sets the list of children test definitions */\r
+ public void setTasks(List<TestDefinition> tasks) {\r
+ this.tasks = tasks;\r
+ if (tasks != null) {\r
+ taskPaths = new Vector<TreeSPath>();\r
+ }\r
+ }\r
+\r
+ public void notifyCurrentPath(StructureRegistry<TreeSPath> registry,\r
+ TreeSPath path) {\r
+ this.path = path;\r
+ this.registry = registry;\r
+\r
+ // clear task paths\r
+ taskPaths.clear();\r
+\r
+ Integer count = 0;\r
+ for (TestDefinition task : tasks) {\r
+ final StructureElement element;\r
+ if (task instanceof StructureElementProvider) {\r
+ element = ((StructureElementProvider) task)\r
+ .createStructureElement();\r
+ } else {\r
+ element = new SimpleSElement("[no desc]");\r
+ }\r
+ TreeSPath taskPath = this.path.createChild(count.toString());\r
+ registry.register(taskPath, element);\r
+ taskPaths.add(taskPath);\r
+ if (task instanceof StructureAware) {\r
+ ((StructureAware<TreeSPath>) task).notifyCurrentPath(registry,\r
+ taskPath);\r
+ }\r
+ count++;\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.tree;\r
+\r
+import java.util.List;\r
+import java.util.Vector;\r
+\r
+import org.argeo.slc.core.test.TestResultPart;\r
+import org.argeo.slc.core.test.TestStatus;\r
+\r
+/**\r
+ * List of <code>TestResultPart</code>. It can be used to build complex\r
+ * <code>TestResult</code> affording the possibility to a\r
+ * <code>TestDefinition</code> to add a list of result part under the same\r
+ * <code>StructurePath</code>.\r
+ * \r
+ * @see TreeTestResult\r
+ */\r
+public class PartSubList {\r
+\r
+ /** For ORM */\r
+ private Long tid;\r
+\r
+ private List<TestResultPart> parts = new Vector<TestResultPart>();\r
+\r
+ /** Gets the result parts. */\r
+ public List<TestResultPart> getParts() {\r
+ return parts;\r
+ }\r
+\r
+ /** Sets the result parts. */\r
+ public void setParts(List<TestResultPart> parts) {\r
+ this.parts = parts;\r
+ }\r
+\r
+ Long getTid() {\r
+ return tid;\r
+ }\r
+\r
+ void setTid(Long tid) {\r
+ this.tid = tid;\r
+ }\r
+\r
+ public Boolean getIsPassed() {\r
+ for (TestResultPart part : parts) {\r
+ if (part.getStatus() != TestStatus.PASSED) {\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.tree;\r
+\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.SortedMap;\r
+import java.util.TreeMap;\r
+import java.util.Vector;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.core.structure.StructureAware;\r
+import org.argeo.slc.core.structure.StructureElement;\r
+import org.argeo.slc.core.structure.StructureRegistry;\r
+import org.argeo.slc.core.structure.tree.TreeSPath;\r
+import org.argeo.slc.core.test.TestResult;\r
+import org.argeo.slc.core.test.TestResultListener;\r
+import org.argeo.slc.core.test.TestResultPart;\r
+import org.argeo.slc.core.test.TestRun;\r
+import org.argeo.slc.core.test.TestRunAware;\r
+\r
+/**\r
+ * Complex implementation of a test result compatible with a tree based\r
+ * structure.\r
+ */\r
+public class TreeTestResult implements TestResult, StructureAware<TreeSPath>,\r
+ Comparable<TreeTestResult> {\r
+ private Log log = LogFactory.getLog(TreeTestResult.class);\r
+\r
+ private List<TestResultListener<TreeTestResult>> listeners = new Vector<TestResultListener<TreeTestResult>>();\r
+\r
+ private TreeSPath currentPath;\r
+ private TestRun currentTestRun;\r
+\r
+ private Date closeDate;\r
+\r
+ private Boolean isClosed = false;\r
+\r
+ private Boolean warnIfAlreadyClosed = true;\r
+\r
+ private String uuid;\r
+\r
+ private SortedMap<TreeSPath, PartSubList> resultParts = new TreeMap<TreeSPath, PartSubList>();\r
+ private SortedMap<TreeSPath, StructureElement> elements = new TreeMap<TreeSPath, StructureElement>();\r
+\r
+ private Map<String, String> attributes = new TreeMap<String, String>();\r
+\r
+ /** Sets the list of listeners. */\r
+ public void setListeners(List<TestResultListener<TreeTestResult>> listeners) {\r
+ this.listeners = listeners;\r
+ }\r
+\r
+ public void addResultPart(TestResultPart part) {\r
+ if (isClosed)\r
+ throw new SlcException("Cannot result parts to a closed result");\r
+\r
+ if (currentPath == null)\r
+ throw new SlcException("No current path set.");\r
+\r
+ PartSubList subList = resultParts.get(currentPath);\r
+ if (subList == null) {\r
+ subList = new PartSubList();\r
+ resultParts.put(currentPath, subList);\r
+ }\r
+ if (part instanceof TestRunAware && currentTestRun != null) {\r
+ ((TestRunAware) part).notifyTestRun(currentTestRun);\r
+ }\r
+ subList.getParts().add(part);\r
+\r
+ // notify listeners\r
+ synchronized (listeners) {\r
+ for (TestResultListener<TreeTestResult> listener : listeners) {\r
+ listener.resultPartAdded(this, part);\r
+ }\r
+ }\r
+ }\r
+\r
+ public void notifyCurrentPath(StructureRegistry<TreeSPath> registry,\r
+ TreeSPath path) {\r
+ if (registry != null) {\r
+ for (TreeSPath p : path.getHierarchyAsList()) {\r
+ if (!elements.containsKey(p)) {\r
+ StructureElement elem = registry.getElement(p);\r
+ if (elem != null) {\r
+ elements.put(p, elem);\r
+ }\r
+ } else {\r
+ if (log.isTraceEnabled())\r
+ log.trace("An element is already registered for path "\r
+ + p + " and was not updated");\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ currentPath = path;\r
+ }\r
+\r
+ /** Gets the current path. */\r
+ public TreeSPath getCurrentPath() {\r
+ return currentPath;\r
+ }\r
+\r
+ /** Gets all the results structured as a map of <code>PartSubList<code>s. */\r
+ public SortedMap<TreeSPath, PartSubList> getResultParts() {\r
+ return resultParts;\r
+ }\r
+\r
+ /** Used by ORM systems. */\r
+ void setResultParts(SortedMap<TreeSPath, PartSubList> resultParts) {\r
+ this.resultParts = resultParts;\r
+ }\r
+\r
+ public void close() {\r
+ if (resultParts.size() == 0) {\r
+ if (log.isTraceEnabled())\r
+ log.trace("Test Result #" + getUuid()\r
+ + " contains no results, no need to close it.");\r
+ return;\r
+ }\r
+\r
+ if (isClosed) {\r
+ if (warnIfAlreadyClosed)\r
+ log.warn("Test Result #" + getUuid()\r
+ + " already closed. Doing nothing.");\r
+ return;\r
+ }\r
+\r
+ closeDate = new Date();\r
+\r
+ synchronized (listeners) {\r
+ for (TestResultListener<TreeTestResult> listener : listeners) {\r
+ listener.close(this);\r
+ }\r
+ listeners.clear();\r
+ }\r
+ isClosed = true;\r
+\r
+ if (log.isTraceEnabled())\r
+ log.trace("Test Result " + getUuid() + " closed.");\r
+ }\r
+\r
+ public Date getCloseDate() {\r
+ return closeDate;\r
+ }\r
+\r
+ /** Sets the close date (for ORM) */\r
+ public void setCloseDate(Date closeDate) {\r
+ this.closeDate = closeDate;\r
+ }\r
+\r
+ public void notifyTestRun(TestRun testRun) {\r
+ currentTestRun = testRun;\r
+ }\r
+\r
+ public SortedMap<TreeSPath, StructureElement> getElements() {\r
+ return elements;\r
+ }\r
+\r
+ public void setElements(SortedMap<TreeSPath, StructureElement> pathNames) {\r
+ this.elements = pathNames;\r
+ }\r
+\r
+ public String getUuid() {\r
+ return uuid;\r
+ }\r
+\r
+ public void setUuid(String uuid) {\r
+ this.uuid = uuid;\r
+ }\r
+\r
+ public SortedMap<TreeSPath, StructureElement> getRelatedElements(\r
+ TreeSPath path) {\r
+ if (path == null)\r
+ throw new SlcException(\r
+ "Cannot retrieve element for a null path in result #"\r
+ + uuid);\r
+\r
+ SortedMap<TreeSPath, StructureElement> relatedElements = new TreeMap<TreeSPath, StructureElement>();\r
+ List<TreeSPath> hierarchy = path.getHierarchyAsList();\r
+ for (TreeSPath currPath : elements.keySet()) {\r
+ if (hierarchy.contains(currPath)) {\r
+ relatedElements.put(currPath, elements.get(currPath));\r
+ }\r
+ }\r
+ return relatedElements;\r
+ }\r
+\r
+ public TestRun getCurrentTestRun() {\r
+ return currentTestRun;\r
+ }\r
+\r
+ public int compareTo(TreeTestResult ttr2) {\r
+ TreeTestResult ttr1 = this;\r
+ if (ttr1.getCloseDate() != null && ttr2.getCloseDate() != null) {\r
+ return -ttr1.getCloseDate().compareTo(ttr2.getCloseDate());\r
+ } else if (ttr1.getCloseDate() != null && ttr2.getCloseDate() == null) {\r
+ return 1;\r
+ } else if (ttr1.getCloseDate() == null && ttr2.getCloseDate() != null) {\r
+ return -1;\r
+ } else {\r
+ return ttr1.getUuid().compareTo(ttr2.getUuid());\r
+ }\r
+ }\r
+\r
+ public Map<String, String> getAttributes() {\r
+ return attributes;\r
+ }\r
+\r
+ public void setAttributes(Map<String, String> attributes) {\r
+ this.attributes = attributes;\r
+ }\r
+\r
+ public void setWarnIfAlreadyClosed(Boolean warnIfAlreadyClosed) {\r
+ this.warnIfAlreadyClosed = warnIfAlreadyClosed;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.tree;\r
+\r
+import java.util.SortedSet;\r
+import java.util.TreeSet;\r
+\r
+public class TreeTestResultCollection implements\r
+ Comparable<TreeTestResultCollection> {\r
+ private String id;\r
+ private SortedSet<TreeTestResult> results = new TreeSet<TreeTestResult>();\r
+\r
+ public TreeTestResultCollection() {\r
+ }\r
+\r
+ public TreeTestResultCollection(String id) {\r
+ this.id = id;\r
+ }\r
+\r
+ public String getId() {\r
+ return id;\r
+ }\r
+\r
+ public void setId(String id) {\r
+ this.id = id;\r
+ }\r
+\r
+ public SortedSet<TreeTestResult> getResults() {\r
+ return results;\r
+ }\r
+\r
+ public void setResults(SortedSet<TreeTestResult> results) {\r
+ this.results = results;\r
+ }\r
+\r
+ public int compareTo(TreeTestResultCollection o) {\r
+ return getId().compareTo(o.getId());\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object o) {\r
+ if (o instanceof TreeTestResultCollection) {\r
+ return getId().equals(((TreeTestResultCollection) o).getId());\r
+ }\r
+ return false;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.tree;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+\r
+import org.argeo.slc.core.test.TestResultListener;\r
+import org.argeo.slc.core.test.TestResultPart;\r
+import org.argeo.slc.core.test.TestStatus;\r
+\r
+/**\r
+ * Listener logging tree-based test results to the underlying logging system.\r
+ * \r
+ * @see TreeTestResult\r
+ * \r
+ */\r
+public class TreeTestResultLogger implements TestResultListener<TreeTestResult> {\r
+\r
+ private static Log log = LogFactory.getLog(TreeTestResultLogger.class);\r
+\r
+ private Boolean logExceptionMessages = false;\r
+\r
+ public void resultPartAdded(TreeTestResult testResult,\r
+ TestResultPart testResultPart) {\r
+ String msg = testResultPart + " - " + testResult.getUuid() + ":"\r
+ + testResult.getCurrentPath();\r
+ if (testResultPart.getStatus().equals(TestStatus.PASSED)) {\r
+ log.info(msg);\r
+ } else if (testResultPart.getStatus().equals(TestStatus.FAILED)) {\r
+ log.warn(msg);\r
+ } else if (testResultPart.getStatus().equals(TestStatus.ERROR)) {\r
+ if (logExceptionMessages)\r
+ msg = msg + "\n" + testResultPart.getExceptionMessage();\r
+\r
+ log.error(msg);\r
+\r
+ if (!logExceptionMessages || log.isDebugEnabled())\r
+ log.debug(testResultPart.getExceptionMessage());\r
+\r
+ } else {\r
+ log.error("Unknow test status: " + msg);\r
+ }\r
+ }\r
+\r
+ public void close(TreeTestResult testResult) {\r
+ log.info("Test result " + testResult.getUuid() + " closed.");\r
+ }\r
+\r
+ public void setLogExceptionMessages(Boolean logExceptionMessages) {\r
+ this.logExceptionMessages = logExceptionMessages;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.tree;\r
+\r
+import java.io.File;\r
+import java.io.FileOutputStream;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+\r
+import javax.xml.parsers.DocumentBuilder;\r
+import javax.xml.parsers.DocumentBuilderFactory;\r
+import javax.xml.transform.Templates;\r
+import javax.xml.transform.Transformer;\r
+import javax.xml.transform.TransformerFactory;\r
+import javax.xml.transform.dom.DOMResult;\r
+import javax.xml.transform.dom.DOMSource;\r
+import javax.xml.transform.stream.StreamResult;\r
+import javax.xml.transform.stream.StreamSource;\r
+\r
+import org.springframework.core.io.Resource;\r
+import org.springframework.oxm.Marshaller;\r
+import org.springframework.xml.transform.StringResult;\r
+import org.w3c.dom.Document;\r
+\r
+import org.apache.commons.io.IOUtils;\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.core.test.TestResultListener;\r
+import org.argeo.slc.core.test.TestResultPart;\r
+\r
+public class XsltReportGenerator implements TestResultListener<TreeTestResult> {\r
+ private Log log = LogFactory.getLog(getClass());\r
+\r
+ private DocumentBuilder documentBuilder = null;\r
+\r
+ private Resource xsltStyleSheet;\r
+\r
+ private Templates templates;\r
+\r
+ private Marshaller marshaller;\r
+\r
+ private String outputDir;\r
+ private String outputFileExtension = "html";\r
+\r
+ private Boolean logXml = false;\r
+\r
+ public void init() {\r
+ if (templates != null)\r
+ return;\r
+\r
+ if (xsltStyleSheet == null)\r
+ throw new SlcException("XSLT style sheet not specified.");\r
+\r
+ InputStream in = null;\r
+ try {\r
+ TransformerFactory transformerFactory = TransformerFactory\r
+ .newInstance();\r
+ in = xsltStyleSheet.getInputStream();\r
+ StreamSource xsltSource = new StreamSource(in);\r
+ templates = transformerFactory.newTemplates(xsltSource);\r
+ } catch (Exception e) {\r
+ throw new SlcException("Could not initialize templates", e);\r
+ } finally {\r
+ IOUtils.closeQuietly(in);\r
+ }\r
+ }\r
+\r
+ public void resultPartAdded(TreeTestResult testResult,\r
+ TestResultPart testResultPart) {\r
+\r
+ }\r
+\r
+ public void close(TreeTestResult testResult) {\r
+ if (templates == null)\r
+ throw new SlcException("XSLT template not initialized");\r
+\r
+ File file = getFile(testResult);\r
+ OutputStream out = null;\r
+\r
+ try {\r
+ Transformer transformer = templates.newTransformer();\r
+\r
+ if (documentBuilder == null)\r
+ documentBuilder = DocumentBuilderFactory.newInstance()\r
+ .newDocumentBuilder();\r
+\r
+ Document document = documentBuilder.newDocument();\r
+ DOMResult marshallResult = new DOMResult(document);\r
+ marshaller.marshal(testResult, marshallResult);\r
+\r
+ if (logXml) {\r
+ Transformer identityTransformer = TransformerFactory\r
+ .newInstance().newTransformer();\r
+ StringResult xmlResult = new StringResult();\r
+ identityTransformer.transform(new DOMSource(marshallResult\r
+ .getNode()), xmlResult);\r
+ log.info("Marshalled XML:\n" + xmlResult);\r
+ }\r
+\r
+ DOMSource transfoSource = new DOMSource(marshallResult.getNode());\r
+\r
+ if (outputDir != null) {\r
+ File dir = new File(outputDir);\r
+ dir.mkdirs();\r
+ out = new FileOutputStream(file);\r
+ StreamResult outputResult = new StreamResult(out);\r
+ transformer.transform(transfoSource, outputResult);\r
+ } else {\r
+ // print on console if no output dir\r
+ StringResult result = new StringResult();\r
+ transformer.transform(transfoSource, result);\r
+ log.info("Generated report:\n" + result);\r
+ }\r
+ } catch (Exception e) {\r
+ throw new SlcException(\r
+ "Could not transform test result to " + file, e);\r
+ } finally {\r
+ IOUtils.closeQuietly(out);\r
+ }\r
+ }\r
+\r
+ public Resource getXsltStyleSheet() {\r
+ return xsltStyleSheet;\r
+ }\r
+\r
+ public void setXsltStyleSheet(Resource xsltStyleSheet) {\r
+ this.xsltStyleSheet = xsltStyleSheet;\r
+ }\r
+\r
+ public void setTemplates(Templates templates) {\r
+ this.templates = templates;\r
+ }\r
+\r
+ public void setMarshaller(Marshaller marshaller) {\r
+ this.marshaller = marshaller;\r
+ }\r
+\r
+ public void setOutputDir(String outputDir) {\r
+ this.outputDir = outputDir;\r
+ }\r
+\r
+ public void setOutputFileExtension(String outputFileExtension) {\r
+ this.outputFileExtension = outputFileExtension;\r
+ }\r
+\r
+ protected File getFile(TreeTestResult result) {\r
+ Long time = System.currentTimeMillis();\r
+ return new File(outputDir + File.separator + time + "-"\r
+ + result.getUuid() + "." + outputFileExtension);\r
+ }\r
+\r
+ public void setLogXml(Boolean logXml) {\r
+ this.logXml = logXml;\r
+ }\r
+\r
+}\r
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+Extension of SLC Test integrating tree-based structure.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.dao.process;\r
+\r
+import java.util.List;\r
+\r
+import org.argeo.slc.core.process.SlcExecution;\r
+import org.argeo.slc.core.process.SlcExecutionStep;\r
+\r
+public interface SlcExecutionDao {\r
+ public void create(SlcExecution slcExecution);\r
+\r
+ public void update(SlcExecution slcExecution);\r
+\r
+ public void merge(SlcExecution slcExecution);\r
+\r
+ public SlcExecution getSlcExecution(String uuid);\r
+\r
+ public List<SlcExecution> listSlcExecutions();\r
+\r
+ public void addSteps(String slcExecutionId,\r
+ List<SlcExecutionStep> additionalSteps);\r
+}\r
--- /dev/null
+package org.argeo.slc.dao.test;\r
+\r
+import java.util.Date;\r
+import java.util.List;\r
+\r
+import org.argeo.slc.core.test.TestResult;\r
+\r
+/**\r
+ * The dao for <code>TestResult</code>.\r
+ * \r
+ * @see TestResult\r
+ */\r
+public interface TestResultDao<T extends TestResult> {\r
+ /** Gets a test result based on its id. */\r
+ public T getTestResult(String uuid);\r
+\r
+ /** Persists a new test result. */\r
+ public void create(TestResult testResult);\r
+\r
+ /** Updates an already persisted test result. */\r
+ public void update(TestResult testResult);\r
+\r
+ /** Lists all test results. */\r
+ public List<T> listTestResults();\r
+\r
+ public void close(String id, Date closeDate);\r
+}\r
--- /dev/null
+package org.argeo.slc.dao.test;\r
+\r
+import org.argeo.slc.core.test.TestRunDescriptor;\r
+\r
+public interface TestRunDescriptorDao {\r
+ public TestRunDescriptor getTestRunDescriptor(String id);\r
+\r
+ public void saveOrUpdate(TestRunDescriptor testRunDescriptor);\r
+}\r
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+Data Access Objects for SLC Test.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.dao.test.tree;\r
+\r
+import java.util.SortedSet;\r
+\r
+import org.argeo.slc.core.test.tree.TreeTestResultCollection;\r
+\r
+public interface TreeTestResultCollectionDao {\r
+ public void create(TreeTestResultCollection ttrCollection);\r
+\r
+ public void update(TreeTestResultCollection ttrCollection);\r
+\r
+ public TreeTestResultCollection getTestResultCollection(String id);\r
+\r
+ public SortedSet<TreeTestResultCollection> listCollections();\r
+\r
+ public void addResultToCollection(TreeTestResultCollection ttrc,\r
+ String resultUuid);\r
+\r
+ public void removeResultFromCollection(TreeTestResultCollection ttrc,\r
+ String resultUuid);\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.dao.test.tree;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.argeo.slc.core.structure.StructureElement;\r
+import org.argeo.slc.core.structure.tree.TreeSPath;\r
+import org.argeo.slc.core.test.SimpleResultPart;\r
+import org.argeo.slc.core.test.tree.TreeTestResult;\r
+import org.argeo.slc.dao.test.TestResultDao;\r
+\r
+public interface TreeTestResultDao extends TestResultDao<TreeTestResult> {\r
+ /** Lists results containing this path */\r
+ public List<TreeTestResult> listResults(TreeSPath path);\r
+\r
+ public void addResultPart(String testResultId, TreeSPath path,\r
+ SimpleResultPart resultPart,\r
+ Map<TreeSPath, StructureElement> relatedElements);\r
+\r
+ public void updateAttributes(String testResultId,\r
+ Map<String, String> attributes);\r
+}\r
--- /dev/null
+package org.argeo.slc.dao.test.tree;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+\r
+import org.argeo.slc.core.test.TestResultListener;\r
+import org.argeo.slc.core.test.TestResultPart;\r
+import org.argeo.slc.core.test.tree.TreeTestResult;\r
+\r
+/**\r
+ * Listener persisting tree-based results.\r
+ * \r
+ * @see TreeTestResult\r
+ */\r
+public class TreeTestResultPersister implements\r
+ TestResultListener<TreeTestResult> {\r
+ private static Log log = LogFactory.getLog(TreeTestResultPersister.class);\r
+\r
+ private TreeTestResultDao testResultDao;\r
+\r
+ public void resultPartAdded(TreeTestResult testResult,\r
+ TestResultPart testResultPart) {\r
+ try {\r
+ TreeTestResult persistedResult = testResultDao\r
+ .getTestResult(testResult.getUuid());\r
+\r
+ if (persistedResult == null) {\r
+ testResultDao.create(testResult);\r
+ } else {\r
+ testResultDao.update(testResult);\r
+ }\r
+ } catch (Exception e) {\r
+ log.error("Could not persist result part " + testResultPart\r
+ + " for result " + testResult.getUuid());\r
+ }\r
+ }\r
+\r
+ public void close(TreeTestResult testResult) {\r
+ TreeTestResult persistedResult = (TreeTestResult) testResultDao\r
+ .getTestResult(testResult.getUuid());\r
+\r
+ if (persistedResult != null) {\r
+ persistedResult.setCloseDate(testResult.getCloseDate());\r
+ testResultDao.update(persistedResult);\r
+ }\r
+ if (log.isDebugEnabled())\r
+ log.debug("Closed result persister for result "\r
+ + testResult.getUuid());\r
+ }\r
+\r
+ /** Sets the DAO to use in order to persist the results. */\r
+ public void setTestResultDao(TreeTestResultDao testResultDao) {\r
+ this.testResultDao = testResultDao;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+/**\r
+ * Converts data into a format better adapted for comparison. It is typically\r
+ * used to convert <code>String</code> into typed format such as\r
+ * <code>BigDecimal</code>\r
+ */\r
+public interface DataInterpreter {\r
+ /**\r
+ * Converts data\r
+ * \r
+ * @param key\r
+ * any object used to differentiate the type of data (e.g.\r
+ * column, path)\r
+ * @param value\r
+ * the data to convert\r
+ * @return the converted object\r
+ */\r
+ public Object convert(Object key, Object value);\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+import org.springframework.core.io.Resource;\r
+\r
+/** A comparator providing structured information about the differences found. */\r
+public interface Diff {\r
+ /** Performs the comparison. */\r
+ public DiffResult compare(Resource expected, Resource reached);\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+/** The root class for issues which happened during a diff. */\r
+public abstract class DiffIssue implements Comparable<DiffIssue> {\r
+ /** The position of this issue. */\r
+ protected final DiffPosition position;\r
+\r
+ /** Constructor */\r
+ public DiffIssue(DiffPosition position) {\r
+ super();\r
+ this.position = position;\r
+ }\r
+\r
+ public int compareTo(DiffIssue o) {\r
+ return position.compareTo(o.position);\r
+ }\r
+\r
+ /** The position of this issue within the test file */\r
+ public DiffPosition getPosition() {\r
+ return position;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+/** Intermediate class that can hold the key to be displayed. */\r
+public abstract class DiffIssueKey extends DiffIssue {\r
+ /** The position of this issue. */\r
+ protected DiffKey key;\r
+\r
+ /** Constructor without key */\r
+ public DiffIssueKey(DiffPosition position) {\r
+ super(position);\r
+ }\r
+\r
+ /** Constructor with key */\r
+ public DiffIssueKey(DiffPosition position, DiffKey key) {\r
+ super(position);\r
+ this.key = key;\r
+ }\r
+\r
+ public Object getKey() {\r
+ return key;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ if (key != null) {\r
+ return key.toString();\r
+ } else {\r
+ return "";\r
+ }\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+/**\r
+ * Object able to uniquely identify an atomic diff part. Used to identify\r
+ * missings and left-overs.\r
+ */\r
+public interface DiffKey {\r
+ public String toString();\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+/**\r
+ * A value missing in one of the file. If its position is related to expected,\r
+ * this means it is a left over in the reached, if its position is related to\r
+ * the reached it means that it is missing from the reached. If the value is\r
+ * null it means that the entire line is missing.\r
+ */\r
+public class DiffMissing extends DiffIssueKey {\r
+\r
+ public DiffMissing(DiffPosition position, DiffKey key) {\r
+ super(position);\r
+ super.key = key;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ if (position.relatedFile == RelatedFile.EXPECTED) {\r
+ return position + ": left over " + super.toString();\r
+ } else if (position.relatedFile == RelatedFile.REACHED) {\r
+ return position + ": missing " + super.toString();\r
+ }\r
+ return super.toString();\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+/**\r
+ * <code>DiffMissing</code> using the XPath of the position as\r
+ * <code>DiffKey</code>\r
+ */\r
+public class DiffMissingXml extends DiffMissing {\r
+\r
+ public DiffMissingXml(XPathDiffPosition position) {\r
+ super(position, new DiffKeyXml(position.getXPath()));\r
+ }\r
+\r
+ /** Implementation of <code>DiffKey</code> based on an XPath string. */\r
+ protected static class DiffKeyXml implements DiffKey {\r
+ private final String xPath;\r
+\r
+ public DiffKeyXml(String xPath) {\r
+ this.xPath = xPath;\r
+ }\r
+\r
+ public String getXPath() {\r
+ return xPath;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return xPath;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (!(obj instanceof DiffKeyXml))\r
+ return false;\r
+ return xPath.equals(((DiffKeyXml) obj).xPath);\r
+ }\r
+\r
+ @Override\r
+ public int hashCode() {\r
+ return xPath.hashCode();\r
+ }\r
+\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+/** Diff issue where reached and expected values are different. */\r
+public class DiffNotMatched extends DiffIssueKey {\r
+ private final Object expected;\r
+ private final Object reached;\r
+\r
+ public DiffNotMatched(DiffPosition position, Object expected, Object reached) {\r
+ super(position);\r
+ this.expected = expected;\r
+ this.reached = reached;\r
+ }\r
+\r
+ public DiffNotMatched(DiffPosition position, Object expected,\r
+ Object reached, DiffKey key) {\r
+ super(position, key);\r
+ this.expected = expected;\r
+ this.reached = reached;\r
+ }\r
+\r
+ public Object getExpected() {\r
+ return expected;\r
+ }\r
+\r
+ public Object getReached() {\r
+ return reached;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ String result = position + ": not matched " + expected + " <> "\r
+ + reached;\r
+ if (super.key != null) {\r
+ result = result + " - Key: " + super.toString();\r
+ }\r
+\r
+ return result;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+/** The position of a diff issue within the test resource. */\r
+public abstract class DiffPosition implements Comparable<DiffPosition> {\r
+ protected RelatedFile relatedFile;\r
+\r
+ public DiffPosition(RelatedFile relatedFile) {\r
+ super();\r
+ this.relatedFile = relatedFile;\r
+ }\r
+\r
+ public RelatedFile getRelatedFile() {\r
+ return relatedFile;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * The result of a diff. Can be subclassed to provided more structured\r
+ * information.\r
+ */\r
+public interface DiffResult {\r
+ /** The list of issues, a zero size meaning that the diff succeeded. */\r
+ public List<DiffIssue> getIssues();\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Parses a string as a vector of strings according to a separator, dealing
+ * properly with missing values. This is intended to be used instead of the
+ * standard StringTokenizer, which does not deal well with empty values.
+ * Contrary to the StringTokenizer the provided String is parsed in the
+ * constructor and the values stored as a property. This should therefore not be
+ * used to parse long strings. No reference to the argument passed in
+ * constructor is kept.
+ */
+public class LineTokenizer {
+ private final List<String> tokens;
+
+ /** Complete constructor. */
+ public LineTokenizer(String stringToParse, Character separator,
+ String noValueString) {
+ this.tokens = parse(stringToParse, separator, noValueString);
+ }
+
+ /**
+ * Parse the string as a vector of strings. Can be overridden in order to
+ * provide another implementation.
+ */
+ protected List<String> parse(final String stringToParse,
+ final char separator, final String noValueString) {
+ // Init
+ final int NULL = -1;
+ List<String> res = new ArrayList<String>();
+ final char[] array = stringToParse.toCharArray();
+ int lastSeparatorIndex = NULL;
+
+ // Loop on chars
+ for (int currIndex = 0; currIndex < array.length; currIndex++) {
+ char c = array[currIndex];
+ if (c == separator) {
+ if (currIndex == 0) {
+ // first char is a separator
+ res.add(new String(noValueString));
+ lastSeparatorIndex = 0;
+ } else if (lastSeparatorIndex == NULL) {
+ // first separator found
+ res.add(new String(array, 0, currIndex));
+ lastSeparatorIndex = currIndex;
+ } else if (lastSeparatorIndex != NULL
+ && (lastSeparatorIndex == (currIndex - 1))) {
+ // consecutive separators
+ res.add(new String(noValueString));
+ lastSeparatorIndex = currIndex;
+ } else {
+ // simple case
+ res.add(new String(array, lastSeparatorIndex + 1, currIndex
+ - lastSeparatorIndex - 1));
+ lastSeparatorIndex = currIndex;
+ }
+ }
+ }
+
+ // Finalize
+ if (lastSeparatorIndex == NULL) {
+ // no separator found
+ res.add(new String(stringToParse));
+ } else if (lastSeparatorIndex == (array.length - 1)) {
+ // last char is a separator
+ res.add(new String(noValueString));
+ } else {
+ // last token
+ res.add(new String(array, lastSeparatorIndex + 1, array.length
+ - lastSeparatorIndex - 1));
+ }
+ return res;
+ }
+
+ /** The tokens. */
+ public List<String> getTokens() {
+ return tokens;
+ }
+
+ /** Parse */
+ public static List<String> tokenize(String stringToParse,
+ Character separator, String noValueString) {
+ LineTokenizer lt = new LineTokenizer(stringToParse, separator,
+ noValueString);
+ return lt.getTokens();
+ }
+
+ /** Parse, using the empty string as no value string. */
+ public static List<String> tokenize(String stringToParse,
+ Character separator) {
+ return tokenize(stringToParse, separator, "");
+ }
+
+}
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+/** Enumeration of the types of resource tested. */\r
+public enum RelatedFile {\r
+ /** The expected resource */\r
+ EXPECTED,\r
+ /** The reached resource */\r
+ REACHED\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+import java.util.List;\r
+import java.util.Vector;\r
+\r
+/** A basic implementation of <code>DiffResult</code>. */\r
+public class SimpleDiffResult implements DiffResult {\r
+ private List<DiffIssue> issues = new Vector<DiffIssue>();\r
+\r
+ public List<DiffIssue> getIssues() {\r
+ return issues;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+import org.argeo.slc.core.UnsupportedException;\r
+\r
+/**\r
+ * A diff position within a table structure such a CSV file or an SQL result\r
+ * set.\r
+ */\r
+public class TableDiffPosition extends DiffPosition {\r
+ private Integer line;\r
+ /** Can be null */\r
+ private Integer column;\r
+ /** Can be null */\r
+ private String columnName;\r
+\r
+ public TableDiffPosition(RelatedFile relatedFile, Integer line,\r
+ Integer column, String columnName) {\r
+ super(relatedFile);\r
+ this.line = line;\r
+ this.column = column;\r
+ this.columnName = columnName;\r
+ }\r
+\r
+ public Integer getLine() {\r
+ return line;\r
+ }\r
+\r
+ public Integer getColumn() {\r
+ return column;\r
+ }\r
+\r
+ public String getColumnName() {\r
+ return columnName;\r
+ }\r
+\r
+ public int compareTo(DiffPosition dp) {\r
+ if (!(dp instanceof TableDiffPosition))\r
+ throw new UnsupportedException("position", dp);\r
+\r
+ TableDiffPosition o = (TableDiffPosition) dp;\r
+ if (relatedFile.equals(o.relatedFile)) {\r
+ if (line == o.line) {\r
+ return column.compareTo(o.column);\r
+ } else {\r
+ return line.compareTo(o.line);\r
+ }\r
+ } else {\r
+ return relatedFile.compareTo(o.relatedFile);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ StringBuffer buf = new StringBuffer("");\r
+ buf.append(relatedFile).append('[').append(line);\r
+ if (column != null) {\r
+ buf.append(',').append(column);\r
+ if (columnName != null) {\r
+ buf.append('-').append(columnName);\r
+ }\r
+ }\r
+ buf.append(']');\r
+ return buf.toString();\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+/** Compares objects, eventually using tolerance mechanisms. */\r
+public interface Tolerance {\r
+ /**\r
+ * Compares objects\r
+ * \r
+ * @param key\r
+ * any object used to differentiate the type of data (e.g.\r
+ * column, path)\r
+ * @param expected\r
+ * the expected value\r
+ * @param reached\r
+ * the reached value\r
+ * @return the converted object\r
+ */\r
+ public Boolean compare(Object key, Object expected, Object reached);\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;\r
+\r
+import org.argeo.slc.core.UnsupportedException;\r
+\r
+/** A diff position within an Xml file. <b>NOT YET IMPLEMENTED</b>. */\r
+public class XPathDiffPosition extends DiffPosition {\r
+\r
+ private String xPath;\r
+\r
+ public XPathDiffPosition(RelatedFile relatedFile, String path) {\r
+ super(relatedFile);\r
+ xPath = path;\r
+ }\r
+\r
+ public int compareTo(DiffPosition dp) {\r
+ if (!(dp instanceof XPathDiffPosition))\r
+ throw new UnsupportedException("position", dp);\r
+\r
+ XPathDiffPosition o = (XPathDiffPosition) dp;\r
+ if (relatedFile.equals(o.relatedFile)) {\r
+ return xPath.compareTo(o.xPath);\r
+ } else {\r
+ return relatedFile.compareTo(o.relatedFile);\r
+ }\r
+ }\r
+\r
+ public String getXPath() {\r
+ return xPath;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return xPath;\r
+ }\r
+}\r
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+Abstraction of diff comparison with structured results.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.logging;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.PropertyConfigurator;
+import org.argeo.slc.core.SlcException;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.util.ResourceUtils;
+import org.springframework.util.SystemPropertyUtils;
+
+public class Log4jUtils {
+
+ /**
+ * Configure log4j based on properties, with the following priorities (from
+ * highest to lowest):<br>
+ * 1. System properties<br>
+ * 2. configuration file itself
+ */
+ public static void initLog4j(String configuration) {
+ // clears previous configuration
+ shutDownLog4j();
+
+ ClassLoader cl = Log4jUtils.class.getClassLoader();
+ Properties properties = new Properties();
+ if (configuration != null) {
+ InputStream in = null;
+ try {
+ if (configuration
+ .startsWith(ResourceUtils.CLASSPATH_URL_PREFIX)) {
+ String path = configuration
+ .substring(ResourceUtils.CLASSPATH_URL_PREFIX
+ .length());
+ in = cl.getResourceAsStream(path);
+ } else {
+ in = new DefaultResourceLoader(cl).getResource(
+ configuration).getInputStream();
+ }
+
+ properties.load(in);
+ } catch (IOException e) {
+ throw new SlcException("Cannot load properties from "
+ + configuration);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ // Overrides with System properties
+ overrideLog4jProperties(properties, System.getProperties());
+
+ PropertyConfigurator.configure(properties);
+ }
+
+ private static void overrideLog4jProperties(Properties target,
+ Properties additional) {
+ for (Object obj : additional.keySet()) {
+ String key = obj.toString();
+ if (key.startsWith("log4j.")) {
+ if (!key.equals("log4j.configuration")) {
+ String value = SystemPropertyUtils
+ .resolvePlaceholders(additional.getProperty(key));
+ target.put(key, value);
+ }
+ }
+ }
+ }
+
+ public static void shutDownLog4j() {
+ LogManager.shutdown();
+ }
+
+ private Log4jUtils() {
+
+ }
+}
--- /dev/null
+package org.argeo.slc.msg.process;
+
+import org.argeo.slc.core.process.SlcExecution;
+
+public class SlcExecutionRequest {
+ private SlcExecution slcExecution;
+
+ public SlcExecutionRequest() {
+ }
+
+ public SlcExecutionRequest(SlcExecution slcExecution) {
+ this.slcExecution = slcExecution;
+ }
+
+ public SlcExecution getSlcExecution() {
+ return slcExecution;
+ }
+
+ public void setSlcExecution(SlcExecution slcExecution) {
+ this.slcExecution = slcExecution;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "#" + slcExecution.getUuid();
+ }
+}
--- /dev/null
+package org.argeo.slc.msg.process;\r
+\r
+public class SlcExecutionStatusRequest {\r
+ private String slcExecutionUuid;\r
+ private String newStatus;\r
+\r
+ public SlcExecutionStatusRequest() {\r
+ }\r
+\r
+ public SlcExecutionStatusRequest(String slcExecutionUuid, String newStatus) {\r
+ this.slcExecutionUuid = slcExecutionUuid;\r
+ this.newStatus = newStatus;\r
+ }\r
+\r
+ public String getSlcExecutionUuid() {\r
+ return slcExecutionUuid;\r
+ }\r
+\r
+ public void setSlcExecutionUuid(String slcExecutionUuid) {\r
+ this.slcExecutionUuid = slcExecutionUuid;\r
+ }\r
+\r
+ public String getNewStatus() {\r
+ return newStatus;\r
+ }\r
+\r
+ public void setNewStatus(String newStatus) {\r
+ this.newStatus = newStatus;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return getClass().getSimpleName() + "#" + slcExecutionUuid;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.msg.process;\r
+\r
+import java.util.List;\r
+import java.util.Vector;\r
+\r
+import org.argeo.slc.core.process.SlcExecutionStep;\r
+\r
+public class SlcExecutionStepsRequest {\r
+ private String slcExecutionUuid;\r
+ private List<SlcExecutionStep> steps = new Vector<SlcExecutionStep>();\r
+\r
+ public SlcExecutionStepsRequest() {\r
+\r
+ }\r
+\r
+ public SlcExecutionStepsRequest(String slcExecutionUuid,\r
+ List<SlcExecutionStep> steps) {\r
+ this.slcExecutionUuid = slcExecutionUuid;\r
+ this.steps = steps;\r
+ }\r
+\r
+ public SlcExecutionStepsRequest(String slcExecutionUuid,\r
+ SlcExecutionStep step) {\r
+ this.slcExecutionUuid = slcExecutionUuid;\r
+ List<SlcExecutionStep> steps = new Vector<SlcExecutionStep>();\r
+ steps.add(step);\r
+ this.steps = steps;\r
+ }\r
+\r
+ public String getSlcExecutionUuid() {\r
+ return slcExecutionUuid;\r
+ }\r
+\r
+ public void setSlcExecutionUuid(String slcExecutionUuid) {\r
+ this.slcExecutionUuid = slcExecutionUuid;\r
+ }\r
+\r
+ public List<SlcExecutionStep> getSteps() {\r
+ return steps;\r
+ }\r
+\r
+ public void setSteps(List<SlcExecutionStep> step) {\r
+ this.steps = step;\r
+ }\r
+\r
+ public void addStep(SlcExecutionStep step) {\r
+ steps.add(step);\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return getClass().getSimpleName() + "#" + slcExecutionUuid + " "\r
+ + steps;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.msg.test.tree;\r
+\r
+import java.util.Date;\r
+\r
+import org.argeo.slc.core.test.tree.TreeTestResult;\r
+\r
+public class CloseTreeTestResultRequest {\r
+ private String resultUuid;\r
+ private Date closeDate;\r
+\r
+ public CloseTreeTestResultRequest() {\r
+\r
+ }\r
+\r
+ public CloseTreeTestResultRequest(String resultUuid, Date closeDate) {\r
+ this.resultUuid = resultUuid;\r
+ this.closeDate = closeDate;\r
+ }\r
+\r
+ public CloseTreeTestResultRequest(TreeTestResult ttr) {\r
+ this.resultUuid = ttr.getUuid();\r
+ this.closeDate = ttr.getCloseDate();\r
+ }\r
+\r
+ public String getResultUuid() {\r
+ return resultUuid;\r
+ }\r
+\r
+ public void setResultUuid(String id) {\r
+ this.resultUuid = id;\r
+ }\r
+\r
+ public Date getCloseDate() {\r
+ return closeDate;\r
+ }\r
+\r
+ public void setCloseDate(Date closeDate) {\r
+ this.closeDate = closeDate;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return getClass().getSimpleName() + "#" + resultUuid;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.msg.test.tree;\r
+\r
+import org.argeo.slc.core.test.TestRunDescriptor;\r
+import org.argeo.slc.core.test.tree.TreeTestResult;\r
+\r
+public class CreateTreeTestResultRequest {\r
+ private TreeTestResult treeTestResult;\r
+ private TestRunDescriptor testRunDescriptor;\r
+\r
+ public CreateTreeTestResultRequest() {\r
+\r
+ }\r
+\r
+ public CreateTreeTestResultRequest(TreeTestResult treeTestResult) {\r
+ this.treeTestResult = treeTestResult;\r
+ if (treeTestResult.getCurrentTestRun() != null)\r
+ testRunDescriptor = new TestRunDescriptor(treeTestResult\r
+ .getCurrentTestRun());\r
+ }\r
+\r
+ public TreeTestResult getTreeTestResult() {\r
+ return treeTestResult;\r
+ }\r
+\r
+ public void setTreeTestResult(TreeTestResult treeTestResult) {\r
+ this.treeTestResult = treeTestResult;\r
+ }\r
+\r
+ public TestRunDescriptor getTestRunDescriptor() {\r
+ return testRunDescriptor;\r
+ }\r
+\r
+ public void setTestRunDescriptor(TestRunDescriptor testRunDescriptor) {\r
+ this.testRunDescriptor = testRunDescriptor;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return getClass().getSimpleName() + "#" + treeTestResult.getUuid();\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.msg.test.tree;\r
+\r
+import java.util.Map;\r
+import java.util.SortedMap;\r
+\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.core.structure.StructureElement;\r
+import org.argeo.slc.core.structure.tree.TreeSPath;\r
+import org.argeo.slc.core.test.SimpleResultPart;\r
+import org.argeo.slc.core.test.TestRunDescriptor;\r
+import org.argeo.slc.core.test.tree.PartSubList;\r
+import org.argeo.slc.core.test.tree.TreeTestResult;\r
+\r
+public class ResultPartRequest {\r
+ private String resultUuid;\r
+ private SimpleResultPart resultPart;\r
+ private TreeSPath path;\r
+ private Map<TreeSPath, StructureElement> relatedElements;\r
+ private TestRunDescriptor testRunDescriptor;\r
+ private Map<String, String> attributes;\r
+\r
+ public ResultPartRequest() {\r
+\r
+ }\r
+\r
+ public ResultPartRequest(TreeTestResult ttr, TreeSPath path,\r
+ SimpleResultPart resultPart) {\r
+ resultUuid = ttr.getUuid();\r
+ this.resultPart = resultPart;\r
+ this.path = (path != null ? path : ttr.getCurrentPath());\r
+ relatedElements = ttr.getRelatedElements(this.path);\r
+ if (ttr.getCurrentTestRun() != null)\r
+ testRunDescriptor = new TestRunDescriptor(ttr.getCurrentTestRun());\r
+ attributes = ttr.getAttributes();\r
+ }\r
+\r
+ public ResultPartRequest(TreeTestResult ttr) {\r
+ resultUuid = ttr.getUuid();\r
+ this.path = ttr.getCurrentPath();\r
+\r
+ PartSubList lst = ttr.getResultParts().get(path);\r
+ if (lst.getParts().size() < 1) {\r
+ throw new SlcException("Cannot find part for path " + path\r
+ + " in result " + resultUuid);\r
+ }\r
+\r
+ this.resultPart = (SimpleResultPart) lst.getParts().get(\r
+ lst.getParts().size() - 1);\r
+ relatedElements = ttr.getRelatedElements(path);\r
+ if (ttr.getCurrentTestRun() != null)\r
+ testRunDescriptor = new TestRunDescriptor(ttr.getCurrentTestRun());\r
+ }\r
+\r
+ public String getResultUuid() {\r
+ return resultUuid;\r
+ }\r
+\r
+ public void setResultUuid(String resultUuid) {\r
+ this.resultUuid = resultUuid;\r
+ }\r
+\r
+ public SimpleResultPart getResultPart() {\r
+ return resultPart;\r
+ }\r
+\r
+ public void setResultPart(SimpleResultPart resultPart) {\r
+ this.resultPart = resultPart;\r
+ }\r
+\r
+ public TreeSPath getPath() {\r
+ return path;\r
+ }\r
+\r
+ public void setPath(TreeSPath path) {\r
+ this.path = path;\r
+ }\r
+\r
+ public TestRunDescriptor getTestRunDescriptor() {\r
+ return testRunDescriptor;\r
+ }\r
+\r
+ public void setTestRunDescriptor(TestRunDescriptor testRunDescriptor) {\r
+ this.testRunDescriptor = testRunDescriptor;\r
+ }\r
+\r
+ public Map<TreeSPath, StructureElement> getRelatedElements() {\r
+ return relatedElements;\r
+ }\r
+\r
+ public void setRelatedElements(\r
+ Map<TreeSPath, StructureElement> relatedElements) {\r
+ this.relatedElements = relatedElements;\r
+ }\r
+\r
+ public Map<String, String> getAttributes() {\r
+ return attributes;\r
+ }\r
+\r
+ public void setAttributes(SortedMap<String, String> attributes) {\r
+ this.attributes = attributes;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return getClass().getSimpleName() + "#" + resultUuid + " " + path;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.runtime;
+
+import org.argeo.slc.core.process.SlcExecution;
+
+/** Provides access to the object used during the execution */
+public interface SlcExecutionContext {
+ public <T> T getBean(String name);
+
+ public SlcExecution getSlcExecution();
+}
--- /dev/null
+package org.argeo.slc.runtime;
+
+public interface SlcExecutionOutput<T extends SlcExecutionContext> {
+ /** Called after the execution, before the resources are freed. */
+ public void postExecution(T executionContext);
+}
--- /dev/null
+package org.argeo.slc.spring;\r
+\r
+import java.io.IOException;\r
+import java.net.URI;\r
+import java.util.Map;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.core.SlcException;\r
+import org.springframework.beans.factory.BeanFactoryUtils;\r
+import org.springframework.beans.factory.ListableBeanFactory;\r
+import org.springframework.core.io.DefaultResourceLoader;\r
+import org.springframework.core.io.Resource;\r
+\r
+public class SpringUtils {\r
+ private final static Log log = LogFactory.getLog(SpringUtils.class);\r
+\r
+ public static <T> T loadSingleFromContext(ListableBeanFactory context,\r
+ Class<T> clss) {\r
+ // Map<String, T> beans = context.getBeansOfType(clss);\r
+ Map<String, T> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(\r
+ context, clss, false, false);\r
+ if (beans.size() == 1) {\r
+ return beans.values().iterator().next();\r
+ } else if (beans.size() > 1) {\r
+ if (log.isDebugEnabled()) {\r
+ log\r
+ .debug(("Found more that on bean for type " + clss\r
+ + ": " + beans.keySet()));\r
+ }\r
+ return null;\r
+ } else {\r
+ return null;\r
+ }\r
+ }\r
+\r
+ public static Resource getParent(Resource res) {\r
+ try {\r
+ if (res.getURL().getPath().equals("/"))\r
+ return null;\r
+\r
+ String urlStr = res.getURL().toString();\r
+ if (urlStr.charAt(urlStr.length() - 1) == '/')\r
+ urlStr = urlStr.substring(0, urlStr.length() - 2);\r
+\r
+ String parentUrlStr = urlStr.substring(0, urlStr.lastIndexOf('/')) + '/';\r
+ URI uri = new URI(parentUrlStr).normalize();\r
+ return new DefaultResourceLoader(Thread.currentThread()\r
+ .getContextClassLoader()).getResource(uri.toString());\r
+ } catch (Exception e) {\r
+ throw new SlcException("Cannot get parent for resource " + res, e);\r
+ }\r
+ }\r
+\r
+ public static String extractRelativePath(Resource ancestor, Resource child) {\r
+ try {\r
+\r
+ return ancestor.getURL().toURI().relativize(child.getURL().toURI())\r
+ .normalize().toString();\r
+ } catch (Exception e) {\r
+ throw new SlcException("Cannot extract relative path of " + child\r
+ + " based on " + ancestor, e);\r
+ }\r
+ }\r
+\r
+ private SpringUtils() {\r
+\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.support.deploy;\r
+\r
+import java.io.File;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.core.build.Distribution;\r
+import org.argeo.slc.core.deploy.DeployEnvironment;\r
+import org.argeo.slc.core.deploy.DeployedSystem;\r
+import org.argeo.slc.core.deploy.Deployment;\r
+import org.argeo.slc.core.deploy.DeploymentData;\r
+import org.argeo.slc.core.deploy.TargetData;\r
+\r
+public class HttpdApplicationDeployment implements Deployment {\r
+ private static final Log log = LogFactory\r
+ .getLog(HttpdApplicationDeployment.class);\r
+\r
+ private HttpdApplicationTargetData targetData;\r
+ private DeploymentData deploymentData;\r
+ private SimpleHttpdApplication deployedSystem;\r
+ private Distribution distribution;\r
+\r
+ private DeployEnvironment deployEnvironment;\r
+\r
+ public void execute() {\r
+ try {\r
+ deployEnvironment.unpackTo(distribution, targetData\r
+ .getTargetRootLocation(), null);\r
+\r
+ // FIXME: make it generic\r
+ String deployDataPath = targetData.getTargetRootLocation()\r
+ .getCanonicalPath();\r
+\r
+ deployEnvironment.unpackTo(deploymentData,\r
+ new File(deployDataPath), null);\r
+ deployedSystem = new SimpleHttpdApplication();\r
+ deployedSystem.setTargetData(targetData);\r
+\r
+ log.info("Deployed " + distribution + " to " + targetData);\r
+ } catch (Exception e) {\r
+ throw new SlcException("Cannot deploy " + distribution + " to "\r
+ + targetData, e);\r
+ }\r
+\r
+ }\r
+\r
+ public void setTargetData(TargetData targetData) {\r
+ this.targetData = (HttpdApplicationTargetData) targetData;\r
+ }\r
+\r
+ public void setDeploymentData(DeploymentData deploymentData) {\r
+ this.deploymentData = deploymentData;\r
+ }\r
+\r
+ public DeployedSystem getDeployedSystem() {\r
+ return deployedSystem;\r
+ }\r
+\r
+ public void setDistribution(Distribution distribution) {\r
+ this.distribution = distribution;\r
+ }\r
+\r
+ public void setDeployEnvironment(DeployEnvironment deployEnvironment) {\r
+ this.deployEnvironment = deployEnvironment;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.support.deploy;\r
+\r
+import java.io.File;\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.core.deploy.TargetData;\r
+\r
+public class HttpdApplicationTargetData implements TargetData {\r
+ private HttpdServer webServer;\r
+ private String relativePath;\r
+ private String targetRootPath;\r
+\r
+ public HttpdServer getWebServer() {\r
+ return webServer;\r
+ }\r
+\r
+ public void setWebServer(HttpdServer webServer) {\r
+ this.webServer = webServer;\r
+ }\r
+\r
+ public String getRelativePath() {\r
+ return relativePath;\r
+ }\r
+\r
+ /**\r
+ * If targetRootLocation not set, used to build the targetRootLocation,\r
+ * relative to the webserver base.\r
+ */\r
+ public void setRelativePath(String relativePath) {\r
+ this.relativePath = relativePath;\r
+ }\r
+\r
+ public String getTargetRootPath() {\r
+ return targetRootPath;\r
+ }\r
+\r
+ public void setTargetRootPath(String targetRootPath) {\r
+ this.targetRootPath = targetRootPath;\r
+ }\r
+\r
+ public URL getTargetBaseUrl() {\r
+ try {\r
+ URL wsUrl = getWebServer().getBaseUrl();\r
+ // TODO: use URI\r
+ return new URL(wsUrl, wsUrl.getFile() + '/' + relativePath);\r
+ } catch (MalformedURLException e) {\r
+ throw new SlcException("Cannot get base url for " + relativePath, e);\r
+ }\r
+ }\r
+\r
+ public File getTargetRootLocation() {\r
+ if (targetRootPath != null && !targetRootPath.equals("")) {\r
+ return new File(targetRootPath);\r
+ } else {\r
+ HttpdServerTargetData targetData = (HttpdServerTargetData) getWebServer()\r
+ .getTargetData();\r
+ String path = targetData.getServerRoot() + File.separator\r
+ + getRelativePath();\r
+ return new File(path);\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.support.deploy;\r
+\r
+import java.io.IOException;\r
+import java.net.URL;\r
+\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.core.build.Distribution;\r
+import org.argeo.slc.core.deploy.DeploymentData;\r
+import org.argeo.slc.core.deploy.TargetData;\r
+\r
+public class HttpdServer implements WebServer {\r
+ private HttpdServerTargetData targetData;\r
+ private HttpdServerDeploymentData deploymentData;\r
+\r
+ public URL getBaseUrl() {\r
+ try {\r
+ return new URL("http://localhost:" + targetData.getPort());\r
+ } catch (IOException e) {\r
+ throw new SlcException("Cannot get url for Httpd server "\r
+ + getDeployedSystemId(), e);\r
+ }\r
+ }\r
+\r
+ public String getDeployedSystemId() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+ public Distribution getDistribution() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+ public DeploymentData getDeploymentData() {\r
+ return deploymentData;\r
+ }\r
+\r
+ public TargetData getTargetData() {\r
+ return targetData;\r
+ }\r
+\r
+ public void setTargetData(TargetData targetData) {\r
+ this.targetData = (HttpdServerTargetData)targetData;\r
+ }\r
+\r
+ public void setDeploymentData(DeploymentData deploymentData) {\r
+ this.deploymentData = (HttpdServerDeploymentData)deploymentData;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.support.deploy;
+
+import org.argeo.slc.core.build.Distribution;
+import org.argeo.slc.core.deploy.DeployedSystem;
+import org.argeo.slc.core.deploy.Deployment;
+import org.argeo.slc.core.deploy.DeploymentData;
+import org.argeo.slc.core.deploy.TargetData;
+
+public class HttpdServerDeployment implements Deployment {
+ private HttpdServerTargetData targetData;
+
+ public void execute() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public DeployedSystem getDeployedSystem() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setDeploymentData(DeploymentData deploymentData) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void setDistribution(Distribution distribution) {
+ }
+
+ public void setTargetData(TargetData targetData) {
+ this.targetData = (HttpdServerTargetData) targetData;
+ }
+
+}
--- /dev/null
+package org.argeo.slc.support.deploy;
+
+import org.argeo.slc.core.deploy.DeploymentData;
+
+public class HttpdServerDeploymentData implements DeploymentData {
+ private String configFile;
+
+ public String getConfigFile() {
+ return configFile;
+ }
+
+ public void setConfigFile(String configFile) {
+ this.configFile = configFile;
+ }
+
+}
--- /dev/null
+package org.argeo.slc.support.deploy;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.core.SlcException;
+import org.argeo.slc.core.deploy.DeployedSystemManager;
+
+public class HttpdServerManager implements DeployedSystemManager<HttpdServer> {
+ private final static Log log = LogFactory.getLog(HttpdServerManager.class);
+
+ private HttpdServer httpdServer;
+
+ public void start() {
+ runProcessAsync(createCommandLine("start"));
+ log.info("Started httpd server with root "
+ + getHttpdServerTargetData().getServerRoot());
+ }
+
+ public void stop() {
+ runProcessAsync(createCommandLine("stop"));
+ log.info("Stopped httpd server with root "
+ + getHttpdServerTargetData().getServerRoot());
+ }
+
+ protected String[] createCommandLine(String action) {
+ String httpdPath = getHttpdServerTargetData().getExecutables()
+ .getExecutablePath("httpd");
+ String[] cmd = { httpdPath, "-d",
+ getHttpdServerTargetData().getServerRoot(), "-f",
+ getHttpdServerDeploymentData().getConfigFile(), "-k", action };
+ if (log.isDebugEnabled())
+ log.debug("Command line: " + Arrays.asList(cmd));
+ return cmd;
+ }
+
+ protected static void runProcessAsync(String... command) {
+ ProcessBuilder procBuilder = new ProcessBuilder(command);
+ procBuilder.redirectErrorStream(true);
+ try {
+ Process proc = procBuilder.start();
+ final InputStream in = proc.getInputStream();
+ Thread logThread = new Thread() {
+
+ @Override
+ public void run() {
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(in));
+ String line = null;
+ try {
+ while ((line = reader.readLine()) != null)
+ log.info(line);
+ } catch (IOException e) {
+ log.error("Failed to read stdout", e);
+ }
+ }
+ };
+
+ logThread.start();
+ } catch (IOException e) {
+ throw new SlcException("Could not run command", e);
+ }
+ }
+
+ public void setDeployedSystem(HttpdServer httpdServer) {
+ this.httpdServer = httpdServer;
+ }
+
+ protected HttpdServerDeploymentData getHttpdServerDeploymentData() {
+ return (HttpdServerDeploymentData) httpdServer.getDeploymentData();
+ }
+
+ protected HttpdServerTargetData getHttpdServerTargetData() {
+ return (HttpdServerTargetData) httpdServer.getTargetData();
+ }
+}
--- /dev/null
+package org.argeo.slc.support.deploy;
+
+import org.argeo.slc.core.deploy.InstalledExecutables;
+import org.argeo.slc.core.deploy.TargetData;
+
+public class HttpdServerTargetData implements TargetData {
+ private String serverRoot;
+ private Integer port;
+ private InstalledExecutables executables;
+
+ public String getServerRoot() {
+ return serverRoot;
+ }
+
+ public void setServerRoot(String serverRoot) {
+ this.serverRoot = serverRoot;
+ }
+
+ public Integer getPort() {
+ return port;
+ }
+
+ public void setPort(Integer port) {
+ this.port = port;
+ }
+
+ public InstalledExecutables getExecutables() {
+ return executables;
+ }
+
+ public void setExecutables(InstalledExecutables executables) {
+ this.executables = executables;
+ }
+
+}
--- /dev/null
+package org.argeo.slc.support.deploy;\r
+\r
+import java.io.File;\r
+import java.net.URL;\r
+\r
+import org.argeo.slc.core.build.Distribution;\r
+import org.argeo.slc.core.deploy.DeploymentData;\r
+\r
+public class SimpleHttpdApplication implements WebApplication {\r
+ private HttpdApplicationTargetData targetData;\r
+ private Distribution distribution;\r
+\r
+ public void setDistribution(Distribution distribution) {\r
+ this.distribution = distribution;\r
+ }\r
+\r
+ public URL getBaseUrl() {\r
+ return targetData.getTargetBaseUrl();\r
+ }\r
+\r
+ public File getRootLocation() {\r
+ return targetData.getTargetRootLocation();\r
+ }\r
+\r
+ public String getDeployedSystemId() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+ public HttpdApplicationTargetData getTargetData() {\r
+ return targetData;\r
+ }\r
+\r
+ public void setTargetData(HttpdApplicationTargetData targetData) {\r
+ this.targetData = targetData;\r
+ }\r
+\r
+ public Distribution getDistribution() {\r
+ return distribution;\r
+ }\r
+\r
+ public DeploymentData getDeploymentData() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.support.deploy;\r
+\r
+import java.io.File;\r
+import java.net.URL;\r
+\r
+import org.argeo.slc.core.deploy.DeployedSystem;\r
+\r
+public interface WebApplication extends DeployedSystem {\r
+ public URL getBaseUrl();\r
+\r
+ public File getRootLocation();\r
+}\r
--- /dev/null
+package org.argeo.slc.support.deploy;\r
+\r
+import java.net.URL;\r
+\r
+import org.argeo.slc.core.deploy.DeployedSystem;\r
+\r
+public interface WebServer extends DeployedSystem {\r
+ public URL getBaseUrl();\r
+}\r
--- /dev/null
+package org.argeo.slc.support.deploy.db;
+
+import java.sql.Connection;
+
+public interface DbModel {
+ public void createSchema(Connection connection);
+}
--- /dev/null
+package org.argeo.slc.support.deploy.db;\r
+\r
+import java.sql.SQLException;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.core.UnsupportedException;\r
+import org.argeo.slc.core.build.Distribution;\r
+import org.argeo.slc.core.deploy.DeployedSystem;\r
+import org.argeo.slc.core.deploy.Deployment;\r
+import org.argeo.slc.core.deploy.DeploymentData;\r
+import org.argeo.slc.core.deploy.TargetData;\r
+import org.dbunit.DataSourceDatabaseTester;\r
+import org.dbunit.DatabaseUnitException;\r
+import org.dbunit.IDatabaseTester;\r
+import org.dbunit.database.IDatabaseConnection;\r
+import org.dbunit.dataset.IDataSet;\r
+import org.dbunit.operation.DatabaseOperation;\r
+\r
+public class DbUnitDeployment implements Deployment {\r
+ private static Log log = LogFactory.getLog(DbUnitDeployment.class);\r
+\r
+ private JdbcAware mxDatabase;\r
+ private DbUnitDeploymentData deploymentData;\r
+ private DbModel dbModel;\r
+\r
+ public void execute() {\r
+ try {\r
+ IDatabaseTester databaseTester = new DataSourceDatabaseTester(\r
+ mxDatabase.getDataSource());\r
+ databaseTester.setSetUpOperation(new DatabaseOperation() {\r
+\r
+ @Override\r
+ public void execute(IDatabaseConnection connection,\r
+ IDataSet dataSet) throws DatabaseUnitException,\r
+ SQLException {\r
+ if (dbModel != null) {\r
+ dbModel.createSchema(connection.getConnection());\r
+ DatabaseOperation.INSERT.execute(connection, dataSet);\r
+ } else {\r
+ DatabaseOperation.UPDATE.execute(connection, dataSet);\r
+ }\r
+ }\r
+\r
+ });\r
+ databaseTester.setDataSet(deploymentData.createDataSet());\r
+ databaseTester.onSetup();\r
+ databaseTester.onTearDown();\r
+\r
+ log.info("Database deployed.");\r
+ } catch (Exception e) {\r
+ throw new SlcException("Could not initialize the database", e);\r
+ }\r
+ }\r
+\r
+ public DeployedSystem getDeployedSystem() {\r
+ // TODO: think of a more generic approach. MxDtaabse deployed system?\r
+ // (with deployment id etc.)\r
+ throw new UnsupportedException("Method not supported");\r
+ }\r
+\r
+ public void setDbModel(DbModel dbModel) {\r
+ this.dbModel = dbModel;\r
+ }\r
+\r
+ public void setDeploymentData(DeploymentData deploymentData) {\r
+ this.deploymentData = (DbUnitDeploymentData) deploymentData;\r
+ }\r
+\r
+ public void setTargetData(TargetData targetData) {\r
+ this.mxDatabase = (JdbcAware) targetData;\r
+\r
+ }\r
+\r
+ public void setDistribution(Distribution distribution) {\r
+ throw new UnsupportedException("Method not supported");\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.support.deploy.db;\r
+\r
+import java.io.InputStream;\r
+\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.core.deploy.DeploymentData;\r
+import org.dbunit.dataset.IDataSet;\r
+import org.dbunit.dataset.xml.FlatXmlDataSet;\r
+import org.springframework.core.io.Resource;\r
+\r
+public class DbUnitDeploymentData implements DeploymentData {\r
+ private Resource dataSetLocation;\r
+\r
+ public IDataSet createDataSet() {\r
+ try {\r
+ InputStream in = dataSetLocation.getInputStream();\r
+ IDataSet dataSet = new FlatXmlDataSet(in);\r
+ in.close();\r
+ return dataSet;\r
+ } catch (Exception e) {\r
+ throw new SlcException("Cannot create data set", e);\r
+ }\r
+\r
+ }\r
+\r
+ public void setDataSetLocation(Resource dataSetLocation) {\r
+ this.dataSetLocation = dataSetLocation;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.support.deploy.db;
+
+import javax.sql.DataSource;
+
+public interface JdbcAware {
+ public DataSource getDataSource();
+}
--- /dev/null
+package org.argeo.slc.support.deploy.db;
+
+import javax.sql.DataSource;
+
+import org.argeo.slc.core.deploy.AbstractDeployedSystem;
+
+public class SimpleJdbcDatabase extends AbstractDeployedSystem implements
+ JdbcAware {
+ private DataSource dataSource;
+
+ public String getDeployedSystemId() {
+ return dataSource.toString();
+ }
+
+ public DataSource getDataSource() {
+ return dataSource;
+ }
+
+ public void setDataSource(DataSource dataSource) {
+ this.dataSource = dataSource;
+ }
+}
--- /dev/null
+package org.argeo.slc.unit;\r
+\r
+import junit.framework.TestCase;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.spring.SpringUtils;\r
+import org.springframework.context.ConfigurableApplicationContext;\r
+import org.springframework.context.support.ClassPathXmlApplicationContext;\r
+\r
+/** Helper for tests using a Spring application co,text. */\r
+public abstract class AbstractSpringTestCase extends TestCase {\r
+ protected final Log log = LogFactory.getLog(getClass());\r
+ private ConfigurableApplicationContext context;\r
+\r
+ /**\r
+ * Gets (and create if necessary) the application context to use. Default\r
+ * implementation uses a class path xml application context and calls\r
+ * {@link #getApplicationContextLocation()}.\r
+ */\r
+ protected ConfigurableApplicationContext getContext() {\r
+ if (context == null) {\r
+ context = new ClassPathXmlApplicationContext(\r
+ getApplicationContextLocation());\r
+ }\r
+ return context;\r
+ }\r
+\r
+ /** Returns a bean from the underlying context */\r
+ protected <T> T getBean(String beanId) {\r
+ return (T) getContext().getBean(beanId);\r
+ }\r
+\r
+ protected <T> T getBean(Class<? extends T> clss) {\r
+ T bean = SpringUtils.loadSingleFromContext(getContext(), clss);\r
+ if (bean == null) {\r
+ throw new SlcException("Cannot retrieve a unique bean of type "\r
+ + clss);\r
+ } else {\r
+ return bean;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Th location of the application to load. The default implementation\r
+ * returns <i>applicationContext.xml</i> found in the same package as the\r
+ * test.\r
+ */\r
+ protected String getApplicationContextLocation() {\r
+ return inPackage("applicationContext.xml");\r
+ }\r
+\r
+ /**\r
+ * Prefixes the package of the class after converting the '.' to '/' in\r
+ * order to have a resource path.\r
+ */\r
+ protected String inPackage(String suffix) {\r
+ String prefix = getClass().getPackage().getName().replace('.', '/');\r
+ return prefix + '/' + suffix;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.unit;\r
+\r
+import java.util.Calendar;\r
+import java.util.Date;\r
+import java.util.GregorianCalendar;\r
+\r
+import static junit.framework.Assert.assertEquals;\r
+import static junit.framework.Assert.assertNull;\r
+import static junit.framework.Assert.assertNotNull;\r
+\r
+public abstract class UnitUtils {\r
+ public static void assertDateSec(Date expected, Date reached) {\r
+ if (expected == null) {\r
+ assertNull(reached);\r
+ return;\r
+ } else {\r
+ assertNotNull(reached);\r
+ }\r
+\r
+ Calendar expectedCal = new GregorianCalendar();\r
+ expectedCal.setTime(expected);\r
+ Calendar reachedCal = new GregorianCalendar();\r
+ reachedCal.setTime(reached);\r
+ assertEquals(expectedCal.get(Calendar.YEAR), reachedCal\r
+ .get(Calendar.YEAR));\r
+ assertEquals(expectedCal.get(Calendar.MONTH), reachedCal\r
+ .get(Calendar.MONTH));\r
+ assertEquals(expectedCal.get(Calendar.DATE), reachedCal\r
+ .get(Calendar.DATE));\r
+ assertEquals(expectedCal.get(Calendar.HOUR_OF_DAY), reachedCal\r
+ .get(Calendar.HOUR_OF_DAY));\r
+ assertEquals(expectedCal.get(Calendar.MINUTE), reachedCal\r
+ .get(Calendar.MINUTE));\r
+ assertEquals(expectedCal.get(Calendar.SECOND), reachedCal\r
+ .get(Calendar.SECOND));\r
+ }\r
+\r
+ private UnitUtils() {\r
+\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.argeo.slc.unit;\r
+\r
+import java.io.IOException;\r
+\r
+import javax.xml.transform.Source;\r
+\r
+import junit.framework.TestCase;\r
+\r
+import org.springframework.xml.validation.XmlValidator;\r
+import org.springframework.xml.xsd.XsdSchema;\r
+import org.xml.sax.SAXParseException;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+\r
+public abstract class UnitXmlUtils {\r
+ private final static Log log = LogFactory.getLog(UnitXmlUtils.class);\r
+\r
+ public static void assertXsdSchemaValidation(XsdSchema schema, Source source)\r
+ throws IOException {\r
+ XmlValidator validator = schema.createValidator();\r
+ assertXmlValidation(validator, source);\r
+ }\r
+\r
+ public static void assertXmlValidation(XmlValidator validator, Source source)\r
+ throws IOException {\r
+ SAXParseException[] exceptions = validator.validate(source);\r
+ if (exceptions.length != 0) {\r
+ for (SAXParseException ex : exceptions) {\r
+ log.error(ex.getMessage());\r
+ }\r
+ TestCase.fail("Could not validate");\r
+ }\r
+ }\r
+\r
+ private UnitXmlUtils() {\r
+\r
+ }\r
+}\r
--- /dev/null
+<html>\r
+<head></head>\r
+<body>\r
+Helpers for unit tests.\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.unit.process;\r
+\r
+import static junit.framework.Assert.assertEquals;\r
+import static junit.framework.Assert.assertNotNull;\r
+import static org.argeo.slc.unit.UnitUtils.assertDateSec;\r
+\r
+import java.util.UUID;\r
+\r
+import org.argeo.slc.core.process.SlcExecution;\r
+import org.argeo.slc.core.process.SlcExecutionStep;\r
+\r
+public abstract class SlcExecutionTestUtils {\r
+\r
+ public static SlcExecution createSimpleSlcExecution() {\r
+ SlcExecution slcExec = new SlcExecution();\r
+ slcExec.setUuid(UUID.randomUUID().toString());\r
+ slcExec.setHost("localhost");\r
+ slcExec.setUser("user");\r
+ slcExec.setType("slcAnt");\r
+ slcExec.setStatus("STARTED");\r
+ slcExec.getAttributes().put("ant.file", "/test");\r
+ return slcExec;\r
+ }\r
+\r
+ public static void assertSlcExecution(SlcExecution expected,\r
+ SlcExecution reached) {\r
+ assertNotNull(reached);\r
+ assertEquals(expected.getHost(), reached.getHost());\r
+ assertEquals(expected.getUser(), reached.getUser());\r
+ assertEquals(expected.getType(), reached.getType());\r
+ assertEquals(expected.getStatus(), reached.getStatus());\r
+\r
+ // Attributes\r
+ assertEquals(expected.getAttributes().size(), reached.getAttributes()\r
+ .size());\r
+ for (String key : expected.getAttributes().keySet()) {\r
+ String expectedValue = expected.getAttributes().get(key);\r
+ String reachedValue = reached.getAttributes().get(key);\r
+ assertNotNull(reachedValue);\r
+ assertEquals(expectedValue, reachedValue);\r
+ }\r
+\r
+ assertEquals(expected.getSteps().size(), reached.getSteps().size());\r
+ for (int i = 0; i < expected.getSteps().size(); i++) {\r
+ SlcExecutionStep stepExpected = expected.getSteps().get(i);\r
+ SlcExecutionStep stepReached = reached.getSteps().get(i);\r
+ assertSlcExecutionStep(stepExpected, stepReached);\r
+ }\r
+ }\r
+\r
+ public static void assertSlcExecutionStep(SlcExecutionStep expected,\r
+ SlcExecutionStep reached) {\r
+ assertNotNull(reached);\r
+ assertEquals(expected.getUuid(), reached.getUuid());\r
+ assertEquals(expected.getType(), reached.getType());\r
+ assertEquals(expected.logAsString(), reached.logAsString());\r
+ assertDateSec(expected.getBegin(), reached.getBegin());\r
+ }\r
+\r
+ private SlcExecutionTestUtils() {\r
+\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.unit.test.tree;\r
+\r
+import java.util.UUID;\r
+\r
+import org.argeo.slc.core.build.Distribution;\r
+import org.argeo.slc.core.deploy.DeployedSystem;\r
+import org.argeo.slc.core.deploy.DeploymentData;\r
+import org.argeo.slc.core.deploy.TargetData;\r
+import org.argeo.slc.core.process.SlcExecution;\r
+import org.argeo.slc.core.process.SlcExecutionStep;\r
+import org.argeo.slc.core.structure.SimpleSElement;\r
+import org.argeo.slc.core.structure.tree.TreeSPath;\r
+import org.argeo.slc.core.structure.tree.TreeSRegistry;\r
+import org.argeo.slc.core.test.SimpleResultPart;\r
+import org.argeo.slc.core.test.SimpleTestRun;\r
+import org.argeo.slc.core.test.TestStatus;\r
+import org.argeo.slc.core.test.tree.PartSubList;\r
+import org.argeo.slc.core.test.tree.TreeTestResult;\r
+import org.argeo.slc.msg.test.tree.ResultPartRequest;\r
+import org.argeo.slc.unit.process.SlcExecutionTestUtils;\r
+\r
+public abstract class TreeTestResultTestUtils {\r
+\r
+ public static TreeTestResult createSimpleTreeTestResult() {\r
+ TreeTestResult treeTestResult = new TreeTestResult();\r
+ treeTestResult.setUuid(UUID.randomUUID().toString());\r
+ return treeTestResult;\r
+ }\r
+\r
+ public static TreeTestResult createCompleteTreeTestResult() {\r
+ SlcExecution slcExecution = SlcExecutionTestUtils\r
+ .createSimpleSlcExecution();\r
+ SlcExecutionStep step = new SlcExecutionStep("JUnit step");\r
+ slcExecution.getSteps().add(step);\r
+\r
+ TreeTestResult ttr = createMinimalConsistentTreeTestResult(slcExecution);\r
+\r
+ ttr.addResultPart(createSimpleResultPartPassed());\r
+ ttr.addResultPart(createSimpleResultPartFailed());\r
+ ttr.addResultPart(createSimpleResultPartError());\r
+ return ttr;\r
+ }\r
+\r
+ public static TreeTestResult createMinimalConsistentTreeTestResult(\r
+ SlcExecution slcExecution) {\r
+ SimpleTestRun testRun = new SimpleTestRun();\r
+ testRun.setUuid(UUID.randomUUID().toString());\r
+\r
+ String pathStr = "/test";\r
+ TreeSPath path = new TreeSPath(pathStr);\r
+\r
+ TreeSRegistry registry = new TreeSRegistry();\r
+ SimpleSElement elem = new SimpleSElement("Unit Test");\r
+ elem.getTags().put("myTag", "myTagValue");\r
+ registry.register(path, elem);\r
+\r
+ TreeTestResult ttr = createSimpleTreeTestResult();\r
+ ttr.getAttributes().put("testCase", "UNIT");\r
+\r
+ // Simulate test run\r
+ ttr.notifyCurrentPath(registry, path);\r
+ ttr.notifyTestRun(testRun);\r
+ testRun.setTestResult(ttr);\r
+ testRun.setDeployedSystem(new DeployedSystem() {\r
+ private String uuid = UUID.randomUUID().toString();\r
+\r
+ public String getDeployedSystemId() {\r
+ return uuid;\r
+ }\r
+\r
+ public Distribution getDistribution() {\r
+ return null;\r
+ }\r
+\r
+ public DeploymentData getDeploymentData() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+ public TargetData getTargetData() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+ });\r
+ testRun.notifySlcExecution(slcExecution);\r
+ return ttr;\r
+ }\r
+\r
+ public static SimpleResultPart createSimpleResultPartPassed() {\r
+ SimpleResultPart partPassed = new SimpleResultPart();\r
+ String msgPassed = "message\nnew line";\r
+ partPassed.setStatus(TestStatus.PASSED);\r
+ partPassed.setMessage(msgPassed);\r
+ return partPassed;\r
+ }\r
+\r
+ public static SimpleResultPart createSimpleResultPartFailed() {\r
+ SimpleResultPart partFailed = new SimpleResultPart();\r
+ String msgFailed = "too bad";\r
+ partFailed.setStatus(TestStatus.FAILED);\r
+ partFailed.setMessage(msgFailed);\r
+ return partFailed;\r
+ }\r
+\r
+ public static SimpleResultPart createSimpleResultPartError() {\r
+ SimpleResultPart partFailed = new SimpleResultPart();\r
+ String msgFailed = "crashed\nanother line";\r
+ partFailed.setStatus(TestStatus.ERROR);\r
+ partFailed.setMessage(msgFailed);\r
+ partFailed.setException(new Exception("Test Exception"));\r
+ return partFailed;\r
+ }\r
+\r
+ public static ResultPartRequest createSimpleResultPartRequest(\r
+ TreeTestResult ttr) {\r
+ TreeSPath path = ttr.getCurrentPath();\r
+ PartSubList lst = ttr.getResultParts().get(path);\r
+ SimpleResultPart part = (SimpleResultPart) lst.getParts().get(2);\r
+\r
+ ResultPartRequest req = new ResultPartRequest(ttr, path, part);\r
+ req.setPath(ttr.getCurrentPath());\r
+\r
+ return req;\r
+ }\r
+\r
+ private TreeTestResultTestUtils() {\r
+\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.unit.test.tree;\r
+\r
+import static junit.framework.Assert.assertEquals;\r
+import static junit.framework.Assert.assertNotNull;\r
+import static junit.framework.Assert.assertNull;\r
+import static junit.framework.Assert.fail;\r
+import static org.argeo.slc.unit.UnitUtils.assertDateSec;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.core.structure.SimpleSElement;\r
+import org.argeo.slc.core.structure.tree.TreeSPath;\r
+import org.argeo.slc.core.test.SimpleResultPart;\r
+import org.argeo.slc.core.test.TestResultPart;\r
+import org.argeo.slc.core.test.tree.PartSubList;\r
+import org.argeo.slc.core.test.tree.TreeTestResult;\r
+\r
+/** Utilities for unit tests. */\r
+public class UnitTestTreeUtil {\r
+ private final static Log log = LogFactory.getLog(UnitTestTreeUtil.class);\r
+\r
+ public static void assertTreeTestResult(TreeTestResult expected,\r
+ TreeTestResult reached) {\r
+ assertEquals(expected.getUuid(), reached.getUuid());\r
+ assertDateSec(expected.getCloseDate(), reached.getCloseDate());\r
+\r
+ // Attributes\r
+ assertEquals(expected.getAttributes().size(), reached.getAttributes()\r
+ .size());\r
+ for (String key : expected.getAttributes().keySet()) {\r
+ String expectedValue = expected.getAttributes().get(key);\r
+ String reachedValue = reached.getAttributes().get(key);\r
+ assertNotNull(reachedValue);\r
+ assertEquals(expectedValue, reachedValue);\r
+ }\r
+\r
+ // Result parts\r
+ assertEquals(expected.getResultParts().size(), reached.getResultParts()\r
+ .size());\r
+ for (TreeSPath path : expected.getResultParts().keySet()) {\r
+ PartSubList lstExpected = expected.getResultParts().get(path);\r
+ PartSubList lstReached = expected.getResultParts().get(path);\r
+ if (lstReached == null) {\r
+ fail("No result for path " + path);\r
+ return;\r
+ }\r
+ assertPartSubList(lstExpected, lstReached);\r
+ }\r
+\r
+ // Elements\r
+ assertEquals(expected.getElements().size(), reached.getElements()\r
+ .size());\r
+ for (TreeSPath path : expected.getElements().keySet()) {\r
+ // String nameExpected = expected.getElements().get(path);\r
+ // String nameReached = expected.getElements().get(path);\r
+ SimpleSElement elemExpected = (SimpleSElement) expected\r
+ .getElements().get(path);\r
+ SimpleSElement elemReached = (SimpleSElement) expected\r
+ .getElements().get(path);\r
+ assertNotNull(elemReached);\r
+ assertElements(elemExpected, elemReached);\r
+ }\r
+\r
+ }\r
+\r
+ public static void assertElements(SimpleSElement expected,\r
+ SimpleSElement reached) {\r
+ assertEquals(expected.getLabel(), reached.getLabel());\r
+ assertEquals(expected.getTags().size(), reached.getTags().size());\r
+ for (String tagName : expected.getTags().keySet()) {\r
+ String expectedTagValue = expected.getTags().get(tagName);\r
+ String reachedTagValue = reached.getTags().get(tagName);\r
+ assertNotNull(reachedTagValue);\r
+ assertEquals(expectedTagValue, reachedTagValue);\r
+ }\r
+ }\r
+\r
+ public static void assertPartSubList(PartSubList lstExpected,\r
+ PartSubList lstReached) {\r
+ assertEquals(lstExpected.getParts().size(), lstReached.getParts()\r
+ .size());\r
+ for (int i = 0; i < lstExpected.getParts().size(); i++) {\r
+ assertPart(lstExpected.getParts().get(i), lstReached.getParts()\r
+ .get(i));\r
+ }\r
+ }\r
+\r
+ /** Asserts one part of a tree test result */\r
+ public static void assertPart(TreeTestResult testResult, String pathStr,\r
+ int index, Integer status, String message) {\r
+ TreeSPath path = new TreeSPath(pathStr);\r
+ PartSubList list = testResult.getResultParts().get(path);\r
+ if (list == null) {\r
+ fail("No result for path " + path);\r
+ return;\r
+ }\r
+ if (index >= list.getParts().size()) {\r
+ fail("Not enough parts.");\r
+ }\r
+ SimpleResultPart part = (SimpleResultPart) list.getParts().get(index);\r
+ assertPart(part, status, message, null, part.getTestRunUuid(), true);\r
+ }\r
+\r
+ public static void assertPart(TestResultPart expected,\r
+ TestResultPart reached) {\r
+ String expectedTestRunUuid = null;\r
+ if (expected instanceof SimpleResultPart) {\r
+ expectedTestRunUuid = ((SimpleResultPart) expected)\r
+ .getTestRunUuid();\r
+ }\r
+\r
+ assertPart(reached, expected.getStatus(), expected.getMessage(),\r
+ expected.getExceptionMessage(), expectedTestRunUuid, false);\r
+ }\r
+\r
+ /** Assert one part of a tree test result. */\r
+ private static void assertPart(TestResultPart part, Integer status,\r
+ String message, String exceptionDescription,\r
+ String expectedTestRunUuid, boolean skipExceptionMessage) {\r
+ assertEquals(status, part.getStatus());\r
+\r
+ if (message != null) {\r
+ if (log.isTraceEnabled()) {\r
+ log.trace("Expected message:" + message);\r
+ log.trace("Reached message:" + part.getMessage());\r
+ }\r
+ assertEquals(message, part.getMessage());\r
+ }\r
+\r
+ if (!skipExceptionMessage) {\r
+ if (exceptionDescription == null) {\r
+ assertNull(part.getExceptionMessage());\r
+ } else {\r
+ if (log.isTraceEnabled()) {\r
+ log.trace("Expected exception message:"\r
+ + exceptionDescription);\r
+ log.trace("Reached exception message:"\r
+ + part.getExceptionMessage());\r
+ }\r
+\r
+ assertEquals(exceptionDescription, part.getExceptionMessage());\r
+ }\r
+ }\r
+\r
+ if (expectedTestRunUuid != null) {\r
+ SimpleResultPart reachedPart = (SimpleResultPart) part;\r
+ assertNotNull(reachedPart.getTestRunUuid());\r
+ assertEquals(expectedTestRunUuid, reachedPart.getTestRunUuid());\r
+ } else {\r
+ if (part instanceof SimpleResultPart) {\r
+ assertNull(((SimpleResultPart) part).getTestRunUuid());\r
+ }\r
+\r
+ }\r
+\r
+ }\r
+\r
+ public static void describeTreeTestResult(TreeTestResult ttr) {\r
+ log.info("TreeTestResult #" + ttr.getUuid());\r
+ log.info(" Close date: " + ttr.getCloseDate());\r
+ log.info(" Attributes:");\r
+ for (String key : ttr.getAttributes().keySet())\r
+ log.info(" " + key + "=" + ttr.getAttributes().get(key));\r
+\r
+ log.info(" Result parts: (size=" + ttr.getResultParts().size() + ")");\r
+ for (TreeSPath path : ttr.getResultParts().keySet()) {\r
+ log.info(" Path: " + path);\r
+ PartSubList lst = ttr.getResultParts().get(path);\r
+ for (TestResultPart part : lst.getParts())\r
+ log.info(" " + part);\r
+ }\r
+\r
+ log.info(" Elements: (size=" + ttr.getElements().size() + ")");\r
+ for (TreeSPath path : ttr.getElements().keySet()) {\r
+ SimpleSElement elem = (SimpleSElement) ttr.getElements().get(path);\r
+ log.info(" Path: " + path + ", Element: " + elem.getLabel());\r
+ for (String tag : elem.getTags().keySet())\r
+ log.info(" " + tag + "=" + elem.getTags().get(tag));\r
+ }\r
+\r
+ }\r
+\r
+ /** Makes sure this is a singleton */\r
+ private UnitTestTreeUtil() {\r
+\r
+ }\r
+}\r
--- /dev/null
+Manifest-Version: 1.0\r
+Export-Package: org.argeo.slc.castor.process;version="0.11.2.SNAPSHOT"\r
+ ,org.argeo.slc.core.test.spring;version="0.11.2.SNAPSHOT",org.argeo.s\r
+ lc.dao.process;uses:="org.argeo.slc.core.process";version="0.11.2.SNA\r
+ PSHOT",org.argeo.slc.dao.test.tree;uses:="org.argeo.slc.dao.test,org.\r
+ apache.commons.logging,org.argeo.slc.core.test.tree,org.argeo.slc.cor\r
+ e.structure.tree,org.argeo.slc.core.test";version="0.11.2.SNAPSHOT",o\r
+ rg.argeo.slc.core.test;uses:="org.apache.commons.logging,org.argeo.sl\r
+ c.core,org.argeo.slc.core.test.context,org.argeo.slc.core.deploy,org.\r
+ argeo.slc.core.process,org.argeo.slc.core.structure.tree";version="0.\r
+ 11.2.SNAPSHOT",org.argeo.slc.core.structure;version="0.11.2.SNAPSHOT"\r
+ ,org.argeo.slc.msg.test.tree;uses:="org.argeo.slc.core,org.argeo.slc.\r
+ core.test.tree,org.argeo.slc.core.structure.tree,org.argeo.slc.core.t\r
+ est";version="0.11.2.SNAPSHOT",org.argeo.slc.core;version="0.11.2.SNA\r
+ PSHOT",org.argeo.slc.castor.test.tree;uses:="org.exolab.castor.mappin\r
+ g,org.argeo.slc.core.test";version="0.11.2.SNAPSHOT",org.argeo.slc.co\r
+ re.test.context;uses:="org.argeo.slc.core.structure,org.apache.common\r
+ s.logging,org.argeo.slc.core,org.argeo.slc.core.structure.tree,org.ar\r
+ geo.slc.core.test,org.springframework.beans.factory";version="0.11.2.\r
+ SNAPSHOT",org.argeo.slc.core.build;version="0.11.2.SNAPSHOT",org.arge\r
+ o.slc.core.process;uses:="org.springframework.oxm,org.argeo.slc.core,\r
+ javax.xml.transform,javax.xml.transform.stream,org.apache.commons.io"\r
+ ;version="0.11.2.SNAPSHOT",org.argeo.slc.core.structure.tree;uses:="o\r
+ rg.argeo.slc.core.structure,org.argeo.slc.core";version="0.11.2.SNAPS\r
+ HOT",org.argeo.slc.castor.msg;version="0.11.2.SNAPSHOT",org.argeo.slc\r
+ .castor.structure;version="0.11.2.SNAPSHOT",org.argeo.slc.core.proces\r
+ s.spring;version="0.11.2.SNAPSHOT",org.argeo.slc.unit;uses:="org.apac\r
+ he.commons.logging,org.springframework.context.support,org.springfram\r
+ ework.context,org.springframework.xml.xsd,org.springframework.xml.val\r
+ idation,org.xml.sax,org.argeo.slc.core,junit.framework,javax.xml.tran\r
+ sform,org.argeo.slc.spring,org.springframework.beans.factory";version\r
+ ="0.11.2.SNAPSHOT",org.argeo.slc.diff;uses:="org.argeo.slc.core,org.s\r
+ pringframework.core.io";version="0.11.2.SNAPSHOT",org.argeo.slc.xml.s\r
+ pring;version="0.11.2.SNAPSHOT",org.argeo.slc.logging;uses:="org.apac\r
+ he.log4j,org.argeo.slc.core,org.springframework.util,org.springframew\r
+ ork.core.io,org.apache.commons.io";version="0.11.2.SNAPSHOT",org.arge\r
+ o.slc.core.test.tree;uses:="org.springframework.oxm,org.apache.common\r
+ s.logging,org.springframework.xml.transform,org.springframework.core.\r
+ io,javax.xml.parsers,javax.xml.transform.dom,org.w3c.dom,org.argeo.sl\r
+ c.core.test,org.argeo.slc.core.structure,org.argeo.slc.core,javax.xml\r
+ .transform,javax.xml.transform.stream,org.apache.commons.io,org.argeo\r
+ .slc.core.structure.tree";version="0.11.2.SNAPSHOT",org.argeo.slc.cas\r
+ tor;version="0.11.2.SNAPSHOT",org.argeo.slc.unit.test.tree;uses:="org\r
+ .apache.commons.logging,org.argeo.slc.unit,org.argeo.slc.core.test.tr\r
+ ee,org.argeo.slc.core.test,org.argeo.slc.core.structure,org.argeo.slc\r
+ .msg.test.tree,junit.framework,org.argeo.slc.core.build,org.argeo.slc\r
+ .unit.process,org.argeo.slc.core.deploy,org.argeo.slc.core.process,or\r
+ g.argeo.slc.core.structure.tree";version="0.11.2.SNAPSHOT",org.argeo.\r
+ slc.dao.test;uses:="org.argeo.slc.core.test";version="0.11.2.SNAPSHOT\r
+ ",org.argeo.slc.castor.test;version="0.11.2.SNAPSHOT",org.argeo.slc.s\r
+ upport.deploy;uses:="org.apache.commons.logging,org.argeo.slc.core,or\r
+ g.argeo.slc.core.build,org.argeo.slc.core.deploy";version="0.11.2.SNA\r
+ PSHOT",org.argeo.slc.castor.structure.tree;uses:="org.exolab.castor.m\r
+ apping,org.argeo.slc.core.structure.tree";version="0.11.2.SNAPSHOT",o\r
+ rg.argeo.slc.castor.spring;version="0.11.2.SNAPSHOT",org.argeo.slc.su\r
+ pport.deploy.db;uses:="org.apache.commons.logging,org.dbunit.operatio\r
+ n,org.springframework.core.io,org.dbunit.dataset,org.argeo.slc.core,j\r
+ avax.sql,org.argeo.slc.core.build,org.dbunit.dataset.xml,org.dbunit.d\r
+ atabase,org.dbunit,org.argeo.slc.core.deploy";version="0.11.2.SNAPSHO\r
+ T",org.argeo.slc.core.test.tree.htmlreport;version="0.11.2.SNAPSHOT",\r
+ org.argeo.slc.unit.process;uses:="junit.framework,org.argeo.slc.unit,\r
+ org.argeo.slc.core.process";version="0.11.2.SNAPSHOT",org.argeo.slc.s\r
+ pring;uses:="org.apache.commons.logging,org.argeo.slc.core,org.spring\r
+ framework.core.io,org.springframework.beans.factory";version="0.11.2.\r
+ SNAPSHOT",org.argeo.slc.runtime;uses:="org.argeo.slc.core.process";ve\r
+ rsion="0.11.2.SNAPSHOT",org.argeo.slc.core.deploy;uses:="org.apache.c\r
+ ommons.logging,org.argeo.slc.core,org.argeo.slc.core.build";version="\r
+ 0.11.2.SNAPSHOT",org.argeo.slc.msg.process;uses:="org.argeo.slc.core.\r
+ process";version="0.11.2.SNAPSHOT",org.argeo.slc.xml;version="0.11.2.\r
+ SNAPSHOT"\r
+Tool: Bnd-0.0.255\r
+Bundle-Name: Argeo SLC Core\r
+Created-By: 1.6.0 (Sun Microsystems Inc.)\r
+Bundle-Vendor: Argeo\r
+Bundle-Version: 0.11.2.SNAPSHOT\r
+Bundle-ManifestVersion: 2\r
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt\r
+Bundle-Description: SLC Core\r
+Import-Package: javax.sql,javax.xml.parsers;version="1.3",javax.xml.tr\r
+ ansform;version="1.3",javax.xml.transform.dom;version="1.3",javax.xml\r
+ .transform.stream;version="1.3",junit.framework;version="3.8",org.apa\r
+ che.commons.io;version="1.4",org.apache.commons.logging;version="1.1"\r
+ ,org.apache.log4j;version="1.2",org.argeo.slc.castor;version="0.11.2.\r
+ SNAPSHOT",org.argeo.slc.castor.msg;version="0.11.2.SNAPSHOT",org.arge\r
+ o.slc.castor.process;version="0.11.2.SNAPSHOT",org.argeo.slc.castor.s\r
+ pring;version="0.11.2.SNAPSHOT",org.argeo.slc.castor.structure;versio\r
+ n="0.11.2.SNAPSHOT",org.argeo.slc.castor.structure.tree;version="0.11\r
+ .2.SNAPSHOT",org.argeo.slc.castor.test;version="0.11.2.SNAPSHOT",org.\r
+ argeo.slc.castor.test.tree;version="0.11.2.SNAPSHOT",org.argeo.slc.co\r
+ re;version="0.11.2.SNAPSHOT",org.argeo.slc.core.build;version="0.11.2\r
+ .SNAPSHOT",org.argeo.slc.core.deploy;version="0.11.2.SNAPSHOT",org.ar\r
+ geo.slc.core.process;version="0.11.2.SNAPSHOT",org.argeo.slc.core.pro\r
+ cess.spring;version="0.11.2.SNAPSHOT",org.argeo.slc.core.structure;ve\r
+ rsion="0.11.2.SNAPSHOT",org.argeo.slc.core.structure.tree;version="0.\r
+ 11.2.SNAPSHOT",org.argeo.slc.core.test;version="0.11.2.SNAPSHOT",org.\r
+ argeo.slc.core.test.context;version="0.11.2.SNAPSHOT",org.argeo.slc.c\r
+ ore.test.spring;version="0.11.2.SNAPSHOT",org.argeo.slc.core.test.tre\r
+ e;version="0.11.2.SNAPSHOT",org.argeo.slc.core.test.tree.htmlreport;v\r
+ ersion="0.11.2.SNAPSHOT",org.argeo.slc.dao.process;version="0.11.2.SN\r
+ APSHOT",org.argeo.slc.dao.test;version="0.11.2.SNAPSHOT",org.argeo.sl\r
+ c.dao.test.tree;version="0.11.2.SNAPSHOT",org.argeo.slc.diff;version=\r
+ "0.11.2.SNAPSHOT",org.argeo.slc.logging;version="0.11.2.SNAPSHOT",org\r
+ .argeo.slc.msg.process;version="0.11.2.SNAPSHOT",org.argeo.slc.msg.te\r
+ st.tree;version="0.11.2.SNAPSHOT",org.argeo.slc.runtime;version="0.11\r
+ .2.SNAPSHOT",org.argeo.slc.spring;version="0.11.2.SNAPSHOT",org.argeo\r
+ .slc.support.deploy;version="0.11.2.SNAPSHOT",org.argeo.slc.support.d\r
+ eploy.db;version="0.11.2.SNAPSHOT",org.argeo.slc.unit;version="0.11.2\r
+ .SNAPSHOT",org.argeo.slc.unit.process;version="0.11.2.SNAPSHOT",org.a\r
+ rgeo.slc.unit.test.tree;version="0.11.2.SNAPSHOT",org.argeo.slc.xml;v\r
+ ersion="0.11.2.SNAPSHOT",org.argeo.slc.xml.spring;version="0.11.2.SNA\r
+ PSHOT",org.dbunit;version="2.2",org.dbunit.database;version="2.2",org\r
+ .dbunit.dataset;version="2.2",org.dbunit.dataset.xml;version="2.2",or\r
+ g.dbunit.operation;version="2.2",org.exolab.castor.mapping;version="1\r
+ .2",org.springframework.beans.factory;version="2.5.6.A",org.springfra\r
+ mework.context;version="2.5.6.A",org.springframework.context.support;\r
+ version="2.5.6.A",org.springframework.core.io;version="2.5.6.A",org.s\r
+ pringframework.oxm;version="1.5.5.A",org.springframework.util;version\r
+ ="2.5.6.A",org.springframework.xml.transform;version="1.5.5.A",org.sp\r
+ ringframework.xml.validation;version="1.5.5.A",org.springframework.xm\r
+ l.xsd;version="1.5.5.A",org.w3c.dom;version="1.3",org.xml.sax;version\r
+ ="1.3"\r
+Bundle-SymbolicName: org.argeo.slc.core\r
+Bundle-DocURL: http://www.argeo.org\r
+Originally-Created-By: 1.6.0 (Sun Microsystems Inc.)\r
+\r
--- /dev/null
+<?xml version="1.0"?>\r
+\r
+<mapping>\r
+ <description>Mapping of generic types</description>\r
+\r
+ <class name="java.lang.Exception" auto-complete="false">\r
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"\r
+ ns-prefix="slc" />\r
+ <field name="message" type="string" set-method="%1"\r
+ get-method="getMessage">\r
+ <bind-xml node="attribute" />\r
+ </field>\r
+ <field name="stackTrace" collection="array"\r
+ type="java.lang.StackTraceElement">\r
+ <bind-xml auto-naming="deriveByClass"\r
+ location="stack-trace" />\r
+ </field>\r
+ </class>\r
+\r
+ <class name="java.lang.StackTraceElement" auto-complete="false"\r
+ verify-constructable="false">\r
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"\r
+ ns-prefix="slc" />\r
+ <field name="declaringClass" type="string" set-method="%1"\r
+ get-method="getClassName">\r
+ <bind-xml node="attribute" />\r
+ </field>\r
+ <field name="methodName" type="string" set-method="%2"\r
+ get-method="getMethodName">\r
+ <bind-xml node="attribute" />\r
+ </field>\r
+ <field name="fileName" type="string" set-method="%3"\r
+ get-method="getFileName">\r
+ <bind-xml node="attribute" />\r
+ </field>\r
+ <field name="lineNumber" type="integer" set-method="%4"\r
+ get-method="getLineNumber">\r
+ <bind-xml node="attribute" />\r
+ </field>\r
+ </class>\r
+</mapping>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+
+<mapping>
+ <description>Message objects XML mapping</description>
+
+ <!-- TESTS -->
+ <class
+ name="org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest">
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+ ns-prefix="slc" />
+ <field name="treeTestResult"
+ type="org.argeo.slc.core.test.tree.TreeTestResult" />
+ <field name="testRunDescriptor" />
+ </class>
+
+ <class
+ name="org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest">
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+ ns-prefix="slc" />
+ <field name="resultUuid" />
+ <field name="closeDate" />
+ </class>
+
+ <class name="org.argeo.slc.msg.test.tree.ResultPartRequest">
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+ ns-prefix="slc" />
+ <field name="resultUuid" />
+ <field name="resultPart"
+ type="org.argeo.slc.core.test.SimpleResultPart">
+ <bind-xml auto-naming="deriveByClass" />
+ </field>
+
+ <field name="relatedElements" collection="map">
+ <bind-xml name="element" location="related-elements">
+ <class name="org.exolab.castor.mapping.MapItem">
+ <map-to
+ ns-uri="http://argeo.org/projects/slc/schemas"
+ ns-prefix="slc" />
+ <field name="key"
+ type="org.argeo.slc.core.structure.tree.TreeSPath"
+ handler="org.argeo.slc.castor.structure.tree.TreeSPathFieldHandler">
+ <bind-xml name="path" node="attribute" />
+ </field>
+ <field name="value"
+ type="org.argeo.slc.core.structure.SimpleSElement">
+ <bind-xml auto-naming="deriveByClass" />
+ </field>
+ </class>
+ </bind-xml>
+ </field>
+ <field name="path">
+ <bind-xml auto-naming="deriveByClass" />
+ </field>
+ <field name="testRunDescriptor" />
+ <field name="attributes" collection="hashtable">
+ <bind-xml name="attribute" location="attributes">
+ <class name="org.exolab.castor.mapping.MapItem">
+ <map-to
+ ns-uri="http://argeo.org/projects/slc/schemas"
+ ns-prefix="slc" />
+ <field name="key" type="string">
+ <bind-xml name="name" node="attribute" />
+ </field>
+ <field name="value" type="string">
+ <bind-xml node="text" />
+ </field>
+ </class>
+ </bind-xml>
+ </field>
+ </class>
+
+
+ <!-- PROCESS -->
+ <class name="org.argeo.slc.msg.process.SlcExecutionStepsRequest">
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+ ns-prefix="slc" />
+ <field name="slcExecutionUuid" />
+ <field name="steps" collection="vector"
+ type="org.argeo.slc.core.process.SlcExecutionStep">
+ <bind-xml auto-naming="deriveByClass" location="steps" />
+ </field>
+ </class>
+
+ <class name="org.argeo.slc.msg.process.SlcExecutionStatusRequest">
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+ ns-prefix="slc" />
+ <field name="slcExecutionUuid" />
+ <field name="newStatus" />
+ </class>
+
+ <class name="org.argeo.slc.msg.process.SlcExecutionRequest">
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+ ns-prefix="slc" />
+ <field name="slcExecution"
+ type="org.argeo.slc.core.process.SlcExecution" />
+ </class>
+
+
+</mapping>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>\r
+\r
+<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http://castor.org/mapping.dtd">\r
+\r
+<mapping>\r
+ <description>Process objects XML mapping</description>\r
+\r
+ <class name="org.argeo.slc.core.process.SlcExecution">\r
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"\r
+ ns-prefix="slc" />\r
+ <field name="uuid" identity="true">\r
+ <bind-xml node="attribute" />\r
+ </field>\r
+ <field name="status" />\r
+ <field name="type" />\r
+ <field name="host" />\r
+ <field name="user" />\r
+ <field name="steps" collection="vector"\r
+ type="org.argeo.slc.core.process.SlcExecutionStep">\r
+ <bind-xml auto-naming="deriveByClass" location="steps" />\r
+ </field>\r
+ <field name="attributes" collection="map">\r
+ <bind-xml name="attribute" location="attributes">\r
+ <class name="org.exolab.castor.mapping.MapItem">\r
+ <map-to\r
+ ns-uri="http://argeo.org/projects/slc/schemas" ns-prefix="slc" />\r
+ <field name="key" type="string">\r
+ <bind-xml name="name" node="attribute" />\r
+ </field>\r
+ <field name="value" type="string">\r
+ <bind-xml node="text" />\r
+ </field>\r
+ </class>\r
+ </bind-xml>\r
+ </field>\r
+ </class>\r
+\r
+ <class name="org.argeo.slc.core.process.SlcExecutionStep">\r
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"\r
+ ns-prefix="slc" />\r
+ <field name="uuid" identity="true">\r
+ <bind-xml node="attribute" />\r
+ </field>\r
+ <field name="type" />\r
+ <field name="begin" />\r
+ <field name="logLines" collection="vector" type="string">\r
+ <bind-xml name="log-line" location="log-lines" />\r
+ </field>\r
+ </class>\r
+ \r
+</mapping>
\ No newline at end of file
--- /dev/null
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
+ default-lazy-init="true">
+
+ <bean id="slcDefault.castor.marshaller"
+ class="org.springframework.oxm.castor.CastorMarshaller">
+ <property name="mappingLocations">
+ <list>
+ <value>
+ classpath:org/argeo/slc/castor/msg/mapping.xml
+ </value>
+ <value>
+ classpath:org/argeo/slc/castor/process/mapping.xml
+ </value>
+ <value>
+ classpath:org/argeo/slc/castor/structure/mapping.xml
+ </value>
+ <value>
+ classpath:org/argeo/slc/castor/test/mapping.xml
+ </value>
+ </list>
+ </property>
+ <property name="whitespacePreserve" value="true" />
+ </bean>
+
+ <bean id="slcDefault.castor.xsltReportGenerator"
+ class="org.argeo.slc.core.test.tree.XsltReportGenerator"
+ init-method="init">
+ <property name="xsltStyleSheet"
+ value="classpath:/org/argeo/slc/core/test/tree/basicReport.xslt" />
+ <property name="marshaller" ref="slcDefault.castor.marshaller" />
+ <property name="logXml" value="false" />
+ <property name="outputDir" value="${slc.workDir}/results/html" />
+ </bean>
+
+
+</beans>
--- /dev/null
+<?xml version="1.0"?>\r
+\r
+<mapping>\r
+ <description>Structure related objects XML mapping</description>\r
+\r
+ <class name="org.argeo.slc.core.structure.tree.TreeSPath"\r
+ auto-complete="false">\r
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"\r
+ ns-prefix="slc" />\r
+ <field name="asUniqueString" type="string">\r
+ <bind-xml node="attribute" />\r
+ </field>\r
+ </class>\r
+\r
+ <class name="org.argeo.slc.core.structure.SimpleSElement"\r
+ auto-complete="false">\r
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"\r
+ ns-prefix="slc" />\r
+ <field name="label" type="string" />\r
+ <field name="tags" collection="map">\r
+ <bind-xml name="tag" location="tags">\r
+ <class name="org.exolab.castor.mapping.MapItem">\r
+ <map-to\r
+ ns-uri="http://argeo.org/projects/slc/schemas" ns-prefix="slc" />\r
+ <field name="key" type="string">\r
+ <bind-xml name="name" node="attribute" />\r
+ </field>\r
+ <field name="value" type="string">\r
+ <bind-xml name="tag-value" />\r
+ </field>\r
+ </class>\r
+ </bind-xml>\r
+ </field>\r
+ </class>\r
+</mapping>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+
+<mapping>
+ <description>Test objects XML mapping</description>
+
+ <class name="org.argeo.slc.core.test.TestRunDescriptor"
+ auto-complete="false">
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+ ns-prefix="slc" />
+ <field name="testRunUuid" />
+ <field name="slcExecutionUuid" />
+ <field name="slcExecutionStepUuid" />
+ <field name="testResultUuid" />
+ <field name="deployedSytemId" />
+ </class>
+
+ <class name="org.argeo.slc.core.test.tree.TreeTestResult"
+ auto-complete="false">
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+ ns-prefix="slc" />
+ <field name="uuid" type="string">
+ <bind-xml name="uuid" node="attribute" />
+ </field>
+ <field name="closeDate" />
+ <field name="attributes" collection="map">
+ <bind-xml name="attribute" location="attributes">
+ <class name="org.exolab.castor.mapping.MapItem">
+ <map-to
+ ns-uri="http://argeo.org/projects/slc/schemas" ns-prefix="slc" />
+ <field name="key" type="string">
+ <bind-xml name="name" node="attribute" />
+ </field>
+ <field name="value" type="string">
+ <bind-xml node="text" />
+ </field>
+ </class>
+ </bind-xml>
+ </field>
+ <field name="resultParts" collection="sortedmap">
+ <bind-xml name="result-part" location="result-parts">
+ <class name="org.exolab.castor.mapping.MapItem">
+ <map-to
+ ns-uri="http://argeo.org/projects/slc/schemas" ns-prefix="slc" />
+ <field name="key"
+ type="org.argeo.slc.core.structure.tree.TreeSPath"
+ handler="org.argeo.slc.castor.structure.tree.TreeSPathFieldHandler">
+ <bind-xml name="path" node="attribute" />
+ </field>
+ <field name="value"
+ type="org.argeo.slc.core.test.tree.PartSubList">
+ <bind-xml name="part-sub-list" />
+ </field>
+ </class>
+ </bind-xml>
+ </field>
+ <field name="elements" collection="sortedmap">
+ <bind-xml name="element" location="elements">
+ <class name="org.exolab.castor.mapping.MapItem">
+ <map-to
+ ns-uri="http://argeo.org/projects/slc/schemas" ns-prefix="slc" />
+ <field name="key"
+ type="org.argeo.slc.core.structure.tree.TreeSPath"
+ handler="org.argeo.slc.castor.structure.tree.TreeSPathFieldHandler">
+ <bind-xml name="path" node="attribute" />
+ </field>
+ <field name="value"
+ type="org.argeo.slc.core.structure.SimpleSElement">
+ <bind-xml auto-naming="deriveByClass" />
+ </field>
+ </class>
+ </bind-xml>
+ </field>
+ </class>
+
+ <class name="org.argeo.slc.core.test.tree.PartSubList"
+ auto-complete="false">
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+ ns-prefix="slc" />
+ <field name="parts" collection="arraylist"
+ type="org.argeo.slc.core.test.SimpleResultPart">
+ <bind-xml auto-naming="deriveByClass" location="parts" />
+ </field>
+ </class>
+
+ <class name="org.argeo.slc.core.test.SimpleResultPart"
+ auto-complete="false">
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+ ns-prefix="slc" />
+ <field name="testRunUuid" type="string" />
+ <field name="message" type="string" />
+ <field name="status" type="string"
+ handler="org.argeo.slc.castor.test.tree.StatusFieldHandler" />
+ <field name="exceptionMessage" type="string" />
+ </class>
+
+ <class name="org.argeo.slc.core.test.tree.TreeTestResultCollection"
+ auto-complete="false">
+ <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+ ns-prefix="slc" />
+ <field name="id" type="string">
+ <bind-xml name="id" node="attribute" />
+ </field>
+ <field name="results" collection="set"
+ type="org.argeo.slc.core.test.tree.TreeTestResult">
+ <bind-xml auto-naming="deriveByClass" location="results" />
+ </field>
+ </class>
+</mapping>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"\r
+ default-lazy-init="true">\r
+\r
+ <import
+ resource="classpath:/org/argeo/slc/castor/spring/applicationContext.xml" />
+
+ <bean name="slcDefault.process.fileSlcExecutionNotifier"
+ class="org.argeo.slc.core.process.FileSlcExecutionNotifier">
+ <property name="basePath" value="${slc.workDir}/process" />
+ <property name="marshaller" ref="slcDefault.castor.marshaller" />
+ </bean>
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
+ default-lazy-init="true">
+
+ <bean id="slcDefault.test.resultLogger"
+ class="org.argeo.slc.core.test.tree.TreeTestResultLogger">
+ </bean>
+
+ <bean name="slcDefault.test.testRun"
+ class="org.argeo.slc.core.test.SimpleTestRun"
+ scope="prototype">
+ </bean>
+
+ <bean name="slcDefault.test.uuid" class="java.util.UUID"
+ factory-method="randomUUID" scope="prototype">
+ </bean>
+
+ <bean id="slcDefault.test.basicTreeTestResult"
+ class="org.argeo.slc.core.test.tree.TreeTestResult"
+ abstract="true" destroy-method="close">
+ <property name="uuid">
+ <bean factory-bean="slcDefault.test.uuid"
+ factory-method="toString">
+ </bean>
+ </property>
+ <property name="listeners">
+ <list>
+ <ref bean="slcDefault.test.resultLogger" />
+ </list>
+ </property>
+ </bean>
+
+ <bean id="slcDefault.test.basicSimpleTestResult"
+ class="org.argeo.slc.core.test.SimpleTestResult"
+ abstract="true">
+ <property name="uuid">
+ <bean factory-bean="slcDefault.test.uuid"
+ factory-method="toString">
+ </bean>
+ </property>
+ </bean>
+
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<xsl:stylesheet version="1.0"\r
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\r
+ xmlns:slc="http://argeo.org/projects/slc/schemas"\r
+ exclude-result-prefixes="slc">\r
+\r
+ <xsl:output method="html" omit-xml-declaration="yes" />\r
+\r
+ <xsl:template match="/">\r
+ <html>\r
+ <head>\r
+ <title>Result</title>\r
+ </head>\r
+ <body style="font-family: sans-serif">\r
+ <h1>\r
+ Result\r
+ <xsl:value-of select="slc:tree-test-result/@uuid" />\r
+ </h1>\r
+ <xsl:for-each\r
+ select="slc:tree-test-result/slc:result-parts/slc:result-part">\r
+ <h2>\r
+ <xsl:value-of select="@path" />\r
+ </h2>\r
+ <table>\r
+ <xsl:for-each\r
+ select="slc:part-sub-list/slc:parts/slc:simple-result-part">\r
+ <tr>\r
+ <xsl:choose>\r
+ <xsl:when\r
+ test="slc:status = 'PASSED' ">\r
+ <td style="color:green">\r
+ <xsl:value-of\r
+ select="slc:message" />\r
+ </td>\r
+ </xsl:when>\r
+ <xsl:otherwise>\r
+ <td style="color:red">\r
+ <xsl:value-of\r
+ select="slc:message" />\r
+ </td>\r
+ </xsl:otherwise>\r
+ </xsl:choose>\r
+ </tr>\r
+ </xsl:for-each>\r
+ </table>\r
+ </xsl:for-each>\r
+ </body>\r
+ </html>\r
+ </xsl:template>\r
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null
+<html>\r
+<head>\r
+<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">\r
+<title>SLC test results</title>\r
+</head>\r
+<frameset cols="30%,70%">\r
+ <frame src="slc-resultsList.html" name="navigation">\r
+ <frame src="about:blank" name="main">\r
+ <noframes>\r
+ <h2>Frame Alert</h2>\r
+ <p>This document is designed to be viewed using the frames feature.\r
+ If you see this message, you are using a non-frame-capable web client.\r
+ </p>\r
+ </noframes>\r
+</frameset>\r
+</html>\r
--- /dev/null
+body {\r
+ font-family: sans-serif;\r
+ font-size: 12px;\r
+ color: black;\r
+ background-color: white;\r
+}\r
+\r
+h1 {\r
+ font-family: sans-serif;\r
+ font-size: 16px;\r
+ font-weight: bold;\r
+ color: #000000;\r
+ padding: 0px 0px 5px 0px;\r
+ margin: 0px;\r
+}\r
+\r
+h2 {\r
+ font-family: sans-serif;\r
+ font-size: 14px;\r
+ font-weight: bold;\r
+ color: #000000;\r
+ padding: 5px 0px 5px 0px;\r
+ margin: 0px;\r
+ margin-top: 5px;\r
+}\r
+\r
+table,form {\r
+ margin: 0px;\r
+}\r
+\r
+th {\r
+ font-size: 12px;\r
+ padding: 2px 20px 2px 2px;\r
+ vertical-align: top;\r
+ text-align: left;\r
+}\r
+\r
+td {\r
+ font-size: 12px;\r
+ padding: 1px;\r
+ vertical-align: top;\r
+ text-align: left;\r
+}\r
+\r
+.passed {\r
+ color: green;\r
+}\r
+\r
+.failed {\r
+ color: red;\r
+}\r
+\r
+a {\r
+ text-decoration: none;\r
+}\r
+\r
+a.nav {\r
+ color: #0066CC;\r
+ text-decoration: none;\r
+}\r
+\r
+a:hover {\r
+ text-decoration: underline;\r
+}
\ No newline at end of file
--- /dev/null
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:slc="http://argeo.org/projects/slc/schemas"
+ elementFormDefault="qualified"
+ targetNamespace="http://argeo.org/projects/slc/schemas">
+ <!-- TREE TEST RESULT -->
+ <xs:element name="tree-test-result" type="slc:TreeTestResultType" />
+ <xs:element name="tree-test-result-collection"
+ type="slc:TreeTestResultCollectionType" />
+
+ <xs:complexType name="TreeTestResultCollectionType">
+ <xs:all>
+ <xs:element name="results" minOccurs="0"
+ type="slc:ResultsType" />
+ </xs:all>
+ <xs:attribute name="id" use="required" />
+ </xs:complexType>
+ <xs:complexType name="ResultsType">
+ <xs:sequence>
+ <xs:element name="tree-test-result"
+ type="slc:TreeTestResultType" minOccurs="0"
+ maxOccurs="unbounded">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="TreeTestResultType">
+ <xs:all>
+ <xs:element name="close-date" type="xs:dateTime"
+ minOccurs="0" />
+ <xs:element name="attributes" minOccurs="0"
+ type="slc:AttributesType" />
+ <xs:element name="result-parts" minOccurs="0"
+ type="slc:ResultPartsType" />
+ <xs:element name="elements" minOccurs="0"
+ type="slc:ElementsType" />
+ </xs:all>
+ <xs:attribute name="uuid" use="required" />
+ </xs:complexType>
+ <xs:complexType name="ResultPartsType">
+ <xs:sequence>
+ <xs:element name="result-part" type="slc:ResultPartType"
+ minOccurs="0" maxOccurs="unbounded">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="ResultPartType">
+ <xs:all>
+ <xs:element name="part-sub-list" type="slc:PartSubListType" />
+ </xs:all>
+ <xs:attribute name="path" type="xs:string" use="required" />
+ </xs:complexType>
+ <xs:complexType name="PartSubListType">
+ <xs:all>
+ <xs:element name="parts" minOccurs="0" type="slc:PartsType" />
+ </xs:all>
+ </xs:complexType>
+ <xs:complexType name="PartsType">
+ <xs:sequence>
+ <xs:element name="simple-result-part"
+ type="slc:SimpleResultPartType" maxOccurs="unbounded">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="SimpleResultPartType">
+ <xs:all>
+ <xs:element name="status">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="PASSED" />
+ <xs:enumeration value="FAILED" />
+ <xs:enumeration value="ERROR" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="message" type="xs:string" />
+ <xs:element name="exception-message" minOccurs="0"
+ type="xs:string" />
+ <xs:element name="stack-lines" minOccurs="0"
+ type="slc:StackLinesType" />
+ <xs:element name="test-run-uuid" type="xs:string"
+ minOccurs="0" />
+ </xs:all>
+ </xs:complexType>
+ <xs:complexType name="StackLinesType">
+ <xs:sequence>
+ <xs:element name="stack-line" maxOccurs="unbounded"
+ type="xs:string" />
+ </xs:sequence>
+ <xs:attribute name="message" type="xs:string" />
+ </xs:complexType>
+ <xs:complexType name="ElementsType">
+ <xs:sequence>
+ <xs:element name="element" type="slc:ElementType"
+ minOccurs="0" maxOccurs="unbounded">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="ElementType">
+ <xs:all>
+ <xs:element name="simple-sElement"
+ type="slc:SimpleSElementType" />
+ </xs:all>
+ <xs:attribute name="path" type="xs:string" use="required" />
+ </xs:complexType>
+ <xs:complexType name="SimpleSElementType">
+ <xs:all>
+ <xs:element name="label" type="xs:string" />
+ <xs:element name="tags" type="slc:TagsType" minOccurs="0" />
+ </xs:all>
+ </xs:complexType>
+ <xs:complexType name="TagsType">
+ <xs:sequence>
+ <xs:element name="tag" type="slc:TagType" minOccurs="0"
+ maxOccurs="unbounded">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="TagType">
+ <xs:all>
+ <xs:element name="tag-value" type="xs:string" />
+ </xs:all>
+ <xs:attribute name="name" type="xs:string" use="required" />
+ </xs:complexType>
+ <xs:complexType name="TreeSPathType">
+ <xs:attribute name="as-unique-string" type="xs:string"
+ use="required" />
+ </xs:complexType>
+ <xs:complexType name="TestRunDescriptorType">
+ <xs:all>
+ <xs:element name="test-run-uuid" type="xs:string" />
+ <xs:element name="slc-execution-uuid" type="xs:string"
+ minOccurs="0" />
+ <xs:element name="slc-execution-step-uuid" type="xs:string"
+ minOccurs="0" />
+ <xs:element name="deployed-sytem-id" type="xs:string"
+ minOccurs="0" />
+ <xs:element name="test-result-uuid" type="xs:string"
+ minOccurs="0" />
+ </xs:all>
+ </xs:complexType>
+
+ <!-- TREE TEST RESULT REQUESTS -->
+ <xs:element name="create-tree-test-result-request">
+ <xs:complexType>
+ <xs:all>
+ <xs:element name="tree-test-result"
+ type="slc:TreeTestResultType" />
+ <xs:element name="test-run-descriptor"
+ type="slc:TestRunDescriptorType" maxOccurs="1" minOccurs="0"/>
+ </xs:all>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="close-tree-test-result-request">
+ <xs:complexType>
+ <xs:all>
+ <xs:element name="result-uuid" type="xs:string" />
+ <xs:element name="close-date" type="xs:dateTime" />
+ </xs:all>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="result-part-request">
+ <xs:complexType>
+ <xs:all>
+ <xs:element name="result-uuid" type="xs:string" />
+ <xs:element name="simple-result-part"
+ type="slc:SimpleResultPartType" />
+ <xs:element name="related-elements"
+ type="slc:ElementsType" />
+ <xs:element name="tree-sPath" type="slc:TreeSPathType" />
+ <xs:element name="test-run-descriptor"
+ type="slc:TestRunDescriptorType" />
+ <xs:element name="attributes" minOccurs="0"
+ type="slc:AttributesType" />
+ </xs:all>
+ </xs:complexType>
+ </xs:element>
+
+ <!-- SLC EXECUTION -->
+ <xs:element name="slc-execution" type="slc:SlcExecutionType" />
+ <xs:complexType name="SlcExecutionType">
+ <xs:all>
+ <xs:element name="status" type="xs:string" />
+ <xs:element name="type" type="xs:string" />
+ <xs:element name="host" type="xs:string" />
+ <xs:element name="user" type="xs:string" />
+ <xs:element name="steps" minOccurs="0"
+ type="slc:SlcExecutionStepsType" />
+ <xs:element name="attributes" minOccurs="0"
+ type="slc:AttributesType" />
+ </xs:all>
+ <xs:attribute name="uuid" type="xs:string" use="required" />
+ </xs:complexType>
+ <xs:complexType name="SlcExecutionStepsType">
+ <xs:sequence>
+ <xs:element name="slc-execution-step"
+ type="slc:SlcExecutionStepType" maxOccurs="unbounded">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="SlcExecutionStepType">
+ <xs:all>
+ <xs:element name="type" type="xs:string" />
+ <xs:element name="begin" type="xs:dateTime" />
+ <xs:element name="log-lines" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="log-line" type="xs:string"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:all>
+ <xs:attribute name="uuid" type="xs:string" use="required" />
+ </xs:complexType>
+ <xs:complexType name="AttributesType">
+ <xs:sequence>
+ <xs:element name="attribute" type="slc:AttributeType"
+ minOccurs="0" maxOccurs="unbounded">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="AttributeType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="name" type="xs:string"
+ use="required" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- SLC EXECUTION REQUESTS-->
+ <xs:element name="slc-execution-request">
+ <xs:complexType>
+ <xs:all>
+ <xs:element name="slc-execution"
+ type="slc:SlcExecutionType" />
+ </xs:all>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="slc-execution-steps-request">
+ <xs:complexType>
+ <xs:all>
+ <xs:element name="slc-execution-uuid" type="xs:string" />
+ <xs:element name="steps"
+ type="slc:SlcExecutionStepsType" />
+ </xs:all>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="slc-execution-status-request">
+ <xs:complexType>
+ <xs:all>
+ <xs:element name="slc-execution-uuid" type="xs:string" />
+ <xs:element name="new-status" type="xs:string" />
+ </xs:all>
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
\ No newline at end of file
--- /dev/null
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"\r
+ default-lazy-init="true">\r
+\r
+ <bean id="slcDefault.xml.xsdValidator"\r
+ factory-bean="slcDefault.xml.xsdSchema" factory-method="createValidator" />\r
+\r
+ <bean id="slcDefault.xml.xsdSchema"\r
+ class="org.springframework.xml.xsd.SimpleXsdSchema">\r
+ <property name="xsd"\r
+ value="classpath:/org/argeo/slc/xml/slc.xsd" />\r
+ </bean>\r
+</beans>\r
--- /dev/null
+Argeo SLC Site
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.core.process;\r
+\r
+import java.io.IOException;\r
+import java.io.StringReader;\r
+import java.text.SimpleDateFormat;\r
+import java.util.UUID;\r
+\r
+import javax.xml.transform.stream.StreamSource;\r
+\r
+import org.apache.commons.io.IOUtils;\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.msg.process.SlcExecutionRequest;\r
+import org.argeo.slc.msg.process.SlcExecutionStepsRequest;\r
+import org.argeo.slc.unit.AbstractSpringTestCase;\r
+import org.argeo.slc.unit.UnitXmlUtils;\r
+import org.argeo.slc.unit.process.SlcExecutionTestUtils;\r
+import org.springframework.oxm.Marshaller;\r
+import org.springframework.oxm.Unmarshaller;\r
+import org.springframework.xml.transform.StringResult;\r
+import org.springframework.xml.transform.StringSource;\r
+import org.springframework.xml.validation.XmlValidator;\r
+\r
+public class SlcExecutionCastorTest extends AbstractSpringTestCase {\r
+ private Log log = LogFactory.getLog(getClass());\r
+\r
+ private Marshaller marshaller;\r
+ private Unmarshaller unmarshaller;\r
+\r
+ @Override\r
+ public void setUp() {\r
+ marshaller = getBean(Marshaller.class);\r
+ unmarshaller = getBean(Unmarshaller.class);\r
+ }\r
+\r
+ public void testMarshalling() throws Exception {\r
+ SlcExecution slcExec = SlcExecutionTestUtils.createSimpleSlcExecution();\r
+\r
+ SlcExecutionRequest msgSave = new SlcExecutionRequest();\r
+ msgSave.setSlcExecution(slcExec);\r
+\r
+ String msgSaveXml = marshallAndLog(marshaller, msgSave);\r
+\r
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");\r
+ SlcExecutionStep step0 = new SlcExecutionStep();\r
+ step0.setUuid(UUID.randomUUID().toString());\r
+ step0.setBegin(sdf.parse("2008-04-17 18:21"));\r
+ step0.setType("LOG");\r
+ step0.addLog("A log message\nand another line");\r
+\r
+ SlcExecutionStep step1 = new SlcExecutionStep();\r
+ step1.setUuid(UUID.randomUUID().toString());\r
+ step1.setBegin(sdf.parse("2008-04-17 18:25"));\r
+ step1.setType("LOG");\r
+ step1.addLog("A nother log message");\r
+\r
+ SlcExecutionStepsRequest msgNotif = new SlcExecutionStepsRequest();\r
+ msgNotif.addStep(step0);\r
+ msgNotif.addStep(step1);\r
+ msgNotif.setSlcExecutionUuid(slcExec.getUuid());\r
+\r
+ String msgNotifXml = marshallAndLog(marshaller, msgNotif);\r
+\r
+ SlcExecutionRequest msgSaveUnm = unmarshall(unmarshaller, msgSaveXml);\r
+ assertNotNull(msgSaveUnm);\r
+ SlcExecutionTestUtils.assertSlcExecution(slcExec, msgSaveUnm\r
+ .getSlcExecution());\r
+\r
+ SlcExecutionStepsRequest msgNotifUnm = unmarshall(unmarshaller,\r
+ msgNotifXml);\r
+ assertNotNull(msgNotifUnm);\r
+ assertEquals(slcExec.getUuid(), msgNotifUnm.getSlcExecutionUuid());\r
+ assertEquals(2, msgNotifUnm.getSteps().size());\r
+ SlcExecutionTestUtils.assertSlcExecutionStep(step0, msgNotifUnm\r
+ .getSteps().get(0));\r
+ SlcExecutionTestUtils.assertSlcExecutionStep(step1, msgNotifUnm\r
+ .getSteps().get(1));\r
+\r
+ SlcExecution slcExecUnm = msgSaveUnm.getSlcExecution();\r
+ slcExecUnm.getSteps().addAll(msgNotifUnm.getSteps());\r
+\r
+ SlcExecutionRequest msgUpdate = new SlcExecutionRequest();\r
+ msgUpdate.setSlcExecution(slcExecUnm);\r
+ String msgUpdateXml = marshallAndLog(marshaller, msgUpdate);\r
+\r
+ SlcExecutionRequest msgUpdateUnm = unmarshall(unmarshaller,\r
+ msgUpdateXml);\r
+ assertNotNull(msgUpdateUnm);\r
+ }\r
+\r
+ private String marshallAndLog(Marshaller marshaller, Object obj)\r
+ throws IOException {\r
+ StringResult xml = new StringResult();\r
+ marshaller.marshal(obj, xml);\r
+ log.info("Marshalled object: " + xml);\r
+\r
+ UnitXmlUtils.assertXmlValidation(getBean(XmlValidator.class),\r
+ new StringSource(xml.toString()));\r
+\r
+ return xml.toString();\r
+ }\r
+\r
+ private <T> T unmarshall(Unmarshaller unmarshaller, String xml)\r
+ throws IOException {\r
+ StringReader reader = new StringReader(xml);\r
+ Object obj = unmarshaller.unmarshal(new StreamSource(reader));\r
+ IOUtils.closeQuietly(reader);\r
+ return (T) obj;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.structure.tree;\r
+\r
+import junit.framework.TestCase;\r
+\r
+public class TreeSPathTest extends TestCase {\r
+\r
+ public void testNew() {\r
+ TreeSPath path = new TreeSPath("/test");\r
+ assertEquals("test", path.getName());\r
+ assertNull(path.getParent());\r
+\r
+ path = new TreeSPath("/root/subdir");\r
+ assertEquals("subdir", path.getName());\r
+ assertEquals(new TreeSPath("/root"), path.getParent());\r
+ }\r
+\r
+ public void testEquals() {\r
+ TreeSPath path1 = new TreeSPath("/test");\r
+ TreeSPath path2 = new TreeSPath("/test");\r
+ assertEquals(path1, path2);\r
+\r
+ path1 = new TreeSPath("/test/subdir/anotherdir");\r
+ path2 = new TreeSPath("/test/subdir/anotherdir");\r
+ assertEquals(path1, path2);\r
+\r
+ path1 = new TreeSPath("/test/subdir/anotherd");\r
+ path2 = new TreeSPath("/test/subdir/anotherdir");\r
+ assertNotSame(path1, path2);\r
+\r
+ path1 = new TreeSPath("/test/subdir");\r
+ path2 = new TreeSPath("/test/subdir/anotherdir");\r
+ assertNotSame(path1, path2);\r
+\r
+ path1 = new TreeSPath("/test/subd/anotherdir");\r
+ path2 = new TreeSPath("/test/subdir/anotherdir");\r
+ assertNotSame(path1, path2);\r
+ }\r
+\r
+ public void testCheckFormat() {\r
+ try {\r
+ new TreeSPath("hello");\r
+ fail("Bad format should be rejected");\r
+ } catch (Exception e) {\r
+ // exception expected\r
+ }\r
+\r
+ try {\r
+ new TreeSPath("/");\r
+ fail("Bad format should be rejected");\r
+ } catch (Exception e) {\r
+ // exception expected\r
+ }\r
+\r
+ assertEquals(new TreeSPath("/test"), new TreeSPath("/test/"));\r
+ assertEquals(new TreeSPath("/test/dir"), new TreeSPath(\r
+ "//test///dir////"));\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.context;\r
+\r
+import java.util.List;\r
+\r
+import org.argeo.slc.core.test.SimpleTestResult;\r
+import org.argeo.slc.core.test.TestResultPart;\r
+import org.argeo.slc.core.test.TestStatus;\r
+import org.argeo.slc.unit.AbstractSpringTestCase;\r
+\r
+public class ContextTest extends AbstractSpringTestCase {\r
+\r
+ public void testComplexContext() {\r
+ SimpleTestResult testResult = new SimpleTestResult();\r
+ ContextUtils.compareReachedExpected(\r
+ (ContextAware) getBean("context.c1"), testResult, null);\r
+ ContextUtils.compareReachedExpected(\r
+ (ContextAware) getBean("context.c2"), testResult, null);\r
+ ContextUtils.compareReachedExpected(\r
+ (ContextAware) getBean("context.c3"), testResult, null);\r
+\r
+ List<TestResultPart> parts = testResult.getParts();\r
+ assertEquals(6, parts.size());\r
+ assertEquals(TestStatus.PASSED, parts.get(0).getStatus());\r
+ assertEquals(TestStatus.PASSED, parts.get(1).getStatus());\r
+ assertEquals(TestStatus.PASSED, parts.get(2).getStatus());\r
+ assertEquals(TestStatus.FAILED, parts.get(3).getStatus());\r
+ assertEquals(TestStatus.PASSED, parts.get(4).getStatus());\r
+ assertEquals(TestStatus.PASSED, parts.get(5).getStatus());\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.tree;\r
+\r
+import static org.argeo.slc.unit.UnitUtils.assertDateSec;\r
+import static org.argeo.slc.unit.test.tree.TreeTestResultTestUtils.createCompleteTreeTestResult;\r
+import static org.argeo.slc.unit.test.tree.TreeTestResultTestUtils.createSimpleResultPartRequest;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest;\r
+import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest;\r
+import org.argeo.slc.msg.test.tree.ResultPartRequest;\r
+import org.argeo.slc.unit.AbstractSpringTestCase;\r
+import org.argeo.slc.unit.UnitXmlUtils;\r
+import org.argeo.slc.unit.test.tree.UnitTestTreeUtil;\r
+import org.springframework.oxm.Marshaller;\r
+import org.springframework.oxm.Unmarshaller;\r
+import org.springframework.xml.transform.StringResult;\r
+import org.springframework.xml.transform.StringSource;\r
+import org.springframework.xml.validation.XmlValidator;\r
+\r
+public class TreeTestResultCastorTest extends AbstractSpringTestCase {\r
+ private Log log = LogFactory.getLog(getClass());\r
+\r
+ private Marshaller marshaller;\r
+ private Unmarshaller unmarshaller;\r
+\r
+ @Override\r
+ public void setUp() {\r
+ marshaller = getBean(Marshaller.class);\r
+ unmarshaller = getBean(Unmarshaller.class);\r
+ }\r
+\r
+ public void testMarshUnmarsh() throws Exception {\r
+ TreeTestResult ttr = createCompleteTreeTestResult();\r
+\r
+ StringResult xml = marshallAndValidate(ttr);\r
+\r
+ TreeTestResult ttrUnm = (TreeTestResult) unmarshaller\r
+ .unmarshal(new StringSource(xml.toString()));\r
+\r
+ UnitTestTreeUtil.assertTreeTestResult(ttr, ttrUnm);\r
+ }\r
+\r
+ public void testCreateTreeTestResultRequest() throws Exception {\r
+ CreateTreeTestResultRequest req = new CreateTreeTestResultRequest();\r
+ req.setTreeTestResult(createCompleteTreeTestResult());\r
+\r
+ StringResult xml = marshallAndValidate(req);\r
+\r
+ CreateTreeTestResultRequest reqUnm = (CreateTreeTestResultRequest) unmarshaller\r
+ .unmarshal(new StringSource(xml.toString()));\r
+\r
+ UnitTestTreeUtil.assertTreeTestResult(req.getTreeTestResult(), reqUnm\r
+ .getTreeTestResult());\r
+ }\r
+\r
+ public void testResultPartRequest() throws Exception {\r
+ TreeTestResult ttr = createCompleteTreeTestResult();\r
+ ResultPartRequest req = createSimpleResultPartRequest(ttr);\r
+\r
+ StringResult xml = marshallAndValidate(req);\r
+\r
+ ResultPartRequest reqUnm = (ResultPartRequest) unmarshaller\r
+ .unmarshal(new StringSource(xml.toString()));\r
+\r
+ UnitTestTreeUtil\r
+ .assertPart(req.getResultPart(), reqUnm.getResultPart());\r
+ }\r
+\r
+ public void testCloseTreeTestResultRequest() throws Exception {\r
+ TreeTestResult ttr = createCompleteTreeTestResult();\r
+ ttr.close();\r
+\r
+ CloseTreeTestResultRequest req = new CloseTreeTestResultRequest(ttr\r
+ .getUuid(), ttr.getCloseDate());\r
+\r
+ StringResult xml = marshallAndValidate(req);\r
+\r
+ CloseTreeTestResultRequest reqUnm = (CloseTreeTestResultRequest) unmarshaller\r
+ .unmarshal(new StringSource(xml.toString()));\r
+\r
+ assertEquals(ttr.getUuid(), reqUnm.getResultUuid());\r
+ assertDateSec(ttr.getCloseDate(), ttr.getCloseDate());\r
+ }\r
+\r
+ private StringResult marshallAndValidate(Object obj) throws Exception {\r
+ StringResult xml = new StringResult();\r
+ marshaller.marshal(obj, xml);\r
+\r
+ log.info("Marshalled ResultPart Request: " + xml);\r
+\r
+ UnitXmlUtils.assertXmlValidation(getBean(XmlValidator.class),\r
+ new StringSource(xml.toString()));\r
+ return xml;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.core.test.tree;\r
+\r
+import static org.argeo.slc.unit.test.tree.TreeTestResultTestUtils.createCompleteTreeTestResult;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.argeo.slc.unit.AbstractSpringTestCase;\r
+import org.argeo.slc.unit.UnitXmlUtils;\r
+import org.argeo.slc.unit.test.tree.UnitTestTreeUtil;\r
+import org.springframework.oxm.Marshaller;\r
+import org.springframework.oxm.Unmarshaller;\r
+import org.springframework.xml.transform.StringResult;\r
+import org.springframework.xml.transform.StringSource;\r
+import org.springframework.xml.validation.XmlValidator;\r
+\r
+public class TreeTestResultCollectionCastorTest extends AbstractSpringTestCase {\r
+ private Log log = LogFactory.getLog(getClass());\r
+\r
+ private Marshaller marshaller;\r
+ private Unmarshaller unmarshaller;\r
+\r
+ @Override\r
+ public void setUp() {\r
+ marshaller = getBean(Marshaller.class);\r
+ unmarshaller = getBean(Unmarshaller.class);\r
+ }\r
+\r
+ public void testMarshUnmarsh() throws Exception {\r
+ TreeTestResult ttr = createCompleteTreeTestResult();\r
+ TreeTestResult ttr2 = createCompleteTreeTestResult();\r
+\r
+ TreeTestResultCollection ttrc = new TreeTestResultCollection();\r
+ ttrc.setId("testCollection");\r
+ ttrc.getResults().add(ttr);\r
+ ttrc.getResults().add(ttr2);\r
+\r
+ StringResult xml = marshallAndValidate(ttrc);\r
+\r
+ TreeTestResultCollection ttrcUnm = (TreeTestResultCollection) unmarshaller\r
+ .unmarshal(new StringSource(xml.toString()));\r
+\r
+ assertEquals(ttrc.getId(), ttrcUnm.getId());\r
+ assertEquals(ttrc.getResults().size(), ttrcUnm.getResults().size());\r
+ for (TreeTestResult ttrT : ttrc.getResults()) {\r
+ if (ttrT.getUuid().equals(ttr.getUuid()))\r
+ UnitTestTreeUtil.assertTreeTestResult(ttr, ttrT);\r
+ else\r
+ UnitTestTreeUtil.assertTreeTestResult(ttr2, ttrT);\r
+ }\r
+ }\r
+\r
+ private StringResult marshallAndValidate(Object obj) throws Exception {\r
+ StringResult xml = new StringResult();\r
+ marshaller.marshal(obj, xml);\r
+\r
+ log.info("Marshalled ResultPart Request: " + xml);\r
+\r
+ UnitXmlUtils.assertXmlValidation(getBean(XmlValidator.class),\r
+ new StringSource(xml.toString()));\r
+ return xml;\r
+ }\r
+}\r
--- /dev/null
+package org.argeo.slc.diff;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+public class LineTokenizerTest extends TestCase {
+ public void testSimple() throws Exception {
+ testAndAssert("a,b,c", new String[] { "a", "b", "c" });
+ testAndAssert("hello,bonjour,hallo,priviet", new String[] { "hello",
+ "bonjour", "hallo", "priviet" });
+ }
+
+ public void testTricky() throws Exception {
+ testAndAssert("alone", new String[] { "alone" });
+ testAndAssert("", new String[] { "" });
+
+ testAndAssert(",hello,bonjour,hallo,priviet", new String[] { "",
+ "hello", "bonjour", "hallo", "priviet" });
+ testAndAssert("hello,bonjour,,hallo,priviet", new String[] { "hello",
+ "bonjour", "", "hallo", "priviet" });
+ testAndAssert("hello,bonjour,hallo,priviet,", new String[] { "hello",
+ "bonjour", "hallo", "priviet", "" });
+ testAndAssert(",hello,,bonjour,hallo,,,,priviet,", new String[] { "",
+ "hello", "", "bonjour", "hallo", "", "", "", "priviet", "" });
+
+ testAndAssert(",,,", new String[] { "", "", "", "" });
+ }
+
+ public void testComplex() throws Exception {
+ testAndAssert("a#b#c", '#', "", new String[] { "a", "b", "c" });
+ testAndAssert("hello!bonjour!hallo!priviet", '!', "", new String[] {
+ "hello", "bonjour", "hallo", "priviet" });
+
+ testAndAssert("hello,,bonjour,,hallo,priviet", ',', "<EMPTY>",
+ new String[] { "hello", "<EMPTY>", "bonjour", "<EMPTY>",
+ "hallo", "priviet" });
+ }
+
+ private void testAndAssert(String str, String[] expected) {
+ testAndAssert(str, ',', "", expected);
+ }
+
+ private void testAndAssert(String str, Character sep, String noValueStr,
+ String[] expected) {
+ List<String> res = LineTokenizer.tokenize(str, sep, noValueStr);
+ assertEquals("Size", expected.length, res.size());
+ for (int i = 0; i < res.size(); i++) {
+ String token = res.get(i);
+ assertEquals("Value@" + i, expected[i], token);
+ }
+ }
+}
--- /dev/null
+# Set root logger level to DEBUG and its only appender to A1.\r
+log4j.rootLogger=WARN, console\r
+\r
+## Levels\r
+# Slc\r
+log4j.logger.org.argeo=DEBUG\r
+\r
+# Castor\r
+log4j.logger.org.exolab.castor=WARN\r
+\r
+# Spring\r
+log4j.logger.org.springframework=WARN\r
+\r
+\r
+## Appenders\r
+# A1 is set to be a ConsoleAppender.\r
+log4j.appender.console=org.apache.log4j.ConsoleAppender\r
+\r
+# A1 uses PatternLayout.\r
+log4j.appender.console.layout=org.apache.log4j.PatternLayout\r
+log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c%n\r
+\r
--- /dev/null
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
+\r
+<!-- TODO: remove this file\r
+ <import\r
+ resource="classpath:/org/argeo/slc/castor/spring/applicationContext.xml" />\r
+ <import\r
+ resource="classpath:/org/argeo/slc/ws/client/spring/applicationContext.xml" />\r
+-->\r
+</beans>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
+\r
+\r
+ <import\r
+ resource="classpath:/org/argeo/slc/xml/spring/applicationContext.xml" />\r
+ <import\r
+ resource="classpath:/org/argeo/slc/castor/spring/applicationContext.xml" />\r
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
+\r
+ <bean id="parentContext.pc1" parent="parentContext.template">\r
+ <property name="values">\r
+ <map>\r
+ <entry key="rootvar" value="text" />\r
+ </map>\r
+ </property>\r
+ <property name="expectedValues">\r
+ <map>\r
+ <entry key="reference" value="20" />\r
+ </map>\r
+ </property>\r
+ </bean>\r
+\r
+ <bean id="context.c1" parent="context.template">\r
+ <property name="parentContext" ref="parentContext.pc1" />\r
+ <property name="values">\r
+ <map>\r
+ <entry key="reference" value="20" />\r
+ <entry key="any" value="999" />\r
+ <entry key="skipped" value="999" />\r
+ </map>\r
+ </property>\r
+ <property name="expectedValues">\r
+ <map>\r
+ <entry key="reference" value="21" />\r
+ <entry key="any" value="*" />\r
+ <entry key="skipped" value="!" />\r
+ </map>\r
+ </property>\r
+ </bean>\r
+\r
+ <bean id="context.c2" parent="context.template">\r
+ <property name="parentContext" ref="parentContext.pc1" />\r
+ <property name="values">\r
+ <map>\r
+ <entry key="var" value="37" />\r
+ <entry key="bad" value="56" />\r
+ </map>\r
+ </property>\r
+ <property name="expectedValues">\r
+ <map>\r
+ <entry key="var" value="37" />\r
+ <entry key="bad" value="57" />\r
+ </map>\r
+ </property>\r
+ </bean>\r
+\r
+ <bean id="parentContext.pc2" parent="parentContext.template">\r
+ <property name="parentContext" ref="parentContext.pc1" />\r
+ <property name="expectedValues">\r
+ <map>\r
+ <entry key="reference" value="40" />\r
+ </map>\r
+ </property>\r
+ </bean>\r
+\r
+ <bean id="context.c3" parent="context.template">\r
+ <property name="parentContext" ref="parentContext.pc2" />\r
+ <property name="values">\r
+ <map>\r
+ <entry key="reference" value="41" />\r
+ <entry key="rootvar" value="textX" />\r
+ </map>\r
+ </property>\r
+ <property name="expectedValues">\r
+ <map>\r
+ <entry key="reference" value="40" />\r
+ <entry key="rootvar" value="text" />\r
+ </map>\r
+ </property>\r
+ </bean>\r
+\r
+\r
+ <bean id="parentContext.template"\r
+ class="org.argeo.slc.core.test.context.SimpleParentContextAware"\r
+ abstract="true">\r
+ </bean>\r
+\r
+ <bean id="context.template"\r
+ class="org.argeo.slc.core.test.context.SimpleContextAware"\r
+ abstract="true">\r
+ </bean>\r
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
+\r
+ <import\r
+ resource="classpath:/org/argeo/slc/xml/spring/applicationContext.xml" />\r
+ <import\r
+ resource="classpath:/org/argeo/slc/castor/spring/applicationContext.xml" />\r
+\r
+</beans>
\ No newline at end of file