mobile/android/tests/background/junit3/src/healthreport/TestHealthReportProvider.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/tests/background/junit3/src/healthreport/TestHealthReportProvider.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,253 @@
     1.4 +/* Any copyright is dedicated to the Public Domain.
     1.5 +   http://creativecommons.org/publicdomain/zero/1.0/ */
     1.6 +
     1.7 +package org.mozilla.gecko.background.healthreport;
     1.8 +
     1.9 +import org.mozilla.gecko.background.helpers.DBHelpers;
    1.10 +import org.mozilla.gecko.background.helpers.DBProviderTestCase;
    1.11 +
    1.12 +import android.content.ContentResolver;
    1.13 +import android.content.ContentValues;
    1.14 +import android.database.Cursor;
    1.15 +import android.net.Uri;
    1.16 +import android.test.mock.MockContentResolver;
    1.17 +
    1.18 +public class TestHealthReportProvider extends DBProviderTestCase<HealthReportProvider> {
    1.19 +  protected static final int MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
    1.20 +
    1.21 +  public TestHealthReportProvider() {
    1.22 +    super(HealthReportProvider.class, HealthReportProvider.HEALTH_AUTHORITY);
    1.23 +  }
    1.24 +
    1.25 +  public TestHealthReportProvider(Class<HealthReportProvider> providerClass,
    1.26 +                                  String providerAuthority) {
    1.27 +    super(providerClass, providerAuthority);
    1.28 +  }
    1.29 +
    1.30 +  private Uri getCompleteUri(String rest) {
    1.31 +    return Uri.parse("content://" + HealthReportProvider.HEALTH_AUTHORITY + rest +
    1.32 +                     (rest.indexOf('?') == -1 ? "?" : "&") +
    1.33 +                     "profilePath=" + Uri.encode(fakeProfileDirectory.getAbsolutePath()));
    1.34 +  }
    1.35 +
    1.36 +  private void ensureCount(int expected, Uri uri) {
    1.37 +    final MockContentResolver resolver = getMockContentResolver();
    1.38 +    Cursor cursor = resolver.query(uri, null, null, null, null);
    1.39 +    assertNotNull(cursor);
    1.40 +    assertEquals(expected, cursor.getCount());
    1.41 +    cursor.close();
    1.42 +  }
    1.43 +
    1.44 +  private void ensureMeasurementCount(int expected) {
    1.45 +    final Uri measurements = getCompleteUri("/measurements/");
    1.46 +    ensureCount(expected, measurements);
    1.47 +  }
    1.48 +
    1.49 +  private void ensureFieldCount(int expected) {
    1.50 +    final Uri fields = getCompleteUri("/fields/");
    1.51 +    ensureCount(expected, fields);
    1.52 +  }
    1.53 +
    1.54 +  public void testNonExistentMeasurement() {
    1.55 +    assertNotNull(getContext());
    1.56 +    Uri u = getCompleteUri("/events/" + 0 + "/" + "testm" + "/" + 3 + "/" + "testf");
    1.57 +    ContentValues v = new ContentValues();
    1.58 +    v.put("value", 5);
    1.59 +    ContentResolver r = getMockContentResolver();
    1.60 +    assertNotNull(r);
    1.61 +    try {
    1.62 +      r.insert(u, v);
    1.63 +      fail("Should throw.");
    1.64 +    } catch (IllegalStateException e) {
    1.65 +      assertTrue(e.getMessage().contains("No field with name testf"));
    1.66 +    }
    1.67 +  }
    1.68 +
    1.69 +  public void testEnsureMeasurements() {
    1.70 +    ensureMeasurementCount(0);
    1.71 +
    1.72 +    final MockContentResolver resolver = getMockContentResolver();
    1.73 +
    1.74 +    // Note that we insert no fields. These are empty measurements.
    1.75 +    ContentValues values = new ContentValues();
    1.76 +    resolver.insert(getCompleteUri("/fields/testm1/1"), values);
    1.77 +    ensureMeasurementCount(1);
    1.78 +
    1.79 +    resolver.insert(getCompleteUri("/fields/testm1/1"), values);
    1.80 +    ensureMeasurementCount(1);
    1.81 +
    1.82 +    resolver.insert(getCompleteUri("/fields/testm1/3"), values);
    1.83 +    ensureMeasurementCount(2);
    1.84 +
    1.85 +    resolver.insert(getCompleteUri("/fields/testm2/1"), values);
    1.86 +    ensureMeasurementCount(3);
    1.87 +
    1.88 +    Cursor cursor = resolver.query(getCompleteUri("/measurements/"), null, null, null, null);
    1.89 +
    1.90 +    assertTrue(cursor.moveToFirst());
    1.91 +    assertEquals("testm1", cursor.getString(1));    // 'id' is column 0.
    1.92 +    assertEquals(1,        cursor.getInt(2));
    1.93 +
    1.94 +    assertTrue(cursor.moveToNext());
    1.95 +    assertEquals("testm1", cursor.getString(1));
    1.96 +    assertEquals(3,        cursor.getInt(2));
    1.97 +
    1.98 +    assertTrue(cursor.moveToNext());
    1.99 +    assertEquals("testm2", cursor.getString(1));
   1.100 +    assertEquals(1,        cursor.getInt(2));
   1.101 +    assertFalse(cursor.moveToNext());
   1.102 +
   1.103 +    cursor.close();
   1.104 +
   1.105 +    resolver.delete(getCompleteUri("/measurements/"), null, null);
   1.106 +  }
   1.107 +
   1.108 +  /**
   1.109 +   * Return true if the two times occur on the same UTC day.
   1.110 +   */
   1.111 +  private static boolean sameDay(long start, long end) {
   1.112 +   return Math.floor(start / MILLISECONDS_PER_DAY) ==
   1.113 +          Math.floor(end / MILLISECONDS_PER_DAY);
   1.114 +  }
   1.115 +
   1.116 +  private static int getDay(long time) {
   1.117 +    return (int) Math.floor(time / MILLISECONDS_PER_DAY);
   1.118 +  }
   1.119 +
   1.120 +
   1.121 +  public void testRealData() {
   1.122 +    ensureMeasurementCount(0);
   1.123 +    long start = System.currentTimeMillis();
   1.124 +    int day = getDay(start);
   1.125 +
   1.126 +    final MockContentResolver resolver = getMockContentResolver();
   1.127 +
   1.128 +    // Register a provider with four fields.
   1.129 +    ContentValues values = new ContentValues();
   1.130 +    values.put("counter1", 1);
   1.131 +    values.put("counter2", 4);
   1.132 +    values.put("last1",    7);
   1.133 +    values.put("discrete1", 11);
   1.134 +
   1.135 +    resolver.insert(getCompleteUri("/fields/testm1/1"), values);
   1.136 +    ensureMeasurementCount(1);
   1.137 +    ensureFieldCount(4);
   1.138 +
   1.139 +    final Uri envURI = resolver.insert(getCompleteUri("/environments/"), getTestEnvContentValues());
   1.140 +    String envHash = null;
   1.141 +    Cursor envCursor = resolver.query(envURI, null, null, null, null);
   1.142 +    try {
   1.143 +      assertTrue(envCursor.moveToFirst());
   1.144 +      envHash = envCursor.getString(2);      // id, version, hash, ...
   1.145 +    } finally {
   1.146 +      envCursor.close();
   1.147 +    }
   1.148 +
   1.149 +    final Uri eventURI = HealthReportUtils.getEventURI(envURI);
   1.150 +
   1.151 +    Uri discrete1 = eventURI.buildUpon().appendEncodedPath("testm1/1/discrete1").build();
   1.152 +    Uri counter1 = eventURI.buildUpon().appendEncodedPath("testm1/1/counter1/counter").build();
   1.153 +    Uri counter2 = eventURI.buildUpon().appendEncodedPath("testm1/1/counter2/counter").build();
   1.154 +    Uri last1 = eventURI.buildUpon().appendEncodedPath("testm1/1/last1/last").build();
   1.155 +
   1.156 +    ContentValues discreteS = new ContentValues();
   1.157 +    ContentValues discreteI = new ContentValues();
   1.158 +
   1.159 +    discreteS.put("value", "Some string");
   1.160 +    discreteI.put("value", 9);
   1.161 +    resolver.insert(discrete1, discreteS);
   1.162 +    resolver.insert(discrete1, discreteI);
   1.163 +
   1.164 +    ContentValues counter = new ContentValues();
   1.165 +    resolver.update(counter1, counter, null, null);   // Defaults to 1.
   1.166 +    resolver.update(counter2, counter, null, null);   // Defaults to 1.
   1.167 +    counter.put("value", 3);
   1.168 +    resolver.update(counter2, counter, null, null);   // Increment by 3.
   1.169 +
   1.170 +    // Interleaving.
   1.171 +    discreteS.put("value", "Some other string");
   1.172 +    discreteI.put("value", 3);
   1.173 +    resolver.insert(discrete1, discreteS);
   1.174 +    resolver.insert(discrete1, discreteI);
   1.175 +
   1.176 +    // Note that we explicitly do not support last-values transitioning between types.
   1.177 +    ContentValues last = new ContentValues();
   1.178 +    last.put("value", 123);
   1.179 +    resolver.update(last1, last, null, null);
   1.180 +    last.put("value", 245);
   1.181 +    resolver.update(last1, last, null, null);
   1.182 +
   1.183 +    int expectedRows = 2 + 1 + 4;   // Two counters, one last, four entries for discrete.
   1.184 +
   1.185 +    // Now let's see what comes up in the query!
   1.186 +    // We'll do "named" first -- the results include strings.
   1.187 +    Cursor cursor = resolver.query(getCompleteUri("/events/?time=" + start), null, null, null, null);
   1.188 +    assertEquals(expectedRows, cursor.getCount());
   1.189 +    assertTrue(cursor.moveToFirst());
   1.190 +
   1.191 +    // Let's be safe in case someone runs this test at midnight.
   1.192 +    long end = System.currentTimeMillis();
   1.193 +    if (!sameDay(start, end)) {
   1.194 +      System.out.println("Aborting testAddData: spans midnight.");
   1.195 +      cursor.close();
   1.196 +      return;
   1.197 +    }
   1.198 +
   1.199 +    // "date", "env", m, mv, f, f_flags, "value"
   1.200 +    Object[][] expected = {
   1.201 +      {day, envHash, "testm1", 1, "counter1", null, 1},
   1.202 +      {day, envHash, "testm1", 1, "counter2", null, 4},
   1.203 +
   1.204 +      // Discrete values don't preserve order of insertion across types, but
   1.205 +      // this actually isn't really permitted -- fields have a single type.
   1.206 +      {day, envHash, "testm1", 1, "discrete1", null, 9},
   1.207 +      {day, envHash, "testm1", 1, "discrete1", null, 3},
   1.208 +      {day, envHash, "testm1", 1, "discrete1", null, "Some string"},
   1.209 +      {day, envHash, "testm1", 1, "discrete1", null, "Some other string"},
   1.210 +      {day, envHash, "testm1", 1, "last1", null, 245},
   1.211 +    };
   1.212 +
   1.213 +
   1.214 +    DBHelpers.assertCursorContains(expected, cursor);
   1.215 +    cursor.close();
   1.216 +
   1.217 +    resolver.delete(getCompleteUri("/measurements/"), null, null);
   1.218 +    ensureMeasurementCount(0);
   1.219 +    ensureFieldCount(0);
   1.220 +  }
   1.221 +
   1.222 +  private ContentValues getTestEnvContentValues() {
   1.223 +    ContentValues v = new ContentValues();
   1.224 +    v.put("profileCreation", 0);
   1.225 +    v.put("cpuCount", 0);
   1.226 +    v.put("memoryMB", 0);
   1.227 +
   1.228 +    v.put("isBlocklistEnabled", 0);
   1.229 +    v.put("isTelemetryEnabled", 0);
   1.230 +    v.put("extensionCount", 0);
   1.231 +    v.put("pluginCount", 0);
   1.232 +    v.put("themeCount", 0);
   1.233 +
   1.234 +    v.put("architecture", "");
   1.235 +    v.put("sysName", "");
   1.236 +    v.put("sysVersion", "");
   1.237 +    v.put("vendor", "");
   1.238 +    v.put("appName", "");
   1.239 +    v.put("appID", "");
   1.240 +    v.put("appVersion", "");
   1.241 +    v.put("appBuildID", "");
   1.242 +    v.put("platformVersion", "");
   1.243 +    v.put("platformBuildID", "");
   1.244 +    v.put("os", "");
   1.245 +    v.put("xpcomabi", "");
   1.246 +    v.put("updateChannel", "");
   1.247 +
   1.248 +    // v2.
   1.249 +    v.put("distribution", "");
   1.250 +    v.put("osLocale", "en_us");
   1.251 +    v.put("appLocale", "en_us");
   1.252 +    v.put("acceptLangSet", 0);
   1.253 +
   1.254 +    return v;
   1.255 +  }
   1.256 +}

mercurial