]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.jcr/src/org/argeo/slc/jcr/JcrTestResult.java
Merge remote-tracking branch 'origin/master' into testing
[gpl/argeo-slc.git] / org.argeo.slc.jcr / src / org / argeo / slc / jcr / JcrTestResult.java
1 package org.argeo.slc.jcr;
2
3 import java.util.Date;
4 import java.util.GregorianCalendar;
5 import java.util.HashMap;
6 import java.util.Map;
7 import java.util.UUID;
8
9 import javax.jcr.Credentials;
10 import javax.jcr.Node;
11 import javax.jcr.Property;
12 import javax.jcr.PropertyIterator;
13 import javax.jcr.Repository;
14 import javax.jcr.Session;
15 import javax.jcr.query.Query;
16 import javax.jcr.query.QueryManager;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.argeo.jcr.JcrUtils;
21 import org.argeo.slc.SlcException;
22 import org.argeo.slc.SlcNames;
23 import org.argeo.slc.SlcTypes;
24 import org.argeo.slc.attachment.Attachment;
25 import org.argeo.slc.attachment.AttachmentsEnabled;
26 import org.argeo.slc.test.TestResult;
27 import org.argeo.slc.test.TestResultPart;
28 import org.argeo.slc.test.TestRun;
29 import org.argeo.slc.test.TestStatus;
30
31 /**
32 * {@link TestResult} wrapping a JCR node of type
33 * {@link SlcTypes#SLC_TEST_RESULT}.
34 */
35 public class JcrTestResult implements TestResult, SlcNames, AttachmentsEnabled {
36 private final static Log log = LogFactory.getLog(JcrTestResult.class);
37
38 /** Should only be set for an already existing result. */
39 private String uuid;
40 private Repository repository;
41 private Session session;
42 /**
43 * For testing purposes, best practice is to not set them explicitely but
44 * via other mechanisms such as JAAS or SPring Security.
45 */
46 private Credentials credentials = null;
47 private String resultType = SlcTypes.SLC_TEST_RESULT;
48
49 /** cached for performance purposes */
50 private String nodeIdentifier = null;
51
52 private Map<String, String> attributes = new HashMap<String, String>();
53
54 public void init() {
55 try {
56 session = repository.login(credentials);
57 if (uuid == null) {
58 // create new result
59 uuid = UUID.randomUUID().toString();
60 String path = SlcJcrUtils.createResultPath(session, uuid);
61 Node resultNode = JcrUtils.mkdirs(session, path, resultType);
62 resultNode.setProperty(SLC_UUID, uuid);
63 for (String attr : attributes.keySet()) {
64 String property = attr;
65 // compatibility with legacy applications
66 if ("testCase".equals(attr))
67 property = SLC_TEST_CASE;
68 else if ("testCaseType".equals(attr))
69 property = SLC_TEST_CASE_TYPE;
70 resultNode.setProperty(property, attributes.get(attr));
71 }
72 session.save();
73 if (log.isDebugEnabled())
74 log.debug("Created test result " + uuid);
75 }
76 } catch (Exception e) {
77 JcrUtils.discardQuietly(session);
78 throw new SlcException("Cannot initialize JCR result", e);
79 }
80 }
81
82 public void destroy() {
83 JcrUtils.logoutQuietly(session);
84 if (log.isTraceEnabled())
85 log.trace("Logged out session for result " + uuid);
86 }
87
88 public Node getNode() {
89 try {
90 Node resultNode;
91 if (nodeIdentifier != null) {
92 return session.getNodeByIdentifier(nodeIdentifier);
93 } else {
94 QueryManager qm = session.getWorkspace().getQueryManager();
95 Query q = qm.createQuery("select * from ["
96 + SlcTypes.SLC_TEST_RESULT + "] where [slc:uuid]='"
97 + uuid + "'", Query.JCR_SQL2);
98 resultNode = JcrUtils.querySingleNode(q);
99 if (resultNode != null)
100 nodeIdentifier = resultNode.getIdentifier();
101 }
102 return resultNode;
103 } catch (Exception e) {
104 throw new SlcException("Cannot get result node", e);
105 }
106 }
107
108 public void notifyTestRun(TestRun testRun) {
109 // TODO store meta data about the test running
110 // if (log.isDebugEnabled())
111 // log.debug("Running test "
112 // + testRun.getTestDefinition().getClass().getName() + "...");
113 }
114
115 public void addResultPart(TestResultPart testResultPart) {
116 Node node = getNode();
117
118 try {
119 // error : revert all unsaved changes on the resultNode to be sure
120 // it is in a consistant state
121 if (testResultPart.getExceptionMessage() != null)
122 JcrUtils.discardQuietly(node.getSession());
123 node.getSession().save();
124
125 // add the new result part, retrieving status information
126 Node resultPartNode = node.addNode(SlcNames.SLC_RESULT_PART,
127 SlcTypes.SLC_CHECK);
128 resultPartNode.setProperty(SLC_SUCCESS, testResultPart.getStatus()
129 .equals(TestStatus.PASSED));
130 if (testResultPart.getMessage() != null)
131 resultPartNode.setProperty(SLC_MESSAGE,
132 testResultPart.getMessage());
133 if (testResultPart.getStatus().equals(TestStatus.ERROR)) {
134 resultPartNode.setProperty(SLC_ERROR_MESSAGE,
135 (testResultPart.getExceptionMessage() == null) ? ""
136 : testResultPart.getExceptionMessage());
137 }
138
139 // helper update aggregate status node
140 Node mainStatus;
141 if (!node.hasNode(SLC_AGGREGATED_STATUS)) {
142
143 mainStatus = node.addNode(SLC_AGGREGATED_STATUS,
144 SlcTypes.SLC_CHECK);
145 mainStatus.setProperty(SLC_SUCCESS,
146 resultPartNode.getProperty(SLC_SUCCESS).getBoolean());
147 if (resultPartNode.hasProperty(SLC_MESSAGE))
148 mainStatus.setProperty(SLC_MESSAGE, resultPartNode
149 .getProperty(SLC_MESSAGE).getString());
150 if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE))
151 mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode
152 .getProperty(SLC_ERROR_MESSAGE).getString());
153 } else {
154 mainStatus = node.getNode(SLC_AGGREGATED_STATUS);
155 if (mainStatus.hasProperty(SLC_ERROR_MESSAGE)) {
156 // main status already in error we do nothing
157 } else if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE)) {
158 // main status was not in error and new result part is in
159 // error; we update main status
160 mainStatus.setProperty(SLC_SUCCESS, false);
161 mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode
162 .getProperty(SLC_ERROR_MESSAGE).getString());
163 if (resultPartNode.hasProperty(SLC_MESSAGE))
164 mainStatus.setProperty(SLC_MESSAGE, resultPartNode
165 .getProperty(SLC_MESSAGE).getString());
166 else
167 // remove old message to remain consistent
168 mainStatus.setProperty(SLC_MESSAGE, "");
169 } else if (!mainStatus.getProperty(SLC_SUCCESS).getBoolean()) {
170 // main status was already failed and new result part is not
171 // in error, we do nothing
172 } else if (!resultPartNode.getProperty(SLC_SUCCESS)
173 .getBoolean()) {
174 // new resultPart that is failed
175 mainStatus.setProperty(SLC_SUCCESS, false);
176 if (resultPartNode.hasProperty(SLC_MESSAGE))
177 mainStatus.setProperty(SLC_MESSAGE, resultPartNode
178 .getProperty(SLC_MESSAGE).getString());
179 else
180 // remove old message to remain consistent
181 mainStatus.setProperty(SLC_MESSAGE, "");
182 } else if (resultPartNode.hasProperty(SLC_MESSAGE)
183 && (!mainStatus.hasProperty(SLC_MESSAGE) || (""
184 .equals(mainStatus.getProperty(SLC_MESSAGE)
185 .getString().trim())))) {
186 mainStatus.setProperty(SLC_MESSAGE, resultPartNode
187 .getProperty(SLC_MESSAGE).getString());
188 }
189 }
190 JcrUtils.updateLastModified(node);
191 node.getSession().save();
192 } catch (Exception e) {
193 JcrUtils.discardUnderlyingSessionQuietly(node);
194 throw new SlcException("Cannot add ResultPart to node " + node, e);
195 }
196 }
197
198 public String getUuid() {
199 Node node = getNode();
200 try {
201 return node.getProperty(SLC_UUID).getString();
202 } catch (Exception e) {
203 throw new SlcException("Cannot get UUID from " + node, e);
204 }
205 }
206
207 /** JCR session is NOT logged out */
208 public void close() {
209 Node node = getNode();
210 try {
211 if (node.hasNode(SLC_COMPLETED))
212 return;
213 node.setProperty(SLC_COMPLETED, new GregorianCalendar());
214 JcrUtils.updateLastModified(node);
215 node.getSession().save();
216 } catch (Exception e) {
217 JcrUtils.discardUnderlyingSessionQuietly(node);
218 throw new SlcException("Cannot get close date from " + node, e);
219 }
220 }
221
222 public Date getCloseDate() {
223 Node node = getNode();
224 try {
225 if (!node.hasNode(SLC_COMPLETED))
226 return null;
227 return node.getProperty(SLC_COMPLETED).getDate().getTime();
228 } catch (Exception e) {
229 throw new SlcException("Cannot get close date from " + node, e);
230 }
231 }
232
233 public Map<String, String> getAttributes() {
234 Node node = getNode();
235 try {
236 Map<String, String> map = new HashMap<String, String>();
237 PropertyIterator pit = node.getProperties();
238 while (pit.hasNext()) {
239 Property p = pit.nextProperty();
240 if (!p.isMultiple())
241 map.put(p.getName(), p.getValue().getString());
242 }
243 return map;
244 } catch (Exception e) {
245 throw new SlcException("Cannot get close date from " + node, e);
246 }
247 }
248
249 public void addAttachment(Attachment attachment) {
250 // TODO implement it
251 }
252
253 public void setUuid(String uuid) {
254 this.uuid = uuid;
255 }
256
257 public void setRepository(Repository repository) {
258 this.repository = repository;
259 }
260
261 public void setResultType(String resultType) {
262 this.resultType = resultType;
263 }
264
265 public void setAttributes(Map<String, String> attributes) {
266 if (uuid != null)
267 throw new SlcException(
268 "Attributes cannot be set on an already initialized test result."
269 + " Update the related JCR node directly instead.");
270 this.attributes = attributes;
271 }
272
273 public void setCredentials(Credentials credentials) {
274 this.credentials = credentials;
275 }
276 }