mobile/android/base/tests/testDistribution.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 package org.mozilla.gecko.tests;
     3 import java.io.File;
     4 import java.io.FileOutputStream;
     5 import java.io.InputStream;
     6 import java.io.OutputStream;
     8 import org.json.JSONArray;
     9 import org.json.JSONException;
    10 import org.json.JSONObject;
    11 import org.mozilla.gecko.Actions;
    12 import org.mozilla.gecko.Distribution;
    13 import org.mozilla.gecko.db.BrowserContract;
    14 import org.mozilla.gecko.util.ThreadUtils;
    16 import android.app.Activity;
    17 import android.content.SharedPreferences;
    19 /**
    20  * Tests distribution customization.
    21  * mock-package.zip should contain the following directory structure:
    22  *
    23  *   distribution/
    24  *     preferences.json
    25  *     bookmarks.json
    26  *     searchplugins/
    27  *       common/
    28  *         engine.xml
    29  */
    30 public class testDistribution extends ContentProviderTest {
    31     private static final String MOCK_PACKAGE = "mock-package.zip";
    32     private static final int PREF_REQUEST_ID = 0x7357;
    34     private Activity mActivity;
    36     /**
    37      * This is a hack.
    38      *
    39      * Startup results in us writing prefs -- we fetch the Distribution, which
    40      * caches its state. Our tests try to wipe those prefs, but apparently
    41      * sometimes race with startup, which leads to us not getting one of our
    42      * expected messages. The test fails.
    43      *
    44      * This hack waits for any existing background tasks -- such as the one that
    45      * writes prefs -- to finish before we begin the test.
    46      */
    47     private void waitForBackgroundHappiness() {
    48         final Object signal = new Object();
    49         final Runnable done = new Runnable() {
    50             @Override
    51             public void run() {
    52                 synchronized (signal) {
    53                     signal.notify();
    54                 }
    55             }
    56         };
    57         synchronized (signal) {
    58             ThreadUtils.postToBackgroundThread(done);
    59             try {
    60                 signal.wait();
    61             } catch (InterruptedException e) {
    62                 mAsserter.ok(false, "InterruptedException waiting on background thread.", e.toString());
    63             }
    64         }
    65         mAsserter.dumpLog("Background task completed. Proceeding.");
    66     }
    68     public void testDistribution() {
    69         mActivity = getActivity();
    71         String mockPackagePath = getMockPackagePath();
    73         // Wait for any startup-related background distribution shenanigans to
    74         // finish. This reduces the chance of us racing with startup pref writes.
    75         waitForBackgroundHappiness();
    77         // Pre-clear distribution pref, run basic preferences and en-US localized preferences Tests
    78         clearDistributionPref();
    79         setTestLocale("en-US");
    80         initDistribution(mockPackagePath);
    81         checkPreferences();
    82         checkLocalizedPreferences("en-US");
    83         checkSearchPlugin();
    85         // Pre-clear distribution pref, and run es-MX localized preferences Test
    86         clearDistributionPref();
    87         setTestLocale("es-MX");
    88         initDistribution(mockPackagePath);
    89         checkLocalizedPreferences("es-MX");
    90     }
    92     // Initialize the distribution from the mock package.
    93     private void initDistribution(String aPackagePath) {
    94         // Call Distribution.init with the mock package.
    95         Actions.EventExpecter distributionSetExpecter = mActions.expectGeckoEvent("Distribution:Set:OK");
    96         Distribution.init(mActivity, aPackagePath, "prefs-" + System.currentTimeMillis());
    97         distributionSetExpecter.blockForEvent();
    98         distributionSetExpecter.unregisterListener();
    99     }
   101     // Test distribution and preferences values stored in preferences.json
   102     private void checkPreferences() {
   103         String prefID = "distribution.id";
   104         String prefAbout = "distribution.about";
   105         String prefVersion = "distribution.version";
   106         String prefTestBoolean = "distribution.test.boolean";
   107         String prefTestString = "distribution.test.string";
   108         String prefTestInt = "distribution.test.int";
   110         try {
   111             final String[] prefNames = { prefID,
   112                                          prefAbout,
   113                                          prefVersion,
   114                                          prefTestBoolean,
   115                                          prefTestString,
   116                                          prefTestInt };
   118             Actions.RepeatedEventExpecter eventExpecter = mActions.expectGeckoEvent("Preferences:Data");
   119             mActions.sendPreferencesGetEvent(PREF_REQUEST_ID, prefNames);
   121             JSONObject data = null;
   122             int requestId = -1;
   124             // Wait until we get the correct "Preferences:Data" event
   125             while (requestId != PREF_REQUEST_ID) {
   126                 data = new JSONObject(eventExpecter.blockForEventData());
   127                 requestId = data.getInt("requestId");
   128             }
   129             eventExpecter.unregisterListener();
   131             JSONArray preferences = data.getJSONArray("preferences");
   132             for (int i = 0; i < preferences.length(); i++) {
   133                 JSONObject pref = (JSONObject) preferences.get(i);
   134                 String name = pref.getString("name");
   136                 if (name.equals(prefID)) {
   137                     mAsserter.is(pref.getString("value"), "test-partner", "check " + prefID);
   138                 } else if (name.equals(prefAbout)) {
   139                     mAsserter.is(pref.getString("value"), "Test Partner", "check " + prefAbout);
   140                 } else if (name.equals(prefVersion)) {
   141                     mAsserter.is(pref.getInt("value"), 1, "check " + prefVersion);
   142                 } else if (name.equals(prefTestBoolean)) {
   143                     mAsserter.is(pref.getBoolean("value"), true, "check " + prefTestBoolean);
   144                 } else if (name.equals(prefTestString)) {
   145                     mAsserter.is(pref.getString("value"), "test", "check " + prefTestString);
   146                 } else if (name.equals(prefTestInt)) {
   147                     mAsserter.is(pref.getInt("value"), 5, "check " + prefTestInt);
   148                 }
   149             }
   151         } catch (JSONException e) {
   152             mAsserter.ok(false, "exception getting preferences", e.toString());
   153         }
   154     }
   156     private void checkSearchPlugin() {
   157         Actions.RepeatedEventExpecter eventExpecter = mActions.expectGeckoEvent("SearchEngines:Data");
   158         mActions.sendGeckoEvent("SearchEngines:GetVisible", null);
   160         try {
   161             JSONObject data = new JSONObject(eventExpecter.blockForEventData());
   162             eventExpecter.unregisterListener();
   163             JSONArray searchEngines = data.getJSONArray("searchEngines");
   164             boolean foundEngine = false;
   165             for (int i = 0; i < searchEngines.length(); i++) {
   166                 JSONObject engine = (JSONObject) searchEngines.get(i);
   167                 String name = engine.getString("name");
   168                 if (name.equals("Test search engine")) {
   169                     foundEngine = true;
   170                     break;
   171                 }
   172             }
   173             mAsserter.ok(foundEngine, "check search plugin", "found test search plugin");
   174         } catch (JSONException e) {
   175             mAsserter.ok(false, "exception getting search plugins", e.toString());
   176         }
   177     }
   179     // Sets the distribution locale preference for the test
   180     private void setTestLocale(String aLocale) {
   181         String prefUseragentLocale = "general.useragent.locale";
   183         JSONObject jsonPref = new JSONObject();
   184         try {
   185             // Request the pref change to the locale.
   186             jsonPref.put("name", prefUseragentLocale);
   187             jsonPref.put("type", "string");
   188             jsonPref.put("value", aLocale);
   189             mActions.sendGeckoEvent("Preferences:Set", jsonPref.toString());
   191             // Wait for confirmation of the pref change.
   192             final String[] prefNames = { prefUseragentLocale };
   194             Actions.RepeatedEventExpecter eventExpecter = mActions.expectGeckoEvent("Preferences:Data");
   195             mActions.sendPreferencesGetEvent(PREF_REQUEST_ID, prefNames);
   197             JSONObject data = null;
   198             int requestId = -1;
   200             // Wait until we get the correct "Preferences:Data" event
   201             while (requestId != PREF_REQUEST_ID) {
   202                 data = new JSONObject(eventExpecter.blockForEventData());
   203                 requestId = data.getInt("requestId");
   204             }
   205             eventExpecter.unregisterListener();
   207         } catch (Exception e) {
   208             mAsserter.ok(false, "exception setting test locale", e.toString());
   209         }
   210     }
   212     // Test localized distribution and preferences values stored in preferences.json
   213     private void checkLocalizedPreferences(String aLocale) {
   214         String prefAbout = "distribution.about";
   215         String prefLocalizeable = "distribution.test.localizeable";
   216         String prefLocalizeableOverride = "distribution.test.localizeable-override";
   218         try {
   219             final String[] prefNames = { prefAbout, prefLocalizeable, prefLocalizeableOverride };
   221             Actions.RepeatedEventExpecter eventExpecter = mActions.expectGeckoEvent("Preferences:Data");
   222             mActions.sendPreferencesGetEvent(PREF_REQUEST_ID, prefNames);
   224             JSONObject data = null;
   225             int requestId = -1;
   227             // Wait until we get the correct "Preferences:Data" event
   228             while (requestId != PREF_REQUEST_ID) {
   229                 data = new JSONObject(eventExpecter.blockForEventData());
   230                 requestId = data.getInt("requestId");
   231             }
   232             eventExpecter.unregisterListener();
   234             JSONArray preferences = data.getJSONArray("preferences");
   235             for (int i = 0; i < preferences.length(); i++) {
   236                 JSONObject pref = (JSONObject) preferences.get(i);
   237                 String name = pref.getString("name");
   239                 if (name.equals(prefAbout)) {
   240                     if (aLocale.equals("en-US")) {
   241                         mAsserter.is(pref.getString("value"), "Test Partner", "check " + prefAbout);
   242                     } else if (aLocale.equals("es-MX")) {
   243                         mAsserter.is(pref.getString("value"), "Afiliado de Prueba", "check " + prefAbout);
   244                     }
   245                 } else if (name.equals(prefLocalizeable)) {
   246                     if (aLocale.equals("en-US")) {
   247                         mAsserter.is(pref.getString("value"), "http://test.org/en-US/en-US/", "check " + prefLocalizeable);
   248                     } else if (aLocale.equals("es-MX")) {
   249                         mAsserter.is(pref.getString("value"), "http://test.org/es-MX/es-MX/", "check " + prefLocalizeable);
   250                     }
   251                 } else if (name.equals(prefLocalizeableOverride)) {
   252                     if (aLocale.equals("en-US")) {
   253                         mAsserter.is(pref.getString("value"), "http://cheese.com", "check " + prefLocalizeableOverride);
   254                     } else if (aLocale.equals("es-MX")) {
   255                         mAsserter.is(pref.getString("value"), "http://test.org/es-MX/", "check " + prefLocalizeableOverride);
   256                     }
   257                 }
   258             }
   260         } catch (JSONException e) {
   261             mAsserter.ok(false, "exception getting preferences", e.toString());
   262         }
   263     }
   265     // Copies the mock package to the data directory and returns the file path to it.
   266     private String getMockPackagePath() {
   267         String mockPackagePath = "";
   269         try {
   270             InputStream inStream = getAsset(MOCK_PACKAGE);
   271             File dataDir = new File(mActivity.getApplicationInfo().dataDir);
   272             File outFile = new File(dataDir, MOCK_PACKAGE);
   274             OutputStream outStream = new FileOutputStream(outFile);
   275             int b;
   276             while ((b = inStream.read()) != -1) {
   277                 outStream.write(b);
   278             }
   279             inStream.close();
   280             outStream.close();
   282             mockPackagePath = outFile.getPath();
   284         } catch (Exception e) {
   285             mAsserter.ok(false, "exception copying mock distribution package to data directory", e.toString());
   286         }
   288         return mockPackagePath;
   289     }
   291     // Clears the distribution pref to return distribution state to STATE_UNKNOWN
   292     private void clearDistributionPref() {
   293         mAsserter.dumpLog("Clearing distribution pref.");
   294         SharedPreferences settings = mActivity.getSharedPreferences("GeckoApp", Activity.MODE_PRIVATE);
   295         String keyName = mActivity.getPackageName() + ".distribution_state";
   296         settings.edit().remove(keyName).commit();
   297     }
   299     @Override
   300     public void setUp() throws Exception {
   301         // TODO: Set up the content provider after setting the distribution.
   302         super.setUp(sBrowserProviderCallable, BrowserContract.AUTHORITY, "browser.db");
   303     }
   305     private void delete(File file) throws Exception {
   306       if (file.isDirectory()) {
   307         File[] files = file.listFiles();
   308         for (File f : files) {
   309           delete(f);
   310         }
   311       }
   312       mAsserter.ok(file.delete(), "clean up distribution files", "deleted " + file.getPath());
   313     }
   315     @Override
   316     public void tearDown() throws Exception {
   317         File dataDir = new File(mActivity.getApplicationInfo().dataDir);
   319         // Delete mock package from data directory.
   320         File mockPackage = new File(dataDir, MOCK_PACKAGE);
   321         mAsserter.ok(mockPackage.delete(), "clean up mock package", "deleted " + mockPackage.getPath());
   323         // Recursively delete distribution files that Distribution.init copied to data directory.
   324         File distDir = new File(dataDir, "distribution");
   325         delete(distDir);
   327         clearDistributionPref();
   329         super.tearDown();
   330     }
   331 }

mercurial