/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.loganalysis.util; import com.android.loganalysis.util.RegexTrie.CompPattern; import junit.framework.TestCase; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.regex.Pattern; /** * Set of unit tests to verify the behavior of the RegexTrie */ public class RegexTrieTest extends TestCase { private RegexTrie mTrie = null; private static final Integer STORED_VAL = 42; private static final List NULL_LIST = Arrays.asList((String)null); @Override public void setUp() throws Exception { mTrie = new RegexTrie(); } public void testStringPattern() { mTrie.put(STORED_VAL, "[p]art1", "[p]art2", "[p]art3"); Integer retrieved = mTrie.retrieve("part1", "part2", "part3"); assertEquals(STORED_VAL, retrieved); } public void testAlternation_single() { mTrie.put(STORED_VAL, "alpha|beta"); Integer retrieved; retrieved = mTrie.retrieve("alpha"); assertEquals(STORED_VAL, retrieved); retrieved = mTrie.retrieve("beta"); assertEquals(STORED_VAL, retrieved); retrieved = mTrie.retrieve("alpha|beta"); assertNull(retrieved); retrieved = mTrie.retrieve("gamma"); assertNull(retrieved); retrieved = mTrie.retrieve("alph"); assertNull(retrieved); } public void testAlternation_multiple() { mTrie.put(STORED_VAL, "a|alpha", "b|beta"); Integer retrieved; retrieved = mTrie.retrieve("a", "b"); assertEquals(STORED_VAL, retrieved); retrieved = mTrie.retrieve("a", "beta"); assertEquals(STORED_VAL, retrieved); retrieved = mTrie.retrieve("alpha", "b"); assertEquals(STORED_VAL, retrieved); retrieved = mTrie.retrieve("alpha", "beta"); assertEquals(STORED_VAL, retrieved); retrieved = mTrie.retrieve("alpha"); assertNull(retrieved); retrieved = mTrie.retrieve("beta"); assertNull(retrieved); retrieved = mTrie.retrieve("alpha", "bet"); assertNull(retrieved); } public void testGroups_fullMatch() { mTrie.put(STORED_VAL, "a|(alpha)", "b|(beta)"); Integer retrieved; List> groups = new ArrayList>(); retrieved = mTrie.retrieve(groups, "a", "b"); assertEquals(STORED_VAL, retrieved); assertEquals(2, groups.size()); assertEquals(NULL_LIST, groups.get(0)); assertEquals(NULL_LIST, groups.get(1)); retrieved = mTrie.retrieve(groups, "a", "beta"); assertEquals(STORED_VAL, retrieved); assertEquals(2, groups.size()); assertEquals(NULL_LIST, groups.get(0)); assertEquals(Arrays.asList("beta"), groups.get(1)); retrieved = mTrie.retrieve(groups, "alpha", "b"); assertEquals(STORED_VAL, retrieved); assertEquals(2, groups.size()); assertEquals(Arrays.asList("alpha"), groups.get(0)); assertEquals(NULL_LIST, groups.get(1)); retrieved = mTrie.retrieve(groups, "alpha", "beta"); assertEquals(STORED_VAL, retrieved); assertEquals(2, groups.size()); assertEquals(Arrays.asList("alpha"), groups.get(0)); assertEquals(Arrays.asList("beta"), groups.get(1)); } public void testGroups_partialMatch() { mTrie.put(STORED_VAL, "a|(alpha)", "b|(beta)"); Integer retrieved; List> groups = new ArrayList>(); retrieved = mTrie.retrieve(groups, "alpha"); assertNull(retrieved); assertEquals(1, groups.size()); assertEquals(Arrays.asList("alpha"), groups.get(0)); retrieved = mTrie.retrieve(groups, "beta"); assertNull(retrieved); assertEquals(0, groups.size()); retrieved = mTrie.retrieve(groups, "alpha", "bet"); assertNull(retrieved); assertEquals(1, groups.size()); assertEquals(Arrays.asList("alpha"), groups.get(0)); retrieved = mTrie.retrieve(groups, "alpha", "betar"); assertNull(retrieved); assertEquals(1, groups.size()); assertEquals(Arrays.asList("alpha"), groups.get(0)); retrieved = mTrie.retrieve(groups, "alpha", "beta", "gamma"); assertNull(retrieved); assertEquals(2, groups.size()); assertEquals(Arrays.asList("alpha"), groups.get(0)); assertEquals(Arrays.asList("beta"), groups.get(1)); } /** * Make sure that the wildcard functionality works */ public void testWildcard() { mTrie.put(STORED_VAL, "a", null); Integer retrieved; List> groups = new ArrayList>(); retrieved = mTrie.retrieve(groups, "a", "b", "c"); assertEquals(STORED_VAL, retrieved); assertEquals(3, groups.size()); assertTrue(groups.get(0).isEmpty()); assertEquals(Arrays.asList("b"), groups.get(1)); assertEquals(Arrays.asList("c"), groups.get(2)); retrieved = mTrie.retrieve(groups, "a"); assertNull(retrieved); assertEquals(1, groups.size()); assertTrue(groups.get(0).isEmpty()); } /** * Make sure that if a wildcard and a more specific match could both match, that the more * specific match takes precedence */ public void testWildcard_precedence() { // Do one before and one after the wildcard to check for ordering effects mTrie.put(STORED_VAL + 1, "a", "(b)"); mTrie.put(STORED_VAL, "a", null); mTrie.put(STORED_VAL + 2, "a", "(c)"); Integer retrieved; List> groups = new ArrayList>(); retrieved = mTrie.retrieve(groups, "a", "d"); assertEquals(STORED_VAL, retrieved); assertEquals(2, groups.size()); assertTrue(groups.get(0).isEmpty()); assertEquals(Arrays.asList("d"), groups.get(1)); retrieved = mTrie.retrieve(groups, "a", "b"); assertEquals((Integer)(STORED_VAL + 1), retrieved); assertEquals(2, groups.size()); assertTrue(groups.get(0).isEmpty()); assertEquals(Arrays.asList("b"), groups.get(1)); retrieved = mTrie.retrieve(groups, "a", "c"); assertEquals((Integer)(STORED_VAL + 2), retrieved); assertEquals(2, groups.size()); assertTrue(groups.get(0).isEmpty()); assertEquals(Arrays.asList("c"), groups.get(1)); } /** * Verify a bugfix: make sure that no NPE results from calling #retrieve with a wildcard but * without a place to retrieve captures. */ public void testWildcard_noCapture() throws NullPointerException { mTrie.put(STORED_VAL, "a", null); String[] key = new String[] {"a", "b", "c"}; mTrie.retrieve(key); mTrie.retrieve(null, key); // test passes if no exceptions were thrown } public void testMultiChild() { mTrie.put(STORED_VAL + 1, "a", "b"); mTrie.put(STORED_VAL + 2, "a", "c"); Object retrieved; retrieved = mTrie.retrieve("a", "b"); assertEquals(STORED_VAL + 1, retrieved); retrieved = mTrie.retrieve("a", "c"); assertEquals(STORED_VAL + 2, retrieved); } /** * Make sure that {@link CompPattern#equals} works as expected. Shake a proverbial fist at Java */ public void testCompPattern_equality() { String regex = "regex"; Pattern p1 = Pattern.compile(regex); Pattern p2 = Pattern.compile(regex); Pattern pOther = Pattern.compile("other"); CompPattern cp1 = new CompPattern(p1); CompPattern cp2 = new CompPattern(p2); CompPattern cpOther = new CompPattern(pOther); // This is the problem with Pattern as implemented assertFalse(p1.equals(p2)); assertFalse(p2.equals(p1)); // Make sure that wrapped patterns with the same regex are considered equivalent assertTrue(cp2.equals(p1)); assertTrue(cp2.equals(p2)); assertTrue(cp2.equals(cp1)); // And make sure that wrapped patterns with different regexen are still considered different assertFalse(cp2.equals(pOther)); assertFalse(cp2.equals(cpOther)); } public void testCompPattern_hashmap() { HashMap map = new HashMap(); String regex = "regex"; Pattern p1 = Pattern.compile(regex); Pattern p2 = Pattern.compile(regex); Pattern pOther = Pattern.compile("other"); CompPattern cp1 = new CompPattern(p1); CompPattern cp2 = new CompPattern(p2); CompPattern cpOther = new CompPattern(pOther); map.put(cp1, STORED_VAL); assertTrue(map.containsKey(cp1)); assertTrue(map.containsKey(cp2)); assertFalse(map.containsKey(cpOther)); map.put(cpOther, STORED_VAL); assertEquals(map.size(), 2); assertTrue(map.containsKey(cp1)); assertTrue(map.containsKey(cp2)); assertTrue(map.containsKey(cpOther)); } }