package ru.yandex.market.graphouse.search.tree; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import org.junit.Test; import ru.yandex.market.graphouse.retention.DefaultRetentionProvider; import ru.yandex.market.graphouse.search.MetricStatus; import ru.yandex.market.graphouse.utils.AppendableWrapper; import java.io.IOException; import java.nio.file.PathMatcher; import java.util.Arrays; import java.util.Collection; import java.util.Map; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; public class MetricTreeTest { private MetricTree tree = new MetricTree(InMemoryMetricDir::new, new DefaultRetentionProvider()); public static Pattern createPattern(final String globPattern) { String result = globPattern.replace("*", "[-_0-9a-zA-Z]*"); result = result.replace("?", "[-_0-9a-zA-Z]"); try { return Pattern.compile(result); } catch (PatternSyntaxException e) { return null; } } @Test public void testGlob() { Multimap<String, String> pattern2Candidates = generate(); for (Map.Entry<String, Collection<String>> pattern2CandidatesMap : pattern2Candidates.asMap().entrySet()) { String glob = pattern2CandidatesMap.getKey(); Pattern pattern = createPattern(glob); if (pattern == null) { System.out.println("Wrong pattern " + glob); continue; } for (String node : pattern2CandidatesMap.getValue()) { System.out.println(String.format("%40s\t%40s\t%s", glob, node, pattern.matcher(node).matches())); } } } @Test public void testGlobPath() { PathMatcher matcher = MetricTree.createPathMatcher("asdf["); assertNull(matcher); Multimap<String, String> pattern2Candidates = generate(); for (Map.Entry<String, Collection<String>> pattern2CandidatesMap : pattern2Candidates.asMap().entrySet()) { String glob = pattern2CandidatesMap.getKey(); matcher = MetricTree.createPathMatcher(glob); if (matcher == null) { System.out.println("Wrong pattern " + glob); continue; } for (String node : pattern2CandidatesMap.getValue()) { System.out.println(String.format("%40s\t%40s\t%s", glob, node, MetricTree.matches(matcher, node))); } } } private Multimap<String, String> generate() { Multimap<String, String> pattern2Candidates = ArrayListMultimap.create(); pattern2Candidates.putAll("msh0[1-6]d_market_yandex_net", Arrays.asList("msh01d_market_yandex_net", "msh03d_market_yandex_net")); pattern2Candidates.putAll("min.market-front*.e", Arrays.asList("min.market-front.e", "min.market-front-ugr.e")); pattern2Candidates.putAll("min.market-front{-ugr,-fol}.e", Arrays.asList("min.market-front-fol.e", "min.market-front-ugr.e")); pattern2Candidates.putAll("min.market-front{,-ugr,-fol}.e", Arrays.asList("min.market-front.e", "min.market-front-ugr.e")); return pattern2Candidates; } @Test public void testContainsExpression() throws Exception { assertTrue(MetricTree.containsExpressions("msh0[1-6]d_market_yandex_net")); } @Test public void testSearch() throws Exception { tree.add("five_sec.int_8742.x1"); tree.add("five_sec.int_8742.x1"); tree.add("five_sec.int_8743.x1"); tree.add("five_sec.int_8742.x2"); search("five_sec.int_874?.x1", "five_sec.int_8742.x1", "five_sec.int_8743.x1"); search("five_sec.int_8742.x*", "five_sec.int_8742.x1", "five_sec.int_8742.x2"); search("*", "five_sec."); search("five_sec.*", "five_sec.int_8742.", "five_sec.int_8743."); } @Test public void testStatusesWorkflow() throws Exception { assertEquals(MetricStatus.SIMPLE, tree.add("five_sec.int_8742.x1").getStatus()); assertEquals(MetricStatus.SIMPLE, tree.add("five_sec.int_8742.x1").getStatus()); // BAN -> APPROVED tree.add("five_sec.int_8743.x1"); assertEquals(MetricStatus.BAN, tree.modify("five_sec.int_8743.", MetricStatus.BAN).getStatus()); searchWithMessage("Dir is BANned, but we found it", "five_sec.*", "five_sec.int_8742."); searchWithMessage("Dir is BANned, but we found it's metric", "five_sec.int_8743.", ""); assertEquals("Dir is BANned, but we can add metric into it", null, tree.add("five_sec.int_8743.x0")); assertEquals("Dir is BANned, but we can add dir into it", null, tree.add("five_sec.int_8743.new.")); assertEquals(MetricStatus.APPROVED, tree.modify("five_sec.int_8743.", MetricStatus.APPROVED).getStatus()); search("five_sec.*", "five_sec.int_8742.", "five_sec.int_8743."); // HIDDEN search("five_sec.int_8742.*", "five_sec.int_8742.x1"); assertEquals(MetricStatus.HIDDEN, tree.modify("five_sec.int_8742.", MetricStatus.HIDDEN).getStatus()); searchWithMessage("Dir is HIDDEN, but we found it", "five_sec.*", "five_sec.int_8743."); searchWithMessage("Dir is HIDDEN, but we found it's metric", "five_sec.int_8742.*", ""); assertEquals(MetricStatus.SIMPLE, tree.add("five_sec.int_8742.x2").getStatus()); search("five_sec.int_8742.*", "five_sec.int_8742.x1", "five_sec.int_8742.x2"); assertEquals(MetricStatus.APPROVED, tree.modify("five_sec.int_8742.", MetricStatus.APPROVED).getStatus()); search("five_sec.*", "five_sec.int_8742.", "five_sec.int_8743."); // SIMPLE -> AUTO_HIDDEN -> SIMPLE search("five_sec.int_8742.*", "five_sec.int_8742.x1", "five_sec.int_8742.x2"); assertEquals(MetricStatus.HIDDEN, tree.modify("five_sec.int_8742.x2", MetricStatus.HIDDEN).getStatus()); searchWithMessage("Metric is HIDDEN, but we found it", "five_sec.int_8742.*", "five_sec.int_8742.x1"); assertEquals(MetricStatus.HIDDEN, tree.modify("five_sec.int_8742.x1", MetricStatus.HIDDEN).getStatus()); searchWithMessage("Dir is AUTO_HIDDEN, but we found it", "five_sec.*", "five_sec.int_8743.", "five_sec.int_8742."); //Cause "five_sec.int_8742." is Approved assertEquals(MetricStatus.SIMPLE, tree.add("five_sec.int_8742.x3").getStatus()); searchWithMessage("We added new metric in AUTO_HIDDEN dir, but dir is still AUTO_HIDDEN", "five_sec.*", "five_sec.int_8742.", "five_sec.int_8743."); search("five_sec.int_8742.*", "five_sec.int_8742.x3"); assertEquals(MetricStatus.SIMPLE, tree.add("five_sec.int_8742.x2.y1").getStatus()); searchWithMessage("We added new metric, but dir is still AUTO_HIDDEN", "five_sec.*", "five_sec.int_8742.", "five_sec.int_8743."); search("five_sec.int_8742.*", "five_sec.int_8742.x2.", "five_sec.int_8742.x3"); } private void search(String pattern, String... expected) throws IOException { searchWithMessage("", pattern, expected); } private void searchWithMessage(String message, String pattern, String... expected) throws IOException { Arrays.sort(expected); AppendableWrapper result = new AppendableWrapper(); tree.search(pattern, result); String[] actual = result.toString().split("\\n"); Arrays.sort(actual); assertArrayEquals(message + "\nFound " + result, expected, actual); } }