com.nordstrom.automation.junit.ArtifactCollector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of junit-foundation Show documentation
Show all versions of junit-foundation Show documentation
This is the foundation framework for JUnit automation
package com.nordstrom.automation.junit;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.junit.runner.Description;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.nordstrom.common.file.PathUtils;
/**
* This is the base class for implementations of scenario-specific artifact collectors.
*
* @param scenario-specific artifact type
*/
public class ArtifactCollector extends AtomIdentity {
private static final ConcurrentHashMap>> WATCHER_MAP;
private static final Function>> NEW_INSTANCE;
static {
WATCHER_MAP = new ConcurrentHashMap<>();
NEW_INSTANCE = new Function>>() {
@Override
public List> apply(Integer input) {
return new ArrayList<>();
}
};
}
private final T provider;
private final List artifactPaths = new ArrayList<>();
public ArtifactCollector(Object instance, T provider) {
super(instance);
this.provider = provider;
}
/**
* {@inheritDoc}
*/
@Override
public void starting(Description description) {
super.starting(description);
List> watcherList =
LifecycleHooks.computeIfAbsent(WATCHER_MAP, description.hashCode(), NEW_INSTANCE);
watcherList.add(this);
}
/**
* {@inheritDoc}
*/
@Override
public void failed(Throwable e, Description description) {
captureArtifact(e);
}
/**
* Capture artifact from the current test result context.
*
* @param reason impetus for capture request; may be 'null'
* @return (optional) path at which the captured artifact was stored
*/
public Optional captureArtifact(Throwable reason) {
if (! provider.canGetArtifact(getInstance())) {
return Optional.absent();
}
byte[] artifact = provider.getArtifact(getInstance(), reason);
if ((artifact == null) || (artifact.length == 0)) {
return Optional.absent();
}
Path collectionPath = getCollectionPath();
if (!collectionPath.toFile().exists()) {
try {
Files.createDirectories(collectionPath);
} catch (IOException e) {
if (provider.getLogger() != null) {
String messageTemplate = "Unable to create collection directory ({}); no artifact was captured";
provider.getLogger().warn(messageTemplate, collectionPath, e);
}
return Optional.absent();
}
}
Path artifactPath;
try {
artifactPath = PathUtils.getNextPath(
collectionPath,
getArtifactBaseName(),
provider.getArtifactExtension());
} catch (IOException e) {
if (provider.getLogger() != null) {
provider.getLogger().warn("Unable to get output path; no artifact was captured", e);
}
return Optional.absent();
}
try {
if (provider.getLogger() != null) {
provider.getLogger().info("Saving captured artifact to ({}).", artifactPath);
}
Files.write(artifactPath, artifact);
} catch (IOException e) {
if (provider.getLogger() != null) {
provider.getLogger().warn("I/O error saving to ({}); no artifact was captured", artifactPath, e);
}
return Optional.absent();
}
recordArtifactPath(artifactPath);
return Optional.of(artifactPath);
}
/**
* Get path of directory at which to store artifacts.
*
* @return path of artifact storage directory
*/
private Path getCollectionPath() {
Path collectionPath = PathUtils.ReportsDirectory.getPathForObject(getInstance());
return collectionPath.resolve(provider.getArtifactPath(getInstance()));
}
/**
* Get base name for artifact files for the specified test result.
*
* NOTE: The base name is derived from the name of the current test.
* If the method is parameterized, a hash code is computed from the parameter
* values and appended to the base name as an 8-digit hexadecimal integer.
*
* @return artifact file base name
*/
private String getArtifactBaseName() {
int hashcode = getParameters().hashCode();
if (hashcode != 0) {
String hashStr = String.format("%08X", hashcode);
return getDescription().getMethodName() + "-" + hashStr;
} else {
return getDescription().getMethodName();
}
}
/**
* Record the path at which the specified artifact was store in the indicated test result.
*
* @param artifactPath path at which the captured artifact was stored
*/
private void recordArtifactPath(Path artifactPath) {
artifactPaths.add(artifactPath);
}
/**
* Retrieve the paths of artifacts that were stored in the indicated test result.
*
* @return (optional) list of artifact paths
*/
public Optional> retrieveArtifactPaths() {
if (artifactPaths.isEmpty()) {
return Optional.absent();
} else {
return Optional.of(artifactPaths);
}
}
/**
* Get the artifact provider object.
*
* @return artifact provider object
*/
public T getArtifactProvider() {
return provider;
}
/**
* Get reference to an instance of the specified watcher type associated with the described method.
*
* @param type-specific artifact collector class
* @param description JUnit method description object
* @param watcherType watcher type
* @return optional watcher instance
*/
@SuppressWarnings("unchecked")
public static > Optional
getWatcher(Description description, Class watcherType) {
List> watcherList = WATCHER_MAP.get(description.hashCode());
if (watcherList != null) {
for (ArtifactCollector extends ArtifactType> watcher : watcherList) {
if (watcher.getClass() == watcherType) {
return Optional.of((S) watcher);
}
}
}
return Optional.absent();
}
/**
* Release the watchers for the specified description.
*
* @param description JUnit method description
*/
static void releaseWatchersOf(Description description) {
WATCHER_MAP.remove(description.hashCode());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy