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.

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

mercurial