blob: 311677e7cafa1c17f90780fcd643ffeea1f76c44 [file] [log] [blame]
// Copyright 2017 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 "services/tracing/recorder.h"
#include <utility>
#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace tracing {
class RecorderTest : public testing::Test {
public:
void SetUp() override { message_loop_.reset(new base::MessageLoop()); }
void TearDown() override {
recorder_.reset();
message_loop_.reset();
}
void CreateRecorder(mojom::RecorderRequest request,
mojom::TraceDataType data_type,
const base::Closure& callback) {
recorder_.reset(new Recorder(std::move(request), data_type, callback));
}
void CreateRecorder(mojom::TraceDataType data_type,
const base::Closure& callback) {
CreateRecorder(nullptr, data_type, callback);
}
void AddChunk(const std::string& chunk) { recorder_->AddChunk(chunk); }
void AddMetadata(base::Value metadata) {
recorder_->AddMetadata(std::move(metadata));
}
std::unique_ptr<Recorder> recorder_;
private:
std::unique_ptr<base::MessageLoop> message_loop_;
};
TEST_F(RecorderTest, AddChunkArray) {
size_t num_calls = 0;
CreateRecorder(mojom::TraceDataType::ARRAY,
base::BindRepeating([](size_t* num_calls) { (*num_calls)++; },
base::Unretained(&num_calls)));
AddChunk("chunk1");
AddChunk("chunk2");
AddChunk("chunk3");
EXPECT_EQ("chunk1,chunk2,chunk3", recorder_->data());
// Verify that the recorder has called the callback every time it received a
// chunk.
EXPECT_EQ(3u, num_calls);
}
TEST_F(RecorderTest, AddChunkObject) {
size_t num_calls = 0;
CreateRecorder(mojom::TraceDataType::OBJECT,
base::BindRepeating([](size_t* num_calls) { (*num_calls)++; },
base::Unretained(&num_calls)));
AddChunk("chunk1");
AddChunk("chunk2");
AddChunk("chunk3");
// Objects are similar to arrays. Their chunks are separated by commas.
EXPECT_EQ("chunk1,chunk2,chunk3", recorder_->data());
// Verify that the recorder has called the callback every time it received a
// chunk.
EXPECT_EQ(3u, num_calls);
}
TEST_F(RecorderTest, AddChunkString) {
size_t num_calls = 0;
CreateRecorder(mojom::TraceDataType::STRING,
base::BindRepeating([](size_t* num_calls) { (*num_calls)++; },
base::Unretained(&num_calls)));
AddChunk("chunk1");
AddChunk("chunk2");
AddChunk("chunk3");
EXPECT_EQ("chunk1chunk2chunk3", recorder_->data());
EXPECT_EQ(3u, num_calls);
}
TEST_F(RecorderTest, AddMetadata) {
CreateRecorder(mojom::TraceDataType::ARRAY, base::BindRepeating([] {}));
base::DictionaryValue dict1;
dict1.SetKey("network-type", base::Value("Ethernet"));
AddMetadata(std::move(dict1));
base::DictionaryValue dict2;
dict2.SetKey("os-name", base::Value("CrOS"));
AddMetadata(std::move(dict2));
EXPECT_EQ(2u, recorder_->metadata().size());
std::string net;
EXPECT_TRUE(recorder_->metadata().GetString("network-type", &net));
EXPECT_EQ("Ethernet", net);
std::string os;
EXPECT_TRUE(recorder_->metadata().GetString("os-name", &os));
EXPECT_EQ("CrOS", os);
}
TEST_F(RecorderTest, OnConnectionError) {
base::RunLoop run_loop;
size_t num_calls = 0;
{
mojom::RecorderPtr ptr;
auto request = MakeRequest(&ptr);
CreateRecorder(std::move(request), mojom::TraceDataType::STRING,
base::BindRepeating(
[](size_t* num_calls, base::Closure quit_closure) {
(*num_calls)++;
quit_closure.Run();
},
base::Unretained(&num_calls), run_loop.QuitClosure()));
}
// |ptr| is deleted at this point and so the recorder should notify us that
// the client is not going to send any more data by running the callback.
run_loop.Run();
EXPECT_EQ(1u, num_calls);
}
} // namespace tracing