From a7b136d40c14e4559faa5c34dc2b4dd2170ac2d4 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sat, 31 May 2008 17:59:34 +0000 Subject: [PATCH] Introduce agent project git-svn-id: https://svn.argeo.org/slc/trunk@1165 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- org.argeo.slc.agent/.classpath | 12 + org.argeo.slc.agent/.project | 23 ++ .../.settings/org.eclipse.jdt.core.prefs | 23 ++ .../org.eclipse.wst.common.component | 9 + ....eclipse.wst.common.project.facet.core.xml | 7 + .../org.eclipse.wst.validation.prefs | 6 + org.argeo.slc.agent/build.xml | 35 ++ org.argeo.slc.agent/pom.xml | 139 +++++++ org.argeo.slc.agent/src/assembly/base.xml | 15 + org.argeo.slc.agent/src/base/bin/slc | 326 +++++++++++++++++ org.argeo.slc.agent/src/base/bin/slc.bat | 226 ++++++++++++ .../org/argeo/slc/ant/AntRegistryUtil.java | 121 ++++++ .../java/org/argeo/slc/ant/AntRunner.java | 109 ++++++ .../argeo/slc/ant/BasicSlcProjectHelper.java | 43 +++ .../slc/ant/ProjectRelatedBuildListener.java | 11 + .../argeo/slc/ant/RemoveRootDirMapper.java | 40 ++ .../java/org/argeo/slc/ant/SlcAntConfig.java | 344 ++++++++++++++++++ .../org/argeo/slc/ant/SlcAntException.java | 19 + .../slc/ant/SlcExecutionBuildListener.java | 233 ++++++++++++ .../org/argeo/slc/ant/SlcProjectHelper.java | 266 ++++++++++++++ .../argeo/slc/ant/deploy/SlcDeployTask.java | 75 ++++ .../org/argeo/slc/ant/deploy/package.html | 6 + .../main/java/org/argeo/slc/ant/package.html | 38 ++ .../slc/ant/spring/AbstractSpringArg.java | 87 +++++ .../slc/ant/spring/AbstractSpringTask.java | 25 ++ .../java/org/argeo/slc/ant/spring/MapArg.java | 76 ++++ .../org/argeo/slc/ant/spring/OverrideArg.java | 112 ++++++ .../org/argeo/slc/ant/spring/package.html | 6 + .../argeo/slc/ant/structure/SAwareTask.java | 157 ++++++++ .../org/argeo/slc/ant/structure/package.html | 6 + .../argeo/slc/ant/test/ParentContextType.java | 102 ++++++ .../slc/ant/test/SlcCloseTestResultTask.java | 24 ++ .../org/argeo/slc/ant/test/SlcReportTask.java | 40 ++ .../org/argeo/slc/ant/test/SlcTestTask.java | 176 +++++++++ .../java/org/argeo/slc/ant/test/package.html | 6 + .../structure/tree/TreeSPathFieldHandler.java | 41 +++ .../castor/test/tree/StatusFieldHandler.java | 43 +++ .../java/org/argeo/slc/core/SlcException.java | 17 + .../argeo/slc/core/UnsupportedException.java | 54 +++ .../argeo/slc/core/build/Distribution.java | 6 + .../argeo/slc/core/build/DistributionId.java | 7 + .../slc/core/build/VersionDistributionId.java | 82 +++++ .../org/argeo/slc/core/build/package.html | 6 + .../slc/core/deploy/DeployEnvironment.java | 9 + .../argeo/slc/core/deploy/DeployedSystem.java | 9 + .../slc/core/deploy/DeployedSystemId.java | 9 + .../org/argeo/slc/core/deploy/Deployment.java | 9 + .../argeo/slc/core/deploy/DeploymentData.java | 5 + .../slc/core/deploy/ExecutableDeployment.java | 5 + .../argeo/slc/core/deploy/NumericDSId.java | 40 ++ .../org/argeo/slc/core/deploy/TargetData.java | 5 + .../slc/core/deploy/WritableDeployment.java | 9 + .../org/argeo/slc/core/deploy/package.html | 6 + .../main/java/org/argeo/slc/core/package.html | 6 + .../process/FileSlcExecutionNotifier.java | 84 +++++ .../argeo/slc/core/process/SlcExecution.java | 101 +++++ .../slc/core/process/SlcExecutionAware.java | 5 + .../core/process/SlcExecutionNotifier.java | 15 + .../slc/core/process/SlcExecutionStep.java | 81 +++++ .../WebServiceSlcExecutionNotifier.java | 117 ++++++ .../slc/core/structure/DefaultSRegistry.java | 63 ++++ .../slc/core/structure/SimpleSElement.java | 69 ++++ .../slc/core/structure/StructureAware.java | 10 + .../slc/core/structure/StructureElement.java | 10 + .../structure/StructureElementProvider.java | 5 + .../slc/core/structure/StructurePath.java | 16 + .../slc/core/structure/StructureRegistry.java | 57 +++ .../org/argeo/slc/core/structure/package.html | 6 + .../slc/core/structure/tree/TreeSPath.java | 205 +++++++++++ .../core/structure/tree/TreeSRegistry.java | 95 +++++ .../slc/core/structure/tree/TreeSRelated.java | 11 + .../structure/tree/TreeSRelatedHelper.java | 32 ++ .../slc/core/structure/tree/package.html | 6 + .../argeo/slc/core/test/BasicTestData.java | 24 ++ .../slc/core/test/BasicTestDefinition.java | 36 ++ .../slc/core/test/ExecutableTestRun.java | 9 + .../test/IncompatibleTestDataException.java | 18 + .../org/argeo/slc/core/test/NumericTRId.java | 71 ++++ .../argeo/slc/core/test/SimpleResultPart.java | 128 +++++++ .../argeo/slc/core/test/SimpleTestResult.java | 74 ++++ .../argeo/slc/core/test/SimpleTestRun.java | 96 +++++ .../org/argeo/slc/core/test/SlcTestUtils.java | 40 ++ .../org/argeo/slc/core/test/TestData.java | 9 + .../argeo/slc/core/test/TestDataProvider.java | 5 + .../argeo/slc/core/test/TestDataUtils.java | 45 +++ .../argeo/slc/core/test/TestDefinition.java | 10 + .../org/argeo/slc/core/test/TestReport.java | 10 + .../org/argeo/slc/core/test/TestResult.java | 23 ++ .../org/argeo/slc/core/test/TestResultId.java | 14 + .../slc/core/test/TestResultListener.java | 11 + .../argeo/slc/core/test/TestResultPart.java | 18 + .../java/org/argeo/slc/core/test/TestRun.java | 22 ++ .../org/argeo/slc/core/test/TestRunAware.java | 7 + .../slc/core/test/TestRunDescriptor.java | 82 +++++ .../org/argeo/slc/core/test/TestStatus.java | 29 ++ .../argeo/slc/core/test/WritableTestRun.java | 14 + .../slc/core/test/context/ContextAware.java | 18 + .../slc/core/test/context/ContextUtils.java | 165 +++++++++ .../test/context/DefaultContextTestData.java | 14 + .../core/test/context/ParentContextAware.java | 8 + .../core/test/context/SimpleContextAware.java | 69 ++++ .../context/SimpleParentContextAware.java | 33 ++ .../argeo/slc/core/test/context/package.html | 6 + .../java/org/argeo/slc/core/test/package.html | 6 + .../tree/CompositeTreeTestDefinition.java | 90 +++++ .../argeo/slc/core/test/tree/PartSubList.java | 50 +++ .../slc/core/test/tree/TreeTestResult.java | 183 ++++++++++ .../test/tree/TreeTestResultCollection.java | 45 +++ .../core/test/tree/TreeTestResultLogger.java | 39 ++ .../WebServiceTreeTestResultNotifier.java | 110 ++++++ .../core/test/tree/XsltReportGenerator.java | 156 ++++++++ .../tree/htmlreport/FullHtmlTreeReport.java | 168 +++++++++ .../core/test/tree/htmlreport/ResultPage.java | 211 +++++++++++ .../test/tree/htmlreport/ResultsList.java | 63 ++++ .../core/test/tree/htmlreport/package.html | 6 + .../org/argeo/slc/core/test/tree/package.html | 6 + .../slc/dao/process/SlcExecutionDao.java | 12 + .../slc/dao/structure/SimpleSElementDao.java | 5 + .../org/argeo/slc/dao/structure/package.html | 6 + .../slc/dao/structure/tree/TreeSPathDao.java | 11 + .../dao/structure/tree/TreeSRegistryDao.java | 25 ++ .../argeo/slc/dao/structure/tree/package.html | 6 + .../org/argeo/slc/dao/test/TestResultDao.java | 28 ++ .../slc/dao/test/TestRunDescriptorDao.java | 8 + .../java/org/argeo/slc/dao/test/package.html | 6 + .../tree/TreeTestResultCollectionDao.java | 15 + .../slc/dao/test/tree/TreeTestResultDao.java | 12 + .../test/tree/TreeTestResultPersister.java | 55 +++ .../org/argeo/slc/diff/DataInterpreter.java | 20 + .../main/java/org/argeo/slc/diff/Diff.java | 9 + .../java/org/argeo/slc/diff/DiffIssue.java | 22 ++ .../main/java/org/argeo/slc/diff/DiffKey.java | 9 + .../java/org/argeo/slc/diff/DiffMissing.java | 31 ++ .../org/argeo/slc/diff/DiffMissingXml.java | 43 +++ .../org/argeo/slc/diff/DiffNotMatched.java | 27 ++ .../java/org/argeo/slc/diff/DiffPosition.java | 16 + .../java/org/argeo/slc/diff/DiffResult.java | 12 + .../org/argeo/slc/diff/LineTokenizer.java | 96 +++++ .../java/org/argeo/slc/diff/RelatedFile.java | 9 + .../org/argeo/slc/diff/SimpleDiffResult.java | 14 + .../org/argeo/slc/diff/TableDiffPosition.java | 66 ++++ .../java/org/argeo/slc/diff/Tolerance.java | 18 + .../org/argeo/slc/diff/XPathDiffPosition.java | 35 ++ .../main/java/org/argeo/slc/diff/package.html | 6 + .../slc/maven/MavenDeployEnvironment.java | 73 ++++ .../java/org/argeo/slc/maven/MavenFile.java | 63 ++++ .../org/argeo/slc/maven/MavenManager.java | 105 ++++++ .../slc/msg/process/SlcExecutionRequest.java | 16 + .../process/SlcExecutionStatusRequest.java | 30 ++ .../msg/process/SlcExecutionStepsRequest.java | 31 ++ .../test/tree/CloseTreeTestResultRequest.java | 41 +++ .../tree/CreateTreeTestResultRequest.java | 23 ++ .../slc/msg/test/tree/ResultPartRequest.java | 93 +++++ .../org/argeo/slc/spring/SpringUtils.java | 21 ++ .../slc/support/deploy/ApacheHttpdServer.java | 47 +++ .../deploy/HttpdApplicationDeployment.java | 79 ++++ .../deploy/HttpdApplicationTargetData.java | 44 +++ .../deploy/SimpleHttpdApplication.java | 41 +++ .../slc/support/deploy/WebApplication.java | 11 + .../argeo/slc/support/deploy/WebServer.java | 9 + .../slc/unit/AbstractSpringTestCase.java | 64 ++++ .../java/org/argeo/slc/unit/UnitUtils.java | 42 +++ .../java/org/argeo/slc/unit/UnitXmlUtils.java | 39 ++ .../main/java/org/argeo/slc/unit/package.html | 6 + .../unit/process/SlcExecutionTestUtils.java | 54 +++ .../test/tree/TreeTestResultTestUtils.java | 107 ++++++ .../slc/unit/test/tree/UnitTestTreeUtil.java | 148 ++++++++ .../client/ValidatingClientInterceptor.java | 88 +++++ .../argeo/slc/ws/client/WebServiceUtils.java | 78 ++++ .../org.apache.tools.ant.ProjectHelper | 1 + .../org/argeo/slc/ant/taskdefs.properties | 5 + .../org/argeo/slc/ant/typedefs.properties | 2 + .../org/argeo/slc/castor/mapping.xml | 41 +++ .../org/argeo/slc/castor/msg/mapping.xml | 82 +++++ .../org/argeo/slc/castor/process/mapping.xml | 51 +++ .../slc/castor/spring/applicationContext.xml | 40 ++ .../argeo/slc/castor/structure/mapping.xml | 35 ++ .../org/argeo/slc/castor/test/mapping.xml | 82 +++++ .../core/test/spring/applicationContext.xml | 38 ++ .../argeo/slc/core/test/tree/basicReport.xslt | 50 +++ .../slc/core/test/tree/htmlreport/index.html | 16 + .../slc/core/test/tree/htmlreport/style.css | 64 ++++ .../argeo/slc/support/deploy/ant/build.xml | 23 ++ .../ws/client/spring/applicationContext.xml | 40 ++ .../main/resources/org/argeo/slc/xml/slc.xsd | 235 ++++++++++++ .../slc/xml/spring/applicationContext.xml | 14 + org.argeo.slc.agent/src/site/apt/index.apt | 1 + .../java/org/argeo/slc/ant/SlcAntTest.java | 24 ++ .../core/process/SlcExecutionCastorTest.java | 115 ++++++ .../core/structure/tree/TreeSPathTest.java | 57 +++ .../slc/core/test/context/ContextTest.java | 30 ++ .../test/tree/TreeTestResultCastorTest.java | 100 +++++ .../org/argeo/slc/diff/LineTokenizerTest.java | 53 +++ .../argeo/slc/ws/SlcAntWsIntegrationTest.java | 25 ++ .../slc/ws/SlcExecutionWsIntegrationTest.java | 29 ++ .../ws/TreeTestResultWsIntegrationTest.java | 70 ++++ .../src/test/resources/log4j.properties | 27 ++ .../org/argeo/slc/ant/applicationContext.xml | 12 + .../resources/org/argeo/slc/ant/build.xml | 18 + .../org/argeo/slc/ant/nonDepContext.xml | 42 +++ .../argeo/slc/castor/applicationContext.xml | 11 + .../slc/core/process/applicationContext.xml | 11 + .../core/test/context/applicationContext.xml | 88 +++++ .../slc/core/test/tree/applicationContext.xml | 11 + .../org/argeo/slc/ws/applicationContext.xml | 11 + .../resources/org/argeo/slc/ws/execution.xml | 30 ++ .../resources/org/argeo/slc/ws/result.xml | 20 + 207 files changed, 10119 insertions(+) create mode 100644 org.argeo.slc.agent/.classpath create mode 100644 org.argeo.slc.agent/.project create mode 100644 org.argeo.slc.agent/.settings/org.eclipse.jdt.core.prefs create mode 100644 org.argeo.slc.agent/.settings/org.eclipse.wst.common.component create mode 100644 org.argeo.slc.agent/.settings/org.eclipse.wst.common.project.facet.core.xml create mode 100644 org.argeo.slc.agent/.settings/org.eclipse.wst.validation.prefs create mode 100644 org.argeo.slc.agent/build.xml create mode 100644 org.argeo.slc.agent/pom.xml create mode 100644 org.argeo.slc.agent/src/assembly/base.xml create mode 100644 org.argeo.slc.agent/src/base/bin/slc create mode 100644 org.argeo.slc.agent/src/base/bin/slc.bat create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntRegistryUtil.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntRunner.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/BasicSlcProjectHelper.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/ProjectRelatedBuildListener.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/RemoveRootDirMapper.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConfig.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntException.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcProjectHelper.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/deploy/SlcDeployTask.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/deploy/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/AbstractSpringArg.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/AbstractSpringTask.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/MapArg.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/OverrideArg.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/structure/SAwareTask.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/structure/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/ParentContextType.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/SlcCloseTestResultTask.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/SlcReportTask.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/SlcTestTask.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/castor/structure/tree/TreeSPathFieldHandler.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/castor/test/tree/StatusFieldHandler.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/SlcException.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/UnsupportedException.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/Distribution.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/DistributionId.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/VersionDistributionId.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeployEnvironment.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeployedSystem.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeployedSystemId.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/Deployment.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeploymentData.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/ExecutableDeployment.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/NumericDSId.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/TargetData.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/WritableDeployment.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/FileSlcExecutionNotifier.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecution.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecutionAware.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecutionNotifier.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecutionStep.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/WebServiceSlcExecutionNotifier.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/DefaultSRegistry.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/SimpleSElement.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureAware.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureElement.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureElementProvider.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructurePath.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureRegistry.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSPath.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSRegistry.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSRelated.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSRelatedHelper.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/BasicTestData.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/BasicTestDefinition.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/ExecutableTestRun.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/IncompatibleTestDataException.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/NumericTRId.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SimpleResultPart.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SimpleTestResult.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SimpleTestRun.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SlcTestUtils.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestData.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestDataProvider.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestDataUtils.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestDefinition.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestReport.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResult.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResultId.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResultListener.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResultPart.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestRun.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestRunAware.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestRunDescriptor.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestStatus.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/WritableTestRun.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/ContextAware.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/ContextUtils.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/DefaultContextTestData.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/ParentContextAware.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/SimpleContextAware.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/SimpleParentContextAware.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/CompositeTreeTestDefinition.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/PartSubList.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/TreeTestResult.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultCollection.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultLogger.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/WebServiceTreeTestResultNotifier.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/XsltReportGenerator.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/FullHtmlTreeReport.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultPage.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultsList.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/process/SlcExecutionDao.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/SimpleSElementDao.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/tree/TreeSPathDao.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/tree/TreeSRegistryDao.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/tree/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/TestResultDao.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/TestRunDescriptorDao.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultCollectionDao.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultDao.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultPersister.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DataInterpreter.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/Diff.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffIssue.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffKey.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffMissing.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffMissingXml.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffNotMatched.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffPosition.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffResult.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/LineTokenizer.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/RelatedFile.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/SimpleDiffResult.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/TableDiffPosition.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/Tolerance.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/XPathDiffPosition.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/maven/MavenDeployEnvironment.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/maven/MavenFile.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/maven/MavenManager.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/process/SlcExecutionRequest.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/process/SlcExecutionStatusRequest.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/process/SlcExecutionStepsRequest.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/test/tree/CloseTreeTestResultRequest.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/test/tree/CreateTreeTestResultRequest.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/test/tree/ResultPartRequest.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/spring/SpringUtils.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/ApacheHttpdServer.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/HttpdApplicationDeployment.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/HttpdApplicationTargetData.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/SimpleHttpdApplication.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/WebApplication.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/WebServer.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/AbstractSpringTestCase.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/UnitUtils.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/UnitXmlUtils.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/package.html create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/process/SlcExecutionTestUtils.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/test/tree/TreeTestResultTestUtils.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/test/tree/UnitTestTreeUtil.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ws/client/ValidatingClientInterceptor.java create mode 100644 org.argeo.slc.agent/src/main/java/org/argeo/slc/ws/client/WebServiceUtils.java create mode 100644 org.argeo.slc.agent/src/main/resources/META-INF/services/org.apache.tools.ant.ProjectHelper create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/ant/taskdefs.properties create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/ant/typedefs.properties create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/mapping.xml create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/msg/mapping.xml create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/process/mapping.xml create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/spring/applicationContext.xml create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/structure/mapping.xml create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/test/mapping.xml create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/spring/applicationContext.xml create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/tree/basicReport.xslt create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/tree/htmlreport/index.html create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/tree/htmlreport/style.css create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/support/deploy/ant/build.xml create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/ws/client/spring/applicationContext.xml create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/xml/slc.xsd create mode 100644 org.argeo.slc.agent/src/main/resources/org/argeo/slc/xml/spring/applicationContext.xml create mode 100644 org.argeo.slc.agent/src/site/apt/index.apt create mode 100644 org.argeo.slc.agent/src/test/java/org/argeo/slc/ant/SlcAntTest.java create mode 100644 org.argeo.slc.agent/src/test/java/org/argeo/slc/core/process/SlcExecutionCastorTest.java create mode 100644 org.argeo.slc.agent/src/test/java/org/argeo/slc/core/structure/tree/TreeSPathTest.java create mode 100644 org.argeo.slc.agent/src/test/java/org/argeo/slc/core/test/context/ContextTest.java create mode 100644 org.argeo.slc.agent/src/test/java/org/argeo/slc/core/test/tree/TreeTestResultCastorTest.java create mode 100644 org.argeo.slc.agent/src/test/java/org/argeo/slc/diff/LineTokenizerTest.java create mode 100644 org.argeo.slc.agent/src/test/java/org/argeo/slc/ws/SlcAntWsIntegrationTest.java create mode 100644 org.argeo.slc.agent/src/test/java/org/argeo/slc/ws/SlcExecutionWsIntegrationTest.java create mode 100644 org.argeo.slc.agent/src/test/java/org/argeo/slc/ws/TreeTestResultWsIntegrationTest.java create mode 100644 org.argeo.slc.agent/src/test/resources/log4j.properties create mode 100644 org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/applicationContext.xml create mode 100644 org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/build.xml create mode 100644 org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/nonDepContext.xml create mode 100644 org.argeo.slc.agent/src/test/resources/org/argeo/slc/castor/applicationContext.xml create mode 100644 org.argeo.slc.agent/src/test/resources/org/argeo/slc/core/process/applicationContext.xml create mode 100644 org.argeo.slc.agent/src/test/resources/org/argeo/slc/core/test/context/applicationContext.xml create mode 100644 org.argeo.slc.agent/src/test/resources/org/argeo/slc/core/test/tree/applicationContext.xml create mode 100644 org.argeo.slc.agent/src/test/resources/org/argeo/slc/ws/applicationContext.xml create mode 100644 org.argeo.slc.agent/src/test/resources/org/argeo/slc/ws/execution.xml create mode 100644 org.argeo.slc.agent/src/test/resources/org/argeo/slc/ws/result.xml diff --git a/org.argeo.slc.agent/.classpath b/org.argeo.slc.agent/.classpath new file mode 100644 index 000000000..f60c963ad --- /dev/null +++ b/org.argeo.slc.agent/.classpath @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/org.argeo.slc.agent/.project b/org.argeo.slc.agent/.project new file mode 100644 index 000000000..15b8bfab0 --- /dev/null +++ b/org.argeo.slc.agent/.project @@ -0,0 +1,23 @@ + + + org.argeo.slc.core + + + + + + org.maven.ide.eclipse.maven2Builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + org.maven.ide.eclipse.maven2Nature + + diff --git a/org.argeo.slc.agent/.settings/org.eclipse.jdt.core.prefs b/org.argeo.slc.agent/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..1485b0214 --- /dev/null +++ b/org.argeo.slc.agent/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,23 @@ +#Sat Dec 01 11:46:50 CET 2007 +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,*.testsuite,*.deploy,*.location,*.execution,*.datapool,*.artifact,package.html,*.svg +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +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.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error diff --git a/org.argeo.slc.agent/.settings/org.eclipse.wst.common.component b/org.argeo.slc.agent/.settings/org.eclipse.wst.common.component new file mode 100644 index 000000000..ecc11d82b --- /dev/null +++ b/org.argeo.slc.agent/.settings/org.eclipse.wst.common.component @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.argeo.slc.agent/.settings/org.eclipse.wst.common.project.facet.core.xml b/org.argeo.slc.agent/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..55c9972e3 --- /dev/null +++ b/org.argeo.slc.agent/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.slc.agent/.settings/org.eclipse.wst.validation.prefs b/org.argeo.slc.agent/.settings/org.eclipse.wst.validation.prefs new file mode 100644 index 000000000..ab6929475 --- /dev/null +++ b/org.argeo.slc.agent/.settings/org.eclipse.wst.validation.prefs @@ -0,0 +1,6 @@ +#Mon Apr 21 18:01:59 CEST 2008 +DELEGATES_PREFERENCE=delegateValidatorListorg.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator\=org.eclipse.wst.xsd.core.internal.validation.eclipse.Validator;org.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator\=org.eclipse.wst.wsdl.validation.internal.eclipse.Validator; +USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator;org.eclipse.jst.jsp.core.internal.validation.JSPContentValidator;org.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.jst.jsf.validation.internal.appconfig.AppConfigValidator;org.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator;org.eclipse.jst.jsp.core.internal.validation.JSPBatchValidator;org.eclipse.jst.jsf.validation.internal.JSPSemanticsValidator; +USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator;org.eclipse.jst.jsp.core.internal.validation.JSPContentValidator;org.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.jst.jsf.validation.internal.appconfig.AppConfigValidator;org.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator;org.eclipse.jst.jsp.core.internal.validation.JSPBatchValidator;org.eclipse.jst.jsf.validation.internal.JSPSemanticsValidator; +USER_PREFERENCE=overrideGlobalPreferencestruedisableAllValidationfalseversion1.1.102.v200709122200 +eclipse.preferences.version=1 diff --git a/org.argeo.slc.agent/build.xml b/org.argeo.slc.agent/build.xml new file mode 100644 index 000000000..4213f1de9 --- /dev/null +++ b/org.argeo.slc.agent/build.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/pom.xml b/org.argeo.slc.agent/pom.xml new file mode 100644 index 000000000..54184e74d --- /dev/null +++ b/org.argeo.slc.agent/pom.xml @@ -0,0 +1,139 @@ + + + 4.0.0 + + org.argeo.slc + argeo-slc + 0.9-SNAPSHOT + ../org.argeo.slc + + argeo-slc-core + Argeo SLC Core + SLC Core + + + scm:svn:https://www.argeo.org/svn/slc/trunk/org.argeo.slc.core + + + https://www.argeo.org/svn/slc/trunk/org.argeo.slc.core + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-assembly-plugin + + + src/assembly/base.xml + + + + + assembly-base + package + + single + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*IntegrationTest*.java + + + + + + + + log4j + log4j + + + + org.springframework + spring-context + + + org.springframework.ws + spring-ws-core + + + org.springframework.ws + spring-oxm + + + + org.codehaus.castor + castor + + + xerces + xercesImpl + + + + javax.xml.soap + saaj-api + + + com.sun.xml.messaging.saaj + saaj-impl + + + javax.activation + activation + + + + org.apache.ant + ant + + + org.apache.ant + ant-commons-logging + + + + org.apache.commons + commons-io + + + org.dbunit + dbunit + + + junit + junit + + + xalan + xalan + + + org.apache.maven + maven-embedder + + + org.apache.maven + maven-settings + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/assembly/base.xml b/org.argeo.slc.agent/src/assembly/base.xml new file mode 100644 index 000000000..69c072f34 --- /dev/null +++ b/org.argeo.slc.agent/src/assembly/base.xml @@ -0,0 +1,15 @@ + + base + false + + zip + + + + src/base + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/base/bin/slc b/org.argeo.slc.agent/src/base/bin/slc new file mode 100644 index 000000000..bcc63c85a --- /dev/null +++ b/org.argeo.slc.agent/src/base/bin/slc @@ -0,0 +1,326 @@ +#! /bin/sh + +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Extract launch and ant arguments, (see details below). +ant_exec_args= +no_config=false +use_jikes_default=false +ant_exec_debug=false +show_help=false +for arg in "$@" ; do + if [ "$arg" = "--noconfig" ] ; then + no_config=true + elif [ "$arg" = "--usejikes" ] ; then + use_jikes_default=true + elif [ "$arg" = "--execdebug" ] ; then + ant_exec_debug=true + elif [ my"$arg" = my"--h" -o my"$arg" = my"--help" ] ; then + show_help=true + ant_exec_args="$ant_exec_args -h" + else + if [ my"$arg" = my"-h" -o my"$arg" = my"-help" ] ; then + show_help=true + fi + ant_exec_args="$ant_exec_args \"$arg\"" + fi +done + +# Source/default ant configuration +if $no_config ; then + rpm_mode=false + usejikes=$use_jikes_default +else + # load system-wide ant configuration (ONLY if ANT_HOME has NOT been set) + if [ -z "$ANT_HOME" -o "$ANT_HOME" = "/usr/share/ant" ]; then + if [ -f "/etc/ant.conf" ] ; then + . /etc/ant.conf + fi + fi + + # load user ant configuration + if [ -f "$HOME/.ant/ant.conf" ] ; then + . $HOME/.ant/ant.conf + fi + if [ -f "$HOME/.antrc" ] ; then + . "$HOME/.antrc" + fi + + # provide default configuration values + if [ -z "$rpm_mode" ] ; then + rpm_mode=false + fi + if [ -z "$usejikes" ] ; then + usejikes=$use_jikes_default + fi +fi + +# Setup Java environment in rpm mode +if $rpm_mode ; then + if [ -f /usr/share/java-utils/java-functions ] ; then + . /usr/share/java-utils/java-functions + set_jvm + set_javacmd + fi +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +case "`uname`" in + CYGWIN*) cygwin=true ;; + Darwin*) darwin=true + if [ -z "$JAVA_HOME" ] ; then + JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home + fi + ;; +esac + +if [ -z "$ANT_HOME" -o ! -d "$ANT_HOME" ] ; then + ## resolve links - $0 may be a link to ant's home + PRG="$0" + progname=`basename "$0"` + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi + done + + ANT_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + ANT_HOME=`cd "$ANT_HOME" && pwd` +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$ANT_HOME" ] && + ANT_HOME=`cygpath --unix "$ANT_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# set ANT_LIB location +ANT_LIB="${ANT_HOME}/lib" + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + JAVACMD="$JAVA_HOME/jre/sh/java" + elif [ -x "$JAVA_HOME/jre/bin/java" ] ; then + JAVACMD="$JAVA_HOME/jre/bin/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD=`which java 2> /dev/null ` + if [ -z "$JAVACMD" ] ; then + JAVACMD=java + fi + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." + echo " We cannot execute $JAVACMD" + exit 1 +fi + +# Build local classpath using just the launcher in non-rpm mode or +# use the Jpackage helper in rpm mode with basic and default jars +# specified in the ant.conf configuration. Because the launcher is +# used, libraries linked in ANT_HOME/lib will also be included, but this +# is discouraged as it is not java-version safe. A user should +# request optional jars and their dependencies via the OPT_JAR_LIST +# variable +if $rpm_mode && [ -x /usr/bin/build-classpath ] ; then + LOCALCLASSPATH="$(/usr/bin/build-classpath ant ant-launcher jaxp_parser_impl xml-commons-apis)" + + # If no optional jars have been specified then build the default list + if [ -z "$OPT_JAR_LIST" ] ; then + for file in /etc/ant.d/*; do + if [ -f "$file" ]; then + case "$file" in + *~) ;; + *#*) ;; + *.rpmsave) ;; + *.rpmnew) ;; + *) + for dep in `cat "$file"`; do + case "$OPT_JAR_LIST" in + *"$dep"*) ;; + *) OPT_JAR_LIST="$OPT_JAR_LIST${OPT_JAR_LIST:+ }$dep" + esac + done + esac + fi + done + fi + + # If the user requested to try to add some other jars to the classpath + if [ -n "$OPT_JAR_LIST" ] ; then + _OPTCLASSPATH="$(/usr/bin/build-classpath $OPT_JAR_LIST 2> /dev/null)" + if [ -n "$_OPTCLASSPATH" ] ; then + LOCALCLASSPATH="$LOCALCLASSPATH:$_OPTCLASSPATH" + fi + fi + + # Explicitly add javac path to classpath, assume JAVA_HOME set + # properly in rpm mode + if [ -f "$JAVA_HOME/lib/tools.jar" ] ; then + LOCALCLASSPATH="$LOCALCLASSPATH:$JAVA_HOME/lib/tools.jar" + fi + if [ -f "$JAVA_HOME/lib/classes.zip" ] ; then + LOCALCLASSPATH="$LOCALCLASSPATH:$JAVA_HOME/lib/classes.zip" + fi + + # if CLASSPATH_OVERRIDE env var is set, LOCALCLASSPATH will be + # user CLASSPATH first and ant-found jars after. + # In that case, the user CLASSPATH will override ant-found jars + # + # if CLASSPATH_OVERRIDE is not set, we'll have the normal behaviour + # with ant-found jars first and user CLASSPATH after + if [ -n "$CLASSPATH" ] ; then + # merge local and specified classpath + if [ -z "$LOCALCLASSPATH" ] ; then + LOCALCLASSPATH="$CLASSPATH" + elif [ -n "$CLASSPATH_OVERRIDE" ] ; then + LOCALCLASSPATH="$CLASSPATH:$LOCALCLASSPATH" + else + LOCALCLASSPATH="$LOCALCLASSPATH:$CLASSPATH" + fi + + # remove class path from launcher -cp option + CLASSPATH="" + fi +else + # not using rpm_mode; use launcher to determine classpaths + if [ -z "$LOCALCLASSPATH" ] ; then + LOCALCLASSPATH=$ANT_LIB/ant-launcher.jar + else + LOCALCLASSPATH=$ANT_LIB/ant-launcher.jar:$LOCALCLASSPATH + fi +fi + +if [ -n "$JAVA_HOME" ] ; then + # OSX hack to make Ant work with jikes + if $darwin ; then + OSXHACK="${JAVA_HOME}/../Classes" + if [ -d "${OSXHACK}" ] ; then + for i in "${OSXHACK}"/*.jar + do + JIKESPATH="$JIKESPATH:$i" + done + fi + fi +fi + +# Allow Jikes support (off by default) +if $usejikes; then + ANT_OPTS="$ANT_OPTS -Dbuild.compiler=jikes" +fi + +# For Cygwin, switch paths to appropriate format before running java +# For PATHs convert to unix format first, then to windows format to ensure +# both formats are supported. Probably this will fail on directories with ; +# in the name in the path. Let's assume that paths containing ; are more +# rare than windows style paths on cygwin. +if $cygwin; then + if [ "$OS" = "Windows_NT" ] && cygpath -m .>/dev/null 2>/dev/null ; then + format=mixed + else + format=windows + fi + ANT_HOME=`cygpath --$format "$ANT_HOME"` + ANT_LIB=`cygpath --$format "$ANT_LIB"` + JAVA_HOME=`cygpath --$format "$JAVA_HOME"` + LCP_TEMP=`cygpath --path --unix "$LOCALCLASSPATH"` + LOCALCLASSPATH=`cygpath --path --$format "$LCP_TEMP"` + if [ -n "$CLASSPATH" ] ; then + CP_TEMP=`cygpath --path --unix "$CLASSPATH"` + CLASSPATH=`cygpath --path --$format "$CP_TEMP"` + fi + CYGHOME=`cygpath --$format "$HOME"` +fi + +# Show script help if requested +if $show_help ; then + echo $0 '[script options] [options] [target [target2 [target3] ..]]' + echo 'Script Options:' + echo ' --help, --h print this message and ant help' + echo ' --noconfig suppress sourcing of /etc/ant.conf,' + echo ' $HOME/.ant/ant.conf, and $HOME/.antrc' + echo ' configuration files' + echo ' --usejikes enable use of jikes by default, unless' + echo ' set explicitly in configuration files' + echo ' --execdebug print ant exec line generated by this' + echo ' launch script' + echo ' ' +fi +# add a second backslash to variables terminated by a backslash under cygwin +if $cygwin; then + case "$ANT_HOME" in + *\\ ) + ANT_HOME="$ANT_HOME\\" + ;; + esac + case "$CYGHOME" in + *\\ ) + CYGHOME="$CYGHOME\\" + ;; + esac + case "$JIKESPATH" in + *\\ ) + JIKESPATH="$JIKESPATH\\" + ;; + esac + case "$LOCALCLASSPATH" in + *\\ ) + LOCALCLASSPATH="$LOCALCLASSPATH\\" + ;; + esac + case "$CLASSPATH" in + *\\ ) + CLASSPATH="$CLASSPATH\\" + ;; + esac +fi +# Execute ant using eval/exec to preserve spaces in paths, +# java options, and ant args +ant_sys_opts= +if [ -n "$CYGHOME" ]; then + if [ -n "$JIKESPATH" ]; then + ant_sys_opts="-Djikes.class.path=\"$JIKESPATH\" -Dcygwin.user.home=\"$CYGHOME\"" + else + ant_sys_opts="-Dcygwin.user.home=\"$CYGHOME\"" + fi +else + if [ -n "$JIKESPATH" ]; then + ant_sys_opts="-Djikes.class.path=\"$JIKESPATH\"" + fi +fi +ant_exec_command="exec \"$JAVACMD\" $ANT_OPTS -classpath \"$LOCALCLASSPATH\" -Dant.home=\"$ANT_HOME\" -Dant.library.dir=\"$ANT_LIB\" $ant_sys_opts org.apache.tools.ant.launch.Launcher $ANT_ARGS -cp \"$CLASSPATH\" $ant_exec_args" +if $ant_exec_debug ; then + echo $ant_exec_command +fi +eval $ant_exec_command diff --git a/org.argeo.slc.agent/src/base/bin/slc.bat b/org.argeo.slc.agent/src/base/bin/slc.bat new file mode 100644 index 000000000..f8fb7d5da --- /dev/null +++ b/org.argeo.slc.agent/src/base/bin/slc.bat @@ -0,0 +1,226 @@ +@echo off + +REM Licensed to the Apache Software Foundation (ASF) under one or more +REM contributor license agreements. See the NOTICE file distributed with +REM this work for additional information regarding copyright ownership. +REM The ASF licenses this file to You under the Apache License, Version 2.0 +REM (the "License"); you may not use this file except in compliance with +REM the License. You may obtain a copy of the License at +REM +REM http://www.apache.org/licenses/LICENSE-2.0 +REM +REM Unless required by applicable law or agreed to in writing, software +REM distributed under the License is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM See the License for the specific language governing permissions and +REM limitations under the License. + +REM This is an inordinately troublesome piece of code, particularly because it +REM tries to work on both Win9x and WinNT-based systems. If we could abandon '9x +REM support, things would be much easier, but sadly, it is not yet time. +REM Be cautious about editing this, and only add WinNT specific stuff in code that +REM only runs on WinNT. + +if "%HOME%"=="" goto homeDrivePathPre +if exist "%HOME%\antrc_pre.bat" call "%HOME%\antrc_pre.bat" + +:homeDrivePathPre +if "%HOMEDRIVE%%HOMEPATH%"=="" goto userProfilePre +if "%HOMEDRIVE%%HOMEPATH%"=="%HOME%" goto userProfilePre +if exist "%HOMEDRIVE%%HOMEPATH%\antrc_pre.bat" call "%HOMEDRIVE%%HOMEPATH%\antrc_pre.bat" + +:userProfilePre +if "%USERPROFILE%"=="" goto alpha +if "%USERPROFILE%"=="%HOME%" goto alpha +if "%USERPROFILE%"=="%HOMEDRIVE%%HOMEPATH%" goto alpha +if exist "%USERPROFILE%\antrc_pre.bat" call "%USERPROFILE%\antrc_pre.bat" + +:alpha + +if "%OS%"=="Windows_NT" @setlocal +if "%OS%"=="WINNT" @setlocal + +if "%ANT_HOME%"=="" goto setDefaultAntHome + +:stripAntHome +if not _%ANT_HOME:~-1%==_\ goto checkClasspath +set ANT_HOME=%ANT_HOME:~0,-1% +goto stripAntHome + +:setDefaultAntHome +rem %~dp0 is expanded pathname of the current script under NT +set ANT_HOME=%~dp0.. + +:checkClasspath +set _USE_CLASSPATH=yes +rem CLASSPATH must not be used if it is equal to "" +if "%CLASSPATH%"=="""" set _USE_CLASSPATH=no +if "%CLASSPATH%"=="" set _USE_CLASSPATH=no + +rem Slurp the command line arguments. This loop allows for an unlimited number +rem of arguments (up to the command line limit, anyway). +set ANT_CMD_LINE_ARGS=%1 +if ""%1""=="""" goto doneStart +shift +:setupArgs +if ""%1""=="""" goto doneStart +if ""%1""==""-noclasspath"" goto clearclasspath +set ANT_CMD_LINE_ARGS=%ANT_CMD_LINE_ARGS% %1 +shift +goto setupArgs + +rem here is there is a -noclasspath in the options +:clearclasspath +set _USE_CLASSPATH=no +shift +goto setupArgs + +rem This label provides a place for the argument list loop to break out +rem and for NT handling to skip to. + +:doneStart + +if _USE_CLASSPATH==no goto findAntHome + +:stripClasspath +if not _%CLASSPATH:~-1%==_\ goto findAntHome +set CLASSPATH=%CLASSPATH:~0,-1% +goto stripClasspath + +:findAntHome +rem find ANT_HOME if it does not exist due to either an invalid value passed +rem by the user or the %0 problem on Windows 9x +if exist "%ANT_HOME%\lib\ant.jar" goto checkJava + +rem check for ant in Program Files +if not exist "%ProgramFiles%\ant" goto checkSystemDrive +set ANT_HOME=%ProgramFiles%\ant +goto checkJava + +:checkSystemDrive +rem check for ant in root directory of system drive +if not exist %SystemDrive%\ant\lib\ant.jar goto checkCDrive +set ANT_HOME=%SystemDrive%\ant +goto checkJava + +:checkCDrive +rem check for ant in C:\ant for Win9X users +if not exist C:\ant\lib\ant.jar goto noAntHome +set ANT_HOME=C:\ant +goto checkJava + +:noAntHome +echo ANT_HOME is set incorrectly or ant could not be located. Please set ANT_HOME. +goto end + +:checkJava +set _JAVACMD=%JAVACMD% + +if "%JAVA_HOME%" == "" goto noJavaHome +if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome +if "%_JAVACMD%" == "" set _JAVACMD=%JAVA_HOME%\bin\java.exe +goto checkJikes + +:noJavaHome +if "%_JAVACMD%" == "" set _JAVACMD=java.exe + +:checkJikes +if not "%JIKESPATH%"=="" goto runAntWithJikes + +:runAnt +if "%_USE_CLASSPATH%"=="no" goto runAntNoClasspath +:runAntWithClasspath +"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% -cp "%CLASSPATH%" %ANT_CMD_LINE_ARGS% +rem Check the error code of the Ant build +if not "%OS%"=="Windows_NT" goto onError +set ANT_ERROR=%ERRORLEVEL% +goto end + +:runAntNoClasspath +"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% %ANT_CMD_LINE_ARGS% +rem Check the error code of the Ant build +if not "%OS%"=="Windows_NT" goto onError +set ANT_ERROR=%ERRORLEVEL% +goto end + +:runAntWithJikes + +if not _%JIKESPATH:~-1%==_\ goto checkJikesAndClasspath +set JIKESPATH=%JIKESPATH:~0,-1% +goto runAntWithJikes + +:checkJikesAndClasspath + +if "%_USE_CLASSPATH%"=="no" goto runAntWithJikesNoClasspath + +:runAntWithJikesAndClasspath +"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" "-Djikes.class.path=%JIKESPATH%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% -cp "%CLASSPATH%" %ANT_CMD_LINE_ARGS% +rem Check the error code of the Ant build +if not "%OS%"=="Windows_NT" goto onError +set ANT_ERROR=%ERRORLEVEL% +goto end + +:runAntWithJikesNoClasspath +"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" "-Djikes.class.path=%JIKESPATH%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% %ANT_CMD_LINE_ARGS% +rem Check the error code of the Ant build +if not "%OS%"=="Windows_NT" goto onError +set ANT_ERROR=%ERRORLEVEL% +goto end + +:onError +rem Windows 9x way of checking the error code. It matches via brute force. +for %%i in (1 10 100) do set err%%i= +for %%i in (0 1 2) do if errorlevel %%i00 set err100=%%i +if %err100%==2 goto onError200 +if %err100%==0 set err100= +for %%i in (0 1 2 3 4 5 6 7 8 9) do if errorlevel %err100%%%i0 set err10=%%i +if "%err100%"=="" if %err10%==0 set err10= +:onError1 +for %%i in (0 1 2 3 4 5 6 7 8 9) do if errorlevel %err100%%err10%%%i set err1=%%i +goto onErrorEnd +:onError200 +for %%i in (0 1 2 3 4 5) do if errorlevel 2%%i0 set err10=%%i +if err10==5 for %%i in (0 1 2 3 4 5) do if errorlevel 25%%i set err1=%%i +if not err10==5 goto onError1 +:onErrorEnd +set ANT_ERROR=%err100%%err10%%err1% +for %%i in (1 10 100) do set err%%i= + +:end +rem bug ID 32069: resetting an undefined env variable changes the errorlevel. +if not "%_JAVACMD%"=="" set _JAVACMD= +if not "%_ANT_CMD_LINE_ARGS%"=="" set ANT_CMD_LINE_ARGS= + +if "%ANT_ERROR%"=="0" goto mainEnd + +rem Set the return code if we are not in NT. We can only set +rem a value of 1, but it's better than nothing. +if not "%OS%"=="Windows_NT" echo 1 > nul | choice /n /c:1 + +rem Set the ERRORLEVEL if we are running NT. +if "%OS%"=="Windows_NT" color 00 + +goto omega + +:mainEnd + +rem If there were no errors, we run the post script. +if "%OS%"=="Windows_NT" @endlocal +if "%OS%"=="WINNT" @endlocal + +if "%HOME%"=="" goto homeDrivePathPost +if exist "%HOME%\antrc_post.bat" call "%HOME%\antrc_post.bat" + +:homeDrivePathPost +if "%HOMEDRIVE%%HOMEPATH%"=="" goto userProfilePost +if "%HOMEDRIVE%%HOMEPATH%"=="%HOME%" goto userProfilePost +if exist "%HOMEDRIVE%%HOMEPATH%\antrc_post.bat" call "%HOMEDRIVE%%HOMEPATH%\antrc_post.bat" + +:userProfilePost +if "%USERPROFILE%"=="" goto omega +if "%USERPROFILE%"=="%HOME%" goto omega +if "%USERPROFILE%"=="%HOMEDRIVE%%HOMEPATH%" goto omega +if exist "%USERPROFILE%\antrc_post.bat" call "%USERPROFILE%\antrc_post.bat" + +:omega + diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntRegistryUtil.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntRegistryUtil.java new file mode 100644 index 000000000..e81fb30eb --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntRegistryUtil.java @@ -0,0 +1,121 @@ +package org.argeo.slc.ant; + +import java.io.File; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectHelper; +import org.apache.tools.ant.listener.CommonsLoggingListener; +import org.argeo.slc.core.structure.StructurePath; +import org.argeo.slc.core.structure.StructureRegistry; + +/** Utilities to manipulate the structure registry in SLC Ant. */ +public class AntRegistryUtil { + private static Log log = LogFactory.getLog(AntRegistryUtil.class); + + /** Reads a structure registry from an Ant file without executing it. */ + public static StructureRegistry readRegistry(File antFile) { + if (log.isDebugEnabled()) + log.debug("Reads registry for Ant file " + antFile); + Project p = new Project(); + p.setUserProperty("ant.file", antFile.getAbsolutePath()); + p.setBaseDir(antFile.getParentFile()); + p.init(); + ProjectHelper helper = new SlcProjectHelper(); + p.addReference(ProjectHelper.PROJECTHELPER_REFERENCE, helper); + helper.parse(p, antFile); + + StructureRegistry registry = (StructureRegistry) p + .getReference(SlcProjectHelper.REF_STRUCTURE_REGISTRY); + registry.setMode(StructureRegistry.READ); + + p.executeTarget(p.getDefaultTarget()); + return registry; + } + + /** Executes only the active paths of the Ant file. */ + public static Project runActive(File antFile, + List activePaths) { + if (log.isDebugEnabled()) + log.debug("Runs the " + activePaths.size() + + " provided active paths of Ant file " + antFile); + Project p = new Project(); + p.setUserProperty("ant.file", antFile.getAbsolutePath()); + p.setBaseDir(antFile.getParentFile()); + p.init(); + ProjectHelper helper = new SlcProjectHelper(); + p.addReference(ProjectHelper.PROJECTHELPER_REFERENCE, helper); + helper.parse(p, antFile); + + StructureRegistry registry = (StructureRegistry) p + .getReference(SlcProjectHelper.REF_STRUCTURE_REGISTRY); + registry.setMode(StructureRegistry.ACTIVE); + registry.setActivePaths(activePaths); + + runProject(p, null); + return p; + } + + /** Executes all paths of the provided target of the Ant file. */ + public static Project runAll(File antFile, String target) { + if (log.isDebugEnabled()) + log.debug("Runs all paths of Ant file " + antFile); + Project p = new Project(); + p.setUserProperty("ant.file", antFile.getAbsolutePath()); + p.setBaseDir(antFile.getParentFile()); + p.init(); + ProjectHelper helper = new SlcProjectHelper(); + p.addReference(ProjectHelper.PROJECTHELPER_REFERENCE, helper); + helper.parse(p, antFile); + + runProject(p, target); + return p; + } + + /** Executes all paths of the provided target of the Ant URL. */ + public static Project runAll(URL url, String target, Properties properties) { + if (log.isDebugEnabled()) + log.debug("Runs all paths of Ant URL " + url); + Project p = new Project(); + p.setUserProperty("ant.file", url.toString()); + // p.setBaseDir(url.toString()); + p.addBuildListener(new CommonsLoggingListener()); + p.init(); + ProjectHelper helper = new SlcProjectHelper(); + p.addReference(ProjectHelper.PROJECTHELPER_REFERENCE, helper); + helper.parse(p, url); + + if (properties != null) { + for (Map.Entry entry : properties.entrySet()) { + p.setUserProperty(entry.getKey().toString(), entry.getValue() + .toString()); + } + } + + runProject(p, target); + return p; + } + + /** Executes all paths of the default target of the Ant file. */ + public static Project runAll(File antFile) { + return runAll(antFile, null); + } + + protected static void runProject(Project p, String target) { + p.fireBuildStarted(); + Throwable exception = null; + try { + p.executeTarget(target != null ? target : p.getDefaultTarget()); + } catch (Throwable e) { + exception = e; + log.error("Exception when running Ant: ",e); + } finally { + p.fireBuildFinished(exception); + } + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntRunner.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntRunner.java new file mode 100644 index 000000000..da88eafa1 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntRunner.java @@ -0,0 +1,109 @@ +package org.argeo.slc.ant; + +import java.io.File; +import java.net.URL; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.Properties; +import java.util.Vector; + +import org.springframework.context.ApplicationContext; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectHelper; + +public class AntRunner { + private ApplicationContext context; + private ProjectHelper projectHelper; + private URL buildFile; + private String[] targets; + private Properties properties; + + public AntRunner() { + + } + + public AntRunner(ApplicationContext context, ProjectHelper projectHelper, + URL buildFile, String[] targets) { + super(); + this.context = context; + this.projectHelper = projectHelper; + this.buildFile = buildFile; + this.targets = targets; + } + + public AntRunner(ApplicationContext context, URL buildFile, String target) { + super(); + this.context = context; + + BasicSlcProjectHelper basicSlcProjectHelper = new BasicSlcProjectHelper(); + this.projectHelper = basicSlcProjectHelper; + basicSlcProjectHelper.setContext(context); + + this.buildFile = buildFile; + this.targets = new String[] { target }; + } + + public void run() { + Project p = new Project(); + + String path = buildFile.getFile(); + p.setUserProperty("ant.file", path); + p.setBaseDir(extractBaseDir(path)); + + p.init(); + p.addReference(ProjectHelper.PROJECTHELPER_REFERENCE, projectHelper); + projectHelper.parse(p, buildFile); + + if (properties != null) { + for (Map.Entry entry : properties.entrySet()) { + p.setUserProperty(entry.getKey().toString(), entry.getValue() + .toString()); + } + } + + p.fireBuildStarted(); + Throwable exception = null; + try { + if (targets == null) { + p.executeTarget(p.getDefaultTarget()); + } else { + p.executeTargets(new Vector(Arrays.asList(targets))); + } + } catch (Throwable e) { + exception = e; + throw new SlcAntException("Could not run Ant script " + buildFile, + e); + } finally { + p.fireBuildFinished(exception); + } + + } + + private File extractBaseDir(String path) { + String baseDir = null; + if (path.length() > 1) { + int indx = path.lastIndexOf('/', path.length() - 1); + if (indx == -1 || indx == 0) { + baseDir = "/"; + } else { + baseDir = path.substring(0, indx) + "/"; + } + } else { + baseDir = "/"; + } + File file = new File(baseDir); + if (file.exists()) { + return file; + } else { + return new File(System.getProperty("user.dir")); + } + } + + public static void main(String[] args) { + // TODO Auto-generated method stub + + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/BasicSlcProjectHelper.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/BasicSlcProjectHelper.java new file mode 100644 index 000000000..620acdfcb --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/BasicSlcProjectHelper.java @@ -0,0 +1,43 @@ +package org.argeo.slc.ant; + +import org.springframework.context.ApplicationContext; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.helper.ProjectHelper2; + +import org.argeo.slc.core.structure.SimpleSElement; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.structure.tree.TreeSRegistry; + +public class BasicSlcProjectHelper extends ProjectHelper2 { + private ApplicationContext context; + + private String projectRootPath = "/project"; + + @Override + public void parse(Project project, Object source) throws BuildException { + TreeSRegistry registry = new TreeSRegistry(); + TreeSPath projectPath = TreeSPath.parseToCreatePath(projectRootPath); + + // FIXME + registry.register(projectPath, new SimpleSElement("ROOT")); + + project.addReference(SlcProjectHelper.REF_STRUCTURE_REGISTRY, registry); + project.addReference(SlcProjectHelper.REF_PROJECT_PATH, projectPath); + + super.parse(project, source); + + project.addReference(SlcProjectHelper.REF_ROOT_CONTEXT, context); + SlcProjectHelper.createAndRegisterSlcExecution(project); + + SlcProjectHelper.addCustomTaskAndTypes(project); + } + + public void setContext(ApplicationContext context) { + this.context = context; + } + + + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/ProjectRelatedBuildListener.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/ProjectRelatedBuildListener.java new file mode 100644 index 000000000..6d047d5d0 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/ProjectRelatedBuildListener.java @@ -0,0 +1,11 @@ +package org.argeo.slc.ant; + +import org.apache.tools.ant.BuildListener; +import org.apache.tools.ant.Project; + +public interface ProjectRelatedBuildListener extends BuildListener { + public Project getProject(); + + /** SlcExecution must already have been registered in project*/ + public void init(Project project); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/RemoveRootDirMapper.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/RemoveRootDirMapper.java new file mode 100644 index 000000000..43b247c2b --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/RemoveRootDirMapper.java @@ -0,0 +1,40 @@ +package org.argeo.slc.ant; + +import java.util.StringTokenizer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.util.FileNameMapper; + +public class RemoveRootDirMapper implements FileNameMapper { + private Log log = LogFactory.getLog(RemoveRootDirMapper.class); + private String to = "enabled"; + + public String[] mapFileName(String sourceFileName) { + StringTokenizer st = new StringTokenizer(sourceFileName, "/"); + boolean first = true; + boolean skipRoot = !to.equals("disabled"); + StringBuffer buf = new StringBuffer(""); + while (st.hasMoreTokens()) { + if (first && skipRoot) { // skip + st.nextToken(); + first = false; + } else { + buf.append(st.nextToken()).append('/'); + } + } + + if (log.isTraceEnabled()) { + log.trace("Source: " + sourceFileName + " - out: " + buf); + } + return new String[] { buf.toString() }; + } + + public void setFrom(String from) { + } + + public void setTo(String to) { + this.to = to; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConfig.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConfig.java new file mode 100644 index 000000000..9b2824886 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConfig.java @@ -0,0 +1,344 @@ +package org.argeo.slc.ant; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Map; +import java.util.Properties; +import java.util.StringTokenizer; + +import org.springframework.util.Log4jConfigurer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.Project; + +/** + *

+ * Manager and initializer of the properties required by SLC Ant. + *

+ * + *

+ * All properties described here will get a value one way or another (see below + * for details)/ Each property will be accessible via Ant or Spring properties. + *

+ * + *

+ * The property slc.rootFile is set based on the location of the SLC + * root property file found in the directory structure of a called Ant file. The + * default name of this file is slcRoot.properties (can be set by + * {@link #setSlcRootFileName(String)}).
+ * This property provides the absolute path to the unique SLC root property file + * which marks the root of an Ant SLC tree structure. + *

+ * + *

+ * The property slc.rootDir is inferred from slc.rootFile and + * provides a convenient shortcut to the root directory of the Ant files + * directory structure. + *

+ * + *

+ * A few directory and file related properties can be set in the SLC root + * property file (if they are not explicitly set their default values will be + * used): + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
PropertyDescriptionDefault
slc.confDirDirectory where to find the various configuration files of a given SLC + * Ant deployment${slc.rootDir}/../conf
slc.workDirDirectory where data can be retrieved or generated: build outputs, test + * inputs/outputs, test results, etc. The underlying directory structure is + * specified by the specific SLC application.${slc.rootDir}/../work
slc.propertyFileNamesComma-separated list of the files names of the property files to load + * from the conf directory. Having various files allows to separate between SLC + * framework properties and properties specific to a given application built on + * top of SLC. All will be available across Ant and Spring.slc.properties
Note: Only the properties above can be set in the SLC root + * properties file. All other properties should be defined in the registered + * conf files. + *

+ * + *

+ * Any property can be defined in the conf files defined in the SLC root + * properties file (see above). SLC expects some which will have defaults but + * can be overriden there. By convention they should be defined in the + * slc.properties file, while application specific properties should be + * defined in other conf files. This allows for a clean spearation between SLC + * and the applications built on top of it: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
PropertyDescriptionDefault
slc.applicationContextPath to the root Spring application context file used by SLC Ant.${slc.confDir}/applicationContext.xml
slc.defaultTestRunName of the {@link WritableTestRun} Spring bean that the + * slc.test task will use by default. This can be overridden when + * calling the task from Ant.defaultTestRun
+ *

+ */ +public class SlcAntConfig { + // SLC ROOT PROPERTIES + /** Property for the root file (SLC root property file). */ + public final static String ROOT_FILE_PROPERTY = "slc.rootFile"; + /** Property for the root dir (SLC root property file). */ + public final static String ROOT_DIR_PROPERTY = "slc.rootDir"; + /** Property for the conf dir (SLC root property file). */ + public final static String CONF_DIR_PROPERTY = "slc.confDir"; + /** Property for the work dir (SLC root property file). */ + public final static String WORK_DIR_PROPERTY = "slc.workDir"; + /** + * Comma-separated list of property file names to load from the conf dir and + * add to project user properties + */ + public final static String PROPERTY_FILE_NAMES_PROPERTY = "slc.propertyFileNames"; + + // SLC CONF PROPERTIES + /** Path to the root Spring application context */ + public static String APPLICATION_CONTEXT_PROPERTY = "slc.applicationContext"; + /** Name of the Spring bean used by default */ + public static String DEFAULT_TEST_RUN_PROPERTY = "slc.defaultTestRun"; + + // SLC LOCAL PROPERTIES + /** Property for the dir label (SLC local property file). */ + public static String DIR_LABEL_PROPERTY = "slc.dirLabel"; + + private String slcRootFileName = "slcRoot.properties"; + private String slcLocalFileName = "slcLocal.properties"; + + /** + * Retrieves or infers all properties and set them as project user + * properties. All these properties will be set as project properties if + * they had not been set as project properties before (like by + * overriding through the standard Ant mechanisms). + * + * @param project + * the Ant Project being run. + * @return whether the project could be initialized for SLC usage (e.g. + * presence of an SLC root file) + */ + public boolean initProject(Project project) { + File projectBaseDir = project.getBaseDir(); + File slcRootFile = findSlcRootFile(projectBaseDir); + if (slcRootFile == null) { + return false; + } + + // pass the project properties through the System properties + System.getProperties().putAll((Map) project.getUserProperties()); + Properties all = new Properties(); + all.putAll(System.getProperties()); + prepareAllProperties(slcRootFile, all); + + Log log = LogFactory.getLog(this.getClass()); + for (Object o : all.keySet()) { + String key = o.toString(); + // System.out.println(key+"="+all.getProperty(key)); + if (project.getUserProperty(key) == null) {// not already set + // if (log.isDebugEnabled()) + // log.debug(key + "=" + all.getProperty(key)); + project.setUserProperty(key, all.getProperty(key)); + } + } + return true; + } + + /** + * Retrieves or infers all required properties. + * + * @param slcRootFile + * the location of the SLC root file + * + * @return the prepared properties. Note that it also contains the System + * and Ant properties which had previously been set. + */ + public void prepareAllProperties(File slcRootFile, Properties all) { + try { + final String fileUrlPrefix = ""; + + all.put(ROOT_FILE_PROPERTY, slcRootFile.getCanonicalPath()); + // Remove basedir property in order to avoid conflict with Maven + if (all.containsKey("basedir")) + all.remove("basedir"); + + Properties rootProps = loadFile(slcRootFile.getCanonicalPath()); + + final File confDir; + final File workDir; + // Root dir + final File rootDir = slcRootFile.getParentFile(); + all.setProperty(ROOT_DIR_PROPERTY, fileUrlPrefix + + rootDir.getCanonicalPath()); + + // Conf dir + if (all.getProperty(CONF_DIR_PROPERTY) == null) { + confDir = new File(rootProps.getProperty(CONF_DIR_PROPERTY, + rootDir.getAbsolutePath() + "/../conf")) + .getCanonicalFile(); + all.setProperty(CONF_DIR_PROPERTY, fileUrlPrefix + + confDir.getAbsolutePath()); + } else { + confDir = new File(all.getProperty(CONF_DIR_PROPERTY)) + .getCanonicalFile(); + } + + // Work dir + if (all.getProperty(WORK_DIR_PROPERTY) == null) { + workDir = new File(rootProps.getProperty(WORK_DIR_PROPERTY, + rootDir.getAbsolutePath() + "/../work")) + .getCanonicalFile(); + all.setProperty(WORK_DIR_PROPERTY, fileUrlPrefix + + workDir.getAbsolutePath()); + } else { + workDir = new File(all.getProperty(WORK_DIR_PROPERTY)) + .getCanonicalFile(); + } + + // Properties from the conf dir files + Properties properties = new Properties(); + StringTokenizer st = new StringTokenizer(rootProps.getProperty( + PROPERTY_FILE_NAMES_PROPERTY, "slc.properties"), ","); + while (st.hasMoreTokens()) { + String fileName = st.nextToken(); + properties.putAll(loadFile(confDir.getAbsolutePath() + + File.separator + fileName)); + } + + for (Object o : properties.keySet()) { + String key = o.toString(); + if (all.getProperty(key) == null) {// not already set + all.setProperty(key, properties.getProperty(key)); + } + } + + // Default application context + if (all.getProperty(APPLICATION_CONTEXT_PROPERTY) == null) { + all.setProperty(APPLICATION_CONTEXT_PROPERTY, confDir + .getAbsolutePath() + + "/applicationContext.xml"); + } + // Default test run + if (all.getProperty(DEFAULT_TEST_RUN_PROPERTY) == null) { + all.setProperty(DEFAULT_TEST_RUN_PROPERTY, + "defaultTestRun"); + } + + // Default log4j + if (all.getProperty("log4j.configuration") == null) { + System.setProperty("log4j.configuration", confDir + .getCanonicalPath() + + File.separator + "log4j.properties"); + // TODO: fix dependency to log4j + Log4jConfigurer.initLogging(confDir.getCanonicalPath() + + File.separator + "log4j.properties"); + } + } catch (Exception e) { + throw new SlcAntException("Unexpected exception while configuring", + e); + } + } + + /** Loads the content of a file as Properties. */ + private Properties loadFile(String path) { + Properties p = new Properties(); + try { + FileInputStream in = new FileInputStream(path); + p.load(in); + in.close(); + } catch (IOException e) { + throw new SlcAntException("Cannot read SLC root file", e); + } + return p; + } + + /** + * Looks for a file named {@link #getSlcLocalFileName()} in the directory, + * loads it as properties file and return the value of the property + * {@link #DIR_LABEL_PROPERTY}. + */ + public String getDescriptionForDir(File dir) { + String description = dir.getName(); + File slcLocal = new File(dir.getPath() + File.separator + + getSlcLocalFileName()); + if (slcLocal.exists()) { + Properties properties = loadFile(slcLocal.getAbsolutePath()); + description = properties.getProperty( + SlcAntConfig.DIR_LABEL_PROPERTY, description); + } + return description; + } + + /** + * Recursively scans directories downwards until it find a file names as + * defined by {@link #getSlcRootFileName()}. + */ + public File findSlcRootFile(File dir) { + for (File file : dir.listFiles()) { + if (!file.isDirectory() + && file.getName().equals(getSlcRootFileName())) { + return file; + } + } + + File parentDir = dir.getParentFile(); + if (parentDir == null) { + return null;// stop condition: not found + } else { + return findSlcRootFile(parentDir); + } + } + + /** + * Gets the file name of the file marking the root directory, default being + * slcRoot.properties. + */ + public String getSlcRootFileName() { + return slcRootFileName; + } + + /** Sets the file name of the file marking the root directory. */ + public void setSlcRootFileName(String slcRootFileName) { + this.slcRootFileName = slcRootFileName; + } + + /** + * Gets the file name of the file containing directory specific properties, + * default being slcLocal.properties. + */ + public String getSlcLocalFileName() { + return slcLocalFileName; + } + + /** Sets the file name of the file containing directory specific properties. */ + public void setSlcLocalFileName(String slcLocalFileName) { + this.slcLocalFileName = slcLocalFileName; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntException.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntException.java new file mode 100644 index 000000000..854df33cf --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntException.java @@ -0,0 +1,19 @@ +package org.argeo.slc.ant; + +import org.argeo.slc.core.SlcException; + +/** Base for all SLC Ant exceptions. */ +public class SlcAntException extends SlcException { + static final long serialVersionUID = 1l; + + /** Constructor. */ + public SlcAntException(String message) { + super(message); + } + + /** Constructor. */ + public SlcAntException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java new file mode 100644 index 000000000..a8dd15c7d --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java @@ -0,0 +1,233 @@ +package org.argeo.slc.ant; + +import java.util.List; +import java.util.Vector; + +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.LogManager; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.tools.ant.BuildEvent; +import org.apache.tools.ant.Project; + +import org.argeo.slc.core.process.SlcExecution; +import org.argeo.slc.core.process.SlcExecutionNotifier; +import org.argeo.slc.core.process.SlcExecutionStep; +import org.argeo.slc.core.process.WebServiceSlcExecutionNotifier; + +public class SlcExecutionBuildListener extends AppenderSkeleton implements + ProjectRelatedBuildListener { + public static final String ANT_TYPE = "org.apache.tools.ant"; + public static final String SLC_ANT_TYPE = "org.argeo.slc.ant"; + + public static final String REF_SLC_EXECUTION = "slcExecution"; + + private Project project; + + // to avoid stack overflow when logging for log4j + private boolean isLogging = false; + + private List notifiers = new Vector(); + + private boolean currentStepNotified = true; + + // CUSTOMIZATIONS + private boolean logBeforeFirstTarget = false; + private boolean firstTargetStarted = false; + + private boolean logTaskStartFinish = true; + + public void init(Project project) { + if (this.project != null) { + throw new SlcAntException("Build listener already initialized"); + } + + this.project = project; + + if (!LogManager.getRootLogger().isAttached(this)) { + LogManager.getRootLogger().addAppender(this); + } + + SlcExecution slcExecution = (SlcExecution) project + .getReference(REF_SLC_EXECUTION); + if (slcExecution == null) + throw new SlcAntException("No SLC Execution registered."); + + for (SlcExecutionNotifier notifier : notifiers) { + notifier.newExecution(slcExecution); + } + + } + + public void buildStarted(BuildEvent event) { + } + + public void buildFinished(BuildEvent event) { + SlcExecution slcExecution = getSlcExecution(event); + String oldStatus = slcExecution.getStatus(); + slcExecution.setStatus(SlcExecution.STATUS_FINISHED); + + for (SlcExecutionNotifier notifier : notifiers) { + notifier.updateStatus(slcExecution, oldStatus, slcExecution + .getStatus()); + } + } + + public void messageLogged(BuildEvent event) { + if (!shouldLog()) + return; + + SlcExecution slcExecution = getSlcExecution(event); + if (slcExecution != null) { + if (currentStepNotified) { + slcExecution.getSteps().add( + new SlcExecutionStep("LOG", event.getMessage())); + notifyStep(slcExecution, slcExecution.currentStep()); + currentStepNotified = true; + } else { + slcExecution.currentStep().addLog(event.getMessage()); + } + } else { + // TODO: log before initialization? + } + } + + public void targetStarted(BuildEvent event) { + if (!firstTargetStarted) + firstTargetStarted = true; + + addLogStep(event, "Target " + event.getTarget().getName() + " started"); + } + + public void targetFinished(BuildEvent event) { + addLogStep(event, "Target " + event.getTarget().getName() + " finished"); + } + + public void taskStarted(BuildEvent event) { + if (!shouldLog()) + return; + + SlcExecution slcExecution = getSlcExecution(event); + if (!currentStepNotified) { + notifyStep(slcExecution, slcExecution.currentStep()); + currentStepNotified = true; + } + + String msg = null; + if (logTaskStartFinish) + msg = "Task " + event.getTask().getTaskName() + " started"; + + slcExecution.getSteps().add(new SlcExecutionStep("LOG", msg)); + + currentStepNotified = false; + } + + public void taskFinished(BuildEvent event) { + if (!shouldLog()) + return; + + SlcExecution slcExecution = getSlcExecution(event); + if (!currentStepNotified) { + + if (logTaskStartFinish) + slcExecution.currentStep().addLog( + "Task " + event.getTask().getTaskName() + " finished"); + + notifyStep(slcExecution, slcExecution.currentStep()); + currentStepNotified = true; + } + } + + public void setNotifiers(List notifiers) { + this.notifiers = notifiers; + } + + protected SlcExecution getSlcExecution(BuildEvent event) { + Project projectEvt = event.getProject(); + if (!projectEvt.equals(project)) + throw new SlcAntException("Event project " + projectEvt + + " not consistent with listener project " + project); + + SlcExecution slcExecution = (SlcExecution) project + .getReference(REF_SLC_EXECUTION); + + if (slcExecution == null) + throw new SlcAntException("No SLC Execution registered."); + return slcExecution; + } + + protected void addLogStep(BuildEvent event, String msg) { + SlcExecution slcExecution = getSlcExecution(event); + slcExecution.getSteps().add(new SlcExecutionStep("LOG", msg)); + + notifyStep(slcExecution, slcExecution.currentStep()); + currentStepNotified = true; + } + + protected void notifyStep(SlcExecution slcExecution, SlcExecutionStep step) { + Vector additionalSteps = new Vector(); + additionalSteps.add(step); + notifySteps(slcExecution, additionalSteps); + } + + protected void notifySteps(SlcExecution slcExecution, + List additionalSteps) { + for (SlcExecutionNotifier notifier : notifiers) { + notifier.addSteps(slcExecution, additionalSteps); + } + } + + /* Log4j methods */ + + @Override + protected void append(LoggingEvent event) { + if (isLogging) { + // avoid StackOverflow if notification calls Log4j itself. + return; + } + + if (event.getLoggerName().equals( + WebServiceSlcExecutionNotifier.class.getName())) { + return; + } + + isLogging = true; + + try { + SlcExecution slcExecution = (SlcExecution) project + .getReference(REF_SLC_EXECUTION); + if (slcExecution != null) { + if (currentStepNotified) { + slcExecution.getSteps().add( + new SlcExecutionStep("LOG", event.getMessage() + .toString())); + currentStepNotified = false; + } + slcExecution.currentStep() + .addLog(event.getMessage().toString()); + } else { + // TODO: log before initialization? + } + } finally { + isLogging = false; + } + + } + + protected boolean shouldLog() { + return logBeforeFirstTarget || firstTargetStarted; + } + + @Override + public void close() { + } + + @Override + public boolean requiresLayout() { + return false; + } + + public Project getProject() { + return project; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcProjectHelper.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcProjectHelper.java new file mode 100644 index 000000000..001ead97b --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcProjectHelper.java @@ -0,0 +1,266 @@ +package org.argeo.slc.ant; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; +import java.util.Vector; + +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.FileSystemXmlApplicationContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.log4j.LogManager; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.BuildListener; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.helper.ProjectHelper2; + +import org.argeo.slc.core.process.SlcExecution; +import org.argeo.slc.core.process.SlcExecutionNotifier; +import org.argeo.slc.core.structure.DefaultSRegistry; +import org.argeo.slc.core.structure.SimpleSElement; +import org.argeo.slc.core.structure.StructureRegistry; +import org.argeo.slc.core.structure.tree.TreeSPath; + +/** + * Custom implementation of an Ant ProjectHelper binding a Spring + * application context and a structure registry with the Ant project. + */ +public class SlcProjectHelper extends ProjectHelper2 { + private static Log log; + + /** The Ant reference to the Spring application context used. */ + public static String REF_ROOT_CONTEXT = "slcApplicationContext"; + /** The Ant reference to the SLC structure registry used. */ + public static String REF_STRUCTURE_REGISTRY = "slcStructureRegistry"; + /** The Ant reference to the TreePath of the current project */ + public static String REF_PROJECT_PATH = "slcProjectPath"; + /** + * Resource path to the property file listing the SLC specific Ant tasks: + * /org/argeo/slc/ant/taskdefs.properties + */ + private static String SLC_TASKDEFS_RESOURCE_PATH = "/org/argeo/slc/ant/taskdefs.properties"; + private static String SLC_TYPEDEFS_RESOURCE_PATH = "/org/argeo/slc/ant/typedefs.properties"; + + protected SlcAntConfig slcAntConfig = null; + + @Override + public void parse(Project project, Object source) throws BuildException { + + if (source instanceof File) { + File sourceFile = (File) source; + // Reset basedir property, in order to avoid base dir override when + // running in Maven + project.setProperty("basedir", sourceFile.getParentFile() + .getAbsolutePath()); + } + + if (slcAntConfig != null) { + // Config already initialized (probably import), only parse + super.parse(project, source); + return; + } + + // Initialize config + slcAntConfig = new SlcAntConfig(); + + if (!slcAntConfig.initProject(project)) { + // not SLC compatible, do normal Ant + super.parse(project, source); + return; + } + + if (log == null) { + // log4j is initialized only now + log = LogFactory.getLog(SlcProjectHelper.class); + } + + if (log.isDebugEnabled()) + log.debug("SLC properties are set, starting initialization for " + + source + " (projectHelper=" + this + ")"); + + beforeParsing(project); + + // Calls the underlying implementation to do the actual work + super.parse(project, source); + + afterParsing(project); + } + + /** + * Performs operations after config initialization and before Ant file + * parsing. Performed only once when the main project file is parsed. Should + * be called by overriding methods. + */ + protected void beforeParsing(Project project) { + // Init Spring application context + initSpringContext(project); + + // Init structure registry + DefaultSRegistry registry = new DefaultSRegistry(); + project.addReference(REF_STRUCTURE_REGISTRY, registry); + } + + /** + * Performs operations after parsing of the main file. Called only once (not + * for imports). + */ + protected void afterParsing(Project project) { + // Creates structure root + registerProjectAndParents(project, slcAntConfig); + addCustomTaskAndTypes(project); + } + + /** Creates the tree-based structure for this project. */ + private void registerProjectAndParents(Project project, + SlcAntConfig slcAntConfig) { + StructureRegistry registry = (StructureRegistry) project + .getReference(REF_STRUCTURE_REGISTRY); + File rootDir = new File(project + .getUserProperty(SlcAntConfig.ROOT_DIR_PROPERTY)) + .getAbsoluteFile(); + File baseDir = project.getBaseDir().getAbsoluteFile(); + List dirs = new Vector(); + File currentDir = baseDir; + do { + dirs.add(currentDir); + currentDir = currentDir.getParentFile(); + if (log.isTraceEnabled()) + log.trace("List " + currentDir); + } while (!currentDir.equals(rootDir.getParentFile())); + + // first path is root dir (because of previous algorithm) + TreeSPath currPath = TreeSPath.createRootPath(rootDir.getName()); + for (int i = dirs.size() - 1; i >= 0; i--) { + File dir = dirs.get(i); + + // retrieves description for this path + final String description; + if (i == 0) {// project itself + description = project.getDescription() != null + && !project.getDescription().equals("") ? project + .getDescription() : project.getName() != null ? project + .getName() : slcAntConfig.getDescriptionForDir(dir); + } else { + description = slcAntConfig.getDescriptionForDir(dir); + if (log.isTraceEnabled()) + log.trace("Dir desc " + i + "/" + dirs.size() + ": " + + description); + } + SimpleSElement element = new SimpleSElement(description); + + // creates and register path + if (!dir.equals(rootDir)) {// already set + currPath = currPath.createChild(dir.getName()); + } + registry.register(currPath, element); + } + project.addReference(REF_PROJECT_PATH, currPath); + } + + /** Gets the path of a project (root). */ + // private static TreeSPath getProjectPath(Project project) { + // return (TreeSPath) project.getReference(REF_PROJECT_PATH); + // } + /** Initializes the Spring application context. */ + private void initSpringContext(Project project) { + System.getProperties().putAll((Map) project.getProperties()); + String acPath = project + .getUserProperty(SlcAntConfig.APPLICATION_CONTEXT_PROPERTY); + if (log.isDebugEnabled()) + log.debug("Loading Spring application context from " + acPath); + // FIXME: workaround to the removal of leading '/' by Spring + // use URL instead? + AbstractApplicationContext context = new FileSystemXmlApplicationContext( + '/' + acPath); + context.registerShutdownHook(); + project.addReference(REF_ROOT_CONTEXT, context); + + createAndRegisterSlcExecution(project); + // Add build listeners declared in Spring context + // Map listeners = context.getBeansOfType( + // BuildListener.class, false, true); + // for (BuildListener listener : listeners.values()) { + // project.addBuildListener(listener); + // } + } + + /** Loads the SLC specific Ant tasks. */ + protected static void addCustomTaskAndTypes(Project project) { + Properties taskdefs = getDefs(project, SLC_TASKDEFS_RESOURCE_PATH); + for (Object o : taskdefs.keySet()) { + String name = o.toString(); + try { + project.addTaskDefinition(name, Class.forName(taskdefs + .getProperty(name))); + } catch (ClassNotFoundException e) { + log.error("Unknown class for task " + name, e); + } + } + Properties typedefs = getDefs(project, SLC_TYPEDEFS_RESOURCE_PATH); + for (Object o : typedefs.keySet()) { + String name = o.toString(); + try { + project.addDataTypeDefinition(name, Class.forName(typedefs + .getProperty(name))); + } catch (ClassNotFoundException e) { + log.error("Unknown class for type " + name, e); + } + } + } + + private static Properties getDefs(Project project, String path) { + Properties defs = new Properties(); + try { + InputStream in = project.getClass().getResourceAsStream(path); + defs.load(in); + in.close(); + } catch (IOException e) { + throw new SlcAntException("Cannot load task definitions", e); + } + return defs; + } + + protected static void createAndRegisterSlcExecution(Project project) { + SlcExecution slcExecution = new SlcExecution(); + slcExecution.setUuid(UUID.randomUUID().toString()); + try { + slcExecution.setHost(InetAddress.getLocalHost().getHostName()); + } catch (UnknownHostException e) { + slcExecution.setHost(SlcExecution.UNKOWN_HOST); + } + + if (project.getReference(SlcProjectHelper.REF_ROOT_CONTEXT) != null) { + slcExecution.setType(SlcExecutionBuildListener.SLC_ANT_TYPE); + } else { + slcExecution.setType(SlcExecutionBuildListener.ANT_TYPE); + } + + slcExecution.setUser(System.getProperty("user.name")); + slcExecution.setStatus(SlcExecution.STATUS_RUNNING); + slcExecution.getAttributes().put("ant.file", + project.getProperty("ant.file")); + + project.addReference(SlcExecutionBuildListener.REF_SLC_EXECUTION, + slcExecution); + + // Add build listeners declared in Spring context + Map listeners = ((ListableBeanFactory) project + .getReference(REF_ROOT_CONTEXT)).getBeansOfType( + ProjectRelatedBuildListener.class, false, true); + for (ProjectRelatedBuildListener listener : listeners.values()) { + listener.init(project); + project.addBuildListener(listener); + } + + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/deploy/SlcDeployTask.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/deploy/SlcDeployTask.java new file mode 100644 index 000000000..36c22547b --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/deploy/SlcDeployTask.java @@ -0,0 +1,75 @@ +package org.argeo.slc.ant.deploy; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.BuildException; + +import org.argeo.slc.ant.spring.AbstractSpringArg; +import org.argeo.slc.ant.structure.SAwareTask; +import org.argeo.slc.core.deploy.DeploymentData; +import org.argeo.slc.core.deploy.TargetData; +import org.argeo.slc.core.deploy.WritableDeployment; + +/** Ant task wrapping a deployment. */ +public class SlcDeployTask extends SAwareTask { + private Log log = LogFactory.getLog(SlcDeployTask.class); + + private String deploymentBean = null; + + private DeploymentDataArg deploymentDataArg; + private TargetDataArg targetDataArg; + + @Override + public void executeActions(String mode) throws BuildException { + WritableDeployment deployment = (WritableDeployment) getContext() + .getBean(deploymentBean); + + // set overridden references + if (deploymentDataArg != null) { + deployment.setDeploymentData(deploymentDataArg.getDeploymentData()); + log.trace("Overrides deployment data"); + } + + if (targetDataArg != null) { + deployment.setTargetData(targetDataArg.getTargetData()); + log.trace("Overrides target data"); + } + + deployment.execute(); + } + + /** + * The bean name of the test run to use. If not set the default is used. + * + * @see SlcAntConfig + */ + public void setDeployment(String deploymentBean) { + this.deploymentBean = deploymentBean; + } + + /** Creates deployment data sub tag. */ + public DeploymentDataArg createDeploymentData() { + deploymentDataArg = new DeploymentDataArg(); + return deploymentDataArg; + } + + /** Creates target data sub tag. */ + public TargetDataArg createTargetData() { + targetDataArg = new TargetDataArg(); + return targetDataArg; + } +} + +class DeploymentDataArg extends AbstractSpringArg { + DeploymentData getDeploymentData() { + return (DeploymentData) getBeanInstance(); + } + +} + +class TargetDataArg extends AbstractSpringArg { + TargetData getTargetData() { + return (TargetData) getBeanInstance(); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/deploy/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/deploy/package.html new file mode 100644 index 000000000..76582d159 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/deploy/package.html @@ -0,0 +1,6 @@ + + + +Integration of SLC Deploy in Ant. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/package.html new file mode 100644 index 000000000..9f36fb1bf --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/package.html @@ -0,0 +1,38 @@ + + + +Bases classes for SLC Ant extensions. +

Introduction

+SLC Ant allows to integrate Ant and Spring in order to run an +application based on top of SLC. Sequence of actions are defined in Ant +files with specific Ant tasks referencing Spring beans implementing the +SLC interfaces. The properties of these beans can be overridden at +runtime in the Ant scripts. +
+SLC Ant also provides a tree-based implementation of the SLC structure +which allows to uniquely identify and reference the various actions. + +

Installation

+The structure will be first defined by the directory tree where the Ant +files are stored. In order to define the root of this tree, you need to +place in the root directory an +SLC Ant root file +(default name: slcRoot.properties). +
+In this root file you can define a configuration directory and a work +directory (default values are provided if they are not explicitly set). +
+Additional properties can then be defined in files stored under the +configuration directory. +
+For details about the configuration and the various properties, please +refer to {@link org.argeo.slc.ant.SlcAntConfig}. + +

Running SLC Ant

+SLC Ant can be run either via pure Ant scripts or programmatically using +{@link org.argeo.slc.ant.AntRegistryUtil}. In both cases, make sure that +SLC and its dependencies are in the classpath (Spring (always), logging +system such as log4j, Hibernate, etc.). + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/AbstractSpringArg.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/AbstractSpringArg.java new file mode 100644 index 000000000..6096f1f63 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/AbstractSpringArg.java @@ -0,0 +1,87 @@ +package org.argeo.slc.ant.spring; + +import java.util.List; +import java.util.Vector; + +import org.springframework.beans.BeanWrapper; +import org.springframework.beans.BeanWrapperImpl; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; + +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.types.DataType; + +import org.argeo.slc.ant.SlcAntException; +import org.argeo.slc.ant.SlcProjectHelper; +import org.argeo.slc.core.SlcException; + +/** Abstract Ant type wrapping a Spring bean. */ +public abstract class AbstractSpringArg extends DataType { + private List overrides = new Vector(); + + private String bean; + + // cache bean instance to avoid reading it twice if it is a prototype + private Object beanInstance = null; + + /** The name of the underlying bean, as set throught the attribute. */ + public String getBean() { + return bean; + } + + /** Setter for the bean name. */ + public void setBean(String bean) { + this.bean = bean; + } + + /** + * Retrieve the instance of the bean, and sets the overriden properties. + * The value is cached. + */ + public Object getBeanInstance() { + if (beanInstance == null) { + beanInstance = getContext().getBean(bean); + + setOverridenProperties(beanInstance); + + if (beanInstance instanceof InitializingBean) { + try { + ((InitializingBean) beanInstance).afterPropertiesSet(); + } catch (Exception e) { + throw new SlcException("Could not initialize bean", e); + } + } + } + return beanInstance; + } + + protected void setOverridenProperties(Object obj){ + BeanWrapper wrapper = new BeanWrapperImpl(obj); + for (OverrideArg override : overrides) { + if (override.getName() == null) { + throw new SlcAntException( + "The name of the property to override has to be set."); + } + +// LogFactory.getLog(getClass()).debug( +// "Prop " + override.getName()); + wrapper.setPropertyValue(override.getName(), override + .getObject()); + } + + } + + /** Creates an override subtag. */ + public OverrideArg createOverride() { + OverrideArg propertyArg = new OverrideArg(); + overrides.add(propertyArg); + return propertyArg; + } + + /** The related Spring application context. */ + protected ApplicationContext getContext() { + return (ApplicationContext) getProject().getReference( + SlcProjectHelper.REF_ROOT_CONTEXT); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/AbstractSpringTask.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/AbstractSpringTask.java new file mode 100644 index 000000000..925140fa5 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/AbstractSpringTask.java @@ -0,0 +1,25 @@ +package org.argeo.slc.ant.spring; + +import org.springframework.context.ApplicationContext; + +import org.apache.tools.ant.Task; + +import org.argeo.slc.ant.SlcExecutionBuildListener; +import org.argeo.slc.ant.SlcProjectHelper; +import org.argeo.slc.core.process.SlcExecution; + +/** Abstract Ant task providing access to a Spring context. */ +public abstract class AbstractSpringTask extends Task { + + /** Gets the related Spring context. */ + protected ApplicationContext getContext() { + return (ApplicationContext) getProject().getReference( + SlcProjectHelper.REF_ROOT_CONTEXT); + } + + /** Gets the related slc execution or null if not is registered. */ + protected SlcExecution getSlcExecution() { + return (SlcExecution) getProject().getReference( + SlcExecutionBuildListener.REF_SLC_EXECUTION); + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/MapArg.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/MapArg.java new file mode 100644 index 000000000..eb4527644 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/MapArg.java @@ -0,0 +1,76 @@ +package org.argeo.slc.ant.spring; + +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.Vector; + +import org.apache.tools.ant.BuildException; + +import org.argeo.slc.core.SlcException; + +public class MapArg { + private List entries = new Vector(); + private Map map = new TreeMap(); + + public EntryArg createEntry() { + EntryArg arg = new EntryArg(); + entries.add(arg); + return arg; + } + + public Map getMap() { + if (map.size() == 0) { + for (EntryArg arg : entries) { + String key = arg.getKey(); + if (map.containsKey(key)) { + throw new SlcException("Key '" + key + "' already set."); + } else { + map.put(key, arg.getValueStr()); + } + } + } + return map; + } + + public static class EntryArg { + private String key; + private Object valueStr; + private OverrideArg overrideArg; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Object getValueStr() { + if (overrideArg != null) { + return overrideArg.getObject(); + } else if (valueStr != null) { + return valueStr; + } else { + throw new BuildException("Value not set."); + } + } + + public void setValue(String value) { + check(); + this.valueStr = value; + } + + public OverrideArg createOverride() { + check(); + overrideArg = new OverrideArg(); + return overrideArg; + } + + private void check() { + if (valueStr != null || overrideArg != null) { + throw new BuildException("Value already set"); + } + } + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/OverrideArg.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/OverrideArg.java new file mode 100644 index 000000000..5c0dc3e69 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/OverrideArg.java @@ -0,0 +1,112 @@ +package org.argeo.slc.ant.spring; + +import java.util.List; +import java.util.Vector; + +import org.apache.tools.ant.BuildException; + +import org.argeo.slc.core.SlcException; + +/** Ant type allowing to override bean properties. */ +public class OverrideArg extends AbstractSpringArg { + private String name; + private Object value; + private OverrideList overrideList; + private MapArg overrideMap; + private String antref; + + /** The name of the property to override. */ + public String getName() { + return name; + } + + /** Sets the name. */ + public void setName(String name) { + this.name = name; + } + + /** Sets a reference to an ant data type. */ + public void setAntref(String antref) { + checkValueAlreadySet(); + this.antref = antref; + } + + /** Both value and bean cannot be set. */ + public void setValue(String value) { + checkValueAlreadySet(); + this.value = value; + } + + @Override + public void setBean(String bean) { + checkValueAlreadySet(); + super.setBean(bean); + } + + /** Creates override list sub tag. */ + public OverrideList createList() { + checkValueAlreadySet(); + overrideList = new OverrideList(); + return overrideList; + } + + public MapArg createMap() { + checkValueAlreadySet(); + overrideMap = new MapArg(); + return overrideMap; + } + + /** + * The related object: the value if a value had been set or an instance of + * the bean if not. + */ + public Object getObject() { + if (value != null) { + return value; + } else if (getBean() != null) { + return getBeanInstance(); + } else if (overrideList != null) { + return overrideList.getAsObjectList(); + } else if (overrideMap != null) { + return overrideMap.getMap(); + } else if (antref != null) { + Object obj = getProject().getReference(antref); + if (obj == null) { + throw new SlcException("No object found for reference " + + antref); + } + setOverridenProperties(obj); + return obj; + } else { + throw new BuildException("Value or bean not set."); + } + } + + private void checkValueAlreadySet() { + if (value != null || overrideList != null || antref != null + || getBean() != null || overrideMap != null) { + throw new BuildException("Value already set."); + } + } + + /** List of overrides */ + protected class OverrideList { + private List list = new Vector(); + + /** Creates override sub tag. */ + public OverrideArg createOverride() { + OverrideArg overrideArg = new OverrideArg(); + list.add(overrideArg); + return overrideArg; + } + + /** Gets as list of objects. */ + public List getAsObjectList() { + List objectList = new Vector(); + for (OverrideArg arg : list) { + objectList.add(arg.getObject()); + } + return objectList; + } + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/package.html new file mode 100644 index 000000000..6d141d993 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/package.html @@ -0,0 +1,6 @@ + + + +Integration of Spring in Ant. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/structure/SAwareTask.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/structure/SAwareTask.java new file mode 100644 index 000000000..d248a3870 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/structure/SAwareTask.java @@ -0,0 +1,157 @@ +package org.argeo.slc.ant.structure; + +import java.util.List; +import java.util.Vector; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Target; + +import org.argeo.slc.ant.SlcAntException; +import org.argeo.slc.ant.SlcProjectHelper; +import org.argeo.slc.ant.spring.AbstractSpringArg; +import org.argeo.slc.ant.spring.AbstractSpringTask; +import org.argeo.slc.core.structure.SimpleSElement; +import org.argeo.slc.core.structure.StructureAware; +import org.argeo.slc.core.structure.StructureElement; +import org.argeo.slc.core.structure.StructureRegistry; +import org.argeo.slc.core.structure.tree.TreeSPath; + +/** Ant task that can be registered within a structure. */ +public abstract class SAwareTask extends AbstractSpringTask { + private String path; + private TreeSPath treeSPath; + private final List sAwareArgs = new Vector(); + + private StructureElementArg structureElementArg; + + @Override + public void init() throws BuildException { + StructureRegistry registry = getRegistry(); + Target target = getOwningTarget(); + + TreeSPath targetPath = createTargetPath(target); + SimpleSElement targetElement = (SimpleSElement) registry + .getElement(createTargetPath(target)); + + if (targetElement == null) { + targetElement = new SimpleSElement(target.getDescription(), + ""); + registry.register(targetPath, targetElement); + } + } + + /** + * Includes this arg in the checks for propagation of structure related + * information. + */ + protected void addSAwareArg(AbstractSpringArg arg) { + sAwareArgs.add(arg); + } + + @Override + /** + * Called by Ant at runtime. Decides whether to call the actions depending + * of the mode of the underlying structure registry. + * + * @see #executeActions + * @see StructureRegistry + */ + public final void execute() throws BuildException { + if (path == null) { + // register the task in the structure + TreeSPath targetPath = createTargetPath(getOwningTarget()); + TreeSPath taskPath = targetPath.createChild(getTaskName() + + targetPath.listChildren(getRegistry()).size()); + + treeSPath = taskPath; + } else { + treeSPath = new TreeSPath(path); + } + + if (getRegistry().getElement(treeSPath) == null) { + // No structure element registered. + if (structureElementArg != null) { + getRegistry().register(treeSPath, + structureElementArg.getStructureElement()); + } else { + if (getDescription() != null) { + getRegistry().register(treeSPath, + new SimpleSElement(getDescription())); + } + } + } + + // notify registered args + for (AbstractSpringArg arg : sAwareArgs) { + Object obj = arg.getBeanInstance(); + + if (obj instanceof StructureAware) { + StructureAware sAwareT = (StructureAware) obj; + sAwareT.notifyCurrentPath(getRegistry(), treeSPath); + } + } + + // execute depending on the registry mode + String mode = getRegistry().getMode(); + if (mode.equals(StructureRegistry.ALL)) { + executeActions(mode); + } else if (mode.equals(StructureRegistry.ACTIVE)) { + List activePaths = getRegistry().getActivePaths(); + + if (activePaths.contains(treeSPath)) { + if (activePaths.contains(treeSPath)) { + executeActions(mode); + } + } + } + + } + + /** Actions to be executed by the implementor. */ + protected abstract void executeActions(String mode); + + /** Create a reference to an external structure element. */ + public StructureElementArg createStructureElement() { + if (structureElementArg != null) + throw new SlcAntException("Arg already set."); + structureElementArg = new StructureElementArg(); + return structureElementArg; + } + + /** Gets the underlying structure registry. */ + protected StructureRegistry getRegistry() { + return (StructureRegistry) getProject().getReference( + SlcProjectHelper.REF_STRUCTURE_REGISTRY); + } + + /** Creates the treeSPath for a given Ant target. */ + protected static TreeSPath createTargetPath(Target target) { + TreeSPath projectPath = (TreeSPath) target.getProject().getReference( + SlcProjectHelper.REF_PROJECT_PATH); + return projectPath.createChild(target.getName()); + } + + /** Gets the treeSPath under which this task is registered. */ + public TreeSPath getTreeSPath() { + return treeSPath; + } + + public String getLabel() { + String description = super.getDescription(); + if (description == null) { + return ""; + } else { + return description; + } + } + + public void setPath(String path) { + this.path = path; + } +} + +class StructureElementArg extends AbstractSpringArg { + public StructureElement getStructureElement() { + return (StructureElement) getBeanInstance(); + } +} \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/structure/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/structure/package.html new file mode 100644 index 000000000..99e45d335 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/structure/package.html @@ -0,0 +1,6 @@ + + + +Integration of SLC Structure in Ant. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/ParentContextType.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/ParentContextType.java new file mode 100644 index 000000000..7915b1a42 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/ParentContextType.java @@ -0,0 +1,102 @@ +package org.argeo.slc.ant.test; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.apache.tools.ant.types.DataType; + +import org.argeo.slc.ant.spring.MapArg; +import org.argeo.slc.core.SlcException; +import org.argeo.slc.core.test.context.ContextAware; +import org.argeo.slc.core.test.context.ContextUtils; +import org.argeo.slc.core.test.context.ParentContextAware; + +public class ParentContextType extends DataType implements ParentContextAware { + private MapArg values = null; + private MapArg expectedValues = null; + + private String contextAnyFlag = DEFAULT_ANY_FLAG; + private String contextSkipFlag = DEFAULT_SKIP_FLAG; + + private String basedon = null; + + private List children = new Vector(); + + public MapArg createValues() { + values = new MapArg(); + return values; + } + + public MapArg createExpectedValues() { + expectedValues = new MapArg(); + return expectedValues; + } + + public void addChildContext(ContextAware contextAware) { + children.add(contextAware); + } + + public Collection getChildContexts() { + return children; + } + + public String getContextAnyFlag() { + return contextAnyFlag; + } + + public void setContextAnyFlag(String contextAnyFlag) { + this.contextAnyFlag = contextAnyFlag; + } + + public String getContextSkipFlag() { + return contextSkipFlag; + } + + public void setContextSkipFlag(String contextSkipFlag) { + this.contextSkipFlag = contextSkipFlag; + } + + public Map getExpectedValues() { + if (expectedValues == null) + expectedValues = new MapArg(); + if (basedon != null) { + Map map = getBaseContext().getExpectedValues(); + ContextUtils.putNotContained(expectedValues.getMap(), map); + } + return expectedValues.getMap(); + } + + public Map getValues() { + if (values == null) + values = new MapArg(); + if (basedon != null) { + Map map = getBaseContext().getValues(); + ContextUtils.putNotContained(values.getMap(), map); + } + return values.getMap(); + } + + private ParentContextType getBaseContext() { + return (ParentContextType) getProject().getReference(basedon); + } + + public void setValues(Map values) { + throw new SlcException("Cannot override values map."); + } + + public void setUpdateValues(Map overrideValues) { + getValues().putAll(overrideValues); + } + + public void setUpdateExpectedValues( + Map overrideExpectedValues) { + getExpectedValues().putAll(overrideExpectedValues); + } + + public void setBasedon(String basedon) { + this.basedon = basedon; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/SlcCloseTestResultTask.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/SlcCloseTestResultTask.java new file mode 100644 index 000000000..bc0c2ba1a --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/SlcCloseTestResultTask.java @@ -0,0 +1,24 @@ +package org.argeo.slc.ant.test; + +import org.argeo.slc.ant.structure.SAwareTask; +import org.argeo.slc.core.structure.StructureRegistry; +import org.argeo.slc.core.test.TestResult; + +/** Ant tasks closing a given result. */ +public class SlcCloseTestResultTask extends SAwareTask { + private String result; + + @Override + public void executeActions(String mode) { + if (!mode.equals(StructureRegistry.READ)) { + TestResult testResult = (TestResult) getContext().getBean(result); + testResult.close(); + } + } + + /** Sets the bean name of the result to close. */ + public void setResult(String bean) { + this.result = bean; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/SlcReportTask.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/SlcReportTask.java new file mode 100644 index 000000000..75877625d --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/SlcReportTask.java @@ -0,0 +1,40 @@ +package org.argeo.slc.ant.test; + +import org.argeo.slc.ant.structure.SAwareTask; +import org.argeo.slc.core.structure.StructureAware; +import org.argeo.slc.core.structure.StructureRegistry; +import org.argeo.slc.core.test.TestReport; +import org.argeo.slc.core.test.TestResult; + +/** Ant tasks generating a report. */ +public class SlcReportTask extends SAwareTask { + private String result; + private String report; + + @Override + public void executeActions(String mode) { + if (!mode.equals(StructureRegistry.READ)) { + TestResult testResult = null; + if (result != null) { + testResult = (TestResult) getContext().getBean(result); + } + TestReport testReport = (TestReport) getContext().getBean(report); + if (testReport instanceof StructureAware) { + ((StructureAware) testReport).notifyCurrentPath(getRegistry(), + null); + } + testReport.generateTestReport(testResult); + } + } + + /** Sets the bean name of the result to close. */ + public void setResult(String bean) { + this.result = bean; + } + + /** Sets the bean name of the report to generate. */ + public void setReport(String report) { + this.report = report; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/SlcTestTask.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/SlcTestTask.java new file mode 100644 index 000000000..6f2411c00 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/SlcTestTask.java @@ -0,0 +1,176 @@ +package org.argeo.slc.ant.test; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.BuildException; + +import org.argeo.slc.ant.SlcAntConfig; +import org.argeo.slc.ant.spring.AbstractSpringArg; +import org.argeo.slc.ant.structure.SAwareTask; +import org.argeo.slc.core.SlcException; +import org.argeo.slc.core.deploy.DeployedSystem; +import org.argeo.slc.core.process.SlcExecution; +import org.argeo.slc.core.process.SlcExecutionAware; +import org.argeo.slc.core.structure.StructureAware; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.test.ExecutableTestRun; +import org.argeo.slc.core.test.SimpleTestResult; +import org.argeo.slc.core.test.SimpleTestRun; +import org.argeo.slc.core.test.TestData; +import org.argeo.slc.core.test.TestDefinition; +import org.argeo.slc.core.test.TestResult; +import org.argeo.slc.core.test.WritableTestRun; +import org.argeo.slc.spring.SpringUtils; + +/** Ant task wrapping a test run. */ +public class SlcTestTask extends SAwareTask { + private Log log = LogFactory.getLog(SlcTestTask.class); + + private String testRunBean = null; + + private TestDefinitionArg testDefinitionArg; + private TestDataArg testDataArg; + private DeployedSystemArg deployedSystemArg; + private TestResultArg testResultArg; + + @Override + public void executeActions(String mode) throws BuildException { + // find test run + final String testRunBeanT; + if (testRunBean != null) { + testRunBeanT = testRunBean; + } else { + testRunBeanT = getProject().getUserProperty( + SlcAntConfig.DEFAULT_TEST_RUN_PROPERTY); + } + WritableTestRun testRun = null; + + if (testRunBeanT != null) { + testRun = (WritableTestRun) getContext().getBean(testRunBeanT); + if (log.isTraceEnabled()) + log.trace("Load test run bean from bean name " + testRunBeanT); + } + + if (testRun == null) { + testRun = loadSingleFromContext(WritableTestRun.class); + if (testRun == null) { + testRun = new SimpleTestRun(); + log.warn("Created default simple test run"); + } else { + if (log.isTraceEnabled()) + log.trace("Load test run from scanning Spring context"); + } + } + + // set overridden references + if (testDataArg != null) { + testRun.setTestData(testDataArg.getTestData()); + log.trace("Overrides test data"); + } + + if (testDefinitionArg != null) { + testRun.setTestDefinition(testDefinitionArg.getTestDefinition()); + log.trace("Overrides test definition"); + } + + if (deployedSystemArg != null) { + testRun.setDeployedSystem(deployedSystemArg.getDeployedSystem()); + log.trace("Overrides deployed system"); + } + + if (testResultArg != null) { + testRun.setTestResult(testResultArg.getTestResult()); + log.trace("Overrides test result"); + } + + // notify path to test result + TestResult result = testRun.getTestResult(); + if (result == null) { + result = loadSingleFromContext(TestResult.class); + if (result == null) { + result = new SimpleTestResult(); + log.warn("Created default simple test result"); + } else { + if (log.isTraceEnabled()) + log.trace("Load test result from scanning Spring context"); + } + testRun.setTestResult(result); + } + + SlcExecution slcExecution = getSlcExecution(); + testRun.notifySlcExecution(slcExecution); + + if (result != null && result instanceof StructureAware) { + ((StructureAware) result).notifyCurrentPath( + getRegistry(), getTreeSPath()); + } + + ((ExecutableTestRun) testRun).execute(); + } + + /** + * The bean name of the test run to use. If not set the default is used. + * + * @see SlcAntConfig + */ + public void setTestRun(String testRunBean) { + this.testRunBean = testRunBean; + } + + /** Creates sub tag. */ + public TestDefinitionArg createTestDefinition() { + testDefinitionArg = new TestDefinitionArg(); + // only test definitions can add to path + addSAwareArg(testDefinitionArg); + return testDefinitionArg; + } + + /** Creates sub tag. */ + public TestDataArg createTestData() { + testDataArg = new TestDataArg(); + return testDataArg; + } + + /** Creates sub tag. */ + public DeployedSystemArg createDeployedSystem() { + deployedSystemArg = new DeployedSystemArg(); + return deployedSystemArg; + } + + /** Creates sub tag. */ + public TestResultArg createTestResult() { + testResultArg = new TestResultArg(); + return testResultArg; + } + + protected T loadSingleFromContext(Class clss) { + return SpringUtils.loadSingleFromContext(getContext(), clss); + } +} + +class TestDefinitionArg extends AbstractSpringArg { + TestDefinition getTestDefinition() { + return (TestDefinition) getBeanInstance(); + } +} + +class TestDataArg extends AbstractSpringArg { + TestData getTestData() { + return (TestData) getBeanInstance(); + } + +} + +class DeployedSystemArg extends AbstractSpringArg { + DeployedSystem getDeployedSystem() { + return (DeployedSystem) getBeanInstance(); + } + +} + +class TestResultArg extends AbstractSpringArg { + TestResult getTestResult() { + return (TestResult) getBeanInstance(); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/package.html new file mode 100644 index 000000000..179159b39 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/test/package.html @@ -0,0 +1,6 @@ + + + +Integration of SLC Test in Ant. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/castor/structure/tree/TreeSPathFieldHandler.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/castor/structure/tree/TreeSPathFieldHandler.java new file mode 100644 index 000000000..ad117ff14 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/castor/structure/tree/TreeSPathFieldHandler.java @@ -0,0 +1,41 @@ +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())); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/castor/test/tree/StatusFieldHandler.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/castor/test/tree/StatusFieldHandler.java new file mode 100644 index 000000000..4cc334878 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/castor/test/tree/StatusFieldHandler.java @@ -0,0 +1,43 @@ +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); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/SlcException.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/SlcException.java new file mode 100644 index 000000000..7daffaf87 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/SlcException.java @@ -0,0 +1,17 @@ +package org.argeo.slc.core; + +/** Basis for all SLC exceptions. This is an unchecked exception. */ +public class SlcException extends RuntimeException { + static final long serialVersionUID = 1l; + + /** Constructor. */ + public SlcException(String message) { + super(message); + } + + /** Constructor. */ + public SlcException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/UnsupportedException.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/UnsupportedException.java new file mode 100644 index 000000000..4b46b35de --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/UnsupportedException.java @@ -0,0 +1,54 @@ +package org.argeo.slc.core; + +/** Exception for unsupported features or actions. */ +public class UnsupportedException extends SlcException { + static final long serialVersionUID = 1l; + + /** Action not supported. */ + public UnsupportedException() { + this("Action not supported"); + } + + /** Constructor with a message. */ + public UnsupportedException(String message) { + super(message); + } + + /** + * Constructor generating a message. + * + * @param nature + * the nature of the unsupported object + * @param obj + * the object itself (its class name will be used in message) + */ + public UnsupportedException(String nature, Object obj) { + super("Unsupported " + nature + ": " + + (obj != null ? obj.getClass() : "[object is null]")); + } + + /** + * Constructor generating a message. + * + * @param nature + * the nature of the unsupported object + * @param clss + * the class itself (will be used in message) + */ + public UnsupportedException(String nature, Class clss) { + super("Unsupported " + nature + ": " + clss); + } + + /** + * Constructor generating a message. + * + * @param nature + * the nature of the unsupported object + * @param value + * the problematic value itself + */ + public UnsupportedException(String nature, String value) { + super("Unsupported " + nature + ": " + value); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/Distribution.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/Distribution.java new file mode 100644 index 000000000..a9ada27f0 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/Distribution.java @@ -0,0 +1,6 @@ +package org.argeo.slc.core.build; + +public interface Distribution { + public String getDistributionId(); + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/DistributionId.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/DistributionId.java new file mode 100644 index 000000000..c253a679b --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/DistributionId.java @@ -0,0 +1,7 @@ +package org.argeo.slc.core.build; + +/** The id uniquely identifying the distribution of a software system. + * @deprecated*/ +public interface DistributionId { + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/VersionDistributionId.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/VersionDistributionId.java new file mode 100644 index 000000000..27ac020b3 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/VersionDistributionId.java @@ -0,0 +1,82 @@ +package org.argeo.slc.core.build; + +import java.util.StringTokenizer; + +/** + *

+ * An implementation of the distribution id using the standard + * Major.Minor.Release notation. And additional arbitrary string can also be + * added. + *

+ * + *

+ * Examples:
+ * 0.2.6
+ * 2.4.12.RC1 + *

+ */ +public class VersionDistributionId implements DistributionId { + + private Integer major; + private Integer minor; + private Integer release; + private String additional; + + /** Parse the provided string in order to set the various components. */ + public void setVersionString(String str) { + StringTokenizer st = new StringTokenizer(str, "."); + if (st.hasMoreTokens()) + major = Integer.parseInt(st.nextToken()); + if (st.hasMoreTokens()) + minor = Integer.parseInt(st.nextToken()); + if (st.hasMoreTokens()) + release = Integer.parseInt(st.nextToken()); + if (st.hasMoreTokens()) + additional = st.nextToken(); + } + + public Integer getMajor() { + return major; + } + + public void setMajor(Integer major) { + this.major = major; + } + + public Integer getMinor() { + return minor; + } + + public void setMinor(Integer minor) { + this.minor = minor; + } + + public Integer getRelease() { + return release; + } + + public void setRelease(Integer release) { + this.release = release; + } + + public String getAdditional() { + return additional; + } + + public void setAdditional(String additional) { + this.additional = additional; + } + + @Override + public boolean equals(Object obj) { + // TODO Auto-generated method stub + return super.equals(obj); + } + + @Override + public String toString() { + return major + "." + minor + "." + release + + (additional != null ? "." + additional : ""); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/package.html new file mode 100644 index 000000000..5da205278 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/build/package.html @@ -0,0 +1,6 @@ + + + +SLC Build: building of software systems. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeployEnvironment.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeployEnvironment.java new file mode 100644 index 000000000..ca747f65e --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeployEnvironment.java @@ -0,0 +1,9 @@ +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 filter); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeployedSystem.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeployedSystem.java new file mode 100644 index 000000000..2fabf5606 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeployedSystem.java @@ -0,0 +1,9 @@ +package org.argeo.slc.core.deploy; + +import org.argeo.slc.core.build.Distribution; + +/** An instance of a software system. */ +public interface DeployedSystem { + public String getDeployedSystemId(); + public Distribution getDistribution(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeployedSystemId.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeployedSystemId.java new file mode 100644 index 000000000..ea4d19250 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeployedSystemId.java @@ -0,0 +1,9 @@ +package org.argeo.slc.core.deploy; + +import org.argeo.slc.core.build.DistributionId; + +/** The id uniquely identifying a deployed system. + * @deprecated*/ +public interface DeployedSystemId { + public DistributionId getDistributionId(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/Deployment.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/Deployment.java new file mode 100644 index 000000000..4a7403071 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/Deployment.java @@ -0,0 +1,9 @@ +package org.argeo.slc.core.deploy; + +public interface Deployment { + public DeployedSystem getDeployedSystem(); + + public TargetData getTargetData(); + + public DeploymentData getDeploymentData(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeploymentData.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeploymentData.java new file mode 100644 index 000000000..0148ea529 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/DeploymentData.java @@ -0,0 +1,5 @@ +package org.argeo.slc.core.deploy; + +public interface DeploymentData { + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/ExecutableDeployment.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/ExecutableDeployment.java new file mode 100644 index 000000000..284e6c511 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/ExecutableDeployment.java @@ -0,0 +1,5 @@ +package org.argeo.slc.core.deploy; + +public interface ExecutableDeployment extends Deployment { + public void execute(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/NumericDSId.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/NumericDSId.java new file mode 100644 index 000000000..494fc8a77 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/NumericDSId.java @@ -0,0 +1,40 @@ +package org.argeo.slc.core.deploy; + +import org.argeo.slc.core.build.DistributionId; + +/** + * A basic implementation of a deployed system id, based on a long value and a + * reference to a distribution id. + */ +public class NumericDSId implements DeployedSystemId { + + private Long value; + private DistributionId distributionId; + + public Long getValue() { + return value; + } + + public void setValue(Long value) { + this.value = value; + } + + public DistributionId getDistributionId() { + return distributionId; + } + + public void setDistributionId(DistributionId distributionId) { + this.distributionId = distributionId; + } + + @Override + public boolean equals(Object obj) { + return value.toString().equals(obj.toString()); + } + + @Override + public String toString() { + return value.toString(); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/TargetData.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/TargetData.java new file mode 100644 index 000000000..2fe155d31 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/TargetData.java @@ -0,0 +1,5 @@ +package org.argeo.slc.core.deploy; + +public interface TargetData { + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/WritableDeployment.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/WritableDeployment.java new file mode 100644 index 000000000..15c3ccb6c --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/WritableDeployment.java @@ -0,0 +1,9 @@ +package org.argeo.slc.core.deploy; + +public interface WritableDeployment extends ExecutableDeployment { + public void setDeployedSystem(DeployedSystem deployedSystem); + + public void setTargetData(TargetData targetData); + + public void setDeploymentData(DeploymentData deploymentData); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/package.html new file mode 100644 index 000000000..f3a4c5bd6 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/deploy/package.html @@ -0,0 +1,6 @@ + + + +SLC Deploy: deployment of software systems. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/package.html new file mode 100644 index 000000000..db808c822 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/package.html @@ -0,0 +1,6 @@ + + + +Common classes of teh SLC framework. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/FileSlcExecutionNotifier.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/FileSlcExecutionNotifier.java new file mode 100644 index 000000000..1559635bd --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/FileSlcExecutionNotifier.java @@ -0,0 +1,84 @@ +package org.argeo.slc.core.process; + +import java.io.File; +import java.io.FileWriter; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.transform.stream.StreamResult; + +import org.springframework.oxm.Marshaller; + +import org.apache.commons.io.IOUtils; + +import org.argeo.slc.core.SlcException; + +public class FileSlcExecutionNotifier implements SlcExecutionNotifier { + private final static SimpleDateFormat sdf = new SimpleDateFormat( + "yyyyMMdd-HHmmss"); + + private String basePath; + private Marshaller marshaller; + + private Map uuidToDir = new HashMap(); + + public void addSteps(SlcExecution slcExecution, + List additionalSteps) { + writeSlcExecution(slcExecution); + } + + public void newExecution(SlcExecution slcExecution) { + String dirPath = basePath + File.separator + sdf.format(new Date()) + + '-' + slcExecution.getUuid(); + File dir = new File(dirPath); + dir.mkdirs(); + + uuidToDir.put(slcExecution.getUuid(), dirPath); + + writeSlcExecution(slcExecution); + } + + public void updateExecution(SlcExecution slcExecution) { + writeSlcExecution(slcExecution); + } + + public void updateStatus(SlcExecution slcExecution, String oldStatus, + String newStatus) { + writeSlcExecution(slcExecution); + } + + protected void writeSlcExecution(SlcExecution slcExecution) { + FileWriter out = null; + try { + out = new FileWriter(getFilePath(slcExecution)); + marshaller.marshal(slcExecution, new StreamResult(out)); + } catch (Exception e) { + throw new SlcException("Cannot marshall SlcExecution to " + + getFilePath(slcExecution), e); + } finally { + IOUtils.closeQuietly(out); + } + } + + protected String getFileName(SlcExecution slcExecution) { + return "SlcExecution-" + slcExecution.getUuid() + ".xml"; + } + + protected String getFilePath(SlcExecution slcExecution) { + String dirPath = uuidToDir.get(slcExecution.getUuid()); + return dirPath + File.separator + "SlcExecution-" + + slcExecution.getUuid() + ".xml"; + } + + public void setBasePath(String basePath) { + this.basePath = basePath; + } + + public void setMarshaller(Marshaller marshaller) { + this.marshaller = marshaller; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecution.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecution.java new file mode 100644 index 000000000..4df206815 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecution.java @@ -0,0 +1,101 @@ +package org.argeo.slc.core.process; + +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.Vector; + +public class SlcExecution { + public final static String STATUS_SCHEDULED = "SCHEDULED"; + public final static String STATUS_RUNNING = "RUNNING"; + public final static String STATUS_FINISHED = "FINISHED"; + public final static String STATUS_ERROR = "ERROR"; + public final static String STATUS_CLEANED = "CLEANED"; + + public final static String UNKOWN_HOST = "UNKOWN_HOST"; + + private String uuid; + private String host; + private String user; + private String type; + private String status; + private Map attributes = new TreeMap(); + + private List steps = new Vector(); + + public List getSteps() { + return steps; + } + + public void setSteps(List steps) { + this.steps = steps; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getUser() { + return user; + } + + public void setUser(String path) { + this.user = path; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public SlcExecutionStep currentStep() { + if (steps.size() > 0) + return steps.get(steps.size() - 1); + else + return null; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof SlcExecution) { + return getUuid().equals(((SlcExecution) obj).getUuid()); + } + return false; + } + + @Override + public int hashCode() { + return getUuid().hashCode(); + } + + public Map getAttributes() { + return attributes; + } + + public void setAttributes(Map attributes) { + this.attributes = attributes; + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecutionAware.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecutionAware.java new file mode 100644 index 000000000..089dc317e --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecutionAware.java @@ -0,0 +1,5 @@ +package org.argeo.slc.core.process; + +public interface SlcExecutionAware { + public void notifySlcExecution(SlcExecution slcExecution); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecutionNotifier.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecutionNotifier.java new file mode 100644 index 000000000..bf3b67ba5 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecutionNotifier.java @@ -0,0 +1,15 @@ +package org.argeo.slc.core.process; + +import java.util.List; + +public interface SlcExecutionNotifier { + public void newExecution(SlcExecution slcExecution); + + public void addSteps(SlcExecution slcExecution, + List additionalSteps); + + public void updateExecution(SlcExecution slcExecution); + + public void updateStatus(SlcExecution slcExecution, String oldStatus, + String newStatus); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecutionStep.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecutionStep.java new file mode 100644 index 000000000..56b6ba020 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/SlcExecutionStep.java @@ -0,0 +1,81 @@ +package org.argeo.slc.core.process; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import java.util.Vector; + +import org.apache.commons.io.IOUtils; + +public class SlcExecutionStep { + private String uuid; + private String type; + private Date begin; + private List logLines = new Vector(); + + /** Empty constructor */ + public SlcExecutionStep() { + } + + public SlcExecutionStep(String type, String log) { + this.type = type; + this.begin = new Date(); + this.uuid = UUID.randomUUID().toString(); + addLog(log); + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Date getBegin() { + return begin; + } + + public void setBegin(Date begin) { + this.begin = begin; + } + + public List getLogLines() { + return logLines; + } + + public void setLogLines(List logLines) { + this.logLines = logLines; + } + + public String logAsString() { + StringWriter writer = new StringWriter(); + String log = writer.toString(); + IOUtils.closeQuietly(writer); + return log; + } + + public void addLog(String log) { + if (log == null) + return; + + try { + List lines = IOUtils.readLines(new StringReader(log)); + logLines.addAll(lines); + } catch (IOException e) { + throw new RuntimeException("Cannot add log", e); + } + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/WebServiceSlcExecutionNotifier.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/WebServiceSlcExecutionNotifier.java new file mode 100644 index 000000000..969234487 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/process/WebServiceSlcExecutionNotifier.java @@ -0,0 +1,117 @@ +package org.argeo.slc.core.process; + +import java.util.List; + +import org.springframework.ws.client.WebServiceIOException; +import org.springframework.ws.client.core.WebServiceTemplate; +import org.springframework.ws.soap.client.SoapFaultClientException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.msg.process.SlcExecutionRequest; +import org.argeo.slc.msg.process.SlcExecutionStatusRequest; +import org.argeo.slc.msg.process.SlcExecutionStepsRequest; +import org.argeo.slc.ws.client.WebServiceUtils; + +public class WebServiceSlcExecutionNotifier implements SlcExecutionNotifier { + private WebServiceTemplate template; + + private Log log = LogFactory.getLog(getClass()); + + private Boolean cannotConnect = false; + + public void newExecution(SlcExecution slcExecution) { + if (cannotConnect) + return; + + SlcExecutionRequest req = new SlcExecutionRequest(); + req.setSlcExecution(slcExecution); + try { + WebServiceUtils.marshalSendAndReceive(template, req); + if (log.isTraceEnabled()) + log.trace("Notified creation of slc execution " + + slcExecution.getUuid()); + } catch (SoapFaultClientException e) { + WebServiceUtils.manageSoapException(e); + } catch (WebServiceIOException e) { + manageIoException(e); + } + } + + public void updateExecution(SlcExecution slcExecution) { + if (cannotConnect) + return; + + SlcExecutionRequest req = new SlcExecutionRequest(); + req.setSlcExecution(slcExecution); + try { + WebServiceUtils.marshalSendAndReceive(template, req); + if (log.isTraceEnabled()) + log.trace("Notified update of slc execution " + + slcExecution.getUuid()); + } catch (SoapFaultClientException e) { + WebServiceUtils.manageSoapException(e); + } catch (WebServiceIOException e) { + manageIoException(e); + } + } + + public void updateStatus(SlcExecution slcExecution, String oldStatus, + String newStatus) { + if (cannotConnect) + return; + + SlcExecutionStatusRequest req = new SlcExecutionStatusRequest( + slcExecution.getUuid(), newStatus); + try { + WebServiceUtils.marshalSendAndReceive(template, req); + if (log.isTraceEnabled()) + log.trace("Notified status update of slc execution " + + slcExecution.getUuid()); + } catch (SoapFaultClientException e) { + WebServiceUtils.manageSoapException(e); + } catch (WebServiceIOException e) { + manageIoException(e); + } + } + + public void addSteps(SlcExecution slcExecution, + List additionalSteps) { + if (cannotConnect) + return; + + SlcExecutionStepsRequest req = new SlcExecutionStepsRequest(); + req.setSlcExecutionUuid(slcExecution.getUuid()); + req.setSteps(additionalSteps); + if (log.isTraceEnabled()) { + for (SlcExecutionStep step : additionalSteps) { + log.trace("Step " + step.getUuid() + ": " + step.logAsString()); + } + } + + try { + WebServiceUtils.marshalSendAndReceive(template, req); + if (log.isTraceEnabled()) + log.trace("Added steps to slc execution " + + slcExecution.getUuid()); + } catch (SoapFaultClientException e) { + WebServiceUtils.manageSoapException(e); + } catch (WebServiceIOException e) { + manageIoException(e); + } + } + + public void setTemplate(WebServiceTemplate template) { + this.template = template; + } + + protected void manageIoException(WebServiceIOException e) { + if (!cannotConnect) { + log.error("Cannot connect to " + template.getDefaultUri() + + ". Won't try again.", e); + cannotConnect = true; + } + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/DefaultSRegistry.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/DefaultSRegistry.java new file mode 100644 index 000000000..44b4a7a98 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/DefaultSRegistry.java @@ -0,0 +1,63 @@ +package org.argeo.slc.core.structure; + +import java.util.List; +import java.util.Vector; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** Default implementation of a StructureRegistry. */ +public class DefaultSRegistry implements StructureRegistry { + private static Log log = LogFactory.getLog(DefaultSRegistry.class); + + private List elements = new Vector(); + private List paths = new Vector(); + private String mode = StructureRegistry.ALL; + + private List activePaths; + + public List listElements() { + return new Vector(elements); + } + + public List listPaths() { + return new Vector(paths); + } + + public void register(StructurePath path, StructureElement element) { + StructureElement treeSElement = element; + elements.add(treeSElement); + paths.add(path); + + if (log.isTraceEnabled()) + log.trace("Registered " + path + " (label: '" + + treeSElement.getLabel() + "', position: " + + elements.size() + ")"); + } + + public StructureElement getElement(StructurePath path) { + int index = paths.indexOf(path); + if (index >= 0) { + return elements.get(index); + } else {// not found + return null; + } + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public List getActivePaths() { + return activePaths; + } + + public void setActivePaths(List activePaths) { + this.activePaths = activePaths; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/SimpleSElement.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/SimpleSElement.java new file mode 100644 index 000000000..9faea935f --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/SimpleSElement.java @@ -0,0 +1,69 @@ +package org.argeo.slc.core.structure; + +import java.util.Map; +import java.util.TreeMap; + +import javax.swing.tree.TreeSelectionModel; + +/** + * Basic implementation of StructureElement. + * + * @see TreeSPath + */ +public class SimpleSElement implements StructureElement { + /** For ORM */ + private Long tid; + private String label; + private Map tags = new TreeMap(); + + /** For ORM */ + public SimpleSElement() { + } + + /** Constructor */ + public SimpleSElement(String label) { + this.label = label; + } + + /** Constructor */ + public SimpleSElement(String label, String defaultLabel) { + this(label != null ? label : defaultLabel); + } + + /** Constructor */ + public SimpleSElement(SimpleSElement sElement) { + setLabel(sElement.getLabel()); + setTags(new TreeMap(sElement.getTags())); + } + + public String getLabel() { + return label; + } + + /** Sets the label. */ + public void setLabel(String label) { + this.label = label; + } + + public Long getTid() { + return tid; + } + + void setTid(Long tid) { + this.tid = tid; + } + + public Map getTags() { + return tags; + } + + public void setTags(Map tags) { + this.tags = tags; + } + + @Override + public SimpleSElement clone(){ + return new SimpleSElement(this); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureAware.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureAware.java new file mode 100644 index 000000000..643af73af --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureAware.java @@ -0,0 +1,10 @@ +package org.argeo.slc.core.structure; + +/** + * Wrapper for an element, which is able to propagate registration to + * sub-elements. + */ +public interface StructureAware { + /** Called after registration. */ + public void notifyCurrentPath(StructureRegistry registry, T path); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureElement.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureElement.java new file mode 100644 index 000000000..8e9d15bff --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureElement.java @@ -0,0 +1,10 @@ +package org.argeo.slc.core.structure; + +/** + * Atomic element holding metadata such as description about the element which + * registered. + */ +public interface StructureElement { + /** Label of this element. */ + public String getLabel(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureElementProvider.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureElementProvider.java new file mode 100644 index 000000000..b9aa14452 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureElementProvider.java @@ -0,0 +1,5 @@ +package org.argeo.slc.core.structure; + +public interface StructureElementProvider { + public StructureElement createStructureElement(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructurePath.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructurePath.java new file mode 100644 index 000000000..452dc9514 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructurePath.java @@ -0,0 +1,16 @@ +package org.argeo.slc.core.structure; + +/** + * Path allowing to uniquely identify a StructureElement within a + * registry. + * + * @see StructureElement + * @see StructurePath + */ +public interface StructurePath { + /** + * Unique representation as a string. Most implementation will also provide + * a mean to interpret this string. + */ + public String getAsUniqueString(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureRegistry.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureRegistry.java new file mode 100644 index 000000000..71f80cb77 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/StructureRegistry.java @@ -0,0 +1,57 @@ +package org.argeo.slc.core.structure; + +import java.util.List; + +import org.argeo.slc.core.deploy.DeployedSystem; + +/** Registry where the whole structure is stored. */ +public interface StructureRegistry

{ + /** Read mode: the structure is only read. */ + public static String READ = "READ"; + /** All mode: everything is executed regardless of the active paths. */ + public static String ALL = "ALL"; + /** Active mode: only the active paths are executed. */ + public static String ACTIVE = "STATUS_ACTIVE"; + + /** Adds an element to the registry. */ + public void register(P path, StructureElement element); + + /** Lists all registered elements. */ + public List listElements(); + + /** Lists all registered elements. */ + public List

listPaths(); + + /** Gets a element based on its path. */ + public T getElement(P path); + + /** + * Set the interpreter mode: read, all or active. + * + * @see #READ + * @see #ALL + * @see #STATUS_ACTIVE + */ + public void setMode(String mode); + + /** + * Gets the current interpreter mode. + * + * @see #READ + * @see #ALL + * @see #STATUS_ACTIVE + */ + public String getMode(); + + /** + * Gets the list of active paths, which will be run if executed in + * STATUS_ACTIVE mode. + */ + public List

getActivePaths(); + + /** + * Sets the list of active path, which will be run if executed in + * STATUS_ACTIVE mode. + */ + public void setActivePaths(List

activePaths); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/package.html new file mode 100644 index 000000000..d9bab8a55 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/package.html @@ -0,0 +1,6 @@ + + + +SLC Structure framework allowing to uniquely reference actions. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSPath.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSPath.java new file mode 100644 index 000000000..a31239f83 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSPath.java @@ -0,0 +1,205 @@ +package org.argeo.slc.core.structure.tree; + +import java.util.List; +import java.util.StringTokenizer; +import java.util.Vector; + +import org.argeo.slc.core.SlcException; +import org.argeo.slc.core.structure.StructurePath; +import org.argeo.slc.core.structure.StructureRegistry; + +/** + * Path for tree based StructureRegistry implementations. + */ +public class TreeSPath implements StructurePath, Comparable { + /** Default character to use a separator: /. */ + private static Character DEFAULT_SEPARATOR = '/'; + + private Character separator = DEFAULT_SEPARATOR; + + private String asUniqueString; + + /** For ORM */ + private Long tid; + + public TreeSPath() { + + } + + public TreeSPath(String asUniqueString) { + this.asUniqueString = checkAndFormatPath(asUniqueString); + } + + public String getAsUniqueString() { + return asUniqueString; + } + + /** + * Sets all the required data from a string. ATTENTION: the path is + * not checked for performance reason. This method should be used only by + * ORM/OXM frameworks. Use constructor to create immutable tree structure + * paths. + */ + public void setAsUniqueString(String str) { + this.asUniqueString = str; + } + + /** The separator actually used by this path. */ + public Character getSeparator() { + return separator; + } + + /** Gets the parent path. */ + public TreeSPath getParent() { + int lastSep = getAsUniqueString().lastIndexOf(separator); + if (lastSep < 1) { + return null; + } + String parentUniqueString = getAsUniqueString().substring(0, lastSep); + return new TreeSPath(parentUniqueString); + } + + /** Gets the name part of the path. */ + public String getName() { + int lastSep = getAsUniqueString().lastIndexOf(separator); + return getAsUniqueString().substring(lastSep+1); + } + + /** Create a path without parent. */ + public static TreeSPath createRootPath(String name) { + if (name.indexOf(DEFAULT_SEPARATOR) >= 0) { + throw new SlcException("Name cannot contain " + DEFAULT_SEPARATOR); + } + return new TreeSPath('/' + name); + } + + /** Create a child . */ + public TreeSPath createChild(String name) { + if (name.indexOf(separator) > -1) { + throw new SlcException("Tree path name '" + name + + "' contains separator character " + separator); + } + return new TreeSPath(getAsUniqueString() + '/' + name); + } + + /** + * Parses a string to a path. + * + * @deprecated use constructor instead + */ + public static TreeSPath parseToCreatePath(String path) { + return parseToCreatePath(path, DEFAULT_SEPARATOR); + } + + protected String checkAndFormatPath(String str) { + if (str.length() < 2) { + throw new SlcException("Path " + str + " is not short"); + } + if (str.charAt(0) != separator) { + throw new SlcException("Path " + str + " have to start with " + + separator); + } + + StringBuffer buf = new StringBuffer(str.length() + 5); + StringTokenizer st = new StringTokenizer(str, separator.toString()); + while (st.hasMoreTokens()) { + buf.append(separator).append(st.nextToken()); + } + return buf.toString(); + } + + /** + * Parses a string to a path. + * + * @deprecated use constructor instead + */ + public static TreeSPath parseToCreatePath(String path, Character separator) { + return new TreeSPath(path); + } + + /** Lists the children from a registry. */ + public List listChildren(StructureRegistry registry) { + return listChildrenPaths(registry, this); + } + + /** Lists the children from a given path from a registry. */ + public static List listChildrenPaths( + StructureRegistry registry, TreeSPath path) { + List paths = new Vector(); + List allPaths = registry.listPaths(); + for (TreeSPath pathT : allPaths) { + if (pathT.getParent() != null && pathT.getParent().equals(path)) { + paths.add(pathT); + } + } + return paths; + } + + /** Gets the root tree path of this path. */ + public TreeSPath getRoot() { + TreeSPath root = this; + while (root.getParent() != null) { + root = root.getParent(); + } + return root; + } + + /** Depth of this path. */ + public Integer getDepth() { + return depthImpl(this); + } + + protected int depthImpl(TreeSPath path) { + if (path.getParent() == null) { + return 1; + } else { + return depthImpl(path.getParent()) + 1; + } + } + + public List getHierarchyAsList() { + List lst = new Vector(); + addParentToList(lst, this); + lst.add(this); + return lst; + } + + protected void addParentToList(List lst, TreeSPath current) { + TreeSPath parent = current.getParent(); + if (parent != null) { + addParentToList(lst, parent); + lst.add(parent); + } + } + + @Override + public String toString() { + return getAsUniqueString(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof StructurePath) { + StructurePath path = (StructurePath) obj; + return getAsUniqueString().equals(path.getAsUniqueString()); + } + return false; + } + + @Override + public int hashCode() { + return getAsUniqueString().hashCode(); + } + + public int compareTo(StructurePath o) { + return getAsUniqueString().compareTo(o.getAsUniqueString()); + } + + public Long getTid() { + return tid; + } + + void setTid(Long tid) { + this.tid = tid; + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSRegistry.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSRegistry.java new file mode 100644 index 000000000..10125678c --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSRegistry.java @@ -0,0 +1,95 @@ +package org.argeo.slc.core.structure.tree; + +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.Vector; + +import org.argeo.slc.core.UnsupportedException; +import org.argeo.slc.core.structure.SimpleSElement; +import org.argeo.slc.core.structure.StructureElement; +import org.argeo.slc.core.structure.StructureRegistry; + +/** Tree based implementation of a structure registry. */ +public class TreeSRegistry implements StructureRegistry { + public final static String STATUS_ACTIVE = "STATUS_ACTIVE"; + + /** For ORM */ + private Long tid; + private String status; + private Map elements = new TreeMap(); + + private String mode = StructureRegistry.ALL; + + private List activePaths; + + public T getElement(TreeSPath path) { + return (T)elements.get(path); + } + + public List listElements() { + return new Vector(elements.values()); + } + + public List listPaths() { + return new Vector(elements.keySet()); + } + + public void register(TreeSPath path, StructureElement element) { + final SimpleSElement simpleSElement; + if (element instanceof SimpleSElement) { + simpleSElement = (SimpleSElement) element; + } else { + simpleSElement = new SimpleSElement(element.getLabel()); + } + + if (path == null) + throw new UnsupportedException("Path cannot be null."); + + elements.put(path, simpleSElement); + + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public List getActivePaths() { + return activePaths; + } + + public void setActivePaths(List activePaths) { + this.activePaths = activePaths; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + /** Gets the elements. */ + public Map getElements() { + return elements; + } + + /** Sets the elements (for ORM). */ + public void setElements(Map elements) { + this.elements = elements; + } + + Long getTid() { + return tid; + } + + void setTid(Long tid) { + this.tid = tid; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSRelated.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSRelated.java new file mode 100644 index 000000000..f939fbc12 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSRelated.java @@ -0,0 +1,11 @@ +package org.argeo.slc.core.structure.tree; + +import org.argeo.slc.core.structure.StructureAware; +import org.argeo.slc.core.structure.StructureElement; +import org.argeo.slc.core.structure.StructureRegistry; + +public interface TreeSRelated extends StructureAware{ + public TreeSPath getBasePath(); + public StructureRegistry getRegistry(); + public StructureElement getStructureElement(String key); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSRelatedHelper.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSRelatedHelper.java new file mode 100644 index 000000000..acc829c36 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/TreeSRelatedHelper.java @@ -0,0 +1,32 @@ +package org.argeo.slc.core.structure.tree; + +import org.argeo.slc.core.structure.SimpleSElement; +import org.argeo.slc.core.structure.StructureElement; +import org.argeo.slc.core.structure.StructureRegistry; + +/** + * Provides default implementations of some methods of TreeSRelated. + */ +public abstract class TreeSRelatedHelper implements TreeSRelated { + private TreeSPath basePath; + private StructureRegistry registry; + + public TreeSPath getBasePath() { + return basePath; + } + + public StructureRegistry getRegistry() { + return registry; + } + + public void notifyCurrentPath(StructureRegistry registry, + TreeSPath path) { + basePath = path; + this.registry = registry; + } + + public StructureElement getStructureElement(String key) { + return new SimpleSElement(key); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/package.html new file mode 100644 index 000000000..a2a51e4d9 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/structure/tree/package.html @@ -0,0 +1,6 @@ + + + +Tree-based implementation of the SLC structure framework. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/BasicTestData.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/BasicTestData.java new file mode 100644 index 000000000..a8ee46cbf --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/BasicTestData.java @@ -0,0 +1,24 @@ +package org.argeo.slc.core.test; + + +public class BasicTestData implements TestData { + private Object expected; + private Object reached; + + public Object getExpected() { + return expected; + } + + public void setExpected(Object expected) { + this.expected = expected; + } + + public Object getReached() { + return reached; + } + + public void setReached(Object reached) { + this.reached = reached; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/BasicTestDefinition.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/BasicTestDefinition.java new file mode 100644 index 000000000..1178b41ec --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/BasicTestDefinition.java @@ -0,0 +1,36 @@ +package org.argeo.slc.core.test; + +import org.argeo.slc.core.structure.tree.TreeSRelatedHelper; +import org.argeo.slc.core.test.context.ContextAware; +import org.argeo.slc.core.test.context.ContextUtils; + +/** Understands basic test data and context aware test data. */ +public class BasicTestDefinition extends TreeSRelatedHelper implements + TestDefinition { + + public void execute(TestRun testRun) { + if (testRun. getTestData() instanceof BasicTestData) { + BasicTestData testData = testRun.getTestData(); + TestResult result = testRun.getTestResult(); + + try { + if (testData.getExpected().equals(testData.getReached())) { + result.addResultPart(new SimpleResultPart( + TestStatus.PASSED, "Reached and expected equals")); + } else { + result.addResultPart(new SimpleResultPart( + TestStatus.FAILED, "Expected " + + testData.getExpected() + " but reched " + + testData.getReached())); + } + } catch (Exception e) { + result.addResultPart(new SimpleResultPart(TestStatus.ERROR, + "Could not compare", e)); + } + } else if (testRun. getTestData() instanceof ContextAware) { + TestData testData = testRun.getTestData(); + ContextUtils.compareReachedExpected((ContextAware) testData, + testRun.getTestResult(), this); + } + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/ExecutableTestRun.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/ExecutableTestRun.java new file mode 100644 index 000000000..34216799f --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/ExecutableTestRun.java @@ -0,0 +1,9 @@ +package org.argeo.slc.core.test; + +/** A test run that can be executed */ +public interface ExecutableTestRun extends TestRun { + + /** Executes this test run. */ + public void execute(); + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/IncompatibleTestDataException.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/IncompatibleTestDataException.java new file mode 100644 index 000000000..db4184d05 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/IncompatibleTestDataException.java @@ -0,0 +1,18 @@ +package org.argeo.slc.core.test; + +import org.argeo.slc.core.SlcException; + +/** + * Exception to throw when a test definition cannot interpret the provided test + * data. + */ +public class IncompatibleTestDataException extends SlcException { + static final long serialVersionUID = 1l; + + public IncompatibleTestDataException(TestData testData, + TestDefinition testDefinition) { + super("TestData " + testData.getClass() + + " is not compatible with TestDefinition " + + testDefinition.getClass()); + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/NumericTRId.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/NumericTRId.java new file mode 100644 index 000000000..0b1674ae9 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/NumericTRId.java @@ -0,0 +1,71 @@ +package org.argeo.slc.core.test; + +import org.argeo.slc.core.deploy.DeployedSystemId; + +/** + * Basic implementation of test run id based on a long value and a reference to + * a deployed system id. + * + * @deprecated + */ +public class NumericTRId implements TestResultId { + /** For ORM */ + private Long tid; + + private Long value; + private DeployedSystemId deployedSystemId; + + /** For ORM */ + public NumericTRId() { + + } + + public NumericTRId(Long value) { + this.value = value; + } + + /** + * Initializes the long value with the current time (based on + * java.lang.System.currentTimeMillis()). + */ + public void init() { + if (getValue() == null) { + setValue(System.currentTimeMillis()); + } + } + + public Long getValue() { + return value; + } + + public void setValue(Long value) { + this.value = value; + } + + public DeployedSystemId getDeployedSystemId() { + return deployedSystemId; + } + + public void setDeployedSystemId(DeployedSystemId deployedSystemId) { + this.deployedSystemId = deployedSystemId; + } + + @Override + public boolean equals(Object obj) { + return value.toString().equals(obj.toString()); + } + + @Override + public String toString() { + return value.toString(); + } + + Long getTid() { + return tid; + } + + void setTid(Long tid) { + this.tid = tid; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SimpleResultPart.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SimpleResultPart.java new file mode 100644 index 000000000..e114e1f6d --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SimpleResultPart.java @@ -0,0 +1,128 @@ +package org.argeo.slc.core.test; + +/** + *

+ * Basic implementation of a result part, implementing the standard three status + * approach for test results. + *

+ * + * @see TestStatus + */ +public class SimpleResultPart implements TestResultPart, TestStatus, + TestRunAware { + + /** @deprecated */ + private Long tid; + + private String testRunUuid; + + /** The status. Default to ERROR since it should always be explicitely set. */ + private Integer status = ERROR; + private String message; + private String exceptionMessage; + + public SimpleResultPart() { + } + + public SimpleResultPart(Integer status, String message) { + this(status, message, null); + } + + public SimpleResultPart(Integer status, String message, Exception exception) { + this.status = status; + this.message = message; + setException(exception); + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Integer getStatus() { + return status; + } + + public String getExceptionMessage() { + return exceptionMessage; + } + + public void setException(Exception exception) { + if (exception == null) + return; + + StringBuffer buf = new StringBuffer(""); + buf.append(exception.toString()); + buf.append('\n'); + for (StackTraceElement elem : exception.getStackTrace()) { + buf.append('\t').append(elem.toString()).append('\n'); + } + + if (exception.getCause() != null) + addRootCause(buf, exception.getCause()); + + this.exceptionMessage = buf.toString(); + } + + protected void addRootCause(StringBuffer buf, Throwable cause) { + if (cause == null) + return; + + buf.append("Caused by: " + cause.getMessage()); + for (StackTraceElement elem : cause.getStackTrace()) { + buf.append('\t').append(elem.toString()).append('\n'); + } + + if (cause.getCause() != null) { + addRootCause(buf, cause.getCause()); + } + } + + @Override + public String toString() { + StringBuffer buf = new StringBuffer(""); + buf.append(SlcTestUtils.statusToString(status)); + if (status == PASSED || status == FAILED) { + buf.append(' '); + } else if (status == ERROR) { + buf.append(" "); + } + buf.append(message); + return buf.toString(); + } + + /** @deprecated */ + Long getTid() { + return tid; + } + + /** @deprecated */ + void setTid(Long tid) { + this.tid = tid; + } + + public String getTestRunUuid() { + return testRunUuid; + } + + /** For ORM */ + public void setTestRunUuid(String testRunUuid) { + this.testRunUuid = testRunUuid; + } + + public void notifyTestRun(TestRun testRun) { + testRunUuid = testRun.getUuid(); + } + + public void setExceptionMessage(String exceptionMessage) { + this.exceptionMessage = exceptionMessage; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SimpleTestResult.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SimpleTestResult.java new file mode 100644 index 000000000..c1d783a77 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SimpleTestResult.java @@ -0,0 +1,74 @@ +package org.argeo.slc.core.test; + +import java.util.Date; +import java.util.List; +import java.util.UUID; +import java.util.Vector; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.core.SlcException; + +/** + * Basic implementation of a test result containing only a list of result parts. + */ +public class SimpleTestResult implements TestResult { + private static Log log = LogFactory.getLog(SimpleTestResult.class); + + private String uuid; + private String currentTestRunUuid; + + private Boolean throwError = true; + + private Date closeDate; + private List parts = new Vector(); + + public void addResultPart(TestResultPart part) { + if (throwError && part.getStatus() == ERROR) { + throw new SlcException( + "There was an error in the underlying test: " + + part.getExceptionMessage()); + } + parts.add(part); + if (log.isDebugEnabled()) + log.debug(part); + } + + public void close() { + parts.clear(); + closeDate = new Date(); + } + + public List getParts() { + return parts; + } + + public Date getCloseDate() { + return closeDate; + } + + public void setThrowError(Boolean throwError) { + this.throwError = throwError; + } + + public void notifyTestRun(TestRun testRun) { + currentTestRunUuid = testRun.getUuid(); + } + + public String getUuid() { + if (uuid == null) { + uuid = UUID.randomUUID().toString(); + } + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getCurrentTestRunUuid() { + return currentTestRunUuid; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SimpleTestRun.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SimpleTestRun.java new file mode 100644 index 000000000..e2ab043cf --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SimpleTestRun.java @@ -0,0 +1,96 @@ +package org.argeo.slc.core.test; + +import java.util.UUID; + +import org.argeo.slc.core.deploy.DeployedSystem; +import org.argeo.slc.core.process.SlcExecution; +import org.argeo.slc.core.process.SlcExecutionStep; + +/** + * A basic bean implementation of a WritableTestRun, holding + * references to the various parts of a test run. + */ +public class SimpleTestRun implements WritableTestRun, ExecutableTestRun { + private String uuid; + + private String slcExecutionUuid; + private String slcExecutionStepUuid; + + private DeployedSystem deployedSystem; + private TestData testData; + private TestDefinition testDefinition; + private TestResult testResult; + + /** Executes the underlying test definition. */ + public void execute() { + uuid = UUID.randomUUID().toString(); + if (testResult != null) + testResult.notifyTestRun(this); + testDefinition.execute(this); + } + + public T getDeployedSystem() { + return (T) deployedSystem; + } + + public void setDeployedSystem(DeployedSystem deployedSystem) { + this.deployedSystem = deployedSystem; + } + + public T getTestData() { + return (T) testData; + } + + public void setTestData(TestData testData) { + this.testData = testData; + } + + public T getTestDefinition() { + return (T) testDefinition; + } + + public void setTestDefinition(TestDefinition testDefinition) { + this.testDefinition = testDefinition; + } + + public T getTestResult() { + return (T) testResult; + } + + public void setTestResult(TestResult testResult) { + this.testResult = testResult; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getSlcExecutionUuid() { + return slcExecutionUuid; + } + + public void setSlcExecutionUuid(String slcExecutionUuid) { + this.slcExecutionUuid = slcExecutionUuid; + } + + public String getSlcExecutionStepUuid() { + return slcExecutionStepUuid; + } + + public void setSlcExecutionStepUuid(String slcExecutionStepUuid) { + this.slcExecutionStepUuid = slcExecutionStepUuid; + } + + public void notifySlcExecution(SlcExecution slcExecution) { + slcExecutionUuid = slcExecution.getUuid(); + SlcExecutionStep step = slcExecution.currentStep(); + if (step != null) { + slcExecutionStepUuid = step.getUuid(); + } + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SlcTestUtils.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SlcTestUtils.java new file mode 100644 index 000000000..c7d7840cd --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/SlcTestUtils.java @@ -0,0 +1,40 @@ +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(){ + + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestData.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestData.java new file mode 100644 index 000000000..4105e0925 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestData.java @@ -0,0 +1,9 @@ +package org.argeo.slc.core.test; + +/** + * Any data required by a test in order to run: configuration, expected, + * reached, etc. + */ +public interface TestData { + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestDataProvider.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestDataProvider.java new file mode 100644 index 000000000..e0e02c3a6 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestDataProvider.java @@ -0,0 +1,5 @@ +package org.argeo.slc.core.test; + +public interface TestDataProvider { + public T getTestData(Class clss, String key); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestDataUtils.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestDataUtils.java new file mode 100644 index 000000000..66cae87c3 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestDataUtils.java @@ -0,0 +1,45 @@ +package org.argeo.slc.core.test; + +import org.argeo.slc.core.UnsupportedException; + +/** Utilities for dealing with test datas. */ +public class TestDataUtils { + /** Extracts the test data from the given provider. */ + public static T getFromProvider(Object obj, + Class clss, String key) { + if (obj instanceof TestDataProvider) { + TestDataProvider testDataProvider = (TestDataProvider) obj; + return testDataProvider.getTestData(clss, key); + } else { + throw new UnsupportedException("test data provider", obj); + } + } + + /** + * Extracts the test data from the given provider using null + * as key. + */ + public static T getFromProvider(Object obj, + Class clss) { + return getFromProvider(obj, clss, null); + } + + /** + * Returns it self after making the proper checks. Used for test data being + * their own data providers. + */ + public static T getItSelf(Class clss, + TestData testDataObject) { + if (clss.isAssignableFrom(testDataObject.getClass())) { + return (T) testDataObject; + } else { + throw new UnsupportedException("test data", testDataObject); + } + + } + + /** Makes sure this is an utility class. */ + private TestDataUtils() { + + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestDefinition.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestDefinition.java new file mode 100644 index 000000000..7c75d6a73 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestDefinition.java @@ -0,0 +1,10 @@ +package org.argeo.slc.core.test; + +/** + * The programmatic definition of a test, which will be associated with + * transient objects within a test run. + */ +public interface TestDefinition extends TestStatus { + /** Performs the test. */ + public void execute(TestRun testRun); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestReport.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestReport.java new file mode 100644 index 000000000..8256e8644 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestReport.java @@ -0,0 +1,10 @@ +package org.argeo.slc.core.test; + +/** + * A report that can be generated based on a given test result. This + * interface may change in the future. + */ +public interface TestReport { + /** Performs the actions necessary to generate a report. */ + public void generateTestReport(TestResult result); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResult.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResult.java new file mode 100644 index 000000000..5aa1c6193 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResult.java @@ -0,0 +1,23 @@ +package org.argeo.slc.core.test; + +import java.util.Date; + +/** The result of a test */ +public interface TestResult extends TestStatus, TestRunAware { + public String getUuid(); + + /** Adds a part of the result. */ + public void addResultPart(TestResultPart part); + + /** + * Marks that the collection of test results is completed and free the + * related resources (also closing listeners). + */ + public void close(); + + /** + * The date when this test result was closed. Can be null, which means the + * result is not closed. + */ + public Date getCloseDate(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResultId.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResultId.java new file mode 100644 index 000000000..46af52799 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResultId.java @@ -0,0 +1,14 @@ +package org.argeo.slc.core.test; + +import org.argeo.slc.core.deploy.DeployedSystemId; + +/** + * The unique id referencing a test result. + * + * @deprecated + */ +public interface TestResultId { + /** Gets the id of the related deployed system. */ + public DeployedSystemId getDeployedSystemId(); + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResultListener.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResultListener.java new file mode 100644 index 000000000..c42d783d0 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResultListener.java @@ -0,0 +1,11 @@ +package org.argeo.slc.core.test; + +/** Listener to the operations on a test result. */ +public interface TestResultListener { + /** Notified when a part was added to a test result. */ + public void resultPartAdded(T testResult, + TestResultPart testResultPart); + + /** Stops listening and release the related resources. */ + public void close(T testResult); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResultPart.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResultPart.java new file mode 100644 index 000000000..fc5749b86 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestResultPart.java @@ -0,0 +1,18 @@ +package org.argeo.slc.core.test; + + +/** + * Part of a test result. + * + * @see TestResult + */ +public interface TestResultPart { + /** The status, as defined in {@link TestStatus}. */ + public Integer getStatus(); + + /** The related message. */ + public String getMessage(); + + /** The underlying Exception. Can be null. */ + public String getExceptionMessage(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestRun.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestRun.java new file mode 100644 index 000000000..5a4ac50b6 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestRun.java @@ -0,0 +1,22 @@ +package org.argeo.slc.core.test; + +import org.argeo.slc.core.deploy.DeployedSystem; +import org.argeo.slc.core.process.SlcExecutionAware; + +/** The actual run of a test */ +public interface TestRun extends SlcExecutionAware{ + /** Gets UUID */ + public String getUuid(); + + /** Gets the related test definition. */ + public T getTestDefinition(); + + /** Gets the related test data */ + public T getTestData(); + + /** Gets the related deployed system. */ + public T getDeployedSystem(); + + /** Gets the related result where to record results. */ + public T getTestResult(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestRunAware.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestRunAware.java new file mode 100644 index 000000000..6cca1440e --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestRunAware.java @@ -0,0 +1,7 @@ +package org.argeo.slc.core.test; + +public interface TestRunAware { + /** Notifies the current test run. */ + public void notifyTestRun(TestRun testRun); + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestRunDescriptor.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestRunDescriptor.java new file mode 100644 index 000000000..d48ea2db9 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestRunDescriptor.java @@ -0,0 +1,82 @@ +package org.argeo.slc.core.test; + +import org.argeo.slc.core.deploy.DeployedSystem; +import org.argeo.slc.core.process.SlcExecution; + +public class TestRunDescriptor { + private String testRunUuid; + private String slcExecutionUuid; + private String slcExecutionStepUuid; + private String testResultUuid; + private String deployedSytemId; + + public TestRunDescriptor() { + + } + + public TestRunDescriptor(TestRun testRun) { + testRunUuid = testRun.getUuid(); + + if (testRun.getTestResult() != null) + testResultUuid = testRun. getTestResult().getUuid(); + + if (testRun.getDeployedSystem() != null) + deployedSytemId = testRun. getDeployedSystem() + .getDeployedSystemId(); + + if (testRun instanceof SimpleTestRun) { + slcExecutionUuid = ((SimpleTestRun) testRun).getSlcExecutionUuid(); + slcExecutionStepUuid = ((SimpleTestRun) testRun) + .getSlcExecutionStepUuid(); + } + } + + public String getTestRunUuid() { + return testRunUuid; + } + + public void setTestRunUuid(String testRunUuid) { + this.testRunUuid = testRunUuid; + } + + public String getSlcExecutionUuid() { + return slcExecutionUuid; + } + + public void setSlcExecutionUuid(String slcExecutionUuid) { + this.slcExecutionUuid = slcExecutionUuid; + } + + public String getSlcExecutionStepUuid() { + return slcExecutionStepUuid; + } + + public void setSlcExecutionStepUuid(String slcExecutionStepUuid) { + this.slcExecutionStepUuid = slcExecutionStepUuid; + } + + public String getTestResultUuid() { + return testResultUuid; + } + + public void setTestResultUuid(String testResultUuid) { + this.testResultUuid = testResultUuid; + } + + public String getDeployedSytemId() { + return deployedSytemId; + } + + public void setDeployedSytemId(String deploymentId) { + this.deployedSytemId = deploymentId; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof TestRunDescriptor) { + return getTestRunUuid().equals( + ((TestRunDescriptor) obj).getTestRunUuid()); + } + return false; + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestStatus.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestStatus.java new file mode 100644 index 000000000..d6954be8f --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/TestStatus.java @@ -0,0 +1,29 @@ +package org.argeo.slc.core.test; + +/** + * Simple statuses. + *

+ *

    + *
  • {@link #PASSED}: the test succeeded
  • + *
  • {@link #FAILED}: the test could run, but did not reach the expected + * result
  • + *
  • {@link #ERROR}: an error during the test run prevented to get a + * significant information on the tested system.
  • + *
+ *

+ */ +public interface TestStatus { + /** The flag for a passed test: 0 */ + public final static Integer PASSED = 0; + /** The flag for a failed test: 1 */ + public final static Integer FAILED = 1; + /** + * The flag for a test which could not properly run because of an error + * (there is no feedback on the behavior of the tested component): 2 + */ + public final static Integer ERROR = 2; + public final static String STATUSSTR_PASSED = "PASSED"; + public final static String STATUSSTR_FAILED = "FAILED"; + public final static String STATUSSTR_ERROR = "ERROR"; + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/WritableTestRun.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/WritableTestRun.java new file mode 100644 index 000000000..8cfe2b72c --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/WritableTestRun.java @@ -0,0 +1,14 @@ +package org.argeo.slc.core.test; + +import org.argeo.slc.core.deploy.DeployedSystem; + +/** Test run whose various components can be externally set. */ +public interface WritableTestRun extends ExecutableTestRun { + public void setDeployedSystem(DeployedSystem deployedSystem); + + public void setTestData(TestData testData); + + public void setTestDefinition(TestDefinition testDefinition); + + public void setTestResult(TestResult testResult); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/ContextAware.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/ContextAware.java new file mode 100644 index 000000000..5e411831e --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/ContextAware.java @@ -0,0 +1,18 @@ +package org.argeo.slc.core.test.context; + +import java.util.Map; + +public interface ContextAware { + public final static String DEFAULT_SKIP_FLAG = "!"; + public final static String DEFAULT_ANY_FLAG = "*"; + + public Map getValues(); + + public void setValues(Map values); + + public Map getExpectedValues(); + + public String getContextSkipFlag(); + + public String getContextAnyFlag(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/ContextUtils.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/ContextUtils.java new file mode 100644 index 000000000..3826a8710 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/ContextUtils.java @@ -0,0 +1,165 @@ +package org.argeo.slc.core.test.context; + +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.structure.StructureAware; +import org.argeo.slc.core.structure.StructureElement; +import org.argeo.slc.core.structure.StructureRegistry; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.structure.tree.TreeSRelated; +import org.argeo.slc.core.test.SimpleResultPart; +import org.argeo.slc.core.test.TestResult; +import org.argeo.slc.core.test.TestStatus; + +public class ContextUtils { + private final static Log log = LogFactory.getLog(ContextUtils.class); + + public static void compareReachedExpected(ContextAware contextAware, + TestResult testResult, TreeSRelated treeSRelated) { + for (String key : contextAware.getExpectedValues().keySet()) { + + // Compare expected values with reached ones + Object expectedValue = contextAware.getExpectedValues().get(key); + + if (expectedValue.toString().equals( + contextAware.getContextSkipFlag())) { + if (log.isDebugEnabled()) + log.debug("Skipped check for key '" + key + "'"); + continue; + } + + // Register in structure + registerInStructure(testResult, treeSRelated, key); + + if (contextAware.getValues().containsKey(key)) { + Object reachedValue = contextAware.getValues().get(key); + + if (expectedValue.equals(contextAware.getContextAnyFlag())) { + testResult.addResultPart(new SimpleResultPart( + TestStatus.PASSED, "Expected any value for key '" + + key + "'")); + } else if (expectedValue.equals(reachedValue)) { + testResult.addResultPart(new SimpleResultPart( + TestStatus.PASSED, "Values matched for key '" + key + + "'")); + } else { + testResult.addResultPart(new SimpleResultPart( + TestStatus.FAILED, "Mismatch for key '" + key + + "': expected '" + expectedValue + + "' but reached '" + reachedValue + "'")); + } + } else { + testResult.addResultPart(new SimpleResultPart( + TestStatus.FAILED, "No value reached for key '" + key + + "'")); + } + resetStructure(testResult, treeSRelated); + } + } + + private static void registerInStructure(TestResult testResult, + TreeSRelated treeSRelated, String key) { + if (treeSRelated != null) { + if (treeSRelated.getBasePath() != null) { + TreeSPath path = treeSRelated.getBasePath().createChild(key); + StructureRegistry registry = treeSRelated + .getRegistry(); + final StructureElement element = treeSRelated + .getStructureElement(key); + registry.register(path, element); + if (testResult instanceof StructureAware) + ((StructureAware) testResult).notifyCurrentPath( + registry, path); + + if (log.isDebugEnabled()) + log.debug("Checking key " + key + " for path " + path); + } + } + } + + private static void resetStructure(TestResult testResult, + TreeSRelated treeSRelated) { + if (treeSRelated != null) { + if (treeSRelated.getBasePath() != null) { + if (testResult instanceof StructureAware) { + ((StructureAware) testResult).notifyCurrentPath( + treeSRelated.getRegistry(), treeSRelated + .getBasePath()); + } + } + } + } + + /** + * Makes sure that all children and sub-children of parent share the same + * maps for values and expected values. + */ + public static void synchronize(ParentContextAware parent) { + Map expectedValuesCommon = new TreeMap( + parent.getExpectedValues()); + synchronize(parent, expectedValuesCommon); + if (log.isDebugEnabled()) + log.debug("Synchonized context " + parent); + + } + + private static void synchronize(ParentContextAware parent, + Map expectedValuesCommon) { + for (ContextAware child : parent.getChildContexts()) { + // Values + putNotContained(parent.getValues(), child.getValues()); + child.setValues(parent.getValues()); + + // Expected Values + // Expected values reference is not overridden: each child has its + // own expected values map. + overrideContained(expectedValuesCommon, child.getExpectedValues()); + + // Creates a new Map in order not to disturb other context using the + // same keys + Map expectedValuesCommonChild = new TreeMap( + expectedValuesCommon); + putNotContained(expectedValuesCommonChild, child + .getExpectedValues()); + + if (child instanceof ParentContextAware) { + // Recursive sync + synchronize((ParentContextAware) child, + expectedValuesCommonChild); + } + } + + } + + /** + * Put into common map the values from child map which are not already + * defined in common map. + */ + public static void putNotContained(Map commonMap, + Map childMap) { + for (String key : childMap.keySet()) { + if (!commonMap.containsKey(key)) { + commonMap.put(key, childMap.get(key)); + } + } + } + + /** Overrides child map values with the values already set in common map */ + public static void overrideContained(Map commonMap, + Map childMap) { + for (String key : childMap.keySet()) { + if (commonMap.containsKey(key)) { + childMap.put(key, commonMap.get(key)); + } + } + } + + /** Makes sure this cannot be instantiated. */ + private ContextUtils() { + + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/DefaultContextTestData.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/DefaultContextTestData.java new file mode 100644 index 000000000..a39a91539 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/DefaultContextTestData.java @@ -0,0 +1,14 @@ +package org.argeo.slc.core.test.context; + +import org.argeo.slc.core.test.TestData; +import org.argeo.slc.core.test.TestDataProvider; +import org.argeo.slc.core.test.TestDataUtils; + +public class DefaultContextTestData extends SimpleContextAware implements + TestData, TestDataProvider { + + public T getTestData(Class clss, String key) { + return TestDataUtils.getItSelf(clss, this); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/ParentContextAware.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/ParentContextAware.java new file mode 100644 index 000000000..a8fc8b2be --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/ParentContextAware.java @@ -0,0 +1,8 @@ +package org.argeo.slc.core.test.context; + +import java.util.Collection; + +public interface ParentContextAware extends ContextAware { + public Collection getChildContexts(); + public void addChildContext(ContextAware contextAware); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/SimpleContextAware.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/SimpleContextAware.java new file mode 100644 index 000000000..c4fb5ab40 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/SimpleContextAware.java @@ -0,0 +1,69 @@ +package org.argeo.slc.core.test.context; + +import java.util.Map; +import java.util.TreeMap; + +import org.springframework.beans.factory.InitializingBean; + +import org.argeo.slc.core.SlcException; + +public class SimpleContextAware implements ContextAware, InitializingBean { + private ParentContextAware parentContext; + + private Map values = new TreeMap(); + private Map expectedValues = new TreeMap(); + + private String contextSkipFlag = DEFAULT_SKIP_FLAG; + private String contextAnyFlag = DEFAULT_ANY_FLAG; + + public Map getValues() { + return values; + } + + public void setValues(Map values) { + this.values = values; + } + + public Map getExpectedValues() { + return expectedValues; + } + + public void setExpectedValues(Map expectedValues) { + this.expectedValues = expectedValues; + } + + /** Used to add this context as a child by setting a property. */ + public void setParentContext(ParentContextAware parentContextAware) { + if (parentContext != null) + throw new SlcException("Parent context already set"); + this.parentContext = parentContextAware; + this.parentContext.addChildContext(this); + } + + protected ParentContextAware getParentContext() { + return parentContext; + } + + public void afterPropertiesSet() throws Exception { + if (parentContext != null) { + ContextUtils.synchronize(parentContext); + } + } + + public String getContextSkipFlag() { + return contextSkipFlag; + } + + public void setContextSkipFlag(String contextSkipFlag) { + this.contextSkipFlag = contextSkipFlag; + } + + public String getContextAnyFlag() { + return contextAnyFlag; + } + + public void setContextAnyFlag(String contextAnyFlag) { + this.contextAnyFlag = contextAnyFlag; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/SimpleParentContextAware.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/SimpleParentContextAware.java new file mode 100644 index 000000000..2dfa12346 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/SimpleParentContextAware.java @@ -0,0 +1,33 @@ +package org.argeo.slc.core.test.context; + +import java.util.Collection; +import java.util.List; +import java.util.Vector; + +import org.springframework.beans.factory.InitializingBean; + +public class SimpleParentContextAware extends SimpleContextAware implements + ParentContextAware, InitializingBean { + private List children = new Vector(); + + public Collection getChildContexts() { + return children; + } + + public void addChildContext(ContextAware contextAware) { + children.add(contextAware); + } + + @Override + public void afterPropertiesSet() throws Exception { + if (getParentContext() != null) { + // If has a parent, sync it. + super.afterPropertiesSet(); + } else { + if(children.size()>0){ + // No need to synchronize if no children + ContextUtils.synchronize(this); + } + } + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/package.html new file mode 100644 index 000000000..cd08d63f3 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/context/package.html @@ -0,0 +1,6 @@ + + + +Context variables to be passed between parts of tests. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/package.html new file mode 100644 index 000000000..c70d2d151 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/package.html @@ -0,0 +1,6 @@ + + + +SLC Test: test of software systems. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/CompositeTreeTestDefinition.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/CompositeTreeTestDefinition.java new file mode 100644 index 000000000..f26c08580 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/CompositeTreeTestDefinition.java @@ -0,0 +1,90 @@ +package org.argeo.slc.core.test.tree; + +import java.util.List; +import java.util.Vector; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.core.structure.SimpleSElement; +import org.argeo.slc.core.structure.StructureAware; +import org.argeo.slc.core.structure.StructureElement; +import org.argeo.slc.core.structure.StructureElementProvider; +import org.argeo.slc.core.structure.StructurePath; +import org.argeo.slc.core.structure.StructureRegistry; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.test.TestDefinition; +import org.argeo.slc.core.test.TestResult; +import org.argeo.slc.core.test.TestRun; + +/** + * Collection of test definitions propagating tree structure information to its + * children. + */ +public class CompositeTreeTestDefinition implements TestDefinition, + StructureAware { + private Log log = LogFactory.getLog(CompositeTreeTestDefinition.class); + + private List tasks = null; + private List taskPaths = null; + private TreeSPath path; + private StructureRegistry registry; + + public void execute(TestRun testRun) { + log.info("Execute sequence of test definitions..."); + + int i = 0; + for (TestDefinition task : tasks) { + TestResult result = testRun.getTestResult(); + if (result instanceof StructureAware) { + ((StructureAware) result).notifyCurrentPath(registry, taskPaths + .get(i)); + } + + task.execute(testRun); + + // Reset current path in case it has been changed + if (result instanceof StructureAware) { + ((StructureAware) result).notifyCurrentPath(registry, path); + } + i++; + } + } + + /** Sets the list of children test definitions */ + public void setTasks(List tasks) { + this.tasks = tasks; + if (tasks != null) { + taskPaths = new Vector(); + } + } + + public void notifyCurrentPath(StructureRegistry registry, + TreeSPath path) { + this.path = path; + this.registry = registry; + + // clear task paths + taskPaths.clear(); + + Integer count = 0; + for (TestDefinition task : tasks) { + final StructureElement element; + if (task instanceof StructureElementProvider) { + element = ((StructureElementProvider) task) + .createStructureElement(); + } else { + element = new SimpleSElement("[no desc]"); + } + TreeSPath taskPath = this.path.createChild(count.toString()); + registry.register(taskPath, element); + taskPaths.add(taskPath); + if (task instanceof StructureAware) { + ((StructureAware) task).notifyCurrentPath(registry, + taskPath); + } + count++; + } + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/PartSubList.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/PartSubList.java new file mode 100644 index 000000000..128da6abb --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/PartSubList.java @@ -0,0 +1,50 @@ +package org.argeo.slc.core.test.tree; + +import java.util.List; +import java.util.Vector; + +import org.argeo.slc.core.test.TestResultPart; +import org.argeo.slc.core.test.TestStatus; + +/** + * List of TestResultPart. It can be used to build complex + * TestResult affording the possibility to a + * TestDefinition to add a list of result part under the same + * StructurePath. + * + * @see TreeTestResult + */ +public class PartSubList { + + /** For ORM */ + private Long tid; + + private List parts = new Vector(); + + /** Gets the result parts. */ + public List getParts() { + return parts; + } + + /** Sets the result parts. */ + public void setParts(List parts) { + this.parts = parts; + } + + Long getTid() { + return tid; + } + + void setTid(Long tid) { + this.tid = tid; + } + + public Boolean getIsPassed() { + for (TestResultPart part : parts) { + if (part.getStatus() != TestStatus.PASSED) { + return false; + } + } + return true; + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/TreeTestResult.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/TreeTestResult.java new file mode 100644 index 000000000..328d5981a --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/TreeTestResult.java @@ -0,0 +1,183 @@ +package org.argeo.slc.core.test.tree; + +import java.util.Date; +import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.Vector; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.core.SlcException; +import org.argeo.slc.core.structure.StructureAware; +import org.argeo.slc.core.structure.StructureElement; +import org.argeo.slc.core.structure.StructureRegistry; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.test.TestResult; +import org.argeo.slc.core.test.TestResultListener; +import org.argeo.slc.core.test.TestResultPart; +import org.argeo.slc.core.test.TestRun; +import org.argeo.slc.core.test.TestRunAware; + +/** + * Complex implementation of a test result compatible with a tree based + * structure. + */ +public class TreeTestResult implements TestResult, StructureAware,Comparable { + private Log log = LogFactory.getLog(TreeTestResult.class); + + private List> listeners = new Vector>(); + + private TreeSPath currentPath; + private TestRun currentTestRun; + + private Date closeDate; + + private boolean isClosed = false; + + private String uuid; + + private SortedMap resultParts = new TreeMap(); + private SortedMap elements = new TreeMap(); + + /** Sets the list of listeners. */ + public void setListeners(List> listeners) { + this.listeners = listeners; + } + + public void addResultPart(TestResultPart part) { + if (currentPath == null) { + throw new SlcException("No current path set."); + } + PartSubList subList = resultParts.get(currentPath); + if (subList == null) { + subList = new PartSubList(); + resultParts.put(currentPath, subList); + } + if (part instanceof TestRunAware && currentTestRun != null) { + ((TestRunAware) part).notifyTestRun(currentTestRun); + } + subList.getParts().add(part); + + // notify listeners + synchronized (listeners) { + for (TestResultListener listener : listeners) { + listener.resultPartAdded(this, part); + } + } + } + + public void notifyCurrentPath(StructureRegistry registry, + TreeSPath path) { + if (registry != null) { + for (TreeSPath p : path.getHierarchyAsList()) { + if (!elements.containsKey(p)) { + StructureElement elem = registry.getElement(p); + if (elem != null) { + elements.put(p, elem); + } + } else { + if (log.isTraceEnabled()) + log.trace("An element is already registered for path " + + p + " and was not updated"); + } + + } + } + + currentPath = (TreeSPath) path; + } + + /** Gets the current path. */ + public TreeSPath getCurrentPath() { + return currentPath; + } + + /** Gets all the results structured as a map of PartSubLists. */ + public SortedMap getResultParts() { + return resultParts; + } + + /** Used by ORM systems. */ + void setResultParts(SortedMap resultParts) { + this.resultParts = resultParts; + } + + public void close() { + if (isClosed) { + throw new SlcException("Test Result #" + getUuid() + + " alredy closed."); + } + closeDate = new Date(); + + synchronized (listeners) { + for (TestResultListener listener : listeners) { + listener.close(this); + } + listeners.clear(); + } + isClosed = true; + + log.info("Test Result #" + getUuid() + " closed."); + } + + public Date getCloseDate() { + return closeDate; + } + + /** Sets the close date (for ORM) */ + public void setCloseDate(Date closeDate) { + this.closeDate = closeDate; + } + + public void notifyTestRun(TestRun testRun) { + currentTestRun = testRun; + } + + public SortedMap getElements() { + return elements; + } + + public void setElements(SortedMap pathNames) { + this.elements = pathNames; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public SortedMap getRelatedElements( + TreeSPath path) { + SortedMap relatedElements = new TreeMap(); + List hierarchy = path.getHierarchyAsList(); + for (TreeSPath currPath : elements.keySet()) { + if (hierarchy.contains(currPath)) { + relatedElements.put(currPath, elements.get(currPath)); + } + } + return relatedElements; + } + + public TestRun getCurrentTestRun() { + return currentTestRun; + } + + public int compareTo(TreeTestResult ttr2) { + TreeTestResult ttr1 = this; + if (ttr1.getCloseDate() != null && ttr2.getCloseDate() != null) { + return -ttr1.getCloseDate().compareTo(ttr2.getCloseDate()); + } else if (ttr1.getCloseDate() != null && ttr2.getCloseDate() == null) { + return 1; + } else if (ttr1.getCloseDate() == null && ttr2.getCloseDate() != null) { + return -1; + } else { + return ttr1.getUuid().compareTo(ttr2.getUuid()); + } + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultCollection.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultCollection.java new file mode 100644 index 000000000..1c454687c --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultCollection.java @@ -0,0 +1,45 @@ +package org.argeo.slc.core.test.tree; + +import java.util.SortedSet; +import java.util.TreeSet; + +public class TreeTestResultCollection implements + Comparable { + private String id; + private SortedSet results = new TreeSet(); + + public TreeTestResultCollection() { + } + + public TreeTestResultCollection(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public SortedSet getResults() { + return results; + } + + public void setResults(SortedSet results) { + this.results = results; + } + + public int compareTo(TreeTestResultCollection o) { + return getId().compareTo(o.getId()); + } + + @Override + public boolean equals(Object o) { + if (o instanceof TreeTestResultCollection) { + return getId().equals(((TreeTestResultCollection) o).getId()); + } + return false; + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultLogger.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultLogger.java new file mode 100644 index 000000000..2246e18b0 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultLogger.java @@ -0,0 +1,39 @@ +package org.argeo.slc.core.test.tree; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.core.test.TestResultListener; +import org.argeo.slc.core.test.TestResultPart; +import org.argeo.slc.core.test.TestStatus; + +/** + * Listener logging tree-based test results to the underlying logging system. + * + * @see TreeTestResult + * + */ +public class TreeTestResultLogger implements TestResultListener { + + private static Log log = LogFactory.getLog(TreeTestResultLogger.class); + + public void resultPartAdded(TreeTestResult testResult, + TestResultPart testResultPart) { + String msg = testResultPart + " - " + testResult.getUuid() + ":" + + testResult.getCurrentPath(); + if (testResultPart.getStatus().equals(TestStatus.PASSED)) { + log.info(msg); + } else if (testResultPart.getStatus().equals(TestStatus.FAILED)) { + log.warn(msg); + } else if (testResultPart.getStatus().equals(TestStatus.ERROR)) { + log.error(msg + "\n" + testResultPart.getExceptionMessage()); + } else { + log.error("Unknow test status: " + msg); + } + } + + public void close(TreeTestResult testResult) { + log.info("Test result " + testResult.getUuid() + " closed."); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/WebServiceTreeTestResultNotifier.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/WebServiceTreeTestResultNotifier.java new file mode 100644 index 000000000..6cfd4da61 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/WebServiceTreeTestResultNotifier.java @@ -0,0 +1,110 @@ +package org.argeo.slc.core.test.tree; + +import org.springframework.ws.client.WebServiceIOException; +import org.springframework.ws.client.core.WebServiceTemplate; +import org.springframework.ws.soap.client.SoapFaultClientException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.core.test.TestResultListener; +import org.argeo.slc.core.test.TestResultPart; +import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest; +import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest; +import org.argeo.slc.msg.test.tree.ResultPartRequest; +import org.argeo.slc.ws.client.WebServiceUtils; + +public class WebServiceTreeTestResultNotifier implements + TestResultListener { + private WebServiceTemplate template; + private Boolean onlyOnClose = false; + + private Log log = LogFactory.getLog(getClass()); + + private Boolean cannotConnect = false; + + public void resultPartAdded(TreeTestResult testResult, + TestResultPart testResultPart) { + if (onlyOnClose) + return; + + if (cannotConnect) + return; + + try { + if (testResult.getResultParts().size() == 1 + && testResult.getResultParts().values().iterator().next() + .getParts().size() == 1) { + CreateTreeTestResultRequest req = new CreateTreeTestResultRequest( + testResult); + + if (log.isDebugEnabled()) + log.debug("Send create result request for result " + + testResult.getUuid()); + + WebServiceUtils.marshalSendAndReceive(template, req); + } else { + ResultPartRequest req = new ResultPartRequest(testResult); + + if (log.isDebugEnabled()) + log.debug("Send result parts for result " + + testResult.getUuid()); + + WebServiceUtils.marshalSendAndReceive(template, req); + } + } catch (SoapFaultClientException e) { + WebServiceUtils.manageSoapException(e); + + } catch (WebServiceIOException e) { + manageIoException(e); + } + } + + public void close(TreeTestResult testResult) { + if (cannotConnect) + return; + + try { + if (onlyOnClose) { + CreateTreeTestResultRequest req = new CreateTreeTestResultRequest( + testResult); + + if (log.isDebugEnabled()) + log.debug("Send create result request for result " + + testResult.getUuid()); + + WebServiceUtils.marshalSendAndReceive(template, req); + } else { + CloseTreeTestResultRequest req = new CloseTreeTestResultRequest( + testResult); + + if (log.isDebugEnabled()) + log.debug("Send close result request for result " + + testResult.getUuid()); + + WebServiceUtils.marshalSendAndReceive(template, req); + + } + } catch (SoapFaultClientException e) { + WebServiceUtils.manageSoapException(e); + } catch (WebServiceIOException e) { + manageIoException(e); + } + } + + public void setTemplate(WebServiceTemplate template) { + this.template = template; + } + + public void setOnlyOnClose(Boolean onlyOnClose) { + this.onlyOnClose = onlyOnClose; + } + + protected void manageIoException(WebServiceIOException e) { + if (!cannotConnect) { + log.error("Cannot connect to " + template.getDefaultUri() + + ". Won't try again.", e); + cannotConnect = true; + } + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/XsltReportGenerator.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/XsltReportGenerator.java new file mode 100644 index 000000000..059c209f1 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/XsltReportGenerator.java @@ -0,0 +1,156 @@ +package org.argeo.slc.core.test.tree; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Templates; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.springframework.core.io.Resource; +import org.springframework.oxm.Marshaller; +import org.springframework.xml.transform.StringResult; +import org.w3c.dom.Document; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.core.SlcException; +import org.argeo.slc.core.test.TestResultListener; +import org.argeo.slc.core.test.TestResultPart; + +public class XsltReportGenerator implements TestResultListener { + private Log log = LogFactory.getLog(getClass()); + + private DocumentBuilder documentBuilder = null; + + private Resource xsltStyleSheet; + + private Templates templates; + + private Marshaller marshaller; + + private String outputDir; + private String outputFileExtension = "html"; + + private Boolean logXml = false; + + public void init() { + if (templates != null) + return; + + if (xsltStyleSheet == null) + throw new SlcException("XSLT style sheet not specified."); + + InputStream in = null; + try { + TransformerFactory transformerFactory = TransformerFactory + .newInstance(); + in = xsltStyleSheet.getInputStream(); + StreamSource xsltSource = new StreamSource(in); + templates = transformerFactory.newTemplates(xsltSource); + } catch (Exception e) { + throw new SlcException("Could not initialize templates", e); + } finally { + IOUtils.closeQuietly(in); + } + } + + public void resultPartAdded(TreeTestResult testResult, + TestResultPart testResultPart) { + + } + + public void close(TreeTestResult testResult) { + if (templates == null) + throw new SlcException("XSLT template not initialized"); + + File file = getFile(testResult); + OutputStream out = null; + + try { + Transformer transformer = templates.newTransformer(); + + if (documentBuilder == null) + documentBuilder = DocumentBuilderFactory.newInstance() + .newDocumentBuilder(); + + Document document = documentBuilder.newDocument(); + DOMResult marshallResult = new DOMResult(document); + marshaller.marshal(testResult, marshallResult); + + if (logXml) { + Transformer identityTransformer = TransformerFactory + .newInstance().newTransformer(); + StringResult xmlResult = new StringResult(); + identityTransformer.transform(new DOMSource(marshallResult + .getNode()), xmlResult); + log.info("Marshalled XML:\n" + xmlResult); + } + + DOMSource transfoSource = new DOMSource(marshallResult.getNode()); + + if (outputDir != null) { + File dir = new File(outputDir); + dir.mkdirs(); + out = new FileOutputStream(file); + StreamResult outputResult = new StreamResult(out); + transformer.transform(transfoSource, outputResult); + } else { + // print on console if no output dir + StringResult result = new StringResult(); + transformer.transform(transfoSource, result); + log.info("Generated report:\n" + result); + } + } catch (Exception e) { + throw new SlcException( + "Could not transform test result to " + file, e); + } finally { + IOUtils.closeQuietly(out); + } + } + + public Resource getXsltStyleSheet() { + return xsltStyleSheet; + } + + public void setXsltStyleSheet(Resource xsltStyleSheet) { + this.xsltStyleSheet = xsltStyleSheet; + } + + public void setTemplates(Templates templates) { + this.templates = templates; + } + + public void setMarshaller(Marshaller marshaller) { + this.marshaller = marshaller; + } + + public void setOutputDir(String outputDir) { + this.outputDir = outputDir; + } + + public void setOutputFileExtension(String outputFileExtension) { + this.outputFileExtension = outputFileExtension; + } + + protected File getFile(TreeTestResult result) { + Long time = System.currentTimeMillis(); + return new File(outputDir + File.separator + time + "-" + + result.getUuid() + "." + outputFileExtension); + } + + public void setLogXml(Boolean logXml) { + this.logXml = logXml; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/FullHtmlTreeReport.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/FullHtmlTreeReport.java new file mode 100644 index 000000000..a77eb34f0 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/FullHtmlTreeReport.java @@ -0,0 +1,168 @@ +package org.argeo.slc.core.test.tree.htmlreport; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.util.Comparator; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.core.SlcException; +import org.argeo.slc.core.structure.StructureAware; +import org.argeo.slc.core.structure.StructurePath; +import org.argeo.slc.core.structure.StructureRegistry; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.test.TestReport; +import org.argeo.slc.core.test.TestResult; +import org.argeo.slc.core.test.tree.TreeTestResult; +import org.argeo.slc.dao.structure.tree.TreeSRegistryDao; +import org.argeo.slc.dao.test.TestResultDao; + +/** + * Basic implementation of TestReport generating static HTML pages. If a + * TestResultDao is passed, all the data is dumped, otherwise + * only the passed TestResult. + */ +public class FullHtmlTreeReport implements TestReport, StructureAware { + private static final Log log = LogFactory.getLog(FullHtmlTreeReport.class); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + + private TestResultDao testResultDao; + private TreeSRegistryDao treeSRegistryDao; + private File reportDir; + + private StructureRegistry localRegistry; + + public void generateTestReport(TestResult testResult) { + + if (testResultDao == null) { + if (testResult == null) + throw new SlcException( + "Cannot generate report without DAO or result instance."); + + TreeTestResult result = (TreeTestResult) testResult; + ResultPage page = new ResultPage(this, result); + page.generate(getRegistry(result)); + } else { + if (reportDir.exists()) { + // clean + for (File file : reportDir.listFiles()) { + file.delete(); + } + } + reportDir.mkdirs(); + + resourceToFile("index.html"); + + ResultsList index = new ResultsList(this); + List list = testResultDao.listTestResults(); + SortedSet sortedSet = new TreeSet( + new Comparator() { + + public int compare(TestResult o1, TestResult o2) { + if (o1.getCloseDate() == null + || o2.getCloseDate() == null) + return 0; + // inverse date order (last first) + return o2.getCloseDate().compareTo( + o1.getCloseDate()); + } + + }); + sortedSet.addAll(list); + for (TestResult testRes : sortedSet) { + TreeTestResult result = (TreeTestResult) testRes; + + index.addTestResult(result); + ResultPage page = new ResultPage(this, result); + page.generate(getRegistry(result)); + } + index.close(); + } + log.info("Generated HTML test result report to "+reportDir); + } + + /** + * Generates a result file location based on the report dir and the id of + * the test result. + */ + protected File getResultFile(TreeTestResult result) { + return new File(reportDir.getPath() + File.separator + "slc-result-" + + result.getUuid() + ".html"); + } + + /** Sets the DAO to use to extract all data. */ + public void setTestResultDao(TestResultDao testResultDao) { + this.testResultDao = testResultDao; + } + + /** Sets the tree structure registry DAO. */ + public void setTreeSRegistryDao(TreeSRegistryDao treeSRegistryDao) { + this.treeSRegistryDao = treeSRegistryDao; + } + + /** Sets the directory where to generate all the data. */ + public void setReportDir(File reportDir) { + this.reportDir = reportDir; + } + + private StructureRegistry getRegistry(TreeTestResult result) { + StructureRegistry registry = null; + if (treeSRegistryDao != null) { + TreeSPath path = result.getResultParts().firstKey(); + registry = treeSRegistryDao.getActiveTreeSRegistry(); + } + if (registry == null) { + registry = localRegistry; + } + if (registry == null) { + throw new SlcException("No structure registry available"); + } + return registry; + } + + public void notifyCurrentPath(StructureRegistry registry, StructurePath path) { + this.localRegistry = registry; + } + + File getReportDir() { + return reportDir; + } + + void addStyles(StringBuffer buf) { + try { + buf.append("\n"); + } catch (IOException e) { + throw new SlcException("Cannot load styles", e); + } + } + + private void resourceToFile(String resourceName) { + try { + File file = new File(getReportDir() + File.separator + resourceName); + InputStream in = FullHtmlTreeReport.class + .getResourceAsStream(resourceName); + FileOutputStream out = new FileOutputStream(file); + IOUtils.copy(in, out); + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + } catch (Exception e) { + throw new SlcException("Cannot load resource", e); + } + + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultPage.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultPage.java new file mode 100644 index 000000000..69bba492e --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultPage.java @@ -0,0 +1,211 @@ +package org.argeo.slc.core.test.tree.htmlreport; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Date; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.core.structure.StructureElement; +import org.argeo.slc.core.structure.StructureRegistry; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.test.SimpleResultPart; +import org.argeo.slc.core.test.TestResultPart; +import org.argeo.slc.core.test.TestStatus; +import org.argeo.slc.core.test.tree.PartSubList; +import org.argeo.slc.core.test.tree.TreeTestResult; + +class ResultPage { + private final static Log log = LogFactory.getLog(ResultPage.class); + + private final FullHtmlTreeReport report; + private final TreeTestResult result; + + ResultPage(FullHtmlTreeReport report, TreeTestResult result) { + this.report = report; + this.result = result; + } + + /** + * Generates a result page for one test result + * + * @param file + * file to which generate the HTML + * @param result + * the result to dump + */ + protected void generate(StructureRegistry registry) { + StringBuffer buf = new StringBuffer(""); + buf.append("\n"); + buf.append("
"); + buf.append("Result #").append(result.getUuid()); + buf.append("\n"); + report.addStyles(buf); + buf.append("
\n"); + + buf.append("\n"); + + // Header + buf.append("\n"); + buf.append("

Result #").append(result.getUuid()).append("

\n"); + Date closeDate = result.getCloseDate(); + if (closeDate == null) { + buf.append("[Not closed]"); + } else { + buf.append(report.sdf.format(closeDate)); + } + + // TOC + generateToc(buf, registry); + + generatePartsList(buf, registry); + + buf.append(""); + buf.append(""); + + try { + FileUtils.writeStringToFile(report.getResultFile(result), buf + .toString()); + } catch (IOException e) { + log.error("Could not save result page.", e); + } + } + + private void generateToc(StringBuffer buf, + StructureRegistry registry) { + buf.append("

Overview

\n"); + SortedMap toc = new TreeMap(); + for (TreeSPath path : result.getResultParts().keySet()) { + PartSubList subList = (PartSubList) result.getResultParts().get( + path); + boolean isFailed = false; + for (TestResultPart part : subList.getParts()) { + if (!part.getStatus().equals(TestStatus.PASSED)) { + isFailed = true; + break; + } + } + fillToc(toc, path, isFailed); + } + + buf.append("\n"); + for (TreeSPath path : toc.keySet()) { + boolean inResult = result.getResultParts().containsKey(path); + boolean isFailed = !toc.get(path).equals(TestStatus.PASSED); + + buf.append("\n"); + } + buf.append("
"); + int depth = path.getDepth(); + for (int i = 0; i < depth; i++) { + buf.append("      "); + } + + if (inResult) { + buf.append(""); + } + if (registry != null) { + StructureElement element = registry.getElement(path); + if (element != null) { + buf.append(element.getLabel()); + } else { + buf.append(path.getName()); + } + } + if (inResult) { + buf.append(""); + } + buf.append("
\n"); + buf.append("
\n"); + } + + private void generatePartsList(StringBuffer buf, + StructureRegistry registry) { + for (TreeSPath path : result.getResultParts().keySet()) { + buf.append("

\n"); + buf.append(""); + buf.append("

"); + describedPath(path, registry, buf); + buf.append("

"); + + PartSubList subList = (PartSubList) result.getResultParts().get( + path); + buf.append("\n"); + int displayedIndex = 1;// for display only + for (TestResultPart part : subList.getParts()) { + SimpleResultPart sPart = (SimpleResultPart) part; + buf.append("Related Test Run Id:").append( + sPart.getTestRunUuid()).append("
\n"); + String clss = ""; + if (sPart.getStatus().equals(TestStatus.PASSED)) { + clss = "passed"; + } else { + clss = "failed"; + } + buf.append(""); + buf.append(""); + buf.append(""); + buf.append("\n"); + + displayedIndex++; + } + buf.append("
").append(displayedIndex) + .append(""); + + buf.append(sPart.getMessage()); + if (sPart.getStatus().equals(TestStatus.ERROR)) { + buf + .append("

An unexpected error prevented the test to run properly."); + buf.append(sPart.getExceptionMessage()); + buf.append("

"); + } + buf.append("
\n"); + buf.append("top\n"); + buf.append("
\n"); + } + } + + private void fillToc(SortedMap toc, TreeSPath path, + boolean isFailed) { + if (isFailed) { + toc.put(path, TestStatus.FAILED); + } else { + if (!toc.containsKey(path)) { + toc.put(path, TestStatus.PASSED); + } + } + + if (path.getParent() != null) { + fillToc(toc, path.getParent(), isFailed); + } + } + + private String anchor(TreeSPath path) { + return path.getAsUniqueString().replace(path.getSeparator(), '_'); + } + + private void describedPath(TreeSPath path, + StructureRegistry registry, StringBuffer buf) { + // StringBuffer buf = new StringBuffer(""); + if (path.getParent() != null) { + describedPath(path.getParent(), registry, buf); + } + String description = path.getName(); + if (registry != null) { + StructureElement element = registry.getElement(path); + if (element != null) { + description = element.getLabel(); + } + } + buf.append('/').append(description); + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultsList.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultsList.java new file mode 100644 index 000000000..09895d454 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultsList.java @@ -0,0 +1,63 @@ +package org.argeo.slc.core.test.tree.htmlreport; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Date; + +import org.argeo.slc.core.test.tree.TreeTestResult; + +class ResultsList { + private final FullHtmlTreeReport report; + private final StringBuffer buf = new StringBuffer(""); + + ResultsList(FullHtmlTreeReport report) { + this.report = report; + + buf.append("
Results
"); + buf.append("
"); + buf.append("Results\n"); + report.addStyles(buf); + buf.append("
\n"); + buf.append("\n"); + + buf.append("

Results

\n"); + buf.append("\n"); + buf.append("\n"); + } + + void addTestResult(TreeTestResult result) { + buf.append("\n"); + // Date + buf.append("\n"); + // Id and link + buf.append("\n"); + + buf.append("\n"); + } + + void close() { + buf.append("
DateResult Id
"); + Date closeDate = result.getCloseDate(); + if (closeDate == null) { + buf.append("[Not closed]"); + } else { + buf.append(report.sdf.format(closeDate)); + } + buf.append("#"); + buf.append(result.getUuid()).append("
\n"); + + try { + FileWriter writer = new FileWriter(report.getReportDir().getPath() + + File.separator + "slc-resultsList.html"); + writer.write(buf.toString()); + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/package.html new file mode 100644 index 000000000..b10bc3d6f --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/htmlreport/package.html @@ -0,0 +1,6 @@ + + + +Static HTML report for tree based test results. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/package.html new file mode 100644 index 000000000..8ad12037e --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/core/test/tree/package.html @@ -0,0 +1,6 @@ + + + +Extension of SLC Test integrating tree-based structure. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/process/SlcExecutionDao.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/process/SlcExecutionDao.java new file mode 100644 index 000000000..181a9febe --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/process/SlcExecutionDao.java @@ -0,0 +1,12 @@ +package org.argeo.slc.dao.process; + +import java.util.List; + +import org.argeo.slc.core.process.SlcExecution; + +public interface SlcExecutionDao { + public void create(SlcExecution slcExecution); + public void update(SlcExecution slcExecution); + public SlcExecution getSlcExecution(String uuid); + public List listSlcExecutions(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/SimpleSElementDao.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/SimpleSElementDao.java new file mode 100644 index 000000000..bed950ff3 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/SimpleSElementDao.java @@ -0,0 +1,5 @@ +package org.argeo.slc.dao.structure; + +public interface SimpleSElementDao { + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/package.html new file mode 100644 index 000000000..f8b5ae763 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/package.html @@ -0,0 +1,6 @@ + + + +DAOs for the core structure objects. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/tree/TreeSPathDao.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/tree/TreeSPathDao.java new file mode 100644 index 000000000..0ebca0d8c --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/tree/TreeSPathDao.java @@ -0,0 +1,11 @@ +package org.argeo.slc.dao.structure.tree; + +import org.argeo.slc.core.structure.tree.TreeSPath; + +public interface TreeSPathDao { + public void create(TreeSPath path); + + public TreeSPath getTreeSPath(String pathString); + + public TreeSPath getOrCreate(TreeSPath pathTransient); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/tree/TreeSRegistryDao.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/tree/TreeSRegistryDao.java new file mode 100644 index 000000000..f271f8cbe --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/tree/TreeSRegistryDao.java @@ -0,0 +1,25 @@ +package org.argeo.slc.dao.structure.tree; + +import org.argeo.slc.core.structure.StructureRegistry; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.structure.tree.TreeSRegistry; + +/** + * DAO for tree-base structure registry. + * + * @see TreeSRegistry + */ +public interface TreeSRegistryDao { + /** Gets the TreeSRegistry which has the same root path as the provided path. */ + public TreeSRegistry getActiveTreeSRegistry(); + + /** Creates a new registry. */ + public void create(TreeSRegistry registry); + + /** Updates an existing registry. */ + public void update(TreeSRegistry registry); + + /** Sync with local registry */ + public void syncPath(TreeSRegistry registry, + StructureRegistry localRegistry, TreeSPath path); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/tree/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/tree/package.html new file mode 100644 index 000000000..b8cd81210 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/structure/tree/package.html @@ -0,0 +1,6 @@ + + + +DAOs for the tree-based structure objects. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/TestResultDao.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/TestResultDao.java new file mode 100644 index 000000000..01cdffd25 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/TestResultDao.java @@ -0,0 +1,28 @@ +package org.argeo.slc.dao.test; + +import java.util.Date; +import java.util.List; + +import org.argeo.slc.core.test.TestResult; + +/** + * The dao for TestResult. + * + * @see TestResult + */ +public interface TestResultDao { + /** Gets a test result based on its id. */ + public T getTestResult(String uuid); + + /** Persists a new test result. */ + public void create(TestResult testResult); + + /** Updates an already persisted test result. */ + public void update(TestResult testResult); + + /** Lists all test results. */ + public List listTestResults(); + + + public void close(String id, Date closeDate); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/TestRunDescriptorDao.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/TestRunDescriptorDao.java new file mode 100644 index 000000000..7397458b5 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/TestRunDescriptorDao.java @@ -0,0 +1,8 @@ +package org.argeo.slc.dao.test; + +import org.argeo.slc.core.test.TestRunDescriptor; + +public interface TestRunDescriptorDao { + public TestRunDescriptor getTestRunDescriptor(String id); + public void saveOrUpdate(TestRunDescriptor testRunDescriptor); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/package.html new file mode 100644 index 000000000..38ae2b5bf --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/package.html @@ -0,0 +1,6 @@ + + + +Data Access Objects for SLC Test. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultCollectionDao.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultCollectionDao.java new file mode 100644 index 000000000..02bc13488 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultCollectionDao.java @@ -0,0 +1,15 @@ +package org.argeo.slc.dao.test.tree; + +import java.util.SortedSet; + +import org.argeo.slc.core.test.tree.TreeTestResultCollection; + +public interface TreeTestResultCollectionDao { + public void create(TreeTestResultCollection ttrCollection); + + public void update(TreeTestResultCollection ttrCollection); + + public TreeTestResultCollection getTestResultCollection(String id); + + public SortedSet listCollections(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultDao.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultDao.java new file mode 100644 index 000000000..c66d36921 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultDao.java @@ -0,0 +1,12 @@ +package org.argeo.slc.dao.test.tree; + +import java.util.List; + +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.test.tree.TreeTestResult; +import org.argeo.slc.dao.test.TestResultDao; + +public interface TreeTestResultDao extends TestResultDao { + /** Lists results containing this path */ + public List listResults(TreeSPath path); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultPersister.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultPersister.java new file mode 100644 index 000000000..73766ead6 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultPersister.java @@ -0,0 +1,55 @@ +package org.argeo.slc.dao.test.tree; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.core.test.TestResultListener; +import org.argeo.slc.core.test.TestResultPart; +import org.argeo.slc.core.test.tree.TreeTestResult; + +/** + * Listener persisting tree-based results. + * + * @see TreeTestResult + */ +public class TreeTestResultPersister implements + TestResultListener { + private static Log log = LogFactory.getLog(TreeTestResultPersister.class); + + private TreeTestResultDao testResultDao; + + public void resultPartAdded(TreeTestResult testResult, + TestResultPart testResultPart) { + try { + TreeTestResult persistedResult = testResultDao + .getTestResult(testResult.getUuid()); + + if (persistedResult == null) { + testResultDao.create(testResult); + } else { + testResultDao.update(testResult); + } + } catch (Exception e) { + log.error("Could not persist result part " + testResultPart + + " for result " + testResult.getUuid()); + } + } + + public void close(TreeTestResult testResult) { + TreeTestResult persistedResult = (TreeTestResult) testResultDao + .getTestResult(testResult.getUuid()); + + if (persistedResult != null) { + persistedResult.setCloseDate(testResult.getCloseDate()); + testResultDao.update(persistedResult); + } + if (log.isDebugEnabled()) + log.debug("Closed result persister for result " + + testResult.getUuid()); + } + + /** Sets the DAO to use in order to persist the results. */ + public void setTestResultDao(TreeTestResultDao testResultDao) { + this.testResultDao = testResultDao; + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DataInterpreter.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DataInterpreter.java new file mode 100644 index 000000000..7a57b0552 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DataInterpreter.java @@ -0,0 +1,20 @@ +package org.argeo.slc.diff; + +/** + * Converts data into a format better adapted for comparison. It is typically + * used to convert String into typed format such as + * BigDecimal + */ +public interface DataInterpreter { + /** + * Converts data + * + * @param key + * any object used to differentiate the type of data (e.g. + * column, path) + * @param value + * the data to convert + * @return the converted object + */ + public Object convert(Object key, Object value); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/Diff.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/Diff.java new file mode 100644 index 000000000..0b28996e9 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/Diff.java @@ -0,0 +1,9 @@ +package org.argeo.slc.diff; + +import org.springframework.core.io.Resource; + +/** A comparator providing structured information about the differences found. */ +public interface Diff { + /** Performs the comparison. */ + public DiffResult compare(Resource expected, Resource reached); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffIssue.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffIssue.java new file mode 100644 index 000000000..5517b3a66 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffIssue.java @@ -0,0 +1,22 @@ +package org.argeo.slc.diff; + +/** The root class for issues which happened during a diff. */ +public abstract class DiffIssue implements Comparable { + /** The position of this issue. */ + protected final DiffPosition position; + + /** Constructor */ + public DiffIssue(DiffPosition position) { + super(); + this.position = position; + } + + public int compareTo(DiffIssue o) { + return position.compareTo(o.position); + } + + /** The position of this issue within the test file */ + public DiffPosition getPosition() { + return position; + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffKey.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffKey.java new file mode 100644 index 000000000..9d34f720a --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffKey.java @@ -0,0 +1,9 @@ +package org.argeo.slc.diff; + +/** + * Object able to uniquely identify an atomic diff part. Used to identify + * missings and left-overs. + */ +public interface DiffKey { + public String toString(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffMissing.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffMissing.java new file mode 100644 index 000000000..da4476660 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffMissing.java @@ -0,0 +1,31 @@ +package org.argeo.slc.diff; + +/** + * A value missing in one of the file. If its position is related to expected, + * this means it is a left over in the reached, if its position is related to + * the reached it means that it is missing from the reached. If the value is + * null it means that the entire line is missing. + */ +public class DiffMissing extends DiffIssue { + private final DiffKey key; + + public DiffMissing(DiffPosition position, DiffKey key) { + super(position); + this.key = key; + } + + public Object getKey() { + return key; + } + + @Override + public String toString() { + if (position.relatedFile == RelatedFile.EXPECTED) { + return position + ": left over " + key; + } else if (position.relatedFile == RelatedFile.REACHED) { + return position + ": missing " + key; + } + return super.toString(); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffMissingXml.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffMissingXml.java new file mode 100644 index 000000000..ca3fd21a2 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffMissingXml.java @@ -0,0 +1,43 @@ +package org.argeo.slc.diff; + +/** + * DiffMissing using the XPath of the position as + * DiffKey + */ +public class DiffMissingXml extends DiffMissing { + + public DiffMissingXml(XPathDiffPosition position) { + super(position, new DiffKeyXml(position.getXPath())); + } + + /** Implementation of DiffKey based on an XPath string. */ + protected static class DiffKeyXml implements DiffKey { + private final String xPath; + + public DiffKeyXml(String xPath) { + this.xPath = xPath; + } + + public String getXPath() { + return xPath; + } + + @Override + public String toString() { + return xPath; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof DiffKeyXml)) + return false; + return xPath.equals(((DiffKeyXml) obj).xPath); + } + + @Override + public int hashCode() { + return xPath.hashCode(); + } + + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffNotMatched.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffNotMatched.java new file mode 100644 index 000000000..04f7acff1 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffNotMatched.java @@ -0,0 +1,27 @@ +package org.argeo.slc.diff; + +/** Diff issue where reached and expected values are different. */ +public class DiffNotMatched extends DiffIssue { + private final Object expected; + private final Object reached; + + public DiffNotMatched(DiffPosition position, Object expected, Object reached) { + super(position); + this.expected = expected; + this.reached = reached; + } + + public Object getExpected() { + return expected; + } + + public Object getReached() { + return reached; + } + + @Override + public String toString() { + return position + ": not matched " + expected + " <> " + reached; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffPosition.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffPosition.java new file mode 100644 index 000000000..302c0afa9 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffPosition.java @@ -0,0 +1,16 @@ +package org.argeo.slc.diff; + +/** The position of a diff issue within the test resource. */ +public abstract class DiffPosition implements Comparable { + protected RelatedFile relatedFile; + + public DiffPosition(RelatedFile relatedFile) { + super(); + this.relatedFile = relatedFile; + } + + public RelatedFile getRelatedFile() { + return relatedFile; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffResult.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffResult.java new file mode 100644 index 000000000..0e29fdd05 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/DiffResult.java @@ -0,0 +1,12 @@ +package org.argeo.slc.diff; + +import java.util.List; + +/** + * The result of a diff. Can be subclassed to provided more structured + * information. + */ +public interface DiffResult { + /** The list of issues, a zero size meaning that the diff succeeded. */ + public List getIssues(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/LineTokenizer.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/LineTokenizer.java new file mode 100644 index 000000000..fed4c37b5 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/LineTokenizer.java @@ -0,0 +1,96 @@ +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 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 parse(final String stringToParse, + final char separator, final String noValueString) { + // Init + final int NULL = -1; + List res = new ArrayList(); + 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 getTokens() { + return tokens; + } + + /** Parse */ + public static List 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 tokenize(String stringToParse, + Character separator) { + return tokenize(stringToParse, separator, ""); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/RelatedFile.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/RelatedFile.java new file mode 100644 index 000000000..757968355 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/RelatedFile.java @@ -0,0 +1,9 @@ +package org.argeo.slc.diff; + +/** Enumeration of the types of resource tested. */ +public enum RelatedFile { + /** The expected resource */ + EXPECTED, + /** The reached resource */ + REACHED +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/SimpleDiffResult.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/SimpleDiffResult.java new file mode 100644 index 000000000..6eefb7f28 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/SimpleDiffResult.java @@ -0,0 +1,14 @@ +package org.argeo.slc.diff; + +import java.util.List; +import java.util.Vector; + +/** A basic implementation of DiffResult. */ +public class SimpleDiffResult implements DiffResult { + private List issues = new Vector(); + + public List getIssues() { + return issues; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/TableDiffPosition.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/TableDiffPosition.java new file mode 100644 index 000000000..d8a3d785d --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/TableDiffPosition.java @@ -0,0 +1,66 @@ +package org.argeo.slc.diff; + +import org.argeo.slc.core.UnsupportedException; + +/** + * A diff position within a table structure such a CSV file or an SQL result + * set. + */ +public class TableDiffPosition extends DiffPosition { + private Integer line; + /** Can be null */ + private Integer column; + /** Can be null */ + private String columnName; + + public TableDiffPosition(RelatedFile relatedFile, Integer line, + Integer column, String columnName) { + super(relatedFile); + this.line = line; + this.column = column; + this.columnName = columnName; + } + + public Integer getLine() { + return line; + } + + public Integer getColumn() { + return column; + } + + public String getColumnName() { + return columnName; + } + + public int compareTo(DiffPosition dp) { + if (!(dp instanceof TableDiffPosition)) + throw new UnsupportedException("position", dp); + + TableDiffPosition o = (TableDiffPosition) dp; + if (relatedFile.equals(o.relatedFile)) { + if (line == o.line) { + return column.compareTo(o.column); + } else { + return line.compareTo(o.line); + } + } else { + return relatedFile.compareTo(o.relatedFile); + } + } + + @Override + public String toString() { + StringBuffer buf = new StringBuffer(""); + buf.append(relatedFile).append('[').append(line); + if (column != null) { + buf.append(',').append(column); + if (columnName != null) { + buf.append('-').append(columnName); + } + } + buf.append(']'); + return buf.toString(); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/Tolerance.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/Tolerance.java new file mode 100644 index 000000000..b44a7123a --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/Tolerance.java @@ -0,0 +1,18 @@ +package org.argeo.slc.diff; + +/** Compares objects, eventually using tolerance mechanisms. */ +public interface Tolerance { + /** + * Compares objects + * + * @param key + * any object used to differentiate the type of data (e.g. + * column, path) + * @param expected + * the expected value + * @param reached + * the reached value + * @return the converted object + */ + public Boolean compare(Object key, Object expected, Object reached); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/XPathDiffPosition.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/XPathDiffPosition.java new file mode 100644 index 000000000..0d2234240 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/XPathDiffPosition.java @@ -0,0 +1,35 @@ +package org.argeo.slc.diff; + +import org.argeo.slc.core.UnsupportedException; + +/** A diff position within an Xml file. NOT YET IMPLEMENTED. */ +public class XPathDiffPosition extends DiffPosition { + + private String xPath; + + public XPathDiffPosition(RelatedFile relatedFile, String path) { + super(relatedFile); + xPath = path; + } + + public int compareTo(DiffPosition dp) { + if (!(dp instanceof XPathDiffPosition)) + throw new UnsupportedException("position", dp); + + XPathDiffPosition o = (XPathDiffPosition) dp; + if (relatedFile.equals(o.relatedFile)) { + return xPath.compareTo(o.xPath); + } else { + return relatedFile.compareTo(o.relatedFile); + } + } + + public String getXPath() { + return xPath; + } + + @Override + public String toString() { + return xPath; + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/package.html new file mode 100644 index 000000000..a58e68575 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/diff/package.html @@ -0,0 +1,6 @@ + + + +Abstraction of diff comparison with structured results. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/maven/MavenDeployEnvironment.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/maven/MavenDeployEnvironment.java new file mode 100644 index 000000000..d10b073e1 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/maven/MavenDeployEnvironment.java @@ -0,0 +1,73 @@ +package org.argeo.slc.maven; + +import java.io.File; +import java.net.URL; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.ant.AntRegistryUtil; +import org.argeo.slc.core.SlcException; +import org.argeo.slc.core.deploy.DeployEnvironment; + +public class MavenDeployEnvironment implements DeployEnvironment { + private static final Log log = LogFactory + .getLog(MavenDeployEnvironment.class); + private MavenManager mavenManager; + + public void unpackTo(Object packg, File targetLocation, + Map filter) { + File packageLocation; + String type = null; + String removeRootDir = "enabled"; + if (packg instanceof MavenFile) { + packageLocation = mavenManager + .getPackageLocation((MavenFile) packg); + type = ((MavenFile) packg).getType(); + } else if (packg instanceof File) { + packageLocation = (File) packg; + // TODO: type based on extension + } else { + throw new SlcException("Unrecognized package type " + + packg.getClass()); + } + if (log.isDebugEnabled()) { + log.debug("Unpack " + packageLocation + " of type " + type + " to " + + targetLocation); + } + + try { + File tempDir = new File("/tmp/"+UUID.randomUUID().toString()); + tempDir.mkdirs(); + targetLocation.mkdirs(); + Properties props = new Properties(); + props.setProperty("dest", targetLocation.getAbsolutePath()); + props.setProperty("src", packageLocation.getAbsolutePath()); + props.setProperty("tempDir", tempDir.getAbsolutePath()); + props.setProperty("removeRootDir", removeRootDir); + + URL antUrl = getClass().getClassLoader().getResource( + "org/argeo/slc/support/deploy/ant/build.xml"); + + if (type == null || type.equals("zip")) { + AntRegistryUtil.runAll(antUrl, "deployZip", props); + } else if (type.equals("tar.gz")) { + AntRegistryUtil.runAll(antUrl, "deployTarGz", props); + } else { + throw new SlcException("Unknow package type " + type); + } + } catch (SlcException e) { + throw e; + } catch (Exception e) { + throw new SlcException("Cannot unpack package " + packg + " to " + + targetLocation, e); + } + } + + public void setMavenManager(MavenManager mavenManager) { + this.mavenManager = mavenManager; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/maven/MavenFile.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/maven/MavenFile.java new file mode 100644 index 000000000..31c6385a6 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/maven/MavenFile.java @@ -0,0 +1,63 @@ +package org.argeo.slc.maven; + +import org.argeo.slc.core.build.Distribution; +import org.argeo.slc.core.deploy.DeploymentData; + +public class MavenFile implements Distribution, DeploymentData { + private String groupId; + private String artifactId; + private String version; + private String type; + private String classifier; + + private String distributionId; + + public String getDistributionId() { + return distributionId; + } + + public void setDistributionId(String distributionId) { + this.distributionId = distributionId; + } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } + + public String getArtifactId() { + return artifactId; + } + + public void setArtifactId(String artifactId) { + this.artifactId = artifactId; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getClassifier() { + return classifier; + } + + public void setClassifier(String classifier) { + this.classifier = classifier; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/maven/MavenManager.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/maven/MavenManager.java new file mode 100644 index 000000000..3a07e227a --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/maven/MavenManager.java @@ -0,0 +1,105 @@ +package org.argeo.slc.maven; + +import java.io.File; +import java.util.List; +import java.util.Vector; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.embedder.MavenEmbedder; +import org.apache.maven.embedder.MavenEmbedderException; + +import org.argeo.slc.core.SlcException; + +public class MavenManager { + private final Log log = LogFactory.getLog(getClass()); + + private String repositoryId; + private String repositoryUrl; + private String localRepositoryPath; + + private ArtifactRepository localRepository; + private List remoteRepositories; + + private MavenEmbedder mavenEmbedder; + + public void init() { + try { + mavenEmbedder = new MavenEmbedder(); + mavenEmbedder.setOffline(true); + mavenEmbedder.setClassLoader(Thread.currentThread() + .getContextClassLoader()); + mavenEmbedder.start(); + + mavenEmbedder.setLocalRepositoryDirectory(new File( + localRepositoryPath)); + + localRepository = mavenEmbedder.getLocalRepository(); + + // localRepository = mavenEmbedder.createLocalRepository(new File( + // localRepositoryPath)); + + ArtifactRepository repository = mavenEmbedder.createRepository( + repositoryUrl, repositoryId); + + remoteRepositories = new Vector(); + remoteRepositories.add(repository); + } catch (Exception e) { + throw new SlcException("Cannot initialize Maven manager", e); + } + } + + private Artifact resolve(MavenFile mavenDistribution) { + try { + Artifact artifact; + if (mavenDistribution.getClassifier() == null) { + artifact = mavenEmbedder.createArtifact(mavenDistribution + .getGroupId(), mavenDistribution.getArtifactId(), + mavenDistribution.getVersion(), + Artifact.SCOPE_PROVIDED, mavenDistribution.getType()); + } else { + artifact = mavenEmbedder.createArtifactWithClassifier( + mavenDistribution.getGroupId(), mavenDistribution + .getArtifactId(), mavenDistribution + .getVersion(), mavenDistribution.getType(), + mavenDistribution.getClassifier()); + } + + mavenEmbedder + .resolve(artifact, remoteRepositories, localRepository); + + return artifact; + } catch (Exception e) { + throw new SlcException("Cannot resolve artifact.", e); + } + } + + public File getPackageLocation(MavenFile mavenDistribution) { + return resolve(mavenDistribution).getFile(); + } + + public void destroy() { + try { + if (mavenEmbedder != null) { + mavenEmbedder.stop(); + } + } catch (MavenEmbedderException e) { + log.error("Cannot destroy Maven manager", e); + } + } + + public void setRepositoryId(String repositoryId) { + this.repositoryId = repositoryId; + } + + public void setRepositoryUrl(String repositoryUrl) { + this.repositoryUrl = repositoryUrl; + } + + public void setLocalRepositoryPath(String localRepositoryPath) { + this.localRepositoryPath = localRepositoryPath; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/process/SlcExecutionRequest.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/process/SlcExecutionRequest.java new file mode 100644 index 000000000..84d582681 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/process/SlcExecutionRequest.java @@ -0,0 +1,16 @@ +package org.argeo.slc.msg.process; + +import org.argeo.slc.core.process.SlcExecution; + +public class SlcExecutionRequest { + private SlcExecution slcExecution; + + public SlcExecution getSlcExecution() { + return slcExecution; + } + + public void setSlcExecution(SlcExecution slcExecution) { + this.slcExecution = slcExecution; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/process/SlcExecutionStatusRequest.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/process/SlcExecutionStatusRequest.java new file mode 100644 index 000000000..78afc830f --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/process/SlcExecutionStatusRequest.java @@ -0,0 +1,30 @@ +package org.argeo.slc.msg.process; + +public class SlcExecutionStatusRequest { + private String slcExecutionUuid; + private String newStatus; + + public SlcExecutionStatusRequest() { + } + + public SlcExecutionStatusRequest(String slcExecutionUuid, String newStatus) { + this.slcExecutionUuid = slcExecutionUuid; + this.newStatus = newStatus; + } + + public String getSlcExecutionUuid() { + return slcExecutionUuid; + } + + public void setSlcExecutionUuid(String slcExecutionUuid) { + this.slcExecutionUuid = slcExecutionUuid; + } + + public String getNewStatus() { + return newStatus; + } + + public void setNewStatus(String newStatus) { + this.newStatus = newStatus; + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/process/SlcExecutionStepsRequest.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/process/SlcExecutionStepsRequest.java new file mode 100644 index 000000000..237f05f87 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/process/SlcExecutionStepsRequest.java @@ -0,0 +1,31 @@ +package org.argeo.slc.msg.process; + +import java.util.List; +import java.util.Vector; + +import org.argeo.slc.core.process.SlcExecutionStep; + +public class SlcExecutionStepsRequest { + private String slcExecutionUuid; + private List steps = new Vector(); + + public String getSlcExecutionUuid() { + return slcExecutionUuid; + } + + public void setSlcExecutionUuid(String slcExecutionUuid) { + this.slcExecutionUuid = slcExecutionUuid; + } + + public List getSteps() { + return steps; + } + + public void setSteps(List step) { + this.steps = step; + } + + public void addStep(SlcExecutionStep step) { + steps.add(step); + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/test/tree/CloseTreeTestResultRequest.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/test/tree/CloseTreeTestResultRequest.java new file mode 100644 index 000000000..c0b74e36e --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/test/tree/CloseTreeTestResultRequest.java @@ -0,0 +1,41 @@ +package org.argeo.slc.msg.test.tree; + +import java.util.Date; + +import org.argeo.slc.core.test.tree.TreeTestResult; + +public class CloseTreeTestResultRequest { + private String resultUuid; + private Date closeDate; + + public CloseTreeTestResultRequest() { + + } + + public CloseTreeTestResultRequest(String resultUuid, Date closeDate) { + this.resultUuid = resultUuid; + this.closeDate = closeDate; + } + + public CloseTreeTestResultRequest(TreeTestResult ttr) { + this.resultUuid = ttr.getUuid(); + this.closeDate = ttr.getCloseDate(); + } + + public String getResultUuid() { + return resultUuid; + } + + public void setResultUuid(String id) { + this.resultUuid = id; + } + + public Date getCloseDate() { + return closeDate; + } + + public void setCloseDate(Date closeDate) { + this.closeDate = closeDate; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/test/tree/CreateTreeTestResultRequest.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/test/tree/CreateTreeTestResultRequest.java new file mode 100644 index 000000000..0a7af822b --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/test/tree/CreateTreeTestResultRequest.java @@ -0,0 +1,23 @@ +package org.argeo.slc.msg.test.tree; + +import org.argeo.slc.core.test.tree.TreeTestResult; + +public class CreateTreeTestResultRequest { + private TreeTestResult treeTestResult; + + public CreateTreeTestResultRequest() { + + } + + public CreateTreeTestResultRequest(TreeTestResult treeTestResult) { + this.treeTestResult = treeTestResult; + } + + public TreeTestResult getTreeTestResult() { + return treeTestResult; + } + + public void setTreeTestResult(TreeTestResult treeTestResult) { + this.treeTestResult = treeTestResult; + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/test/tree/ResultPartRequest.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/test/tree/ResultPartRequest.java new file mode 100644 index 000000000..ac0908711 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/msg/test/tree/ResultPartRequest.java @@ -0,0 +1,93 @@ +package org.argeo.slc.msg.test.tree; + +import java.util.Map; + +import org.argeo.slc.core.SlcException; +import org.argeo.slc.core.process.SlcExecution; +import org.argeo.slc.core.structure.StructureElement; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.test.SimpleResultPart; +import org.argeo.slc.core.test.TestRunDescriptor; +import org.argeo.slc.core.test.tree.PartSubList; +import org.argeo.slc.core.test.tree.TreeTestResult; + +public class ResultPartRequest { + private String resultUuid; + private SimpleResultPart resultPart; + private TreeSPath path; + private Map relatedElements; + private TestRunDescriptor testRunDescriptor; + + public ResultPartRequest() { + + } + + public ResultPartRequest(TreeTestResult ttr, TreeSPath path, + SimpleResultPart resultPart) { + resultUuid = ttr.getUuid(); + this.resultPart = resultPart; + this.path = path; + relatedElements = ttr.getRelatedElements(path); + if (ttr.getCurrentTestRun() != null) + testRunDescriptor = new TestRunDescriptor(ttr.getCurrentTestRun()); + } + + public ResultPartRequest(TreeTestResult ttr) { + resultUuid = ttr.getUuid(); + this.path = ttr.getCurrentPath(); + + PartSubList lst = ttr.getResultParts().get(path); + if (lst.getParts().size() < 1) { + throw new SlcException("Cannot find part for path " + path + + " in result " + resultUuid); + } + + this.resultPart = (SimpleResultPart) lst.getParts().get( + lst.getParts().size() - 1); + relatedElements = ttr.getRelatedElements(path); + if (ttr.getCurrentTestRun() != null) + testRunDescriptor = new TestRunDescriptor(ttr.getCurrentTestRun()); + } + + public String getResultUuid() { + return resultUuid; + } + + public void setResultUuid(String resultUuid) { + this.resultUuid = resultUuid; + } + + public SimpleResultPart getResultPart() { + return resultPart; + } + + public void setResultPart(SimpleResultPart resultPart) { + this.resultPart = resultPart; + } + + public TreeSPath getPath() { + return path; + } + + public void setPath(TreeSPath path) { + this.path = path; + } + + public TestRunDescriptor getTestRunDescriptor() { + return testRunDescriptor; + } + + public void setTestRunDescriptor(TestRunDescriptor testRunDescriptor) { + this.testRunDescriptor = testRunDescriptor; + } + + public Map getRelatedElements() { + return relatedElements; + } + + public void setRelatedElements( + Map relatedElements) { + this.relatedElements = relatedElements; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/spring/SpringUtils.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/spring/SpringUtils.java new file mode 100644 index 000000000..fc9b65686 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/spring/SpringUtils.java @@ -0,0 +1,21 @@ +package org.argeo.slc.spring; + +import java.util.Map; + +import org.springframework.beans.factory.ListableBeanFactory; + +public class SpringUtils { + public static T loadSingleFromContext(ListableBeanFactory context, + Class clss) { + Map beans = context.getBeansOfType(clss); + if (beans.size() == 1) { + return beans.values().iterator().next(); + } else { + return null; + } + } + + private SpringUtils() { + + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/ApacheHttpdServer.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/ApacheHttpdServer.java new file mode 100644 index 000000000..6d77cdd51 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/ApacheHttpdServer.java @@ -0,0 +1,47 @@ +package org.argeo.slc.support.deploy; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +import org.argeo.slc.core.SlcException; +import org.argeo.slc.core.build.Distribution; +import org.springframework.core.io.Resource; + +public class ApacheHttpdServer implements WebServer { + private Resource baseUrlRes; + private File baseLocation; + + public URL getBaseUrl() { + try { + return baseUrlRes.getURL(); + } catch (IOException e) { + throw new SlcException("Cannot get url from "+baseUrlRes,e); + } + } + + public void setBaseUrlRes(Resource baseUrlRes){ + this.baseUrlRes = baseUrlRes; + } + + + + public File getBaseLocation() { + return baseLocation; + } + + public void setBaseLocation(File baseLocation) { + this.baseLocation = baseLocation; + } + + public String getDeployedSystemId() { + // TODO Auto-generated method stub + return null; + } + + public Distribution getDistribution() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/HttpdApplicationDeployment.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/HttpdApplicationDeployment.java new file mode 100644 index 000000000..79eb0bd4f --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/HttpdApplicationDeployment.java @@ -0,0 +1,79 @@ +package org.argeo.slc.support.deploy; + +import java.io.File; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.core.SlcException; +import org.argeo.slc.core.build.Distribution; +import org.argeo.slc.core.deploy.DeployEnvironment; +import org.argeo.slc.core.deploy.DeployedSystem; +import org.argeo.slc.core.deploy.DeploymentData; +import org.argeo.slc.core.deploy.ExecutableDeployment; +import org.argeo.slc.core.deploy.TargetData; + +public class HttpdApplicationDeployment implements ExecutableDeployment { + private static final Log log = LogFactory + .getLog(HttpdApplicationDeployment.class); + + private HttpdApplicationTargetData targetData; + private DeploymentData deploymentData; + private SimpleHttpdApplication deployedSystem; + private Distribution distribution; + + private DeployEnvironment deployEnvironment; + + public void execute() { + try { + deployEnvironment.unpackTo(getDistribution(), targetData + .getTargetRootLocation(), null); + + // FIXME: make it generic + String deployDataPath = targetData.getTargetRootLocation() + .getCanonicalPath(); + + deployEnvironment.unpackTo(getDeploymentData(), new File( + deployDataPath), null); + deployedSystem = new SimpleHttpdApplication(); + deployedSystem.setTargetData(targetData); + + } catch (Exception e) { + throw new SlcException("Cannot deploy " + deploymentData + " to " + + targetData, e); + } + + } + + public void setTargetData(TargetData targetData) { + this.targetData = (HttpdApplicationTargetData) targetData; + } + + public void setDeploymentData(DeploymentData deploymentData) { + this.deploymentData = deploymentData; + } + + public DeployedSystem getDeployedSystem() { + return deployedSystem; + } + + public DeploymentData getDeploymentData() { + return deploymentData; + } + + public TargetData getTargetData() { + return targetData; + } + + public Distribution getDistribution() { + return distribution; + } + + public void setDistribution(Distribution distribution) { + this.distribution = distribution; + } + + public void setDeployEnvironment(DeployEnvironment deployEnvironment) { + this.deployEnvironment = deployEnvironment; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/HttpdApplicationTargetData.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/HttpdApplicationTargetData.java new file mode 100644 index 000000000..7097289ec --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/HttpdApplicationTargetData.java @@ -0,0 +1,44 @@ +package org.argeo.slc.support.deploy; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; + +import org.argeo.slc.core.SlcException; +import org.argeo.slc.core.deploy.TargetData; + +public class HttpdApplicationTargetData implements TargetData { + private ApacheHttpdServer webServer; + private String relativePath; + + public ApacheHttpdServer getWebServer() { + return webServer; + } + + public void setWebServer(ApacheHttpdServer webServer) { + this.webServer = webServer; + } + + public String getRelativePath() { + return relativePath; + } + + public void setRelativePath(String relativePath) { + this.relativePath = relativePath; + } + + public URL getTargetBaseUrl() { + try { + URL wsUrl = getWebServer().getBaseUrl(); + return new URL(wsUrl, wsUrl.getFile() + '/' + relativePath); + } catch (MalformedURLException e) { + throw new SlcException("Cannot get base url for " + relativePath, e); + } + } + + public File getTargetRootLocation() { + return new File(getWebServer().getBaseLocation().getPath() + + File.separator + getRelativePath()); + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/SimpleHttpdApplication.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/SimpleHttpdApplication.java new file mode 100644 index 000000000..bb98c383f --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/SimpleHttpdApplication.java @@ -0,0 +1,41 @@ +package org.argeo.slc.support.deploy; + +import java.io.File; +import java.net.URL; + +import org.argeo.slc.core.build.Distribution; + +public class SimpleHttpdApplication implements WebApplication { + private HttpdApplicationTargetData targetData; + private Distribution distribution; + + public void setDistribution(Distribution distribution) { + this.distribution = distribution; + } + + public URL getBaseUrl() { + return targetData.getTargetBaseUrl(); + } + + public File getRootLocation() { + return targetData.getTargetRootLocation(); + } + + public String getDeployedSystemId() { + // TODO Auto-generated method stub + return null; + } + + public HttpdApplicationTargetData getTargetData() { + return targetData; + } + + public void setTargetData(HttpdApplicationTargetData targetData) { + this.targetData = targetData; + } + + public Distribution getDistribution() { + return distribution; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/WebApplication.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/WebApplication.java new file mode 100644 index 000000000..da0b1129e --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/WebApplication.java @@ -0,0 +1,11 @@ +package org.argeo.slc.support.deploy; + +import java.io.File; +import java.net.URL; + +import org.argeo.slc.core.deploy.DeployedSystem; + +public interface WebApplication extends DeployedSystem{ + public URL getBaseUrl(); + public File getRootLocation(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/WebServer.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/WebServer.java new file mode 100644 index 000000000..fc747bc94 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/support/deploy/WebServer.java @@ -0,0 +1,9 @@ +package org.argeo.slc.support.deploy; + +import java.net.URL; + +import org.argeo.slc.core.deploy.DeployedSystem; + +public interface WebServer extends DeployedSystem { + public URL getBaseUrl(); +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/AbstractSpringTestCase.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/AbstractSpringTestCase.java new file mode 100644 index 000000000..4ad916d57 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/AbstractSpringTestCase.java @@ -0,0 +1,64 @@ +package org.argeo.slc.unit; + +import junit.framework.TestCase; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.core.SlcException; +import org.argeo.slc.spring.SpringUtils; + +/** Helper for tests using a Spring application co,text. */ +public abstract class AbstractSpringTestCase extends TestCase { + protected final Log log = LogFactory.getLog(getClass()); + private ApplicationContext context; + + /** + * Gets (and create if necessary) the application context to use. Default + * implementation uses a class path xml application context and calls + * {@link #getApplicationContextLocation()}. + */ + protected ApplicationContext getContext() { + if (context == null) { + context = new ClassPathXmlApplicationContext( + getApplicationContextLocation()); + } + return context; + } + + /** Returns a bean from the underlying context */ + protected T getBean(String beanId) { + return (T) getContext().getBean(beanId); + } + + protected T getBean(Class clss) { + T bean = SpringUtils.loadSingleFromContext(getContext(), clss); + if (bean == null) { + throw new SlcException("Cannot retrieve a unique bean of type " + + clss); + } else { + return bean; + } + } + + /** + * Th location of the application to load. The default implementation + * returns applicationContext.xml found in the same package as the + * test. + */ + protected String getApplicationContextLocation() { + return inPackage("applicationContext.xml"); + } + + /** + * Prefixes the package of the class after converting the '.' to '/' in + * order to have a resource path. + */ + protected String inPackage(String suffix) { + String prefix = getClass().getPackage().getName().replace('.', '/'); + return prefix + '/' + suffix; + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/UnitUtils.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/UnitUtils.java new file mode 100644 index 000000000..e88deed01 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/UnitUtils.java @@ -0,0 +1,42 @@ +package org.argeo.slc.unit; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertNotNull; + +public abstract class UnitUtils { + public static void assertDateSec(Date expected, Date reached) { + if (expected == null) { + assertNull(reached); + return; + } else { + assertNotNull(reached); + } + + Calendar expectedCal = new GregorianCalendar(); + expectedCal.setTime(expected); + Calendar reachedCal = new GregorianCalendar(); + reachedCal.setTime(reached); + assertEquals(expectedCal.get(Calendar.YEAR), reachedCal + .get(Calendar.YEAR)); + assertEquals(expectedCal.get(Calendar.MONTH), reachedCal + .get(Calendar.MONTH)); + assertEquals(expectedCal.get(Calendar.DATE), reachedCal + .get(Calendar.DATE)); + assertEquals(expectedCal.get(Calendar.HOUR_OF_DAY), reachedCal + .get(Calendar.HOUR_OF_DAY)); + assertEquals(expectedCal.get(Calendar.MINUTE), reachedCal + .get(Calendar.MINUTE)); + assertEquals(expectedCal.get(Calendar.SECOND), reachedCal + .get(Calendar.SECOND)); + } + + private UnitUtils() { + + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/UnitXmlUtils.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/UnitXmlUtils.java new file mode 100644 index 000000000..af6f92320 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/UnitXmlUtils.java @@ -0,0 +1,39 @@ +package org.argeo.slc.unit; + +import java.io.IOException; + +import javax.xml.transform.Source; + +import junit.framework.TestCase; + +import org.springframework.xml.validation.XmlValidator; +import org.springframework.xml.xsd.XsdSchema; +import org.xml.sax.SAXParseException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public abstract class UnitXmlUtils { + private final static Log log = LogFactory.getLog(UnitXmlUtils.class); + + public static void assertXsdSchemaValidation(XsdSchema schema, Source source) + throws IOException { + XmlValidator validator = schema.createValidator(); + assertXmlValidation(validator, source); + } + + public static void assertXmlValidation(XmlValidator validator, Source source) + throws IOException { + SAXParseException[] exceptions = validator.validate(source); + if (exceptions.length != 0) { + for (SAXParseException ex : exceptions) { + log.error(ex.getMessage()); + } + TestCase.fail("Could not validate"); + } + } + + private UnitXmlUtils() { + + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/package.html b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/package.html new file mode 100644 index 000000000..907430d09 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/package.html @@ -0,0 +1,6 @@ + + + +Helpers for unit tests. + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/process/SlcExecutionTestUtils.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/process/SlcExecutionTestUtils.java new file mode 100644 index 000000000..70400da54 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/process/SlcExecutionTestUtils.java @@ -0,0 +1,54 @@ +package org.argeo.slc.unit.process; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static org.argeo.slc.unit.UnitUtils.assertDateSec; + +import java.util.UUID; + +import org.argeo.slc.core.process.SlcExecution; +import org.argeo.slc.core.process.SlcExecutionStep; + +public abstract class SlcExecutionTestUtils { + + public static SlcExecution createSimpleSlcExecution() { + SlcExecution slcExec = new SlcExecution(); + slcExec.setUuid(UUID.randomUUID().toString()); + slcExec.setHost("localhost"); + slcExec.setUser("user"); + slcExec.setType("slcAnt"); + slcExec.setStatus("STARTED"); + slcExec.getAttributes().put("ant.file", "/test"); + return slcExec; + } + + public static void assertSlcExecution(SlcExecution expected, + SlcExecution reached) { + assertNotNull(reached); + assertEquals(expected.getHost(), reached.getHost()); + assertEquals(expected.getUser(), reached.getUser()); + assertEquals(expected.getType(), reached.getType()); + assertEquals(expected.getStatus(), reached.getStatus()); + assertEquals(expected.getAttributes().size(), reached.getAttributes() + .size()); + for (String key : expected.getAttributes().keySet()) { + String expectedValue = expected.getAttributes().get(key); + String reachedValue = reached.getAttributes().get(key); + assertNotNull(reachedValue); + assertEquals(expectedValue, reachedValue); + } + } + + public static void assertSlcExecutionStep(SlcExecutionStep expected, + SlcExecutionStep reached) { + assertNotNull(reached); + assertEquals(expected.getUuid(), reached.getUuid()); + assertEquals(expected.getType(), reached.getType()); + assertEquals(expected.logAsString(), reached.logAsString()); + assertDateSec(expected.getBegin(), reached.getBegin()); + } + + private SlcExecutionTestUtils() { + + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/test/tree/TreeTestResultTestUtils.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/test/tree/TreeTestResultTestUtils.java new file mode 100644 index 000000000..944fe2e64 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/test/tree/TreeTestResultTestUtils.java @@ -0,0 +1,107 @@ +package org.argeo.slc.unit.test.tree; + +import java.util.UUID; + +import org.argeo.slc.core.build.Distribution; +import org.argeo.slc.core.deploy.DeployedSystem; +import org.argeo.slc.core.process.SlcExecution; +import org.argeo.slc.core.process.SlcExecutionStep; +import org.argeo.slc.core.structure.SimpleSElement; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.structure.tree.TreeSRegistry; +import org.argeo.slc.core.test.SimpleResultPart; +import org.argeo.slc.core.test.SimpleTestRun; +import org.argeo.slc.core.test.TestStatus; +import org.argeo.slc.core.test.tree.PartSubList; +import org.argeo.slc.core.test.tree.TreeTestResult; +import org.argeo.slc.msg.test.tree.ResultPartRequest; +import org.argeo.slc.unit.process.SlcExecutionTestUtils; + +public abstract class TreeTestResultTestUtils { + + public static TreeTestResult createSimpleTreeTestResult() { + TreeTestResult treeTestResult = new TreeTestResult(); + treeTestResult.setUuid(UUID.randomUUID().toString()); + return treeTestResult; + } + + public static TreeTestResult createCompleteTreeTestResult() { + SlcExecution slcExecution = SlcExecutionTestUtils + .createSimpleSlcExecution(); + SlcExecutionStep step = new SlcExecutionStep("LOG", "JUnit step"); + slcExecution.getSteps().add(step); + + SimpleTestRun testRun = new SimpleTestRun(); + testRun.setUuid(UUID.randomUUID().toString()); + + String pathStr = "/test"; + TreeSPath path = new TreeSPath(pathStr); + + TreeSRegistry registry = new TreeSRegistry(); + SimpleSElement elem = new SimpleSElement("Unit Test"); + elem.getTags().put("myTag", "myTagValue"); + registry.register(path, elem); + + TreeTestResult ttr = createSimpleTreeTestResult(); + ttr.notifyCurrentPath(registry, path); + ttr.notifyTestRun(testRun); + testRun.setTestResult(ttr); + testRun.setDeployedSystem(new DeployedSystem() { + private String uuid = UUID.randomUUID().toString(); + + public String getDeployedSystemId() { + return uuid; + } + + public Distribution getDistribution() { + return null; + } + }); + testRun.notifySlcExecution(slcExecution); + + ttr.addResultPart(createSimpleResultPartPassed()); + ttr.addResultPart(createSimpleResultPartFailed()); + ttr.addResultPart(createSimpleResultPartError()); + return ttr; + } + + public static SimpleResultPart createSimpleResultPartPassed() { + SimpleResultPart partPassed = new SimpleResultPart(); + String msgPassed = "message\nnew line"; + partPassed.setStatus(TestStatus.PASSED); + partPassed.setMessage(msgPassed); + return partPassed; + } + + public static SimpleResultPart createSimpleResultPartFailed() { + SimpleResultPart partFailed = new SimpleResultPart(); + String msgFailed = "too bad"; + partFailed.setStatus(TestStatus.FAILED); + partFailed.setMessage(msgFailed); + return partFailed; + } + + public static SimpleResultPart createSimpleResultPartError() { + SimpleResultPart partFailed = new SimpleResultPart(); + String msgFailed = "crashed\nanother line"; + partFailed.setStatus(TestStatus.ERROR); + partFailed.setMessage(msgFailed); + partFailed.setException(new Exception("Test Exception")); + return partFailed; + } + + public static ResultPartRequest createSimpleResultPartRequest(TreeTestResult ttr) { + TreeSPath path = ttr.getCurrentPath(); + PartSubList lst = ttr.getResultParts().get(path); + SimpleResultPart part = (SimpleResultPart) lst.getParts().get(2); + + ResultPartRequest req = new ResultPartRequest(ttr, path, part); + req.setPath(ttr.getCurrentPath()); + + return req; + } + + private TreeTestResultTestUtils() { + + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/test/tree/UnitTestTreeUtil.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/test/tree/UnitTestTreeUtil.java new file mode 100644 index 000000000..1862055fa --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/unit/test/tree/UnitTestTreeUtil.java @@ -0,0 +1,148 @@ +package org.argeo.slc.unit.test.tree; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.fail; +import static org.argeo.slc.unit.UnitUtils.assertDateSec; + +import org.argeo.slc.core.structure.SimpleSElement; +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.test.SimpleResultPart; +import org.argeo.slc.core.test.TestResultPart; +import org.argeo.slc.core.test.tree.PartSubList; +import org.argeo.slc.core.test.tree.TreeTestResult; + +/** Utilities for unit tests. */ +public class UnitTestTreeUtil { + private final static Log log = LogFactory.getLog(UnitTestTreeUtil.class); + + public static void assertTreeTestResult(TreeTestResult expected, + TreeTestResult reached) { + assertEquals(expected.getUuid(), reached.getUuid()); + assertDateSec(expected.getCloseDate(), reached.getCloseDate()); + + assertEquals(expected.getResultParts().size(), reached.getResultParts() + .size()); + for (TreeSPath path : expected.getResultParts().keySet()) { + PartSubList lstExpected = expected.getResultParts().get(path); + PartSubList lstReached = expected.getResultParts().get(path); + if (lstReached == null) { + fail("No result for path " + path); + return; + } + assertPartSubList(lstExpected, lstReached); + } + + assertEquals(expected.getElements().size(), reached.getElements() + .size()); + for (TreeSPath path : expected.getElements().keySet()) { + // String nameExpected = expected.getElements().get(path); + // String nameReached = expected.getElements().get(path); + SimpleSElement elemExpected = (SimpleSElement) expected + .getElements().get(path); + SimpleSElement elemReached = (SimpleSElement) expected + .getElements().get(path); + assertNotNull(elemReached); + assertElements(elemExpected, elemReached); + } + + } + + public static void assertElements(SimpleSElement expected, + SimpleSElement reached) { + assertEquals(expected.getLabel(), reached.getLabel()); + assertEquals(expected.getTags().size(), reached.getTags().size()); + for (String tagName : expected.getTags().keySet()) { + String expectedTagValue = expected.getTags().get(tagName); + String reachedTagValue = reached.getTags().get(tagName); + assertNotNull(reachedTagValue); + assertEquals(expectedTagValue, reachedTagValue); + } + } + + public static void assertPartSubList(PartSubList lstExpected, + PartSubList lstReached) { + assertEquals(lstExpected.getParts().size(), lstReached.getParts() + .size()); + for (int i = 0; i < lstExpected.getParts().size(); i++) { + assertPart(lstExpected.getParts().get(i), lstReached.getParts() + .get(i)); + } + } + + /** Asserts one part of a tree test result */ + public static void assertPart(TreeTestResult testResult, String pathStr, + int index, Integer status, String message) { + TreeSPath path = new TreeSPath(pathStr); + PartSubList list = testResult.getResultParts().get(path); + if (list == null) { + fail("No result for path " + path); + return; + } + if (index >= list.getParts().size()) { + fail("Not enough parts."); + } + SimpleResultPart part = (SimpleResultPart) list.getParts().get(index); + assertPart(part, status, message, null, part.getTestRunUuid(), true); + } + + public static void assertPart(TestResultPart expected, + TestResultPart reached) { + String expectedTestRunUuid = null; + if (expected instanceof SimpleResultPart) { + expectedTestRunUuid = ((SimpleResultPart) expected) + .getTestRunUuid(); + } + + assertPart(reached, expected.getStatus(), expected.getMessage(), + expected.getExceptionMessage(), expectedTestRunUuid, false); + } + + /** Assert one part of a tree test result. */ + private static void assertPart(TestResultPart part, Integer status, + String message, String exceptionDescription, + String expectedTestRunUuid, boolean skipExceptionMessage) { + assertEquals(status, part.getStatus()); + + if (log.isTraceEnabled()) { + log.trace("Expected message:" + message); + log.trace("Reached message:" + part.getMessage()); + } + assertEquals(message, part.getMessage()); + if (!skipExceptionMessage) { + if (exceptionDescription == null) { + assertNull(part.getExceptionMessage()); + } else { + if (log.isTraceEnabled()) { + log.trace("Expected exception message:" + + exceptionDescription); + log.trace("Reached exception message:" + + part.getExceptionMessage()); + } + + assertEquals(exceptionDescription, part.getExceptionMessage()); + } + } + + if (expectedTestRunUuid != null) { + SimpleResultPart reachedPart = (SimpleResultPart) part; + assertNotNull(reachedPart.getTestRunUuid()); + assertEquals(expectedTestRunUuid, reachedPart.getTestRunUuid()); + } else { + if (part instanceof SimpleResultPart) { + assertNull(((SimpleResultPart) part).getTestRunUuid()); + } + + } + + } + + /** Makes sure this is a singleton */ + private UnitTestTreeUtil() { + + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ws/client/ValidatingClientInterceptor.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ws/client/ValidatingClientInterceptor.java new file mode 100644 index 000000000..cd3add67c --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ws/client/ValidatingClientInterceptor.java @@ -0,0 +1,88 @@ +package org.argeo.slc.ws.client; + +import java.io.IOException; + +import javax.xml.transform.Source; + +import org.springframework.ws.client.WebServiceClientException; +import org.springframework.ws.client.WebServiceIOException; +import org.springframework.ws.client.support.interceptor.ClientInterceptor; +import org.springframework.ws.context.MessageContext; +import org.springframework.xml.validation.XmlValidator; +import org.xml.sax.SAXParseException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class ValidatingClientInterceptor implements ClientInterceptor { + private final static Log log = LogFactory + .getLog(ValidatingClientInterceptor.class); + + private Boolean validateRequest = true; + private Boolean validateResponse = false; + private XmlValidator validator = null; + + public boolean handleFault(MessageContext messageContext) + throws WebServiceClientException { + return true; + } + + public boolean handleRequest(MessageContext messageContext) + throws WebServiceClientException { + if (validateRequest) { + if (messageContext.getRequest() == null) + return true; + + Source source = messageContext.getRequest().getPayloadSource(); + try { + return validate(source); + } catch (IOException e) { + throw new WebServiceIOException("Cannot validate request", e); + } + } else { + return true; + } + } + + public boolean handleResponse(MessageContext messageContext) + throws WebServiceClientException { + if (validateResponse) { + if (messageContext.getResponse() == null) + return true; + + Source source = messageContext.getResponse().getPayloadSource(); + try { + return validate(source); + } catch (IOException e) { + throw new WebServiceIOException("Cannot validate response", e); + } + } else { + return true; + } + } + + protected boolean validate(Source source) throws IOException { + SAXParseException[] exceptions = validator.validate(source); + if (exceptions.length != 0) { + for (SAXParseException ex : exceptions) { + log.error(ex.getMessage()); + } + return false; + } else { + return true; + } + } + + public void setValidateRequest(Boolean validateRequest) { + this.validateRequest = validateRequest; + } + + public void setValidateResponse(Boolean validateResponse) { + this.validateResponse = validateResponse; + } + + public void setValidator(XmlValidator validator) { + this.validator = validator; + } + +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ws/client/WebServiceUtils.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ws/client/WebServiceUtils.java new file mode 100644 index 000000000..d37a27efe --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ws/client/WebServiceUtils.java @@ -0,0 +1,78 @@ +package org.argeo.slc.ws.client; + +import java.util.Iterator; + +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMSource; + +import org.springframework.ws.client.core.WebServiceTemplate; +import org.springframework.ws.soap.SoapFaultDetail; +import org.springframework.ws.soap.SoapFaultDetailElement; +import org.springframework.ws.soap.client.SoapFaultClientException; +import org.springframework.xml.transform.StringResult; +import org.w3c.dom.Node; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public abstract class WebServiceUtils { + private final static Log log = LogFactory.getLog(WebServiceUtils.class); + + public static Object marshalSendAndReceiveSafe(WebServiceTemplate template, + Object req) { + try { + Object resp = marshalSendAndReceive(template, req); + return resp; + } catch (Exception e) { + log.error("Cannot send web servicerequest: "+e.getMessage()); + if(log.isDebugEnabled()){ + log.debug("Webservice exception details: ",e); + } + return null; + } + } + + public static Object marshalSendAndReceive( + WebServiceTemplate template, Object req) { + if (log.isTraceEnabled()) { + try { + StringResult result = new StringResult(); + template.getMarshaller().marshal(req, result); + log.trace("About to send " + result); + } catch (Exception e) { + log.error("Cannot marshall " + req + " for logging", e); + } + } + Object resp = template.marshalSendAndReceive(req); + return resp; + } + + public static void manageSoapException(SoapFaultClientException e) { + log + .error("WS root cause: " + + e.getSoapFault().getFaultStringOrReason()); + StringBuffer stack = new StringBuffer(""); + SoapFaultDetail detail = e.getSoapFault().getFaultDetail(); + if (detail != null) { + Iterator it = (Iterator) detail + .getDetailEntries(); + while (it.hasNext()) { + SoapFaultDetailElement elem = it.next(); + if (elem.getName().getLocalPart().equals("StackElement")) { + Source source = elem.getSource(); + if (source instanceof DOMSource) { + Node node = ((DOMSource) source).getNode(); + stack.append(node.getTextContent()).append('\n'); + } + } + } + + if (stack.length() > 0 && log.isTraceEnabled()) + log.error("WS root cause stack: " + stack); + } + } + + private WebServiceUtils() { + + } +} diff --git a/org.argeo.slc.agent/src/main/resources/META-INF/services/org.apache.tools.ant.ProjectHelper b/org.argeo.slc.agent/src/main/resources/META-INF/services/org.apache.tools.ant.ProjectHelper new file mode 100644 index 000000000..1c222d5e1 --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/META-INF/services/org.apache.tools.ant.ProjectHelper @@ -0,0 +1 @@ +org.argeo.slc.ant.SlcProjectHelper \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/ant/taskdefs.properties b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/ant/taskdefs.properties new file mode 100644 index 000000000..85e0743c8 --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/ant/taskdefs.properties @@ -0,0 +1,5 @@ +# Tasks +slc.test=org.argeo.slc.ant.test.SlcTestTask +slc.deploy=org.argeo.slc.ant.deploy.SlcDeployTask +slc.closeResult=org.argeo.slc.ant.test.SlcCloseTestResultTask +slc.report=org.argeo.slc.ant.test.SlcReportTask diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/ant/typedefs.properties b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/ant/typedefs.properties new file mode 100644 index 000000000..0cb3b2c46 --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/ant/typedefs.properties @@ -0,0 +1,2 @@ +# Types +slc.context=org.argeo.slc.ant.test.ParentContextType diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/mapping.xml b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/mapping.xml new file mode 100644 index 000000000..92c2c71d0 --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/mapping.xml @@ -0,0 +1,41 @@ + + + + Mapping of generic types + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/msg/mapping.xml b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/msg/mapping.xml new file mode 100644 index 000000000..f695f9573 --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/msg/mapping.xml @@ -0,0 +1,82 @@ + + + + Message objects XML mapping + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/process/mapping.xml b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/process/mapping.xml new file mode 100644 index 000000000..1b5b2ec95 --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/process/mapping.xml @@ -0,0 +1,51 @@ + + + + + + Process objects XML mapping + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/spring/applicationContext.xml b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/spring/applicationContext.xml new file mode 100644 index 000000000..068d773fb --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/spring/applicationContext.xml @@ -0,0 +1,40 @@ + + + + + + + classpath:org/argeo/slc/castor/msg/mapping.xml + + + classpath:org/argeo/slc/castor/process/mapping.xml + + + classpath:org/argeo/slc/castor/structure/mapping.xml + + + classpath:org/argeo/slc/castor/test/mapping.xml + + + + + + + + + + + + + + + diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/structure/mapping.xml b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/structure/mapping.xml new file mode 100644 index 000000000..3e20025b3 --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/structure/mapping.xml @@ -0,0 +1,35 @@ + + + + Structure related objects XML mapping + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/test/mapping.xml b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/test/mapping.xml new file mode 100644 index 000000000..adfea8a9d --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/castor/test/mapping.xml @@ -0,0 +1,82 @@ + + + + Test objects XML mapping + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/spring/applicationContext.xml b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/spring/applicationContext.xml new file mode 100644 index 000000000..3e1cd53eb --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/spring/applicationContext.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/tree/basicReport.xslt b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/tree/basicReport.xslt new file mode 100644 index 000000000..947cef0f9 --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/tree/basicReport.xslt @@ -0,0 +1,50 @@ + + + + + + + + + Result + + +

+ Result + +

+ +

+ +

+ + + + + + + + + + + + + +
+ + + +
+
+ + +
+
\ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/tree/htmlreport/index.html b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/tree/htmlreport/index.html new file mode 100644 index 000000000..32beed3b5 --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/tree/htmlreport/index.html @@ -0,0 +1,16 @@ + + + +SLC test results + + + + + + <h2>Frame Alert</h2> + <p>This document is designed to be viewed using the frames feature. + If you see this message, you are using a non-frame-capable web client. + </p> + + + diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/tree/htmlreport/style.css b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/tree/htmlreport/style.css new file mode 100644 index 000000000..134c6b55d --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/core/test/tree/htmlreport/style.css @@ -0,0 +1,64 @@ +body { + font-family: sans-serif; + font-size: 12px; + color: black; + background-color: white; +} + +h1 { + font-family: sans-serif; + font-size: 16px; + font-weight: bold; + color: #000000; + padding: 0px 0px 5px 0px; + margin: 0px; +} + +h2 { + font-family: sans-serif; + font-size: 14px; + font-weight: bold; + color: #000000; + padding: 5px 0px 5px 0px; + margin: 0px; + margin-top: 5px; +} + +table,form { + margin: 0px; +} + +th { + font-size: 12px; + padding: 2px 20px 2px 2px; + vertical-align: top; + text-align: left; +} + +td { + font-size: 12px; + padding: 1px; + vertical-align: top; + text-align: left; +} + +.passed { + color: green; +} + +.failed { + color: red; +} + +a { + text-decoration: none; +} + +a.nav { + color: #0066CC; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/support/deploy/ant/build.xml b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/support/deploy/ant/build.xml new file mode 100644 index 000000000..693f5ecb9 --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/support/deploy/ant/build.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/ws/client/spring/applicationContext.xml b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/ws/client/spring/applicationContext.xml new file mode 100644 index 000000000..9bb2ff7f4 --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/ws/client/spring/applicationContext.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/xml/slc.xsd b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/xml/slc.xsd new file mode 100644 index 000000000..b457f18f0 --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/xml/slc.xsd @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/main/resources/org/argeo/slc/xml/spring/applicationContext.xml b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/xml/spring/applicationContext.xml new file mode 100644 index 000000000..13bd1dd03 --- /dev/null +++ b/org.argeo.slc.agent/src/main/resources/org/argeo/slc/xml/spring/applicationContext.xml @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/org.argeo.slc.agent/src/site/apt/index.apt b/org.argeo.slc.agent/src/site/apt/index.apt new file mode 100644 index 000000000..f414460db --- /dev/null +++ b/org.argeo.slc.agent/src/site/apt/index.apt @@ -0,0 +1 @@ +Argeo SLC Site \ No newline at end of file diff --git a/org.argeo.slc.agent/src/test/java/org/argeo/slc/ant/SlcAntTest.java b/org.argeo.slc.agent/src/test/java/org/argeo/slc/ant/SlcAntTest.java new file mode 100644 index 000000000..c19cdd4a2 --- /dev/null +++ b/org.argeo.slc.agent/src/test/java/org/argeo/slc/ant/SlcAntTest.java @@ -0,0 +1,24 @@ +package org.argeo.slc.ant; + +import java.net.URL; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.unit.AbstractSpringTestCase; + +public class SlcAntTest extends AbstractSpringTestCase { + private Log log = LogFactory.getLog(getClass()); + + public void testSimpleRun() { + // AntRegistryUtil.runAll(getClass().getResource( + // "/org/argeo/slc/ant/build.xml"), "test", null); + + URL url = getClass().getResource("/org/argeo/slc/ant/build.xml"); + log.info("Run Ant file from URL: " + url); + AntRunner antRunner = new AntRunner(getContext(), url, "test"); + + antRunner.run(); + } + +} diff --git a/org.argeo.slc.agent/src/test/java/org/argeo/slc/core/process/SlcExecutionCastorTest.java b/org.argeo.slc.agent/src/test/java/org/argeo/slc/core/process/SlcExecutionCastorTest.java new file mode 100644 index 000000000..8ede3a234 --- /dev/null +++ b/org.argeo.slc.agent/src/test/java/org/argeo/slc/core/process/SlcExecutionCastorTest.java @@ -0,0 +1,115 @@ +package org.argeo.slc.core.process; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.io.StringWriter; +import java.text.SimpleDateFormat; +import java.util.UUID; + +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.msg.process.SlcExecutionRequest; +import org.argeo.slc.msg.process.SlcExecutionStepsRequest; +import org.argeo.slc.unit.AbstractSpringTestCase; +import org.argeo.slc.unit.UnitXmlUtils; +import org.argeo.slc.unit.process.SlcExecutionTestUtils; + +import org.springframework.oxm.Marshaller; +import org.springframework.oxm.Unmarshaller; +import org.springframework.xml.transform.StringResult; +import org.springframework.xml.transform.StringSource; +import org.springframework.xml.validation.XmlValidator; +import org.springframework.xml.xsd.XsdSchema; + +public class SlcExecutionCastorTest extends AbstractSpringTestCase { + private Log log = LogFactory.getLog(getClass()); + + private Marshaller marshaller; + private Unmarshaller unmarshaller; + + @Override + public void setUp() { + marshaller = getBean(Marshaller.class); + unmarshaller = getBean(Unmarshaller.class); + } + + public void testMarshalling() throws Exception { + SlcExecution slcExec = SlcExecutionTestUtils.createSimpleSlcExecution(); + + SlcExecutionRequest msgSave = new SlcExecutionRequest(); + msgSave.setSlcExecution(slcExec); + + String msgSaveXml = marshallAndLog(marshaller, msgSave); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + SlcExecutionStep step0 = new SlcExecutionStep(); + step0.setUuid(UUID.randomUUID().toString()); + step0.setBegin(sdf.parse("2008-04-17 18:21")); + step0.setType("LOG"); + step0.addLog("A log message\nand another line"); + + SlcExecutionStep step1 = new SlcExecutionStep(); + step1.setUuid(UUID.randomUUID().toString()); + step1.setBegin(sdf.parse("2008-04-17 18:25")); + step1.setType("LOG"); + step1.addLog("A nother log message"); + + SlcExecutionStepsRequest msgNotif = new SlcExecutionStepsRequest(); + msgNotif.addStep(step0); + msgNotif.addStep(step1); + msgNotif.setSlcExecutionUuid(slcExec.getUuid()); + + String msgNotifXml = marshallAndLog(marshaller, msgNotif); + + SlcExecutionRequest msgSaveUnm = unmarshall(unmarshaller, msgSaveXml); + assertNotNull(msgSaveUnm); + SlcExecutionTestUtils.assertSlcExecution(slcExec, msgSaveUnm + .getSlcExecution()); + + SlcExecutionStepsRequest msgNotifUnm = unmarshall(unmarshaller, + msgNotifXml); + assertNotNull(msgNotifUnm); + assertEquals(slcExec.getUuid(), msgNotifUnm.getSlcExecutionUuid()); + assertEquals(2, msgNotifUnm.getSteps().size()); + SlcExecutionTestUtils.assertSlcExecutionStep(step0, msgNotifUnm + .getSteps().get(0)); + SlcExecutionTestUtils.assertSlcExecutionStep(step1, msgNotifUnm + .getSteps().get(1)); + + SlcExecution slcExecUnm = msgSaveUnm.getSlcExecution(); + slcExecUnm.getSteps().addAll(msgNotifUnm.getSteps()); + + SlcExecutionRequest msgUpdate = new SlcExecutionRequest(); + msgUpdate.setSlcExecution(slcExecUnm); + String msgUpdateXml = marshallAndLog(marshaller, msgUpdate); + + SlcExecutionRequest msgUpdateUnm = unmarshall(unmarshaller, + msgUpdateXml); + assertNotNull(msgUpdateUnm); + } + + private String marshallAndLog(Marshaller marshaller, Object obj) + throws IOException { + StringResult xml = new StringResult(); + marshaller.marshal(obj, xml); + log.info("Marshalled object: " + xml); + + UnitXmlUtils.assertXmlValidation(getBean(XmlValidator.class), + new StringSource(xml.toString())); + + return xml.toString(); + } + + private T unmarshall(Unmarshaller unmarshaller, String xml) + throws IOException { + StringReader reader = new StringReader(xml); + Object obj = unmarshaller.unmarshal(new StreamSource(reader)); + IOUtils.closeQuietly(reader); + return (T) obj; + } +} diff --git a/org.argeo.slc.agent/src/test/java/org/argeo/slc/core/structure/tree/TreeSPathTest.java b/org.argeo.slc.agent/src/test/java/org/argeo/slc/core/structure/tree/TreeSPathTest.java new file mode 100644 index 000000000..fab683111 --- /dev/null +++ b/org.argeo.slc.agent/src/test/java/org/argeo/slc/core/structure/tree/TreeSPathTest.java @@ -0,0 +1,57 @@ +package org.argeo.slc.core.structure.tree; + +import junit.framework.TestCase; + +public class TreeSPathTest extends TestCase { + + public void testNew() { + TreeSPath path = new TreeSPath("/test"); + assertEquals("test", path.getName()); + assertNull(path.getParent()); + + path = new TreeSPath("/root/subdir"); + assertEquals("subdir", path.getName()); + assertEquals(new TreeSPath("/root"), path.getParent()); + } + + public void testEquals() { + TreeSPath path1 = new TreeSPath("/test"); + TreeSPath path2 = new TreeSPath("/test"); + assertEquals(path1, path2); + + path1 = new TreeSPath("/test/subdir/anotherdir"); + path2 = new TreeSPath("/test/subdir/anotherdir"); + assertEquals(path1, path2); + + path1 = new TreeSPath("/test/subdir/anotherd"); + path2 = new TreeSPath("/test/subdir/anotherdir"); + assertNotSame(path1, path2); + + path1 = new TreeSPath("/test/subdir"); + path2 = new TreeSPath("/test/subdir/anotherdir"); + assertNotSame(path1, path2); + + path1 = new TreeSPath("/test/subd/anotherdir"); + path2 = new TreeSPath("/test/subdir/anotherdir"); + assertNotSame(path1, path2); + } + + public void testCheckFormat(){ + try{ + new TreeSPath("hello"); + fail("Bad format should be rejected"); + }catch(Exception e){ + // exception expected + } + + try{ + new TreeSPath("/"); + fail("Bad format should be rejected"); + }catch(Exception e){ + // exception expected + } + + assertEquals(new TreeSPath("/test"), new TreeSPath("/test/")); + assertEquals(new TreeSPath("/test/dir"), new TreeSPath("//test///dir////")); + } +} diff --git a/org.argeo.slc.agent/src/test/java/org/argeo/slc/core/test/context/ContextTest.java b/org.argeo.slc.agent/src/test/java/org/argeo/slc/core/test/context/ContextTest.java new file mode 100644 index 000000000..6d53ef7e3 --- /dev/null +++ b/org.argeo.slc.agent/src/test/java/org/argeo/slc/core/test/context/ContextTest.java @@ -0,0 +1,30 @@ +package org.argeo.slc.core.test.context; + +import java.util.List; + +import org.argeo.slc.core.test.SimpleTestResult; +import org.argeo.slc.core.test.TestResultPart; +import org.argeo.slc.core.test.TestStatus; +import org.argeo.slc.unit.AbstractSpringTestCase; + +public class ContextTest extends AbstractSpringTestCase { + + public void testComplexContext() { + SimpleTestResult testResult = new SimpleTestResult(); + ContextUtils.compareReachedExpected( + (ContextAware) getBean("context.c1"), testResult, null); + ContextUtils.compareReachedExpected( + (ContextAware) getBean("context.c2"), testResult, null); + ContextUtils.compareReachedExpected( + (ContextAware) getBean("context.c3"), testResult, null); + + List parts = testResult.getParts(); + assertEquals(6, parts.size()); + assertEquals(TestStatus.PASSED, parts.get(0).getStatus()); + assertEquals(TestStatus.PASSED, parts.get(1).getStatus()); + assertEquals(TestStatus.PASSED, parts.get(2).getStatus()); + assertEquals(TestStatus.FAILED, parts.get(3).getStatus()); + assertEquals(TestStatus.PASSED, parts.get(4).getStatus()); + assertEquals(TestStatus.PASSED, parts.get(5).getStatus()); + } +} diff --git a/org.argeo.slc.agent/src/test/java/org/argeo/slc/core/test/tree/TreeTestResultCastorTest.java b/org.argeo.slc.agent/src/test/java/org/argeo/slc/core/test/tree/TreeTestResultCastorTest.java new file mode 100644 index 000000000..aec7a68b4 --- /dev/null +++ b/org.argeo.slc.agent/src/test/java/org/argeo/slc/core/test/tree/TreeTestResultCastorTest.java @@ -0,0 +1,100 @@ +package org.argeo.slc.core.test.tree; + +import org.springframework.oxm.Marshaller; +import org.springframework.oxm.Unmarshaller; +import org.springframework.xml.transform.StringResult; +import org.springframework.xml.transform.StringSource; +import org.springframework.xml.validation.XmlValidator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import static org.argeo.slc.unit.UnitUtils.assertDateSec; +import static org.argeo.slc.unit.test.tree.TreeTestResultTestUtils.createCompleteTreeTestResult; +import static org.argeo.slc.unit.test.tree.TreeTestResultTestUtils.createSimpleResultPartRequest; + +import org.argeo.slc.core.structure.tree.TreeSPath; +import org.argeo.slc.core.test.SimpleResultPart; +import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest; +import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest; +import org.argeo.slc.msg.test.tree.ResultPartRequest; +import org.argeo.slc.unit.AbstractSpringTestCase; +import org.argeo.slc.unit.UnitXmlUtils; +import org.argeo.slc.unit.test.tree.UnitTestTreeUtil; + +public class TreeTestResultCastorTest extends AbstractSpringTestCase { + private Log log = LogFactory.getLog(getClass()); + + private Marshaller marshaller; + private Unmarshaller unmarshaller; + + @Override + public void setUp() { + marshaller = getBean(Marshaller.class); + unmarshaller = getBean(Unmarshaller.class); + } + + public void testMarshUnmarsh() throws Exception { + TreeTestResult ttr = createCompleteTreeTestResult(); + + StringResult xml = marshallAndValidate(ttr); + + TreeTestResult ttrUnm = (TreeTestResult) unmarshaller + .unmarshal(new StringSource(xml.toString())); + + UnitTestTreeUtil.assertTreeTestResult(ttr, ttrUnm); + } + + public void testCreateTreeTestResultRequest() throws Exception { + CreateTreeTestResultRequest req = new CreateTreeTestResultRequest(); + req.setTreeTestResult(createCompleteTreeTestResult()); + + StringResult xml = marshallAndValidate(req); + + CreateTreeTestResultRequest reqUnm = (CreateTreeTestResultRequest) unmarshaller + .unmarshal(new StringSource(xml.toString())); + + UnitTestTreeUtil.assertTreeTestResult(req.getTreeTestResult(), reqUnm + .getTreeTestResult()); + } + + public void testResultPartRequest() throws Exception { + TreeTestResult ttr = createCompleteTreeTestResult(); + ResultPartRequest req = createSimpleResultPartRequest(ttr); + + StringResult xml = marshallAndValidate(req); + + ResultPartRequest reqUnm = (ResultPartRequest) unmarshaller + .unmarshal(new StringSource(xml.toString())); + + UnitTestTreeUtil + .assertPart(req.getResultPart(), reqUnm.getResultPart()); + } + + public void testCloseTreeTestResultRequest() throws Exception { + TreeTestResult ttr = createCompleteTreeTestResult(); + ttr.close(); + + CloseTreeTestResultRequest req = new CloseTreeTestResultRequest(ttr + .getUuid(), ttr.getCloseDate()); + + StringResult xml = marshallAndValidate(req); + + CloseTreeTestResultRequest reqUnm = (CloseTreeTestResultRequest) unmarshaller + .unmarshal(new StringSource(xml.toString())); + + assertEquals(ttr.getUuid(), reqUnm.getResultUuid()); + assertDateSec(ttr.getCloseDate(), ttr.getCloseDate()); + } + + private StringResult marshallAndValidate(Object obj) throws Exception { + StringResult xml = new StringResult(); + marshaller.marshal(obj, xml); + + log.info("Marshalled ResultPart Request: " + xml); + + UnitXmlUtils.assertXmlValidation(getBean(XmlValidator.class), + new StringSource(xml.toString())); + return xml; + } +} diff --git a/org.argeo.slc.agent/src/test/java/org/argeo/slc/diff/LineTokenizerTest.java b/org.argeo.slc.agent/src/test/java/org/argeo/slc/diff/LineTokenizerTest.java new file mode 100644 index 000000000..58ed61a92 --- /dev/null +++ b/org.argeo.slc.agent/src/test/java/org/argeo/slc/diff/LineTokenizerTest.java @@ -0,0 +1,53 @@ +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", ',', "", + new String[] { "hello", "", "bonjour", "", + "hallo", "priviet" }); + } + + private void testAndAssert(String str, String[] expected) { + testAndAssert(str, ',', "", expected); + } + + private void testAndAssert(String str, Character sep, String noValueStr, + String[] expected) { + List 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); + } + } +} diff --git a/org.argeo.slc.agent/src/test/java/org/argeo/slc/ws/SlcAntWsIntegrationTest.java b/org.argeo.slc.agent/src/test/java/org/argeo/slc/ws/SlcAntWsIntegrationTest.java new file mode 100644 index 000000000..7b3d662f7 --- /dev/null +++ b/org.argeo.slc.agent/src/test/java/org/argeo/slc/ws/SlcAntWsIntegrationTest.java @@ -0,0 +1,25 @@ +package org.argeo.slc.ws; + +import java.net.URL; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.ant.AntRunner; +import org.argeo.slc.unit.AbstractSpringTestCase; + +public class SlcAntWsIntegrationTest extends AbstractSpringTestCase { + private Log log = LogFactory.getLog(getClass()); + + public void testSimpleRun() { + // AntRegistryUtil.runAll(getClass().getResource( + // "/org/argeo/slc/ant/build.xml"), "test", null); + + URL url = getClass().getResource("/org/argeo/slc/ant/build.xml"); + log.info("Run Ant file from URL: " + url); + AntRunner antRunner = new AntRunner(getContext(), url, "test"); + + antRunner.run(); + } + +} diff --git a/org.argeo.slc.agent/src/test/java/org/argeo/slc/ws/SlcExecutionWsIntegrationTest.java b/org.argeo.slc.agent/src/test/java/org/argeo/slc/ws/SlcExecutionWsIntegrationTest.java new file mode 100644 index 000000000..47d584f23 --- /dev/null +++ b/org.argeo.slc.agent/src/test/java/org/argeo/slc/ws/SlcExecutionWsIntegrationTest.java @@ -0,0 +1,29 @@ +package org.argeo.slc.ws; + +import org.springframework.ws.client.core.WebServiceTemplate; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.argeo.slc.core.process.SlcExecution; +import org.argeo.slc.msg.process.SlcExecutionRequest; +import org.argeo.slc.unit.AbstractSpringTestCase; +import org.argeo.slc.unit.process.SlcExecutionTestUtils; + +public class SlcExecutionWsIntegrationTest extends AbstractSpringTestCase { + private Log log = LogFactory.getLog(getClass()); + + public void testSendSlcExecutionrequest() { + WebServiceTemplate template = getBean(WebServiceTemplate.class); + SlcExecution slcExec = SlcExecutionTestUtils.createSimpleSlcExecution(); + + SlcExecutionRequest req = new SlcExecutionRequest(); + req.setSlcExecution(slcExec); + + log.info("Send SlcExecutionRequest for SlcExecution " + + slcExec.getUuid()); + + Object resp = template.marshalSendAndReceive(req); + log.info("Resp: " + resp); + } +} diff --git a/org.argeo.slc.agent/src/test/java/org/argeo/slc/ws/TreeTestResultWsIntegrationTest.java b/org.argeo.slc.agent/src/test/java/org/argeo/slc/ws/TreeTestResultWsIntegrationTest.java new file mode 100644 index 000000000..7796c26d7 --- /dev/null +++ b/org.argeo.slc.agent/src/test/java/org/argeo/slc/ws/TreeTestResultWsIntegrationTest.java @@ -0,0 +1,70 @@ +package org.argeo.slc.ws; + +import org.springframework.ws.client.core.WebServiceTemplate; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import static org.argeo.slc.unit.test.tree.TreeTestResultTestUtils.createCompleteTreeTestResult; +import static org.argeo.slc.unit.test.tree.TreeTestResultTestUtils.createSimpleResultPartRequest; + +import org.argeo.slc.core.test.tree.TreeTestResult; +import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest; +import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest; +import org.argeo.slc.msg.test.tree.ResultPartRequest; +import org.argeo.slc.unit.AbstractSpringTestCase; + +public class TreeTestResultWsIntegrationTest extends AbstractSpringTestCase { + private Log log = LogFactory.getLog(getClass()); + + public void testCreateTreeTestResultRequest() { + WebServiceTemplate template = getBean(WebServiceTemplate.class); + CreateTreeTestResultRequest req = new CreateTreeTestResultRequest( + createCompleteTreeTestResult()); + req.getTreeTestResult().close();// in order to avoid unclosed in test db + + log.info("Send CreateTreeTestResultRequest for result " + + req.getTreeTestResult().getUuid()); + + Object resp = template.marshalSendAndReceive(req); + log.info("Resp: " + resp); + } + + public void testResultPartRequest() { + WebServiceTemplate template = getBean(WebServiceTemplate.class); + TreeTestResult ttr = createCompleteTreeTestResult(); + ttr.close();// in order to avoid unclosed in test db + CreateTreeTestResultRequest reqCreate = new CreateTreeTestResultRequest( + ttr); + log.info("Send CreateTreeTestResultRequest for result " + + reqCreate.getTreeTestResult().getUuid()); + template.marshalSendAndReceive(reqCreate); + + ResultPartRequest req = createSimpleResultPartRequest(ttr); + + log.info("Send ResultPartRequest for result " + req.getResultUuid()); + Object resp = template.marshalSendAndReceive(req); + log.info("Resp: " + resp); + } + + public void testCloseTreeTestResultRequest() { + WebServiceTemplate template = getBean(WebServiceTemplate.class); + + TreeTestResult ttr = createCompleteTreeTestResult(); + CreateTreeTestResultRequest reqCreate = new CreateTreeTestResultRequest( + ttr); + log.info("Send CreateTreeTestResultRequest for result " + + reqCreate.getTreeTestResult().getUuid()); + template.marshalSendAndReceive(reqCreate); + + ttr.close(); + CloseTreeTestResultRequest req = new CloseTreeTestResultRequest(ttr + .getUuid(), ttr.getCloseDate()); + + log.info("Send CloseTreeTestResultRequest for result " + + req.getResultUuid()); + + Object resp = template.marshalSendAndReceive(req); + log.info("Resp: " + resp); + } +} diff --git a/org.argeo.slc.agent/src/test/resources/log4j.properties b/org.argeo.slc.agent/src/test/resources/log4j.properties new file mode 100644 index 000000000..605a28c48 --- /dev/null +++ b/org.argeo.slc.agent/src/test/resources/log4j.properties @@ -0,0 +1,27 @@ +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=INFO, console + +## Levels +# Slc +log4j.logger.org.argeo=DEBUG + +# Castor +log4j.logger.org.exolab.castor=WARN + +# Spring +log4j.logger.org.springframework=INFO +# Hibernate +log4j.logger.org.hibernate=WARN +#log4j.logger.org.hibernate.SQL=TRACE +#log4j.logger.org.hibernate.tool.hbm2ddl=TRACE +#log4j.logger.org.hibernate.type=TRACE + + +## Appenders +# A1 is set to be a ConsoleAppender. +log4j.appender.console=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c%n + diff --git a/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/applicationContext.xml b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/applicationContext.xml new file mode 100644 index 000000000..6ff9b8522 --- /dev/null +++ b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/applicationContext.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/build.xml b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/build.xml new file mode 100644 index 000000000..f2ea5c52c --- /dev/null +++ b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/build.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/nonDepContext.xml b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/nonDepContext.xml new file mode 100644 index 000000000..56da88a8b --- /dev/null +++ b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ant/nonDepContext.xml @@ -0,0 +1,42 @@ + + + + + + + + + + toto + + + toto + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/test/resources/org/argeo/slc/castor/applicationContext.xml b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/castor/applicationContext.xml new file mode 100644 index 000000000..7a89af927 --- /dev/null +++ b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/castor/applicationContext.xml @@ -0,0 +1,11 @@ + + + + diff --git a/org.argeo.slc.agent/src/test/resources/org/argeo/slc/core/process/applicationContext.xml b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/core/process/applicationContext.xml new file mode 100644 index 000000000..899daf548 --- /dev/null +++ b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/core/process/applicationContext.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/test/resources/org/argeo/slc/core/test/context/applicationContext.xml b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/core/test/context/applicationContext.xml new file mode 100644 index 000000000..e45899c11 --- /dev/null +++ b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/core/test/context/applicationContext.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/test/resources/org/argeo/slc/core/test/tree/applicationContext.xml b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/core/test/tree/applicationContext.xml new file mode 100644 index 000000000..9601c3301 --- /dev/null +++ b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/core/test/tree/applicationContext.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ws/applicationContext.xml b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ws/applicationContext.xml new file mode 100644 index 000000000..a94d128b3 --- /dev/null +++ b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ws/applicationContext.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ws/execution.xml b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ws/execution.xml new file mode 100644 index 000000000..bdb071b0c --- /dev/null +++ b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ws/execution.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ws/result.xml b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ws/result.xml new file mode 100644 index 000000000..ce5442d5e --- /dev/null +++ b/org.argeo.slc.agent/src/test/resources/org/argeo/slc/ws/result.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + \ No newline at end of file -- 2.39.2