| Index: chrome/browser/data_usage/tab_id_annotator_unittest.cc
|
| diff --git a/chrome/browser/data_usage/tab_id_annotator_unittest.cc b/chrome/browser/data_usage/tab_id_annotator_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..299d40032c9df39e1fd00c0b067b08915bd7146a
|
| --- /dev/null
|
| +++ b/chrome/browser/data_usage/tab_id_annotator_unittest.cc
|
| @@ -0,0 +1,171 @@
|
| +// Copyright 2015 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 "chrome/browser/data_usage/tab_id_annotator.h"
|
| +
|
| +#include <stdint.h>
|
| +
|
| +#include <string>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/callback.h"
|
| +#include "base/location.h"
|
| +#include "base/macros.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/run_loop.h"
|
| +#include "base/time/time.h"
|
| +#include "chrome/browser/sessions/session_tab_helper.h"
|
| +#include "chrome/test/base/chrome_render_view_host_test_harness.h"
|
| +#include "components/data_usage/core/data_use.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/render_frame_host.h"
|
| +#include "content/public/browser/render_process_host.h"
|
| +#include "content/public/browser/resource_request_info.h"
|
| +#include "content/public/browser/web_contents.h"
|
| +#include "net/base/network_change_notifier.h"
|
| +#include "net/base/request_priority.h"
|
| +#include "net/url_request/url_request.h"
|
| +#include "net/url_request/url_request_test_util.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "url/gurl.h"
|
| +
|
| +using content::BrowserThread;
|
| +using data_usage::DataUse;
|
| +
|
| +namespace chrome_browser_data_usage {
|
| +
|
| +namespace {
|
| +
|
| +class TabIdAnnotatorTest : public ChromeRenderViewHostTestHarness {
|
| + public:
|
| + TabIdAnnotatorTest() {
|
| + // Cannot use IO_MAIN_LOOP with RenderViewHostTestHarness.
|
| + SetThreadBundleOptions(content::TestBrowserThreadBundle::REAL_IO_THREAD);
|
| + }
|
| +
|
| + ~TabIdAnnotatorTest() override {}
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(TabIdAnnotatorTest);
|
| +};
|
| +
|
| +// Synthesizes a DataUse object with the given |tab_id|.
|
| +scoped_ptr<DataUse> CreateDataUse(int32_t tab_id) {
|
| + return scoped_ptr<DataUse>(new DataUse(
|
| + GURL("http://foo.com"), base::TimeTicks(), GURL(), tab_id,
|
| + net::NetworkChangeNotifier::CONNECTION_UNKNOWN, std::string(), 100, 100));
|
| +}
|
| +
|
| +// Expects that |expected| and |actual| are equal.
|
| +void ExpectDataUse(scoped_ptr<DataUse> expected, scoped_ptr<DataUse> actual) {
|
| + // Single out the |tab_id| for better debug output in failure cases.
|
| + EXPECT_EQ(expected->tab_id, actual->tab_id);
|
| + EXPECT_EQ(*expected, *actual);
|
| +}
|
| +
|
| +// Expects that |expected| and |actual| are equal, then quits |ui_run_loop| on
|
| +// the UI thread.
|
| +void ExpectDataUseAndQuit(base::RunLoop* ui_run_loop,
|
| + scoped_ptr<DataUse> expected,
|
| + scoped_ptr<DataUse> actual) {
|
| + DCHECK(ui_run_loop);
|
| + ExpectDataUse(expected.Pass(), actual.Pass());
|
| +
|
| + // This can't use run_loop->QuitClosure here because that uses WeakPtrs, which
|
| + // aren't thread safe.
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&base::RunLoop::Quit, base::Unretained(ui_run_loop)));
|
| +}
|
| +
|
| +// Tests that for a sample URLRequest, associated with the given
|
| +// |render_process_id| and |render_frame_id|, repeatedly annotating DataUse for
|
| +// that URLRequest yields the |expected_tab_id|. |ui_run_loop| is the RunLoop on
|
| +// the UI thread that should be quit after all the annotations are done.
|
| +// Passing in -1 for either or both of |render_process_id| or |render_frame_id|
|
| +// indicates that the URLRequest should have no associated ResourceRequestInfo.
|
| +void TestAnnotateOnIOThread(base::RunLoop* ui_run_loop,
|
| + int render_process_id,
|
| + int render_frame_id,
|
| + int32_t expected_tab_id) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + DCHECK(ui_run_loop);
|
| +
|
| + TabIdAnnotator annotator;
|
| + net::TestURLRequestContext context;
|
| + net::TestDelegate test_delegate;
|
| + scoped_ptr<net::URLRequest> request =
|
| + context.CreateRequest(GURL("http://foo.com"), net::IDLE, &test_delegate);
|
| +
|
| + if (render_process_id != -1 && render_frame_id != -1) {
|
| + // The only args that matter here for the ResourceRequestInfo are the
|
| + // |request|, the |render_process_id|, and the |render_frame_id|; arbitrary
|
| + // values are used for all the other args.
|
| + content::ResourceRequestInfo::AllocateForTesting(
|
| + request.get(), content::RESOURCE_TYPE_MAIN_FRAME, nullptr,
|
| + render_process_id, -1, render_frame_id, true, false, true, true, false);
|
| + }
|
| +
|
| + // An invalid tab ID to check that the annotator always sets the tab ID. -2 is
|
| + // used because a tab ID of -1 is a valid value that means "no tab was found".
|
| + const int32_t kInvalidTabId = -2;
|
| +
|
| + // Annotate two separate DataUse objects to ensure that repeated annotations
|
| + // for the same URLRequest work properly.
|
| + scoped_ptr<DataUse> first_expected_data_use = CreateDataUse(expected_tab_id);
|
| + annotator.Annotate(
|
| + request.get(), CreateDataUse(kInvalidTabId),
|
| + base::Bind(&ExpectDataUse, base::Passed(&first_expected_data_use)));
|
| +
|
| + // Quit the |ui_run_loop| after the second annotation.
|
| + scoped_ptr<DataUse> second_expected_data_use = CreateDataUse(expected_tab_id);
|
| + annotator.Annotate(request.get(), CreateDataUse(kInvalidTabId),
|
| + base::Bind(&ExpectDataUseAndQuit, ui_run_loop,
|
| + base::Passed(&second_expected_data_use)));
|
| +}
|
| +
|
| +TEST_F(TabIdAnnotatorTest, AnnotateWithNoRenderFrame) {
|
| + base::RunLoop ui_run_loop;
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&TestAnnotateOnIOThread, &ui_run_loop,
|
| + -1 /* render_process_id */, -1 /* render_frame_id */,
|
| + -1 /* expected_tab_id */));
|
| + ui_run_loop.Run();
|
| +}
|
| +
|
| +TEST_F(TabIdAnnotatorTest, AnnotateWithRenderFrameAndNoTab) {
|
| + base::RunLoop ui_run_loop;
|
| + // |web_contents()| isn't a tab, so it shouldn't have a tab ID.
|
| + EXPECT_EQ(-1, SessionTabHelper::IdForTab(web_contents()));
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&TestAnnotateOnIOThread, &ui_run_loop,
|
| + web_contents()->GetMainFrame()->GetProcess()->GetID(),
|
| + web_contents()->GetMainFrame()->GetRoutingID(),
|
| + -1 /* expected_tab_id */));
|
| + ui_run_loop.Run();
|
| +}
|
| +
|
| +TEST_F(TabIdAnnotatorTest, AnnotateWithRenderFrameAndTab) {
|
| + base::RunLoop ui_run_loop;
|
| + // Make |web_contents()| into a tab.
|
| + SessionTabHelper::CreateForWebContents(web_contents());
|
| + int32_t expected_tab_id = SessionTabHelper::IdForTab(web_contents());
|
| + // |web_contents()| is a tab, so it should have a tab ID.
|
| + EXPECT_NE(-1, expected_tab_id);
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&TestAnnotateOnIOThread, &ui_run_loop,
|
| + web_contents()->GetMainFrame()->GetProcess()->GetID(),
|
| + web_contents()->GetMainFrame()->GetRoutingID(),
|
| + expected_tab_id));
|
| + ui_run_loop.Run();
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +} // namespace chrome_browser_data_usage
|
|
|