// This file is part of OpenTSDB. // Copyright (C) 2013 The OpenTSDB Authors. // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 2.1 of the License, or (at your // option) any later version. This program is distributed in the hope that it // will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser // General Public License for more details. You should have received a copy // of the GNU Lesser General Public License along with this program. If not, // see <http://www.gnu.org/licenses/>. package net.opentsdb.core; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.HashMap; import net.opentsdb.utils.DateTime; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @PrepareForTest({ TSQuery.class, DateTime.class }) public final class TestTSQuery { @Test public void constructor() { assertNotNull(new TSQuery()); } @Test public void validate() { TSQuery q = this.getMetricForValidate(); q.validateAndSetQuery(); assertEquals(1356998400000L, q.startTime()); assertEquals(1356998460000L, q.endTime()); assertEquals("sys.cpu.0", q.getQueries().get(0).getMetric()); assertEquals("wildcard(*)", q.getQueries().get(0).getTags().get("host")); assertEquals("literal_or(lga)", q.getQueries().get(0).getTags().get("dc")); assertEquals(Aggregators.SUM, q.getQueries().get(0).aggregator()); assertEquals(Aggregators.AVG, q.getQueries().get(0).downsampler()); assertEquals(300000, q.getQueries().get(0).downsampleInterval()); assertNull(q.getTimezone()); assertEquals("UTC", q.getQueries().get(0).downsamplingSpecification() .getTimezone().getID()); assertFalse(q.getQueries().get(0).downsamplingSpecification().useCalendar()); } @Test public void validateWithTimezone() { TSQuery q = this.getMetricForValidate(); q.setUseCalendar(true); q.setTimezone("Pacific/Funafuti"); q.validateAndSetQuery(); assertEquals(1356998400000L, q.startTime()); assertEquals(1356998460000L, q.endTime()); assertEquals("sys.cpu.0", q.getQueries().get(0).getMetric()); assertEquals("wildcard(*)", q.getQueries().get(0).getTags().get("host")); assertEquals("literal_or(lga)", q.getQueries().get(0).getTags().get("dc")); assertEquals(Aggregators.SUM, q.getQueries().get(0).aggregator()); assertEquals(Aggregators.AVG, q.getQueries().get(0).downsampler()); assertEquals(300000, q.getQueries().get(0).downsampleInterval()); assertEquals("Pacific/Funafuti", q.getTimezone()); assertEquals("Pacific/Funafuti", q.getQueries().get(0).downsamplingSpecification() .getTimezone().getID()); assertTrue(q.getQueries().get(0).downsamplingSpecification().useCalendar()); } @Test public void validateVerifyNoDSOverrideWithCalendar() { TSQuery q = this.getMetricForValidate(); q.setUseCalendar(true); q.setTimezone("Pacific/Funafuti"); q.getQueries().get(0).setDownsample(null); q.validateAndSetQuery(); assertEquals(1356998400000L, q.startTime()); assertEquals(1356998460000L, q.endTime()); assertEquals("sys.cpu.0", q.getQueries().get(0).getMetric()); assertEquals("wildcard(*)", q.getQueries().get(0).getTags().get("host")); assertEquals("literal_or(lga)", q.getQueries().get(0).getTags().get("dc")); assertEquals(Aggregators.SUM, q.getQueries().get(0).aggregator()); assertNull(q.getQueries().get(0).downsampler()); assertEquals(0, q.getQueries().get(0).downsampleInterval()); assertEquals("Pacific/Funafuti", q.getTimezone()); assertEquals("UTC", q.getQueries().get(0).downsamplingSpecification() .getTimezone().getID()); assertFalse(q.getQueries().get(0).downsamplingSpecification().useCalendar()); } @Test (expected = IllegalArgumentException.class) public void validateNullStart() { TSQuery q = this.getMetricForValidate(); q.setStart(null); q.validateAndSetQuery(); } @Test (expected = IllegalArgumentException.class) public void validateEmptyStart() { TSQuery q = this.getMetricForValidate(); q.setStart(""); q.validateAndSetQuery(); } @Test (expected = IllegalArgumentException.class) public void validateInvalidStart() { TSQuery q = this.getMetricForValidate(); q.setStart("Not a timestamp at all"); q.validateAndSetQuery(); } @Test public void validateNullEnd() { PowerMockito.mockStatic(System.class); when(System.currentTimeMillis()).thenReturn(1357300800000L); TSQuery q = this.getMetricForValidate(); q.setEnd(null); q.validateAndSetQuery(); assertEquals(1357300800000L, q.endTime()); } @Test public void validateEmptyEnd() { PowerMockito.mockStatic(System.class); when(System.currentTimeMillis()).thenReturn(1357300800000L); TSQuery q = this.getMetricForValidate(); q.setEnd(""); q.validateAndSetQuery(); assertEquals(1357300800000L, q.endTime()); } @Test (expected = IllegalArgumentException.class) public void validateNullQueries() { TSQuery q = this.getMetricForValidate(); q.setQueries(null); q.validateAndSetQuery(); } @Test (expected = IllegalArgumentException.class) public void validateEmptyQueries() { TSQuery q = this.getMetricForValidate(); q.setQueries(new ArrayList<TSSubQuery>()); q.validateAndSetQuery(); } // NOTE: Each of the hash and equals tests should make sure that we the code // doesn't change after validation. @Test public void testHashCodeandEqualsStart() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setStart("1356998300"); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); sub2.setStart("1356998300"); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test (expected = IllegalArgumentException.class) public void testHashCodeandEqualsStartNull() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setStart(null); assertTrue(hash_a != sub1.hashCode()); sub1.validateAndSetQuery(); } @Test (expected = IllegalArgumentException.class) public void testHashCodeandEqualsStartInvalid() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setStart("1h-ago"); assertTrue(hash_a != sub1.hashCode()); sub1.validateAndSetQuery(); } @Test public void testHashCodeandEqualsEnd() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setEnd("1356998490"); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); sub2.setEnd("1356998490"); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test public void testHashCodeandEqualsEndNull() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setEnd(null); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); // this is ok since we assume "now" if end is missing sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); sub2.setEnd(null); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test (expected = IllegalArgumentException.class) public void testHashCodeandEqualsEndInvalid() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setEnd("1356998300"); assertTrue(hash_a != sub1.hashCode()); sub1.validateAndSetQuery(); } @Test public void testHashCodeandEqualsTimezone() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setTimezone("America/New_York"); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); sub2.setTimezone("America/New_York"); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test (expected = IllegalArgumentException.class) public void testHashCodeandEqualsTimezoneInvalid() throws Exception { // silly test isn't calling into the real method, mockit! PowerMockito.mockStatic(DateTime.class); PowerMockito.when(DateTime.parseDateTimeString(anyString(), anyString())) .thenThrow(new IllegalArgumentException("Invalid timezone")); TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setTimezone("Not a timezone"); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); sub2.setTimezone("Not a timezone"); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test public void testHashCodeandEqualsUseCalendar() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setUseCalendar(true); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); sub2.setUseCalendar(true); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test public void testHashCodeandEqualsOptions() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); HashMap<String, ArrayList<String>> options = new HashMap<String, ArrayList<String>>(2); ArrayList<String> params = new ArrayList<String>(1); params.add("1419x576"); options.put("wxh", params); params = new ArrayList<String>(1); params.add("latency"); options.put("label", params); sub1.setOptions(options); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); options = new HashMap<String, ArrayList<String>>(2); params = new ArrayList<String>(1); params.add("1419x576"); options.put("wxh", params); params = new ArrayList<String>(1); params.add("latency"); options.put("label", params); sub2.setOptions(options); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test public void testHashCodeandEqualsOptionsNewPut() { TSQuery sub1 = getMetricForValidate(); HashMap<String, ArrayList<String>> options = new HashMap<String, ArrayList<String>>(3); ArrayList<String> params = new ArrayList<String>(1); params.add("1419x576"); options.put("wxh", params); params = new ArrayList<String>(1); params.add("latency"); options.put("label", params); sub1.setOptions(options); final int hash_a = sub1.hashCode(); params = new ArrayList<String>(1); params.add("top"); options.put("key", params); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); options = new HashMap<String, ArrayList<String>>(2); params = new ArrayList<String>(1); params.add("1419x576"); options.put("wxh", params); params = new ArrayList<String>(1); params.add("latency"); options.put("label", params); params = new ArrayList<String>(1); params.add("top"); options.put("key", params); sub2.setOptions(options); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test public void testHashCodeandEqualsOptionsNewParam() { TSQuery sub1 = getMetricForValidate(); HashMap<String, ArrayList<String>> options = new HashMap<String, ArrayList<String>>(3); ArrayList<String> params = new ArrayList<String>(1); params.add("1419x576"); options.put("wxh", params); params = new ArrayList<String>(1); params.add("latency"); options.put("label", params); sub1.setOptions(options); final int hash_a = sub1.hashCode(); params = new ArrayList<String>(1); params.add("cycles"); options.put("label", params); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); options = new HashMap<String, ArrayList<String>>(2); params = new ArrayList<String>(1); params.add("1419x576"); options.put("wxh", params); params = new ArrayList<String>(1); params.add("cycles"); options.put("label", params); params = new ArrayList<String>(1);; sub2.setOptions(options); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test public void testHashCodeandEqualsOptionsExtraParam() { TSQuery sub1 = getMetricForValidate(); HashMap<String, ArrayList<String>> options = new HashMap<String, ArrayList<String>>(3); ArrayList<String> params = new ArrayList<String>(1); params.add("1419x576"); options.put("wxh", params); params = new ArrayList<String>(1); params.add("latency"); options.put("label", params); sub1.setOptions(options); final int hash_a = sub1.hashCode(); options.get("label").add("extra"); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); options = new HashMap<String, ArrayList<String>>(2); params = new ArrayList<String>(1); params.add("1419x576"); options.put("wxh", params); params = new ArrayList<String>(1); params.add("latency"); params.add("extra"); options.put("label", params); params = new ArrayList<String>(1);; sub2.setOptions(options); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test public void testHashCodeandEqualsPadding() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setPadding(true); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); sub2.setPadding(true); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test public void testHashCodeandEqualsNoAnnotations() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setNoAnnotations(true); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); sub2.setNoAnnotations(true); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test public void testHashCodeandEqualsWithGlobalAnnotations() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setGlobalAnnotations(true); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); sub2.setGlobalAnnotations(true); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test public void testHashCodeandEqualsShowTSUIDs() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setShowTSUIDs(true); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); sub2.setShowTSUIDs(true); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test public void testHashCodeandEqualsMSResolution() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setMsResolution(true); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); sub2.setMsResolution(true); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test public void testHashCodeandEqualsNewSubQuery() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.getQueries().add(TestTSSubQuery.getBaseQuery()); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); sub2.getQueries().add(TestTSSubQuery.getBaseQuery()); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test public void testHashCodeandEqualsChangeSubQuery() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.getQueries().get(0).setMetric("foo"); final int hash_b = sub1.hashCode(); assertTrue(hash_a != hash_b); sub1.validateAndSetQuery(); assertEquals(hash_b, sub1.hashCode()); TSQuery sub2 = getMetricForValidate(); sub2.getQueries().get(0).setMetric("foo"); assertEquals(hash_b, sub2.hashCode()); assertEquals(sub1, sub2); assertFalse(sub1 == sub2); } @Test (expected = IllegalArgumentException.class) public void testHashCodeandEqualsEmptySubQueries() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setQueries(new ArrayList<TSSubQuery>(0)); assertTrue(hash_a != sub1.hashCode()); sub1.validateAndSetQuery(); } @Test (expected = IllegalArgumentException.class) public void testHashCodeandEqualsNullSubQueries() { TSQuery sub1 = getMetricForValidate(); final int hash_a = sub1.hashCode(); sub1.setQueries(null); assertTrue(hash_a != sub1.hashCode()); sub1.validateAndSetQuery(); } @Test public void testEqualsNull() { TSQuery sub1 = getMetricForValidate(); assertFalse(sub1.equals(null)); } @Test public void testEqualsWrongType() { TSQuery sub1 = getMetricForValidate(); assertFalse(sub1.equals(new String("Foobar"))); } @Test public void testEqualsSame() { TSQuery sub1 = getMetricForValidate(); assertTrue(sub1.equals(sub1)); } /** * Sets up an object with good, common values for testing the validation * function with an query string query. Each test can "set" the * method it wants to fool with and call .validateAndSetQuery() * <b>Warning:</b> This method calls into {@link TestTSQuery} * @return A query object */ private TSQuery getMetricForValidate() { final TSQuery query = new TSQuery(); query.setStart("1356998400"); query.setEnd("1356998460"); final ArrayList<TSSubQuery> subs = new ArrayList<TSSubQuery>(1); subs.add(TestTSSubQuery.getMetricForValidate()); query.setQueries(subs); return query; } }