Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(777)

Unified Diff: base/tracked_objects_unittest.cc

Issue 8313013: Support JSON encoding of data for about:tracking information (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« base/tracked_objects.h ('K') | « base/tracked_objects.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/tracked_objects_unittest.cc
===================================================================
--- base/tracked_objects_unittest.cc (revision 106875)
+++ base/tracked_objects_unittest.cc (working copy)
@@ -6,7 +6,8 @@
#include "base/tracked_objects.h"
-#include "base/message_loop.h"
+#include "base/json/json_writer.h"
+#include "base/memory/scoped_ptr.h"
#include "base/time.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -14,7 +15,10 @@
class TrackedObjectsTest : public testing::Test {
public:
- MessageLoop message_loop_;
+ ~TrackedObjectsTest() {
eroman 2011/10/24 22:23:04 nit: indentation
jar (doing other things) 2011/10/27 06:23:35 Done.
+ ThreadData::ShutdownSingleThreadedCleanup();
+ }
+
};
TEST_F(TrackedObjectsTest, MinimalStartupShutdown) {
@@ -50,14 +54,13 @@
death_map.clear();
data->SnapshotDeathMap(&death_map);
EXPECT_EQ(0u, death_map.size());
- ThreadData::ShutdownSingleThreadedCleanup();
}
TEST_F(TrackedObjectsTest, TinyStartupShutdown) {
if (!ThreadData::StartTracking(true))
return;
- // Instigate tracking on a single tracked object, or our thread.
+ // Instigate tracking on a single tracked object, on our thread.
const Location& location = FROM_HERE;
ThreadData::TallyABirthIfActive(location);
@@ -80,7 +83,8 @@
second_birth,
base::TimeTicks(), /* Bogus post_time. */
base::TimeTicks(), /* Bogus delayed_start_time. */
- base::TimeTicks() /* Bogus start_run_time. */);
+ base::TimeTicks(), /* Bogus start_run_time. */
+ base::TimeTicks() /* Bogus end_run_time */ );
birth_map.clear();
data->SnapshotBirthMap(&birth_map);
@@ -93,8 +97,314 @@
// The births were at the same location as the one known death.
EXPECT_EQ(birth_map.begin()->second, death_map.begin()->first);
+}
- ThreadData::ShutdownSingleThreadedCleanup();
+TEST_F(TrackedObjectsTest, DeathDataTest) {
+ if (!ThreadData::StartTracking(true))
+ return;
+
+ scoped_ptr<DeathData> data(new DeathData());
+ ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL));
+ EXPECT_EQ(data->run_duration(), base::TimeDelta());
+ EXPECT_EQ(data->queue_duration(), base::TimeDelta());
+ EXPECT_EQ(data->AverageMsRunDuration(), 0);
+ EXPECT_EQ(data->AverageMsQueueDuration(), 0);
+ EXPECT_EQ(data->count(), 0);
+
+ int run_ms = 42;
+ int queue_ms = 8;
+
+ base::TimeDelta run_duration = base::TimeDelta().FromMilliseconds(run_ms);
+ base::TimeDelta queue_duration = base::TimeDelta().FromMilliseconds(queue_ms);
+ data->RecordDeath(queue_duration, run_duration);
+ EXPECT_EQ(data->run_duration(), run_duration);
+ EXPECT_EQ(data->queue_duration(), queue_duration);
+ EXPECT_EQ(data->AverageMsRunDuration(), run_ms);
+ EXPECT_EQ(data->AverageMsQueueDuration(), queue_ms);
+ EXPECT_EQ(data->count(), 1);
+
+ data->RecordDeath(queue_duration, run_duration);
+ EXPECT_EQ(data->run_duration(), run_duration + run_duration);
+ EXPECT_EQ(data->queue_duration(), queue_duration + queue_duration);
+ EXPECT_EQ(data->AverageMsRunDuration(), run_ms);
+ EXPECT_EQ(data->AverageMsQueueDuration(), queue_ms);
+ EXPECT_EQ(data->count(), 2);
+
+ scoped_ptr<base::DictionaryValue> dictionary(data->ToValue());
+ int integer;
+ EXPECT_TRUE(dictionary->GetInteger("run_ms", &integer));
+ EXPECT_EQ(integer, 2 * run_ms);
+ EXPECT_TRUE(dictionary->GetInteger("queue_ms", &integer));
+ EXPECT_EQ(integer, 2* queue_ms);
+ EXPECT_TRUE(dictionary->GetInteger("count", &integer));
+ EXPECT_EQ(integer, 2);
+
+ std::string output;
+ data->WriteHTML(&output);
+ std::string results = "Lives:2, Run:84ms(42ms/life) Queue:16ms(8ms/life) ";
+ EXPECT_EQ(output, results);
+
+ scoped_ptr<base::Value> value(data->ToValue());
+ std::string json;
+ base::JSONWriter::Write(value.get(), false, &json);
+ std::string birth_only_result = "{\"count\":2,\"queue_ms\":16,\"run_ms\":84}";
+ EXPECT_EQ(json, birth_only_result);
}
+TEST_F(TrackedObjectsTest, BirthOnlyToValueWorkerThread) {
+ if (!ThreadData::StartTracking(true))
+ return;
+ // We don't initialize system with a thread name, so we're viewed as a worker
+ // thread.
+ int fake_line_number = 173;
+ const char* kFile = "FixedFileName";
+ const char* kFunction = "BirthOnlyToValueWorkerThread";
+ Location location(kFunction, kFile, fake_line_number, NULL);
+ Births* birth = ThreadData::TallyABirthIfActive(location);
+ EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
+
+ int process_type = 3;
+ scoped_ptr<base::Value> value(ThreadData::ToValue(process_type));
+ std::string json;
+ base::JSONWriter::Write(value.get(), false, &json);
+ std::string birth_only_result = "{"
+ "\"list\":["
+ "{"
+ "\"birth_thread\":\"WorkerThread-1\","
eroman 2011/10/24 22:23:04 Are thread names guaranteed to be unique? I wander
jar (doing other things) 2011/10/27 06:23:35 It is possible (within a single process) to have t
+ "\"death_data\":{"
+ "\"count\":1,"
+ "\"queue_ms\":0,"
+ "\"run_ms\":0"
+ "},"
+ "\"death_thread\":\"Still_Alive\","
+ "\"location\":{"
+ "\"file_name\":\"FixedFileName\","
+ "\"function_name\":\"BirthOnlyToValueWorkerThread\","
+ "\"line_number\":173"
+ "}"
+ "}"
+ "],"
+ "\"process\":3"
+ "}";
+ EXPECT_EQ(json, birth_only_result);
+}
+
+TEST_F(TrackedObjectsTest, BirthOnlyToValueMainThread) {
+ if (!ThreadData::StartTracking(true))
+ return;
+
+ // Use a well named thread.
+ ThreadData::InitializeThreadContext("SomeMainThreadName");
+ int fake_line_number = 173;
+ const char* kFile = "FixedFileName";
+ const char* kFunction = "BirthOnlyToValueMainThread";
+ Location location(kFunction, kFile, fake_line_number, NULL);
+ // Do not delete birth. We don't own it.
+ Births* birth = ThreadData::TallyABirthIfActive(location);
+ EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
+
+ int process_type = 34;
+ scoped_ptr<base::Value> value(ThreadData::ToValue(process_type));
+ std::string json;
+ base::JSONWriter::Write(value.get(), false, &json);
+ std::string birth_only_result = "{"
+ "\"list\":["
+ "{"
+ "\"birth_thread\":\"SomeMainThreadName\","
+ "\"death_data\":{"
+ "\"count\":1,"
+ "\"queue_ms\":0,"
+ "\"run_ms\":0"
+ "},"
+ "\"death_thread\":\"Still_Alive\","
+ "\"location\":{"
+ "\"file_name\":\"FixedFileName\","
+ "\"function_name\":\"BirthOnlyToValueMainThread\","
+ "\"line_number\":173"
+ "}"
+ "}"
+ "],"
+ "\"process\":34"
+ "}";
+ EXPECT_EQ(json, birth_only_result);
+}
+
+TEST_F(TrackedObjectsTest, LifeCycleToValueMainThread) {
+ if (!ThreadData::StartTracking(true))
+ return;
+
+ // Use a well named thread.
+ ThreadData::InitializeThreadContext("SomeMainThreadName");
+ int fake_line_number = 236;
+ const char* kFile = "FixedFileName";
+ const char* kFunction = "LifeCycleToValueMainThread";
+ Location location(kFunction, kFile, fake_line_number, NULL);
+ // Do not delete birth. We don't own it.
+ Births* birth = ThreadData::TallyABirthIfActive(location);
+ EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
+
+ // TimeTicks initializers ar ein microseconds. Durations are calculated in
+ // milliseconds, so we need to use 1000x.
+ const base::TimeTicks time_posted = base::TimeTicks() +
+ base::TimeDelta::FromMilliseconds(1);
+ const base::TimeTicks delayed_start_time = base::TimeTicks();
+ const base::TimeTicks start_of_run = base::TimeTicks() +
+ base::TimeDelta::FromMilliseconds(5);
+ const base::TimeTicks end_of_run = base::TimeTicks() +
+ base::TimeDelta::FromMilliseconds(7);
+ ThreadData::TallyADeathIfActive(birth, time_posted, delayed_start_time,
+ start_of_run, end_of_run);
+
+ int process_type = 7;
+ scoped_ptr<base::Value> value(ThreadData::ToValue(process_type));
+ std::string json;
+ base::JSONWriter::Write(value.get(), false, &json);
+ std::string one_line_result = "{"
+ "\"list\":["
+ "{"
+ "\"birth_thread\":\"SomeMainThreadName\","
+ "\"death_data\":{"
+ "\"count\":1,"
+ "\"queue_ms\":4,"
+ "\"run_ms\":2"
+ "},"
+ "\"death_thread\":\"SomeMainThreadName\","
+ "\"location\":{"
+ "\"file_name\":\"FixedFileName\","
+ "\"function_name\":\"LifeCycleToValueMainThread\","
+ "\"line_number\":236"
+ "}"
+ "}"
+ "],"
+ "\"process\":7"
+ "}";
+ EXPECT_EQ(json, one_line_result);
+}
+
+TEST_F(TrackedObjectsTest, TwoLives) {
+ if (!ThreadData::StartTracking(true))
+ return;
+
+ // Use a well named thread.
+ ThreadData::InitializeThreadContext("SomeFileThreadName");
+ int fake_line_number = 222;
+ const char* kFile = "AnotherFileName";
+ const char* kFunction = "TwoLives";
+ Location location(kFunction, kFile, fake_line_number, NULL);
+ // Do not delete birth. We don't own it.
+ Births* birth = ThreadData::TallyABirthIfActive(location);
+ EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
+
+ // TimeTicks initializers ar ein microseconds. Durations are calculated in
+ // milliseconds, so we need to use 1000x.
+ const base::TimeTicks time_posted = base::TimeTicks() +
+ base::TimeDelta::FromMilliseconds(1);
+ const base::TimeTicks delayed_start_time = base::TimeTicks();
+ const base::TimeTicks start_of_run = base::TimeTicks() +
+ base::TimeDelta::FromMilliseconds(5);
+ const base::TimeTicks end_of_run = base::TimeTicks() +
+ base::TimeDelta::FromMilliseconds(7);
+ ThreadData::TallyADeathIfActive(birth, time_posted, delayed_start_time,
+ start_of_run, end_of_run);
+
+ birth = ThreadData::TallyABirthIfActive(location);
+ ThreadData::TallyADeathIfActive(birth, time_posted, delayed_start_time,
+ start_of_run, end_of_run);
+
+ int process_type = 7;
+ scoped_ptr<base::Value> value(ThreadData::ToValue(process_type));
+ std::string json;
+ base::JSONWriter::Write(value.get(), false, &json);
+ std::string one_line_result = "{"
+ "\"list\":["
+ "{"
+ "\"birth_thread\":\"SomeFileThreadName\","
+ "\"death_data\":{"
+ "\"count\":2,"
+ "\"queue_ms\":8,"
+ "\"run_ms\":4"
+ "},"
+ "\"death_thread\":\"SomeFileThreadName\","
+ "\"location\":{"
+ "\"file_name\":\"AnotherFileName\","
+ "\"function_name\":\"TwoLives\","
+ "\"line_number\":222"
+ "}"
+ "}"
+ "],"
+ "\"process\":7"
+ "}";
+ EXPECT_EQ(json, one_line_result);
+}
+
+TEST_F(TrackedObjectsTest, DifferentLives) {
+ if (!ThreadData::StartTracking(true))
+ return;
+
+ // Use a well named thread.
+ ThreadData::InitializeThreadContext("SomeFileThreadName");
+ int fake_line_number = 567;
+ const char* kFile = "AnotherFileName";
+ const char* kFunction = "DifferentLives";
+ Location location(kFunction, kFile, fake_line_number, NULL);
+ // Do not delete birth. We don't own it.
+ Births* birth = ThreadData::TallyABirthIfActive(location);
+ EXPECT_NE(birth, reinterpret_cast<Births*>(NULL));
+
+ // TimeTicks initializers ar ein microseconds. Durations are calculated in
+ // milliseconds, so we need to use 1000x.
+ const base::TimeTicks time_posted = base::TimeTicks() +
+ base::TimeDelta::FromMilliseconds(1);
+ const base::TimeTicks delayed_start_time = base::TimeTicks();
+ const base::TimeTicks start_of_run = base::TimeTicks() +
+ base::TimeDelta::FromMilliseconds(5);
+ const base::TimeTicks end_of_run = base::TimeTicks() +
+ base::TimeDelta::FromMilliseconds(7);
+ ThreadData::TallyADeathIfActive(birth, time_posted, delayed_start_time,
+ start_of_run, end_of_run);
+
+ int second_fake_line_number = 999;
+ Location second_location(kFunction, kFile, second_fake_line_number, NULL);
+ birth = ThreadData::TallyABirthIfActive(second_location);
+
+ int process_type = 2;
+ scoped_ptr<base::Value> value(ThreadData::ToValue(process_type));
+ std::string json;
+ base::JSONWriter::Write(value.get(), false, &json);
+ std::string one_line_result = "{"
+ "\"list\":["
+ "{"
+ "\"birth_thread\":\"SomeFileThreadName\","
+ "\"death_data\":{"
+ "\"count\":1,"
+ "\"queue_ms\":4,"
+ "\"run_ms\":2"
+ "},"
+ "\"death_thread\":\"SomeFileThreadName\","
+ "\"location\":{"
+ "\"file_name\":\"AnotherFileName\","
+ "\"function_name\":\"DifferentLives\","
+ "\"line_number\":567"
+ "}"
+ "},"
+ "{"
+ "\"birth_thread\":\"SomeFileThreadName\","
+ "\"death_data\":{"
+ "\"count\":1,"
+ "\"queue_ms\":0,"
+ "\"run_ms\":0"
+ "},"
+ "\"death_thread\":\"Still_Alive\","
+ "\"location\":{"
+ "\"file_name\":\"AnotherFileName\","
+ "\"function_name\":\"DifferentLives\","
+ "\"line_number\":999"
+ "}"
+ "}"
+ "],"
+ "\"process\":2"
+ "}";
+ EXPECT_EQ(json, one_line_result);
+}
+
} // namespace tracked_objects
« base/tracked_objects.h ('K') | « base/tracked_objects.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698