/* * ApplicationInsights-Java * Copyright (c) Microsoft Corporation * All rights reserved. * * MIT License * 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 com.microsoft.applicationinsights; import java.net.URL; import java.util.List; import java.util.Map; import java.util.HashMap; import java.util.Date; import java.util.LinkedList; import java.util.concurrent.TimeUnit; import com.microsoft.applicationinsights.channel.TelemetryChannel; import com.microsoft.applicationinsights.extensibility.ContextInitializer; import com.microsoft.applicationinsights.extensibility.TelemetryInitializer; import com.microsoft.applicationinsights.channel.TelemetrySampler; import com.microsoft.applicationinsights.internal.processor.RequestTelemetryFilter; import com.microsoft.applicationinsights.telemetry.*; import org.junit.Before; import org.junit.Test; import org.junit.Assert; import org.junit.Ignore; import org.mockito.Matchers; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.times; // TODO: Some of the tests should be expanded. currently we just doing sanity checks by verified that // all events are sent, without validating their values that added by the client. /** * Tests the interface of the telemetry client. */ public final class TelemetryClientTests { // region Members private TelemetryConfiguration configuration; private List<Telemetry> eventsSent; private TelemetryClient client; private TelemetryChannel channel; // endregion Members // region Initialization @Before public void testInitialize() { configuration = new TelemetryConfiguration(); configuration.setInstrumentationKey("00000000-0000-0000-0000-000000000000"); channel = mock(TelemetryChannel.class); configuration.setChannel(channel); eventsSent = new LinkedList<Telemetry>(); // Setting the channel to add the sent telemetries to a collection, so they could be verified in tests. Mockito.doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { Telemetry telemetry = ((Telemetry) invocation.getArguments()[0]); eventsSent.add(telemetry); return null; } }).when(channel).send(Matchers.any(Telemetry.class)); client = new TelemetryClient(configuration); } // endregion Initialization // region Track tests @Test public void testNodeNameExists() { String nodeName = client.getContext().getInternal().getNodeName(); Assert.assertFalse(nodeName == null || nodeName.length()==0); } @Test public void testNodeNameSent() { client.trackEvent("Event"); EventTelemetry telemetry = (EventTelemetry) verifyAndGetLastEventSent(); String nodeName = telemetry.getContext().getInternal().getNodeName(); Assert.assertFalse(nodeName == null || nodeName.length()==0); } @Test public void testOverideNodeName(){ String overrideNode = "NewNodeName"; client.getContext().getInternal().setNodeName(overrideNode); client.trackEvent("Event"); EventTelemetry telemetry = (EventTelemetry) verifyAndGetLastEventSent(); String nodeName = telemetry.getContext().getInternal().getNodeName(); Assert.assertTrue("NodeName was not overriden", nodeName.equals(overrideNode)); } @Test public void testChannelSendException() { TelemetryChannel mockChannel = new TelemetryChannel() { @Override public boolean isDeveloperMode() { return false; } @Override public void setDeveloperMode(boolean value) { } @Override public void send(Telemetry item) { throw new RuntimeException(); } @Override public void stop(long timeout, TimeUnit timeUnit) { } @Override public void flush() { } @Override public void setSampler(TelemetrySampler telemetrySampler) { } }; configuration.setChannel(mockChannel); client.trackEvent("Mock"); } @Test(expected = IllegalArgumentException.class) public void testNullTrackTelemetry() { client.track(null); } @Test public void testTrackTelemetryWithDisabled() { configuration.setTrackingIsDisabled(true); Telemetry mockTelemetry = Mockito.mock(Telemetry.class); client.track(mockTelemetry); Mockito.verifyZeroInteractions(channel, mockTelemetry); } @Test public void testUseConfigurationInstrumentationKeyWithNull() { testUseConfigurationInstrumentatonKey(null); } @Test public void testUseConfigurationInstrumentationKeyWithEmpty() { testUseConfigurationInstrumentatonKey(""); } @Test public void testMethodsOnTelemetryAreCalledWhenTracking() { TelemetryChannel mockChannel = Mockito.mock(TelemetryChannel.class); configuration.setChannel(mockChannel); TelemetryContext mockContext = new TelemetryContext(); Telemetry mockTelemetry = Mockito.mock(Telemetry.class); Mockito.doReturn(mockContext).when(mockTelemetry).getContext(); TelemetryClient telemetryClient = new TelemetryClient(configuration); telemetryClient.track(mockTelemetry); Mockito.verify(mockChannel, Mockito.times(1)).send(mockTelemetry); Mockito.verify(mockTelemetry, Mockito.times(1)).setTimestamp(any(Date.class)); Mockito.verify(mockTelemetry, Mockito.times(1)).sanitize(); } @Test public void testTelemetryContextsAreCalled() { ContextInitializer mockContextInitializer = Mockito.mock(ContextInitializer.class); configuration.getContextInitializers().add(mockContextInitializer); TelemetryInitializer mockTelemetryInitializer = Mockito.mock(TelemetryInitializer.class); configuration.getTelemetryInitializers().add(mockTelemetryInitializer); TelemetryContext mockContext = new TelemetryContext(); Telemetry mockTelemetry = Mockito.mock(Telemetry.class); Mockito.doReturn(mockContext).when(mockTelemetry).getContext(); client.track(mockTelemetry); Mockito.verify(mockContextInitializer, Mockito.times(1)).initialize(any(TelemetryContext.class)); Mockito.verify(mockTelemetryInitializer, Mockito.times(1)).initialize(mockTelemetry); } @Test public void testTrackEventWithPropertiesAndMetrics() { Map<String, String> properties = new HashMap<String, String>() {{ put("key", "value"); }}; Map<String, Double> metrics = new HashMap<String, Double>() {{ put("key", 1d); }}; client.trackEvent("Event", properties, metrics); EventTelemetry telemetry = (EventTelemetry) verifyAndGetLastEventSent(); Assert.assertTrue("Expected telemetry property not found", telemetry.getProperties().get("key").equalsIgnoreCase("value")); Assert.assertTrue("Expected telemetry property not found", 1d == telemetry.getMetrics().get("key")); } @Test public void testTrackEventWithName() { client.trackEvent("Event"); verifyAndGetLastEventSent(); } @Test public void testTrackEventWithEventTelemetry() { EventTelemetry eventTelemetry = new EventTelemetry("Event"); client.trackEvent(eventTelemetry); verifyAndGetLastEventSent(); } @Test public void testTrackSessionState() { client.trackSessionState(SessionState.End); verifyAndGetLastEventSent(); } @Test public void testTrackTraceAll() { Map<String, String> properties = new HashMap<String, String>() {{ put("key", "value"); }}; client.trackTrace("Trace", SeverityLevel.Error, properties); Telemetry telemetry = verifyAndGetLastEventSent(); verifyTraceTelemetry(telemetry, SeverityLevel.Error, properties); } @Test public void testTrackTraceWithProperties() { Map<String, String> properties = new HashMap<String, String>() {{ put("key", "value"); }}; client.trackTrace("Trace", null, properties); Telemetry telemetry = verifyAndGetLastEventSent(); verifyTraceTelemetry(telemetry, null, properties); } @Test public void testTrackTraceWithSeverityLevel() { client.trackTrace("Trace", SeverityLevel.Critical); Telemetry telemetry = verifyAndGetLastEventSent(); verifyTraceTelemetry(telemetry, SeverityLevel.Critical, null); } @Test public void testTrackTraceWithName() { client.trackTrace("Trace"); verifyAndGetLastEventSent();} @Test public void testTrackTraceWithTraceTelemetry() { TraceTelemetry telemetry = new TraceTelemetry("Trace"); client.trackTrace(telemetry); verifyAndGetLastEventSent(); } @Test public void testTrackMetricWithExpandedValues() { Map<String, String> properties = new HashMap<String, String>() {{ put("key", "value"); }}; client.trackMetric("Metric", 1, 1, 1, 1, properties); verifyAndGetLastEventSent(); } @Test public void testTrackMetricWithNameAndValue() { client.trackMetric("Metric", 1); verifyAndGetLastEventSent(); } @Test public void testTrackMetricWithMetricTelemetry() { MetricTelemetry telemetry = new MetricTelemetry("Metric", 1); client.trackMetric(telemetry); verifyAndGetLastEventSent(); } @Test public void testTrackExceptionWithPropertiesAndMetrics() { Exception exception = new Exception("Exception"); Map<String, String> properties = new HashMap<String, String>() {{ put("key", "value"); }}; Map<String, Double> metrics = new HashMap<String, Double>() {{ put("key", 1d); }}; client.trackException(exception, properties, metrics); verifyAndGetLastEventSent(); } @Test public void testTrackExceptionWithExceptionTelemetry() { ExceptionTelemetry telemetry = new ExceptionTelemetry(new Exception("Exception")); client.trackException(telemetry); verifyAndGetLastEventSent(); } @Test public void testTrackException() { Exception exception = new Exception("Exception"); client.trackException(exception); verifyAndGetLastEventSent(); } @Test public void testTrackHttpRequest() { client.trackHttpRequest("Name", new Date(), 1, "200", true); verifyAndGetLastEventSent(); } @Test public void testTrackHttpRequestWithHttpRequestTelemetry() { RequestTelemetry telemetry = new RequestTelemetry("Name", new Date(), 1, "200", true); client.trackRequest(telemetry); verifyAndGetLastEventSent(); } @Test @Ignore("Not supported yet.") public void testTrackRemoteDependency(){ } @Test public void testTrackPageViewWithName() { client.trackPageView("PageName"); verifyAndGetLastEventSent(); } @Test public void testTrackPageViewWithPageViewTelemetry() { PageViewTelemetry telemetry = new PageViewTelemetry("PageName"); client.trackPageView(telemetry); verifyAndGetLastEventSent(); } @Test public void testTrack() { TraceTelemetry telemetry = new TraceTelemetry("test"); client.track(telemetry); verifyAndGetLastEventSent(); } @Test public void testContextThrowsInInitialize() { ContextInitializer mockContextInitializer = new ContextInitializer() { @Override public void initialize(TelemetryContext context) { throw new RuntimeException(); } }; configuration.getContextInitializers().add(mockContextInitializer); TraceTelemetry telemetry = new TraceTelemetry("test"); client.track(telemetry); } @Test public void testFlush() { client.flush(); Mockito.verify(channel, Mockito.times(1)).flush(); } @Test public void testFilterOutTelemetry() throws Throwable { RequestTelemetryFilter filter = new RequestTelemetryFilter(); filter.setNotNeededResponseCodes("200-400"); configuration.getTelemetryProcessors().add(filter); RequestTelemetry rt = new RequestTelemetry(); rt.setUrl(new URL("http:///www.microsoft.com/")); client.trackRequest(rt); Mockito.verify(channel, Mockito.never()).send(rt); } @Test public void testDontFilterOutTelemetry() throws Throwable { RequestTelemetryFilter filter = new RequestTelemetryFilter(); filter.setNotNeededResponseCodes("201-400"); RequestTelemetry rt = new RequestTelemetry(); rt.setUrl(new URL("http:///www.microsoft.com/")); client.trackRequest(rt); Mockito.verify(channel, Mockito.times(1)).send(rt); } // endregion Track tests // region Private methods private static void verifyTraceTelemetry(Telemetry telemetry, SeverityLevel expectedSeverityLevel, Map<String, String> expectedProperties) { assertNotNull(telemetry); assertTrue(telemetry instanceof TraceTelemetry); TraceTelemetry traceTelemetry = (TraceTelemetry)telemetry; assertEquals(traceTelemetry.getSeverityLevel(), expectedSeverityLevel); if (expectedProperties != null) { assertEquals(traceTelemetry.getContext().getProperties(), expectedProperties); } } private void testUseConfigurationInstrumentatonKey(String contextInstrumentationKey) { TelemetryConfiguration configuration = new TelemetryConfiguration(); TelemetryChannel mockChannel = Mockito.mock(TelemetryChannel.class); configuration.setChannel(mockChannel); configuration.setInstrumentationKey("00000000-0000-0000-0000-000000000000"); TelemetryContext mockContext = new TelemetryContext(); mockContext.setInstrumentationKey(contextInstrumentationKey); Telemetry mockTelemetry = Mockito.mock(Telemetry.class); Mockito.doReturn(mockContext).when(mockTelemetry).getContext(); TelemetryClient telemetryClient = new TelemetryClient(configuration); telemetryClient.track(mockTelemetry); Mockito.verify(mockChannel, Mockito.times(1)).send(mockTelemetry); assertEquals(mockContext.getInstrumentationKey(), "00000000-0000-0000-0000-000000000000"); } private Telemetry verifyAndGetLastEventSent() { verify(channel, times(1)).send(any(Telemetry.class)); return eventsSent.get(0); } // endregion Private methods }