diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b953387ad37..fc5477ad9de 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -103,8 +103,7 @@ patches/*.java.patch @samartnik third_party/bitcoin-core/BUILD.gn @orspetol # Network auditor -build/commands/lib/whitelistedUrlPatterns.js @brave/sec-team -build/commands/lib/whitelistedUrlPrefixes.js @brave/sec-team +browser/net/brave_network_audit_whitelists.h @brave/sec-team # iOS ios/ @brave/ios diff --git a/BUILD.gn b/BUILD.gn index 2128203690f..2e587ee4bc6 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -159,7 +159,10 @@ if (!is_ios) { deps = [ "test:brave_unit_tests" ] if (!is_android) { - deps += [ "test:brave_browser_tests" ] + deps += [ + "test:brave_browser_tests", + "test:brave_network_audit_tests", + ] } } } diff --git a/browser/net/brave_network_audit_browsertest.cc b/browser/net/brave_network_audit_browsertest.cc new file mode 100644 index 00000000000..b40911a661c --- /dev/null +++ b/browser/net/brave_network_audit_browsertest.cc @@ -0,0 +1,286 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/base_paths.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/json/json_file_value_serializer.h" +#include "base/json/json_reader.h" +#include "base/path_service.h" +#include "base/run_loop.h" +#include "base/test/bind.h" +#include "base/test/test_timeouts.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "brave/browser/brave_rewards/rewards_service_factory.h" +#include "brave/browser/net/brave_network_audit_whitelists.h" +#include "brave/components/brave_rewards/browser/rewards_service_impl.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/prefs/pref_service.h" +#include "content/public/test/browser_test.h" +#include "services/network/public/cpp/network_switches.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "third_party/re2/src/re2/re2.h" + +namespace brave { +namespace { + +// Max amount of time to wait after getting an URL loaded, in milliseconds. Note +// that the value passed to --ui-test-action-timeout in //brave/package.json, as +// part of the 'network-audit' script, must be big enough to accomodate this. +// +// In particular: +// --ui-test-action-timeout: should be greater than |kMaxTimeoutPerLoadedURL|. +// --test-launcher-timeout: should be able to fit the total sum of timeouts. +const int kMaxTimeoutPerLoadedURL = 300000; + +// Based on the implementation of isPrivateIP() from NPM's "ip" module. +// See https://github.com/indutny/node-ip/blob/master/lib/ip.js +constexpr const char* kPrivateIPRegexps[] = { + "(::f{4}:)?10\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})", + "(::f{4}:)?192\\.168\\.([0-9]{1,3})\\.([0-9]{1,3})", + "(::f{4}:)?172\\.(1[6-9]|2\\d|30|31)\\.([0-9]{1,3})\\.([0-9]{1,3})", + "(::f{4}:)?127\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})", + "(::f{4}:)?169\\.254\\.([0-9]{1,3})\\.([0-9]{1,3})", + "f[cd][0-9a-f]{2}:.*", + "fe80:.*", + "::1", + "::"}; + +void WaitForTimeout(int timeout) { + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), + base::TimeDelta::FromMilliseconds(timeout)); + run_loop.Run(); +} + +bool isPrivateURL(const GURL& url) { + for (const char* regexp : kPrivateIPRegexps) { + if (RE2::FullMatch(url.host(), regexp)) { + return true; + } + } + return false; +} + +bool PerformNetworkAuditProcess(base::Value* events) { + DCHECK(events && events->is_list()); + + bool failed = false; + events->EraseListValueIf([&failed](base::Value& event_value) { + base::DictionaryValue* event_dict; + EXPECT_TRUE(event_value.GetAsDictionary(&event_dict)); + + absl::optional event_type = event_dict->FindIntPath("type"); + EXPECT_TRUE(event_type.has_value()); + + // Showing these helps determine which URL requests which don't + // actually hit the network. + if (static_cast(event_type.value()) == + net::NetLogEventType::URL_REQUEST_FAKE_RESPONSE_HEADERS_CREATED) { + return false; + } + + const base::Value* source_dict = event_dict->FindDictPath("source"); + EXPECT_TRUE(source_dict); + + // Consider URL requests only. + absl::optional source_type = source_dict->FindIntPath("type"); + EXPECT_TRUE(source_type.has_value()); + + if (static_cast(source_type.value()) != + net::NetLogSourceType::URL_REQUEST) { + return true; + } + + // Discard events without URLs in the parameters. + if (!event_dict->FindKey("params")) + return true; + + const base::Value* params_dict2 = event_dict->FindDictPath("params"); + EXPECT_TRUE(params_dict2); + + if (!params_dict2->FindKey("url")) + return true; + + const std::string* url_str = params_dict2->FindStringPath("url"); + EXPECT_TRUE(url_str); + + GURL url(*url_str); + EXPECT_TRUE(url.is_valid()); + + if (RE2::FullMatch(url.host(), "[a-z]+")) { + // Chromium sometimes sends requests to random non-resolvable hosts. + return true; + } + + for (const char* protocol : kWhitelistedUrlProtocols) { + if (protocol == url.scheme()) { + return true; + } + } + + bool found_prefix = false; + for (const char* prefix : kWhitelistedUrlPrefixes) { + if (!url.spec().rfind(prefix, 0)) { + found_prefix = true; + break; + } + } + + bool found_pattern = false; + for (const char* pattern : kWhitelistedUrlPatterns) { + if (RE2::FullMatch(url.spec(), pattern)) { + found_pattern = true; + break; + } + } + + if (!found_prefix && !found_pattern) { + // Check if the URL is a private IP. + if (isPrivateURL(url)) { + // Warn but don't fail the audit. + LOG(WARNING) << "NETWORK AUDIT WARNING:" << url.spec() << std::endl; + return false; + } + + LOG(ERROR) << "NETWORK AUDIT FAIL:" << url.spec() << std::endl; + failed = true; + } + + return false; + }); + + return !failed; +} + +void WriteNetworkAuditResultsToDisk(const base::DictionaryValue& results_dic, + const base::FilePath& path) { + std::string results; + JSONFileValueSerializer serializer(path); + serializer.Serialize(results_dic); + + LOG(INFO) << "Network audit results stored in " << path << std::endl; +} + +class BraveNetworkAuditTest : public InProcessBrowserTest { + public: + BraveNetworkAuditTest() = default; + + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + + ASSERT_TRUE(embedded_test_server()->Start()); + + // Create and start the Rewards service + rewards_service_ = static_cast( + brave_rewards::RewardsServiceFactory::GetForProfile(profile())); + base::RunLoop run_loop; + rewards_service_->StartProcess(run_loop.QuitClosure()); + run_loop.Run(); + } + + void TearDownOnMainThread() override { + rewards_service_->Shutdown(); + InProcessBrowserTest::TearDownOnMainThread(); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + base::FilePath source_root_path; + base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root_path); + + // Full log containing all the network requests. + net_log_path_ = source_root_path.AppendASCII("network_log.json"); + + // Log containing the results of the audit only. + audit_results_path_ = + source_root_path.AppendASCII("network_audit_results.json"); + + command_line->AppendSwitchPath(network::switches::kLogNetLog, + net_log_path_); + command_line->AppendSwitchASCII(network::switches::kNetLogCaptureMode, + "Everything"); + } + + void TearDownInProcessBrowserTestFixture() override { + VerifyNetworkAuditLog(); + } + + bool EnableBraveRewards() { + PrefService* pref_service = profile()->GetPrefs(); + pref_service->SetInteger("brave.rewards.version", 7); + pref_service->SetBoolean("brave.rewards.enabled", true); + return pref_service->GetBoolean("brave.rewards.enabled"); + } + + Profile* profile() { return browser()->profile(); } + + private: + // Verify that the netlog file was written, appears to be well formed, and + // includes the requested level of data. + void VerifyNetworkAuditLog() { + // Read the netlog from disk. + std::string file_contents; + ASSERT_TRUE(base::ReadFileToString(net_log_path_, &file_contents)) + << "Could not read: " << net_log_path_; + + // Parse it as JSON. + auto parsed = base::JSONReader::Read(file_contents); + ASSERT_TRUE(parsed.has_value()); + + // Ensure the root value is a dictionary. + base::DictionaryValue* main; + ASSERT_TRUE(parsed->GetAsDictionary(&main)); + + // Ensure it has a "constants" property. + base::Value* constants = main->FindDictPath("constants"); + ASSERT_TRUE(constants && constants->is_dict()); + ASSERT_FALSE(constants->DictEmpty()); + + // Ensure it has an "events" property. + base::Value* events = main->FindListPath("events"); + ASSERT_TRUE(events && events->is_list()); + ASSERT_FALSE(events->GetList().empty()); + + EXPECT_TRUE(PerformNetworkAuditProcess(events)) + << "network-audit FAILED. Import " << net_log_path_.AsUTF8Unsafe() + << " in chrome://net-internals for more details."; + + // Write results of the audit to disk, useful for further debugging. + WriteNetworkAuditResultsToDisk(*main, audit_results_path_); + ASSERT_TRUE(base::PathExists(audit_results_path_)); + } + + brave_rewards::RewardsServiceImpl* rewards_service_; + base::FilePath net_log_path_; + base::FilePath audit_results_path_; + + DISALLOW_COPY_AND_ASSIGN(BraveNetworkAuditTest); +}; + +// Loads brave://welcome first to simulate a first run and then loads another +// URL, and finally enables brave rewards, waiting some time after each load to +// allow gathering network requests. +IN_PROC_BROWSER_TEST_F(BraveNetworkAuditTest, BasicTests) { + // Load the Welcome page. + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("brave://welcome"))); + WaitForTimeout(kMaxTimeoutPerLoadedURL); + + // Load a simple HTML page from the test server. + GURL simple_url(embedded_test_server()->GetURL("/simple.html")); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), simple_url)); + WaitForTimeout(kMaxTimeoutPerLoadedURL); + + // Finally, load brave://rewards and enable Brave Rewards. + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("brave://rewards"))); + ASSERT_TRUE(EnableBraveRewards()); + WaitForTimeout(kMaxTimeoutPerLoadedURL); +} + +} // namespace +} // namespace brave diff --git a/browser/net/brave_network_audit_whitelists.h b/browser/net/brave_network_audit_whitelists.h new file mode 100644 index 00000000000..b8e3f2b8ec7 --- /dev/null +++ b/browser/net/brave_network_audit_whitelists.h @@ -0,0 +1,88 @@ +/* Copyright (c) 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_BROWSER_NET_BRAVE_NETWORK_AUDIT_WHITELISTS_H_ +#define BRAVE_BROWSER_NET_BRAVE_NETWORK_AUDIT_WHITELISTS_H_ + +#include + +namespace brave { + +// Before adding to this list, get approval from the security team. +constexpr const char* kWhitelistedUrlProtocols[] = { + "chrome-extension", "chrome", "brave", "file", "data", "blob", +}; + +// Before adding to this list, get approval from the security team. +constexpr const char* kWhitelistedUrlPrefixes[] = { + // allowed because it 307's to https://componentupdater.brave.com + "https://componentupdater.brave.com/service/update2", + "https://crlsets.brave.com/", + "https://crxdownload.brave.com/crx/blobs/", + + // Omaha/Sparkle + "https://updates.bravesoftware.com/", + + // stats/referrals + "https://laptop-updates.brave.com/", + "https://laptop-updates-staging.brave.com/", + + // needed for DoH on Mac build machines + "https://dns.google/dns-query", + + // needed for DoH on Mac build machines + "https://chrome.cloudflare-dns.com/dns-query", + + // for fetching tor client updater component + "https://tor.bravesoftware.com/", + + // brave sync v2 production + "https://sync-v2.brave.com/v2", + + // brave sync v2 staging + "https://sync-v2.bravesoftware.com/v2", + + // brave sync v2 dev + "https://sync-v2.brave.software/v2", + + // brave A/B testing + "https://variations.brave.com/seed", + + // Brave Today (production) + "https://brave-today-cdn.brave.com/", + + // Brave's Privacy-focused CDN + "https://pcdn.brave.com/", + + // Brave Rewards production + "https://api.rewards.brave.com/v1/parameters", + "https://rewards.brave.com/publishers/prefix-list", + "https://grant.rewards.brave.com/v1/promotions", + + // Brave Rewards staging & dev + "https://api.rewards.bravesoftware.com/v1/parameters", + "https://rewards-stg.bravesoftware.com/publishers/prefix-list", + "https://grant.rewards.bravesoftware.com/v1/promotions", + + // Other + "https://brave-core-ext.s3.brave.com/", + "https://go-updater.brave.com/", + "https://p3a.brave.com/", + "https://redirector.brave.com/", + "https://safebrowsing.brave.com/", + "https://static.brave.com/", + "https://static1.brave.com/", +}; + +// Before adding to this list, get approval from the security team. +constexpr const char* kWhitelistedUrlPatterns[] = { + // allowed because it's url for fetching super referral's mapping table + "https://mobile-data.s3.brave.com/superreferrer/map-table.json", + "https://mobile-data-dev.s3.brave.software/superreferrer/map-table.json", +}; + +} // namespace brave + +#endif // BRAVE_BROWSER_NET_BRAVE_NETWORK_AUDIT_WHITELISTS_H_ diff --git a/build/commands/lib/start.js b/build/commands/lib/start.js index 2321a115d41..bfb7160b05e 100644 --- a/build/commands/lib/start.js +++ b/build/commands/lib/start.js @@ -4,16 +4,6 @@ const ip = require('ip') const URL = require('url').URL const config = require('../lib/config') const util = require('../lib/util') -const whitelistedUrlPrefixes = require('./whitelistedUrlPrefixes') -const whitelistedUrlPatterns = require('./whitelistedUrlPatterns') -const whitelistedUrlProtocols = [ - 'chrome-extension:', - 'chrome:', - 'brave:', - 'file:', - 'data:', - 'blob:' -] const start = (passthroughArgs, buildConfig = config.defaultBuildConfig, options) => { config.buildConfig = buildConfig @@ -85,32 +75,13 @@ const start = (passthroughArgs, buildConfig = config.defaultBuildConfig, options } braveArgs.push('--user-data-dir=' + user_data_dir); } - const networkLogFile = path.resolve(path.join(config.rootDir, 'network_log.json')) - if (options.network_log) { - braveArgs.push(`--log-net-log=${networkLogFile}`) - braveArgs.push(`--net-log-capture-mode=Everything`) - if (user_data_dir) { - // clear the data directory before doing a network test - fs.removeSync(user_data_dir.replace('\\', '')) - if (fs.existsSync(networkLogFile)) { - fs.unlinkSync(networkLogFile) - } - if (fs.existsSync('network-audit-results.json')) { - fs.unlinkSync('network-audit-results.json') - } - } - } let cmdOptions = { stdio: 'inherit', - timeout: options.network_log ? 120000 : undefined, - continueOnFail: options.network_log ? true : false, + timeout: undefined, + continueOnFail: false, shell: process.platform === 'darwin' ? true : false, - killSignal: options.network_log && process.env.RELEASE_TYPE ? 'SIGKILL' : 'SIGTERM' - } - - if (options.network_log) { - console.log('Network audit started. Logging requests for the next 2min or until you quit Brave...') + killSignal: 'SIGTERM' } let outputPath = options.output_path @@ -123,75 +94,6 @@ const start = (passthroughArgs, buildConfig = config.defaultBuildConfig, options } } util.run(outputPath, braveArgs, cmdOptions) - - if (options.network_log) { - let exitCode = 0 - let jsonOutput = {} - // Read the network log - let jsonContent = fs.readFileSync(networkLogFile, 'utf8').trim() - // On windows netlog ends abruptly causing JSON parsing errors - if (!jsonContent.endsWith('}]}')) { - const n = jsonContent.lastIndexOf('},') - jsonContent = jsonContent.substring(0, n) + '}]}' - } - jsonOutput = JSON.parse(jsonContent) - - const URL_REQUEST_TYPE = jsonOutput.constants.logSourceType.URL_REQUEST - const URL_REQUEST_FAKE_RESPONSE_HEADERS_CREATED = jsonOutput.constants.logEventTypes.URL_REQUEST_FAKE_RESPONSE_HEADERS_CREATED - const urlRequests = jsonOutput.events.filter((event) => { - if (event.type === URL_REQUEST_FAKE_RESPONSE_HEADERS_CREATED) { - // showing these helps determine which URL requests which don't - // actually hit the network - return true - } - if (event.source.type === URL_REQUEST_TYPE) { - if (!event.params) { - return false - } - const url = event.params.url - if (!url) { - return false - } - const urlParsed = new URL(url) - const hostname = urlParsed.hostname - if (/^[a-z]+$/.test(hostname)) { - // Chromium sometimes sends requests to random non-resolvable hosts - return false - } - if (whitelistedUrlProtocols.includes(urlParsed.protocol)) { - return false - } - const foundPrefix = whitelistedUrlPrefixes.find((prefix) => { - return url.startsWith(prefix) - }) - const foundPattern = whitelistedUrlPatterns.find((pattern) => { - return RegExp('^' + pattern).test(url) - }) - if (!foundPrefix && !foundPattern) { - // Check if the URL is a private IP - try { - if (ip.isPrivate(hostname)) { - // Warn but don't fail the audit - console.log('NETWORK AUDIT WARN:', url) - return true - } - } catch (e) {} - // This is not a whitelisted URL! log it and exit with non-zero - console.log('NETWORK AUDIT FAIL:', url) - exitCode = 1 - } - return true - } - return false - }) - fs.writeJsonSync('network-audit-results.json', urlRequests) - if (exitCode > 0) { - console.log(`network-audit failed. import ${networkLogFile} in chrome://net-internals for more details.`) - } else { - console.log('network audit passed.') - } - process.exit(exitCode) - } } module.exports = start diff --git a/build/commands/lib/test.js b/build/commands/lib/test.js index f65e7e3a2e5..efff23eae3c 100644 --- a/build/commands/lib/test.js +++ b/build/commands/lib/test.js @@ -74,7 +74,12 @@ const test = (passthroughArgs, suite, buildConfig = config.defaultBuildConfig, o braveArgs = braveArgs.concat(passthroughArgs) // Build the tests - if (suite === 'brave_unit_tests' || suite === 'brave_browser_tests') { + let testSuites = [ + 'brave_unit_tests', + 'brave_browser_tests', + 'brave_network_audit_tests', + ] + if (testSuites.includes(suite)) { util.run('ninja', ['-C', config.outputDir, "brave/test:" + suite], config.defaultOptions) } else { util.run('ninja', ['-C', config.outputDir, suite], config.defaultOptions) diff --git a/build/commands/lib/whitelistedUrlPatterns.js b/build/commands/lib/whitelistedUrlPatterns.js deleted file mode 100644 index f75db6a5ded..00000000000 --- a/build/commands/lib/whitelistedUrlPatterns.js +++ /dev/null @@ -1,11 +0,0 @@ -// Before adding to this list, get approval from the security team -module.exports = [ - 'http://[A-Za-z0-9-\.]+\.gvt1\.com/edgedl/release2/.+', // allowed because it 307's to redirector.brave.com - 'https://[A-Za-z0-9-\.]+\.gvt1\.com/edgedl/release2/.+', // allowed because it 307's to redirector.brave.com - 'http://www.google.com/dl/release2/chrome_component/.+crl-set.+', // allowed because it 307's to crlsets.brave.com - 'https://www.google.com/dl/release2/chrome_component/.+crl-set.+', // allowed because it 307's to crlsets.brave.com - 'http://storage.googleapis.com/update-delta/hfnkpimlhhgieaddgfemjhofmfblmnib/.+crxd', // allowed because it 307's to crlsets.brave.com, - 'https://storage.googleapis.com/update-delta/hfnkpimlhhgieaddgfemjhofmfblmnib/.+crxd', // allowed because it 307's to crlsets.brave.com - 'https://mobile-data.s3.brave.com/superreferrer/map-table.json', // allowed because it's url for fetching super referral's mapping table - 'https://mobile-data-dev.s3.brave.software/superreferrer/map-table.json' // allowed because it's url for fetching super referral's mapping table -] diff --git a/build/commands/lib/whitelistedUrlPrefixes.js b/build/commands/lib/whitelistedUrlPrefixes.js deleted file mode 100644 index ff9e2cae2ef..00000000000 --- a/build/commands/lib/whitelistedUrlPrefixes.js +++ /dev/null @@ -1,32 +0,0 @@ -// Before adding to this list, get approval from the security team -module.exports = [ - 'http://update.googleapis.com/service/update2', // allowed because it 307's to go-updater.brave.com. should never actually connect to googleapis.com. - 'https://update.googleapis.com/service/update2', // allowed because it 307's to go-updater.brave.com. should never actually connect to googleapis.com. - 'https://safebrowsing.googleapis.com/v4/threatListUpdates', // allowed because it 307's to safebrowsing.brave.com - 'https://clients2.googleusercontent.com/crx/blobs/', - 'http://dl.google.com/', // allowed because it 307's to redirector.brave.com - 'https://dl.google.com/', // allowed because it 307's to redirector.brave.com - 'https://no-thanks.invalid/', // fake gaia URL - 'https://go-updater.brave.com/', - 'https://safebrowsing.brave.com/', - 'https://brave-core-ext.s3.brave.com/', - 'https://laptop-updates.brave.com/', // stats/referrals - 'https://static.brave.com/', - 'https://static1.brave.com/', - 'http://componentupdater.brave.com/service/update2', // allowed because it 307's to https://componentupdater.brave.com - 'https://componentupdater.brave.com/service/update2', - 'https://crlsets.brave.com/', - 'https://crxdownload.brave.com/crx/blobs/', - 'https://updates.bravesoftware.com/', // Omaha/Sparkle - 'https://p3a.brave.com/', - 'https://dns.google/dns-query', // needed for DoH on Mac build machines - 'https://chrome.cloudflare-dns.com/dns-query', // needed for DoH on Mac build machines - 'https://tor.bravesoftware.com/', // for fetching tor client updater component - 'https://redirector.brave.com/', - 'https://sync-v2.brave.com/v2', // brave sync v2 production - 'https://sync-v2.bravesoftware.com/v2', // brave sync v2 staging - 'https://sync-v2.brave.software/v2', // brave sync v2 dev - 'https://variations.brave.com/seed', // brave A/B testing - 'https://brave-today-cdn.brave.com/', // Brave Today (production) - 'https://pcdn.brave.com/', // Brave's Privacy-focused CDN -] diff --git a/build/commands/scripts/commands.js b/build/commands/scripts/commands.js index 515edcc6cd7..8d2162bea8a 100755 --- a/build/commands/scripts/commands.js +++ b/build/commands/scripts/commands.js @@ -176,7 +176,6 @@ program .option('--brave_ads_staging', 'ads staging') .option('--brave_ads_debug', 'ads debug') .option('--single_process', 'use a single process') - .option('--network_log', 'log network activity to network_log.json') .option('--output_path [pathname]', 'use the Brave binary located at [pathname]') .arguments('[build_config]') .action(start.bind(null, parsedArgs.unknown)) diff --git a/package.json b/package.json index 9fe8ef966c1..f960b48d7c0 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "update_patches": "node ./build/commands/scripts/commands.js update_patches", "apply_patches": "node ./build/commands/scripts/commands.js apply_patches", "start": "node ./build/commands/scripts/commands.js start", - "network-audit": "node ./build/commands/scripts/commands.js start --enable_brave_update --network_log --user_data_dir_name=brave-network-test --disable-doh", + "network-audit": "npm run test brave_network_audit_tests -- --ui-test-action-timeout=330000 --test-launcher-timeout=1000000", "push_l10n": "node ./build/commands/scripts/commands.js push_l10n", "pull_l10n": "node ./build/commands/scripts/commands.js pull_l10n", "chromium_rebase_l10n": "node ./build/commands/scripts/commands.js chromium_rebase_l10n", @@ -27,7 +27,7 @@ "format": "node ./build/commands/scripts/commands.js format", "test": "node ./build/commands/scripts/commands.js test", "test:scripts": "jest build/commands/lib build/commands/scripts", - "test-security": "npm run check_security && npm run audit_deps && node ./build/commands/scripts/commands.js start --enable_brave_update --network_log --user_data_dir_name=brave-network-test", + "test-security": "npm run check_security && npm run audit_deps && npm run network-audit", "tslint": "tslint --project tsconfig-lint.json \"components/**/*.{ts,tsx}\"", "pep8": "pycodestyle --max-line-length 120 -r script", "pylint": "node ./build/commands/scripts/commands.js pylint", diff --git a/test/BUILD.gn b/test/BUILD.gn index 336a986f9b8..5fe4e0c1d85 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -952,6 +952,39 @@ if (!is_android) { } public_deps = [ ":browser_tests_runner" ] } + + test("brave_network_audit_tests") { + testonly = true + + # We need to disable the ThinLTO cache or the linker will die with + # a "Resource temporarily unavailable" error due to the linking + # reaching the vm.max_map_count limit of 65530 memory mappings. + configs += [ "//chrome/test:disable_thinlto_cache_flags" ] + + sources = [ + "//brave/browser/net/brave_network_audit_browsertest.cc", + "//brave/browser/net/brave_network_audit_whitelists.h", + ] + + deps = [ + "//base", + "//brave/components/brave_rewards/browser", + "//chrome/browser", + "//chrome/browser/profiles:profile", + "//chrome/browser/ui", + "//chrome/test:test_support_ui", + "//components/prefs", + "//content/public/browser", + "//content/test:test_support", + "//services/network/public/cpp", + "//testing/gmock", + "//third_party/re2", + ] + + defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] + + public_deps = [ ":browser_tests_runner" ] + } } else { # if (!is_android) { test("brave_browser_tests") { configs += [ "//build/config:precompiled_headers" ] diff --git a/test/testing.gni b/test/testing.gni index 7c86f5a6483..a108e45a9c3 100644 --- a/test/testing.gni +++ b/test/testing.gni @@ -11,11 +11,8 @@ template("fix_testing_install_name_impl") { executable_path, ] - args = [ - "/usr/bin/install_name_tool", - ] + command_args + [ - rebase_path(executable_path, root_build_dir), - ] + args = [ "/usr/bin/install_name_tool" ] + command_args + + [ rebase_path(executable_path, root_build_dir) ] } } @@ -23,18 +20,27 @@ template("fix_testing_install_name") { change_args = [] if (defined(invoker.changes)) { foreach(change, invoker.changes) { - change_args += ["-change", change[0], change[1]] + change_args += [ + "-change", + change[0], + change[1], + ] } } if (defined(invoker.new_path) && defined(invoker.current_path)) { - change_args += ["-change", invoker.current_path, invoker.new_path] + change_args += [ + "-change", + invoker.current_path, + invoker.new_path, + ] } fix_testing_install_name_impl(target_name + "_unit_tests") { forward_variables_from(invoker, "*") executable_path = "$root_build_dir/brave_unit_tests" command_args = change_args + # input is the same as the output so just fake it outputs = [ "$root_build_dir/alwaysrununittests/$target_name" ] deps = [ "//brave/test:brave_unit_tests" ] @@ -44,8 +50,19 @@ template("fix_testing_install_name") { forward_variables_from(invoker, "*") executable_path = "$root_build_dir/brave_browser_tests" command_args = change_args + # input is the same as the output so just fake it outputs = [ "$root_build_dir/alwaysrunbrowsertests/$target_name" ] deps = [ "//brave/test:brave_browser_tests" ] } + + fix_testing_install_name_impl(target_name + "_network_audit_tests") { + forward_variables_from(invoker, "*") + executable_path = "$root_build_dir/brave_network_audit_tests" + command_args = change_args + + # input is the same as the output so just fake it + outputs = [ "$root_build_dir/alwaysrunbrowsertests/$target_name" ] + deps = [ "//brave/test:brave_network_audit_tests" ] + } }