/**
* The MIT License
* Copyright (c) 2014 JMXTrans Team
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jmxtrans.writers.additional;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.jmxtrans.core.results.QueryResult;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.jmxtrans.core.results.MetricType.COUNTER;
import static org.jmxtrans.core.results.MetricType.GAUGE;
import static org.jmxtrans.core.results.MetricType.SUMMARY;
import static org.jmxtrans.core.results.MetricType.TIMER;
import static org.jmxtrans.core.results.MetricType.UNKNOWN;
import static org.assertj.core.api.Assertions.assertThat;
public class LibratoWriterTest {
private LibratoWriter libratoWriter;
private ByteArrayOutputStream out;
private QueryResult counterResult1;
private QueryResult counterResult2;
private QueryResult gaugeResult1;
private QueryResult gaugeResult2;
private QueryResult timerResult;
private QueryResult summaryResult;
private QueryResult unkownType;
private final ObjectMapper objectMapper = new ObjectMapper();
@BeforeClass
public void createLibratoWriter() {
libratoWriter = new LibratoWriter(new JsonFactory(), "myHost.test.net");
}
@BeforeMethod
public void createOutputStream() {
out = new ByteArrayOutputStream();
}
@BeforeClass
public void createResults() {
counterResult1 = new QueryResult("counter1", COUNTER, 1, 1000L);
counterResult2 = new QueryResult("counter2", COUNTER, 2L, 2000L);
gaugeResult1 = new QueryResult("gauge1", GAUGE, 3.3, 3000L);
gaugeResult2 = new QueryResult("gauge2", GAUGE, 4.4f, 4000L);
timerResult = new QueryResult("timer", TIMER, 4.4f, 4000L);
summaryResult = new QueryResult("summary", SUMMARY, 4.4f, 4000L);
unkownType = new QueryResult("unkownType", UNKNOWN, 5, 5000L);
}
@Test
public void canWriteSimpleResults() throws IOException {
libratoWriter.beforeBatch(out);
libratoWriter.write(out, counterResult1);
libratoWriter.write(out, counterResult2);
libratoWriter.write(out, gaugeResult1);
libratoWriter.write(out, gaugeResult2);
libratoWriter.afterBatch(out);
JsonNode tree = objectMapper.readTree(out.toByteArray());
JsonNode counters = tree.findPath("counters");
assertThat(counters.isArray()).isTrue();
assertThat(counters.size()).isEqualTo(2);
JsonNode counter1 = counters.get(0);
assertThat(counter1.get("name").textValue()).isEqualTo("counter1");
assertThat(counter1.get("source").textValue()).isEqualTo("myHost.test.net");
assertThat(counter1.get("measure_time").intValue()).isEqualTo(1);
assertThat(counter1.get("value").intValue()).isEqualTo(1);
JsonNode counter2 = counters.get(1);
assertThat(counter2.get("name").textValue()).isEqualTo("counter2");
assertThat(counter2.get("source").textValue()).isEqualTo("myHost.test.net");
assertThat(counter2.get("measure_time").intValue()).isEqualTo(2);
assertThat(counter2.get("value").longValue()).isEqualTo(2L);
JsonNode gauges = tree.findPath("gauges");
assertThat(gauges.isArray()).isTrue();
JsonNode gauge1 = gauges.get(0);
assertThat(gauge1.get("name").textValue()).isEqualTo("gauge1");
assertThat(gauge1.get("source").textValue()).isEqualTo("myHost.test.net");
assertThat(gauge1.get("measure_time").intValue()).isEqualTo(3);
assertThat(gauge1.get("value").doubleValue()).isEqualTo(3.3);
JsonNode gauge2 = gauges.get(1);
assertThat(gauge2.get("name").textValue()).isEqualTo("gauge2");
assertThat(gauge2.get("source").textValue()).isEqualTo("myHost.test.net");
assertThat(gauge2.get("measure_time").intValue()).isEqualTo(4);
assertThat(gauge2.get("value").floatValue()).isEqualTo(4.4f);
}
@Test
public void resultCountIsCorrect() throws IOException {
int counter = 0;
libratoWriter.beforeBatch(out);
counter += libratoWriter.write(out, counterResult1);
counter += libratoWriter.write(out, gaugeResult1);
counter += libratoWriter.afterBatch(out);
assertThat(counter).isEqualTo(2);
}
@Test
public void nonNumericValuesAreSentEmpty() throws IOException {
libratoWriter.beforeBatch(out);
libratoWriter.write(out, new QueryResult("nonNumeric", COUNTER, "stringValue", 1000));
libratoWriter.afterBatch(out);
JsonNode tree = objectMapper.readTree(out.toByteArray());
JsonNode counters = tree.findPath("counters");
assertThat(counters.isArray()).isTrue();
assertThat(counters.size()).isEqualTo(1);
JsonNode counter1 = counters.get(0);
assertThat(counter1.get("name").textValue()).isEqualTo("nonNumeric");
assertThat(counter1.get("value")).isNull();
}
@Test
public void atomicIntegerAreSentAsNumbers() throws IOException {
libratoWriter.beforeBatch(out);
libratoWriter.write(out, new QueryResult("atomicInteger", COUNTER, new AtomicInteger(1), 1000));
libratoWriter.afterBatch(out);
JsonNode tree = objectMapper.readTree(out.toByteArray());
JsonNode counters = tree.findPath("counters");
assertThat(counters.isArray()).isTrue();
assertThat(counters.size()).isEqualTo(1);
JsonNode counter1 = counters.get(0);
assertThat(counter1.get("name").textValue()).isEqualTo("atomicInteger");
assertThat(counter1.get("value").intValue()).isEqualTo(1);
}
@Test
public void atomicLongAreSentAsNumbers() throws IOException {
libratoWriter.beforeBatch(out);
libratoWriter.write(out, new QueryResult("atomicLong", COUNTER, new AtomicLong(2), 1000));
libratoWriter.afterBatch(out);
JsonNode tree = objectMapper.readTree(out.toByteArray());
JsonNode counters = tree.findPath("counters");
assertThat(counters.isArray()).isTrue();
assertThat(counters.size()).isEqualTo(1);
JsonNode counter1 = counters.get(0);
assertThat(counter1.get("name").textValue()).isEqualTo("atomicLong");
assertThat(counter1.get("value").longValue()).isEqualTo(2);
}
@Test
public void unknownTypeIsTreatedAsCounter() throws IOException {
libratoWriter.beforeBatch(out);
libratoWriter.write(out, unkownType);
libratoWriter.afterBatch(out);
JsonNode tree = objectMapper.readTree(out.toByteArray());
JsonNode counters = tree.findPath("counters");
assertThat(counters.size()).isEqualTo(1);
}
@Test
public void timerAndSummaryTypesAreTreatedAsCounters() throws IOException {
libratoWriter.beforeBatch(out);
libratoWriter.write(out, timerResult);
libratoWriter.write(out, summaryResult);
libratoWriter.afterBatch(out);
JsonNode tree = objectMapper.readTree(out.toByteArray());
JsonNode counters = tree.findPath("counters");
assertThat(counters.size()).isEqualTo(2);
}
@Test
public void factoryCanCreateLibratoWriter() {
Map<String, String> settings = new HashMap<>();
assertThat(new LibratoWriterFactory().create(settings)).isNotNull();
}
}