From f120d8d5217437e2523780a040b81a5cf5c40865 Mon Sep 17 00:00:00 2001 From: Tomasz Kaik Date: Tue, 10 Jul 2018 16:48:20 +0200 Subject: [PATCH 1/3] [#121] Allow using latest patterns of given suite name Shared Patterns - added new parameter 'patternSuite' which only requires the suite name instead of full correlation ID - updated maven client plugin - updated documentation --- .../aet/plugins/maven/RunTestSuiteMojo.java | 7 ++- .../cognifide/aet/common/TestSuiteRunner.java | 16 +++--- .../src/main/wiki/ClientApplication.md | 3 +- documentation/src/main/wiki/SharedPatterns.md | 7 ++- .../cognifide/aet/executor/SuiteExecutor.java | 17 ++++-- .../cognifide/aet/executor/SuiteFactory.java | 54 +++++++++++++++---- .../cognifide/aet/executor/SuiteServlet.java | 10 ++-- .../aet/executor/SuiteValidator.java | 19 ++++--- .../aet/executor/model/TestSuiteRun.java | 10 ++++ 9 files changed, 104 insertions(+), 39 deletions(-) diff --git a/client/aet-maven-plugin/src/main/java/com/cognifide/aet/plugins/maven/RunTestSuiteMojo.java b/client/aet-maven-plugin/src/main/java/com/cognifide/aet/plugins/maven/RunTestSuiteMojo.java index 6a6f4e134..4c7f6f04d 100644 --- a/client/aet-maven-plugin/src/main/java/com/cognifide/aet/plugins/maven/RunTestSuiteMojo.java +++ b/client/aet-maven-plugin/src/main/java/com/cognifide/aet/plugins/maven/RunTestSuiteMojo.java @@ -45,7 +45,10 @@ public class RunTestSuiteMojo extends AbstractMojo { private String domain; @Parameter(property = "pattern") - private String pattern; + private String patternCorrelationId; + + @Parameter(property = "patternSuite") + private String patternSuite; @Parameter(property = "timeout", defaultValue = "300000") private int timeout; @@ -61,7 +64,7 @@ public void execute() throws MojoExecutionException { validateConfiguration(); try { TestSuiteRunner testSuiteRunner = new TestSuiteRunner(endpointDomain, - mavenProject.getBuild().getDirectory(), timeout, name, domain, pattern, xUnit); + mavenProject.getBuild().getDirectory(), timeout, name, domain, patternCorrelationId, patternSuite, xUnit); testSuiteRunner.runTestSuite(testSuite); } catch (AETException e) { diff --git a/client/client-core/src/main/java/com/cognifide/aet/common/TestSuiteRunner.java b/client/client-core/src/main/java/com/cognifide/aet/common/TestSuiteRunner.java index 7b239ae8f..147eb12b8 100644 --- a/client/client-core/src/main/java/com/cognifide/aet/common/TestSuiteRunner.java +++ b/client/client-core/src/main/java/com/cognifide/aet/common/TestSuiteRunner.java @@ -37,12 +37,8 @@ public class TestSuiteRunner { 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 static final int STATUS_CHECK_INTERVAL_MILLIS = 1000; @@ -64,12 +60,14 @@ protected DateFormat initialValue() { private final String patternCorrelationId; + private final String patternSuite; + private final boolean xUnit; public TestSuiteRunner(String endpointDomain, String buildDirectory, int timeout, String name, String domain, - String patternCorrelationId, boolean xUnit) { + String patternCorrelationId, String patternSuite, boolean xUnit) { this.redirectWriter = new RedirectWriter(buildDirectory); this.buildDirectory = buildDirectory; this.timeout = timeout; @@ -77,6 +75,7 @@ public TestSuiteRunner(String endpointDomain, String buildDirectory, int timeout this.name = name; this.domain = domain; this.patternCorrelationId = patternCorrelationId; + this.patternSuite = patternSuite; this.xUnit = xUnit; suiteExecutionResponseHandler = new JsonResponseHandler<>(SuiteExecutionResult.class); suiteStatusResponseHandler = new JsonResponseHandler<>(SuiteStatusResult.class); @@ -140,6 +139,9 @@ private SuiteExecutionResult startSuiteExecution(File testSuite) { if (patternCorrelationId != null) { entityBuilder.addTextBody("pattern", patternCorrelationId); } + if (patternSuite != null) { + entityBuilder.addTextBody("patternSuite", patternSuite); + } HttpEntity entity = entityBuilder.build(); return retrieveSuiteExecutionResult(entity, timeout); diff --git a/documentation/src/main/wiki/ClientApplication.md b/documentation/src/main/wiki/ClientApplication.md index 76a06a91e..a7f47ebe6 100644 --- a/documentation/src/main/wiki/ClientApplication.md +++ b/documentation/src/main/wiki/ClientApplication.md @@ -34,7 +34,8 @@ mvn aet:run -DtestSuite=FULL_PATH_TO_TEST_SUITE | `name` | Overrides the *name* parameter value from the test suite definition. | - | no | | `domain` | Overrides the *domain* parameter value from the test suite definition. | - | no | | `timeout` | Milliseconds to detect the timeout since the last status received from AET. This is useful to abort the test run if there is no activity for a long time. | 300000 (5 minutes) | no | -| `pattern` | Id of suite that will be used as patterns source. Identical structure of pattern and current suites is assumed. | - | no | +| `pattern` | Correlation ID of suite that will be used as patterns source. Identical structure of pattern and current suites is assumed. If you want to use latest patterns of given suite without specifying full correlation ID, use `patternSuite` parameter instead. | - | no | +| `patternSuite` | Name of the suite, whose latest version will be used as patterns source. Identical structure of pattern and current suites is assumed. This parameter is ignored if `pattern` parameter is already specified. | - | no | | `xUnit` | The flag that indicates whether the xUnit report should be generated and downloaded or not.| false | no | ##### Test results diff --git a/documentation/src/main/wiki/SharedPatterns.md b/documentation/src/main/wiki/SharedPatterns.md index 5e0b7cfa4..60b7b40dd 100644 --- a/documentation/src/main/wiki/SharedPatterns.md +++ b/documentation/src/main/wiki/SharedPatterns.md @@ -88,8 +88,11 @@ you may use different set of [[Modifiers|Modifiers]]: When you run `green` suite use [[following command|ClientApplication#parameters]] to use suite pattern from **master** suite execution. +`mvn aet:run -DtestSuite=green.xml -DpatternSuite=master` + +This option will enforce AET to use patterns from latest version of `master` suite. Alternatively, if you want to use patterns from a specific version (i.e. correlation ID) of `master` suite, use: + `mvn aet:run -DtestSuite=green.xml -Dpattern=company-project-master-1495191612345` -This option will enforce AET to use patterns from specific version of `master` suite. -**Remember that `master` suite must be run before running `green` suite with `patternCorrelationId` option.** +**Remember that `master` suite must be run before running `green` suite with `pattern` or `patternSuite` option.** In other case, running `green` suite will be treated as running it for the first time. 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 f292664c4..510b573b7 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 @@ -29,6 +29,7 @@ import com.cognifide.aet.executor.xmlparser.xml.XmlTestSuiteParser; import com.cognifide.aet.rest.LockService; import com.cognifide.aet.rest.helpers.ReportConfigurationManager; +import com.cognifide.aet.vs.MetadataDAO; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.cache.RemovalListener; @@ -95,6 +96,9 @@ public class SuiteExecutor { @Reference private SuiteValidator suiteValidator; + @Reference + private SuiteFactory suiteFactory; + private Cache suiteRunnerCache; private Cache> suiteStatusCache; @@ -126,12 +130,14 @@ public void activate(Map properties) { * * @param suiteString - content of the test suite XML file * @param domain - overrides domain defined in the suite file - * @param pattern - optional pattern to set, this is a name 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 pattern) { + String patternCorrelationId, String patternSuite) { SuiteRunner suiteRunner = null; HttpSuiteExecutionResultWrapper result; @@ -139,11 +145,12 @@ HttpSuiteExecutionResultWrapper execute(String suiteString, String name, String try { TestSuiteRun testSuiteRun = xmlFileParser.parse(suiteString); testSuiteRun = overrideDomainOrNameIfDefined(testSuiteRun, name, domain); - testSuiteRun.setPatternCorrelationId(pattern); + testSuiteRun.setPatternCorrelationId(patternCorrelationId); + testSuiteRun.setPatternSuite(patternSuite); String validationError = suiteValidator.validateTestSuiteRun(testSuiteRun); if (validationError == null) { - final Suite suite = new SuiteFactory().suiteFromTestSuiteRun(testSuiteRun); + final Suite suite = suiteFactory.suiteFromTestSuiteRun(testSuiteRun); suite.validate(Sets.newHashSet("version", "runTimestamp")); if (lockTestSuite(suite)) { diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteFactory.java b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteFactory.java index 3c958e01a..ababb6b26 100644 --- a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteFactory.java +++ b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteFactory.java @@ -27,13 +27,34 @@ import com.cognifide.aet.executor.model.ParametrizedStep; import com.cognifide.aet.executor.model.TestRun; import com.cognifide.aet.executor.model.TestSuiteRun; +import com.cognifide.aet.vs.MetadataDAO; +import com.cognifide.aet.vs.SimpleDBKey; +import com.cognifide.aet.vs.StorageException; import com.google.common.base.Function; import com.google.common.collect.FluentIterable; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.Service; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -class SuiteFactory { + +@Service(SuiteFactory.class) +@Component( + label = "AET Suite Factory", + description = "Creates a new Suite object from the test suite", + immediate = true +) +public class SuiteFactory { + + private static final Logger LOG = LoggerFactory.getLogger(SuiteFactory.class); + + @Reference + private MetadataDAO metadataDao; Suite suiteFromTestSuiteRun(TestSuiteRun testSuiteRun) { Suite suite = suiteFromTestRun(testSuiteRun); @@ -96,11 +117,25 @@ private Suite suiteFromTestRun(TestSuiteRun testSuiteRun) { String company = testSuiteRun.getCompany(); String project = testSuiteRun.getProject(); String name = testSuiteRun.getName(); - String patternCorrelationId = testSuiteRun.getPatternCorrelationId(); - + String patternCorrelationId = getPatternCorrelationId(testSuiteRun); return new Suite(correlationId, company, project, name, patternCorrelationId); } + private String getPatternCorrelationId(TestSuiteRun testSuiteRun) { + String result = testSuiteRun.getPatternCorrelationId(); + if (result == null && testSuiteRun.getPatternSuite() != null) { + SimpleDBKey dbKey = new SimpleDBKey(testSuiteRun.getCompany(), testSuiteRun.getProject()); + try { + Suite patternSuite = metadataDao.getLatestRun(dbKey, testSuiteRun.getPatternSuite()); + result = patternSuite != null ? patternSuite.getCorrelationId() : null; + } catch (StorageException e) { + LOG.error("Error while retrieving suite from mongo db: '{}', suiteName: '{}'", + dbKey, testSuiteRun.getPatternSuite(), e); + } + } + return result; + } + private boolean comparatorMatchesCollector(CollectorStep collectorStep, ComparatorStep comparatorStep) { return StringUtils.isEmpty(comparatorStep.getCollectorName()) || StringUtils @@ -108,14 +143,11 @@ private boolean comparatorMatchesCollector(CollectorStep collectorStep, } private List extractOperations(List steps) { - return FluentIterable.from(steps).transform(new Function() { - @Override - public Operation apply(ParametrizedStep step) { - final Operation operation = new Operation(step.getName()); - operation.addParameters(step.getParameters()); - return operation; - } - }).toList(); + return steps.stream().map(step -> { + final Operation operation = new Operation(step.getName()); + operation.addParameters(step.getParameters()); + return operation; + }).collect(Collectors.toList()); } } 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 f644d4ae2..c0e9562c1 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 @@ -55,7 +55,8 @@ public class SuiteServlet extends HttpServlet { private static final String SUITE_PARAM = "suite"; private static final String NAME_PARAM = "name"; private static final String DOMAIN_PARAM = "domain"; - private static final String PATTERN_PARAM = "pattern"; + private static final String PATTERN_CORRELATION_ID_PARAM = "pattern"; + private static final String PATTERN_SUITE_PARAM = "patternSuite"; @Reference @@ -71,17 +72,18 @@ public class SuiteServlet extends HttpServlet { */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { + throws IOException { if (ServletFileUpload.isMultipartContent(request)) { Map requestData = getRequestData(request); final String suite = requestData.get(SUITE_PARAM); final String name = requestData.get(NAME_PARAM); final String domain = requestData.get(DOMAIN_PARAM); - final String pattern = requestData.get(PATTERN_PARAM); + final String patternCorrelationId = requestData.get(PATTERN_CORRELATION_ID_PARAM); + final String patternSuite = requestData.get(PATTERN_SUITE_PARAM); if (StringUtils.isNotBlank(suite)) { HttpSuiteExecutionResultWrapper resultWrapper = suiteExecutor - .execute(suite, name, domain, pattern); + .execute(suite, name, domain, patternCorrelationId, patternSuite); final SuiteExecutionResult suiteExecutionResult = resultWrapper.getExecutionResult(); Gson gson = new Gson(); diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteValidator.java b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteValidator.java index 7a72cc902..787bf011b 100644 --- a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteValidator.java +++ b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteValidator.java @@ -60,8 +60,8 @@ public String validateTestSuiteRun(TestSuiteRun testSuiteRun) { } boolean patternValid = isPatternInDatabase(testSuiteRun); if (!patternValid) { - return String.format("Incorrect pattern: '%s'. Not found in database.", - testSuiteRun.getPatternCorrelationId()); + return String.format("Incorrect pattern: correlationId='%s', suiteName='%s'. Not found in database.", + testSuiteRun.getPatternCorrelationId(), testSuiteRun.getPatternSuite()); } for (TestRun testRun : testSuiteRun.getTestRunMap().values()) { if (hasScreenCollector(testRun) && !hasScreenComparator(testRun)) { @@ -81,7 +81,7 @@ public String validateTestSuiteRun(TestSuiteRun testSuiteRun) { * @return true if suite is OK */ private boolean isPatternFromSameProject(TestSuiteRun testSuiteRun) { - boolean sameProject = false; + boolean sameProject; String pattern = testSuiteRun.getPatternCorrelationId(); if (pattern == null) { // patterns will be taken from same suite automatically @@ -121,15 +121,20 @@ private boolean isPatternInDatabase(TestSuiteRun testSuiteRun) { boolean valid = false; SimpleDBKey dbKey = new SimpleDBKey(testSuiteRun.getCompany(), testSuiteRun.getProject()); String patternCorrelationId = testSuiteRun.getPatternCorrelationId(); - if (patternCorrelationId == null) { + String patternSuiteName = testSuiteRun.getPatternSuite(); + if (patternCorrelationId == null && patternSuiteName == null) { valid = true; } else { Suite patternSuite = null; try { - patternSuite = metadataDAO.getSuite(dbKey, patternCorrelationId); + if (patternCorrelationId != null) { + patternSuite = metadataDAO.getSuite(dbKey, patternCorrelationId); + } else { + patternSuite = metadataDAO.getLatestRun(dbKey, patternSuiteName); + } } catch (StorageException se) { - LOG.error("error while retrieving suite from mongo db: '{}', correlationId: '{}'", - dbKey, patternCorrelationId, se); + LOG.error("error while retrieving suite from mongo db: '{}', correlationId: '{}', suiteName: '{}'", + dbKey, patternCorrelationId, patternSuiteName, se); } if (patternSuite != null) { valid = true; diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/model/TestSuiteRun.java b/test-executor/src/main/java/com/cognifide/aet/executor/model/TestSuiteRun.java index a2d38fd5a..31e5dbb7f 100644 --- a/test-executor/src/main/java/com/cognifide/aet/executor/model/TestSuiteRun.java +++ b/test-executor/src/main/java/com/cognifide/aet/executor/model/TestSuiteRun.java @@ -45,6 +45,8 @@ public class TestSuiteRun implements Serializable { private String patternCorrelationId; + private String patternSuite; + /** * Parameters: name, company, project are part of identifier of test suite. * @@ -157,4 +159,12 @@ public void setPatternCorrelationId(String patternCorrelationId) { public String getPatternCorrelationId() { return patternCorrelationId; } + + public String getPatternSuite() { + return patternSuite; + } + + public void setPatternSuite(String patternSuite) { + this.patternSuite = patternSuite; + } } From 525eddf40568afdcab030520e3c6fd65819fd014 Mon Sep 17 00:00:00 2001 From: Tomasz Kaik Date: Wed, 11 Jul 2018 14:03:02 +0200 Subject: [PATCH 2/3] Unit tests for SuiteFactory and SuiteValidator --- .../cognifide/aet/executor/SuiteFactory.java | 11 +- .../aet/executor/SuiteValidator.java | 17 +- .../aet/executor/SuiteFactoryTest.java | 88 +++++++++++ .../aet/executor/SuiteValidatorTest.java | 147 ++++++++++++++++++ 4 files changed, 258 insertions(+), 5 deletions(-) create mode 100644 test-executor/src/test/java/com/cognifide/aet/executor/SuiteFactoryTest.java create mode 100644 test-executor/src/test/java/com/cognifide/aet/executor/SuiteValidatorTest.java diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteFactory.java b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteFactory.java index ababb6b26..d5f932259 100644 --- a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteFactory.java +++ b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteFactory.java @@ -30,8 +30,6 @@ import com.cognifide.aet.vs.MetadataDAO; import com.cognifide.aet.vs.SimpleDBKey; import com.cognifide.aet.vs.StorageException; -import com.google.common.base.Function; -import com.google.common.collect.FluentIterable; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -56,6 +54,15 @@ public class SuiteFactory { @Reference private MetadataDAO metadataDao; + public SuiteFactory() { + // default constructor + } + + // for unit tests + SuiteFactory(MetadataDAO metadataDAO) { + this.metadataDao = metadataDAO; + } + Suite suiteFromTestSuiteRun(TestSuiteRun testSuiteRun) { Suite suite = suiteFromTestRun(testSuiteRun); diff --git a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteValidator.java b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteValidator.java index 787bf011b..b68d5d45e 100644 --- a/test-executor/src/main/java/com/cognifide/aet/executor/SuiteValidator.java +++ b/test-executor/src/main/java/com/cognifide/aet/executor/SuiteValidator.java @@ -49,6 +49,15 @@ public class SuiteValidator { @Reference private MetadataDAO metadataDAO; + public SuiteValidator() { + // default constructor + } + + // for unit tests + SuiteValidator(MetadataDAO metadataDAO) { + this.metadataDAO = metadataDAO; + } + public String validateTestSuiteRun(TestSuiteRun testSuiteRun) { boolean patternFromSameProject = isPatternFromSameProject(testSuiteRun); if (!patternFromSameProject) { @@ -60,8 +69,9 @@ public String validateTestSuiteRun(TestSuiteRun testSuiteRun) { } boolean patternValid = isPatternInDatabase(testSuiteRun); if (!patternValid) { - return String.format("Incorrect pattern: correlationId='%s', suiteName='%s'. Not found in database.", - testSuiteRun.getPatternCorrelationId(), testSuiteRun.getPatternSuite()); + return String + .format("Incorrect pattern: correlationId='%s', suiteName='%s'. Not found in database.", + testSuiteRun.getPatternCorrelationId(), testSuiteRun.getPatternSuite()); } for (TestRun testRun : testSuiteRun.getTestRunMap().values()) { if (hasScreenCollector(testRun) && !hasScreenComparator(testRun)) { @@ -133,7 +143,8 @@ private boolean isPatternInDatabase(TestSuiteRun testSuiteRun) { patternSuite = metadataDAO.getLatestRun(dbKey, patternSuiteName); } } catch (StorageException se) { - LOG.error("error while retrieving suite from mongo db: '{}', correlationId: '{}', suiteName: '{}'", + LOG.error( + "error while retrieving suite from mongo db: '{}', correlationId: '{}', suiteName: '{}'", dbKey, patternCorrelationId, patternSuiteName, se); } if (patternSuite != null) { diff --git a/test-executor/src/test/java/com/cognifide/aet/executor/SuiteFactoryTest.java b/test-executor/src/test/java/com/cognifide/aet/executor/SuiteFactoryTest.java new file mode 100644 index 000000000..d1c6bb679 --- /dev/null +++ b/test-executor/src/test/java/com/cognifide/aet/executor/SuiteFactoryTest.java @@ -0,0 +1,88 @@ +/** + * 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 org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; + +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.executor.model.TestSuiteRun; +import com.cognifide.aet.vs.MetadataDAO; +import com.cognifide.aet.vs.StorageException; +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 SuiteFactoryTest { + + private static final String COMPANY = "company"; + private static final String PROJECT = "project"; + private static final String SUITE_NAME = "suite-name"; + private static final String CORRELATION_ID = "company-project-suite-name-123456789"; + + private SuiteFactory suiteFactory; + + @Mock + private MetadataDAO metadataDAO; + + @Mock + private TestSuiteRun testSuiteRun; + + @Mock + private Suite patternSuite; + + @Before + public void setUp() { + suiteFactory = new SuiteFactory(metadataDAO); + when(testSuiteRun.getCompany()).thenReturn(COMPANY); + when(testSuiteRun.getProject()).thenReturn(PROJECT); + when(testSuiteRun.getName()).thenReturn(SUITE_NAME); + when(testSuiteRun.getCorrelationId()).thenReturn(CORRELATION_ID); + } + + @Test + public void suiteFromTestSuiteRun_whenValidTestSuite_expectSameFieldsInResult() { + String patternCorrelationId = "company-project-other-suite-012345678"; + when(testSuiteRun.getPatternCorrelationId()).thenReturn(patternCorrelationId); + + Suite suite = suiteFactory.suiteFromTestSuiteRun(testSuiteRun); + assertThat(suite.getCompany(), equalTo(COMPANY)); + assertThat(suite.getProject(), equalTo(PROJECT)); + assertThat(suite.getName(), equalTo(SUITE_NAME)); + assertThat(suite.getCorrelationId(), equalTo(CORRELATION_ID)); + assertThat(suite.getPatternCorrelationId(), equalTo(patternCorrelationId)); + } + + @Test + public void suiteFromTestSuiteRun_whenPatternSuiteNameProvided_expectFetchingPatternIdFromDb() + throws StorageException { + String patternCorrelationId = "company-project-other-suite-012345678"; + String patternSuiteName = "other-suite"; + when(testSuiteRun.getPatternSuite()).thenReturn(patternSuiteName); + when(metadataDAO.getLatestRun(any(), eq(patternSuiteName))).thenReturn(patternSuite); + when(patternSuite.getCorrelationId()).thenReturn(patternCorrelationId); + + Suite suite = suiteFactory.suiteFromTestSuiteRun(testSuiteRun); + assertThat(suite.getPatternCorrelationId(), equalTo(patternCorrelationId)); + } + +} diff --git a/test-executor/src/test/java/com/cognifide/aet/executor/SuiteValidatorTest.java b/test-executor/src/test/java/com/cognifide/aet/executor/SuiteValidatorTest.java new file mode 100644 index 000000000..3e86f9584 --- /dev/null +++ b/test-executor/src/test/java/com/cognifide/aet/executor/SuiteValidatorTest.java @@ -0,0 +1,147 @@ +/** + * 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 org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.cognifide.aet.communication.api.metadata.Suite; +import com.cognifide.aet.executor.model.CollectorStep; +import com.cognifide.aet.executor.model.ComparatorStep; +import com.cognifide.aet.executor.model.TestRun; +import com.cognifide.aet.executor.model.TestSuiteRun; +import com.cognifide.aet.vs.MetadataDAO; +import com.cognifide.aet.vs.StorageException; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import java.util.Collections; +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 SuiteValidatorTest { + + private static final String COMPANY = "company"; + private static final String PROJECT = "project"; + private static final String TEST_NAME = "testName"; + + private SuiteValidator suiteValidator; + + @Mock + private MetadataDAO metadataDAO; + + @Mock + private TestSuiteRun testSuiteRun; + + @Mock + private TestRun testRun; + + @Before + public void setUp() { + suiteValidator = new SuiteValidator(metadataDAO); + when(testSuiteRun.getCompany()).thenReturn(COMPANY); + when(testSuiteRun.getProject()).thenReturn(PROJECT); + } + + @Test + public void validateTestSuiteRun_whenPatternIdFromDifferentProject_expectError() { + String patternCorrelationId = "company1-project1-suite-name-123456789"; + when(testSuiteRun.getPatternCorrelationId()).thenReturn(patternCorrelationId); + + String errorMessage = String.format( + "Incorrect pattern: '%s'. Must belong to same company (%s) and project (%s).", + patternCorrelationId, COMPANY, PROJECT); + assertThat(suiteValidator.validateTestSuiteRun(testSuiteRun), equalTo(errorMessage)); + } + + @Test + public void validateTestSuiteRun_whenPatternIdNotInDb_expectError() throws StorageException { + String patternCorrelationId = "company-project-suite-name-123456789"; + when(testSuiteRun.getPatternCorrelationId()).thenReturn(patternCorrelationId); + + String errorMessage = String.format( + "Incorrect pattern: correlationId='%s', suiteName='%s'. Not found in database.", + patternCorrelationId, null); + assertThat(suiteValidator.validateTestSuiteRun(testSuiteRun), equalTo(errorMessage)); + verify(metadataDAO).getSuite(any(), eq(patternCorrelationId)); + } + + @Test + public void validateTestSuiteRun_whenPatternSuiteNotInDb_expectError() throws StorageException { + String patternSuite = "suite-name"; + when(testSuiteRun.getPatternSuite()).thenReturn(patternSuite); + + String errorMessage = String.format( + "Incorrect pattern: correlationId='%s', suiteName='%s'. Not found in database.", + null, patternSuite); + assertThat(suiteValidator.validateTestSuiteRun(testSuiteRun), equalTo(errorMessage)); + verify(metadataDAO).getLatestRun(any(), eq(patternSuite)); + } + + @Test + public void validateTestSuiteRun_whenScreenCollectorWithoutComparator_expectError() { + givenSuiteHasTestWithScreenCollector(); + String errorMessage = String.format( + "Test suite does not contain screen comparator for screen collector in '%s' test, please fix it", + TEST_NAME); + assertThat(suiteValidator.validateTestSuiteRun(testSuiteRun), equalTo(errorMessage)); + } + + @Test + public void validateTestSuiteRun_whenValidSuite_expectSuccess() { + assertNull(suiteValidator.validateTestSuiteRun(testSuiteRun)); + } + + @Test + public void validateTestSuiteRun_whenValidSuiteWithPatternId_expectSuccess() + throws StorageException { + String patternCorrelationId = "company-project-suite-name-123456789"; + Suite patternSuite = new Suite(patternCorrelationId, COMPANY, PROJECT, "suite-name", null); + when(testSuiteRun.getPatternCorrelationId()).thenReturn(patternCorrelationId); + when(metadataDAO.getSuite(any(), eq(patternCorrelationId))).thenReturn(patternSuite); + + assertNull(suiteValidator.validateTestSuiteRun(testSuiteRun)); + } + + @Test + public void validateTestSuiteRun_whenValidSuiteWithScreenCollectorAndComparator_expectSuccess() { + givenSuiteHasTestWithScreenCollector(); + ComparatorStep screenComparator = mock(ComparatorStep.class); + when(screenComparator.getType()).thenReturn("screen"); + when(testRun.getComparatorSteps()) + .thenReturn(ImmutableMap.of("screen", Collections.singletonList(screenComparator))); + + assertNull(suiteValidator.validateTestSuiteRun(testSuiteRun)); + } + + private void givenSuiteHasTestWithScreenCollector() { + CollectorStep screenCollectorStep = new CollectorStep("screen", "screen", Maps.newHashMap()); + when(testSuiteRun.getTestRunMap()).thenReturn(ImmutableMap.of(TEST_NAME, testRun)); + when(testRun.getName()).thenReturn(TEST_NAME); + when(testRun.getCollectorSteps()).thenReturn(Collections.singletonList(screenCollectorStep)); + when(testRun.getComparatorSteps()).thenReturn(Collections.emptyMap()); + } + +} From 07e931d2b739c3aa47cf79e6f66b8e116782e4a6 Mon Sep 17 00:00:00 2001 From: Tomasz Kaik Date: Wed, 11 Jul 2018 14:42:30 +0200 Subject: [PATCH 3/3] [#121] add 'paramSuite' option to aet.sh script Updated CHANGELOG.md with created Pull Request --- CHANGELOG.md | 1 + client/client-scripts/README.md | 1 + client/client-scripts/aet.sh | 10 +++++++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afb19817c..d57a79ccd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to AET will be documented in this file. - [PR-268](https://github.com/Cognifide/aet/pull/268) Bobcat upgrade to version 1.4.0 - [PR-279](https://github.com/Cognifide/aet/pull/279) Upgrade for some of libraries used by AET - [PR-281](https://github.com/Cognifide/aet/pull/281) No version in Bundle names (simpler deployment) +- [PR-286](https://github.com/Cognifide/aet/pull/286) Shared Patterns - use latest patterns of given suite name ([#121](https://github.com/Cognifide/aet/issues/121)) ## Version 2.1.6 diff --git a/client/client-scripts/README.md b/client/client-scripts/README.md index 24beab33e..1fe046a73 100644 --- a/client/client-scripts/README.md +++ b/client/client-scripts/README.md @@ -22,6 +22,7 @@ Usage: Options: -d --domain - Override domain attribute defined in suite file -c --correlationId - Set id of patterns to run test against + -p --patternSuite - Set the suite name to run test against its latest pattern (only used if -c is not set) -i --interval - Set interval in seconds for polling suite status. Default interval : 1 sec -w --waitForUnlock - Set timeout for the script to wait for unlocked suite. Default timeout: 0 sec -v --verbose - Make it more descriptive diff --git a/client/client-scripts/aet.sh b/client/client-scripts/aet.sh index 069eda7fe..9abc7ea6d 100755 --- a/client/client-scripts/aet.sh +++ b/client/client-scripts/aet.sh @@ -23,6 +23,7 @@ SUITE_ENDPOINT="/suite" DOMAIN_BODY="" SUITE_NAME_BODY="" CORRELATION_ID_BODY="" +PATTERN_SUITE_BODY="" function usage { echo echo "AET Test executor" @@ -35,6 +36,7 @@ function usage { echo -e "\t-d --domain - Override domain attribute defined in suite file" echo -e "\t-n --name - Override name attribute defined in suite file" echo -e "\t-c --correlationId - Set id of patterns to run test against." + echo -e "\t-p --patternSuite - Set the suite name to run test against its latest pattern (only used if -c is not set)" echo -e "\t-i --interval - Set interval in seconds for polling suite status. Default interval : 1 sec." echo -e "\t-w --waitForUnlock - Set timeout for the script to wait for unlocked suite. Default timeout: 0 sec." echo -e "\t-v --verbose - Make it more descriptive" @@ -87,7 +89,7 @@ function process_locked_suite { # request /suite endpoint function start_suite { - run_response=$(curl -sw "%{http_code}" -F "suite=@$suite_file_name"$DOMAIN_BODY$SUITE_NAME_BODY$CORRELATION_ID_BODY "$endpoint$SUITE_ENDPOINT") + run_response=$(curl -sw "%{http_code}" -F "suite=@$suite_file_name"$DOMAIN_BODY$SUITE_NAME_BODY$CORRELATION_ID_BODY$PATTERN_SUITE_BODY "$endpoint$SUITE_ENDPOINT") extract_code_and_body "$run_response" if [ $code -eq 200 ]; then @@ -131,6 +133,11 @@ while [[ $# -gt 0 ]]; do CORRELATION_ID_BODY=" -F pattern=$CORRELATION_ID" shift 2 ;; + -p | --patternSuite ) + PATTERN_SUITE=$2 + PATTERN_SUITE_BODY=" -F patternSuite=$PATTERN_SUITE" + shift 2 + ;; -v | --verbose ) VERBOSE=1 shift 1 @@ -148,6 +155,7 @@ if [[ $VERBOSE -eq 1 ]]; then echo -e "\tOverridden domain: ${DOMAIN-not set}" echo -e "\tOverridden suite name: ${SUITE_NAME-not set}" echo -e "\tPattern id: ${CORRELATION_ID-not set}" + echo -e "\tPattern suite: ${PATTERN_SUITE-not set}" echo "" fi