Skip to content

Commit

Permalink
Merge pull request #37 from jscancella/mutationTesting
Browse files Browse the repository at this point in the history
refs #18 - pitest
  • Loading branch information
jscancella authored Mar 1, 2020
2 parents c12c7f7 + 33ede94 commit 1276292
Show file tree
Hide file tree
Showing 35 changed files with 756 additions and 87 deletions.
26 changes: 17 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
plugins {
id 'java'

//these have to be in the main project for now see - https://discuss.gradle.org/t/how-do-i-include-buildscript-block-from-external-gradle-script/7016/2
//these have to be in the main project for now see:
//https://discuss.gradle.org/t/how-do-i-include-buildscript-block-from-external-gradle-script/7016/2
id "com.github.kt3k.coveralls" version "2.9.0"
id "de.aaschmid.cpd" version "3.1"
id "org.owasp.dependencycheck" version "5.3.0"
// id "com.dorongold.task-tree" version "1.5"
id "org.ajoberstar.grgit" version "4.0.1"
id "jp.skypencil.spotbugs.snom" version "0.5.1"
// id "com.github.spotbugs" version "3.0.0"
id "com.jfrog.bintray" version "1.8.4"
id 'info.solidsoft.pitest' version '1.4.7'
}
apply from: 'eclipse.gradle'
apply from: 'bintray.gradle'
//apply from: 'maven-central.gradle'
apply from: 'code-quality.gradle'
apply from: 'message-bundle.gradle'

sourceCompatibility = 1.8
targetCompatibility = 1.8

project.group = "com.github.jscancella"

if(project.version == "unspecified"){
String now = new Date().format( 'MMM-dd-yyyy_HH-mm-ss' )
project.version = "1.0.0-${now}-SNAPSHOT"
Expand Down Expand Up @@ -54,12 +56,18 @@ test {
//testLogging.showStandardStreams = true
}

/*tasks.withType(com.github.spotbugs.SpotBugsTask) {
reports {
xml.enabled = false
html.enabled = true
}
}*/
pitest {
//turn on to figure out why BagitProfileTest is failing
//verbose = true
//it adds dependency to org.pitest:pitest-junit5-plugin and also sets "testPlugin" to "junit5"
junit5PluginVersion = '0.12'
targetClasses = ['com.github.jscancella.*']
excludedTestClasses = ['com.github.jscancella.conformance.profile.BagitProfileTest'] //breaks due to testing all fields
useClasspathFile = true
threads = 4
outputFormats = ['XML', 'HTML']
timestampedReports = false
}

import org.ajoberstar.grgit.*
task cloneConformanceSuite(){
Expand Down
6 changes: 2 additions & 4 deletions code-quality.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,8 @@ jacocoTestReport.dependsOn test //ensure the tests have run before generating a
check.dependsOn integrationTest //run the integration tests
check.dependsOn jacocoTestReport //run the code coverage reports
check.dependsOn javadoc //ensure javadocs are generated correctly

//ignore some of the code quality checks for tests since you can't always follow the best practices when testing
//spotbugsIntegrationTest.enabled = false
//spotbugsTest.enabled = false
check.dependsOn spotbugsMain //run the spotbugs on the main source code
check.dependsOn pmdMain //run pmd and cpd on the main source code

pmdIntegrationTest.enabled = false
pmdTest.enabled = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,19 @@ public void testReadWriteProducesSameBag() throws Exception{
Path newBagDir;

for(final Path bagDir : visitor.getValidTestCases()){
newBagDir = folder.resolve("readWriteProducesSameBag");
bag = Bag.read(bagDir);
bag.write(newBagDir);

testTagFileContents(bag, newBagDir);

testBagsStructureAreEqual(bagDir, newBagDir);
delete(newBagDir);
try {
newBagDir = folder.resolve("readWriteProducesSameBag");
bag = Bag.read(bagDir);
bag.write(newBagDir);

testTagFileContents(bag, newBagDir);

testBagsStructureAreEqual(bagDir, newBagDir);
delete(newBagDir);
}
catch(Exception e) {
Assertions.fail("Read write equivialence fail on bag " + bagDir, e);
}
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/main/java/com/github/jscancella/domain/Bag.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,7 @@ public String toString() {

@Override
public int hashCode() {
return Objects.hash(version) + Objects.hash(fileEncoding) + Objects.hash(payLoadManifests) +
Objects.hash(tagManifests) + Objects.hash(itemsToFetch) + Objects.hash(metadata);
return Objects.hash(version, fileEncoding, payLoadManifests, tagManifests, itemsToFetch, metadata);
}

@Override
Expand Down
13 changes: 9 additions & 4 deletions src/main/java/com/github/jscancella/domain/BagBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.github.jscancella.domain.Metadata.MetadataBuilder;
import com.github.jscancella.domain.internal.PathPair;
import com.github.jscancella.exceptions.InvalidBagStateException;
import com.github.jscancella.exceptions.NoSuchBagitAlgorithmException;
import com.github.jscancella.hash.BagitChecksumNameMapping;

/**
Expand Down Expand Up @@ -116,6 +117,7 @@ public BagBuilder addAlgorithm(final String bagitAlgorithmName) {
}
else {
logger.error(messages.getString("algorithm_not_supported"), bagitAlgorithmName, bagitAlgorithmName);
throw new NoSuchBagitAlgorithmException("Algorithm [" + bagitAlgorithmName + "] is not supported!");
}
return this;
}
Expand Down Expand Up @@ -153,7 +155,7 @@ public BagBuilder bagLocation(final Path dir) {

/**
* Write the bag out to a physical location (on disk)
* @return this builder so as to chain commands
* @return The bag that was created
* @throws IOException if there is a problem reading a file
*/
public Bag write() throws IOException{
Expand All @@ -172,24 +174,27 @@ private Set<Manifest> createTagManifests() throws IOException{

for(final String name : bagitAlgorithmNames) {
final ManifestBuilder builder = new ManifestBuilder(name);

for(final Path tagFile : tagFiles) {
builder.addFile(tagFile, rootDir);
builder.addFile(tagFile, rootDir.relativize(rootDir));
}

manifests.add(builder.build());
}

return manifests;
}

@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
private Set<Manifest> createPayloadManifests() throws IOException{
final Set<Manifest> manifests = new HashSet<>();

for(final String name : bagitAlgorithmNames) {
final ManifestBuilder builder = new ManifestBuilder(name);
for(final PathPair pair : payloadFiles) {
builder.addFile(pair.payloadFile, rootDir.resolve(pair.relativeLocation));
final Path fullPathToNewLocation = rootDir.resolve(pair.getRelativeLocation());
final Path relativeToBaseDir = rootDir.relativize(fullPathToNewLocation);
builder.addFile(pair.getPayloadFile(), relativeToBaseDir);
}

manifests.add(builder.build());
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/github/jscancella/domain/FetchItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ private String internalToString() {
builder.append(length).append(' ');
}

builder.append(path);
builder.append(path.toString().replace('\\', '/'));

return builder.toString();
}
Expand Down Expand Up @@ -86,7 +86,7 @@ public Path getPath() {

@Override
public int hashCode() {
return Objects.hash(uri) + Objects.hash(length) + Objects.hash(path);
return Objects.hash(uri, length, path);
}

@Override
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/com/github/jscancella/domain/Manifest.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public String toString() {

@Override
public int hashCode() {
return Objects.hash(bagitAlgorithmName) + entries.hashCode();
return Objects.hash(bagitAlgorithmName, entries);
}

@Override
Expand Down Expand Up @@ -109,7 +109,9 @@ public ManifestBuilder addEntry(final ManifestEntry entry) {
*/
public ManifestBuilder addFile(final Path file, final Path relative) throws IOException {
if(Files.isDirectory(file)) {
Files.walkFileTree(file, new ManifestBuilderVistor(entries, file, hasher));
final ManifestBuilderVistor vistor = new ManifestBuilderVistor(file, hasher);
Files.walkFileTree(file, vistor);
entries.addAll(vistor.getEntries());
}
else {
final Path physicalLocation = file.toAbsolutePath();
Expand All @@ -128,5 +130,9 @@ public ManifestBuilder addFile(final Path file, final Path relative) throws IOEx
public Manifest build() {
return new Manifest(algorithmName, entries);
}

public String getAlgorithmName(){
return algorithmName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public String toString(){

@Override
public int hashCode(){
return Objects.hash(this.physicalLocation) + Objects.hash(this.relativeLocation) + Objects.hash(this.checksum);
return Objects.hash(this.physicalLocation, this.relativeLocation, this.checksum);
}

@Override
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/com/github/jscancella/domain/Metadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@ public class Metadata {
private Metadata(final Map<String, List<String>> map, final List<SimpleImmutableEntry<String, String>> list) {
this.map = Collections.unmodifiableMap(map);
this.list = Collections.unmodifiableList(list);
cachedString = String.join(",", list.stream().map(o -> o.toString()).collect(Collectors.toList()));
cachedString = buildString();
}

private String buildString() {
return String.join(",", list.stream().map(o -> o.toString()).collect(Collectors.toList()));
}

@Override
public String toString() {
if(cachedString == null) {
cachedString = String.join(",", list.stream().map(o -> o.toString()).collect(Collectors.toList()));
cachedString = buildString();
}
return cachedString;
}
Expand Down Expand Up @@ -68,7 +72,7 @@ public List<SimpleImmutableEntry<String, String>> getList(){
* @return the list of values for that label
*/
public List<String> get(final String key){
return map.get(key.toUpperCase());
return map.getOrDefault(key.toUpperCase(), Collections.EMPTY_LIST);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/github/jscancella/domain/Version.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public int compareTo(final Version other) {

@Override
public int hashCode() {
return Objects.hash(major) + Objects.hash(minor);
return Objects.hash(major, minor);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

Expand All @@ -29,13 +30,12 @@ public final class ManifestBuilderVistor extends SimpleFileVisitor<Path> {
/**
* Create a manifest from the starting point
*
* @param entries the {@link ManifestEntry} that corresponds to a particular file
* @param startingPoint The place to use when creating a relative path
* @param hasher the hashing implementation
*/
public ManifestBuilderVistor(final List<ManifestEntry> entries, final Path startingPoint, final Hasher hasher) {
public ManifestBuilderVistor(final Path startingPoint, final Hasher hasher) {
super();
this.entries = entries;
this.entries = new ArrayList<>();
this.startingPoint = Paths.get(startingPoint.toAbsolutePath().toString());
this.hasher = hasher;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

public final class PathPair {

public final Path payloadFile;
public final String relativeLocation;
private final Path payloadFile;
private final String relativeLocation;

public PathPair(final Path payloadFile, final String relativeLocation) {
this.payloadFile = payloadFile;
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/com/github/jscancella/hash/Hasher.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ public interface Hasher {
* <b>NOT THREAD SAFE</b>
*
* @param bytes the bytes with which to update the checksum
* @param length the number of bytes to update from the array
*/
void update(final byte[] bytes, final int length);
void update(final byte[] bytes);

/**
* @return the checksum of the streamed file. If no file has been streamed, returns a default hash.
Expand Down
40 changes: 20 additions & 20 deletions src/main/java/com/github/jscancella/hash/StandardHasher.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,26 +56,6 @@ public String hash(final Path path) throws IOException{
updateMessageDigest(path, messageDigestInstance);
return formatMessageDigest(messageDigestInstance);
}

@Override
public void update(final byte[] bytes, final int length){
messageDigestInstance.update(bytes, 0, length);
}

@Override
public String getHash(){
return formatMessageDigest(messageDigestInstance);
}

@Override
public void reset(){
messageDigestInstance.reset();
}

@Override
public String getBagitAlgorithmName(){
return BAGIT_ALGORITHM_NAME;
}

private static void updateMessageDigest(final Path path, final MessageDigest messageDigest) throws IOException{
try(InputStream inputStream = new BufferedInputStream(Files.newInputStream(path, StandardOpenOption.READ))){
Expand All @@ -98,7 +78,27 @@ private static String formatMessageDigest(final MessageDigest messageDigest){
return formatter.toString();
}
}

@Override
public String getHash(){
return formatMessageDigest(messageDigestInstance);
}

@Override
public void update(final byte[] bytes){
messageDigestInstance.update(bytes);
}

@Override
public void reset(){
messageDigestInstance.reset();
}

@Override
public String getBagitAlgorithmName(){
return BAGIT_ALGORITHM_NAME;
}

@Override
public void initialize() throws NoSuchAlgorithmException{
messageDigestInstance = MessageDigest.getInstance(MESSAGE_DIGEST_NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static Path writeFetchFile(final List<FetchItem> itemsToFetch, final Path
return fetchFilePath;
}

private static String formatFetchLine(final FetchItem fetchItem, final Path bagitRootDir){
static String formatFetchLine(final FetchItem fetchItem, final Path bagitRootDir){
final StringBuilder fetchLineBuilder = new StringBuilder();
fetchLineBuilder.append(fetchItem.getUri()).append(' ');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ private static Set<Path> writeManifests(

try(BufferedWriter writer = Files.newBufferedWriter(manifestPath, charsetName,
StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE)){
for(final ManifestEntry entry : manifest.getEntries()){
for(final ManifestEntry entry : manifest.getEntries()){
// there are 2 spaces between the checksum and the path so that the manifests
// are compatible with the md5sum tools available on most unix systems.
// This may cause problems on windows due to it being text mode, in which case
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import com.github.jscancella.TempFolderTest;
import com.github.jscancella.conformance.exceptions.BagitVersionIsNotAcceptableException;
import com.github.jscancella.conformance.exceptions.FetchFileNotAllowedException;
import com.github.jscancella.conformance.exceptions.MetatdataValueIsNotAcceptableException;
Expand All @@ -19,7 +18,7 @@
import com.github.jscancella.conformance.exceptions.RequiredTagFileNotPresentException;
import com.github.jscancella.domain.Bag;

public class BagProfileCheckerTest extends TempFolderTest {
public class BagProfileCheckerTest{
private static final Path profileJson = new File("src/test/resources/bagitProfiles/allOptionalFieldsProfile_v1.2.0.json").toPath();

@Test
Expand Down
Loading

0 comments on commit 1276292

Please sign in to comment.