X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=runtime%2Forg.argeo.slc.support.jcr%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fjcr%2FJcrTestResult.java;h=e3394e05cbbda6ecbcd8c11800487512d5b86e2b;hb=2ecb1e7ce15a25ba8026b5ded625f36c1be467bd;hp=74a31678df4dcce1d5f490491d990571431303fa;hpb=99acd32f30678d05eaacc6c5db41d6134d9ce6f9;p=gpl%2Fargeo-slc.git diff --git a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/JcrTestResult.java b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/JcrTestResult.java index 74a31678d..e3394e05c 100644 --- a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/JcrTestResult.java +++ b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/JcrTestResult.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed 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. + */ package org.argeo.slc.jcr; import java.util.Date; @@ -6,39 +21,70 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; +import javax.jcr.Credentials; import javax.jcr.Node; import javax.jcr.Property; import javax.jcr.PropertyIterator; +import javax.jcr.Repository; import javax.jcr.Session; import javax.jcr.query.Query; import javax.jcr.query.QueryManager; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.argeo.jcr.JcrUtils; import org.argeo.slc.SlcException; +import org.argeo.slc.core.attachment.Attachment; +import org.argeo.slc.core.attachment.AttachmentsEnabled; import org.argeo.slc.test.TestResult; import org.argeo.slc.test.TestResultPart; import org.argeo.slc.test.TestRun; import org.argeo.slc.test.TestStatus; -/** {@link TestResult} wrapping a JCR node of type {@link SlcTypes#SLC_RESULT}. */ -public class JcrTestResult implements TestResult, SlcNames { +/** + * {@link TestResult} wrapping a JCR node of type + * {@link SlcTypes#SLC_TEST_RESULT}. + */ +public class JcrTestResult implements TestResult, SlcNames, AttachmentsEnabled { + private final static Log log = LogFactory.getLog(JcrTestResult.class); + /** Should only be set for an already existing result. */ private String uuid; + private Repository repository; private Session session; - private String resultType = SlcTypes.SLC_RESULT; + /** + * For testing purposes, best practice is to not set them explicitely but + * via other mechanisms such as JAAS or SPring Security. + */ + private Credentials credentials = null; + private String resultType = SlcTypes.SLC_TEST_RESULT; /** cached for performance purposes */ private String nodeIdentifier = null; + private Map attributes = new HashMap(); + public void init() { try { + session = repository.login(credentials); if (uuid == null) { // create new result uuid = UUID.randomUUID().toString(); - String path = SlcJcrUtils.createResultPath(uuid); + String path = SlcJcrUtils.createResultPath(session, uuid); Node resultNode = JcrUtils.mkdirs(session, path, resultType); resultNode.setProperty(SLC_UUID, uuid); + for (String attr : attributes.keySet()) { + String property = attr; + // compatibility with legacy applications + if ("testCase".equals(attr)) + property = SLC_TEST_CASE; + else if ("testCaseType".equals(attr)) + property = SLC_TEST_CASE_TYPE; + resultNode.setProperty(property, attributes.get(attr)); + } session.save(); + if (log.isDebugEnabled()) + log.debug("Created test result " + uuid); } } catch (Exception e) { JcrUtils.discardQuietly(session); @@ -47,7 +93,9 @@ public class JcrTestResult implements TestResult, SlcNames { } public void destroy() { - + JcrUtils.logoutQuietly(session); + if (log.isTraceEnabled()) + log.trace("Logged out session for result " + uuid); } public Node getNode() { @@ -57,9 +105,9 @@ public class JcrTestResult implements TestResult, SlcNames { return session.getNodeByIdentifier(nodeIdentifier); } else { QueryManager qm = session.getWorkspace().getQueryManager(); - Query q = qm.createQuery( - "select * from [slc:result] where [slc:uuid]='" + uuid - + "'", Query.JCR_SQL2); + Query q = qm.createQuery("select * from [" + + SlcTypes.SLC_TEST_RESULT + "] where [slc:uuid]='" + + uuid + "'", Query.JCR_SQL2); resultNode = JcrUtils.querySingleNode(q); if (resultNode != null) nodeIdentifier = resultNode.getIdentifier(); @@ -71,29 +119,93 @@ public class JcrTestResult implements TestResult, SlcNames { } public void notifyTestRun(TestRun testRun) { + // TODO store meta data about the test running + // if (log.isDebugEnabled()) + // log.debug("Running test " + // + testRun.getTestDefinition().getClass().getName() + "..."); } public void addResultPart(TestResultPart testResultPart) { Node node = getNode(); + try { - // TODO: find a better way to name it by default - String partName = Long.toString(System.currentTimeMillis()); - Node resultPartNode = node.addNode(partName, SlcTypes.SLC_CHECK); - resultPartNode.setProperty(SLC_SUCCESS, - testResultPart.getStatus() == TestStatus.PASSED); + // error : revert all unsaved changes on the resultNode to be sure + // it is in a consistant state + if (testResultPart.getExceptionMessage() != null) + JcrUtils.discardQuietly(node.getSession()); + node.getSession().save(); + + // add the new result part, retrieving status information + Node resultPartNode = node.addNode(SlcNames.SLC_RESULT_PART, + SlcTypes.SLC_CHECK); + resultPartNode.setProperty(SLC_SUCCESS, testResultPart.getStatus() + .equals(TestStatus.PASSED)); if (testResultPart.getMessage() != null) resultPartNode.setProperty(SLC_MESSAGE, testResultPart.getMessage()); - if (testResultPart.getExceptionMessage() != null) + if (testResultPart.getStatus().equals(TestStatus.ERROR)) { resultPartNode.setProperty(SLC_ERROR_MESSAGE, - testResultPart.getExceptionMessage()); + (testResultPart.getExceptionMessage() == null) ? "" + : testResultPart.getExceptionMessage()); + } + + // helper update aggregate status node + Node mainStatus; + if (!node.hasNode(SLC_AGGREGATED_STATUS)) { + + mainStatus = node.addNode(SLC_AGGREGATED_STATUS, + SlcTypes.SLC_CHECK); + mainStatus.setProperty(SLC_SUCCESS, + resultPartNode.getProperty(SLC_SUCCESS).getBoolean()); + if (resultPartNode.hasProperty(SLC_MESSAGE)) + mainStatus.setProperty(SLC_MESSAGE, resultPartNode + .getProperty(SLC_MESSAGE).getString()); + if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE)) + mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode + .getProperty(SLC_ERROR_MESSAGE).getString()); + } else { + mainStatus = node.getNode(SLC_AGGREGATED_STATUS); + if (mainStatus.hasProperty(SLC_ERROR_MESSAGE)) { + // main status already in error we do nothing + } else if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE)) { + // main status was not in error and new result part is in + // error; we update main status + mainStatus.setProperty(SLC_SUCCESS, false); + mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode + .getProperty(SLC_ERROR_MESSAGE).getString()); + if (resultPartNode.hasProperty(SLC_MESSAGE)) + mainStatus.setProperty(SLC_MESSAGE, resultPartNode + .getProperty(SLC_MESSAGE).getString()); + else + // remove old message to remain consistent + mainStatus.setProperty(SLC_MESSAGE, ""); + } else if (!mainStatus.getProperty(SLC_SUCCESS).getBoolean()) { + // main status was already failed and new result part is not + // in error, we do nothing + } else if (!resultPartNode.getProperty(SLC_SUCCESS) + .getBoolean()) { + // new resultPart that is failed + mainStatus.setProperty(SLC_SUCCESS, false); + if (resultPartNode.hasProperty(SLC_MESSAGE)) + mainStatus.setProperty(SLC_MESSAGE, resultPartNode + .getProperty(SLC_MESSAGE).getString()); + else + // remove old message to remain consistent + mainStatus.setProperty(SLC_MESSAGE, ""); + } else if (resultPartNode.hasProperty(SLC_MESSAGE) + && (!mainStatus.hasProperty(SLC_MESSAGE) || ("" + .equals(mainStatus.getProperty(SLC_MESSAGE) + .getString().trim())))) { + mainStatus.setProperty(SLC_MESSAGE, resultPartNode + .getProperty(SLC_MESSAGE).getString()); + } + } JcrUtils.updateLastModified(node); node.getSession().save(); } catch (Exception e) { JcrUtils.discardUnderlyingSessionQuietly(node); - throw new SlcException("Cannot get UUID from " + node, e); + throw new SlcException("Cannot add ResultPart to node " + node, e); } - } public String getUuid() { @@ -105,6 +217,7 @@ public class JcrTestResult implements TestResult, SlcNames { } } + /** JCR session is NOT logged out */ public void close() { Node node = getNode(); try { @@ -146,16 +259,31 @@ public class JcrTestResult implements TestResult, SlcNames { } } + public void addAttachment(Attachment attachment) { + // TODO implement it + } + public void setUuid(String uuid) { this.uuid = uuid; } - public void setSession(Session session) { - this.session = session; + public void setRepository(Repository repository) { + this.repository = repository; } public void setResultType(String resultType) { this.resultType = resultType; } + public void setAttributes(Map attributes) { + if (uuid != null) + throw new SlcException( + "Attributes cannot be set on an already initialized test result." + + " Update the related JCR node directly instead."); + this.attributes = attributes; + } + + public void setCredentials(Credentials credentials) { + this.credentials = credentials; + } }