Skip to content

Commit

Permalink
[#121] Allow using latest patterns of given suite name
Browse files Browse the repository at this point in the history
Shared Patterns - added new parameter 'patternSuite' which
only requires the suite name instead of full correlation ID
- updated maven client plugin
- updated documentation
  • Loading branch information
tkaik committed Jul 10, 2018
1 parent 724411f commit f120d8d
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,8 @@ public class TestSuiteRunner {

private static final String DATE_FORMAT = "HH:mm:ss.SSS";

private static final ThreadLocal<DateFormat> DATE_FORMATTER = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat(DATE_FORMAT);
}
};
private static final ThreadLocal<DateFormat> DATE_FORMATTER =
ThreadLocal.withInitial(() -> new SimpleDateFormat(DATE_FORMAT));

private static final int STATUS_CHECK_INTERVAL_MILLIS = 1000;

Expand All @@ -64,19 +60,22 @@ 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;
this.endpointDomain = endpointDomain;
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);
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion documentation/src/main/wiki/ClientApplication.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 5 additions & 2 deletions documentation/src/main/wiki/SharedPatterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -95,6 +96,9 @@ public class SuiteExecutor {
@Reference
private SuiteValidator suiteValidator;

@Reference
private SuiteFactory suiteFactory;

private Cache<String, SuiteRunner> suiteRunnerCache;

private Cache<String, Queue<SuiteStatusResult>> suiteStatusCache;
Expand Down Expand Up @@ -126,24 +130,27 @@ public void activate(Map<String, Object> 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;

TestSuiteParser xmlFileParser = new XmlTestSuiteParser();
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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -96,26 +117,37 @@ 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
.equals(comparatorStep.getCollectorName(), collectorStep.getName());
}

private List<Operation> extractOperations(List<? extends ParametrizedStep> steps) {
return FluentIterable.from(steps).transform(new Function<ParametrizedStep, Operation>() {
@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());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<String, String> 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();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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;
}
}

0 comments on commit f120d8d

Please sign in to comment.