Skip to content

Commit 69e0665

Browse files
authored
Verify actual Analytics event HTTP requests / refactor AnalyticsPingManager (#1534)
* Enable UI testing * Refactor AnalyticsPingManager * Add and fix tests * Add HTTP request tests * Pull in org.eclipse.rcp to suppress verbose log * Get client ID when creating an instance * Convert to E2E tests
1 parent 0422ac9 commit 69e0665

5 files changed

Lines changed: 237 additions & 69 deletions

File tree

plugins/com.google.cloud.tools.eclipse.usagetracker.test/pom.xml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,34 @@
1010
<artifactId>com.google.cloud.tools.eclipse.usagetracker.test</artifactId>
1111
<version>0.1.0-SNAPSHOT</version>
1212
<packaging>eclipse-test-plugin</packaging>
13+
14+
<build>
15+
<plugins>
16+
<plugin>
17+
<groupId>org.eclipse.tycho</groupId>
18+
<artifactId>tycho-surefire-plugin</artifactId>
19+
<configuration>
20+
<useUIHarness>true</useUIHarness>
21+
<useUIThread>true</useUIThread>
22+
<product>org.eclipse.platform.ide</product>
23+
</configuration>
24+
</plugin>
25+
<plugin>
26+
<groupId>org.eclipse.tycho</groupId>
27+
<artifactId>target-platform-configuration</artifactId>
28+
<configuration>
29+
<dependency-resolution>
30+
<extraRequirements>
31+
<!-- needed for org.eclipse.equinox.event -->
32+
<requirement>
33+
<type>eclipse-feature</type>
34+
<id>org.eclipse.rcp</id>
35+
<versionRange>0.0.0</versionRange>
36+
</requirement>
37+
</extraRequirements>
38+
</dependency-resolution>
39+
</configuration>
40+
</plugin>
41+
</plugins>
42+
</build>
1343
</project>

plugins/com.google.cloud.tools.eclipse.usagetracker.test/src/com/google/cloud/tools/eclipse/usagetracker/AnalyticsPingManagerTest.java

Lines changed: 74 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
package com.google.cloud.tools.eclipse.usagetracker;
1818

1919
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertFalse;
2021
import static org.junit.Assert.assertTrue;
2122
import static org.mockito.Matchers.any;
2223
import static org.mockito.Matchers.anyBoolean;
24+
import static org.mockito.Matchers.anyString;
2325
import static org.mockito.Matchers.eq;
2426
import static org.mockito.Mockito.never;
2527
import static org.mockito.Mockito.times;
@@ -28,12 +30,11 @@
2830

2931
import com.google.cloud.tools.eclipse.preferences.AnalyticsPreferences;
3032
import com.google.cloud.tools.eclipse.usagetracker.AnalyticsPingManager.PingEvent;
31-
import java.util.Collections;
32-
import java.util.HashMap;
3333
import java.util.Map;
3434
import java.util.concurrent.ConcurrentLinkedQueue;
3535
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
3636
import org.eclipse.swt.widgets.Display;
37+
import org.junit.Before;
3738
import org.junit.Test;
3839
import org.junit.runner.RunWith;
3940
import org.mockito.Mock;
@@ -43,43 +44,21 @@
4344
@RunWith(MockitoJUnitRunner.class)
4445
public class AnalyticsPingManagerTest {
4546

46-
private static final String UUID = "bee5d838-c3f8-4940-a944-b56973597e74";
47-
48-
private static final String EVENT_TYPE = "some-event-type";
49-
private static final String EVENT_NAME = "some-event-name";
50-
51-
private static final String VIRTUAL_HOST = "virtual.host";
52-
private static final String VIRTUAL_DOCUMENT_PAGE =
53-
"/virtual/" + EVENT_TYPE + "/" + EVENT_NAME;
54-
55-
private static final String METADATA_KEY = "some-custom-key";
56-
private static final String METADATA_VALUE = "some-custom-value";
57-
58-
// TODO(chanseok): add a test to that makes an actual HTTP request (locally) and checks the
59-
// incoming request. (https://github.com/GoogleCloudPlatform/google-cloud-eclipse/issues/1437)
60-
private static final Map<String, String> RANDOM_PARAMETERS = Collections.unmodifiableMap(
61-
new HashMap<String, String>() {
62-
{
63-
put("v", "1");
64-
put("tid", "UA-12345678-1");
65-
put("ni", "0");
66-
put("t", "pageview");
67-
put("cd21", "1");
68-
put("cd16", "0");
69-
put("cd17", "0");
70-
put("cid", UUID);
71-
put("cd19", EVENT_TYPE);
72-
put("cd20", EVENT_NAME);
73-
put("dh", VIRTUAL_HOST);
74-
put("dp", VIRTUAL_DOCUMENT_PAGE);
75-
put("dt", METADATA_KEY + "=" + METADATA_VALUE);
76-
}
77-
});
78-
7947
@Mock private IEclipsePreferences preferences;
8048
@Mock private Display display;
8149
@Mock private ConcurrentLinkedQueue<PingEvent> pingEventQueue;
8250

51+
private AnalyticsPingManager pingManager;
52+
53+
@Before
54+
public void setUp() {
55+
// Pretend ping event queue is always empty to prevent making actual HTTP requests.
56+
when(pingEventQueue.isEmpty()).thenReturn(true);
57+
58+
pingManager = new AnalyticsPingManager("https://non-null-url-to-enable-mananger",
59+
"clientId", preferences, display, pingEventQueue);
60+
}
61+
8362
@Test
8463
public void testEventTypeEventNameConvention() {
8564
PingEvent event = new PingEvent("some.event-name", null, null, null);
@@ -101,6 +80,13 @@ public void testMetadataConvention() {
10180
assertEquals("times-happened=1234", parameters.get("dt"));
10281
}
10382

83+
@Test
84+
public void testClientId() {
85+
PingEvent event = new PingEvent("some.event-name", null, null, null);
86+
Map<String, String> parameters = AnalyticsPingManager.buildParametersMap("clientId", event);
87+
assertEquals("clientId", parameters.get("cid"));
88+
}
89+
10490
@Test
10591
public void testOptInDialogShown_optInNotRegisteredAndNotYetOptedIn() {
10692
mockOptIn(false);
@@ -141,9 +127,6 @@ private void mockOptInRegistered(boolean registered) {
141127
}
142128

143129
private void verifyOptInDialogOpen(VerificationMode verificationMode) {
144-
AnalyticsPingManager pingManager =
145-
new AnalyticsPingManager(preferences, display, pingEventQueue, true);
146-
pingManager.unitTestMode = true;
147130
pingManager.showOptInDialogIfNeeded(null);
148131
verify(display, verificationMode).syncExec(any(Runnable.class));
149132
}
@@ -177,11 +160,60 @@ public void testSendPingScheduled_optInRegisteredAndAlreadyOptedIn() {
177160
}
178161

179162
private void verifyPingQueued(VerificationMode verificationMode) {
180-
when(pingEventQueue.isEmpty()).thenReturn(true);
181-
AnalyticsPingManager pingManager =
182-
new AnalyticsPingManager(preferences, display, pingEventQueue, true);
183-
pingManager.unitTestMode = true;
184163
pingManager.sendPing("eventName", "metadataKey", "metadataValue");
185164
verify(pingEventQueue, verificationMode).add(any(PingEvent.class));
186165
}
166+
167+
@Test
168+
public void testGetAnonymizedClientId_generateNewId() {
169+
when(preferences.get(eq(AnalyticsPreferences.ANALYTICS_CLIENT_ID), anyString()))
170+
.thenReturn(null); // Simulate that client ID has never been generated.
171+
String clientId = AnalyticsPingManager.getAnonymizedClientId(preferences);
172+
assertFalse(clientId.isEmpty());
173+
verify(preferences).put(AnalyticsPreferences.ANALYTICS_CLIENT_ID, clientId);
174+
}
175+
176+
@Test
177+
public void testGetAnonymizedClientId_useSavedId() {
178+
when(preferences.get(eq(AnalyticsPreferences.ANALYTICS_CLIENT_ID), anyString()))
179+
.thenReturn("some-unique-client-id");
180+
String clientId = AnalyticsPingManager.getAnonymizedClientId(preferences);
181+
assertEquals("some-unique-client-id", clientId);
182+
verify(preferences, never()).put(AnalyticsPreferences.ANALYTICS_CLIENT_ID, clientId);
183+
}
184+
185+
@Test
186+
public void testSendPingArguments_validArgumentsDoNotThrowException() {
187+
pingManager.sendPing("eventName", "metadataKey", "metadataValue");
188+
}
189+
190+
@Test(expected = IllegalArgumentException.class)
191+
public void testSendPingArguments_nullEventName() {
192+
pingManager.sendPing(null, "metadataKey", "metadataValue");
193+
}
194+
195+
@Test(expected = IllegalArgumentException.class)
196+
public void testSendPingArguments_emptyEventName() {
197+
pingManager.sendPing("", "metadataKey", "metadataValue");
198+
}
199+
200+
@Test(expected = IllegalArgumentException.class)
201+
public void testSendPingArguments_nullMetadataKeyWithNonNullValue() {
202+
pingManager.sendPing("eventName", null, "metadataValue");
203+
}
204+
205+
@Test(expected = IllegalArgumentException.class)
206+
public void testSendPingArguments_emptyMetadataKeyWithNonNullValue() {
207+
pingManager.sendPing("eventName", "", "metadataValue");
208+
}
209+
210+
@Test
211+
public void testSendPingArguments_nullMetadataValueDoNotThrowException() {
212+
pingManager.sendPing("eventName", "metadataKey", null);
213+
}
214+
215+
@Test(expected = IllegalArgumentException.class)
216+
public void testSendPingArguments_emptyMetadataValue() {
217+
pingManager.sendPing("eventName", "metadataKey", "");
218+
}
187219
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright 2017 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.tools.eclipse.usagetracker;
18+
19+
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertNull;
21+
import static org.mockito.Matchers.anyBoolean;
22+
import static org.mockito.Matchers.eq;
23+
import static org.mockito.Mockito.when;
24+
25+
import com.google.cloud.tools.eclipse.preferences.AnalyticsPreferences;
26+
import com.google.cloud.tools.eclipse.test.util.http.TestHttpServer;
27+
import com.google.cloud.tools.eclipse.usagetracker.AnalyticsPingManager.PingEvent;
28+
import com.google.cloud.tools.eclipse.util.CloudToolsInfo;
29+
import java.util.Map;
30+
import java.util.concurrent.ConcurrentLinkedQueue;
31+
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
32+
import org.eclipse.ui.PlatformUI;
33+
import org.junit.Before;
34+
import org.junit.Rule;
35+
import org.junit.Test;
36+
import org.junit.runner.RunWith;
37+
import org.mockito.Mock;
38+
import org.mockito.runners.MockitoJUnitRunner;
39+
40+
@RunWith(MockitoJUnitRunner.class)
41+
public class AnalyticsPingManagerWithServerTest {
42+
43+
@Mock private IEclipsePreferences preferences;
44+
45+
@Rule public TestHttpServer server = new TestHttpServer("", "");
46+
47+
private AnalyticsPingManager pingManager;
48+
49+
@Before
50+
public void setUp() {
51+
when(preferences.getBoolean(eq(AnalyticsPreferences.ANALYTICS_OPT_IN), anyBoolean()))
52+
.thenReturn(true); // Simulate user has opted in.
53+
54+
pingManager = new AnalyticsPingManager(
55+
server.getAddress(), "unique-client-id", preferences,
56+
PlatformUI.getWorkbench().getDisplay(), new ConcurrentLinkedQueue<PingEvent>());
57+
}
58+
59+
@Test
60+
public void testSendPing_noMetadata() throws InterruptedException {
61+
pingManager.sendPing("some.event-name", null, null, null);
62+
pingManager.eventFlushJob.join();
63+
64+
Map<String, String[]> parameters = server.getRequestParameters();
65+
verifyCommonParameters(parameters, "some.event-name");
66+
assertNull(parameters.get("dt"));
67+
}
68+
69+
@Test
70+
public void testSendPing_withMetadata() throws InterruptedException {
71+
pingManager.sendPing("another.event-name", "times-happened", "1234", null);
72+
pingManager.eventFlushJob.join();
73+
74+
Map<String, String[]> parameters = server.getRequestParameters();
75+
verifyCommonParameters(parameters, "another.event-name");
76+
assertEquals("times-happened=1234", parameters.get("dt")[0]);
77+
}
78+
79+
private void verifyCommonParameters(Map<String, String[]> parameters, String expectedEventName) {
80+
assertEquals("1", parameters.get("v")[0]);
81+
assertEquals("pageview", parameters.get("t")[0]);
82+
assertEquals("unique-client-id", parameters.get("cid")[0]);
83+
assertEquals("/virtual/" + CloudToolsInfo.METRICS_NAME + "/" + expectedEventName,
84+
parameters.get("dp")[0]);
85+
assertEquals(CloudToolsInfo.METRICS_NAME, parameters.get("cd19")[0]);
86+
assertEquals(expectedEventName, parameters.get("cd20")[0]);
87+
assertEquals("virtual.eclipse", parameters.get("dh")[0]);
88+
assertEquals("1", parameters.get("cd21")[0]);
89+
assertEquals("0", parameters.get("cd16")[0]);
90+
assertEquals("0", parameters.get("cd17")[0]);
91+
assertEquals("0", parameters.get("ni")[0]);
92+
assertEquals("0", parameters.get("ni")[0]);
93+
}
94+
}

plugins/com.google.cloud.tools.eclipse.usagetracker/META-INF/MANIFEST.MF

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ Import-Package: com.google.api.client.http;version="[1.22.0,1.23.0)",
1515
com.google.cloud.tools.eclipse.preferences,
1616
com.google.cloud.tools.eclipse.util,
1717
com.google.common.annotations;version="[20.0.0,21.0.0)",
18+
com.google.common.base;version="[20.0.0,21.0.0)",
1819
com.google.common.escape;version="[20.0.0,21.0.0)",
1920
com.google.common.net;version="[20.0.0,21.0.0)"

0 commit comments

Comments
 (0)