fune/toolkit/components/url-classifier/tests/unit/test_hashcompleter_v4.js
Francois Marier 251bca17ba Bug 1452445 - Fix update error observer in unit test. r=gcp
We should only observe for update errors while we are expecting
a successful update.

MozReview-Commit-ID: 3grGhmxqhIX

--HG--
extra : rebase_source : d099b83560ac5ec15b18fb69177368a645b63952
2018-05-29 18:06:49 -07:00

245 lines
9.5 KiB
JavaScript

ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
// These tables have a different update URL (for v4).
const TEST_TABLE_DATA_V4 = {
tableName: "test-phish-proto",
providerName: "google4",
updateUrl: "http://localhost:5555/safebrowsing/update?",
gethashUrl: "http://localhost:5555/safebrowsing/gethash-v4?",
};
const PREF_NEXTUPDATETIME_V4 = "browser.safebrowsing.provider.google4.nextupdatetime";
const GETHASH_PATH = "/safebrowsing/gethash-v4";
// The protobuf binary represention of gethash response:
// minimumWaitDuration : 12 secs 10 nanosecs
// negativeCacheDuration : 120 secs 9 nanosecs
//
// { CompleteHash, ThreatType, CacheDuration { secs, nanos } };
// { nsCString("01234567890123456789012345678901"), SOCIAL_ENGINEERING_PUBLIC, { 8, 500 } },
// { nsCString("12345678901234567890123456789012"), SOCIAL_ENGINEERING_PUBLIC, { 7, 100} },
// { nsCString("23456789012345678901234567890123"), SOCIAL_ENGINEERING_PUBLIC, { 1, 20 } },
const GETHASH_RESPONSE_CONTENT = "\x0A\x2D\x08\x02\x1A\x22\x0A\x20\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x2A\x05\x08\x08\x10\xF4\x03\x0A\x2C\x08\x02\x1A\x22\x0A\x20\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x2A\x04\x08\x07\x10\x64\x0A\x2C\x08\x02\x1A\x22\x0A\x20\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x2A\x04\x08\x01\x10\x14\x12\x04\x08\x0C\x10\x0A\x1A\x04\x08\x78\x10\x09";
// The protobuf binary represention of update response:
//
// [
// {
// 'threat_type': 2, // SOCIAL_ENGINEERING_PUBLIC
// 'response_type': 2, // FULL_UPDATE
// 'new_client_state': 'sta\x00te', // NEW_CLIENT_STATE
// 'checksum': { "sha256": CHECKSUM }, // CHECKSUM
// 'additions': { 'compression_type': RAW,
// 'prefix_size': 4,
// 'raw_hashes': "00000001000000020000000300000004"}
// }
// ]
//
const UPDATE_RESPONSE_CONTENT = "\x0A\x4A\x08\x02\x20\x02\x2A\x18\x08\x01\x12\x14\x08\x04\x12\x10\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x3A\x06\x73\x74\x61\x00\x74\x65\x42\x22\x0A\x20\x30\x67\xC7\x2C\x5E\x50\x1C\x31\xE3\xFE\xCA\x73\xF0\x47\xDC\x34\x1A\x95\x63\x99\xEC\x70\x5E\x0A\xEE\x9E\xFB\x17\xA1\x55\x35\x78\x12\x08\x08\x08\x10\x80\x94\xEB\xDC\x03";
const UPDATE_PATH = "/safebrowsing/update";
let gListManager = Cc["@mozilla.org/url-classifier/listmanager;1"]
.getService(Ci.nsIUrlListManager);
let gCompleter = Cc["@mozilla.org/url-classifier/hashcompleter;1"]
.getService(Ci.nsIUrlClassifierHashCompleter);
XPCOMUtils.defineLazyServiceGetter(this, "gUrlUtil",
"@mozilla.org/url-classifier/utils;1",
"nsIUrlClassifierUtils");
// Handles request for TEST_TABLE_DATA_V4.
let gHttpServV4 = null;
const NEW_CLIENT_STATE = "sta\0te";
const CHECKSUM = "\x30\x67\xc7\x2c\x5e\x50\x1c\x31\xe3\xfe\xca\x73\xf0\x47\xdc\x34\x1a\x95\x63\x99\xec\x70\x5e\x0a\xee\x9e\xfb\x17\xa1\x55\x35\x78";
Services.prefs.setBoolPref("browser.safebrowsing.debug", true);
// The "\xFF\xFF" is to generate a base64 string with "/".
Services.prefs.setCharPref("browser.safebrowsing.id", "Firefox\xFF\xFF");
// Register tables.
gListManager.registerTable(TEST_TABLE_DATA_V4.tableName,
TEST_TABLE_DATA_V4.providerName,
TEST_TABLE_DATA_V4.updateUrl,
TEST_TABLE_DATA_V4.gethashUrl);
// This is unfortunately needed since v4 gethash request
// requires the threat type (table name) as well as the
// state it's associated with. We have to run the update once
// to have the state written.
add_test(function test_update_v4() {
gListManager.disableUpdate(TEST_TABLE_DATA_V4.tableName);
gListManager.enableUpdate(TEST_TABLE_DATA_V4.tableName);
// Force table update.
Services.prefs.setCharPref(PREF_NEXTUPDATETIME_V4, "1");
gListManager.maybeToggleUpdateChecking();
});
add_test(function test_getHashRequestV4() {
let request = gUrlUtil.makeFindFullHashRequestV4([TEST_TABLE_DATA_V4.tableName],
[btoa(NEW_CLIENT_STATE)],
[btoa("0123"), btoa("1234567"), btoa("1111")].sort(),
1,
3);
registerHandlerGethashV4("&$req=" + request);
let completeFinishedCnt = 0;
gCompleter.complete("0123", TEST_TABLE_DATA_V4.gethashUrl, TEST_TABLE_DATA_V4.tableName, {
completionV4(hash, table, duration, fullhashes) {
equal(hash, "0123");
equal(table, TEST_TABLE_DATA_V4.tableName);
equal(duration, 120);
equal(fullhashes.length, 1);
let match = fullhashes.QueryInterface(Ci.nsIArray)
.queryElementAt(0, Ci.nsIFullHashMatch);
equal(match.fullHash, "01234567890123456789012345678901");
equal(match.cacheDuration, 8);
info("completion: " + match.fullHash + ", " + table);
},
completionFinished(status) {
equal(status, Cr.NS_OK);
completeFinishedCnt++;
if (3 === completeFinishedCnt) {
run_next_test();
}
},
});
gCompleter.complete("1234567", TEST_TABLE_DATA_V4.gethashUrl, TEST_TABLE_DATA_V4.tableName, {
completionV4(hash, table, duration, fullhashes) {
equal(hash, "1234567");
equal(table, TEST_TABLE_DATA_V4.tableName);
equal(duration, 120);
equal(fullhashes.length, 1);
let match = fullhashes.QueryInterface(Ci.nsIArray)
.queryElementAt(0, Ci.nsIFullHashMatch);
equal(match.fullHash, "12345678901234567890123456789012");
equal(match.cacheDuration, 7);
info("completion: " + match.fullHash + ", " + table);
},
completionFinished(status) {
equal(status, Cr.NS_OK);
completeFinishedCnt++;
if (3 === completeFinishedCnt) {
run_next_test();
}
},
});
gCompleter.complete("1111", TEST_TABLE_DATA_V4.gethashUrl, TEST_TABLE_DATA_V4.tableName, {
completionV4(hash, table, duration, fullhashes) {
equal(hash, "1111");
equal(table, TEST_TABLE_DATA_V4.tableName);
equal(duration, 120);
equal(fullhashes.length, 0);
},
completionFinished(status) {
equal(status, Cr.NS_OK);
completeFinishedCnt++;
if (3 === completeFinishedCnt) {
run_next_test();
}
},
});
});
add_test(function test_minWaitDuration() {
let failedComplete = function() {
gCompleter.complete("0123", TEST_TABLE_DATA_V4.gethashUrl, TEST_TABLE_DATA_V4.tableName, {
completionFinished(status) {
equal(status, Cr.NS_ERROR_ABORT);
},
});
};
let successComplete = function() {
gCompleter.complete("1234567", TEST_TABLE_DATA_V4.gethashUrl, TEST_TABLE_DATA_V4.tableName, {
completionV4(hash, table, duration, fullhashes) {
equal(hash, "1234567");
equal(table, TEST_TABLE_DATA_V4.tableName);
equal(fullhashes.length, 1);
let match = fullhashes.QueryInterface(Ci.nsIArray)
.queryElementAt(0, Ci.nsIFullHashMatch);
equal(match.fullHash, "12345678901234567890123456789012");
equal(match.cacheDuration, 7);
info("completion: " + match.fullHash + ", " + table);
},
completionFinished(status) {
equal(status, Cr.NS_OK);
run_next_test();
},
});
};
let request = gUrlUtil.makeFindFullHashRequestV4([TEST_TABLE_DATA_V4.tableName],
[btoa(NEW_CLIENT_STATE)],
[btoa("1234567")],
1,
1);
registerHandlerGethashV4("&$req=" + request);
// The last gethash response contained a min wait duration 12 secs 10 nano
// So subsequent requests can happen only after the min wait duration
do_timeout(1000, failedComplete);
do_timeout(2000, failedComplete);
do_timeout(4000, failedComplete);
do_timeout(13000, successComplete);
});
function registerHandlerGethashV4(aExpectedQuery) {
gHttpServV4.registerPathHandler(GETHASH_PATH, null);
// V4 gethash handler.
gHttpServV4.registerPathHandler(GETHASH_PATH, function(request, response) {
equal(request.queryString, aExpectedQuery);
response.setStatusLine(request.httpVersion, 200, "OK");
response.bodyOutputStream.write(GETHASH_RESPONSE_CONTENT,
GETHASH_RESPONSE_CONTENT.length);
});
}
function registerHandlerUpdateV4() {
// Update handler. Will respond a valid state to be verified in the
// gethash handler.
gHttpServV4.registerPathHandler(UPDATE_PATH, function(request, response) {
response.setHeader("Content-Type",
"application/vnd.google.safebrowsing-update", false);
response.setStatusLine(request.httpVersion, 200, "OK");
response.bodyOutputStream.write(UPDATE_RESPONSE_CONTENT,
UPDATE_RESPONSE_CONTENT.length);
waitUntilMetaDataSaved(NEW_CLIENT_STATE, CHECKSUM, () => {
run_next_test();
});
});
}
function run_test() {
throwOnUpdateErrors();
gHttpServV4 = new HttpServer();
gHttpServV4.registerDirectory("/", do_get_cwd());
registerHandlerUpdateV4();
gHttpServV4.start(5555);
run_next_test();
}
registerCleanupFunction(function() {
stopThrowingOnUpdateErrors();
});