Continuing removing GUAVA dependencies from junitrunner (junit.runner.sharding
& util).
Bazel users that are using a different Guava version than the one in the
junitrunner jar are getting an IncompatibleClassChangeError. Rewriting
parts of junitrunner code so it won't depend on Guava anymore.
Continuing progress on issue #1150.
Removing most of Guava dependencies from junit.runner.sharding. A more
significant change regards rewriting Guava method
assertThat().containsExactlyElementsIn().
Also removing previous trailing spaces.
--
MOS_MIGRATED_REVID=129992951
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/HashBackedShardingFilter.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/HashBackedShardingFilter.java
index aa641a4..331e147 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/HashBackedShardingFilter.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/HashBackedShardingFilter.java
@@ -14,8 +14,6 @@
package com.google.testing.junit.runner.sharding;
-import com.google.common.base.Preconditions;
-
import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter;
@@ -28,8 +26,9 @@
private final int totalShards;
public HashBackedShardingFilter(int shardIndex, int totalShards) {
- Preconditions.checkArgument(shardIndex >= 0);
- Preconditions.checkArgument(totalShards > shardIndex);
+ if (shardIndex < 0 || totalShards <= shardIndex) {
+ throw new IllegalArgumentException();
+ }
this.shardIndex = shardIndex;
this.totalShards = totalShards;
}
@@ -43,7 +42,9 @@
if (mod < 0) {
mod += totalShards;
}
- Preconditions.checkState(mod >= 0 && mod < totalShards);
+ if (mod < 0 || mod >= totalShards) {
+ throw new IllegalStateException();
+ }
return mod == shardIndex;
}
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/RoundRobinShardingFilter.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/RoundRobinShardingFilter.java
index 09c9e31..d754436 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/RoundRobinShardingFilter.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/RoundRobinShardingFilter.java
@@ -14,12 +14,6 @@
package com.google.testing.junit.runner.sharding;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-
-import org.junit.runner.Description;
-import org.junit.runner.manipulation.Filter;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -27,6 +21,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.junit.runner.Description;
+import org.junit.runner.manipulation.Filter;
/**
* Implements the round-robin sharding strategy.
@@ -40,17 +36,18 @@
* sharding, but are done so that this filter can be compared in tests.
*/
public final class RoundRobinShardingFilter extends Filter {
- @VisibleForTesting
+ // VisibleForTesting
final Map<Description, Integer> testToShardMap;
- @VisibleForTesting
+ // VisibleForTesting
final int shardIndex;
- @VisibleForTesting
+ // VisibleForTesting
final int totalShards;
public RoundRobinShardingFilter(Collection<Description> testDescriptions,
int shardIndex, int totalShards) {
- Preconditions.checkArgument(shardIndex >= 0);
- Preconditions.checkArgument(totalShards > shardIndex);
+ if (shardIndex < 0 || totalShards <= shardIndex) {
+ throw new IllegalArgumentException();
+ }
this.testToShardMap = buildTestToShardMap(testDescriptions);
this.shardIndex = shardIndex;
this.totalShards = totalShards;
@@ -74,9 +71,10 @@
// same shard.
int index = 0;
for (Description description : sortedDescriptions) {
- Preconditions.checkArgument(description.isTest(),
- "Test suite should not be included in the set of tests to shard: %s",
- description.getDisplayName());
+ if (!description.isTest()) {
+ throw new IllegalArgumentException("Test suite should not be included in the set of tests "
+ + "to shard: " + description.getDisplayName());
+ }
map.put(description, index);
index++;
}
@@ -102,7 +100,7 @@
return "round robin sharding filter";
}
- @VisibleForTesting
+ // VisibleForTesting
static class DescriptionComparator implements Comparator<Description> {
@Override
public int compare(Description d1, Description d2) {
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/ShardingEnvironment.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/ShardingEnvironment.java
index 366f25a..dcdbedb 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/ShardingEnvironment.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/ShardingEnvironment.java
@@ -14,12 +14,8 @@
package com.google.testing.junit.runner.sharding;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.io.Files;
-
import java.io.File;
import java.io.IOException;
-
import javax.inject.Inject;
/**
@@ -76,11 +72,13 @@
touchShardFile(shardFile);
}
- @VisibleForTesting
+ // VisibleForTesting
static void touchShardFile(File shardFile) {
if (shardFile != null) {
try {
- Files.touch(shardFile);
+ if (!shardFile.createNewFile() && !shardFile.setLastModified(System.currentTimeMillis())) {
+ throw new IOException("Unable to update modification time of " + shardFile);
+ }
} catch (IOException e) {
throw new RuntimeException("Error writing shard file " + shardFile, e);
}
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/testing/ShardingFilterTestCase.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/testing/ShardingFilterTestCase.java
index 668c790..2d30acc 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/testing/ShardingFilterTestCase.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/testing/ShardingFilterTestCase.java
@@ -14,23 +14,22 @@
package com.google.testing.junit.runner.sharding.testing;
-import static com.google.common.truth.Truth.assertThat;
-
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ListMultimap;
import com.google.testing.junit.runner.sharding.api.ShardingFilterFactory;
-
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
import junit.framework.TestCase;
-
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter;
-import java.util.Deque;
-import java.util.LinkedList;
-import java.util.List;
-
/**
* Common base class for all sharding filter tests.
*/
@@ -42,7 +41,7 @@
* shard index, and total number of shards.
*/
protected abstract ShardingFilterFactory createShardingFilterFactory();
-
+
public final void testShardingIsCompleteAndPartitioned_oneShard() {
assertShardingIsCompleteAndPartitioned(createFilters(TEST_DESCRIPTIONS, 1), TEST_DESCRIPTIONS);
}
@@ -90,11 +89,11 @@
.build();
assertShardingIsStable(createFilters(descriptions, 7), descriptions);
}
-
- public final void testShouldRunTestSuite() {
- Description testSuiteDescription = createTestSuiteDescription();
- Filter filter = createShardingFilterFactory().createFilter(TEST_DESCRIPTIONS, 0, 1);
- assertTrue(filter.shouldRun(testSuiteDescription));
+
+ public final void testShouldRunTestSuite() {
+ Description testSuiteDescription = createTestSuiteDescription();
+ Filter filter = createShardingFilterFactory().createFilter(TEST_DESCRIPTIONS, 0, 1);
+ assertTrue(filter.shouldRun(testSuiteDescription));
}
/**
@@ -109,7 +108,7 @@
}
return builder.build();
}
-
+
protected static final List<Filter> createFilters(List<Description> descriptions, int numShards,
ShardingFilterFactory factory) {
ImmutableList.Builder<Filter> builder = ImmutableList.builder();
@@ -118,7 +117,7 @@
}
return builder.build();
}
-
+
protected final List<Filter> createFilters(List<Description> descriptions, int numShards) {
return createFilters(descriptions, numShards, createShardingFilterFactory());
}
@@ -199,10 +198,10 @@
protected static void assertShardingIsCompleteAndPartitioned(List<Filter> filters,
List<Description> descriptions) {
ListMultimap<Filter, Description> run = simulateTestRun(filters, descriptions);
- assertThat(run.values()).containsExactlyElementsIn(descriptions);
+ assertThatCollectionContainsExactlyElementsInList(run.values(), descriptions);
simulateSelfRandomizingTestRun(filters, descriptions);
- assertThat(run.values()).containsExactlyElementsIn(descriptions);
+ assertThatCollectionContainsExactlyElementsInList(run.values(), descriptions);
}
/**
@@ -223,4 +222,49 @@
simulateSelfRandomizingTestRun(filters, descriptions);
assertEquals(randomizedRun1, randomizedRun2);
}
+
+ /**
+ * Returns whether the Collection and the List contain exactly the same elements with the same
+ * frequency, ignoring the ordering.
+ */
+ private static void assertThatCollectionContainsExactlyElementsInList(
+ Collection<Description> actual, List<Description> expectedDescriptions) {
+ String basicAssertionMessage = "Elements of collection " + actual + " are not the same as the "
+ + "elements of expected list " + expectedDescriptions + ". ";
+ if (actual.size() != expectedDescriptions.size()) {
+ throw new AssertionError(basicAssertionMessage + "The number of elements is different.");
+ }
+
+ List<Description> actualDescriptions = new ArrayList<Description>(actual);
+ // Keeps track of already reviewed descriptions, so they won't be checked again when next
+ // encountered.
+ // Note: this algorithm has O(n^2) time complexity and will be slow for large inputs.
+ Set<Description> reviewedDescriptions = new HashSet<>();
+ for (int i = 0; i < actual.size(); i++) {
+ Description currDescription = actualDescriptions.get(i);
+ // If already reviewed, skip.
+ if (reviewedDescriptions.contains(currDescription)) {
+ continue;
+ }
+ int actualFreq = 0;
+ int expectedFreq = 0;
+ // Count the frequency of the current description in both lists.
+ for (int j = 0; j < actual.size(); j++) {
+ if (currDescription.equals(actualDescriptions.get(j))) {
+ actualFreq++;
+ }
+ if (currDescription.equals(expectedDescriptions.get(j))) {
+ expectedFreq++;
+ }
+ }
+ if (actualFreq < expectedFreq) {
+ throw new AssertionError(basicAssertionMessage + "There are " + (expectedFreq - actualFreq)
+ + " missing occurrences of " + currDescription + ".");
+ } else if (actualFreq > expectedFreq) {
+ throw new AssertionError(basicAssertionMessage + "There are " + (actualFreq - expectedFreq)
+ + " unexpected occurrences of " + currDescription + ".");
+ }
+ reviewedDescriptions.add(currDescription);
+ }
+ }
}
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/GoogleTestSecurityManager.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/GoogleTestSecurityManager.java
index 623b1e6..d8f6426 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/GoogleTestSecurityManager.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/GoogleTestSecurityManager.java
@@ -14,8 +14,6 @@
package com.google.testing.junit.runner.util;
-import com.google.common.annotations.VisibleForTesting;
-
import java.security.Permission;
/**
@@ -68,7 +66,7 @@
}
public boolean isEnabled() { return enabled; }
-
+
/**
* If {@code GoogleTestSecurityManager} is the current security manager,
* uninstall it.
@@ -78,7 +76,7 @@
if (securityManager instanceof GoogleTestSecurityManager) {
GoogleTestSecurityManager testSecurityManager = (GoogleTestSecurityManager) securityManager;
boolean wasEnabled = testSecurityManager.isEnabled();
-
+
try {
testSecurityManager.setEnabled(false);
System.setSecurityManager(null);
@@ -92,7 +90,8 @@
* The security manager can be disabled by the test runner (or any other
* class in the same package) to allow it to exit with a meaningful result
* code.
+ *
+ * VisibleForTesting
*/
- @VisibleForTesting
synchronized void setEnabled(boolean enabled) { this.enabled = enabled; }
}