mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 12:50:09 +00:00
Bug 1261494 - Block Gecko from screwing with the client ID file by resetting the cache at the last minute. r=grisha
MozReview-Commit-ID: EZYrk8IiRiF --HG-- extra : rebase_source : 420c4e802c6d234a594b9f17670791e0029e237e
This commit is contained in:
parent
a957702d89
commit
db493df167
@ -35,46 +35,57 @@ public class testUnifiedTelemetryClientId extends JavascriptBridgeTest {
|
||||
getFHRClientIdFile(),
|
||||
getFHRClientIdParentDir(),
|
||||
};
|
||||
|
||||
// In local testing, it's possible to ^C out of the harness and not have tearDown called,
|
||||
// hence reset. We can't clear the cache because Gecko is not running yet.
|
||||
resetTest(false);
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
// Don't clear cache because who knows what state Gecko is in.
|
||||
resetTest(false);
|
||||
deleteClientIDFiles();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
private void resetTest(final boolean resetJSCache) {
|
||||
Log.d(LOGTAG, "resetTest: begin");
|
||||
private void deleteClientIDFiles() {
|
||||
Log.d(LOGTAG, "deleteClientIDFiles: begin");
|
||||
|
||||
if (resetJSCache) {
|
||||
resetJSCache();
|
||||
}
|
||||
for (final File file : filesToDeleteOnReset) {
|
||||
file.delete();
|
||||
file.delete(); // can't check return value because the file may not exist before deletion.
|
||||
fAssertFalse("Deleted file in reset does not exist", file.exists()); // sanity check.
|
||||
}
|
||||
|
||||
Log.d(LOGTAG, "resetTest: end");
|
||||
Log.d(LOGTAG, "deleteClientIDFiles: end");
|
||||
}
|
||||
|
||||
public void testUnifiedTelemetryClientId() throws Exception {
|
||||
blockForReadyAndLoadJS(TEST_JS);
|
||||
resetJSCache(); // Must be called after Gecko is loaded.
|
||||
fAssertTrue("Profile directory exists", profileDir.exists());
|
||||
|
||||
// Important note: we cannot stop Gecko from running while we run this test and
|
||||
// Gecko is capable of creating client ID files while we run this test. However,
|
||||
// ClientID.jsm will not touch modify the client ID files on disk if its client
|
||||
// ID cache is filled. As such, we prevent it from touching the disk by intentionally
|
||||
// priming the cache & deleting the files it added now, and resetting the cache at the
|
||||
// latest possible moment before we attempt to test the client ID file.
|
||||
//
|
||||
// This is fragile because it relies on the ClientID cache's implementation, however,
|
||||
// some alternatives (e.g. changing file system permissions, file locking) are worse
|
||||
// because they can fire error handling code, which is not currently under test.
|
||||
//
|
||||
// First, we delete the test files - we don't want the cache prime to fail which could happen if
|
||||
// these files are around & corrupted from a previous test/install. Then we prime the cache,
|
||||
// and delete the files the cache priming added, so the tests are ready to add their own version
|
||||
// of these files.
|
||||
deleteClientIDFiles();
|
||||
primeJsClientIdCache();
|
||||
deleteClientIDFiles();
|
||||
|
||||
// TODO: If these tests weren't so expensive to run in automation,
|
||||
// this should be two separate tests to avoid storing state between tests.
|
||||
testJavaCreatesClientId();
|
||||
resetTest(true);
|
||||
testJsCreatesClientId();
|
||||
resetTest(true);
|
||||
testJavaMigratesFromHealthReport();
|
||||
resetTest(true);
|
||||
testJsMigratesFromHealthReport();
|
||||
testJavaCreatesClientId(); // leaves cache filled.
|
||||
deleteClientIDFiles();
|
||||
testJsCreatesClientId(); // leaves cache filled.
|
||||
deleteClientIDFiles();
|
||||
testJavaMigratesFromHealthReport(); // leaves cache filled.
|
||||
deleteClientIDFiles();
|
||||
testJsMigratesFromHealthReport(); // leaves cache filled.
|
||||
|
||||
getJS().syncCall("endTest");
|
||||
}
|
||||
@ -92,6 +103,7 @@ public class testUnifiedTelemetryClientId extends JavascriptBridgeTest {
|
||||
fAssertFalse("Client id file does not exist yet", getClientIdFile().exists());
|
||||
|
||||
final String clientIdFromJava = getClientIdFromJava();
|
||||
resetJSCache();
|
||||
final String clientIdFromJS = getClientIdFromJS();
|
||||
fAssertEquals("Client ID from Java equals ID from JS", clientIdFromJava, clientIdFromJS);
|
||||
|
||||
@ -116,6 +128,7 @@ public class testUnifiedTelemetryClientId extends JavascriptBridgeTest {
|
||||
|
||||
fAssertFalse("Client id file does not exist yet", getClientIdFile().exists());
|
||||
|
||||
resetJSCache();
|
||||
final String clientIdFromJS = getClientIdFromJS();
|
||||
final String clientIdFromJava = getClientIdFromJava();
|
||||
fAssertEquals("Client ID from JS equals ID from Java", clientIdFromJS, clientIdFromJava);
|
||||
@ -148,6 +161,7 @@ public class testUnifiedTelemetryClientId extends JavascriptBridgeTest {
|
||||
|
||||
final String clientIdFromJava = getClientIdFromJava();
|
||||
fAssertEquals("Health report client ID merged by Java", expectedClientId, clientIdFromJava);
|
||||
resetJSCache();
|
||||
final String clientIdFromJS = getClientIdFromJS();
|
||||
fAssertEquals("Merged client ID read by JS", expectedClientId, clientIdFromJS);
|
||||
|
||||
@ -177,6 +191,7 @@ public class testUnifiedTelemetryClientId extends JavascriptBridgeTest {
|
||||
final String expectedClientId = UUID.randomUUID().toString();
|
||||
createFHRClientIdFile(expectedClientId);
|
||||
|
||||
resetJSCache();
|
||||
final String clientIdFromJS = getClientIdFromJS();
|
||||
fAssertEquals("Health report client ID merged by JS", expectedClientId, clientIdFromJS);
|
||||
final String clientIdFromJava = getClientIdFromJava();
|
||||
@ -204,9 +219,20 @@ public class testUnifiedTelemetryClientId extends JavascriptBridgeTest {
|
||||
return getBlockingFromJsString("clientId");
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be called after Gecko is loaded.
|
||||
*/
|
||||
private void primeJsClientIdCache() {
|
||||
// Not the cleanest way, but it works.
|
||||
getClientIdFromJS();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the client ID cache in ClientID.jsm. This method *must* be called after
|
||||
* Gecko is loaded or else this method will hang.
|
||||
*
|
||||
* Note: we do this for very specific reasons - see the comment in the test method
|
||||
* ({@link #testUnifiedTelemetryClientId()}) for more.
|
||||
*/
|
||||
private void resetJSCache() {
|
||||
// HACK: the backing JS method is a promise with no return value. Rather than writing a method
|
||||
|
Loading…
x
Reference in New Issue
Block a user