@Test public void getUidNameMetric() throws Exception { setGetUidName(); assertEquals( "sys.cpu.0", tsdb.getUidName(UniqueIdType.METRIC, new byte[] {0, 0, 1}).joinUninterruptibly()); }
@Test(expected = IllegalArgumentException.class) public void addPointMSTooLarge() throws Exception { // It's an artificial limit and more thought needs to be put into it setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 10000000000000L, 42, tags).joinUninterruptibly(); }
@Test(expected = IllegalArgumentException.class) public void addPointMSNegative() throws Exception { // Fri, 13 Dec 1901 20:45:52 GMT // may support in the future, but 1.0 didn't setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", -2147483648000L, 42, tags).joinUninterruptibly(); }
@SuppressWarnings("unchecked") @Test(expected = NoSuchUniqueName.class) public void addPointNoAutoMetric() throws Exception { setupAddPointStorage(); when(IncomingDataPoints.rowKeyTemplate((TSDB) any(), anyString(), (Map<String, String>) any())) .thenThrow(new NoSuchUniqueName("sys.cpu.user", "metric")); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 1356998400, 42, tags).joinUninterruptibly(); }
@Test public void addPointBothSameTimeSecondAndMs() throws Exception { // this can happen if a second and an ms data point are stored for the same // timestamp. setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 1356998400L, 42, tags).joinUninterruptibly(); tsdb.addPoint("sys.cpu.user", 1356998400000L, 42, tags).joinUninterruptibly(); final byte[] row = new byte[] {0, 0, 1, 0x50, (byte) 0xE2, 0x27, 0, 0, 0, 1, 0, 0, 1}; byte[] value = storage.getColumn(row, new byte[] {0, 0}); assertEquals(2, storage.numColumns(row)); assertNotNull(value); assertEquals(42, value[0]); value = storage.getColumn(row, new byte[] {(byte) 0xF0, 0, 0, 0}); assertNotNull(value); // should have 7 digits of precision assertEquals(42, value[0]); }
@Test(expected = RuntimeException.class) public void initializePluginsPathBad() throws Exception { Field properties = config.getClass().getDeclaredField("properties"); properties.setAccessible(true); @SuppressWarnings("unchecked") HashMap<String, String> props = (HashMap<String, String>) properties.get(config); props.put("tsd.core.plugin_path", "./doesnotexist"); properties.setAccessible(false); tsdb.initializePlugins(true); }
@Test public void addPointBothSameTimeIntAndFloatMs() throws Exception { // this is an odd situation that can occur if the user puts an int and then // a float (or vice-versa) with the same timestamp. What happens in the // aggregators when this occurs? setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 1356998400500L, 42, tags).joinUninterruptibly(); tsdb.addPoint("sys.cpu.user", 1356998400500L, 42.5F, tags).joinUninterruptibly(); final byte[] row = new byte[] {0, 0, 1, 0x50, (byte) 0xE2, 0x27, 0, 0, 0, 1, 0, 0, 1}; byte[] value = storage.getColumn(row, new byte[] {(byte) 0xF0, 0, 0x7D, 0}); assertEquals(2, storage.numColumns(row)); assertNotNull(value); assertEquals(42, value[0]); value = storage.getColumn(row, new byte[] {(byte) 0xF0, 0, 0x7D, 11}); assertNotNull(value); // should have 7 digits of precision assertEquals(42.5F, Float.intBitsToFloat(Bytes.getInt(value)), 0.0000001); }
@Test(expected = RuntimeException.class) public void initializePluginsSearchNotFound() throws Exception { Field properties = config.getClass().getDeclaredField("properties"); properties.setAccessible(true); @SuppressWarnings("unchecked") HashMap<String, String> props = (HashMap<String, String>) properties.get(config); props.put("tsd.search.enable", "true"); props.put("tsd.search.plugin", "net.opentsdb.search.DoesNotExist"); properties.setAccessible(false); tsdb.initializePlugins(true); }
@Test public void addPointLong8BytesNegative() throws Exception { setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 1356998400, -4294967296L, tags).joinUninterruptibly(); final byte[] row = new byte[] {0, 0, 1, 0x50, (byte) 0xE2, 0x27, 0, 0, 0, 1, 0, 0, 1}; final byte[] value = storage.getColumn(row, new byte[] {0, 7}); assertNotNull(value); assertEquals(-4294967296L, Bytes.getLong(value)); }
@Test public void addPointLongEndOfRow() throws Exception { setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 1357001999, 42, tags).joinUninterruptibly(); final byte[] row = new byte[] {0, 0, 1, 0x50, (byte) 0xE2, 0x27, 0, 0, 0, 1, 0, 0, 1}; final byte[] value = storage.getColumn(row, new byte[] {(byte) 0xE0, (byte) 0xF0}); assertNotNull(value); assertEquals(42, value[0]); }
@Test public void addPointFloatPrecision() throws Exception { setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 1356998400, 42.5123459999F, tags).joinUninterruptibly(); final byte[] row = new byte[] {0, 0, 1, 0x50, (byte) 0xE2, 0x27, 0, 0, 0, 1, 0, 0, 1}; final byte[] value = storage.getColumn(row, new byte[] {0, 11}); assertNotNull(value); // should have 7 digits of precision assertEquals(42.512345F, Float.intBitsToFloat(Bytes.getInt(value)), 0.0000001); }
@Test public void addPointSecondOne() throws Exception { // hey, it's valid *shrug* Thu, 01 Jan 1970 00:00:01 GMT setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 1, 42, tags).joinUninterruptibly(); final byte[] row = new byte[] {0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1}; final byte[] value = storage.getColumn(row, new byte[] {0, 16}); assertNotNull(value); assertEquals(42, value[0]); }
@Test public void addPointMS2106() throws Exception { // Sun, 07 Feb 2106 06:28:15.000 GMT setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 4294967295000L, 42, tags).joinUninterruptibly(); final byte[] row = new byte[] {0, 0, 1, (byte) 0xFF, (byte) 0xFF, (byte) 0xF9, 0x60, 0, 0, 1, 0, 0, 1}; final byte[] value = storage.getColumn(row, new byte[] {(byte) 0xF6, (byte) 0x77, 0x46, 0}); assertNotNull(value); assertEquals(42, value[0]); }
@Test public void initializePluginsSearch() throws Exception { Field properties = config.getClass().getDeclaredField("properties"); properties.setAccessible(true); @SuppressWarnings("unchecked") HashMap<String, String> props = (HashMap<String, String>) properties.get(config); props.put("tsd.core.plugin_path", "./"); props.put("tsd.search.enable", "true"); props.put("tsd.search.plugin", "net.opentsdb.search.DummySearchPlugin"); props.put("tsd.search.DummySearchPlugin.hosts", "localhost"); props.put("tsd.search.DummySearchPlugin.port", "42"); properties.setAccessible(false); tsdb.initializePlugins(true); }
@Test public void addPointMS2286() throws Exception { // It's an artificial limit and more thought needs to be put into it setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 9999999999999L, 42, tags).joinUninterruptibly(); final byte[] row = new byte[] {0, 0, 1, (byte) 0x54, (byte) 0x0B, (byte) 0xD9, 0x10, 0, 0, 1, 0, 0, 1}; final byte[] value = storage.getColumn(row, new byte[] {(byte) 0xFA, (byte) 0xAE, 0x5F, (byte) 0xC0}); assertNotNull(value); assertEquals(42, value[0]); }
/** * Finds all the {@link Span}s that match this query. This is what actually scans the HBase table * and loads the data into {@link Span}s. * * @return A map from HBase row key to the {@link Span} for that row key. Since a {@link Span} * actually contains multiple HBase rows, the row key stored in the map has its timestamp * zero'ed out. * @throws HBaseException if there was a problem communicating with HBase to perform the search. * @throws IllegalArgumentException if bad data was retreived from HBase. */ private TreeMap<byte[], Span> findSpans() throws HBaseException { final short metric_width = tsdb.metrics.width(); final TreeMap<byte[], Span> spans = // The key is a row key from HBase. new TreeMap<byte[], Span>(new SpanCmp(metric_width)); int nrows = 0; int hbase_time = 0; // milliseconds. long starttime = System.nanoTime(); final Scanner scanner = getScanner(); try { ArrayList<ArrayList<KeyValue>> rows; while ((rows = scanner.nextRows().joinUninterruptibly()) != null) { hbase_time += (System.nanoTime() - starttime) / 1000000; for (final ArrayList<KeyValue> row : rows) { final byte[] key = row.get(0).key(); if (Bytes.memcmp(metric, key, 0, metric_width) != 0) { throw new IllegalDataException( "HBase returned a row that doesn't match" + " our scanner (" + scanner + ")! " + row + " does not start" + " with " + Arrays.toString(metric)); } Span datapoints = spans.get(key); if (datapoints == null) { datapoints = new Span(tsdb); spans.put(key, datapoints); } datapoints.addRow(tsdb.compact(row)); nrows++; starttime = System.nanoTime(); } } } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException("Should never be here", e); } finally { hbase_time += (System.nanoTime() - starttime) / 1000000; scanlatency.add(hbase_time); } LOG.info(this + " matched " + nrows + " rows in " + spans.size() + " spans"); if (nrows == 0) { return null; } return spans; }
@Test public void addPointLongManyMs() throws Exception { setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); long timestamp = 1356998400500L; for (int i = 1; i <= 50; i++) { tsdb.addPoint("sys.cpu.user", timestamp++, i, tags).joinUninterruptibly(); } final byte[] row = new byte[] {0, 0, 1, 0x50, (byte) 0xE2, 0x27, 0, 0, 0, 1, 0, 0, 1}; final byte[] value = storage.getColumn(row, new byte[] {(byte) 0xF0, 0, 0x7D, 0}); assertNotNull(value); assertEquals(1, value[0]); assertEquals(50, storage.numColumns(row)); }
@Before public void before() throws Exception { PowerMockito.whenNew(HBaseClient.class) .withArguments(anyString(), anyString()) .thenReturn(client); config = new Config(false); tsdb = new TSDB(config); Field met = tsdb.getClass().getDeclaredField("metrics"); met.setAccessible(true); met.set(tsdb, metrics); Field tagk = tsdb.getClass().getDeclaredField("tag_names"); tagk.setAccessible(true); tagk.set(tsdb, tag_names); Field tagv = tsdb.getClass().getDeclaredField("tag_values"); tagv.setAccessible(true); tagv.set(tsdb, tag_values); Field cq = tsdb.getClass().getDeclaredField("compactionq"); cq.setAccessible(true); cq.set(tsdb, compactionq); }
@Test public void addPointMS1970() throws Exception { // Since it's just over Integer.MAX_VALUE, OpenTSDB will treat this as // a millisecond timestamp since it doesn't fit in 4 bytes. // Base time is 4294800 which is Thu, 19 Feb 1970 17:00:00 GMT // offset = F0A36000 or 167296 ms setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 4294967296L, 42, tags).joinUninterruptibly(); final byte[] row = new byte[] {0, 0, 1, 0, (byte) 0x41, (byte) 0x88, (byte) 0x90, 0, 0, 1, 0, 0, 1}; final byte[] value = storage.getColumn(row, new byte[] {(byte) 0xF0, (byte) 0xA3, 0x60, 0}); assertNotNull(value); assertEquals(42, value[0]); }
@Test public void uidTable() { assertNotNull(tsdb.uidTable()); assertArrayEquals("tsdb-uid".getBytes(), tsdb.uidTable()); }
@Test(expected = IllegalArgumentException.class) public void getUIDEmptyName() { setupAssignUid(); tsdb.getUID(UniqueIdType.TAGV, ""); }
@Test public void assignUidMetric() { setupAssignUid(); assertArrayEquals(new byte[] {0, 0, 2}, tsdb.assignUid("metric", "sys.cpu.1")); }
@Test(expected = IllegalArgumentException.class) public void assignUidMetricExists() { setupAssignUid(); tsdb.assignUid("metric", "sys.cpu.0"); }
@Test public void assignUidTagk() { setupAssignUid(); assertArrayEquals(new byte[] {0, 0, 2}, tsdb.assignUid("tagk", "datacenter")); }
@Test public void assignUidTagv() { setupAssignUid(); assertArrayEquals(new byte[] {0, 0, 2}, tsdb.assignUid("tagv", "myserver")); }
@Test(expected = IllegalArgumentException.class) public void assignUidTagvExists() { setupAssignUid(); tsdb.assignUid("tagv", "localhost"); }
@Test(expected = IllegalArgumentException.class) public void assignUidBadType() { setupAssignUid(); tsdb.assignUid("nothere", "localhost"); }
@Test(expected = NullPointerException.class) public void assignUidNullType() { setupAssignUid(); tsdb.assignUid(null, "localhost"); }
@Test(expected = IllegalArgumentException.class) public void assignUidNullName() { setupAssignUid(); tsdb.assignUid("metric", null); }
@Test(expected = IllegalArgumentException.class) public void assignUidInvalidCharacter() { setupAssignUid(); tsdb.assignUid("metric", "Not!A:Valid@Name"); }