[COLLECTIONS-802] Fix remove failed by removing set null to currentKe…#300
Conversation
…y and currentValue.
Codecov Report
@@ Coverage Diff @@
## master #300 +/- ##
============================================
+ Coverage 85.82% 85.88% +0.05%
- Complexity 4674 4676 +2
============================================
Files 292 292
Lines 13471 13469 -2
Branches 1955 1955
============================================
+ Hits 11562 11568 +6
+ Misses 1330 1324 -6
+ Partials 579 577 -2
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Hi,
I did as Ben Manes suggested in the JIRA, downloading the ApacheMapTest.java (JIRA attachment), then with the diff below applied to pom.xml and also some changes to the code (older JVM version, no var statement), found that this PR breaks other tests in ApacheMapTest. We will have to verify if those are not indicators of regressions after this change (probably we will have to update the code in other places…)
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava-testlib</artifactId>
+ <version>31.1-jre</version>
+ <scope>test</scope>
+ </dependency>Bruno
| assertFalse(iter.hasNext()); | ||
| iter.remove(); | ||
| assertTrue("Expect empty but have entry: " + map, map.isEmpty()); | ||
| } |
There was a problem hiding this comment.
Fix looks OK, and the test is failing on master, passing on this branch. We could also modify the test to be more similar to the one reported in the issue.
diff --git a/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java b/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
index 509ac514..c6625909 100644
--- a/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
+++ b/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
@@ -327,7 +327,8 @@ public class ReferenceMapTest<K, V> extends AbstractIterableMapTest<K, V> {
map.put(1, 2);
Iterator<Map.Entry<Integer, Integer>> iter = map.entrySet().iterator();
assertTrue(iter.hasNext());
- iter.next();
+ assertTrue(iter.hasNext());
+ assertEquals(Integer.valueOf(1), iter.next().getKey());
// below line should not affect remove
assertFalse(iter.hasNext());
iter.remove();But not really important, the last assertTrue is where the test fails on master.
|
Ah, I think I may have spoken too fast. I executed the And then against this branch: So looks like this PR is actually reducing the failures 🎉 |
kinow
left a comment
There was a problem hiding this comment.
Approving as the CI here is green, and the other tests in ApacheMapTest using Guava testlib appear to have improved. Sorry the noise, I thought it was supposed to have no more errors in that test 🙇
Thanks @samabcde ! Will leave it open so others can review it too.
|
oops. I must have forgotten, not realized, or master has new failures. I very much like Guava’s collection tests as reusable and catch these minor mistakes. I’d recommend using it elsewhere as another sanity check over your own great testing. |
I hadn't heard about that before, but looks super useful. But from the amount of errors, that would probably be an epic task, maybe even worth of GSoC, I think. Thanks @ben-manes ! |
|
Checking and I accidentally attached the wrong version of The flag import java.util.Map;
import java.util.function.Supplier;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.collections4.map.LRUMap;
import org.apache.commons.collections4.map.LinkedMap;
import org.apache.commons.collections4.map.ReferenceMap;
import com.google.common.collect.testing.MapTestSuiteBuilder;
import com.google.common.collect.testing.TestStringMapGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
public final class ApacheMapTest extends TestCase {
public static Test suite() {
var test = new TestSuite();
test.addTest(suite("HashedMap", HashedMap::new));
test.addTest(suite("LinkedMap", LinkedMap::new));
test.addTest(suite("LRUMap", LRUMap::new));
test.addTest(suite("ReferenceMap", ReferenceMap::new));
return test;
}
public static Test suite(String name, Supplier<Map<String, String>> factory) {
return MapTestSuiteBuilder
.using(new TestStringMapGenerator() {
@Override protected Map<String, String> create(Map.Entry<String, String>[] entries) {
var map = factory.get();
for (var entry : entries) {
map.put(entry.getKey(), entry.getValue());
}
return map;
}
})
.named(name)
.withFeatures(
CollectionSize.ANY,
MapFeature.GENERAL_PURPOSE,
MapFeature.ALLOWS_ANY_NULL_QUERIES,
CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
.createTestSuite();
}
} |
|
Thanks @ben-manes, much easier now to run the tests and compare the results with your updated test. For [ERROR] Failures:
[ERROR] CollectionIteratorTester.testIterator_unknownOrderRemoveSupported:111->runIteratorTest:133 failed with stimuli [hasNext, hasNext, next, hasNext, remove]
[ERROR] CollectionIteratorTester.testIterator_unknownOrderRemoveSupported:111->runIteratorTest:133 failed with stimuli [hasNext, hasNext, next, hasNext, remove]
[ERROR] CollectionIteratorTester.testIterator_unknownOrderRemoveSupported:111->runIteratorTest:133 failed with stimuli [hasNext, hasNext, next, hasNext, remove]
[ERROR] CollectionIteratorTester.testIterator_unknownOrderRemoveSupported:111->runIteratorTest:133 failed with stimuli [next, next, next, hasNext, remove]
[ERROR] CollectionIteratorTester.testIterator_unknownOrderRemoveSupported:111->runIteratorTest:133 failed with stimuli [next, next, next, hasNext, remove]
[ERROR] CollectionIteratorTester.testIterator_unknownOrderRemoveSupported:111->runIteratorTest:133 failed with stimuli [next, next, next, hasNext, remove]
[INFO]
[ERROR] Tests run: 25518, Failures: 6, Errors: 0, Skipped: 4
[INFO] Then for this branch: [INFO] Results:
[INFO]
[WARNING] Tests run: 25520, Failures: 0, Errors: 0, Skipped: 4So no regressions in our CI, nor in the |
|
Also created a follow-up issue, https://issues.apache.org/jira/browse/COLLECTIONS-811, to consider adding Guava's testlib or similar solution to our tests/CI. |
| index = i; | ||
| if (e == null) { | ||
| currentKey = null; | ||
| currentValue = null; |
There was a problem hiding this comment.
Fix is here ☝️ , the rest is renaming variables.


…y and currentValue.
hasNextand return false, which set null tocurrentKey. Henceremovemethod callingparent.remove(currentKey);will not remove the current entry.