aboutsummaryrefslogtreecommitdiffstats
path: root/sdkstats
diff options
context:
space:
mode:
authorRaphael Moll <ralf@android.com>2012-04-11 12:47:40 -0700
committerRaphael Moll <ralf@android.com>2012-04-11 13:24:17 -0700
commitb354c5dcba5e2b4334132fb50b0b343d325f448e (patch)
tree53f14d9a11e96fa38362b36d643630dec2742f77 /sdkstats
parentabd814d21bcc4772e8ae7062366568dd667e9db2 (diff)
downloadsdk-b354c5dcba5e2b4334132fb50b0b343d325f448e.zip
sdk-b354c5dcba5e2b4334132fb50b0b343d325f448e.tar.gz
sdk-b354c5dcba5e2b4334132fb50b0b343d325f448e.tar.bz2
SDK: adjust reported OS/JVM name/arch.
Also add some UTs for testing. Change-Id: I55d4ad04feade4b4e8a81316511720731f9afdc9
Diffstat (limited to 'sdkstats')
-rw-r--r--sdkstats/.classpath2
-rw-r--r--sdkstats/src/com/android/sdkstats/SdkStatsService.java84
-rwxr-xr-xsdkstats/tests/com/android/sdkstats/SdkStatsServiceTest.java279
3 files changed, 337 insertions, 28 deletions
diff --git a/sdkstats/.classpath b/sdkstats/.classpath
index e823aa5..299175e 100644
--- a/sdkstats/.classpath
+++ b/sdkstats/.classpath
@@ -1,11 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="tests"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
<classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/linux-x86/swt/swt.jar"/>
<classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/eclipse/org.eclipse.core.commands_3.6.0.I20100512-1500.jar"/>
<classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/eclipse/org.eclipse.equinox.common_3.6.0.v20100503.jar"/>
<classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/eclipse/org.eclipse.jface_3.6.2.M20110210-1200.jar"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/sdkstats/src/com/android/sdkstats/SdkStatsService.java b/sdkstats/src/com/android/sdkstats/SdkStatsService.java
index 298132d..9c3a008 100644
--- a/sdkstats/src/com/android/sdkstats/SdkStatsService.java
+++ b/sdkstats/src/com/android/sdkstats/SdkStatsService.java
@@ -23,12 +23,18 @@ import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
+import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** Utility class to send "ping" usage reports to the server. */
public class SdkStatsService {
+ protected static final String SYS_PROP_OS_ARCH = "os.arch"; //$NON-NLS-1$
+ protected static final String SYS_PROP_JAVA_VERSION = "java.version"; //$NON-NLS-1$
+ protected static final String SYS_PROP_OS_VERSION = "os.version"; //$NON-NLS-1$
+ protected static final String SYS_PROP_OS_NAME = "os.name"; //$NON-NLS-1$
+
/** Minimum interval between ping, in milliseconds. */
private static final long PING_INTERVAL_MSEC = 86400 * 1000; // 1 day
@@ -42,7 +48,7 @@ public class SdkStatsService {
* elapsed since the last ping, and if the user has not opted out.<br>
*
* The ping will not be sent if the user opt out dialog has not been shown yet.
- * Use {@link #getUserPermissionForPing(Shell)} to display the dialog requesting
+ * Use {@link #checkUserPermissionForPing(Shell)} to display the dialog requesting
* user permissions.<br>
*
* Note: The actual ping (if any) is sent in a <i>non-daemon</i> background thread.
@@ -58,8 +64,8 @@ public class SdkStatsService {
* Display a dialog to the user providing information about the ping service,
* and whether they'd like to opt-out of it.
*
- * Once the dialog has been shown, it sets a preference internally indicating that the user has
- * viewed this dialog. This setting can be queried using {@link #pingPermissionsSet()}.
+ * Once the dialog has been shown, it sets a preference internally indicating
+ * that the user has viewed this dialog.
*/
public void checkUserPermissionForPing(Shell parent) {
if (!mStore.hasPingId()) {
@@ -137,7 +143,7 @@ public class SdkStatsService {
* @param id of the local installation
* @throws IOException if the ping failed
*/
- private static void actuallySendPing(String app, String version, long id)
+ private void actuallySendPing(String app, String version, long id)
throws IOException {
String osName = URLEncoder.encode(getOsName(), "UTF-8");
String osArch = URLEncoder.encode(getOsArch(), "UTF-8");
@@ -173,26 +179,28 @@ public class SdkStatsService {
* For Windows and Mac also append the version, so for example
* Win XP will return win-5.1.
*/
- private static String getOsName() {
- String os = System.getProperty("os.name"); //$NON-NLS-1$
+ protected String getOsName() { // made protected for testing
+ String os = getSystemProperty(SYS_PROP_OS_NAME);
if (os == null || os.length() == 0) {
return "unknown"; //$NON-NLS-1$
}
- if (os.startsWith("Mac OS")) { //$NON-NLS-1$
+ String os2 = os.toLowerCase(Locale.US);
+
+ if (os2.startsWith("mac")) { //$NON-NLS-1$
os = "mac"; //$NON-NLS-1$
String osVers = getOsVersion();
if (osVers != null) {
os = os + '-' + osVers;
}
- } else if (os.startsWith("Windows")) { //$NON-NLS-1$
+ } else if (os2.startsWith("win")) { //$NON-NLS-1$
os = "win"; //$NON-NLS-1$
String osVers = getOsVersion();
if (osVers != null) {
os = os + '-' + osVers;
}
- } else if (os.startsWith("Linux")) { //$NON-NLS-1$
+ } else if (os2.startsWith("linux")) { //$NON-NLS-1$
os = "linux"; //$NON-NLS-1$
} else if (os.length() > 32) {
@@ -208,7 +216,7 @@ public class SdkStatsService {
* This may differ or be equal to the JVM architecture in the sense that
* a 64-bit OS can run a 32-bit JVM.
*/
- private static String getOsArch() {
+ protected String getOsArch() { // made protected for testing
String arch = getJvmArch();
if ("x86_64".equals(arch)) { //$NON-NLS-1$
@@ -229,16 +237,16 @@ public class SdkStatsService {
// it sets PROCESSOR_ARCHITEW6432 to AMD64 or IA64 accordingly.
// Ref: http://msdn.microsoft.com/en-us/library/aa384274(v=vs.85).aspx
- String w6432 = System.getenv("PROCESSOR_ARCHITEW6432"); //$NON-NLS-1$
+ String w6432 = getSystemEnv("PROCESSOR_ARCHITEW6432"); //$NON-NLS-1$
if (w6432 != null && w6432.indexOf("64") != -1) { //$NON-NLS-1$
return "x86_64"; //$NON-NLS-1$
}
} else if (os.startsWith("linux")) { //$NON-NLS-1$
// Let's try the obvious. This works in Ubuntu and Debian
- String s = System.getenv("HOSTTYPE"); //$NON-NLS-1$
+ String s = getSystemEnv("HOSTTYPE"); //$NON-NLS-1$
s = sanitizeOsArch(s);
- if (s.indexOf("86") != -1) {
+ if (s.indexOf("86") != -1) { //$NON-NLS-1$
arch = s;
}
}
@@ -253,15 +261,17 @@ public class SdkStatsService {
* Example of returned versions can be found at http://lopica.sourceforge.net/os.html
* <p/>
* This method removes any exiting micro versions.
+ * Returns null if the version doesn't match X.Y.Z.
*/
- private static String getOsVersion() {
- Pattern p = Pattern.compile("(\\d+)\\.(\\d+).*"); //$NON-NLS-1$
- String osVers = System.getProperty("os.version"); //$NON-NLS-1$
- Matcher m = p.matcher(osVers);
- if (m.matches()) {
- return m.group(1) + '.' + m.group(2);
+ protected String getOsVersion() { // made protected for testing
+ Pattern p = Pattern.compile("(\\d+)\\.(\\d+).*"); //$NON-NLS-1$
+ String osVers = getSystemProperty(SYS_PROP_OS_VERSION);
+ if (osVers != null && osVers.length() > 0) {
+ Matcher m = p.matcher(osVers);
+ if (m.matches()) {
+ return m.group(1) + '.' + m.group(2);
+ }
}
-
return null;
}
@@ -269,7 +279,7 @@ public class SdkStatsService {
* Detects and returns the JVM info: version + architecture.
* Examples: 1.4-ppc, 1.6-x86, 1.7-x86_64
*/
- private static String getJvmInfo() {
+ protected String getJvmInfo() { // made protected for testing
return getJvmVersion() + '-' + getJvmArch();
}
@@ -279,8 +289,8 @@ public class SdkStatsService {
* The "java.version" property returns something like "1.6.0_20"
* of which we want to return "1.6".
*/
- private static String getJvmVersion() {
- String version = System.getProperty("java.version"); //$NON-NLS-1$
+ protected String getJvmVersion() { // made protected for testing
+ String version = getSystemProperty(SYS_PROP_JAVA_VERSION);
if (version == null || version.length() == 0) {
return "unknown"; //$NON-NLS-1$
@@ -318,12 +328,12 @@ public class SdkStatsService {
* Mac untested x86_64
* </pre>
*/
- private static String getJvmArch() {
- String arch = System.getProperty("os.arch"); //$NON-NLS-1$
+ protected String getJvmArch() { // made protected for testing
+ String arch = getSystemProperty(SYS_PROP_OS_ARCH);
return sanitizeOsArch(arch);
}
- private static String sanitizeOsArch(String arch) {
+ private String sanitizeOsArch(String arch) {
if (arch == null || arch.length() == 0) {
return "unknown"; //$NON-NLS-1$
}
@@ -334,7 +344,7 @@ public class SdkStatsService {
return "x86_64"; //$NON-NLS-1$
}
- if (arch.length() == 4 && arch.charAt(0) == 'i' && arch.lastIndexOf("86") == 2) {
+ if (arch.length() >= 4 && arch.charAt(0) == 'i' && arch.indexOf("86") == 2) { //$NON-NLS-1$
// Any variation of iX86 counts as x86 (i386, i486, i686).
return "x86"; //$NON-NLS-1$
}
@@ -356,7 +366,7 @@ public class SdkStatsService {
* @param version supplied by caller
* @return normalized dotted quad version
*/
- private static String normalizeVersion(String app, String version) {
+ private String normalizeVersion(String app, String version) {
// Application name must contain only word characters (no punctuation)
if (!app.matches("\\w+")) { //$NON-NLS-1$
throw new IllegalArgumentException("Bad app name: " + app); //$NON-NLS-1$
@@ -380,4 +390,22 @@ public class SdkStatsService {
}
return normal.toString();
}
+
+ /**
+ * Calls {@link System#getProperty(String)}.
+ * Allows unit-test to override the return value.
+ * @see System#getProperty(String)
+ */
+ protected String getSystemProperty(String name) {
+ return System.getProperty(name);
+ }
+
+ /**
+ * Calls {@link System#getenv(String)}.
+ * Allows unit-test to override the return value.
+ * @see System#getenv(String)
+ */
+ protected String getSystemEnv(String name) {
+ return System.getenv(name);
+ }
}
diff --git a/sdkstats/tests/com/android/sdkstats/SdkStatsServiceTest.java b/sdkstats/tests/com/android/sdkstats/SdkStatsServiceTest.java
new file mode 100755
index 0000000..6b8a4eb
--- /dev/null
+++ b/sdkstats/tests/com/android/sdkstats/SdkStatsServiceTest.java
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdkstats;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+public class SdkStatsServiceTest extends TestCase {
+
+ private static class MockSdkStatsService extends SdkStatsService {
+
+ private final String mOsName;
+ private final String mOsVersion;
+ private final String mOsArch;
+ private final String mJavaVersion;
+ private final Map<String, String> mEnvVars = new HashMap<String, String>();
+
+ public MockSdkStatsService(String osName,
+ String osVersion,
+ String osArch,
+ String javaVersion) {
+ mOsName = osName;
+ mOsVersion = osVersion;
+ mOsArch = osArch;
+ mJavaVersion = javaVersion;
+ }
+
+ public void setSystemEnv(String varName, String value) {
+ mEnvVars.put(varName, value);
+ }
+
+ @Override
+ protected String getSystemProperty(String name) {
+ if (SdkStatsService.SYS_PROP_OS_NAME.equals(name)) {
+ return mOsName;
+ } else if (SdkStatsService.SYS_PROP_OS_VERSION.equals(name)) {
+ return mOsVersion;
+ } else if (SdkStatsService.SYS_PROP_OS_ARCH.equals(name)) {
+ return mOsArch;
+ } else if (SdkStatsService.SYS_PROP_JAVA_VERSION.equals(name)) {
+ return mJavaVersion;
+ }
+ // Don't use current properties values, we don't want the tests to be flaky
+ fail("SdkStatsServiceTest doesn't define a system.property for " + name);
+ return null;
+ }
+
+ @Override
+ protected String getSystemEnv(String name) {
+ if (mEnvVars.containsKey(name)) {
+ return mEnvVars.get(name);
+ }
+ // Don't use current env vars, we don't want the tests to be flaky
+ fail("SdkStatsServiceTest doesn't define a system.getenv for " + name);
+ return null;
+ }
+
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testSdkStatsService_getJvmArch() {
+ MockSdkStatsService m;
+
+ m = new MockSdkStatsService("Windows", "4.0", "x86", "1.7");
+ assertEquals("x86", m.getJvmArch());
+ m = new MockSdkStatsService("Windows", "4.0", "i386", "1.7");
+ assertEquals("x86", m.getJvmArch());
+ m = new MockSdkStatsService("Windows", "4.0", "i486", "1.7");
+ assertEquals("x86", m.getJvmArch());
+ m = new MockSdkStatsService("Linux", "4.0", "i486-linux", "1.7");
+ assertEquals("x86", m.getJvmArch());
+ m = new MockSdkStatsService("Windows", "4.0", "i586", "1.7");
+ assertEquals("x86", m.getJvmArch());
+ m = new MockSdkStatsService("Windows", "4.0", "i686", "1.7");
+ assertEquals("x86", m.getJvmArch());
+
+ m = new MockSdkStatsService("Mac OS", "10.0", "x86_64", "1.7");
+ assertEquals("x86_64", m.getJvmArch());
+ m = new MockSdkStatsService("Mac OS", "8.0", "PowerPC", "1.7");
+ assertEquals("ppc", m.getJvmArch());
+
+ m = new MockSdkStatsService("Mac OS", "4.0", "x86_64", "1.7");
+ assertEquals("x86_64", m.getJvmArch());
+ m = new MockSdkStatsService("Windows", "4.0", "ia64", "1.7");
+ assertEquals("x86_64", m.getJvmArch());
+ m = new MockSdkStatsService("Windows", "4.0", "amd64", "1.7");
+ assertEquals("x86_64", m.getJvmArch());
+
+ m = new MockSdkStatsService("Windows", "4.0", "atom", "1.7");
+ assertEquals("atom", m.getJvmArch());
+
+ // 32 chars max
+ m = new MockSdkStatsService("Windows", "4.0",
+ "one3456789ten3456789twenty6789thirty6789", "1.7");
+ assertEquals("one3456789ten3456789twenty6789th", m.getJvmArch());
+
+ m = new MockSdkStatsService("Windows", "4.0", "", "1.7");
+ assertEquals("unknown", m.getJvmArch());
+
+ m = new MockSdkStatsService("Windows", "4.0", null, "1.7");
+ assertEquals("unknown", m.getJvmArch());
+ }
+
+ public void testSdkStatsService_getJvmVersion() {
+ MockSdkStatsService m;
+
+ m = new MockSdkStatsService("Windows", "4.0", "x86", "1.7.8_09");
+ assertEquals("1.7", m.getJvmVersion());
+
+ m = new MockSdkStatsService("Windows", "4.0", "x86", "");
+ assertEquals("unknown", m.getJvmVersion());
+
+ m = new MockSdkStatsService("Windows", "4.0", "x86", null);
+ assertEquals("unknown", m.getJvmVersion());
+
+ // 8 chars max
+ m = new MockSdkStatsService("Windows", "4.0", "x86",
+ "one3456789ten3456789twenty6789thirty6789");
+ assertEquals("one34567", m.getJvmVersion());
+ }
+
+ public void testSdkStatsService_getJvmInfo() {
+ MockSdkStatsService m;
+
+ m = new MockSdkStatsService("Windows", "4.0", "x86", "1.7.8_09");
+ assertEquals("1.7-x86", m.getJvmInfo());
+
+ m = new MockSdkStatsService("Windows", "4.0", "amd64", "1.7.8_09");
+ assertEquals("1.7-x86_64", m.getJvmInfo());
+
+ m = new MockSdkStatsService("Windows", "4.0", "", "");
+ assertEquals("unknown-unknown", m.getJvmInfo());
+
+ m = new MockSdkStatsService("Windows", "4.0", null, null);
+ assertEquals("unknown-unknown", m.getJvmInfo());
+
+ // 8+32 chars max
+ m = new MockSdkStatsService("Windows", "4.0",
+ "one3456789ten3456789twenty6789thirty6789",
+ "one3456789ten3456789twenty6789thirty6789");
+ assertEquals("one34567-one3456789ten3456789twenty6789th", m.getJvmInfo());
+ }
+
+ public void testSdkStatsService_getOsVersion() {
+ MockSdkStatsService m;
+
+ m = new MockSdkStatsService("Windows", "4.0.32", "x86", "1.7.8_09");
+ assertEquals("4.0", m.getOsVersion());
+
+ m = new MockSdkStatsService("Windows", "4.0", "x86", "1.7.8_09");
+ assertEquals("4.0", m.getOsVersion());
+
+ m = new MockSdkStatsService("Windows", "4", "x86", "1.7.8_09");
+ assertEquals(null, m.getOsVersion());
+
+ m = new MockSdkStatsService("Windows", "4.0;extrainfo", "x86", "1.7.8_09");
+ assertEquals("4.0", m.getOsVersion());
+
+ m = new MockSdkStatsService("Mac OS", "10.8.32", "x86_64", "1.7.8_09");
+ assertEquals("10.8", m.getOsVersion());
+
+ m = new MockSdkStatsService("Mac OS", "10.8", "x86_64", "1.7.8_09");
+ assertEquals("10.8", m.getOsVersion());
+
+ m = new MockSdkStatsService("Other", "", "x86_64", "1.7.8_09");
+ assertEquals(null, m.getOsVersion());
+
+ m = new MockSdkStatsService("Other", null, "x86_64", "1.7.8_09");
+ assertEquals(null, m.getOsVersion());
+ }
+
+ public void testSdkStatsService_getOsArch() {
+ MockSdkStatsService m;
+
+ // 64 bit jvm
+ m = new MockSdkStatsService("Mac OS", "10.8.32", "x86_64", "1.7.8_09");
+ assertEquals("x86_64", m.getOsArch());
+
+ m = new MockSdkStatsService("Windows", "8.32", "x86_64", "1.7.8_09");
+ assertEquals("x86_64", m.getOsArch());
+
+ m = new MockSdkStatsService("Linux", "8.32", "x86_64", "1.7.8_09");
+ assertEquals("x86_64", m.getOsArch());
+
+ // 32 bit jvm with 32 vs 64 bit os
+ m = new MockSdkStatsService("Windows", "8.32", "x86", "1.7.8_09");
+ m.setSystemEnv("PROCESSOR_ARCHITEW6432", null);
+ assertEquals("x86", m.getOsArch());
+
+ m = new MockSdkStatsService("Windows", "8.32", "x86", "1.7.8_09");
+ m.setSystemEnv("PROCESSOR_ARCHITEW6432", "AMD64");
+ assertEquals("x86_64", m.getOsArch());
+
+ m = new MockSdkStatsService("Windows", "8.32", "x86", "1.7.8_09");
+ m.setSystemEnv("PROCESSOR_ARCHITEW6432", "IA64");
+ assertEquals("x86_64", m.getOsArch());
+
+ // 32 bit jvm with 32 vs 64 bit os
+ m = new MockSdkStatsService("Linux", "8.32", "x86", "1.7.8_09");
+ m.setSystemEnv("HOSTTYPE", null);
+ assertEquals("x86", m.getOsArch());
+
+ m = new MockSdkStatsService("Linux", "8.32", "x86", "1.7.8_09");
+ m.setSystemEnv("HOSTTYPE", "i686-linux");
+ assertEquals("x86", m.getOsArch());
+
+ m = new MockSdkStatsService("Linux", "8.32", "x86", "1.7.8_09");
+ m.setSystemEnv("HOSTTYPE", "AMD64");
+ assertEquals("x86_64", m.getOsArch());
+
+ m = new MockSdkStatsService("Linux", "8.32", "x86", "1.7.8_09");
+ m.setSystemEnv("HOSTTYPE", "x86_64");
+ assertEquals("x86_64", m.getOsArch());
+ }
+
+ public void testSdkStatsService_getOsName() {
+ MockSdkStatsService m;
+
+ m = new MockSdkStatsService("Mac OS", "10.8.32", "x86_64", "1.7.8_09");
+ assertEquals("mac-10.8", m.getOsName());
+
+ m = new MockSdkStatsService("mac", "10", "x86", "1.7.8_09");
+ assertEquals("mac", m.getOsName());
+
+ m = new MockSdkStatsService("Windows", "6.2", "x86_64", "1.7.8_09");
+ assertEquals("win-6.2", m.getOsName());
+
+ m = new MockSdkStatsService("win", "6.2", "x86", "1.7.8_09");
+ assertEquals("win-6.2", m.getOsName());
+
+ m = new MockSdkStatsService("win", "6", "x86_64", "1.7.8_09");
+ assertEquals("win", m.getOsName());
+
+ m = new MockSdkStatsService("Linux", "foobuntu-32", "x86", "1.7.8_09");
+ assertEquals("linux", m.getOsName());
+
+ m = new MockSdkStatsService("linux", "1", "x86_64", "1.7.8_09");
+ assertEquals("linux", m.getOsName());
+
+ m = new MockSdkStatsService("PowerPC", "32", "ppc", "1.7.8_09");
+ assertEquals("PowerPC", m.getOsName());
+
+ m = new MockSdkStatsService("freebsd", "42", "x86_64", "1.7.8_09");
+ assertEquals("freebsd", m.getOsName());
+
+ m = new MockSdkStatsService("openbsd", "43", "x86_64", "1.7.8_09");
+ assertEquals("openbsd", m.getOsName());
+
+ // 32 chars max
+ m = new MockSdkStatsService("one3456789ten3456789twenty6789thirty6789",
+ "42", "x86_64", "1.7.8_09");
+ assertEquals("one3456789ten3456789twenty6789th", m.getOsName());
+ }
+}