private File createDistSuggestedSitesFile(int n) {
    FileOutputStream fos = null;

    try {
      File distFile = File.createTempFile("distrosites", ".json", context.getCacheDir());

      fos = new FileOutputStream(distFile);
      fos.write(generateSites(n, DIST_PREFIX).getBytes());

      return distFile;
    } catch (IOException e) {
      fail("Failed to create temp suggested sites file");
    } finally {
      if (fos != null) {
        try {
          fos.close();
        } catch (IOException e) {
          // Ignore.
        }
      }
    }

    return null;
  }
  public void testDistribution() {
    final int DIST_COUNT = 2;
    final int DEFAULT_COUNT = 3;

    File sitesFile =
        new File(context.getCacheDir(), "suggestedsites-" + SystemClock.uptimeMillis() + ".json");
    tempFiles.add(sitesFile);
    assertFalse(sitesFile.exists());

    File distFile = createDistSuggestedSitesFile(DIST_COUNT);
    tempFiles.add(distFile);
    assertTrue(distFile.exists());

    // Init distribution with the mock file.
    TestDistribution distribution = new TestDistribution(context);
    distribution.setFileForLocale(Locale.getDefault(), distFile);
    distribution.start();

    // Init suggested sites with default values.
    resources.setSuggestedSitesResource(generateSites(DEFAULT_COUNT));
    SuggestedSites suggestedSites = new SuggestedSites(context, distribution, sitesFile);

    Object changeLock = new Object();

    // Watch for change notifications on suggested sites.
    ContentResolver cr = context.getContentResolver();
    ContentObserver observer = new TestObserver(changeLock);
    cr.registerContentObserver(BrowserContract.SuggestedSites.CONTENT_URI, false, observer);

    // The initial query will not contain the distribution sites
    // yet. This will happen asynchronously once the distribution
    // is installed.
    Cursor c1 = null;
    try {
      c1 = suggestedSites.get(DEFAULT_LIMIT);
      assertEquals(DEFAULT_COUNT, c1.getCount());
    } finally {
      if (c1 != null) {
        c1.close();
      }
    }

    synchronized (changeLock) {
      try {
        changeLock.wait(5000);
      } catch (InterruptedException ie) {
        fail("No change notification after fetching distribution file");
      }
    }

    // Target file should exist after distribution is deployed.
    assertTrue(sitesFile.exists());
    cr.unregisterContentObserver(observer);

    Cursor c2 = null;
    try {
      c2 = suggestedSites.get(DEFAULT_LIMIT);

      // The next query should contain the distribution contents.
      assertEquals(DIST_COUNT + DEFAULT_COUNT, c2.getCount());

      // The first items should be from the distribution
      for (int i = 0; i < DIST_COUNT; i++) {
        c2.moveToPosition(i);

        String url = c2.getString(c2.getColumnIndexOrThrow(BrowserContract.SuggestedSites.URL));
        assertEquals(DIST_PREFIX + "url" + i, url);

        String title = c2.getString(c2.getColumnIndexOrThrow(BrowserContract.SuggestedSites.TITLE));
        assertEquals(DIST_PREFIX + "title" + i, title);
      }

      // The remaining items should be the default ones
      for (int i = 0; i < c2.getCount() - DIST_COUNT; i++) {
        c2.moveToPosition(i + DIST_COUNT);

        String url = c2.getString(c2.getColumnIndexOrThrow(BrowserContract.SuggestedSites.URL));
        assertEquals("url" + i, url);

        String title = c2.getString(c2.getColumnIndexOrThrow(BrowserContract.SuggestedSites.TITLE));
        assertEquals("title" + i, title);
      }
    } finally {
      if (c2 != null) {
        c2.close();
      }
    }
  }