diff --git a/CHANGELOG.md b/CHANGELOG.md index 3809275d2..cbd9f10a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ All notable changes to AET will be documented in this file. ## Unreleased **List of changes that are finished but not yet released in any final version.** +- [PR-337](https://github.com/Cognifide/aet/pull/337) Added rerun one test or whole suite + ## Version 3.0.0 diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/execution/SuiteStatusResult.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/execution/SuiteStatusResult.java index d37c8d3f0..96c5c1d2c 100644 --- a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/execution/SuiteStatusResult.java +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/execution/SuiteStatusResult.java @@ -15,6 +15,7 @@ */ package com.cognifide.aet.communication.api.execution; +import com.cognifide.aet.communication.api.messages.FullProgressLog; import org.apache.commons.lang3.StringUtils; /** @@ -26,13 +27,20 @@ public class SuiteStatusResult { private String message; + private FullProgressLog progressLog; + public SuiteStatusResult(ProcessingStatus status) { this(status, StringUtils.EMPTY); } public SuiteStatusResult(ProcessingStatus status, String message) { + this(status, message, null); + } + + public SuiteStatusResult(ProcessingStatus status, String message, FullProgressLog progressLog) { this.status = status; this.message = message; + this.progressLog = progressLog; } /** @@ -48,4 +56,8 @@ public ProcessingStatus getStatus() { public String getMessage() { return message; } + + public FullProgressLog getProgressLog() { + return progressLog; + } } diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/job/CollectorJobData.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/job/CollectorJobData.java index 7d690666d..c7d9eae36 100644 --- a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/job/CollectorJobData.java +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/job/CollectorJobData.java @@ -42,8 +42,7 @@ public class CollectorJobData extends JobData { * @param preferredBrowserId - id of preferred browser or null if the default one should be used */ public CollectorJobData(String company, String project, String suiteName, String testName, - List urls, - String proxy, String preferredBrowserId) { + List urls, String proxy, String preferredBrowserId) { super(company, project, suiteName, testName); this.urls = urls; this.proxy = proxy; diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/messages/FullProgressLog.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/messages/FullProgressLog.java new file mode 100644 index 000000000..45c95ca75 --- /dev/null +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/messages/FullProgressLog.java @@ -0,0 +1,46 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.communication.api.messages; + +import java.io.Serializable; +import java.util.Arrays; +import org.apache.commons.lang3.StringUtils; + +public class FullProgressLog implements Serializable { + + private static final long serialVersionUID = -7331561874304014158L; + + private ProgressLog compareLog; + private ProgressLog collectLog; + + public FullProgressLog(ProgressLog collectLog, ProgressLog compareLog) { + this.collectLog = collectLog; + this.compareLog = compareLog; + } + + public ProgressLog getCompareLog() { + return compareLog; + } + + public ProgressLog getCollectLog() { + return collectLog; + } + + @Override + public String toString() { + return StringUtils.join(Arrays.asList(compareLog, collectLog), " ::: "); + } +} diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/ProgressLog.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/messages/ProgressLog.java similarity index 88% rename from core/runner/src/main/java/com/cognifide/aet/runner/processing/ProgressLog.java rename to api/communication-api/src/main/java/com/cognifide/aet/communication/api/messages/ProgressLog.java index f14ae1187..83121e87e 100644 --- a/core/runner/src/main/java/com/cognifide/aet/runner/processing/ProgressLog.java +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/messages/ProgressLog.java @@ -13,10 +13,14 @@ * or implied. See the License for the specific language governing permissions and limitations under * the License. */ -package com.cognifide.aet.runner.processing; +package com.cognifide.aet.communication.api.messages; -public class ProgressLog { +import java.io.Serializable; +public class ProgressLog implements Serializable { + + private static final long serialVersionUID = -3480689780301447508L; + private final String name; private final int receivedMessagesSuccess; diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/messages/ProgressMessage.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/messages/ProgressMessage.java index 67de95688..486682866 100644 --- a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/messages/ProgressMessage.java +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/messages/ProgressMessage.java @@ -18,14 +18,14 @@ /** * Basic message used to send work progress via JMS. */ -public class ProgressMessage extends TaskMessage { - - private static final long serialVersionUID = 490908210242015178L; +public class ProgressMessage extends TaskMessage { + + private static final long serialVersionUID = -428855447599621022L; /** * @param message - progress message. */ - public ProgressMessage(String message) { + public ProgressMessage(FullProgressLog message) { super(MessageType.PROGRESS, message); } diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Comparator.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Comparator.java index 23e44d5f9..64f972cb6 100644 --- a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Comparator.java +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Comparator.java @@ -21,6 +21,7 @@ import com.google.common.collect.ImmutableList; import java.util.ArrayList; import java.util.List; +import java.util.Collections; public class Comparator extends Operation implements Commentable, Named { @@ -30,7 +31,7 @@ public class Comparator extends Operation implements Commentable, Named { private ComparatorStepResult stepResult; - private final List filters = new ArrayList<>(); + private List filters = new ArrayList<>(); private String comment; @@ -49,6 +50,9 @@ public void setStepResult(ComparatorStepResult stepResult) { } public List getFilters() { + if(filters == null){ + return Collections.emptyList(); + } return ImmutableList.copyOf(filters); } @@ -68,6 +72,10 @@ public void setStatistics(Statistics statistics) { this.statistics = statistics; } + public void setFilters(List filters) { + this.filters = filters; + } + @Override public void setComment(String comment) { this.comment = comment; diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/RunType.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/RunType.java new file mode 100644 index 000000000..186685c81 --- /dev/null +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/RunType.java @@ -0,0 +1,22 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.communication.api.metadata; + +public enum RunType { + SUITE, + TEST, + URL, +} diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Suite.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Suite.java index 5305583b4..ce24fe06a 100644 --- a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Suite.java +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Suite.java @@ -32,6 +32,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Valid; @@ -43,7 +44,8 @@ public class Suite implements Serializable, Commentable, Named, Validatable { - private static final long serialVersionUID = 3602287822306302730L; + private static final long serialVersionUID = -3225670696134184553L; + private static final Gson GSON_FOR_JSON = new GsonBuilder() .registerTypeHierarchyAdapter(Collection.class, new CollectionSerializer()) .registerTypeHierarchyAdapter(Map.class, new MapSerializer()) @@ -52,8 +54,12 @@ public class Suite implements Serializable, Commentable, Named, Validatable { private static final Type SUITE_TYPE = new TypeToken() { }.getType(); + public void setCorrelationId(String correlationId) { + this.correlationId = correlationId; + } + @NotBlank - private final String correlationId; + private String correlationId; @NotBlank @Size(max = 30) @@ -130,6 +136,17 @@ public List getTests() { return tests; } + public Optional getTest(String testName){ + Test testToReturn = null; + for (Test test: this.tests) { + if(test.getName().equals(testName)){ + testToReturn = test; + break; + } + } + return Optional.ofNullable(testToReturn); + } + public boolean addTest(Test test) { return tests.add(test); } @@ -191,7 +208,7 @@ public String toString() { .toString(); } - public void setVersion(long version) { + public void setVersion(Long version) { this.version = version; } diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Test.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Test.java index 14060c5a9..64c079cdb 100644 --- a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Test.java +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Test.java @@ -18,6 +18,7 @@ import com.google.common.base.MoreObjects; import java.io.Serializable; import java.util.HashSet; +import java.util.Optional; import java.util.Set; import javax.validation.Valid; import javax.validation.constraints.NotNull; @@ -25,7 +26,7 @@ public class Test implements Serializable, Commentable, Named { - private static final long serialVersionUID = -220660503633061510L; + private static final long serialVersionUID = 6761670624207862805L; @NotBlank private final String name; @@ -38,7 +39,7 @@ public class Test implements Serializable, Commentable, Named { @Valid @NotNull(message = "Test must have at least one url") - private final Set urls = new HashSet<>(); + private Set urls = new HashSet<>(); /** * @param name - name of a test @@ -115,4 +116,25 @@ public String toString() { .add("name", name) .toString(); } + + public Optional getUrl(String urlName) { + Url urlToReturn = null; + for (Url url: this.urls) { + if(url.getName().equals(urlName)){ + urlToReturn = url; + break; + } + } + return Optional.ofNullable(urlToReturn); + } + + public void setUrls(Set urls) { + this.urls = urls; + } + + public void setRerunUrls() { + for (Url url: this.urls) { + url.setReran(); + } + } } diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Url.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Url.java index 20e7b5e3b..30defaa77 100644 --- a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Url.java +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/metadata/Url.java @@ -15,6 +15,7 @@ */ package com.cognifide.aet.communication.api.metadata; +import com.cognifide.aet.communication.api.metadata.Suite.Timestamp; import com.google.common.base.MoreObjects; import java.io.Serializable; import java.util.ArrayList; @@ -25,7 +26,7 @@ public class Url implements Serializable, Commentable, Named { - private static final long serialVersionUID = -8235442513988955778L; + private static final long serialVersionUID = -8223780516461495807L; @NotBlank private final String name; @@ -45,6 +46,10 @@ public class Url implements Serializable, Commentable, Named { @NotNull private final List steps = new ArrayList<>(); + private boolean isReran; + + private Timestamp rerunTimestamp; + public Url(String name, String url, String domain) { this.name = name; this.url = url; @@ -123,4 +128,10 @@ public boolean equals(Object o) { public int hashCode() { return java.util.Objects.hash(name); } + + public void setReran() { + isReran = true; + rerunTimestamp = new Timestamp(System.currentTimeMillis()); + } + } diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/MetadataRunDecorator.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/MetadataRunDecorator.java new file mode 100644 index 000000000..e8caf81c4 --- /dev/null +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/MetadataRunDecorator.java @@ -0,0 +1,81 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.communication.api.wrappers; + +import com.cognifide.aet.communication.api.metadata.Suite; + +public class MetadataRunDecorator extends RunDecorator { + + private static final long serialVersionUID = 2300347507334858549L; + + private Suite suite; + + public MetadataRunDecorator(Run decoratedRun, Suite suite) { + super(decoratedRun); + this.suite = suite; + } + + @Override + public void setObjectToRun(T object) { + decoratedRun.setObjectToRun(object); + } + + @Override + public void setRealSuite(Suite suite) { + this.suite = suite; + } + + @Override + public String getCorrelationId() { + return suite.getCorrelationId(); + } + + @Override + public String getCompany() { + return suite.getCompany(); + } + + @Override + public String getName() { + return suite.getName(); + } + + @Override + public String getSuiteIdentifier() { + return suite.getSuiteIdentifier(); + } + + @Override + public T getObjectToRun() { + return decoratedRun.getObjectToRun(); + } + + @Override + public String getProject() { + return suite.getProject(); + } + + @Override + public Suite getRealSuite() { + return suite; + } + + + public String getTestName() { + return decoratedRun.getTestName(); + } + +} diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/Run.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/Run.java new file mode 100644 index 000000000..05418cf10 --- /dev/null +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/Run.java @@ -0,0 +1,59 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.communication.api.wrappers; + +import com.cognifide.aet.communication.api.metadata.RunType; +import com.cognifide.aet.communication.api.metadata.Suite; +import java.io.Serializable; + +public interface Run extends Serializable { + + RunType getType(); + + T getObjectToRun(); + + void setObjectToRun(T object); + + default void setRealSuite(Suite suite) {} + + default Suite getRealSuite() { + return null; + } + + default String getCorrelationId() { + return null; + } + + default String getProject() { + return null; + } + + default String getCompany() { + return null; + } + + default String getName() { + return null; + } + + default String getSuiteIdentifier() { + return null; + } + + default String getTestName() { + return null; + } +} diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/RunDecorator.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/RunDecorator.java new file mode 100644 index 000000000..95bbc86c5 --- /dev/null +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/RunDecorator.java @@ -0,0 +1,38 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.communication.api.wrappers; + +import com.cognifide.aet.communication.api.metadata.RunType; + +public abstract class RunDecorator implements Run { + + private static final long serialVersionUID = 6866141366419923230L; + + protected Run decoratedRun; + + public Run getRun() { + return decoratedRun; + } + + public RunDecorator(Run decoratedRun) { + this.decoratedRun = decoratedRun; + } + + @Override + public RunType getType() { + return decoratedRun.getType(); + } +} diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/SuiteRunWrapper.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/SuiteRunWrapper.java new file mode 100644 index 000000000..b6b5e589a --- /dev/null +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/SuiteRunWrapper.java @@ -0,0 +1,80 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.communication.api.wrappers; + +import com.cognifide.aet.communication.api.metadata.RunType; +import com.cognifide.aet.communication.api.metadata.Suite; + +public class SuiteRunWrapper implements Run { + + private static final long serialVersionUID = -4514420164522811899L; + + private Suite suite; + + public SuiteRunWrapper(Suite suite) { + this.suite = suite; + } + + @Override + public RunType getType() { + return RunType.SUITE; + } + + @Override + public void setObjectToRun(Suite suite) { + this.suite = suite; + } + + @Override + public void setRealSuite(Suite suite) { + this.suite = suite; + } + + @Override + public String getCorrelationId(){ + return suite.getCorrelationId(); + } + + @Override + public String getCompany(){ + return suite.getCompany(); + } + + @Override + public String getName() { + return suite.getName(); + } + + @Override + public String getSuiteIdentifier() { + return suite.getSuiteIdentifier(); + } + + @Override + public String getProject(){ + return suite.getProject(); + } + + @Override + public Suite getRealSuite() { + return suite; + } + + @Override + public Suite getObjectToRun(){ + return suite; + } +} diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/TestRunWrapper.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/TestRunWrapper.java new file mode 100644 index 000000000..4ee810251 --- /dev/null +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/TestRunWrapper.java @@ -0,0 +1,49 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.communication.api.wrappers; + +import com.cognifide.aet.communication.api.metadata.RunType; +import com.cognifide.aet.communication.api.metadata.Test; + +public class TestRunWrapper implements Run { + + private static final long serialVersionUID = -1391932584294709026L; + + private Test test; + + public TestRunWrapper(Test test) { + this.test = test; + } + + @Override + public void setObjectToRun(Test test) { + this.test = test; + } + + @Override + public RunType getType() { + return RunType.TEST; + } + + @Override + public Test getObjectToRun() { + return test; + } + + public String getTestName() { + return test.getName(); + } +} diff --git a/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/UrlRunWrapper.java b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/UrlRunWrapper.java new file mode 100644 index 000000000..46d6075f1 --- /dev/null +++ b/api/communication-api/src/main/java/com/cognifide/aet/communication/api/wrappers/UrlRunWrapper.java @@ -0,0 +1,69 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.communication.api.wrappers; + +import com.cognifide.aet.communication.api.metadata.RunType; +import com.cognifide.aet.communication.api.metadata.Test; +import com.cognifide.aet.communication.api.metadata.Url; + +public class UrlRunWrapper implements Run { + + private static final long serialVersionUID = -3534307440930598944L; + + private Url url; + private String testName; + private String proxy; + private String preferredBrowserId; + + public UrlRunWrapper(Url url, Test test) { + this.url = url; + this.testName = test.getName(); + this.proxy = test.getProxy(); + this.preferredBrowserId = test.getPreferredBrowserId(); + } + + @Override + public RunType getType() { + return RunType.URL; + } + + @Override + public void setObjectToRun(Url test) { + this.url = test; + } + + @Override + public Url getObjectToRun() { + return url; + } + + public String getTestName() { + return testName; + } + + public String getProxy() { + return proxy; + } + + public String getPreferredBrowserId() { + return preferredBrowserId; + } + + public void setReran(){ + url.setReran(); + } + +} diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/ProgressLogTest.java b/api/communication-api/src/test/java/com/cognifide/aet/communication/api/messages/ProgressLogTest.java similarity index 95% rename from core/runner/src/test/java/com/cognifide/aet/runner/processing/ProgressLogTest.java rename to api/communication-api/src/test/java/com/cognifide/aet/communication/api/messages/ProgressLogTest.java index e04a3e3df..ec2e6cc51 100644 --- a/core/runner/src/test/java/com/cognifide/aet/runner/processing/ProgressLogTest.java +++ b/api/communication-api/src/test/java/com/cognifide/aet/communication/api/messages/ProgressLogTest.java @@ -13,7 +13,7 @@ * or implied. See the License for the specific language governing permissions and limitations under * the License. */ -package com.cognifide.aet.runner.processing; +package com.cognifide.aet.communication.api.messages; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/api/datastorage-api/src/main/java/com/cognifide/aet/vs/MetadataDAO.java b/api/datastorage-api/src/main/java/com/cognifide/aet/vs/MetadataDAO.java index 9fd36b15c..2eec92af6 100644 --- a/api/datastorage-api/src/main/java/com/cognifide/aet/vs/MetadataDAO.java +++ b/api/datastorage-api/src/main/java/com/cognifide/aet/vs/MetadataDAO.java @@ -63,6 +63,13 @@ public interface MetadataDAO extends Serializable { */ Suite getLatestRun(DBKey dbKey, String name) throws StorageException; + /** + * @param oldSuite - Suite to replace in DB + * @param newSuite - New suite which will be replace oldSuite + * @return New Suite + */ + Suite replaceSuite(Suite oldSuite, Suite newSuite) throws StorageException; + /** * @param dbKey - key with project and company name * @return List of suites that were found in database. diff --git a/core/datastorage/src/main/java/com/cognifide/aet/vs/metadata/MetadataDAOMongoDBImpl.java b/core/datastorage/src/main/java/com/cognifide/aet/vs/metadata/MetadataDAOMongoDBImpl.java index 63bb51ae8..32df2521f 100644 --- a/core/datastorage/src/main/java/com/cognifide/aet/vs/metadata/MetadataDAOMongoDBImpl.java +++ b/core/datastorage/src/main/java/com/cognifide/aet/vs/metadata/MetadataDAOMongoDBImpl.java @@ -46,7 +46,7 @@ @Component(immediate = true) public class MetadataDAOMongoDBImpl implements MetadataDAO { - private static final long serialVersionUID = 3031952772776598636L; + private static final long serialVersionUID = -6059718886350668134L; private static final Logger LOGGER = LoggerFactory.getLogger(MetadataDAOMongoDBImpl.class); @@ -139,6 +139,14 @@ public Suite getLatestRun(DBKey dbKey, String name) throws StorageException { return new DocumentConverter(result).toSuite(); } + @Override + public Suite replaceSuite(Suite oldSuite, Suite newSuite) throws StorageException { + MongoCollection metadata = getMetadataCollection(new SimpleDBKey(oldSuite)); + LOGGER.debug("Replacing suite {} in metadata collection.", oldSuite); + metadata.findOneAndReplace(Document.parse(oldSuite.toJson()),Document.parse(newSuite.toJson())); + return newSuite; + } + @Override public List listSuites(DBKey dbKey) throws StorageException { MongoCollection metadata = getMetadataCollection(dbKey); diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/RunnerMessageListener.java b/core/runner/src/main/java/com/cognifide/aet/runner/RunnerMessageListener.java index 890e1fdc0..1e3a06de5 100644 --- a/core/runner/src/main/java/com/cognifide/aet/runner/RunnerMessageListener.java +++ b/core/runner/src/main/java/com/cognifide/aet/runner/RunnerMessageListener.java @@ -20,6 +20,7 @@ import com.cognifide.aet.communication.api.messages.TaskMessage; import com.cognifide.aet.communication.api.metadata.Suite; import com.cognifide.aet.communication.api.queues.JmsConnection; +import com.cognifide.aet.communication.api.wrappers.Run; import com.cognifide.aet.queues.JmsUtils; import com.cognifide.aet.runner.scheduler.CollectorJobSchedulerService; import javax.jms.Destination; @@ -120,11 +121,11 @@ public void onMessage(Message wrapperMessage) { } private void processTestSuite(Message wrapperMessage, TaskMessage message) { - Suite suite = (Suite) message.getData(); + Run objectToRunWrapper = (Run) message.getData(); try { - suiteExecutorService.scheduleSuite(suite, wrapperMessage.getJMSReplyTo()); + suiteExecutorService.scheduleSuite(objectToRunWrapper, wrapperMessage.getJMSReplyTo()); } catch (JMSException e) { - LOGGER.error("Error wile processing RUN {}: ", suite.getCorrelationId(), e); + LOGGER.error("Error wile processing RUN {}: ", objectToRunWrapper.getCorrelationId(), e); sendFatalMessage(wrapperMessage, e.getMessage()); } } diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/SuiteExecutorService.java b/core/runner/src/main/java/com/cognifide/aet/runner/SuiteExecutorService.java index 3c446afda..b81ac73da 100644 --- a/core/runner/src/main/java/com/cognifide/aet/runner/SuiteExecutorService.java +++ b/core/runner/src/main/java/com/cognifide/aet/runner/SuiteExecutorService.java @@ -15,16 +15,22 @@ */ package com.cognifide.aet.runner; -import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.metadata.RunType; +import com.cognifide.aet.communication.api.wrappers.Run; import com.cognifide.aet.runner.processing.SuiteExecutionFactory; -import com.cognifide.aet.runner.processing.SuiteExecutionTask; import com.cognifide.aet.runner.processing.data.SuiteDataService; +import com.cognifide.aet.runner.processing.processors.ProcessorStrategy; +import com.cognifide.aet.runner.processing.processors.SuiteExecutionProcessorStrategy; +import com.cognifide.aet.runner.processing.processors.TestExecutionProcessorStrategy; +import com.cognifide.aet.runner.processing.processors.UrlExecutionProcessorStrategy; import com.google.common.collect.Sets; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -78,14 +84,27 @@ public void deactivate() { scheduledSuites.clear(); } - void scheduleSuite(Suite suite, Destination jmsReplyTo) { - LOGGER.debug("Scheduling {}!", suite); - final ListenableFuture suiteExecutionTask = executor - .submit(new SuiteExecutionTask(suite, jmsReplyTo, suiteDataService, runnerConfiguration, - suiteExecutionFactory)); - scheduledSuites.add(suite.getCorrelationId()); - Futures.addCallback(suiteExecutionTask, new SuiteFinishedCallback(suite.getCorrelationId()), - callbackExecutor); + void scheduleSuite(Run objectToRun, Destination jmsReplyTo) { + LOGGER.debug("Scheduling {}!", objectToRun.getObjectToRun()); + final ListenableFuture suiteExecutionTask; + + ProcessorStrategy processorStrategy = null; + if(objectToRun.getType() == RunType.SUITE){ + processorStrategy = new SuiteExecutionProcessorStrategy(); + } else if (objectToRun.getType() == RunType.TEST) { + processorStrategy = new TestExecutionProcessorStrategy(); + } else if (objectToRun.getType() == RunType.URL){ + processorStrategy = new UrlExecutionProcessorStrategy(); + } + + processorStrategy.setParameters(objectToRun, jmsReplyTo, suiteDataService, + runnerConfiguration, suiteExecutionFactory); + suiteExecutionTask = executor.submit(processorStrategy); + + scheduledSuites.add(objectToRun.getCorrelationId()); + Futures + .addCallback(suiteExecutionTask, new SuiteFinishedCallback(objectToRun.getCorrelationId()), + callbackExecutor); LOGGER.debug( "Currently {} suites are scheduled in the system (max number of concurrent suites: {})", scheduledSuites.size(), runnerConfiguration.getMaxConcurrentSuitesCount()); diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/MessagesSender.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/MessagesSender.java index be528fc76..468d8ced4 100644 --- a/core/runner/src/main/java/com/cognifide/aet/runner/processing/MessagesSender.java +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/MessagesSender.java @@ -27,7 +27,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -class MessagesSender implements Observer { +public class MessagesSender implements Observer { private static final Logger LOGGER = LoggerFactory.getLogger(MessagesSender.class); @@ -49,7 +49,7 @@ public void update(Observable o, Object message) { } } - void sendMessage(BasicMessage message) { + public void sendMessage(BasicMessage message) { try { LOGGER.debug("Sending message: {}", message); resultsProducer.send(session.createObjectMessage(message)); @@ -62,7 +62,7 @@ private boolean isMessage(Object message) { return message instanceof BasicMessage; } - void close() { + public void close() { JmsUtils.closeQuietly(resultsProducer); } diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/SuiteExecutionFactory.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/SuiteExecutionFactory.java index f378ea75e..462bb01d6 100644 --- a/core/runner/src/main/java/com/cognifide/aet/runner/processing/SuiteExecutionFactory.java +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/SuiteExecutionFactory.java @@ -18,7 +18,7 @@ import com.cognifide.aet.communication.api.queues.JmsConnection; import com.cognifide.aet.runner.MessagesManager; import com.cognifide.aet.runner.RunnerConfiguration; -import com.cognifide.aet.runner.processing.data.SuiteIndexWrapper; +import com.cognifide.aet.runner.processing.data.wrappers.RunIndexWrapper; import com.cognifide.aet.runner.processing.steps.CollectDispatcher; import com.cognifide.aet.runner.processing.steps.CollectionResultsRouter; import com.cognifide.aet.runner.processing.steps.ComparisonResultsRouter; @@ -44,26 +44,26 @@ public class SuiteExecutionFactory { private JmsConnection jmsConnection; CollectDispatcher newCollectDispatcher(TimeoutWatch timeoutWatch, - SuiteIndexWrapper suite) + RunIndexWrapper suite) throws JMSException { return new CollectDispatcher(timeoutWatch, jmsConnection, runnerConfiguration, collectorJobSchedulerService, suite); } CollectionResultsRouter newCollectionResultsRouter(TimeoutWatch timeoutWatch, - SuiteIndexWrapper suite) + RunIndexWrapper runIndexWrapper) throws JMSException { return new CollectionResultsRouter(timeoutWatch, jmsConnection, - runnerConfiguration, collectorJobSchedulerService, suite); + runnerConfiguration, collectorJobSchedulerService, runIndexWrapper); } ComparisonResultsRouter newComparisonResultsRouter(TimeoutWatch timeoutWatch, - SuiteIndexWrapper suite) throws JMSException { + RunIndexWrapper runIndexWrapper) throws JMSException { return new ComparisonResultsRouter(timeoutWatch, jmsConnection, - runnerConfiguration, suite); + runnerConfiguration, runIndexWrapper); } - MessagesSender newMessagesSender(Destination jmsReplyTo) throws JMSException { + public MessagesSender newMessagesSender(Destination jmsReplyTo) throws JMSException { return new MessagesSender(jmsReplyTo, jmsConnection); } } diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/SuiteExecutionTask.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/SuiteExecutionTask.java deleted file mode 100644 index 11bcde93b..000000000 --- a/core/runner/src/main/java/com/cognifide/aet/runner/processing/SuiteExecutionTask.java +++ /dev/null @@ -1,108 +0,0 @@ -/** - * AET - * - * Copyright (C) 2013 Cognifide Limited - * - * 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 com.cognifide.aet.runner.processing; - -import com.cognifide.aet.communication.api.messages.FinishedSuiteProcessingMessage; -import com.cognifide.aet.communication.api.messages.FinishedSuiteProcessingMessage.Status; -import com.cognifide.aet.communication.api.metadata.Suite; -import com.cognifide.aet.communication.api.metadata.ValidatorException; -import com.cognifide.aet.runner.RunnerConfiguration; -import com.cognifide.aet.runner.processing.data.SuiteDataService; -import com.cognifide.aet.runner.processing.data.SuiteIndexWrapper; -import com.cognifide.aet.vs.StorageException; -import java.util.concurrent.Callable; -import javax.jms.Destination; -import javax.jms.JMSException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SuiteExecutionTask implements Callable { - - private static final Logger LOGGER = LoggerFactory.getLogger(SuiteExecutionTask.class); - - private final Suite suite; - private final Destination jmsReplyTo; - private final SuiteDataService suiteDataService; - private final RunnerConfiguration runnerConfiguration; - private final SuiteExecutionFactory suiteExecutionFactory; - - private SuiteIndexWrapper indexedSuite; - - private MessagesSender messagesSender; - private SuiteProcessor suiteProcessor; - - public SuiteExecutionTask(Suite suite, Destination jmsReplyTo, - SuiteDataService suiteDataService, RunnerConfiguration runnerConfiguration, - SuiteExecutionFactory suiteExecutionFactory) { - this.suite = suite; - this.jmsReplyTo = jmsReplyTo; - this.suiteDataService = suiteDataService; - this.runnerConfiguration = runnerConfiguration; - this.suiteExecutionFactory = suiteExecutionFactory; - } - - @Override - public String call() { - try { - prepareSuiteWrapper(); - init(); - process(); - save(); - } catch (StorageException | JMSException | ValidatorException e) { - LOGGER.error("Error during processing suite {}", suite, e); - FinishedSuiteProcessingMessage message = new FinishedSuiteProcessingMessage(Status.FAILED, - suite.getCorrelationId()); - message.addError(e.getMessage()); - messagesSender.sendMessage(message); - } finally { - cleanup(); - } - return suite.getCorrelationId(); - } - - private void prepareSuiteWrapper() throws StorageException { - LOGGER.debug("Fetching suite patterns {}", suite); - indexedSuite = new SuiteIndexWrapper(suiteDataService.enrichWithPatterns(suite)); - } - - private void init() throws JMSException { - LOGGER.debug("Initializing suite processors {}", suite); - messagesSender = suiteExecutionFactory.newMessagesSender(jmsReplyTo); - suiteProcessor = new SuiteProcessor(suiteExecutionFactory, indexedSuite, runnerConfiguration, - messagesSender); - } - - private void process() throws JMSException { - LOGGER.info("Start processing: {}", indexedSuite.get()); - suiteProcessor.startProcessing(); - } - - - private void save() throws ValidatorException, StorageException { - LOGGER.debug("Persisting suite {}", suite); - suiteDataService.saveSuite(indexedSuite.get()); - messagesSender.sendMessage( - new FinishedSuiteProcessingMessage(FinishedSuiteProcessingMessage.Status.OK, - suite.getCorrelationId())); - } - - private void cleanup() { - LOGGER.debug("Cleaning up suite {}", suite); - messagesSender.close(); - suiteProcessor.cleanup(); - } - -} diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/SuiteProcessor.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/SuiteProcessor.java index 8e8ca9c6c..73b5c4f1f 100644 --- a/core/runner/src/main/java/com/cognifide/aet/runner/processing/SuiteProcessor.java +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/SuiteProcessor.java @@ -16,25 +16,25 @@ package com.cognifide.aet.runner.processing; import com.cognifide.aet.communication.api.ProcessingError; -import com.cognifide.aet.communication.api.messages.ProcessingErrorMessage; import com.cognifide.aet.communication.api.messages.ProgressMessage; +import com.cognifide.aet.communication.api.messages.ProcessingErrorMessage; +import com.cognifide.aet.communication.api.messages.ProgressLog; import com.cognifide.aet.communication.api.util.ExecutionTimer; import com.cognifide.aet.runner.RunnerConfiguration; -import com.cognifide.aet.runner.processing.data.SuiteIndexWrapper; +import com.cognifide.aet.communication.api.messages.FullProgressLog; +import com.cognifide.aet.runner.processing.data.wrappers.RunIndexWrapper; import com.cognifide.aet.runner.processing.steps.CollectDispatcher; import com.cognifide.aet.runner.processing.steps.CollectionResultsRouter; import com.cognifide.aet.runner.processing.steps.ComparisonResultsRouter; -import java.util.Arrays; import java.util.concurrent.TimeUnit; import javax.jms.JMSException; -import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class contains the actual logic around runner suite processing. */ -class SuiteProcessor { +public class SuiteProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(SuiteProcessor.class); @@ -44,36 +44,36 @@ class SuiteProcessor { private final CollectDispatcher collectDispatcher; private final CollectionResultsRouter collectionResultsRouter; private final ComparisonResultsRouter comparisonResultsRouter; - private final SuiteIndexWrapper indexedSuite; + private final RunIndexWrapper runIndexWrapper; private final RunnerConfiguration runnerConfiguration; private final MessagesSender messagesSender; - SuiteProcessor(SuiteExecutionFactory suiteExecutionFactory, - SuiteIndexWrapper indexedSuite, RunnerConfiguration runnerConfiguration, + public SuiteProcessor(SuiteExecutionFactory suiteExecutionFactory, + RunIndexWrapper runIndexWrapper, RunnerConfiguration runnerConfiguration, MessagesSender messagesSender) throws JMSException { - this.indexedSuite = indexedSuite; + this.runIndexWrapper = runIndexWrapper; this.runnerConfiguration = runnerConfiguration; this.messagesSender = messagesSender; this.timeoutWatch = new TimeoutWatch(); timer = ExecutionTimer.createAndRun("RUNNER"); - collectDispatcher = suiteExecutionFactory.newCollectDispatcher(timeoutWatch, this.indexedSuite); + collectDispatcher = suiteExecutionFactory.newCollectDispatcher(timeoutWatch, this.runIndexWrapper); collectionResultsRouter = suiteExecutionFactory - .newCollectionResultsRouter(timeoutWatch, this.indexedSuite); + .newCollectionResultsRouter(timeoutWatch, this.runIndexWrapper); comparisonResultsRouter = suiteExecutionFactory - .newComparisonResultsRouter(timeoutWatch, this.indexedSuite); + .newComparisonResultsRouter(timeoutWatch, this.runIndexWrapper); collectionResultsRouter.addObserver(messagesSender); comparisonResultsRouter.addObserver(messagesSender); collectionResultsRouter.addChangeObserver(comparisonResultsRouter); } - void startProcessing() throws JMSException { + public void startProcessing() throws JMSException { timeoutWatch.update(); if (tryProcess()) { checkStatusUntilFinishedOrTimedOut(); if (comparisonResultsRouter.isFinished()) { timer.finish(); LOGGER.info("Finished suite run: {}. Task finished in {} ms ({}).", - indexedSuite.get().getCorrelationId(), timer.getExecutionTimeInMillis(), + runIndexWrapper.get().getCorrelationId(), timer.getExecutionTimeInMillis(), timer.getExecutionTimeInMMSS()); LOGGER.info("Total tasks finished in steps: collect: {}; compare: {}.", collectionResultsRouter.getTotalTasksCount(), @@ -82,7 +82,7 @@ void startProcessing() throws JMSException { timer.finish(); LOGGER.warn( "Running {} interrupted after {} ms ({}). Last message received: {} seconds ago... Trying to force report generation.", - indexedSuite.get().getCorrelationId(), timer.getExecutionTimeInMillis(), + runIndexWrapper.get().getCorrelationId(), timer.getExecutionTimeInMillis(), timer.getExecutionTimeInMMSS(), TimeUnit.NANOSECONDS.toSeconds(timeoutWatch.getLastUpdateDifference())); forceFinishSuite(); @@ -90,7 +90,7 @@ void startProcessing() throws JMSException { } } - void cleanup() { + public void cleanup() { comparisonResultsRouter.closeConnections(); collectionResultsRouter.closeConnections(); collectDispatcher.closeConnections(); @@ -105,11 +105,11 @@ private void checkStatusUntilFinishedOrTimedOut() { while (!comparisonResultsRouter.isFinished() && !timeoutWatch .isTimedOut(runnerConfiguration.getFt())) { try { - String currentLog = composeProgressLog(); - if (!currentLog.equals(logMessage)) { - logMessage = currentLog; - LOGGER.info("[{}]: {}", indexedSuite.get().getCorrelationId(), logMessage); - messagesSender.sendMessage(new ProgressMessage(logMessage)); + FullProgressLog currentLog = composeProgressLog(); + if (!currentLog.toString().equals(logMessage)) { + logMessage = currentLog.toString(); + LOGGER.info("[{}]: {}", runIndexWrapper.get().getCorrelationId(), logMessage); + messagesSender.sendMessage(new ProgressMessage(currentLog)); } Thread.sleep(1000); } catch (InterruptedException e) { @@ -118,10 +118,10 @@ private void checkStatusUntilFinishedOrTimedOut() { } } - private String composeProgressLog() { - ProgressLog compareLog = collectionResultsRouter.getProgress(); - ProgressLog reportLog = comparisonResultsRouter.getProgress(); - return StringUtils.join(Arrays.asList(compareLog, reportLog), " ::: "); + private FullProgressLog composeProgressLog() { + ProgressLog collectLog = collectionResultsRouter.getProgress(); + ProgressLog compareLog = comparisonResultsRouter.getProgress(); + return new FullProgressLog(collectLog, compareLog); } private synchronized boolean tryProcess() throws JMSException { @@ -137,7 +137,7 @@ private void forceFinishSuite() { messagesSender.sendMessage(new ProcessingErrorMessage(ProcessingError .reportingError( "Report will be generated after timeout - some results might be missing!"), - indexedSuite.get().getCorrelationId())); + runIndexWrapper.get().getCorrelationId())); timeoutWatch.update(); checkStatusUntilFinishedOrTimedOut(); if (!comparisonResultsRouter.isFinished()) { @@ -145,8 +145,8 @@ private void forceFinishSuite() { messagesSender.sendMessage(new ProcessingErrorMessage(ProcessingError .reportingError( "Report will be generated after timeout - some results might be missing!"), - indexedSuite.get().getCorrelationId())); + runIndexWrapper.get().getCorrelationId())); } - collectDispatcher.cancel(indexedSuite.get().getCorrelationId()); + collectDispatcher.cancel(runIndexWrapper.get().getCorrelationId()); } } diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/SuiteDataService.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/SuiteDataService.java index 5a367171f..86d10f7c7 100644 --- a/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/SuiteDataService.java +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/SuiteDataService.java @@ -17,6 +17,7 @@ import com.cognifide.aet.communication.api.metadata.Suite; import com.cognifide.aet.communication.api.metadata.ValidatorException; +import com.cognifide.aet.vs.DBKey; import com.cognifide.aet.vs.MetadataDAO; import com.cognifide.aet.vs.SimpleDBKey; import com.cognifide.aet.vs.StorageException; @@ -50,4 +51,14 @@ public Suite enrichWithPatterns(final Suite currentRun) throws StorageException public Suite saveSuite(final Suite suite) throws ValidatorException, StorageException { return metadataDAO.saveSuite(suite); } + + public Suite replaceSuite(final Suite oldSuite, final Suite newSuite) throws StorageException { + metadataDAO.replaceSuite(oldSuite,newSuite); + return newSuite; + } + + public Suite getSuite(DBKey dbKey, String correlationId) throws StorageException { + return metadataDAO.getSuite(dbKey, correlationId); + } + } diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/SuiteIndexWrapper.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/SuiteIndexWrapper.java deleted file mode 100644 index d0d20d6ad..000000000 --- a/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/SuiteIndexWrapper.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * AET - * - * Copyright (C) 2013 Cognifide Limited - * - * 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 com.cognifide.aet.runner.processing.data; - -import com.cognifide.aet.communication.api.metadata.Suite; -import com.cognifide.aet.communication.api.metadata.Test; -import com.cognifide.aet.communication.api.metadata.Url; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.collect.FluentIterable; -import java.util.Map; - -public class SuiteIndexWrapper { - - private final Map tests; - - private final Suite suite; - - public SuiteIndexWrapper(Suite suite) { - this.suite = suite; - this.tests = FluentIterable.from(suite.getTests()).uniqueIndex(new NamedToMapFunction()); - } - - public Test getTest(String testName) { - return tests.get(testName); - } - - public Optional getTestUrl(String testName, final String urlName) { - Test test = tests.get(testName); - - return FluentIterable.from(test.getUrls()).firstMatch(new Predicate() { - @Override - public boolean apply(Url url) { - return url.getName().equals(urlName); - } - }); - } - - public Suite get() { - return suite; - } -} diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/SuiteMergeStrategy.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/SuiteMergeStrategy.java index 72a99338f..8ccaba54e 100644 --- a/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/SuiteMergeStrategy.java +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/SuiteMergeStrategy.java @@ -76,13 +76,21 @@ public static Suite merge(Suite current, Suite lastVersion, Suite pattern) { } private static void setVersion(Suite current, Suite lastVersion) { - if (lastVersion != null) { - current.setVersion(lastVersion.getVersion() + 1); - } else { + if(isFirstRun(lastVersion)){ current.setVersion(1L); + } else if(isNotTestOrUrlRerun(current)){ + current.setVersion(lastVersion.getVersion() + 1); } } + private static boolean isNotTestOrUrlRerun(Suite current) { + return current.getVersion() == null; + } + + private static boolean isFirstRun(Suite lastVersion) { + return lastVersion == null; + } + private static void setPatterns(Suite current, Suite pattern) { if (pattern != null) { final ImmutableMap tests = FluentIterable.from(current.getTests()) diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/RunIndexWrapper.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/RunIndexWrapper.java new file mode 100644 index 000000000..8a54ac41e --- /dev/null +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/RunIndexWrapper.java @@ -0,0 +1,67 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.data.wrappers; + +import com.cognifide.aet.communication.api.metadata.Test; +import com.cognifide.aet.communication.api.metadata.Url; +import com.cognifide.aet.communication.api.wrappers.MetadataRunDecorator; +import com.cognifide.aet.communication.api.wrappers.Run; +import java.util.List; +import java.util.Optional; + +public abstract class RunIndexWrapper { + + protected Run objectToRunWrapper; + + RunIndexWrapper(Run objectToRunWrapper) { + this.objectToRunWrapper = objectToRunWrapper; + } + + public static void cleanUrlFromExecutionData(Url url) { + url.setCollectionStats(null); + url.getSteps() + .forEach(step -> { + step.setStepResult(null); + if (step.getComparators() != null) { + step.getComparators() + .forEach(comparator -> + comparator.setStepResult(null) + ); + } + }); + } + + public Optional getTestUrl(String testName, final String urlName) { + Optional test = getTest(testName); + Optional url = Optional.ofNullable(null); + if (test.isPresent()) { + url = test.get().getUrl(urlName); + } + return url; + } + + public Optional getTest(String testName) { + return objectToRunWrapper.getRealSuite().getTest(testName); + } + + public Run get() { + return objectToRunWrapper; + } + + public abstract List> getUrls(); + + public abstract int countUrls(); +} diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/RunIndexWrapperFactory.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/RunIndexWrapperFactory.java new file mode 100644 index 000000000..5b347f8dd --- /dev/null +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/RunIndexWrapperFactory.java @@ -0,0 +1,35 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.data.wrappers; + +import com.cognifide.aet.communication.api.metadata.RunType; +import com.cognifide.aet.communication.api.wrappers.Run; + +public class RunIndexWrapperFactory { + + @SuppressWarnings("unchecked") + public static RunIndexWrapper createInstance(Run objectToRunWrapper) { + if(objectToRunWrapper.getType() == RunType.SUITE){ + return new SuiteRunIndexWrapper(objectToRunWrapper); + } else if (objectToRunWrapper.getType() == RunType.TEST){ + return new TestRunIndexWrapper(objectToRunWrapper); + } else if (objectToRunWrapper.getType() == RunType.URL){ + return new UrlRunIndexWrapper(objectToRunWrapper); + } + return null; + } + +} diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/SuiteRunIndexWrapper.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/SuiteRunIndexWrapper.java new file mode 100644 index 000000000..6068e8e5b --- /dev/null +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/SuiteRunIndexWrapper.java @@ -0,0 +1,55 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.data.wrappers; + +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.metadata.Test; +import com.cognifide.aet.communication.api.metadata.Url; +import com.cognifide.aet.communication.api.wrappers.MetadataRunDecorator; +import com.cognifide.aet.communication.api.wrappers.Run; +import com.cognifide.aet.communication.api.wrappers.UrlRunWrapper; +import java.util.ArrayList; + +public class SuiteRunIndexWrapper extends RunIndexWrapper { + + public SuiteRunIndexWrapper(Run objectToRunWrapper) { + super(objectToRunWrapper); + } + + @Override + public ArrayList> getUrls() { + Suite suite = objectToRunWrapper.getObjectToRun(); + ArrayList> urls = new ArrayList<>(); + for (Test test : suite.getTests()) { + for(Url url : test.getUrls()){ + cleanUrlFromExecutionData(url); + UrlRunWrapper urlRunWrapper = new UrlRunWrapper(url, test); + urls.add(new MetadataRunDecorator<>(urlRunWrapper, suite)); + } + } + return urls; + } + + @Override + public int countUrls() { + int quantityUrls = 0; + Suite suite = objectToRunWrapper.getObjectToRun(); + for (Test test : suite.getTests()) { + quantityUrls += test.getUrls().size(); + } + return quantityUrls; + } +} diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/TestRunIndexWrapper.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/TestRunIndexWrapper.java new file mode 100644 index 000000000..6733f1697 --- /dev/null +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/TestRunIndexWrapper.java @@ -0,0 +1,49 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.data.wrappers; + +import com.cognifide.aet.communication.api.metadata.Test; +import com.cognifide.aet.communication.api.metadata.Url; +import com.cognifide.aet.communication.api.wrappers.MetadataRunDecorator; +import com.cognifide.aet.communication.api.wrappers.Run; +import com.cognifide.aet.communication.api.wrappers.UrlRunWrapper; +import java.util.ArrayList; + +public class TestRunIndexWrapper extends RunIndexWrapper { + + public TestRunIndexWrapper(Run objectToRunWrapper) { + super(objectToRunWrapper); + } + + @Override + public ArrayList> getUrls() { + ArrayList> urls = new ArrayList<>(); + Test test = objectToRunWrapper.getObjectToRun(); + for (Url url : test.getUrls()) { + cleanUrlFromExecutionData(url); + UrlRunWrapper urlRunWrapper = new UrlRunWrapper(url, test); + urls.add(new MetadataRunDecorator<>(urlRunWrapper, objectToRunWrapper.getRealSuite())); + } + return urls; + } + + @Override + public int countUrls() { + Test test = objectToRunWrapper.getObjectToRun(); + return test.getUrls().size(); + } + +} diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/UrlRunIndexWrapper.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/UrlRunIndexWrapper.java new file mode 100644 index 000000000..c27d8c83a --- /dev/null +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/data/wrappers/UrlRunIndexWrapper.java @@ -0,0 +1,50 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.data.wrappers; + +import com.cognifide.aet.communication.api.metadata.Test; +import com.cognifide.aet.communication.api.metadata.Url; +import com.cognifide.aet.communication.api.wrappers.MetadataRunDecorator; +import com.cognifide.aet.communication.api.wrappers.Run; +import com.cognifide.aet.communication.api.wrappers.UrlRunWrapper; +import java.util.ArrayList; +import java.util.Optional; + +public class UrlRunIndexWrapper extends RunIndexWrapper { + + public UrlRunIndexWrapper(Run objectToRunWrapper) { + super(objectToRunWrapper); + } + + @Override + public ArrayList> getUrls() { + ArrayList> urls = new ArrayList<>(); + Optional test = objectToRunWrapper.getRealSuite() + .getTest(objectToRunWrapper.getTestName()); + if (test.isPresent()) { + Url url = objectToRunWrapper.getObjectToRun(); + cleanUrlFromExecutionData(url); + UrlRunWrapper urlRunWrapper = new UrlRunWrapper(url, test.get()); + urls.add(new MetadataRunDecorator<>(urlRunWrapper, objectToRunWrapper.getRealSuite())); + } + return urls; + } + + @Override + public int countUrls() { + return 1; + } +} diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/processors/ProcessorStrategy.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/processors/ProcessorStrategy.java new file mode 100644 index 000000000..66b2010ad --- /dev/null +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/processors/ProcessorStrategy.java @@ -0,0 +1,114 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.processors; + +import com.cognifide.aet.communication.api.messages.FinishedSuiteProcessingMessage; +import com.cognifide.aet.communication.api.messages.FinishedSuiteProcessingMessage.Status; +import com.cognifide.aet.communication.api.metadata.ValidatorException; +import com.cognifide.aet.communication.api.wrappers.Run; +import com.cognifide.aet.runner.RunnerConfiguration; +import com.cognifide.aet.runner.processing.MessagesSender; +import com.cognifide.aet.runner.processing.SuiteExecutionFactory; +import com.cognifide.aet.runner.processing.SuiteProcessor; +import com.cognifide.aet.runner.processing.data.wrappers.RunIndexWrapper; +import com.cognifide.aet.runner.processing.data.SuiteDataService; +import com.cognifide.aet.vs.StorageException; +import java.util.concurrent.Callable; +import javax.jms.JMSException; +import org.slf4j.Logger; +import javax.jms.Destination; + +public abstract class ProcessorStrategy implements Callable { + + protected Logger logger; + protected Destination jmsReplyTo; + protected SuiteDataService suiteDataService; + protected RunnerConfiguration runnerConfiguration; + protected SuiteExecutionFactory suiteExecutionFactory; + protected RunIndexWrapper runIndexWrapper; + protected MessagesSender messagesSender; + protected SuiteProcessor suiteProcessor; + protected Run objectToRunWrapper; + + @Override + public String call() { + try { + prepareSuiteWrapper(); + init(); + process(); + save(); + } catch (StorageException | JMSException | ValidatorException e) { + logger.error("Error during processing suite {}", getObjectToRun(), e); + FinishedSuiteProcessingMessage message = new FinishedSuiteProcessingMessage(Status.FAILED, + objectToRunWrapper.getCorrelationId()); + message.addError(e.getMessage()); + messagesSender.sendMessage(message); + } finally { + cleanup(); + } + return objectToRunWrapper.getCorrelationId(); + } + + public void setParameters(Run objectToRunWrapper, Destination jmsReplyTo, + SuiteDataService suiteDataService, RunnerConfiguration runnerConfiguration, + SuiteExecutionFactory suiteExecutionFactory) { + this.objectToRunWrapper = objectToRunWrapper; + this.jmsReplyTo = jmsReplyTo; + this.suiteDataService = suiteDataService; + this.runnerConfiguration = runnerConfiguration; + this.suiteExecutionFactory = suiteExecutionFactory; + } + + protected void init() throws JMSException { + logger.debug("Initializing suite processors {}", getObjectToRun()); + messagesSender = suiteExecutionFactory.newMessagesSender(jmsReplyTo); + if (suiteProcessor == null) { + suiteProcessor = new SuiteProcessor(suiteExecutionFactory, runIndexWrapper, runnerConfiguration, + messagesSender); + } + } + + protected void process() throws JMSException { + logger.info("Start processing: {}", runIndexWrapper.get()); + suiteProcessor.startProcessing(); + } + + protected void cleanup() { + logger.debug("Cleaning up suite {}", runIndexWrapper.get()); + if(messagesSender != null){ + messagesSender.close(); + } + if(suiteProcessor != null){ + suiteProcessor.cleanup(); + } + } + + //for unit tests + public void setSuiteProcessor(SuiteProcessor suiteProcessor) { + this.suiteProcessor = suiteProcessor; + } + + protected void setLogger(Logger logger) { + this.logger = logger; + } + + protected abstract T getObjectToRun(); + + abstract void prepareSuiteWrapper() throws StorageException; + + abstract void save() throws ValidatorException, StorageException; + +} diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/processors/SuiteExecutionProcessorStrategy.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/processors/SuiteExecutionProcessorStrategy.java new file mode 100644 index 000000000..97b332d21 --- /dev/null +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/processors/SuiteExecutionProcessorStrategy.java @@ -0,0 +1,65 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.processors; + +import com.cognifide.aet.communication.api.messages.FinishedSuiteProcessingMessage; +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.metadata.ValidatorException; +import com.cognifide.aet.communication.api.wrappers.SuiteRunWrapper; +import com.cognifide.aet.runner.processing.data.wrappers.RunIndexWrapperFactory; +import com.cognifide.aet.vs.StorageException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SuiteExecutionProcessorStrategy extends ProcessorStrategy { + + protected static final Logger logger = LoggerFactory + .getLogger(SuiteExecutionProcessorStrategy.class); + + public SuiteExecutionProcessorStrategy() { + setLogger(logger); + } + + void prepareSuiteWrapper() { + logger.debug("Fetching suite patterns {}", getObjectToRun()); + try { + Suite realSuite = objectToRunWrapper.getRealSuite(); + Suite mergedSuite = suiteDataService.enrichWithPatterns(realSuite); + SuiteRunWrapper suiteRunWrapper = new SuiteRunWrapper(mergedSuite); + runIndexWrapper = RunIndexWrapperFactory.createInstance(suiteRunWrapper); + } catch (StorageException e) { + e.printStackTrace(); + } + } + + void save() { + logger.debug("Persisting suite {}", getObjectToRun()); + try { + suiteDataService.saveSuite(objectToRunWrapper.getRealSuite()); + } catch (ValidatorException | StorageException e) { + e.printStackTrace(); + } + messagesSender.sendMessage( + new FinishedSuiteProcessingMessage(FinishedSuiteProcessingMessage.Status.OK, + objectToRunWrapper.getCorrelationId())); + } + + @Override + protected Suite getObjectToRun() { + return (Suite) objectToRunWrapper.getObjectToRun(); + } + +} diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/processors/TestExecutionProcessorStrategy.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/processors/TestExecutionProcessorStrategy.java new file mode 100644 index 000000000..e5f44cc12 --- /dev/null +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/processors/TestExecutionProcessorStrategy.java @@ -0,0 +1,68 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.processors; + +import com.cognifide.aet.communication.api.messages.FinishedSuiteProcessingMessage; +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.metadata.Test; +import com.cognifide.aet.communication.api.metadata.ValidatorException; +import com.cognifide.aet.runner.processing.data.wrappers.RunIndexWrapperFactory; +import com.cognifide.aet.vs.SimpleDBKey; +import com.cognifide.aet.vs.StorageException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TestExecutionProcessorStrategy extends ProcessorStrategy { + + protected static final Logger logger = LoggerFactory + .getLogger(TestExecutionProcessorStrategy.class); + + public TestExecutionProcessorStrategy() { + setLogger(logger); + } + + void prepareSuiteWrapper() throws StorageException { + logger.debug("Fetching suite patterns {}", getObjectToRun()); + try { + Suite mergedSuite = suiteDataService.enrichWithPatterns(objectToRunWrapper.getRealSuite()); + objectToRunWrapper.setRealSuite(mergedSuite); + Test test = (Test) objectToRunWrapper.getObjectToRun(); + String testName = test.getName(); + objectToRunWrapper.setObjectToRun(mergedSuite.getTest(testName).get()); + runIndexWrapper = RunIndexWrapperFactory.createInstance(objectToRunWrapper); + } catch (StorageException e) { + e.printStackTrace(); + } + } + + void save() throws ValidatorException, StorageException { + logger.debug("Persisting suite {}", getObjectToRun()); + try { + Suite oldSuite = suiteDataService.getSuite(new SimpleDBKey(objectToRunWrapper.getRealSuite()), + objectToRunWrapper.getCorrelationId()); + suiteDataService.replaceSuite(oldSuite, objectToRunWrapper.getRealSuite()); + } catch (StorageException e) { + e.printStackTrace(); + } + messagesSender.sendMessage( + new FinishedSuiteProcessingMessage(FinishedSuiteProcessingMessage.Status.OK, + objectToRunWrapper.getCorrelationId())); + } + @Override + protected Test getObjectToRun() { + return (Test) objectToRunWrapper.getObjectToRun(); + } +} diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/processors/UrlExecutionProcessorStrategy.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/processors/UrlExecutionProcessorStrategy.java new file mode 100644 index 000000000..958af42c6 --- /dev/null +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/processors/UrlExecutionProcessorStrategy.java @@ -0,0 +1,71 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.processors; + +import com.cognifide.aet.communication.api.messages.FinishedSuiteProcessingMessage; +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.metadata.Url; +import com.cognifide.aet.communication.api.metadata.ValidatorException; +import com.cognifide.aet.runner.processing.data.wrappers.RunIndexWrapperFactory; +import com.cognifide.aet.vs.SimpleDBKey; +import com.cognifide.aet.vs.StorageException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class UrlExecutionProcessorStrategy extends ProcessorStrategy { + + protected static final Logger logger = LoggerFactory + .getLogger(TestExecutionProcessorStrategy.class); + + public UrlExecutionProcessorStrategy() { + setLogger(logger); + } + + void prepareSuiteWrapper() throws StorageException { + logger.debug("Fetching suite patterns {}", getObjectToRun()); + try { + Suite mergedSuite = suiteDataService.enrichWithPatterns(objectToRunWrapper.getRealSuite()); + objectToRunWrapper.setRealSuite(mergedSuite); + + Url url = (Url) objectToRunWrapper.getObjectToRun(); + String urlName = url.getName(); + String testName = objectToRunWrapper.getTestName(); + objectToRunWrapper.setObjectToRun(mergedSuite.getTest(testName).get().getUrl(urlName).get()); + runIndexWrapper = RunIndexWrapperFactory.createInstance(objectToRunWrapper); + } catch (StorageException e) { + e.printStackTrace(); + } + } + + void save() throws ValidatorException, StorageException { + logger.debug("Persisting suite {}", getObjectToRun()); + try { + Suite oldSuite = suiteDataService.getSuite(new SimpleDBKey(objectToRunWrapper.getRealSuite()), + objectToRunWrapper.getCorrelationId()); + suiteDataService.replaceSuite(oldSuite, objectToRunWrapper.getRealSuite()); + } catch (StorageException e) { + e.printStackTrace(); + } + messagesSender.sendMessage( + new FinishedSuiteProcessingMessage(FinishedSuiteProcessingMessage.Status.OK, + objectToRunWrapper.getCorrelationId())); + } + + @Override + protected Url getObjectToRun() { + return (Url) objectToRunWrapper.getObjectToRun(); + } +} diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/CollectDispatcher.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/CollectDispatcher.java index c28be156c..68fb1b214 100644 --- a/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/CollectDispatcher.java +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/CollectDispatcher.java @@ -16,19 +16,20 @@ package com.cognifide.aet.runner.processing.steps; import com.cognifide.aet.communication.api.job.CollectorJobData; -import com.cognifide.aet.communication.api.metadata.Test; +import com.cognifide.aet.communication.api.messages.ProgressLog; import com.cognifide.aet.communication.api.metadata.Url; import com.cognifide.aet.communication.api.queues.JmsConnection; +import com.cognifide.aet.communication.api.wrappers.MetadataRunDecorator; +import com.cognifide.aet.communication.api.wrappers.UrlRunWrapper; import com.cognifide.aet.runner.RunnerConfiguration; +import com.cognifide.aet.runner.processing.data.wrappers.RunIndexWrapper; import com.cognifide.aet.runner.scheduler.CollectorJobSchedulerService; import com.cognifide.aet.runner.scheduler.MessageWithDestination; -import com.cognifide.aet.runner.processing.ProgressLog; -import com.cognifide.aet.runner.processing.data.SuiteIndexWrapper; import com.cognifide.aet.runner.processing.TimeoutWatch; -import com.google.common.collect.Lists; import com.google.common.collect.Queues; +import java.util.ArrayList; +import java.util.Collections; import java.util.Deque; -import java.util.List; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.ObjectMessage; @@ -46,15 +47,15 @@ public class CollectDispatcher extends StepManager { private final CollectorJobSchedulerService collectorJobScheduler; - private final SuiteIndexWrapper suite; + private final RunIndexWrapper runIndexWrapper; public CollectDispatcher(TimeoutWatch timeoutWatch, JmsConnection jmsConnection, RunnerConfiguration runnerConfiguration, - CollectorJobSchedulerService collectorJobScheduler, SuiteIndexWrapper suite) throws JMSException { - super(timeoutWatch, jmsConnection, suite.get().getCorrelationId(), runnerConfiguration.getMttl()); + CollectorJobSchedulerService collectorJobScheduler, RunIndexWrapper runIndexWrapper) throws JMSException { + super(timeoutWatch, jmsConnection, runIndexWrapper.get().getCorrelationId(), runnerConfiguration.getMttl()); this.urlPackageSize = runnerConfiguration.getUrlPackageSize(); this.collectorJobScheduler = collectorJobScheduler; - this.suite = suite; + this.runIndexWrapper = runIndexWrapper; sender = session.createProducer(null); sender.setTimeToLive(runnerConfiguration.getMttl()); } @@ -73,10 +74,17 @@ public void process() throws JMSException { Deque messagesQueue = Queues.newArrayDeque(); LOGGER.info("Starting processing new Test Suite. CorrelationId: {} ", correlationId); - for (Test test : suite.get().getTests()) { - processUrlsAndGroupToPackages(messagesQueue, test); + for (MetadataRunDecorator metadataRunDecorator : runIndexWrapper.getUrls()) { + UrlRunWrapper urlRunWrapper = (UrlRunWrapper) metadataRunDecorator.getRun(); + final CollectorJobData data = new CollectorJobData(metadataRunDecorator.getCompany(), + metadataRunDecorator.getProject(), metadataRunDecorator.getName(), urlRunWrapper.getTestName(), + new ArrayList<>(Collections.singleton(urlRunWrapper.getObjectToRun())), + urlRunWrapper.getProxy(), urlRunWrapper.getPreferredBrowserId()); + ObjectMessage message = session.createObjectMessage(data); + message.setJMSCorrelationID(correlationId); + messagesQueue.add(new MessageWithDestination(getQueueOut(), message, 1)); } - collectorJobScheduler.add(messagesQueue, suite.get().getCorrelationId()); + collectorJobScheduler.add(messagesQueue, runIndexWrapper.get().getCorrelationId()); LOGGER.info("MessagesQueue was added to collectorJobScheduler. CorrelationId: {} ", correlationId); } @@ -85,26 +93,6 @@ public void cancel(String correlationId) { collectorJobScheduler.cancel(correlationId); } - private void processUrlsAndGroupToPackages(Deque messagesQueue, Test test) - throws JMSException { - int msgIndex = 0; - final int totalUrls = test.getUrls().size(); - List urlsToSend = Lists.newArrayList(); - for (Url testUrl : test.getUrls()) { - msgIndex++; - urlsToSend.add(testUrl); - if (msgIndex % urlPackageSize == 0 || msgIndex == totalUrls) { - final CollectorJobData data = new CollectorJobData(suite.get().getCompany(), - suite.get().getProject(), suite.get().getName(), test.getName(), urlsToSend, - test.getProxy(), test.getPreferredBrowserId()); - ObjectMessage message = session.createObjectMessage(data); - message.setJMSCorrelationID(correlationId); - messagesQueue.add(new MessageWithDestination(getQueueOut(), message, urlsToSend.size())); - urlsToSend.clear(); - } - } - } - @Override public void onMessage(Message message) { // do nothing, this is the first step diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/CollectionResultsRouter.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/CollectionResultsRouter.java index a72a5c91c..7dd844d21 100644 --- a/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/CollectionResultsRouter.java +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/CollectionResultsRouter.java @@ -28,9 +28,10 @@ import com.cognifide.aet.runner.MessagesManager; import com.cognifide.aet.runner.RunnerConfiguration; import com.cognifide.aet.runner.processing.TimeoutWatch; -import com.cognifide.aet.runner.processing.data.SuiteIndexWrapper; +import com.cognifide.aet.runner.processing.data.wrappers.RunIndexWrapper; import com.cognifide.aet.runner.scheduler.CollectorJobSchedulerService; import java.util.List; +import java.util.Optional; import java.util.concurrent.CopyOnWriteArrayList; import javax.jms.JMSException; import javax.jms.Message; @@ -53,31 +54,23 @@ public class CollectionResultsRouter extends StepManager implements TaskFinishPo private final CollectorJobSchedulerService collectorJobScheduler; - private final SuiteIndexWrapper suite; + private RunIndexWrapper runIndexWrapper; private final ExecutionTimer timer; public CollectionResultsRouter(TimeoutWatch timeoutWatch, JmsConnection jmsConnection, RunnerConfiguration runnerConfiguration, - CollectorJobSchedulerService collectorJobScheduler, SuiteIndexWrapper suite) + CollectorJobSchedulerService collectorJobScheduler, RunIndexWrapper runIndexWrapper) throws JMSException { - super(timeoutWatch, jmsConnection, suite.get().getCorrelationId(), + super(timeoutWatch, jmsConnection, runIndexWrapper.get().getCorrelationId(), runnerConfiguration.getMttl()); this.collectorJobScheduler = collectorJobScheduler; - this.suite = suite; - this.messagesToReceive.getAndSet(countUrls()); + this.runIndexWrapper = runIndexWrapper; + this.messagesToReceive.getAndSet(runIndexWrapper.countUrls()); this.changeListeners = new CopyOnWriteArrayList<>(); timer = ExecutionTimer.createAndRun("collection"); } - private int countUrls() { - int urlsCount = 0; - for (Test test : suite.get().getTests()) { - urlsCount += test.getUrls().size(); - } - return urlsCount; - } - @Override public void onMessage(Message message) { if (message instanceof ObjectMessage) { @@ -124,7 +117,7 @@ private void finishTask() throws JMSException { for (ChangeObserver changeListener : changeListeners) { changeListener.informChangesCompleted(); } - timer.finishAndLog(suite.get().getName()); + timer.finishAndLog(runIndexWrapper.get().getName()); LOGGER.debug("Closing consumer!"); consumer.close(); } @@ -165,8 +158,8 @@ private int dispatch(Step step, String testName, String urlName) throws JMSExcep private void createAndSendComparatorJobData(Step step, String testName, String urlName) throws JMSException { ObjectMessage message = session.createObjectMessage( - new ComparatorJobData(suite.get().getCompany(), suite.get().getProject(), - suite.get().getName(), testName, urlName, step)); + new ComparatorJobData(runIndexWrapper.get().getCompany(), runIndexWrapper.get().getProject(), + runIndexWrapper.get().getName(), testName, urlName, step)); message.setJMSCorrelationID(correlationId); sender.send(message); } @@ -176,8 +169,8 @@ private boolean hasComparators(Step step) { } private void updateSuiteUrl(String testName, Url processedUrl) { - final Test test = suite.getTest(testName); - test.addUrl(processedUrl); + final Optional test = runIndexWrapper.getTest(testName); + test.get().addUrl(processedUrl); } public void addChangeObserver(ChangeObserver observer) { diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/ComparisonResultsRouter.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/ComparisonResultsRouter.java index d301dbb57..c2349a1b1 100644 --- a/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/ComparisonResultsRouter.java +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/ComparisonResultsRouter.java @@ -28,8 +28,8 @@ import com.cognifide.aet.runner.MessagesManager; import com.cognifide.aet.runner.RunnerConfiguration; import com.cognifide.aet.runner.processing.TimeoutWatch; -import com.cognifide.aet.runner.processing.data.SuiteIndexWrapper; -import com.google.common.base.Optional; +import com.cognifide.aet.runner.processing.data.wrappers.RunIndexWrapper; +import java.util.Optional; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.ObjectMessage; @@ -43,7 +43,7 @@ public class ComparisonResultsRouter extends StepManager implements ChangeObserv private static final String STEP_NAME = "COMPARED"; - private final SuiteIndexWrapper suite; + private final RunIndexWrapper runIndexWrapper; private final ExecutionTimer timer; @@ -52,10 +52,10 @@ public class ComparisonResultsRouter extends StepManager implements ChangeObserv private boolean aborted; public ComparisonResultsRouter(TimeoutWatch timeoutWatch, JmsConnection jmsConnection, - RunnerConfiguration runnerConfiguration, SuiteIndexWrapper suite) throws JMSException { - super(timeoutWatch, jmsConnection, suite.get().getCorrelationId(), + RunnerConfiguration runnerConfiguration, RunIndexWrapper runIndexWrapper) throws JMSException { + super(timeoutWatch, jmsConnection, runIndexWrapper.get().getCorrelationId(), runnerConfiguration.getMttl()); - this.suite = suite; + this.runIndexWrapper = runIndexWrapper; timer = ExecutionTimer.createAndRun("comparison"); } @@ -102,7 +102,7 @@ private void persistMetadataIfFinished() { if (allResultsReceived()) { LOGGER.info("All results received ({})! Persisting metadata. CorrelationId: {}", messagesToReceive.get(), correlationId); - final Suite currentSuite = this.suite.get(); + final Suite currentSuite = this.runIndexWrapper.get().getRealSuite(); timer.finishAndLog(currentSuite.getName()); currentSuite.setFinishedTimestamp(new Timestamp(System.currentTimeMillis())); long delta = currentSuite.getFinishedTimestamp().get() - currentSuite.getRunTimestamp().get(); @@ -111,7 +111,7 @@ private void persistMetadataIfFinished() { } private void addComparatorToSuite(ComparatorResultData comparisonResult) { - final Optional urlOptional = suite + final Optional urlOptional = runIndexWrapper .getTestUrl(comparisonResult.getTestName(), comparisonResult.getUrlName()); if (urlOptional.isPresent()) { final Url url = urlOptional.get(); @@ -120,7 +120,7 @@ private void addComparatorToSuite(ComparatorResultData comparisonResult) { step.addComparator(comparisonResult.getComparisonResult()); } else { LOGGER.error("Fatal error while saving comparison result: {} of suite.", comparisonResult, - suite.get().getCorrelationId()); + runIndexWrapper.get().getCorrelationId()); } } } @@ -141,7 +141,7 @@ public boolean isFinished() { public void abort() { if (!isFinished()) { LOGGER.warn("Suite {} aborted!. Still waiting for {} of {} comparisons!", - suite.get().getCorrelationId(), + runIndexWrapper.get().getCorrelationId(), messagesToReceive.get() - messagesReceivedSuccess.get() - messagesReceivedFailed.get(), messagesToReceive.get()); } diff --git a/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/StepManager.java b/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/StepManager.java index 5e86b05ea..088b5cabc 100644 --- a/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/StepManager.java +++ b/core/runner/src/main/java/com/cognifide/aet/runner/processing/steps/StepManager.java @@ -20,7 +20,7 @@ import com.cognifide.aet.communication.api.messages.ProcessingErrorMessage; import com.cognifide.aet.communication.api.queues.JmsConnection; import com.cognifide.aet.queues.JmsUtils; -import com.cognifide.aet.runner.processing.ProgressLog; +import com.cognifide.aet.communication.api.messages.ProgressLog; import com.cognifide.aet.runner.processing.TimeoutWatch; import java.util.Observable; import java.util.concurrent.atomic.AtomicInteger; diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/data/wrappers/RunIndexWrapperTest.java b/core/runner/src/test/java/com/cognifide/aet/runner/processing/data/wrappers/RunIndexWrapperTest.java new file mode 100644 index 000000000..cdcfdf3c3 --- /dev/null +++ b/core/runner/src/test/java/com/cognifide/aet/runner/processing/data/wrappers/RunIndexWrapperTest.java @@ -0,0 +1,165 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.data.wrappers; + +import static com.cognifide.aet.runner.processing.data.wrappers.RunIndexWrapper.cleanUrlFromExecutionData; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.cognifide.aet.communication.api.metadata.Comparator; +import com.cognifide.aet.communication.api.metadata.ComparatorStepResult; +import com.cognifide.aet.communication.api.metadata.ComparatorStepResult.Status; +import com.cognifide.aet.communication.api.metadata.Operation; +import com.cognifide.aet.communication.api.metadata.Statistics; +import com.cognifide.aet.communication.api.metadata.Step; +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.metadata.Url; +import com.cognifide.aet.communication.api.wrappers.Run; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class RunIndexWrapperTest { + + private RunIndexWrapper runIndexWrapper; + + @Mock + private Run objectToRunWrapper; + + @Mock + private Suite suite; + + private Optional test; + + private Optional url; + + @Mock + private Step step; + + @Before + public void setUp() { + when(objectToRunWrapper.getRealSuite()).thenReturn(suite); + runIndexWrapper = new SuiteRunIndexWrapper(objectToRunWrapper); + test = Optional + .of(new com.cognifide.aet.communication.api.metadata.Test("testName", "proxy", "chrome")); + url = Optional.of(new Url("urlName","urlUrl","urlDomain")); + test.get().addUrl(url.get()); + } + + @Test + public void cleanUrlFromExecutionData_whenUrlIsRerunning_expectClearedUrl() { + Url realUrl = new Url("urlName", "urlUrl", "urlDomain"); + + realUrl.setCollectionStats(new Statistics(10)); + realUrl.addStep(step); + + Comparator comparator = new Comparator("comparatorType"); + comparator.setStepResult(new ComparatorStepResult("comparatorStepResultName", Status.PASSED)); + ArrayList listOperation = new ArrayList<>(); + listOperation.add(new Operation("operationType")); + comparator.setFilters(listOperation); + + Set comparators = new HashSet<>(); + comparators.add(comparator); + + when(step.getComparators()).thenReturn(comparators); + + cleanUrlFromExecutionData(realUrl); + + assertEquals(realUrl.getName(), "urlName"); + assertEquals(realUrl.getUrl(), "urlUrl"); + assertEquals(realUrl.getDomain(), "urlDomain"); + assertNull(realUrl.getCollectionStats()); + verify(step, times(1)).setStepResult(null); + assertNull(comparator.getStepResult()); + assertEquals(comparator.getFilters().size(), 1); + } + + @Test + public void cleanUrlFromExecutionData_whenUrlIsClear_expectTheSameUrl() { + Url realUrl = new Url("urlName", "urlUrl", "urlDomain"); + realUrl.setCollectionStats(null); + realUrl.addStep(step); + + Comparator comparator = new Comparator("comparatorType"); + Set comparators = new HashSet<>(); + ArrayList listOperation = new ArrayList<>(); + listOperation.add(new Operation("operationType")); + comparator.setFilters(listOperation); + comparators.add(comparator); + + when(step.getComparators()).thenReturn(comparators); + cleanUrlFromExecutionData(realUrl); + + assertEquals(realUrl.getName(), "urlName"); + assertEquals(realUrl.getUrl(), "urlUrl"); + assertEquals(realUrl.getDomain(), "urlDomain"); + assertNull(realUrl.getCollectionStats()); + assertEquals(realUrl.getSteps().size(), 1); + verify(step, times(1)).setStepResult(null); + assertNull(comparator.getStepResult()); + assertEquals(comparator.getFilters().size(), 1); + } + + @Test + public void getTest_whenSuiteHasNotTest_expectNull() { + when(suite.getTest("testName")).thenReturn(null); + when(objectToRunWrapper.getRealSuite()).thenReturn(suite); + assertNull(runIndexWrapper.getTest("testName")); + } + + @Test + public void getTest_whenSuiteHasTest_expectTest() { + when(suite.getTest("testName")).thenReturn(test); + assertThat(runIndexWrapper.getTest("testName"), is(test)); + } + + @Test + public void getTestUrl_whenSuiteHasNotTest_expectNull() { + when(suite.getTest("testName")).thenReturn(Optional.ofNullable(null)); + when(objectToRunWrapper.getRealSuite()).thenReturn(suite); + assertFalse(runIndexWrapper.getTestUrl("testName", "urlName").isPresent()); + } + + @Test + public void getTestUrl_whenTestHasNotUrl_expectNull() { + Set urls = new HashSet<>(); + test.get().setUrls(urls); + when(suite.getTest("testName")).thenReturn(test); + when(objectToRunWrapper.getRealSuite()).thenReturn(suite); + assertFalse(runIndexWrapper.getTestUrl("testName", "urlName").isPresent()); + } + + @Test + public void getTestUrl_whenTestHasUrl_expectOptionalOfUrl() { + when(suite.getTest("testName")).thenReturn(test); + assertThat(runIndexWrapper.getTestUrl("testName", "urlName"), is(url)); + } + +} \ No newline at end of file diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/data/wrappers/SuiteRunIndexWrapperTest.java b/core/runner/src/test/java/com/cognifide/aet/runner/processing/data/wrappers/SuiteRunIndexWrapperTest.java new file mode 100644 index 000000000..23a48d4f8 --- /dev/null +++ b/core/runner/src/test/java/com/cognifide/aet/runner/processing/data/wrappers/SuiteRunIndexWrapperTest.java @@ -0,0 +1,124 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.data.wrappers; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.metadata.Url; +import com.cognifide.aet.communication.api.wrappers.MetadataRunDecorator; +import com.cognifide.aet.communication.api.wrappers.Run; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class SuiteRunIndexWrapperTest { + + private SuiteRunIndexWrapper suiteRunIndexWrapper; + + @Mock + Run objectToRunWrapper; + + @Mock + private Suite suite; + + private Optional test; + + private Optional test2; + + private Optional url; + + private Optional url2; + + @Before + public void setUp() throws Exception { + suiteRunIndexWrapper = new SuiteRunIndexWrapper(objectToRunWrapper); + when(objectToRunWrapper.getRealSuite()).thenReturn(suite); + when(objectToRunWrapper.getObjectToRun()).thenReturn(suite); + test = Optional + .of(new com.cognifide.aet.communication.api.metadata.Test("testName", "proxy", "chrome")); + test2 = Optional + .of(new com.cognifide.aet.communication.api.metadata.Test("testName", "proxy", "chrome")); + url = Optional.of(new Url("urlName","urlUrl","urlDomain")); + url2 = Optional.of(new Url("urlName2","urlUrl2","urlDomain2")); + } + + @Test + public void getUrls_expectZero() { + prepareZeroUrls(); + + ArrayList> urlsResult = suiteRunIndexWrapper + .getUrls(); + assertThat(urlsResult.size(), is(0)); + } + + @Test + public void getUrls_expectThree() { + prepareThreeUrls(); + + ArrayList> urlsResult = suiteRunIndexWrapper + .getUrls(); + assertThat(urlsResult.size(), is(3)); + } + + @Test + public void countUrls_expectZero(){ + prepareZeroUrls(); + + assertThat(suiteRunIndexWrapper.countUrls(), is(0)); + } + + @Test + public void countUrls_expectThree() { + prepareThreeUrls(); + + assertThat(suiteRunIndexWrapper.countUrls(), is(3)); + } + + private void prepareZeroUrls(){ + List tests = new ArrayList<>(); + tests.add(test.get()); + tests.add(test2.get()); + when(suite.getTests()).thenReturn(tests); + } + + private void prepareThreeUrls(){ + Set firstUrlsSet = new HashSet<>(); + firstUrlsSet.add(url.get()); + test.get().setUrls(firstUrlsSet); + + Set secondUrlsSet = new HashSet<>(); + secondUrlsSet.add(url.get()); + secondUrlsSet.add(url2.get()); + test2.get().setUrls(secondUrlsSet); + + List tests = new ArrayList<>(); + tests.add(test.get()); + tests.add(test2.get()); + when(suite.getTests()).thenReturn(tests); + } +} \ No newline at end of file diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/data/wrappers/TestRunIndexWrapperTest.java b/core/runner/src/test/java/com/cognifide/aet/runner/processing/data/wrappers/TestRunIndexWrapperTest.java new file mode 100644 index 000000000..5bba88373 --- /dev/null +++ b/core/runner/src/test/java/com/cognifide/aet/runner/processing/data/wrappers/TestRunIndexWrapperTest.java @@ -0,0 +1,98 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.data.wrappers; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.metadata.Url; +import com.cognifide.aet.communication.api.wrappers.MetadataRunDecorator; +import com.cognifide.aet.communication.api.wrappers.Run; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class TestRunIndexWrapperTest { + + private TestRunIndexWrapper testRunIndexWrapper; + + @Mock + private Run objectToRunWrapper; + + @Mock + private Suite suite; + + private Optional test; + + private Optional url; + + private Optional url2; + + @Before + public void setUp() throws Exception { + test = Optional + .of(new com.cognifide.aet.communication.api.metadata.Test("testName", "proxy", "chrome")); + url = Optional.of(new Url("urlName","urlUrl","urlDomain")); + url2 = Optional.of(new Url("urlName2","urlUrl2","urlDomain2")); + testRunIndexWrapper = new TestRunIndexWrapper(objectToRunWrapper); + when(objectToRunWrapper.getRealSuite()).thenReturn(suite); + when(suite.getTest(any(String.class))).thenReturn(test); + when(objectToRunWrapper.getObjectToRun()).thenReturn(test.get()); + } + + @Test + public void getUrls_expectTwo() { + prepareTwoUrls(); + + ArrayList> urlsResult = testRunIndexWrapper.getUrls(); + assertThat(urlsResult.size(), is(2)); + } + + @Test + public void getUrls_expectZero() { + ArrayList> urlsResult = testRunIndexWrapper + .getUrls(); + assertThat(urlsResult.size(), is(0)); + } + + @Test + public void countUrls_expectZero() { + assertThat(testRunIndexWrapper.countUrls(), is(0)); + } + + @Test + public void countUrls_expectTwo(){ + prepareTwoUrls(); + assertThat(testRunIndexWrapper.countUrls(), is(2)); + } + + private void prepareTwoUrls(){ + Set urls = new HashSet<>(); + urls.add(url.get()); + urls.add(url2.get()); + test.get().setUrls(urls); + } +} \ No newline at end of file diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/data/wrappers/UrlRunIndexWrapperTest.java b/core/runner/src/test/java/com/cognifide/aet/runner/processing/data/wrappers/UrlRunIndexWrapperTest.java new file mode 100644 index 000000000..095f9f24f --- /dev/null +++ b/core/runner/src/test/java/com/cognifide/aet/runner/processing/data/wrappers/UrlRunIndexWrapperTest.java @@ -0,0 +1,73 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.data.wrappers; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.metadata.Url; +import com.cognifide.aet.communication.api.wrappers.MetadataRunDecorator; +import com.cognifide.aet.communication.api.wrappers.Run; +import java.util.ArrayList; +import java.util.Optional; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class UrlRunIndexWrapperTest { + + private UrlRunIndexWrapper urlRunIndexWrapper; + + @Mock + private Run objectToRunWrapper; + + @Mock + private Suite suite; + + private Optional test; + + private Optional url; + + @Before + public void setUp() throws Exception { + urlRunIndexWrapper = new UrlRunIndexWrapper(objectToRunWrapper); + } + + @Test + public void getUrls_expectOne() { + test = Optional + .of(new com.cognifide.aet.communication.api.metadata.Test("testName", "proxy", "chrome")); + url = Optional.of(new Url("urlName", "urlUrl", "urlDomain")); + when(objectToRunWrapper.getRealSuite()).thenReturn(suite); + when(suite.getTest(any(String.class))).thenReturn(test); + when(objectToRunWrapper.getObjectToRun()).thenReturn(url.get()); + + ArrayList> urls = urlRunIndexWrapper + .getUrls(); + assertThat(urls.size(), is(1)); + } + + @Test + public void countUrls_expectOne() { + assertThat(urlRunIndexWrapper.countUrls(), is(1)); + } +} \ No newline at end of file diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/ProcessorStrategyMock.java b/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/ProcessorStrategyMock.java new file mode 100644 index 000000000..e1d059609 --- /dev/null +++ b/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/ProcessorStrategyMock.java @@ -0,0 +1,37 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.processors; + +import com.cognifide.aet.communication.api.metadata.ValidatorException; +import com.cognifide.aet.runner.processing.data.wrappers.SuiteRunIndexWrapper; +import com.cognifide.aet.vs.StorageException; + +public class ProcessorStrategyMock extends ProcessorStrategy{ + + @Override + public Object getObjectToRun() { + return objectToRunWrapper.getObjectToRun(); + } + + @Override + void prepareSuiteWrapper() throws StorageException { + runIndexWrapper = new SuiteRunIndexWrapper(objectToRunWrapper); + } + + @Override + void save() throws ValidatorException, StorageException { } + +} diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/ProcessorStrategyTest.java b/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/ProcessorStrategyTest.java new file mode 100644 index 000000000..81cfa5030 --- /dev/null +++ b/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/ProcessorStrategyTest.java @@ -0,0 +1,108 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.processors; + +import static junit.framework.TestCase.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.times; + +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.wrappers.Run; +import com.cognifide.aet.runner.RunnerConfiguration; +import com.cognifide.aet.runner.processing.MessagesSender; +import com.cognifide.aet.runner.processing.SuiteExecutionFactory; +import com.cognifide.aet.runner.processing.SuiteProcessor; +import com.cognifide.aet.runner.processing.data.SuiteDataService; +import javax.jms.Destination; +import javax.jms.JMSException; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.slf4j.Logger; + +@RunWith(MockitoJUnitRunner.class) +public class ProcessorStrategyTest { + + private ProcessorStrategyMock processorStrategy; + + @Mock + protected Run objectToRunWrapper; + + @Mock + protected Destination jmsReplyTo; + + @Mock + protected SuiteDataService suiteDataService; + + @Mock + protected RunnerConfiguration runnerConfiguration; + + @Mock + protected SuiteExecutionFactory suiteExecutionFactory; + + @Mock + protected Logger logger; + + @Mock + protected Suite suite; + + @Mock + protected MessagesSender messageSender; + + @Mock + protected SuiteProcessor suiteProcessor; + + @Before + public void setUp() throws Exception { + processorStrategy = new ProcessorStrategyMock(); + processorStrategy + .setParameters(objectToRunWrapper, jmsReplyTo, suiteDataService, runnerConfiguration, + suiteExecutionFactory); + processorStrategy.setLogger(logger); + when(objectToRunWrapper.getObjectToRun()).thenReturn(suite); + when(suite.toString()).thenReturn("Suite to string"); + when(suiteExecutionFactory.newMessagesSender(any(Destination.class))).thenReturn(messageSender); + processorStrategy.setSuiteProcessor(suiteProcessor); + } + + @Test + public void call_whenAllIsCorrect_expectAllMethodsWereCalled() throws JMSException { + processorStrategy.call(); + + assertNotNull(processorStrategy.getObjectToRun()); //for check if prepareSuiteWrapper was called + assertNotNull(processorStrategy.messagesSender); //for check if init was called + verify(suiteProcessor, times(1)).startProcessing(); + verify(suiteProcessor, times(1)).cleanup(); + } + + @Test + public void call_whenRaiseError_expectNullPointerException() throws JMSException { + doThrow(JMSException.class).when(suiteProcessor).startProcessing(); + + processorStrategy.call(); + + assertNotNull(processorStrategy.getObjectToRun()); //for check if prepareSuiteWrapper was called + assertNotNull(processorStrategy.messagesSender); //for check if init was called + verify(suiteProcessor, times(1)).startProcessing(); + verify(suiteProcessor, times(1)).cleanup(); + } + +} \ No newline at end of file diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/SuiteExecutionProcessorStrategyTest.java b/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/SuiteExecutionProcessorStrategyTest.java new file mode 100644 index 000000000..72107dcc8 --- /dev/null +++ b/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/SuiteExecutionProcessorStrategyTest.java @@ -0,0 +1,101 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.processors; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.metadata.ValidatorException; +import com.cognifide.aet.communication.api.wrappers.Run; +import com.cognifide.aet.runner.RunnerConfiguration; +import com.cognifide.aet.runner.processing.MessagesSender; +import com.cognifide.aet.runner.processing.SuiteExecutionFactory; +import com.cognifide.aet.runner.processing.SuiteProcessor; +import com.cognifide.aet.runner.processing.data.SuiteDataService; +import com.cognifide.aet.vs.StorageException; +import javax.jms.Destination; +import javax.jms.JMSException; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.slf4j.Logger; + +@RunWith(MockitoJUnitRunner.class) +public class SuiteExecutionProcessorStrategyTest { + + private SuiteExecutionProcessorStrategy suiteExecutionProcessorStrategy; + + @Mock + protected Run objectToRunWrapper; + + @Mock + protected Destination jmsReplyTo; + + @Mock + protected SuiteDataService suiteDataService; + + @Mock + protected RunnerConfiguration runnerConfiguration; + + @Mock + protected SuiteExecutionFactory suiteExecutionFactory; + + @Mock + protected Logger logger; + + @Mock + protected Suite suite; + + @Mock + protected MessagesSender messageSender; + + @Mock + protected SuiteProcessor suiteProcessor; + + @Before + public void setUp() throws JMSException { + suiteExecutionProcessorStrategy = new SuiteExecutionProcessorStrategy(); + suiteExecutionProcessorStrategy + .setParameters(objectToRunWrapper, jmsReplyTo, suiteDataService, runnerConfiguration, + suiteExecutionFactory); + suiteExecutionProcessorStrategy.setLogger(logger); + when(objectToRunWrapper.getObjectToRun()).thenReturn(suite); + when(objectToRunWrapper.getRealSuite()).thenReturn(suite); + when(suite.toString()).thenReturn("Suite to string"); + when(suiteExecutionFactory.newMessagesSender(any(Destination.class))).thenReturn(messageSender); + suiteExecutionProcessorStrategy.setSuiteProcessor(suiteProcessor); + } + + @Test + public void getObjectToRun_checkIfMethodReturnCorrectObject_expectSuite(){ + assertEquals(suite, suiteExecutionProcessorStrategy.getObjectToRun()); + } + + @Test + public void save_checkIfMethodCallsCorrectFunctions() + throws ValidatorException, StorageException, JMSException { + suiteExecutionProcessorStrategy.init(); + suiteExecutionProcessorStrategy.save(); + verify(suiteDataService, times(1)).saveSuite(any(Suite.class)); + } + +} \ No newline at end of file diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/TestExecutionProcessorStrategyTest.java b/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/TestExecutionProcessorStrategyTest.java new file mode 100644 index 000000000..bf0edc3e6 --- /dev/null +++ b/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/TestExecutionProcessorStrategyTest.java @@ -0,0 +1,117 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.processors; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.metadata.ValidatorException; +import com.cognifide.aet.communication.api.wrappers.Run; +import com.cognifide.aet.runner.RunnerConfiguration; +import com.cognifide.aet.runner.processing.MessagesSender; +import com.cognifide.aet.runner.processing.SuiteExecutionFactory; +import com.cognifide.aet.runner.processing.SuiteProcessor; +import com.cognifide.aet.runner.processing.data.SuiteDataService; +import com.cognifide.aet.vs.DBKey; +import com.cognifide.aet.vs.StorageException; +import java.util.Optional; +import javax.jms.Destination; +import javax.jms.JMSException; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.slf4j.Logger; + +@RunWith(MockitoJUnitRunner.class) +public class TestExecutionProcessorStrategyTest { + + private TestExecutionProcessorStrategy testExecutionProcessorStrategy; + + @Mock + protected Run objectToRunWrapper; + + @Mock + protected Destination jmsReplyTo; + + @Mock + protected SuiteDataService suiteDataService; + + @Mock + protected RunnerConfiguration runnerConfiguration; + + @Mock + protected SuiteExecutionFactory suiteExecutionFactory; + + @Mock + protected Logger logger; + + @Mock + protected Suite suite; + + @Mock + protected MessagesSender messageSender; + + @Mock + protected SuiteProcessor suiteProcessor; + + private Optional test; + + @Before + public void setUp() throws JMSException, StorageException { + test = Optional + .of(new com.cognifide.aet.communication.api.metadata.Test("testName", "proxy", "chrome")); + testExecutionProcessorStrategy = new TestExecutionProcessorStrategy(); + testExecutionProcessorStrategy + .setParameters(objectToRunWrapper, jmsReplyTo, suiteDataService, runnerConfiguration, + suiteExecutionFactory); + testExecutionProcessorStrategy.setLogger(logger); + when(objectToRunWrapper.getObjectToRun()).thenReturn(test.get()); + when(objectToRunWrapper.getRealSuite()).thenReturn(suite); + when(suite.toString()).thenReturn("Suite to string"); + when(suiteExecutionFactory.newMessagesSender(any(Destination.class))).thenReturn(messageSender); + testExecutionProcessorStrategy.setSuiteProcessor(suiteProcessor); + when(suite.getTest(any(String.class))).thenReturn(test); + when(suiteDataService.enrichWithPatterns(any(Suite.class))).thenReturn(suite); + } + + @Test + public void prepareSuiteWrapper() throws StorageException { + testExecutionProcessorStrategy.prepareSuiteWrapper(); + verify(suiteDataService, times(1)).enrichWithPatterns(any(Suite.class)); + verify(objectToRunWrapper, times(1)).setObjectToRun(any(Object.class)); + verify(objectToRunWrapper, times(1)).setRealSuite(any(Suite.class)); + } + + @Test + public void save_checkIfMethodCallsCorrectFunctions() + throws JMSException, ValidatorException, StorageException { + testExecutionProcessorStrategy.init(); + testExecutionProcessorStrategy.save(); + verify(suiteDataService, times(1)).getSuite(any(DBKey.class), any(String.class)); + verify(suiteDataService, times(1)).replaceSuite(any(Suite.class), any(Suite.class)); + } + + @Test + public void getObjectToRun_checkIfMethodReturnCorrectObject_expectTest() { + assertEquals(test.get(), testExecutionProcessorStrategy.getObjectToRun()); + } +} \ No newline at end of file diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/UrlExecutionProcessorStrategyTest.java b/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/UrlExecutionProcessorStrategyTest.java new file mode 100644 index 000000000..37486332e --- /dev/null +++ b/core/runner/src/test/java/com/cognifide/aet/runner/processing/processors/UrlExecutionProcessorStrategyTest.java @@ -0,0 +1,122 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.runner.processing.processors; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.metadata.Url; +import com.cognifide.aet.communication.api.metadata.ValidatorException; +import com.cognifide.aet.communication.api.wrappers.Run; +import com.cognifide.aet.runner.RunnerConfiguration; +import com.cognifide.aet.runner.processing.MessagesSender; +import com.cognifide.aet.runner.processing.SuiteExecutionFactory; +import com.cognifide.aet.runner.processing.SuiteProcessor; +import com.cognifide.aet.runner.processing.data.SuiteDataService; +import com.cognifide.aet.vs.DBKey; +import com.cognifide.aet.vs.StorageException; +import java.util.Optional; +import javax.jms.Destination; +import javax.jms.JMSException; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.slf4j.Logger; + +@RunWith(MockitoJUnitRunner.class) +public class UrlExecutionProcessorStrategyTest { + + private UrlExecutionProcessorStrategy urlExecutionProcessorStrategy; + + @Mock + protected Run objectToRunWrapper; + + @Mock + protected Destination jmsReplyTo; + + @Mock + protected SuiteDataService suiteDataService; + + @Mock + protected RunnerConfiguration runnerConfiguration; + + @Mock + protected SuiteExecutionFactory suiteExecutionFactory; + + @Mock + protected Logger logger; + + @Mock + protected Suite suite; + + @Mock + protected MessagesSender messageSender; + + @Mock + protected SuiteProcessor suiteProcessor; + + private Optional test; + + private Optional url; + + @Before + public void setUp() throws Exception { + url = Optional.of(new Url("urlName","urlUrl","urlDomain")); + test = Optional + .of(new com.cognifide.aet.communication.api.metadata.Test("testName", "proxy", "chrome")); + test.get().addUrl(url.get()); + urlExecutionProcessorStrategy = new UrlExecutionProcessorStrategy(); + urlExecutionProcessorStrategy + .setParameters(objectToRunWrapper, jmsReplyTo, suiteDataService, runnerConfiguration, + suiteExecutionFactory); + urlExecutionProcessorStrategy.setLogger(logger); + when(objectToRunWrapper.getObjectToRun()).thenReturn(url.get()); + when(objectToRunWrapper.getRealSuite()).thenReturn(suite); + when(suite.toString()).thenReturn("Suite to string"); + when(suiteExecutionFactory.newMessagesSender(any(Destination.class))).thenReturn(messageSender); + urlExecutionProcessorStrategy.setSuiteProcessor(suiteProcessor); + when(suiteDataService.enrichWithPatterns(any(Suite.class))).thenReturn(suite); + when(suite.getTest(any(String.class))).thenReturn(test); + when(objectToRunWrapper.getTestName()).thenReturn("testName"); + } + + @Test + public void prepareSuiteWrapper() throws StorageException { + urlExecutionProcessorStrategy.prepareSuiteWrapper(); + verify(suiteDataService, times(1)).enrichWithPatterns(any(Suite.class)); + verify(objectToRunWrapper,times(1)).setObjectToRun(any(Object.class)); + verify(objectToRunWrapper,times(1)).setRealSuite(any(Suite.class)); + } + + @Test + public void save_checkIfMethodCallsCorrectFunctions() throws StorageException, ValidatorException, JMSException { + urlExecutionProcessorStrategy.init(); + urlExecutionProcessorStrategy.save(); + verify(suiteDataService, times(1)).getSuite(any(DBKey.class), any(String.class)); + verify(suiteDataService, times(1)).replaceSuite(any(Suite.class), any(Suite.class)); + } + + @Test + public void getObjectToRun_checkIfMethodReturnCorrectObject_expectUrl() { + assertEquals(url.get(), urlExecutionProcessorStrategy.getObjectToRun()); + } +} \ No newline at end of file diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/CollectDispatcherTest.java b/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/CollectDispatcherTest.java index 28ab77491..6a226b8d1 100644 --- a/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/CollectDispatcherTest.java +++ b/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/CollectDispatcherTest.java @@ -25,15 +25,19 @@ import com.cognifide.aet.communication.api.metadata.Test; import com.cognifide.aet.communication.api.metadata.Url; +import com.cognifide.aet.communication.api.wrappers.MetadataRunDecorator; +import com.cognifide.aet.communication.api.wrappers.UrlRunWrapper; import com.cognifide.aet.runner.scheduler.MessageWithDestination; import com.google.common.collect.ImmutableList; import java.io.Serializable; +import java.util.ArrayList; import java.util.HashSet; import java.util.Queue; import java.util.Set; import javax.jms.JMSException; import org.junit.runner.RunWith; import org.mockito.Matchers; +import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.internal.verification.VerificationModeFactory; import org.mockito.runners.MockitoJUnitRunner; @@ -44,9 +48,13 @@ @RunWith(MockitoJUnitRunner.class) public class CollectDispatcherTest extends StepManagerTest { + @Mock + Test test; + @Override protected StepManager createTested() throws JMSException { - return new CollectDispatcher(timeoutWatch, connection, runnerConfiguration, scheduler, suiteIndexWrapper); + return new CollectDispatcher(timeoutWatch, connection, runnerConfiguration, scheduler, + runIndexWrapper); } @Override @@ -64,23 +72,24 @@ public void cancel_expectCleanupOnCollectorJobSchedulerInvoked() throws Exceptio } @org.junit.Test - public void process_when5Urls_expect3SchedulerJobAdded() throws Exception { - Test testA = mockTest("first", 3); - Test testB = mockTest("second", 2); - when(suite.getTests()).thenReturn(ImmutableList.of(testA, testB)); + public void process_when5Urls_expect5SchedulerJobAdded() throws Exception { + ArrayList urlsArray=mockUrlsWrappers(5); + when(runIndexWrapper.getUrls()).thenReturn(urlsArray); ((CollectDispatcher) tested).process(); - verify(session, times(3)).createObjectMessage(Matchers.any()); + + verify(session, times(5)).createObjectMessage(Matchers.any()); verify(scheduler, times(1)).add(Matchers.>any(), anyString()); } @org.junit.Test public void process_when2Urls_expect1SchedulerJobAdded() throws Exception { - Test test = mockTest("testWith2Url", 2); + ArrayList urlsArray=mockUrlsWrappers(2); + when(runIndexWrapper.getUrls()).thenReturn(urlsArray); when(suite.getTests()).thenReturn(ImmutableList.of(test)); ((CollectDispatcher) tested).process(); - verify(session, times(1)).createObjectMessage(Matchers.any()); + verify(session, times(2)).createObjectMessage(Matchers.any()); verify(scheduler, times(1)).add(Matchers.>any(), anyString()); } @@ -120,4 +129,13 @@ private Test mockTest(String name, return test; } + private ArrayList mockUrlsWrappers (int numberOfUrls){ + ArrayListurls = new ArrayList<>(); + for (int i = 0; i < numberOfUrls; ++i) { + UrlRunWrapper urlRunWrapper = new UrlRunWrapper(new Url("/url/" + "Name" + i, "" + i + "_name", null), test); + urls.add(new MetadataRunDecorator(urlRunWrapper, suite)); + } + return urls; + } + } diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/CollectionResultsRouterTest.java b/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/CollectionResultsRouterTest.java index 63aca32af..0f56b217f 100644 --- a/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/CollectionResultsRouterTest.java +++ b/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/CollectionResultsRouterTest.java @@ -37,6 +37,7 @@ import javax.jms.JMSException; import javax.jms.Message; import javax.jms.ObjectMessage; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Matchers; @@ -60,10 +61,11 @@ protected StepManager createTested() throws JMSException { .metadata.Test.class); when(mockedTest.getUrls()).thenReturn(Collections.singleton(Mockito.mock(Url.class))); when(suite.getTests()).thenReturn(Collections.singletonList(mockedTest)); - when(suiteIndexWrapper.getTest(anyString())).thenReturn(mockedTest); + when(runIndexWrapper.getTest(anyString())).thenReturn(java.util.Optional.ofNullable(mockedTest)); + when(runIndexWrapper.countUrls()).thenReturn(1); CollectionResultsRouter collectionResultsRouter = new CollectionResultsRouter(timeoutWatch, connection, runnerConfiguration, - scheduler, suiteIndexWrapper); + scheduler, runIndexWrapper); collectionResultsRouter.addChangeObserver(changeObserver); return collectionResultsRouter; } diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/ComparisonResultsRouterTest.java b/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/ComparisonResultsRouterTest.java index 2d8f5c5e0..939c99a44 100644 --- a/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/ComparisonResultsRouterTest.java +++ b/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/ComparisonResultsRouterTest.java @@ -29,10 +29,10 @@ import com.cognifide.aet.communication.api.metadata.Step; import com.cognifide.aet.communication.api.metadata.Suite.Timestamp; import com.cognifide.aet.communication.api.metadata.Url; -import com.cognifide.aet.runner.processing.ProgressLog; -import com.google.common.base.Optional; +import com.cognifide.aet.communication.api.messages.ProgressLog; import java.util.Collections; import java.util.Observable; +import java.util.Optional; import javax.jms.JMSException; import org.junit.Test; import org.junit.runner.RunWith; @@ -51,7 +51,7 @@ public class ComparisonResultsRouterTest extends StepManagerTest { @Override protected StepManager createTested() throws JMSException { ComparisonResultsRouter tested = new ComparisonResultsRouter(timeoutWatch, connection, runnerConfiguration, - suiteIndexWrapper); + runIndexWrapper); return tested; } @@ -59,7 +59,7 @@ protected StepManager createTested() throws JMSException { public void informChangesCompleted_whenCollectingFinished_expectMetadataPersisted() throws Exception { Timestamp mockedTimestamp = Mockito.mock(Timestamp.class); - when(suiteIndexWrapper.get()).thenReturn(suite); + when(runIndexWrapper.get().getRealSuite()).thenReturn(suite); when(suite.getRunTimestamp()).thenReturn(mockedTimestamp); when(suite.getFinishedTimestamp()).thenReturn(mockedTimestamp); ((ComparisonResultsRouter) tested).informChangesCompleted(); @@ -74,7 +74,7 @@ public void onMessage_whenSuccess_expectResultAddedToMetadataAndCountersUpdated( when(comparatorResultData.getStepIndex()).thenReturn(0); Url mockedUrl = Mockito.mock(Url.class); when(mockedUrl.getSteps()).thenReturn(Collections.singletonList(Mockito.mock(Step.class))); - when(suiteIndexWrapper.getTestUrl(anyString(), anyString())).thenReturn(Optional.of(mockedUrl)); + when(runIndexWrapper.getTestUrl(anyString(), anyString())).thenReturn(Optional.of(mockedUrl)); ((ComparisonResultsRouter) tested).updateAmountToReceive(1); ProgressLog progress = tested.getProgress(); @@ -92,7 +92,7 @@ public void onMessage_whenError_expectObserversNotifiedAndCountersUpdated() thro when(comparatorResultData.getStepIndex()).thenReturn(0); Url mockedUrl = Mockito.mock(Url.class); when(mockedUrl.getSteps()).thenReturn(Collections.singletonList(Mockito.mock(Step.class))); - when(suiteIndexWrapper.getTestUrl(anyString(), anyString())).thenReturn(Optional.of(mockedUrl)); + when(runIndexWrapper.getTestUrl(anyString(), anyString())).thenReturn(Optional.of(mockedUrl)); ((ComparisonResultsRouter) tested).updateAmountToReceive(1); ProgressLog progress = tested.getProgress(); diff --git a/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/StepManagerTest.java b/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/StepManagerTest.java index 2d9b2536b..f09040646 100644 --- a/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/StepManagerTest.java +++ b/core/runner/src/test/java/com/cognifide/aet/runner/processing/steps/StepManagerTest.java @@ -24,9 +24,10 @@ import com.cognifide.aet.communication.api.ProcessingError; import com.cognifide.aet.communication.api.metadata.Suite; import com.cognifide.aet.communication.api.queues.JmsConnection; +import com.cognifide.aet.communication.api.wrappers.SuiteRunWrapper; import com.cognifide.aet.runner.RunnerConfiguration; import com.cognifide.aet.runner.processing.TimeoutWatch; -import com.cognifide.aet.runner.processing.data.SuiteIndexWrapper; +import com.cognifide.aet.runner.processing.data.wrappers.RunIndexWrapper; import com.cognifide.aet.runner.scheduler.CollectorJobSchedulerService; import java.io.Serializable; import java.util.Observable; @@ -67,11 +68,14 @@ public abstract class StepManagerTest { protected CollectorJobSchedulerService scheduler; @Mock - protected SuiteIndexWrapper suiteIndexWrapper; + protected RunIndexWrapper runIndexWrapper; @Mock protected Suite suite; + @Mock + protected SuiteRunWrapper suiteRunWrapper; + @Mock protected MessageConsumer consumer; @@ -91,9 +95,11 @@ public void setUp() throws Exception { when(connection.getJmsSession()).thenReturn(session); when(session.createQueue(anyString())).thenReturn(Mockito.mock(Queue.class)); when(session.createConsumer(Matchers.any(), anyString())).thenReturn(consumer); - when(session.createProducer(Matchers.any())).thenReturn(sender); + when(session.createProducer( + Matchers.any())).thenReturn(sender); when(session.createObjectMessage(Matchers.any())).thenReturn(mockedMessage); - when(suiteIndexWrapper.get()).thenReturn(suite); + when(runIndexWrapper.get()).thenReturn(suiteRunWrapper); + when(suiteRunWrapper.getCorrelationId()).thenReturn(CORRELATION_ID); when(suite.getCorrelationId()).thenReturn(CORRELATION_ID); when(runnerConfiguration.getMttl()).thenReturn(100L); when(runnerConfiguration.getUrlPackageSize()).thenReturn(2); diff --git a/documentation/src/main/wiki/TestProcessing.md b/documentation/src/main/wiki/SuiteProcessing.md similarity index 62% rename from documentation/src/main/wiki/TestProcessing.md rename to documentation/src/main/wiki/SuiteProcessing.md index 40fee0321..4834755b2 100644 --- a/documentation/src/main/wiki/TestProcessing.md +++ b/documentation/src/main/wiki/SuiteProcessing.md @@ -1,4 +1,4 @@ -## Test Processing +## Suite Processing Each AET test processing consists of two phases: @@ -22,3 +22,7 @@ The second phase is operation on collected data. In some cases collected data is The following diagram shows the life cycle of test suite: ![aet-test-suite-lifecycle](assets/diagrams/aet-test-suite-lifecycle.png) + +### Run and rerun part of the suite + +Suite Executor provides methods to run suite from XML format or in case of rerun - suite model from the database. In case of rerun a test or an URL, we are providing the model from database enriched with information necessary to process by runners and workers e.g `Correlation ID`, `Company`, `Project`. In the next step, the model is taken by the runner. It has knowledge about the type of model - is it a suite, a test or an URL and uses it for correct extraction URLs for workers and save or replace information in a database after comparison part. \ No newline at end of file diff --git a/documentation/src/main/wiki/TestExecutor.md b/documentation/src/main/wiki/TestExecutor.md index c23d9b296..3033d9270 100644 --- a/documentation/src/main/wiki/TestExecutor.md +++ b/documentation/src/main/wiki/TestExecutor.md @@ -39,6 +39,25 @@ This endpoint returns JSON object with following fields: | `xunitReportUrl` | Link to xUnit report generated by the suite run. | | `errorMessage` | Contains an error message. Only this field will be present if suite start fails. | +##### Rerun suite + +###### Request + +* **URL**: `/api/suite-rerun` +* **HTTP Method**: POST +* **Parameters**: + * `correlationId` - Correlation ID of the suite to rerun, used to get it from the database + * `suite` - Name of suite, used to get model from the database in case of correlactionID was not provided + * `company` - company name used to create database key + * `project` - project name used to create database key + * `testName` - name of test used to rerun test or used to identify how test should be applied for rerun url, do not provide this parameter for rerun whole suite + * `testUrl` - name of url used to rerun url. In case of rerun whole suite or whole test do not provide it +* **Description**: This endpoint can execute suite. In case when you provide testName it override your test's result in the database or if you provide testName and testUrl it overrides only url's result in the database. If you do not provide additional parameters this endpoint just runs suite and creates new version in database - it doesn't override old information. + +###### Response + +This endpoint returns the same JSON as in case of run suite using `/suite` endpoint. + ##### Get suite processing status ###### Request diff --git a/integration-tests/test-suite/partials/executejavascript.xml b/integration-tests/test-suite/partials/executejavascript.xml new file mode 100644 index 000000000..cb104e492 --- /dev/null +++ b/integration-tests/test-suite/partials/executejavascript.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/integration-tests/test-suite/partials/layout.xml b/integration-tests/test-suite/partials/layout.xml index bc9c03b54..e2cd9c8c3 100644 --- a/integration-tests/test-suite/partials/layout.xml +++ b/integration-tests/test-suite/partials/layout.xml @@ -45,6 +45,7 @@ + diff --git a/integration-tests/test-suite/partials/loginmodifier.xml b/integration-tests/test-suite/partials/loginmodifier.xml new file mode 100644 index 000000000..4c1d146b0 --- /dev/null +++ b/integration-tests/test-suite/partials/loginmodifier.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/report/src/main/webapp/.jshintrc b/report/src/main/webapp/.jshintrc index b15a95787..fae5f5aae 100644 --- a/report/src/main/webapp/.jshintrc +++ b/report/src/main/webapp/.jshintrc @@ -8,7 +8,7 @@ "newcap": true, "nonew": true, "quotmark": true, - "maxparams": 10, + "maxparams": 12, "validthis": true, // Environments diff --git a/report/src/main/webapp/app/app.config.js b/report/src/main/webapp/app/app.config.js index 61f9dd334..3a161d8d2 100644 --- a/report/src/main/webapp/app/app.config.js +++ b/report/src/main/webapp/app/app.config.js @@ -49,6 +49,7 @@ require.config({ 'metadataAccessService': 'services/metadataAccess.service', 'notesService': 'services/notes.service', 'historyService': 'services/history.service', + 'rerunService': 'services/rerun.service', 'suiteInfoService': 'services/suiteInfo.service', 'patternsService': 'services/patterns.service', 'userSettingsService': 'services/userSettings.service', diff --git a/report/src/main/webapp/app/app.module.js b/report/src/main/webapp/app/app.module.js index fb12e35eb..9a271df2c 100644 --- a/report/src/main/webapp/app/app.module.js +++ b/report/src/main/webapp/app/app.module.js @@ -46,6 +46,7 @@ define(['angularAMD', 'metadataAccessService', 'notesService', 'historyService', + 'rerunService', 'suiteInfoService', 'patternsService', 'caseFactory', diff --git a/report/src/main/webapp/app/layout/toolbar/toolbarBottom.controller.js b/report/src/main/webapp/app/layout/toolbar/toolbarBottom.controller.js index 2990815b2..bd0c06f26 100644 --- a/report/src/main/webapp/app/layout/toolbar/toolbarBottom.controller.js +++ b/report/src/main/webapp/app/layout/toolbar/toolbarBottom.controller.js @@ -19,30 +19,43 @@ define([], function () { 'use strict'; return ['$scope', '$rootScope', '$uibModal', '$stateParams', 'patternsService', 'metadataAccessService', 'notesService', - 'viewModeService', 'suiteInfoService', - ToolbarBottomController]; + 'viewModeService', 'suiteInfoService', 'rerunService', 'historyService', + ToolbarBottomController + ]; function ToolbarBottomController($scope, $rootScope, $uibModal, $stateParams, - patternsService, metadataAccessService, notesService, viewModeService, - suiteInfoService) { + patternsService, metadataAccessService, notesService, viewModeService, + suiteInfoService, rerunService, historyService) { var vm = this; // disables accept button if compared against another suite patterns if (suiteInfoService.getInfo().patternCorrelationId) { vm.usesCrossSuitePattern = true; } + vm.showAcceptButton = patternsMayBeUpdated; vm.showRevertButton = patternsMarkedForUpdateMayBeReverted; vm.displayCommentModal = displayCommentModal; vm.scrollSidepanel = scrollSidepanel; + vm.rerunSuite = rerunSuite; + vm.rerunTest = rerunTest; + vm.rerunURL = rerunURL; + vm.rerunService = rerunService; + vm.suiteInfoService = suiteInfoService; + vm.checkRerunStatus = rerunService.checkRerunStatus; + + historyService.fetchHistory(suiteInfoService.getInfo().version, function() { + var currentVersion = suiteInfoService.getInfo().version; + vm.isLastSuiteVersion = historyService.getNextVersion(currentVersion) == null; + }); $rootScope.$on('metadata:changed', updateToolbar); - $scope.$watch('viewMode', function() { - setTimeout(function() { - $('[data-toggle="popover"]').not('.pre-initialized-popover').popover({ - placement: 'bottom' - }); - }, 0); + $scope.$watch('viewMode', function () { + setTimeout(function () { + $('[data-toggle="popover"]').not('.pre-initialized-popover').popover({ + placement: 'bottom' + }); + }, 0); }); $('[data-toggle="popover"]').popover({ @@ -76,7 +89,7 @@ define([], function () { var result = false; if (vm.model) { var patternsToAcceptLeft = - vm.model.patternsToAccept - vm.model.acceptedPatterns; + vm.model.patternsToAccept - vm.model.acceptedPatterns; result = patternsToAcceptLeft > 0; } if (vm.usesCrossSuitePattern) { @@ -90,8 +103,8 @@ define([], function () { var result = false; if (vm.model) { result = - vm.model.acceptedPatterns > 0 && - vm.model.acceptedPatterns <= vm.model.patternsToAccept; + vm.model.acceptedPatterns > 0 && + vm.model.acceptedPatterns <= vm.model.patternsToAccept; } if (vm.usesCrossSuitePattern) { result = false; @@ -120,28 +133,55 @@ define([], function () { } function scrollSidepanel(findParentGroup) { - var $currentElement = $('a.test-name.is-active, a.test-url.is-active'); - var $reportGroup = $currentElement.closest('.aside-report.is-visible'); - var $parentElement = $reportGroup.find('.test-name'); - - if (findParentGroup) { - $parentElement.click(); - performScroll($parentElement); - $reportGroup.addClass('is-expanded'); - } else { - $reportGroup.addClass('is-expanded'); - performScroll($currentElement); - } + var $currentElement = $('a.test-name.is-active, a.test-url.is-active'); + var $reportGroup = $currentElement.closest('.aside-report.is-visible'); + var $parentElement = $reportGroup.find('.test-name'); + + if (findParentGroup) { + $parentElement.click(); + performScroll($parentElement); + $reportGroup.addClass('is-expanded'); + } else { + $reportGroup.addClass('is-expanded'); + performScroll($currentElement); + } } - function performScroll (element) { - element[0].scrollIntoView({behavior: 'smooth', block: 'center', inline: 'nearest'}); + function rerunTest() { + var testName = vm.model.name; + if (vm.model.testGroupName) { + testName = vm.model.testGroupName; + } + rerunService.rerunTest(testName); + } + + function rerunSuite() { + rerunService.rerunSuite(); + } + + function rerunURL(testUrl) { + var testName = vm.model.name; + if (vm.model.testGroupName) { + testName = vm.model.testGroupName; + } + rerunService.rerunURL(testName, testUrl); + } + + function performScroll(element) { + element[0].scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'nearest' + }); } /*************************************** *********** SUITE VIEW PART ********* ***************************************/ function setupSuiteToolbarModel() { + if (localStorage.getItem('currentRerunEndpointUrl')) { + vm.checkRerunStatus(localStorage.getItem('currentRerunEndpointUrl')); + } vm.model = metadataAccessService.getSuite(); vm.updatePatterns = function () { patternsService.updateSuite(); @@ -155,6 +195,9 @@ define([], function () { *********** TEST VIEW PART ********* ***************************************/ function setupTestToolbarModel() { + if (localStorage.getItem('currentRerunEndpointUrl')) { + vm.checkRerunStatus(localStorage.getItem('currentRerunEndpointUrl')); + } var testName = $stateParams.test; vm.model = metadataAccessService.getTest(testName); vm.updatePatterns = function () { @@ -169,10 +212,12 @@ define([], function () { *********** URL VIEW PART ********* ***************************************/ function setupUrlToolbarModel() { + if (localStorage.getItem('currentRerunEndpointUrl')) { + vm.checkRerunStatus(localStorage.getItem('currentRerunEndpointUrl')); + } var testName = $stateParams.test; - vm.model = metadataAccessService.getUrl($stateParams.test, - $stateParams.url); + $stateParams.url); vm.model.testGroupName = metadataAccessService.getTest(testName).name; vm.updatePatterns = function () { patternsService.updateUrl($stateParams.test, $stateParams.url, true); @@ -182,4 +227,4 @@ define([], function () { }; } } -}); +}); \ No newline at end of file diff --git a/report/src/main/webapp/app/layout/toolbar/toolbarBottom.view.html b/report/src/main/webapp/app/layout/toolbar/toolbarBottom.view.html index c77a2fe5b..201ee89b2 100644 --- a/report/src/main/webapp/app/layout/toolbar/toolbarBottom.view.html +++ b/report/src/main/webapp/app/layout/toolbar/toolbarBottom.view.html @@ -20,22 +20,56 @@
+ + {{toolbarBottom.viewMode}}: + {{toolbarBottom.model.name}} +
+
Last rerun: {{toolbarBottom.model.lastRerunTimestamp() | date:'yyyy-MM-dd HH:mm' }}
+
{{toolbarBottom.model.name}} + data-container="body"> {{toolbarBottom.model.name}} + + +
Last rerun: {{toolbarBottom.model.rerunTimestamp | date:'yyyy-MM-dd HH:mm' }}
+
- - test:{{toolbarBottom.model.testGroupName}} + + test:{{toolbarBottom.model.testGroupName}}
+
+

Status: {{rerunMsg}}

+

Progress: {{rerunProgress | number: 2}}%

+
@@ -69,18 +115,18 @@
-
- -
-
- -
-
+ data-toggle="popover" + data-ng-class="toolbarBottom.model.comment ? 'present' : 'absent'" + data-content="{{toolbarBottom.model.comment && '' + toolbarBottom.model.comment + '' || !toolbarBottom.model.comment && 'Click to update this ' + toolbarBottom.viewMode + ' note'}}" + data-html="true" data-trigger="hover" + data-ng-click="toolbarBottom.displayCommentModal()"> +
+ +
+
+ +
+ data-html="true" data-trigger="hover"> Accept {{toolbarBottom.viewMode}} - - + + Accept {{toolbarBottom.viewMode}} - + - - Revert {{toolbarBottom.viewMode}} - + + Revert {{toolbarBottom.viewMode}} +
diff --git a/report/src/main/webapp/app/services/history.service.js b/report/src/main/webapp/app/services/history.service.js index 8f6fcf6e2..c422ac708 100644 --- a/report/src/main/webapp/app/services/history.service.js +++ b/report/src/main/webapp/app/services/history.service.js @@ -49,25 +49,29 @@ define(['angularAMD', 'endpointConfiguration', 'suiteInfoService'], function (an function getPreviousVersion(currentVersion) { var prevVersion = null; - $rootScope.suiteHeaders.forEach(function(suiteHeader, index) { - if(suiteHeader.version === currentVersion) { - if($rootScope.suiteHeaders[index + 1]) { - prevVersion = $rootScope.suiteHeaders[index + 1].version; + if($rootScope.suiteHeaders) { + $rootScope.suiteHeaders.forEach(function(suiteHeader, index) { + if(suiteHeader.version === currentVersion) { + if($rootScope.suiteHeaders[index + 1]) { + prevVersion = $rootScope.suiteHeaders[index + 1].version; + } } - } - }); + }); + } return prevVersion; } function getNextVersion(currentVersion) { var nextVersion = null; - $rootScope.suiteHeaders.forEach(function(suiteHeader, index) { - if(suiteHeader.version === currentVersion) { - if($rootScope.suiteHeaders[index - 1]) { - nextVersion = $rootScope.suiteHeaders[index - 1].version; + if($rootScope.suiteHeaders) { + $rootScope.suiteHeaders.forEach(function(suiteHeader, index) { + if(suiteHeader.version === currentVersion) { + if($rootScope.suiteHeaders[index - 1]) { + nextVersion = $rootScope.suiteHeaders[index - 1].version; + } } - } - }); + }); + } return nextVersion; } diff --git a/report/src/main/webapp/app/services/metadata.service.js b/report/src/main/webapp/app/services/metadata.service.js index 9e7f10645..65712cae2 100644 --- a/report/src/main/webapp/app/services/metadata.service.js +++ b/report/src/main/webapp/app/services/metadata.service.js @@ -185,6 +185,7 @@ define(['angularAMD', 'metadataCacheService', 'metadataEndpointService'], decoratedObject.patternsToAccept = 0; decoratedObject.acceptedPatterns = 0; decoratedObject.getStatus = getStatus; + decoratedObject.lastRerunTimestamp = lastRerunTimestamp; decoratedObject.updatePatternStatistics = updatePatternStatistics; decoratedObject.revertPatternStatistics = revertPatternStatistics; } @@ -203,6 +204,20 @@ define(['angularAMD', 'metadataCacheService', 'metadataEndpointService'], return status; } + function lastRerunTimestamp() { + var timestamp = false; + if (typeof(this.urls) !== 'undefined'){ + this.urls.forEach(function(url){ + if(url.isReran){ + if(timestamp == false || timestamp < url.rerunTimestamp){ + timestamp = url.rerunTimestamp; + } + } + }); + } + return timestamp; + } + function updatePatternStatistics() { decoratedObject.failed--; decoratedObject.rebased++; diff --git a/report/src/main/webapp/app/services/rerun.service.js b/report/src/main/webapp/app/services/rerun.service.js new file mode 100644 index 000000000..cd8506dc0 --- /dev/null +++ b/report/src/main/webapp/app/services/rerun.service.js @@ -0,0 +1,136 @@ +/* + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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. + */ + define(['angularAMD', 'endpointConfiguration', 'suiteInfoService' , 'caseFactory'], function (angularAMD) { + 'use strict'; + angularAMD.factory('rerunService', rerunService); + + /** + * Service responsible for fetching suite's history + */ + function rerunService($rootScope, $http, endpointConfiguration, suiteInfoService, caseFactory) { + $rootScope.endpointUrl = endpointConfiguration.getEndpoint().getUrl; + var service = { + getRerunStatistics: getRerunStatistics, + rerunSuite: rerunSuite, + rerunTest: rerunTest, + rerunURL: rerunURL, + checkRerunStatus: checkRerunStatus, + }; + + return service; + + function getRerunStatistics(msg) { + var statsArray = msg; + statsArray = statsArray.replace(/:::/, ','); + statsArray = statsArray.replace(/\d{2}:\d{2}:\d{2}\.\d{3}/g, ''); + statsArray = statsArray.replace(/[a-zA-z]|:/g, ''); + statsArray = statsArray.replace(/\s/g, ''); + statsArray = statsArray.split(','); + return statsArray; + } + + function rerunSuite() { + $rootScope.rerunInProgress = true; + var suiteInfo = suiteInfoService.getInfo(); + var rerunParams = 'company=' + suiteInfo.company + '&' + 'project=' + suiteInfo.project + '&' + + 'suite=' + suiteInfo.name; + var url = endpointConfiguration.getEndpoint().getUrl + 'suite-rerun?' + rerunParams; + $http.post(url, {}).then(function successCallback(response) { + $rootScope.rerunMsg = 'Suite rerun initialized'; + $rootScope.rerunInProgressSuccessful = true; + localStorage.setItem('currentRerunEndpointUrl', response.data.statusUrl); + $rootScope.rerunProgress = 0; + checkRerunStatus(response.data.statusUrl); + }, function errorCallback(response) { + $rootScope.rerunMsg = response.statusText; + }); + } + + function rerunTest(testName) { + $rootScope.rerunInProgress = true; + var suiteInfo = suiteInfoService.getInfo(); + var rerunParams = 'company=' + suiteInfo.company + '&' + 'project=' + suiteInfo.project + '&' + + 'suite=' + suiteInfo.name + '&' + 'testName=' + testName; + var url = endpointConfiguration.getEndpoint().getUrl + 'suite-rerun?' + rerunParams; + $http.post(url, {}).then(function successCallback(response) { + $rootScope.rerunMsg = 'Test rerun initialized'; + $rootScope.rerunProgress = 0; + $rootScope.rerunInProgressSuccessful = true; + localStorage.setItem('currentRerunEndpointUrl', response.data.statusUrl); + checkRerunStatus(response.data.statusUrl); + }, function errorCallback(response) { + $rootScope.rerunMsg = response.statusText; + }); + } + + function rerunURL(testName, testUrl) { + $rootScope.rerunInProgress = true; + var suiteInfo = suiteInfoService.getInfo(); + var rerunParams = 'company=' + suiteInfo.company + '&' + 'project=' + suiteInfo.project + '&' + + 'suite=' + suiteInfo.name + '&' + 'testUrl=' + testUrl + '&' + 'testName=' + testName; + var url = endpointConfiguration.getEndpoint().getUrl + 'suite-rerun?' + rerunParams; + $http.post(url, {}).then(function successCallback(response) { + $rootScope.rerunMsg = 'URL rerun initialized'; + $rootScope.rerunProgress = 0; + $rootScope.rerunInProgressSuccessful = true; + localStorage.setItem('currentRerunEndpointUrl', response.data.statusUrl); + checkRerunStatus(response.data.statusUrl); + }, function errorCallback(response) { + $rootScope.rerunMsg = response.statusText; + }); + } + + function checkRerunStatus(statusUrl) { + $rootScope.rerunInProgress = true; + var url = statusUrl; + setTimeout(function () { + $http.get(url, {}).then(function successCallback(response) { + if (response.data.status === 'FINISHED') { + var suiteInfo = suiteInfoService.getInfo(); + var linkParams = '?' + 'company=' + suiteInfo.company + '&' + 'project=' + suiteInfo.project + '&' + + 'suite=' + suiteInfo.name; + linkParams = linkParams + '#' + window.location.href.split('#')[1]; + var linkToLatestSuite = location.protocol + '//' + location.host + location.pathname + linkParams; + $rootScope.rerunMsg = 'Rerun completed. Page will now refresh.'; + $rootScope.rerunProgress = 100; + localStorage.removeItem('currentRerunEndpointUrl'); + if (window.location.href !== linkToLatestSuite) { + window.location.assign(linkToLatestSuite); + } else { + window.location.reload(); + } + return; + } else if (response.data.status === 'PROGRESS') { + $rootScope.rerunInProgressSuccessful = true; + var totalTests = response.data.progressLog.collectLog.toReceiveMessages; + var completedTests = response.data.progressLog.collectLog.receivedMessagesSuccess; + $rootScope.rerunProgress = ((completedTests / totalTests) * 90); + $rootScope.rerunMsg = 'Rerun in progress.'; + } else { + $rootScope.rerunMsg = 'Waiting for results.'; + } + checkRerunStatus(statusUrl); + }, function errorCallback(response) { + $rootScope.rerunMsg = response.data.status; + return; + }); + }, 2000); + } + + } +}); \ No newline at end of file diff --git a/report/src/main/webapp/package-lock.json b/report/src/main/webapp/package-lock.json index c75d9cb5f..92ec69283 100644 --- a/report/src/main/webapp/package-lock.json +++ b/report/src/main/webapp/package-lock.json @@ -130,7 +130,7 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=", "dev": true }, "accepts": { @@ -2355,7 +2355,7 @@ "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -4257,7 +4257,7 @@ "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8=", "dev": true, "requires": { "is-arrayish": "^0.2.1" @@ -4290,7 +4290,7 @@ "es5-ext": { "version": "0.10.45", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", - "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", + "integrity": "sha1-C/33tHPaWRnVrfO9Jc63VPzMNlM=", "dev": true, "requires": { "es6-iterator": "~2.0.3", @@ -7508,7 +7508,7 @@ "hosted-git-info": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "integrity": "sha1-l/I2l3vW4SVAiTD/bePuxigewEc=", "dev": true }, "htmlescape": { @@ -7682,7 +7682,7 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc=", "dev": true }, "inline-source-map": { @@ -8753,7 +8753,7 @@ "lockfile": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz", - "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", + "integrity": "sha1-B/gZ0lrkj4flOOZXi2lkpJgaVgk=", "dev": true, "requires": { "signal-exit": "^3.0.2" @@ -9563,7 +9563,7 @@ "natives": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.4.tgz", - "integrity": "sha512-Q29yeg9aFKwhLVdkTAejM/HvYG0Y1Am1+HUkFQGn5k2j8GS+v60TVmZh6nujpEAj/qql+wGUrlryO8bF+b1jEg==", + "integrity": "sha1-Lw8iT8mn3VNAfHZnyEz42+dz3lg=", "dev": true }, "natural-compare": { @@ -9753,7 +9753,7 @@ "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", "dev": true, "requires": { "hosted-git-info": "^2.1.4", @@ -9780,7 +9780,7 @@ "npmconf": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/npmconf/-/npmconf-2.1.3.tgz", - "integrity": "sha512-iTK+HI68GceCoGOHAQiJ/ik1iDfI7S+cgyG8A+PP18IU3X83kRhQIRhAUNj4Bp2JMx6Zrt5kCiozYa9uGWTjhA==", + "integrity": "sha1-HL5d0C6JnTZf7XJgtUBVRz+QoVw=", "dev": true, "requires": { "config-chain": "~1.1.8", @@ -11415,7 +11415,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", "dev": true }, "safe-regex": { @@ -11430,7 +11430,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=", "dev": true }, "sass-graph": { @@ -12051,7 +12051,7 @@ "spdx-correct": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", - "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "integrity": "sha1-BaW01xU6GVvJLDxCW2nzsqlSTII=", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -12061,13 +12061,13 @@ "spdx-exceptions": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", + "integrity": "sha1-LHrmEFbHFKW5ubKyr30xHvXHj+k=", "dev": true }, "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "integrity": "sha1-meEZt6XaAOBUkcn6M4t5BII7QdA=", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -12077,7 +12077,7 @@ "spdx-license-ids": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", - "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", + "integrity": "sha1-enzShHDMbToc/m1miG9rxDDTrIc=", "dev": true }, "split-string": { @@ -12444,7 +12444,7 @@ "stringstream": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", - "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", + "integrity": "sha1-eIAiWw1K0Q4wkn0Weh1vL9OzOnI=", "dev": true }, "strip-ansi": { @@ -12749,7 +12749,7 @@ "timers-ext": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.5.tgz", - "integrity": "sha512-tsEStd7kmACHENhsUPaxb8Jf8/+GZZxyNFQbZD07HQOyooOa6At1rQqjffgvg7n+dxscQa9cjjMdWhJtsP2sxg==", + "integrity": "sha1-dxR91OdrZgwqu4eF25ZXTLvRKSI=", "dev": true, "requires": { "es5-ext": "~0.10.14", diff --git a/rest-endpoint/src/main/java/com/cognifide/aet/rest/ArtifactServlet.java b/rest-endpoint/src/main/java/com/cognifide/aet/rest/ArtifactServlet.java index 144a5ec67..7ea2b4dd9 100644 --- a/rest-endpoint/src/main/java/com/cognifide/aet/rest/ArtifactServlet.java +++ b/rest-endpoint/src/main/java/com/cognifide/aet/rest/ArtifactServlet.java @@ -15,6 +15,8 @@ */ package com.cognifide.aet.rest; +import static com.cognifide.aet.rest.Helper.responseAsJson; + import com.cognifide.aet.vs.Artifact; import com.cognifide.aet.vs.ArtifactsDAO; import com.cognifide.aet.vs.DBKey; @@ -58,7 +60,7 @@ protected void process(DBKey dbKey, HttpServletRequest req, HttpServletResponse resp.setStatus(HttpURLConnection.HTTP_BAD_REQUEST); resp.setContentType("application/json"); resp.getWriter().write( - responseAsJson("Unable to get artifact with id : %s form %s", id, dbKey.toString())); + responseAsJson(GSON, "Unable to get artifact with id : %s form %s", id, dbKey.toString())); } } diff --git a/rest-endpoint/src/main/java/com/cognifide/aet/rest/BasicDataServlet.java b/rest-endpoint/src/main/java/com/cognifide/aet/rest/BasicDataServlet.java index 6b87b769b..01ecef921 100644 --- a/rest-endpoint/src/main/java/com/cognifide/aet/rest/BasicDataServlet.java +++ b/rest-endpoint/src/main/java/com/cognifide/aet/rest/BasicDataServlet.java @@ -15,9 +15,9 @@ */ package com.cognifide.aet.rest; -import com.cognifide.aet.communication.api.metadata.Suite; +import static com.cognifide.aet.rest.Helper.responseAsJson; + import com.cognifide.aet.communication.api.metadata.ValidatorException; -import com.cognifide.aet.communication.api.util.ValidatorProvider; import com.cognifide.aet.vs.DBKey; import com.google.gson.Gson; import java.io.IOException; @@ -30,13 +30,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -abstract class BasicDataServlet extends HttpServlet { +public abstract class BasicDataServlet extends HttpServlet { private static final long serialVersionUID = -5819760668750910009L; private static final Logger LOGGER = LoggerFactory.getLogger(BasicDataServlet.class); - private static final Gson GSON = new Gson(); + protected static final Gson GSON = new Gson(); /*** * Returns JSON representation of Suite based correlationId or suite name @@ -60,7 +60,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) } catch (ValidatorException e) { LOGGER.error("Validation problem!", e); resp.setStatus(HttpURLConnection.HTTP_BAD_REQUEST); - resp.getWriter().write(responseAsJson("There were validation errors when parsing suite: %s", + resp.getWriter().write(responseAsJson(GSON,"There were validation errors when parsing suite: %s", e.getAllViolationMessages())); return; } @@ -82,10 +82,6 @@ void unregister(String servletPath) { setHttpService(null); } - boolean isValidName(String suiteName) { - return ValidatorProvider.getValidator().validateValue(Suite.class, "name", suiteName).isEmpty(); - } - boolean isValidVersion(String version) { boolean valid = false; if (version != null) { @@ -99,33 +95,11 @@ boolean isValidVersion(String version) { return valid; } - boolean isValidCorrelationId(String correlationId) { - return ValidatorProvider.getValidator() - .validateValue(Suite.class, "correlationId", correlationId).isEmpty(); - } - protected abstract void process(DBKey dbKey, HttpServletRequest req, HttpServletResponse resp) throws IOException; - protected String responseAsJson(String format, Object... args) { - return GSON.toJson(new ErrorMessage(format, args)); - } - protected abstract HttpService getHttpService(); protected abstract void setHttpService(HttpService httpService); - private static class ErrorMessage { - - private final String message; - - ErrorMessage(String format, Object... args) { - message = String.format(format, args); - } - - public String getMessage() { - return message; - } - } - } diff --git a/rest-endpoint/src/main/java/com/cognifide/aet/rest/Helper.java b/rest-endpoint/src/main/java/com/cognifide/aet/rest/Helper.java index 74e22f312..17753a8a2 100644 --- a/rest-endpoint/src/main/java/com/cognifide/aet/rest/Helper.java +++ b/rest-endpoint/src/main/java/com/cognifide/aet/rest/Helper.java @@ -15,9 +15,12 @@ */ package com.cognifide.aet.rest; +import com.cognifide.aet.communication.api.metadata.Suite; import com.cognifide.aet.communication.api.metadata.ValidatorException; +import com.cognifide.aet.communication.api.util.ValidatorProvider; import com.cognifide.aet.vs.DBKey; import com.cognifide.aet.vs.SimpleDBKey; +import com.google.gson.Gson; import javax.servlet.http.HttpServletRequest; public final class Helper { @@ -25,6 +28,7 @@ public final class Helper { static final String REST_PREFIX = "/api"; static final String ARTIFACT_PART_PATH = "artifact"; static final String METADATA_PART_PATH = "metadata"; + static final String RERUN_PART_PATH = "suite-rerun"; static final String HISTORY_PART_PATH = "history"; static final String REPORT_PART_PATH = "/report"; static final String CONFIGS_PART_PATH = "/configs"; @@ -39,6 +43,8 @@ public final class Helper { public static final String VERSION_PARAM = "version"; public static final String ID_PARAM = "id"; public static final String REPORT_PART_PATH_DEFAULT_PAGE = "index.html"; + public static final String TEST_RERUN_PARAM = "testName"; + public static final String URL_RERUN_PARAM = "testUrl"; private Helper() { //private helper constructor @@ -76,6 +82,10 @@ public static String getReportPathDefaultPage() { return REPORT_PART_PATH + PATH_SEPARATOR + REPORT_PART_PATH_DEFAULT_PAGE; } + public static String getRerunPath(){ + return REST_PREFIX + PATH_SEPARATOR + RERUN_PART_PATH; + } + public static DBKey getDBKeyFromRequest(HttpServletRequest req) throws ValidatorException { String company = req.getParameter(Helper.COMPANY_PARAM); String project = req.getParameter(Helper.PROJECT_PARAM); @@ -83,4 +93,30 @@ public static DBKey getDBKeyFromRequest(HttpServletRequest req) throws Validator dbKey.validate(null); return dbKey; } + + public static boolean isValidName(String suiteName) { + return ValidatorProvider.getValidator().validateValue(Suite.class, "name", suiteName).isEmpty(); + } + + public static boolean isValidCorrelationId(String correlationId) { + return ValidatorProvider.getValidator() + .validateValue(Suite.class, "correlationId", correlationId).isEmpty(); + } + + public static String responseAsJson(Gson GSON, String format, Object... args) { + return GSON.toJson(new ErrorMessage(format, args)); + } + + private static class ErrorMessage { + + private final String message; + + ErrorMessage(String format, Object... args) { + message = String.format(format, args); + } + + public String getMessage() { + return message; + } + } } diff --git a/rest-endpoint/src/main/java/com/cognifide/aet/rest/HistoryServlet.java b/rest-endpoint/src/main/java/com/cognifide/aet/rest/HistoryServlet.java index 7f0346940..dc2a42d06 100644 --- a/rest-endpoint/src/main/java/com/cognifide/aet/rest/HistoryServlet.java +++ b/rest-endpoint/src/main/java/com/cognifide/aet/rest/HistoryServlet.java @@ -15,6 +15,9 @@ */ package com.cognifide.aet.rest; +import static com.cognifide.aet.rest.Helper.isValidName; +import static com.cognifide.aet.rest.Helper.responseAsJson; + import com.cognifide.aet.vs.DBKey; import com.cognifide.aet.vs.MetadataDAO; import com.cognifide.aet.vs.StorageException; @@ -65,17 +68,20 @@ protected void process(DBKey dbKey, HttpServletRequest req, HttpServletResponse } else { resp.setStatus(HttpURLConnection.HTTP_NOT_FOUND); resp.getWriter() - .write(responseAsJson("History not found for suite: %s %s", suiteName, dbKey.toString())); + .write( + responseAsJson(PRETTY_PRINT_GSON, "History not found for suite: %s %s", suiteName, + dbKey.toString())); } } else { resp.setStatus(HttpURLConnection.HTTP_BAD_REQUEST); resp.getWriter() - .write(responseAsJson("Invalid suite param was specified.")); + .write(responseAsJson(PRETTY_PRINT_GSON, "Invalid suite param was specified.")); } } catch (StorageException e) { LOGGER.error("Failed to get suite's history", e); resp.setStatus(HttpURLConnection.HTTP_BAD_REQUEST); - resp.getWriter().write(responseAsJson("Failed to get history of suite: %s", e.getMessage())); + resp.getWriter().write( + responseAsJson(PRETTY_PRINT_GSON, "Failed to get history of suite: %s", e.getMessage())); } } diff --git a/rest-endpoint/src/main/java/com/cognifide/aet/rest/MetadataServlet.java b/rest-endpoint/src/main/java/com/cognifide/aet/rest/MetadataServlet.java index 83bad1425..d6fbfbaea 100644 --- a/rest-endpoint/src/main/java/com/cognifide/aet/rest/MetadataServlet.java +++ b/rest-endpoint/src/main/java/com/cognifide/aet/rest/MetadataServlet.java @@ -15,6 +15,10 @@ */ package com.cognifide.aet.rest; +import static com.cognifide.aet.rest.Helper.isValidCorrelationId; +import static com.cognifide.aet.rest.Helper.isValidName; +import static com.cognifide.aet.rest.Helper.responseAsJson; + import com.cognifide.aet.communication.api.exceptions.AETException; import com.cognifide.aet.communication.api.metadata.Suite; import com.cognifide.aet.communication.api.metadata.ValidatorException; @@ -86,13 +90,13 @@ protected void process(DBKey dbKey, HttpServletRequest req, HttpServletResponse } else { resp.setStatus(HttpURLConnection.HTTP_BAD_REQUEST); resp.getWriter() - .write(responseAsJson("Neither valid correlationId or suite param was specified.")); + .write(responseAsJson(GSON, "Neither valid correlationId or suite param was specified.")); return; } } catch (StorageException e) { LOGGER.error("Failed to get suite", e); resp.setStatus(HttpURLConnection.HTTP_BAD_REQUEST); - resp.getWriter().write(responseAsJson("Failed to get suite: %s", e.getMessage())); + resp.getWriter().write(responseAsJson(GSON,"Failed to get suite: %s", e.getMessage())); return; } @@ -106,7 +110,7 @@ protected void process(DBKey dbKey, HttpServletRequest req, HttpServletResponse } else { resp.setStatus(HttpURLConnection.HTTP_BAD_REQUEST); resp.getWriter() - .write(responseAsJson("Unable to get Suite Metadata for %s", dbKey.toString())); + .write(responseAsJson(GSON,"Unable to get Suite Metadata for %s", dbKey.toString())); } } @@ -142,23 +146,23 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) } catch (AETException e) { LOGGER.debug("Suite is locked.", e); resp.setStatus(HttpURLConnection.HTTP_CONFLICT); - resp.getWriter().write(responseAsJson(e.getMessage())); + resp.getWriter().write(responseAsJson(GSON, e.getMessage())); } catch (JsonSyntaxException | JsonIOException jsonSyntaxException) { LOGGER.error("Invalid json provided by client", jsonSyntaxException); resp.setStatus(HttpURLConnection.HTTP_BAD_REQUEST); - resp.getWriter().write(responseAsJson("Error: Invalid format of provided Json %s", + resp.getWriter().write(responseAsJson(GSON,"Error: Invalid format of provided Json %s", jsonSyntaxException.getMessage())); } catch (ValidatorException validatorException) { LOGGER.error("Invalid json provided by client: {}", validatorException.getIssues(), validatorException); resp.setStatus(HttpURLConnection.HTTP_BAD_REQUEST); resp.getWriter().write( - responseAsJson("Invalid Suite representation : %s", validatorException.getIssues())); + responseAsJson(GSON,"Invalid Suite representation : %s", validatorException.getIssues())); } catch (StorageException e) { LOGGER.error("Failed to save suite", e); resp.setStatus(HttpURLConnection.HTTP_INTERNAL_ERROR); resp.getWriter() - .write(responseAsJson("ERROR: Unable to save provided Suite. %s", e.getMessage())); + .write(responseAsJson(GSON,"ERROR: Unable to save provided Suite. %s", e.getMessage())); } finally { resp.flushBuffer(); } diff --git a/rest-endpoint/src/main/java/com/cognifide/aet/rest/XUnitServlet.java b/rest-endpoint/src/main/java/com/cognifide/aet/rest/XUnitServlet.java index 3bdcec00d..bd652b92d 100644 --- a/rest-endpoint/src/main/java/com/cognifide/aet/rest/XUnitServlet.java +++ b/rest-endpoint/src/main/java/com/cognifide/aet/rest/XUnitServlet.java @@ -15,6 +15,10 @@ */ package com.cognifide.aet.rest; +import static com.cognifide.aet.rest.Helper.isValidCorrelationId; +import static com.cognifide.aet.rest.Helper.isValidName; +import static com.cognifide.aet.rest.Helper.responseAsJson; + import com.cognifide.aet.communication.api.metadata.Suite; import com.cognifide.aet.exceptions.RestServiceException; import com.cognifide.aet.vs.DBKey; @@ -82,7 +86,7 @@ protected void process(DBKey dbKey, HttpServletRequest request, HttpServletRespo } catch (RestServiceException e) { LOGGER.error("Failed to process request!", e); response.setStatus(HttpURLConnection.HTTP_BAD_REQUEST); - response.getWriter().write(responseAsJson(e.getMessage())); + response.getWriter().write(responseAsJson(GSON, e.getMessage())); } } @@ -123,7 +127,7 @@ private void generateXUnitAndRespondWithIt(DBKey dbKey, HttpServletResponse resp } catch (IOException | JAXBException e) { LOGGER.error("Fatal exception while generating xUnit xml", e); response.setStatus(HttpURLConnection.HTTP_BAD_REQUEST); - response.getWriter().write(responseAsJson("Unable to get xUnit for %s", dbKey.toString())); + response.getWriter().write(responseAsJson(GSON,"Unable to get xUnit for %s", dbKey.toString())); } } diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteCacheUpdater.java b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteCacheUpdater.java index ec4925eaf..5c5cfe3fc 100644 --- a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteCacheUpdater.java +++ b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteCacheUpdater.java @@ -15,13 +15,13 @@ */ package com.cognifide.aet.executor; -import com.cognifide.aet.communication.api.metadata.Suite; import com.cognifide.aet.executor.common.RunnerTerminator; +import com.cognifide.aet.communication.api.wrappers.Run; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * This class runs a thread which updates the caches for given suite run. + * This class runs a thread which updates the caches for given objectToRun run. */ class SuiteCacheUpdater implements Runnable { @@ -33,25 +33,25 @@ class SuiteCacheUpdater implements Runnable { private final RunnerTerminator runnerTerminator; - private final Suite suite; + private final Run objectToRun; - SuiteCacheUpdater(CacheUpdater cacheUpdater, RunnerTerminator runnerTerminator, Suite suite) { + SuiteCacheUpdater(CacheUpdater cacheUpdater, RunnerTerminator runnerTerminator, Run objectToRun) { this.cacheUpdater = cacheUpdater; this.runnerTerminator = runnerTerminator; - this.suite = suite; + this.objectToRun = objectToRun; } /** - * Updates caches for suite. + * Updates caches for objectToRun. */ @Override public void run() { while (runnerTerminator.isActive()) { try { Thread.sleep(CACHE_UPDATE_INTERVAL_MILLIS); - cacheUpdater.update(suite.getCorrelationId(), suite.getSuiteIdentifier()); + cacheUpdater.update(objectToRun.getCorrelationId(), objectToRun.getSuiteIdentifier()); } catch (InterruptedException e) { - LOGGER.error("Failed to update cache for suite: '{}'.", suite.getCorrelationId(), e); + LOGGER.error("Failed to update cache for objectToRun: '{}'.", objectToRun.getCorrelationId(), e); Thread.currentThread().interrupt(); } } diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteExecutor.java b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteExecutor.java index a17758bdd..79acb2597 100644 --- a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteExecutor.java +++ b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteExecutor.java @@ -25,6 +25,8 @@ import com.cognifide.aet.executor.http.HttpSuiteExecutionResultWrapper; import com.cognifide.aet.executor.model.TestRun; import com.cognifide.aet.executor.model.TestSuiteRun; +import com.cognifide.aet.communication.api.wrappers.Run; +import com.cognifide.aet.communication.api.wrappers.SuiteRunWrapper; import com.cognifide.aet.executor.xmlparser.api.ParseException; import com.cognifide.aet.executor.xmlparser.api.TestSuiteParser; import com.cognifide.aet.executor.xmlparser.xml.XmlTestSuiteParser; @@ -97,6 +99,8 @@ public class SuiteExecutor { private SuiteStatusHandler suiteStatusHandler; + private SuiteRunner suiteRunner; + @Activate public void activate(SuiteExecutorConf config) { this.config = config; @@ -119,17 +123,15 @@ public void activate(SuiteExecutorConf config) { * * @param suiteString - content of the test suite XML file * @param domain - overrides domain defined in the suite file - * @param patternCorrelationId - optional pattern to set, this is a correlation ID of a suite - * that will be used as patterns source + * @param patternCorrelationId - optional pattern to set, this is a correlation ID of a suite that + * will be used as patterns source * @param patternSuite - optional pattern to set, this is a name of a suite whose latest version * will be used as patterns source. This parameter is ignored if patternCorrelationId is set * @return status of the suite execution */ HttpSuiteExecutionResultWrapper execute(String suiteString, String name, String domain, - String patternCorrelationId, String patternSuite) { - SuiteRunner suiteRunner = null; + String patternCorrelationId, String patternSuite) { HttpSuiteExecutionResultWrapper result; - TestSuiteParser xmlFileParser = new XmlTestSuiteParser(); try { TestSuiteRun testSuiteRun = xmlFileParser.parse(suiteString); @@ -141,22 +143,8 @@ HttpSuiteExecutionResultWrapper execute(String suiteString, String name, String if (validationError == null) { final Suite suite = suiteFactory.suiteFromTestSuiteRun(testSuiteRun); suite.validate(Sets.newHashSet("version", "runTimestamp")); - - if (lockTestSuite(suite)) { - suiteRunner = createSuiteRunner(suite); - suiteRunner.runSuite(); - - String statusUrl = getStatusUrl(suite); - String htmlReportUrl = getReportUrl(HTML_REPORT_URL_FORMAT, - reportConfigurationManager.getReportDomain(), suite); - String xunitReportUrl = getReportUrl(XUNIT_REPORT_URL_FORMAT, StringUtils.EMPTY, suite); - result = HttpSuiteExecutionResultWrapper.wrap( - SuiteExecutionResult.createSuccessResult(suite.getCorrelationId(), statusUrl, - htmlReportUrl, xunitReportUrl)); - } else { - result = HttpSuiteExecutionResultWrapper.wrapError( - SuiteExecutionResult.createErrorResult(LOCKED_SUITE_MESSAGE), HttpStatus.SC_LOCKED); - } + Run objectToRunWrapper = new SuiteRunWrapper(suite); + result = executeSuite(objectToRunWrapper); } else { result = HttpSuiteExecutionResultWrapper .wrapError(SuiteExecutionResult.createErrorResult(validationError), @@ -167,7 +155,6 @@ HttpSuiteExecutionResultWrapper execute(String suiteString, String name, String result = HttpSuiteExecutionResultWrapper .wrapError(SuiteExecutionResult.createErrorResult(e.getMessage()), HttpStatus.SC_BAD_REQUEST); - } catch (JMSException e) { LOGGER.error("Fatal error", e); result = HttpSuiteExecutionResultWrapper @@ -181,6 +168,25 @@ HttpSuiteExecutionResultWrapper execute(String suiteString, String name, String return result; } + HttpSuiteExecutionResultWrapper executeSuite(Run objectToRunWrapper) + throws JMSException, ValidatorException { + if (lockTestSuite(objectToRunWrapper)) { + suiteRunner = createSuiteRunner(objectToRunWrapper); + suiteRunner.runSuite(); + + String statusUrl = getStatusUrl(objectToRunWrapper); + String htmlReportUrl = getReportUrl(HTML_REPORT_URL_FORMAT, + reportConfigurationManager.getReportDomain(), objectToRunWrapper); + String xunitReportUrl = getReportUrl(XUNIT_REPORT_URL_FORMAT, StringUtils.EMPTY, objectToRunWrapper); + return HttpSuiteExecutionResultWrapper.wrap( + SuiteExecutionResult.createSuccessResult(objectToRunWrapper.getCorrelationId(), statusUrl, + htmlReportUrl, xunitReportUrl)); + } else { + return HttpSuiteExecutionResultWrapper.wrapError( + SuiteExecutionResult.createErrorResult(LOCKED_SUITE_MESSAGE), HttpStatus.SC_LOCKED); + } + } + /** * Returns the status of test suite processing. * @@ -214,29 +220,31 @@ private TestSuiteRun overrideDomainOrNameIfDefined(TestSuiteRun testSuiteRun, St return localTestSuiteRun; } - private boolean lockTestSuite(Suite suite) { - String suiteIdentifier = suite.getSuiteIdentifier(); - String correlationId = suite.getCorrelationId(); + private boolean lockTestSuite(Run objectToRunWrapper) { + String suiteIdentifier = objectToRunWrapper.getSuiteIdentifier(); + String correlationId = objectToRunWrapper.getCorrelationId(); LOGGER.debug("locking suite: '{}' with correlation id: '{}'", suiteIdentifier, correlationId); return lockService.trySetLock(suiteIdentifier, correlationId); } - private SuiteRunner createSuiteRunner(Suite suite) throws JMSException { + private SuiteRunner createSuiteRunner(Run objectToRun) throws JMSException { Session session = jmsConnection.getJmsSession(); SuiteRunner suiteRunner = new SuiteRunner(session, cacheUpdater, - suiteStatusHandler, suite, RUNNER_IN_QUEUE, config.messageReceiveTimeout()); - suiteRunnerCache.put(suite.getCorrelationId(), suiteRunner); - suiteStatusCache.put(suite.getCorrelationId(), new ConcurrentLinkedQueue()); + suiteStatusHandler, objectToRun, RUNNER_IN_QUEUE, config.messageReceiveTimeout()); + suiteRunnerCache.put(objectToRun.getCorrelationId(), suiteRunner); + suiteStatusCache + .put(objectToRun.getCorrelationId(), new ConcurrentLinkedQueue()); return suiteRunner; } - private String getReportUrl(String format, String domain, Suite suite) { + private String getReportUrl(String format, String domain, Run objectToRunWrapper) { return String - .format(format, domain, suite.getCompany(), suite.getProject(), suite.getCorrelationId()); + .format(format, domain, objectToRunWrapper.getCompany(), objectToRunWrapper.getProject(), + objectToRunWrapper.getCorrelationId()); } - private String getStatusUrl(Suite suite) { - return SuiteStatusServlet.SERVLET_PATH + "/" + suite.getCorrelationId(); + private String getStatusUrl(Run objectToRunWrapper) { + return SuiteStatusServlet.SERVLET_PATH + "/" + objectToRunWrapper.getCorrelationId(); } private static class RunnerCacheRemovalListener implements RemovalListener { diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteRerun.java b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteRerun.java new file mode 100644 index 000000000..b9da43c98 --- /dev/null +++ b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteRerun.java @@ -0,0 +1,112 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.executor; + +import static com.cognifide.aet.rest.Helper.isValidCorrelationId; +import static com.cognifide.aet.rest.Helper.isValidName; + +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.communication.api.metadata.Suite.Timestamp; +import com.cognifide.aet.communication.api.metadata.Test; +import com.cognifide.aet.communication.api.metadata.Url; +import com.cognifide.aet.communication.api.wrappers.MetadataRunDecorator; +import com.cognifide.aet.communication.api.wrappers.Run; +import com.cognifide.aet.communication.api.wrappers.SuiteRunWrapper; +import com.cognifide.aet.communication.api.wrappers.TestRunWrapper; +import com.cognifide.aet.communication.api.wrappers.UrlRunWrapper; +import com.cognifide.aet.executor.model.CorrelationIdGenerator; +import com.cognifide.aet.vs.DBKey; +import com.cognifide.aet.vs.MetadataDAO; +import com.cognifide.aet.vs.StorageException; +import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class SuiteRerun { + + private static final Logger LOGGER = LoggerFactory.getLogger(SuiteRerun.class); + + private SuiteRerun() { + } + + static Run getAndPrepareObject(MetadataDAO metadataDAO, DBKey dbKey, String correlationId, + String suiteName, String testName, String urlName) { + Suite suite = null; + try { + suite = getSuiteFromMetadata(metadataDAO, dbKey, correlationId, suiteName); + suite.setRunTimestamp(new Timestamp(System.currentTimeMillis())); + } catch (StorageException e) { + LOGGER.error("Read metadata from DB problem!", e); + } + Run objectToRunWrapper = null; + if (isSuiteRerun(testName, urlName)) { + prepareSuiteToRerun(suite); + objectToRunWrapper = new SuiteRunWrapper(suite); + } else if (isTestRerun(testName, urlName)) { + Optional test = suite.getTest(testName); + test.get().setRerunUrls(); + if(test.isPresent()){ + objectToRunWrapper = new MetadataRunDecorator(new TestRunWrapper(test.get()), suite); + } + } else if (isUrlRerun(testName, urlName)) { + Optional test = suite.getTest(testName); + if(test.isPresent()){ + Optional url = test.get().getUrl(urlName); + if(url.isPresent()){ + UrlRunWrapper urlRunWrapper = new UrlRunWrapper(url.get(), test.get()); + urlRunWrapper.setReran(); + objectToRunWrapper = new MetadataRunDecorator(urlRunWrapper, suite); + } + } + } + return objectToRunWrapper; + } + + private static boolean isSuiteRerun(String testName, String urlName) { + return testName == null && urlName == null; + } + + private static boolean isTestRerun(String testName, String urlName) { + return testName != null && urlName == null; + } + + private static boolean isUrlRerun(String testName, String urlName) { + return testName != null && urlName != null; + } + + public static Suite getSuiteFromMetadata(MetadataDAO metadataDAO, DBKey dbKey, + String correlationId, String suiteName) + throws StorageException { + if (isValidCorrelationId(correlationId)) { + return metadataDAO.getSuite(dbKey, correlationId); + } else if (isValidName(suiteName)) { + return metadataDAO.getLatestRun(dbKey, suiteName); + } else { + return null; + } + } + + private static void prepareSuiteToRerun(Suite suite) { + Optional.ofNullable(suite) + .ifPresent(s -> { + s.setCorrelationId(CorrelationIdGenerator + .generateCorrelationId(s.getCompany(), s.getProject(), s.getName())); + s.setVersion(null); + } + ); + } + +} diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteRerunServlet.java b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteRerunServlet.java new file mode 100644 index 000000000..b001e5887 --- /dev/null +++ b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteRerunServlet.java @@ -0,0 +1,136 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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 com.cognifide.aet.executor; + +import com.cognifide.aet.communication.api.execution.SuiteExecutionResult; +import com.cognifide.aet.communication.api.metadata.ValidatorException; +import com.cognifide.aet.communication.api.wrappers.Run; +import com.cognifide.aet.executor.http.HttpSuiteExecutionResultWrapper; +import com.cognifide.aet.rest.Helper; +import com.cognifide.aet.vs.MetadataDAO; +import com.google.gson.Gson; +import java.io.IOException; +import java.net.HttpURLConnection; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.CharEncoding; +import org.apache.http.HttpStatus; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.http.HttpService; +import org.osgi.service.http.NamespaceException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Component(immediate = true) +public class SuiteRerunServlet extends HttpServlet { + + private static final Logger LOGGER = LoggerFactory.getLogger(SuiteRerunServlet.class); + private static final String SERVLET_PATH = Helper.getRerunPath(); + private static final long serialVersionUID = -2644460433789203661L; + + @Reference + private HttpService httpService; + + @Reference + private SuiteExecutor suiteExecutor; + + @Reference + private transient MetadataDAO metadataDAO; + + private static final Gson GSON = new Gson(); + + private SuiteExecutionResult suiteExecutionResult; + + private HttpSuiteExecutionResultWrapper resultWrapper = null; + + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws IOException { + + addCors(response); + String correlationId = request.getParameter(Helper.CORRELATION_ID_PARAM); + String suiteName = request.getParameter(Helper.SUITE_PARAM); + String testName = request.getParameter(Helper.TEST_RERUN_PARAM); + String urlName = request.getParameter(Helper.URL_RERUN_PARAM); + + Run objectToRunWrapper = null; + + try { + objectToRunWrapper = SuiteRerun + .getAndPrepareObject(metadataDAO, Helper.getDBKeyFromRequest(request), correlationId, suiteName, + testName, urlName); + if(objectToRunWrapper != null) { + try { + resultWrapper = suiteExecutor.executeSuite(objectToRunWrapper); + createResponse(resultWrapper, response); + } catch (javax.jms.JMSException | ValidatorException e) { + e.printStackTrace(); + } + } + } catch (ValidatorException e) { + LOGGER.error("Validation problem!", e); + response.setStatus(HttpURLConnection.HTTP_BAD_REQUEST); + } + } + + private void createResponse(HttpSuiteExecutionResultWrapper resultWrapper, + HttpServletResponse response) throws IOException { + suiteExecutionResult = resultWrapper.getExecutionResult(); + String responseBody = GSON.toJson(suiteExecutionResult); + + if (resultWrapper.hasError()) { + response.sendError(resultWrapper.getStatusCode(), suiteExecutionResult.getErrorMessage()); + } else { + response.setStatus(HttpStatus.SC_OK); + response.setContentType("application/json"); + response.setCharacterEncoding(CharEncoding.UTF_8); + response.getWriter().write(responseBody); + } + } + + @Override + protected void doOptions(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + addCors(resp); + } + + private void addCors(HttpServletResponse response) { + response.setHeader("Access-Control-Allow-Origin", "*"); + response.setHeader("Access-Control-Allow-Headers", + "Origin, X-Requested-With, Content-Type, Accept"); + response.setHeader("Access-Control-Allow-Methods", "POST"); + } + + @Activate + public void start() { + try { + httpService.registerServlet(SERVLET_PATH, this, null, null); + } catch (ServletException | NamespaceException e) { + LOGGER.error("Failed to register servlet at " + SERVLET_PATH, e); + } + } + + @Deactivate + public void stop() { + httpService.unregister(SERVLET_PATH); + httpService = null; + } + +} diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteRunner.java b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteRunner.java index e5c6c7080..a281cb317 100644 --- a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteRunner.java +++ b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteRunner.java @@ -19,10 +19,10 @@ import com.cognifide.aet.communication.api.execution.SuiteStatusResult; import com.cognifide.aet.communication.api.messages.MessageType; import com.cognifide.aet.communication.api.messages.TaskMessage; -import com.cognifide.aet.communication.api.metadata.Suite; import com.cognifide.aet.executor.common.MessageProcessor; import com.cognifide.aet.executor.common.ProcessorFactory; import com.cognifide.aet.executor.common.RunnerTerminator; +import com.cognifide.aet.communication.api.wrappers.Run; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; @@ -52,22 +52,24 @@ public class SuiteRunner implements Runnable { private SuiteCacheUpdater suiteCacheUpdater; - private Suite suite; + private Run objectToRunWrapper; private String inQueueName; private long messageReceiveTimeout; - public SuiteRunner(Session session, CacheUpdater cacheUpdater, - SuiteStatusHandler suiteStatusHandler, Suite suite, String inQueueName, + public SuiteRunner( + Session session, CacheUpdater cacheUpdater, + SuiteStatusHandler suiteStatusHandler, Run objectToRunWrapper, String inQueueName, long messageReceiveTimeout) { this.session = session; this.suiteStatusHandler = suiteStatusHandler; + this.runnerTerminator = new RunnerTerminator(); - this.suite = suite; + this.objectToRunWrapper = objectToRunWrapper; this.inQueueName = inQueueName; this.messageReceiveTimeout = messageReceiveTimeout; - this.suiteCacheUpdater = new SuiteCacheUpdater(cacheUpdater, runnerTerminator, suite); + this.suiteCacheUpdater = new SuiteCacheUpdater(cacheUpdater, runnerTerminator, objectToRunWrapper); } /** @@ -78,7 +80,7 @@ public void runSuite() throws JMSException { Destination outRunnerDestination = session.createTemporaryQueue(); messageConsumer = session.createConsumer(outRunnerDestination); - TaskMessage taskMessage = new TaskMessage<>(MessageType.RUN, suite); + TaskMessage taskMessage = new TaskMessage<>(MessageType.RUN, objectToRunWrapper); ObjectMessage message = session.createObjectMessage(taskMessage); message.setJMSReplyTo(outRunnerDestination); messageProducer.send(message); @@ -122,7 +124,7 @@ public void run() { try { SuiteStatusResult status = getSuiteStatus(); if (status != null) { - suiteStatusHandler.handle(suite.getCorrelationId(), status); + suiteStatusHandler.handle(objectToRunWrapper.getCorrelationId(), status); } else { handleFatalError("Timeout was reached while receiving status message"); } @@ -155,7 +157,7 @@ private SuiteStatusResult getSuiteStatus() throws JMSException { private void handleFatalError(String errorMessage) { SuiteStatusResult status = new SuiteStatusResult(ProcessingStatus.FATAL_ERROR, errorMessage); - suiteStatusHandler.handle(suite.getCorrelationId(), status); + suiteStatusHandler.handle(objectToRunWrapper.getCorrelationId(), status); runnerTerminator.finish(); } } diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteServlet.java b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteServlet.java index edcf090aa..ef4d8e0db 100644 --- a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteServlet.java +++ b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteServlet.java @@ -17,6 +17,7 @@ import com.cognifide.aet.communication.api.execution.SuiteExecutionResult; import com.cognifide.aet.executor.http.HttpSuiteExecutionResultWrapper; +import com.cognifide.aet.vs.MetadataDAO; import com.google.gson.Gson; import java.io.IOException; import java.io.InputStream; @@ -55,7 +56,7 @@ public class SuiteServlet extends HttpServlet { private static final String DOMAIN_PARAM = "domain"; private static final String PATTERN_CORRELATION_ID_PARAM = "pattern"; private static final String PATTERN_SUITE_PARAM = "patternSuite"; - + private static final String TEST_NAME_PARAM = "testName"; @Reference private HttpService httpService; @@ -63,6 +64,9 @@ public class SuiteServlet extends HttpServlet { @Reference private SuiteExecutor suiteExecutor; + @Reference + private transient MetadataDAO metadataDAO; + /** * Starts processing of the test suite defined in the XML file provided in post body. Overrides * domain specified in the suite file if one has been provided in post body. Returns JSON defined diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteStatusServlet.java b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteStatusServlet.java index 144754eae..8936aa405 100644 --- a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteStatusServlet.java +++ b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteStatusServlet.java @@ -37,7 +37,7 @@ public class SuiteStatusServlet extends HttpServlet { private static final Logger LOGGER = LoggerFactory.getLogger(SuiteStatusServlet.class); - public static final String SERVLET_PATH = "/suitestatus"; + public static final String SERVLET_PATH = "/api/suitestatus"; @Reference private HttpService httpService; @@ -55,7 +55,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) String correlationId = StringUtils.substringAfter(request.getRequestURI(), SERVLET_PATH) .replace("/", ""); SuiteStatusResult suiteStatusResult = suiteExecutor.getExecutionStatus(correlationId); - + addCors(response); if (suiteStatusResult != null) { Gson gson = new Gson(); String responseBody = gson.toJson(suiteStatusResult); @@ -78,6 +78,19 @@ public void start() { } } + @Override + protected void doOptions(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + addCors(resp); + } + + private void addCors(HttpServletResponse response) { + response.setHeader("Access-Control-Allow-Origin", "*"); + response.setHeader("Access-Control-Allow-Headers", + "Origin, X-Requested-With, Content-Type, Accept"); + response.setHeader("Access-Control-Allow-Methods", "POST"); + } + @Deactivate public void stop() { httpService.unregister(SERVLET_PATH); diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/common/ProgressMessageProcessor.java b/test-executor/src/main/java/com/cognifide/aet/executor/common/ProgressMessageProcessor.java index 8abdf0286..2a1d9a064 100644 --- a/test-executor/src/main/java/com/cognifide/aet/executor/common/ProgressMessageProcessor.java +++ b/test-executor/src/main/java/com/cognifide/aet/executor/common/ProgressMessageProcessor.java @@ -21,18 +21,13 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; -import org.apache.commons.lang3.StringUtils; class ProgressMessageProcessor implements MessageProcessor { private static final String DATE_FORMAT = "HH:mm:ss.SSS"; - private static final ThreadLocal DATE_FORMATTER = new ThreadLocal() { - @Override - protected DateFormat initialValue() { - return new SimpleDateFormat(DATE_FORMAT); - } - }; + private static final ThreadLocal DATE_FORMATTER = ThreadLocal + .withInitial(() -> new SimpleDateFormat(DATE_FORMAT)); private final ProgressMessage progressMessage; @@ -42,11 +37,14 @@ protected DateFormat initialValue() { @Override public SuiteStatusResult process() { - String message = null; - if (progressMessage != null && StringUtils.isNotEmpty(progressMessage.getData())) { - message = String.format("[%s]: %s", DATE_FORMATTER.get().format(new Date()), - progressMessage.getData()); + SuiteStatusResult result; + if (progressMessage != null && progressMessage.getData() != null) { + String message = String.format("[%s]: %s", DATE_FORMATTER.get().format(new Date()), + progressMessage.getData().toString()); + result = new SuiteStatusResult(ProcessingStatus.PROGRESS, message, progressMessage.getData()); + } else { + result = new SuiteStatusResult(ProcessingStatus.PROGRESS); } - return new SuiteStatusResult(ProcessingStatus.PROGRESS, message); + return result; } } diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/model/CorrelationIdGenerator.java b/test-executor/src/main/java/com/cognifide/aet/executor/model/CorrelationIdGenerator.java index fc1236970..2ed2c708f 100644 --- a/test-executor/src/main/java/com/cognifide/aet/executor/model/CorrelationIdGenerator.java +++ b/test-executor/src/main/java/com/cognifide/aet/executor/model/CorrelationIdGenerator.java @@ -15,7 +15,7 @@ */ package com.cognifide.aet.executor.model; -final class CorrelationIdGenerator { +final public class CorrelationIdGenerator { private static final String CORRELATION_ID_SEPARATOR = "-";