From 5280902847c007391e5c3385456c5a97ae2b9961 Mon Sep 17 00:00:00 2001 From: Rishi Baldawa Date: Wed, 4 Sep 2024 13:32:05 -0700 Subject: [PATCH 1/2] Fix testPatternPermutations within ByteMachingTest For each test within the class we add a list of "noMatches" objects that should never be pattern matches intentinoally or not. However we never check if we ever accidentally register these pattern when adding other patterns. We will fix this by tracking when these patterns get added (probably by error) and then later validate the checks Note, no impact to the correctness of the ByteMachine itself, just that the test scaffolding was broken and needed to be fixed. See https://github.com/aws/event-ruler/issues/181 for more context. --- .../amazon/event/ruler/ByteMachineTest.java | 66 +++++++++++++++---- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/src/test/software/amazon/event/ruler/ByteMachineTest.java b/src/test/software/amazon/event/ruler/ByteMachineTest.java index fad3e7a..3afcb60 100644 --- a/src/test/software/amazon/event/ruler/ByteMachineTest.java +++ b/src/test/software/amazon/event/ruler/ByteMachineTest.java @@ -3,6 +3,7 @@ import org.junit.Test; import software.amazon.event.ruler.input.ParseException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -886,7 +887,7 @@ public void testEqualsIgnoreCasePattern() { @Test public void testEqualsIgnoreCasePatternWithExactMatchAsPrefix() { - String[] noMatches = new String[] { "", "ja", "JA", "JAV", "javax" }; + String[] noMatches = new String[] { "", "j", "JA", "JAV", "javax" }; testPatternPermutations(noMatches, new PatternMatch(Patterns.equalsIgnoreCaseMatch("jAVa"), "java", "jAVa", "JavA", "JAVA"), @@ -1523,7 +1524,7 @@ public void testSuffixEqualsIgnoreCaseWithPrefixMatchLeadingCharacterSameLowerAn @Test public void testSuffixEqualsIgnoreCaseWithWildcardMatchBeingAddedLater() { - String[] noMatches = new String[] { "", "!", "!A", "a", "A", "b", "B" }; + String[] noMatches = new String[] { "", "!", "!A", "a", "A", "c", "B" }; testPatternPermutations(noMatches, new PatternMatch(Patterns.suffixEqualsIgnoreCaseMatch("b!"), "b!", "B!", "cdb!", "CdEB!"), @@ -1534,7 +1535,7 @@ public void testSuffixEqualsIgnoreCaseWithWildcardMatchBeingAddedLater() { @Test public void testSuffixEqualsIgnoreCaseWithExistingWildcardMatch() { - String[] noMatches = new String[] { "", "!", "!A", "a", "A", "b", "B" }; + String[] noMatches = new String[] { "", "!", "!A", "a", "A", "c", "B" }; testPatternPermutations(noMatches, new PatternMatch(Patterns.wildcardMatch("*b"), "!b", "b"), @@ -1724,7 +1725,7 @@ public void testWildcardSingleWildcardCharacterWithOtherPatterns() { @Test public void testWildcardLeadingWildcardCharacterNotUsedByExactMatch() { - String[] noMatches = new String[] { "", "hello", "hellox", "blahabc" }; + String[] noMatches = new String[] { "", "xello", "hellox", "blahabc" }; testPatternPermutations(noMatches, new PatternMatch(Patterns.wildcardMatch("*hello"), "hello", "xhello", "hehello"), @@ -1988,7 +1989,7 @@ public void testWildcardSecondLastCharWildcardOccursBeforeSameFinalCharacterOfEx @Test public void testWildcardSecondLastCharWildcardOccursBeforeDivergentFinalCharacterOfExactMatch() { - String[] noMatches = new String[] { "", "hel", "hexl", "helo", "helxx" }; + String[] noMatches = new String[] { "", "hel", "hexl", "xelo", "helxx" }; testPatternPermutations(noMatches, new PatternMatch(Patterns.wildcardMatch("hel*o"), "helo", "hello", "helxo", "helxxxo"), @@ -2686,18 +2687,23 @@ private void testPatternPermutations(String[] noMatches, PatternMatch ... patter System.out.println("USE ME TO REPRODUCE - ByteMachineTest.testPatternPermutations seeding with " + seed); Random r = new Random(seed); ByteMachine cut = new ByteMachine(); - Set matchValues = Stream.of(patternMatches) + // Tracks addition and removes across these patterns. + Match[] matchValues = Stream.of(patternMatches) .map(patternMatch -> patternMatch.matches) .flatMap(set -> set.stream()) - .collect(Collectors.toSet()); - matchValues.addAll(Arrays.asList(noMatches)); - Matches matches = new Matches(matchValues.stream() - .map(string -> new Match(string)) - .collect(Collectors.toList()) - .toArray(new Match[0])); + .distinct() + .map(string -> new Match(string)) + .collect(Collectors.toList()).toArray(new Match[0]); + // Tracks any unintentional matches for above patterns. + final Match[] noMatchValues = Stream.of(noMatches) + .map(string -> new Match(string)) + .collect(Collectors.toList()) + .toArray(new Match[0]); + Matches matches = new Matches(matchValues, noMatchValues); List permutations = generateAllPermutations(patternMatches); + for (PatternMatch[] additionPermutation : permutations) { // Magic number alert: For 5 or less patterns, it is reasonable to test all deletion permutations for each // addition permutation. But for 6 or more patterns, the runtime becomes ridiculous, so we will settle for @@ -2735,9 +2741,11 @@ private void testPatternPermutation(ByteMachine cut, PatternMatch[] additionPerm private static class Matches { private final Match[] matches; + private final Match[] noMatches; - public Matches(Match ... matches) { + public Matches(Match[] matches, Match[] noMatches) { this.matches = matches; + this.noMatches = noMatches; } public Match[] get() { @@ -2748,6 +2756,9 @@ public Patterns registerPattern(PatternMatch patternMatch) { for (Match match : matches) { match.registerPattern(patternMatch); } + for (Match match : noMatches) { // record these to trigger failure below + match.registerPattern(patternMatch); + } return patternMatch.pattern; } @@ -2755,14 +2766,25 @@ public Patterns deregisterPattern(PatternMatch patternMatch) { for (Match match : matches) { match.deregisterPattern(patternMatch); } + // ignoring noMatches here intentionally return patternMatch.pattern; } public void assertNoPatternsRegistered() { for (Match match : matches) { - assertEquals(0, match.getNumPatternsRegistered()); + assertEquals("Should be zero " + match, 0, match.getNumPatternsRegistered()); + } + for (Match match : noMatches) { + assertEquals("Should be zero " + match, 0, match.getNumPatternsRegistered()); } } + + @Override + public String toString() { + return "Matches{" + + "matches=" + Arrays.asList(matches) + + '}'; + } } private static class Match { @@ -2788,6 +2810,14 @@ public void deregisterPattern(PatternMatch patternMatch) { public int getNumPatternsRegistered() { return num; } + + @Override + public String toString() { + return "Match{" + + "value='" + value + '\'' + + ", num=" + num + + '}'; + } } private static class PatternMatch { @@ -2798,6 +2828,14 @@ public PatternMatch(Patterns pattern, String ... matches) { this.pattern = pattern; this.matches = new HashSet<>(Arrays.asList(matches)); } + + @Override + public String toString() { + return "PatternMatch{" + + "pattern=" + pattern + + ", matches=" + matches + + '}'; + } } } From b9c53aea7a2f6321aae2eca4dc7fc1719fda8a4c Mon Sep 17 00:00:00 2001 From: Rishi Baldawa Date: Wed, 4 Sep 2024 13:38:36 -0700 Subject: [PATCH 2/2] Remover unused import --- src/test/software/amazon/event/ruler/ByteMachineTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/software/amazon/event/ruler/ByteMachineTest.java b/src/test/software/amazon/event/ruler/ByteMachineTest.java index 3afcb60..41a28ad 100644 --- a/src/test/software/amazon/event/ruler/ByteMachineTest.java +++ b/src/test/software/amazon/event/ruler/ByteMachineTest.java @@ -3,7 +3,6 @@ import org.junit.Test; import software.amazon.event.ruler.input.ParseException; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet;