| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/feedback/content/content_tracing_manager.h" |
| |
| #include <memory> |
| |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/functional/callback.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/run_loop.h" |
| #include "base/test/test_future.h" |
| #include "components/feedback/feedback_data.h" |
| #include "components/feedback/feedback_report.h" |
| #include "components/feedback/feedback_uploader.h" |
| #include "content/public/test/browser_test.h" |
| #include "content/public/test/content_browser_test.h" |
| #include "content/public/test/test_utils.h" |
| #include "services/network/public/cpp/shared_url_loader_factory.h" |
| #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" |
| #include "services/network/test/test_url_loader_factory.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace { |
| |
| const std::string kFakeKey = "fake key"; |
| const std::string kFakeValue = "fake value"; |
| const char kTraceFilename[] = "tracing.zip"; |
| const int kFakeTraceId = 1; |
| |
| } // namespace |
| |
| class TestFeedbackUploader final : public feedback::FeedbackUploader { |
| public: |
| TestFeedbackUploader( |
| bool is_off_the_record, |
| const base::FilePath& state_path, |
| scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) |
| : FeedbackUploader(is_off_the_record, |
| state_path, |
| std::move(url_loader_factory)) {} |
| TestFeedbackUploader(const TestFeedbackUploader&) = delete; |
| TestFeedbackUploader& operator=(const TestFeedbackUploader&) = delete; |
| |
| ~TestFeedbackUploader() override = default; |
| |
| base::WeakPtr<FeedbackUploader> AsWeakPtr() override { |
| return weak_ptr_factory_.GetWeakPtr(); |
| } |
| |
| private: |
| base::WeakPtrFactory<TestFeedbackUploader> weak_ptr_factory_{this}; |
| }; |
| |
| class ContentTracingManagerBrowserTest : public content::ContentBrowserTest { |
| public: |
| void SetUpOnMainThread() override { |
| content::ContentBrowserTest::SetUpOnMainThread(); |
| } |
| }; |
| |
| class FeedbackDataBrowserTest : public content::ContentBrowserTest { |
| public: |
| FeedbackDataBrowserTest() |
| : test_shared_loader_factory_( |
| base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( |
| &test_url_loader_factory_)) { |
| EXPECT_TRUE(scoped_temp_dir_.CreateUniqueTempDir()); |
| } |
| |
| void SetUpOnMainThread() override { |
| content::ContentBrowserTest::SetUpOnMainThread(); |
| |
| uploader_ = std::make_unique<TestFeedbackUploader>( |
| /*is_of_the_record=*/false, scoped_temp_dir_.GetPath(), |
| test_shared_loader_factory_); |
| } |
| |
| FeedbackDataBrowserTest(const FeedbackDataBrowserTest&) = delete; |
| FeedbackDataBrowserTest& operator=(const FeedbackDataBrowserTest&) = delete; |
| |
| ~FeedbackDataBrowserTest() override = default; |
| |
| protected: |
| scoped_refptr<feedback::FeedbackData> CreateFeedbackData() { |
| return base::MakeRefCounted<feedback::FeedbackData>( |
| uploader_->AsWeakPtr(), ContentTracingManager::Get()); |
| } |
| |
| base::ScopedTempDir scoped_temp_dir_; |
| network::TestURLLoaderFactory test_url_loader_factory_; |
| scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; |
| std::unique_ptr<TestFeedbackUploader> uploader_; |
| }; |
| |
| // Test that the trace data is compressed successfully. |
| IN_PROC_BROWSER_TEST_F(ContentTracingManagerBrowserTest, TraceDataCompressed) { |
| std::unique_ptr<ContentTracingManager> tracing_manager = |
| ContentTracingManager::Create(); |
| EXPECT_NE(tracing_manager, nullptr); |
| |
| base::test::TestFuture<scoped_refptr<base::RefCountedString>> future; |
| |
| int trace_id = tracing_manager->RequestTrace(); |
| EXPECT_EQ(trace_id, 1); |
| tracing_manager->GetTraceData(trace_id, future.GetCallback()); |
| // The actual trace data varies. |
| EXPECT_TRUE(future.Get()->size() > 0u); |
| } |
| |
| // Test that FeedbackData.CompressSystemInfo will not gather trace data when the |
| // performance tracing is not enabled. |
| IN_PROC_BROWSER_TEST_F(FeedbackDataBrowserTest, TraceNotEnabled) { |
| auto* tracing_manager = ContentTracingManager::Get(); |
| EXPECT_EQ(tracing_manager, nullptr); |
| |
| scoped_refptr<feedback::FeedbackData> feedback_data = CreateFeedbackData(); |
| |
| feedback_data->AddLog(kFakeKey, kFakeValue); |
| // Set a trace id so that Feedback data will try to fetch trace data. |
| feedback_data->set_trace_id(kFakeTraceId); |
| |
| base::RunLoop run_loop; |
| feedback_data->CompressSystemInfo(); |
| run_loop.RunUntilIdle(); |
| |
| const std::map<std::string, std::string>* sys_info = |
| feedback_data->sys_info(); |
| EXPECT_NE(sys_info, nullptr); |
| EXPECT_EQ(sys_info->size(), 1u); |
| // Verify that there is no trace file added. |
| EXPECT_EQ(sys_info->count(kTraceFilename), 0u); |
| } |
| |
| // Test that FeedbackData.CompressSystemInfo will not gather trace data when: |
| // 1) the performance tracing is enabled when feedback data is constructed, but |
| // 2) the tracing manager was reset before feedback data collects trace data. |
| // The code before this CL will crash. |
| IN_PROC_BROWSER_TEST_F(FeedbackDataBrowserTest, TraceEnabledLaterWasReset) { |
| std::unique_ptr<ContentTracingManager> tracing_manager = |
| ContentTracingManager::Create(); |
| EXPECT_NE(ContentTracingManager::Get(), nullptr); |
| |
| int trace_id = tracing_manager->RequestTrace(); |
| EXPECT_EQ(trace_id, 1); |
| |
| scoped_refptr<feedback::FeedbackData> feedback_data = CreateFeedbackData(); |
| |
| feedback_data->AddLog(kFakeKey, kFakeValue); |
| // Set a trace id so that Feedback data will try to fetch trace data. |
| feedback_data->set_trace_id(trace_id); |
| |
| tracing_manager.reset(); |
| EXPECT_EQ(tracing_manager, nullptr); |
| EXPECT_EQ(ContentTracingManager::Get(), nullptr); |
| |
| base::RunLoop run_loop; |
| feedback_data->CompressSystemInfo(); |
| run_loop.RunUntilIdle(); |
| |
| const std::map<std::string, std::string>* sys_info = |
| feedback_data->sys_info(); |
| EXPECT_NE(sys_info, nullptr); |
| EXPECT_EQ(sys_info->size(), 1u); |
| // Verify that there is not a trace file added. |
| EXPECT_EQ(sys_info->count(kTraceFilename), 0u); |
| } |