LCOV - code coverage report
Current view: top level - test/cctest/libplatform - test-tracing.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 283 283 100.0 %
Date: 2019-04-17 Functions: 21 27 77.8 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : #include <limits>
       5             : 
       6             : #include "include/libplatform/v8-tracing.h"
       7             : #include "src/base/platform/platform.h"
       8             : #include "src/libplatform/default-platform.h"
       9             : #include "src/tracing/trace-event.h"
      10             : #include "test/cctest/cctest.h"
      11             : 
      12             : namespace v8 {
      13             : namespace platform {
      14             : namespace tracing {
      15             : 
      16       26644 : TEST(TestTraceConfig) {
      17           5 :   LocalContext env;
      18           5 :   TraceConfig* trace_config = new TraceConfig();
      19           5 :   trace_config->AddIncludedCategory("v8");
      20           5 :   trace_config->AddIncludedCategory(TRACE_DISABLED_BY_DEFAULT("v8.runtime"));
      21             : 
      22           5 :   CHECK_EQ(trace_config->IsSystraceEnabled(), false);
      23           5 :   CHECK_EQ(trace_config->IsArgumentFilterEnabled(), false);
      24           5 :   CHECK_EQ(trace_config->IsCategoryGroupEnabled("v8"), true);
      25           5 :   CHECK_EQ(trace_config->IsCategoryGroupEnabled("v8.cpu_profile"), false);
      26           5 :   CHECK_EQ(trace_config->IsCategoryGroupEnabled("v8.cpu_profile.hires"), false);
      27           5 :   CHECK_EQ(trace_config->IsCategoryGroupEnabled(
      28             :                TRACE_DISABLED_BY_DEFAULT("v8.runtime")),
      29             :            true);
      30           5 :   CHECK_EQ(trace_config->IsCategoryGroupEnabled("v8,v8.cpu_profile"), true);
      31           5 :   CHECK_EQ(
      32             :       trace_config->IsCategoryGroupEnabled("v8,disabled-by-default-v8.runtime"),
      33             :       true);
      34           5 :   CHECK_EQ(trace_config->IsCategoryGroupEnabled(
      35             :                "v8_cpu_profile,v8.cpu_profile.hires"),
      36             :            false);
      37             : 
      38          10 :   delete trace_config;
      39           5 : }
      40             : 
      41       26644 : TEST(TestTraceObject) {
      42           5 :   TraceObject trace_object;
      43           5 :   uint8_t category_enabled_flag = 41;
      44             :   trace_object.Initialize('X', &category_enabled_flag, "Test.Trace",
      45             :                           "Test.Scope", 42, 123, 0, nullptr, nullptr, nullptr,
      46           5 :                           nullptr, 0, 1729, 4104);
      47           5 :   CHECK_EQ('X', trace_object.phase());
      48           5 :   CHECK_EQ(category_enabled_flag, *trace_object.category_enabled_flag());
      49          15 :   CHECK_EQ(std::string("Test.Trace"), std::string(trace_object.name()));
      50          15 :   CHECK_EQ(std::string("Test.Scope"), std::string(trace_object.scope()));
      51           5 :   CHECK_EQ(0u, trace_object.duration());
      52           5 :   CHECK_EQ(0u, trace_object.cpu_duration());
      53           5 : }
      54             : 
      55          30 : class ConvertableToTraceFormatMock : public v8::ConvertableToTraceFormat {
      56             :  public:
      57          15 :   explicit ConvertableToTraceFormatMock(int value) : value_(value) {}
      58          15 :   void AppendAsTraceFormat(std::string* out) const override {
      59         135 :     *out += "[" + std::to_string(value_) + "," + std::to_string(value_) + "]";
      60          15 :   }
      61             : 
      62             :  private:
      63             :   int value_;
      64             : 
      65             :   DISALLOW_COPY_AND_ASSIGN(ConvertableToTraceFormatMock);
      66             : };
      67             : 
      68          60 : class MockTraceWriter : public TraceWriter {
      69             :  public:
      70         391 :   void AppendTraceEvent(TraceObject* trace_event) override {
      71         782 :     events_.push_back(trace_event->name());
      72         391 :   }
      73             : 
      74          25 :   void Flush() override {}
      75             : 
      76          20 :   std::vector<std::string> events() { return events_; }
      77             : 
      78             :  private:
      79             :   std::vector<std::string> events_;
      80             : };
      81             : 
      82       26644 : TEST(TestTraceBufferRingBuffer) {
      83             :   // We should be able to add kChunkSize * 2 + 1 trace events.
      84             :   const int HANDLES_COUNT = TraceBufferChunk::kChunkSize * 2 + 1;
      85           5 :   MockTraceWriter* writer = new MockTraceWriter();
      86             :   TraceBuffer* ring_buffer =
      87           5 :       TraceBuffer::CreateTraceBufferRingBuffer(2, writer);
      88        1945 :   std::string names[HANDLES_COUNT];
      89        1295 :   for (int i = 0; i < HANDLES_COUNT; ++i) {
      90        1935 :     names[i] = "Test.EventNo" + std::to_string(i);
      91             :   }
      92             : 
      93           5 :   std::vector<uint64_t> handles(HANDLES_COUNT);
      94           5 :   uint8_t category_enabled_flag = 41;
      95        1295 :   for (size_t i = 0; i < handles.size(); ++i) {
      96        1290 :     TraceObject* trace_object = ring_buffer->AddTraceEvent(&handles[i]);
      97         645 :     CHECK_NOT_NULL(trace_object);
      98         645 :     trace_object->Initialize('X', &category_enabled_flag, names[i].c_str(),
      99             :                              "Test.Scope", 42, 123, 0, nullptr, nullptr,
     100         645 :                              nullptr, nullptr, 0, 1729, 4104);
     101        1290 :     trace_object = ring_buffer->GetEventByHandle(handles[i]);
     102         645 :     CHECK_NOT_NULL(trace_object);
     103         645 :     CHECK_EQ('X', trace_object->phase());
     104        1290 :     CHECK_EQ(names[i], std::string(trace_object->name()));
     105         645 :     CHECK_EQ(category_enabled_flag, *trace_object->category_enabled_flag());
     106             :   }
     107             : 
     108             :   // We should only be able to retrieve the last kChunkSize + 1.
     109         645 :   for (size_t i = 0; i < TraceBufferChunk::kChunkSize; ++i) {
     110         640 :     CHECK_NULL(ring_buffer->GetEventByHandle(handles[i]));
     111             :   }
     112             : 
     113         655 :   for (size_t i = TraceBufferChunk::kChunkSize; i < handles.size(); ++i) {
     114         650 :     TraceObject* trace_object = ring_buffer->GetEventByHandle(handles[i]);
     115         325 :     CHECK_NOT_NULL(trace_object);
     116             :     // The object properties should be correct.
     117         325 :     CHECK_EQ('X', trace_object->phase());
     118         650 :     CHECK_EQ(names[i], std::string(trace_object->name()));
     119         325 :     CHECK_EQ(category_enabled_flag, *trace_object->category_enabled_flag());
     120             :   }
     121             : 
     122             :   // Check Flush(), that the writer wrote the last kChunkSize  1 event names.
     123           5 :   ring_buffer->Flush();
     124           5 :   auto events = writer->events();
     125           5 :   CHECK_EQ(TraceBufferChunk::kChunkSize + 1, events.size());
     126         655 :   for (size_t i = TraceBufferChunk::kChunkSize; i < handles.size(); ++i) {
     127         975 :     CHECK_EQ(names[i], events[i - TraceBufferChunk::kChunkSize]);
     128             :   }
     129           5 :   delete ring_buffer;
     130           5 : }
     131             : 
     132          10 : void PopulateJSONWriter(TraceWriter* writer) {
     133          10 :   v8::Platform* old_platform = i::V8::GetCurrentPlatform();
     134             :   std::unique_ptr<v8::Platform> default_platform(
     135          20 :       v8::platform::NewDefaultPlatform());
     136          10 :   i::V8::SetPlatformForTesting(default_platform.get());
     137             :   auto tracing = base::make_unique<v8::platform::tracing::TracingController>();
     138             :   v8::platform::tracing::TracingController* tracing_controller = tracing.get();
     139             :   static_cast<v8::platform::DefaultPlatform*>(default_platform.get())
     140          20 :       ->SetTracingController(std::move(tracing));
     141             : 
     142             :   TraceBuffer* ring_buffer =
     143          10 :       TraceBuffer::CreateTraceBufferRingBuffer(1, writer);
     144          10 :   tracing_controller->Initialize(ring_buffer);
     145          10 :   TraceConfig* trace_config = new TraceConfig();
     146          10 :   trace_config->AddIncludedCategory("v8-cat");
     147          10 :   tracing_controller->StartTracing(trace_config);
     148             : 
     149          10 :   TraceObject trace_object;
     150          10 :   trace_object.InitializeForTesting(
     151          10 :       'X', tracing_controller->GetCategoryGroupEnabled("v8-cat"), "Test0",
     152             :       v8::internal::tracing::kGlobalScope, 42, 0x1234, 0, nullptr, nullptr,
     153          10 :       nullptr, nullptr, TRACE_EVENT_FLAG_HAS_ID, 11, 22, 100, 50, 33, 44);
     154          10 :   writer->AppendTraceEvent(&trace_object);
     155          10 :   trace_object.InitializeForTesting(
     156          10 :       'Y', tracing_controller->GetCategoryGroupEnabled("v8-cat"), "Test1",
     157             :       v8::internal::tracing::kGlobalScope, 43, 0x5678, 0, nullptr, nullptr,
     158             :       nullptr, nullptr, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
     159          10 :       55, 66, 110, 55, 77, 88);
     160          10 :   writer->AppendTraceEvent(&trace_object);
     161          10 :   tracing_controller->StopTracing();
     162          10 :   i::V8::SetPlatformForTesting(old_platform);
     163          10 : }
     164             : 
     165       26644 : TEST(TestJSONTraceWriter) {
     166          10 :   std::ostringstream stream;
     167           5 :   TraceWriter* writer = TraceWriter::CreateJSONTraceWriter(stream);
     168           5 :   PopulateJSONWriter(writer);
     169             :   std::string trace_str = stream.str();
     170             :   std::string expected_trace_str =
     171             :       "{\"traceEvents\":[{\"pid\":11,\"tid\":22,\"ts\":100,\"tts\":50,"
     172             :       "\"ph\":\"X\",\"cat\":\"v8-cat\",\"name\":\"Test0\",\"dur\":33,"
     173             :       "\"tdur\":44,\"id\":\"0x2a\",\"args\":{}},{\"pid\":55,\"tid\":66,"
     174             :       "\"ts\":110,\"tts\":55,\"ph\":\"Y\",\"cat\":\"v8-cat\",\"name\":"
     175             :       "\"Test1\",\"dur\":77,\"tdur\":88,\"bind_id\":\"0x5678\","
     176           5 :       "\"flow_in\":true,\"flow_out\":true,\"args\":{}}]}";
     177             : 
     178           5 :   CHECK_EQ(expected_trace_str, trace_str);
     179           5 : }
     180             : 
     181       26644 : TEST(TestJSONTraceWriterWithCustomtag) {
     182          10 :   std::ostringstream stream;
     183          10 :   TraceWriter* writer = TraceWriter::CreateJSONTraceWriter(stream, "customTag");
     184           5 :   PopulateJSONWriter(writer);
     185             :   std::string trace_str = stream.str();
     186             :   std::string expected_trace_str =
     187             :       "{\"customTag\":[{\"pid\":11,\"tid\":22,\"ts\":100,\"tts\":50,"
     188             :       "\"ph\":\"X\",\"cat\":\"v8-cat\",\"name\":\"Test0\",\"dur\":33,"
     189             :       "\"tdur\":44,\"id\":\"0x2a\",\"args\":{}},{\"pid\":55,\"tid\":66,"
     190             :       "\"ts\":110,\"tts\":55,\"ph\":\"Y\",\"cat\":\"v8-cat\",\"name\":"
     191             :       "\"Test1\",\"dur\":77,\"tdur\":88,\"bind_id\":\"0x5678\","
     192           5 :       "\"flow_in\":true,\"flow_out\":true,\"args\":{}}]}";
     193             : 
     194           5 :   CHECK_EQ(expected_trace_str, trace_str);
     195           5 : }
     196             : 
     197       26644 : TEST(TestTracingController) {
     198           5 :   v8::Platform* old_platform = i::V8::GetCurrentPlatform();
     199             :   std::unique_ptr<v8::Platform> default_platform(
     200          10 :       v8::platform::NewDefaultPlatform());
     201           5 :   i::V8::SetPlatformForTesting(default_platform.get());
     202             : 
     203             :   auto tracing = base::make_unique<v8::platform::tracing::TracingController>();
     204             :   v8::platform::tracing::TracingController* tracing_controller = tracing.get();
     205             :   static_cast<v8::platform::DefaultPlatform*>(default_platform.get())
     206          10 :       ->SetTracingController(std::move(tracing));
     207             : 
     208           5 :   MockTraceWriter* writer = new MockTraceWriter();
     209             :   TraceBuffer* ring_buffer =
     210           5 :       TraceBuffer::CreateTraceBufferRingBuffer(1, writer);
     211           5 :   tracing_controller->Initialize(ring_buffer);
     212           5 :   TraceConfig* trace_config = new TraceConfig();
     213           5 :   trace_config->AddIncludedCategory("v8");
     214           5 :   tracing_controller->StartTracing(trace_config);
     215             : 
     216          15 :   TRACE_EVENT0("v8", "v8.Test");
     217             :   // cat category is not included in default config
     218          15 :   TRACE_EVENT0("cat", "v8.Test2");
     219          15 :   TRACE_EVENT0("v8", "v8.Test3");
     220           5 :   tracing_controller->StopTracing();
     221             : 
     222           5 :   CHECK_EQ(2u, writer->events().size());
     223          10 :   CHECK_EQ(std::string("v8.Test"), writer->events()[0]);
     224          10 :   CHECK_EQ(std::string("v8.Test3"), writer->events()[1]);
     225             : 
     226           5 :   i::V8::SetPlatformForTesting(old_platform);
     227           5 : }
     228             : 
     229          15 : void GetJSONStrings(std::vector<std::string>& ret, std::string str,
     230             :                     std::string param, std::string start_delim,
     231             :                     std::string end_delim) {
     232             :   size_t pos = str.find(param);
     233         735 :   while (pos != std::string::npos) {
     234         360 :     size_t start_pos = str.find(start_delim, pos + param.length());
     235         360 :     size_t end_pos = str.find(end_delim, start_pos + 1);
     236         360 :     CHECK_NE(start_pos, std::string::npos);
     237         360 :     CHECK_NE(end_pos, std::string::npos);
     238         720 :     ret.push_back(str.substr(start_pos + 1, end_pos - start_pos - 1));
     239         360 :     pos = str.find(param, pos + 1);
     240             :   }
     241          15 : }
     242             : 
     243       26644 : TEST(TestTracingControllerMultipleArgsAndCopy) {
     244          10 :   std::ostringstream stream;
     245           5 :   uint64_t aa = 11;
     246             :   unsigned int bb = 22;
     247             :   uint16_t cc = 33;
     248             :   unsigned char dd = 44;
     249             :   int64_t ee = -55;
     250             :   int ff = -66;
     251             :   int16_t gg = -77;
     252             :   signed char hh = -88;
     253             :   bool ii1 = true;
     254             :   bool ii2 = false;
     255             :   double jj1 = 99.0;
     256             :   double jj2 = 1e100;
     257             :   double jj3 = std::numeric_limits<double>::quiet_NaN();
     258             :   double jj4 = std::numeric_limits<double>::infinity();
     259             :   double jj5 = -std::numeric_limits<double>::infinity();
     260             :   void* kk = &aa;
     261             :   const char* ll = "100";
     262           5 :   std::string mm = "INIT";
     263           5 :   std::string mmm = "\"INIT\"";
     264             : 
     265             :   // Create a scope for the tracing controller to terminate the trace writer.
     266             :   {
     267           5 :     v8::Platform* old_platform = i::V8::GetCurrentPlatform();
     268             :     std::unique_ptr<v8::Platform> default_platform(
     269          10 :         v8::platform::NewDefaultPlatform());
     270           5 :     i::V8::SetPlatformForTesting(default_platform.get());
     271             : 
     272             :     auto tracing =
     273             :         base::make_unique<v8::platform::tracing::TracingController>();
     274             :     v8::platform::tracing::TracingController* tracing_controller =
     275             :         tracing.get();
     276             :     static_cast<v8::platform::DefaultPlatform*>(default_platform.get())
     277          10 :         ->SetTracingController(std::move(tracing));
     278           5 :     TraceWriter* writer = TraceWriter::CreateJSONTraceWriter(stream);
     279             : 
     280             :     TraceBuffer* ring_buffer =
     281           5 :         TraceBuffer::CreateTraceBufferRingBuffer(1, writer);
     282           5 :     tracing_controller->Initialize(ring_buffer);
     283           5 :     TraceConfig* trace_config = new TraceConfig();
     284           5 :     trace_config->AddIncludedCategory("v8");
     285           5 :     tracing_controller->StartTracing(trace_config);
     286             : 
     287          15 :     TRACE_EVENT1("v8", "v8.Test.aa", "aa", aa);
     288          15 :     TRACE_EVENT1("v8", "v8.Test.bb", "bb", bb);
     289          15 :     TRACE_EVENT1("v8", "v8.Test.cc", "cc", cc);
     290          15 :     TRACE_EVENT1("v8", "v8.Test.dd", "dd", dd);
     291          15 :     TRACE_EVENT1("v8", "v8.Test.ee", "ee", ee);
     292          15 :     TRACE_EVENT1("v8", "v8.Test.ff", "ff", ff);
     293          15 :     TRACE_EVENT1("v8", "v8.Test.gg", "gg", gg);
     294          15 :     TRACE_EVENT1("v8", "v8.Test.hh", "hh", hh);
     295          15 :     TRACE_EVENT1("v8", "v8.Test.ii", "ii1", ii1);
     296          15 :     TRACE_EVENT1("v8", "v8.Test.ii", "ii2", ii2);
     297          15 :     TRACE_EVENT1("v8", "v8.Test.jj1", "jj1", jj1);
     298          15 :     TRACE_EVENT1("v8", "v8.Test.jj2", "jj2", jj2);
     299          15 :     TRACE_EVENT1("v8", "v8.Test.jj3", "jj3", jj3);
     300          15 :     TRACE_EVENT1("v8", "v8.Test.jj4", "jj4", jj4);
     301          15 :     TRACE_EVENT1("v8", "v8.Test.jj5", "jj5", jj5);
     302          15 :     TRACE_EVENT1("v8", "v8.Test.kk", "kk", kk);
     303          15 :     TRACE_EVENT1("v8", "v8.Test.ll", "ll", ll);
     304          15 :     TRACE_EVENT1("v8", "v8.Test.mm", "mm", TRACE_STR_COPY(mmm.c_str()));
     305             : 
     306          15 :     TRACE_EVENT2("v8", "v8.Test2.1", "aa", aa, "ll", ll);
     307          15 :     TRACE_EVENT2("v8", "v8.Test2.2", "mm1", TRACE_STR_COPY(mm.c_str()), "mm2",
     308             :                  TRACE_STR_COPY(mmm.c_str()));
     309             : 
     310             :     // Check copies are correct.
     311          10 :     TRACE_EVENT_COPY_INSTANT0("v8", mm.c_str(), TRACE_EVENT_SCOPE_THREAD);
     312          10 :     TRACE_EVENT_COPY_INSTANT2("v8", mm.c_str(), TRACE_EVENT_SCOPE_THREAD, "mm1",
     313             :                               mm.c_str(), "mm2", mmm.c_str());
     314             :     mm = "CHANGED";
     315             :     mmm = "CHANGED";
     316             : 
     317          10 :     TRACE_EVENT_INSTANT1("v8", "v8.Test", TRACE_EVENT_SCOPE_THREAD, "a1",
     318             :                          new ConvertableToTraceFormatMock(42));
     319             :     std::unique_ptr<ConvertableToTraceFormatMock> trace_event_arg(
     320           5 :         new ConvertableToTraceFormatMock(42));
     321          10 :     TRACE_EVENT_INSTANT2("v8", "v8.Test", TRACE_EVENT_SCOPE_THREAD, "a1",
     322             :                          std::move(trace_event_arg), "a2",
     323             :                          new ConvertableToTraceFormatMock(123));
     324             : 
     325           5 :     tracing_controller->StopTracing();
     326             : 
     327           5 :     i::V8::SetPlatformForTesting(old_platform);
     328             :   }
     329             : 
     330             :   std::string trace_str = stream.str();
     331             : 
     332           5 :   std::vector<std::string> all_args, all_names, all_cats;
     333          30 :   GetJSONStrings(all_args, trace_str, "\"args\"", "{", "}");
     334          30 :   GetJSONStrings(all_names, trace_str, "\"name\"", "\"", "\"");
     335          30 :   GetJSONStrings(all_cats, trace_str, "\"cat\"", "\"", "\"");
     336             : 
     337           5 :   CHECK_EQ(all_args.size(), 24u);
     338           5 :   CHECK_EQ(all_args[0], "\"aa\":11");
     339           5 :   CHECK_EQ(all_args[1], "\"bb\":22");
     340           5 :   CHECK_EQ(all_args[2], "\"cc\":33");
     341           5 :   CHECK_EQ(all_args[3], "\"dd\":44");
     342           5 :   CHECK_EQ(all_args[4], "\"ee\":-55");
     343           5 :   CHECK_EQ(all_args[5], "\"ff\":-66");
     344           5 :   CHECK_EQ(all_args[6], "\"gg\":-77");
     345           5 :   CHECK_EQ(all_args[7], "\"hh\":-88");
     346           5 :   CHECK_EQ(all_args[8], "\"ii1\":true");
     347           5 :   CHECK_EQ(all_args[9], "\"ii2\":false");
     348           5 :   CHECK_EQ(all_args[10], "\"jj1\":99.0");
     349           5 :   CHECK_EQ(all_args[11], "\"jj2\":1e+100");
     350           5 :   CHECK_EQ(all_args[12], "\"jj3\":\"NaN\"");
     351           5 :   CHECK_EQ(all_args[13], "\"jj4\":\"Infinity\"");
     352           5 :   CHECK_EQ(all_args[14], "\"jj5\":\"-Infinity\"");
     353          10 :   std::ostringstream pointer_stream;
     354           5 :   pointer_stream << "\"kk\":\"" << &aa << "\"";
     355           5 :   CHECK_EQ(all_args[15], pointer_stream.str());
     356           5 :   CHECK_EQ(all_args[16], "\"ll\":\"100\"");
     357           5 :   CHECK_EQ(all_args[17], "\"mm\":\"\\\"INIT\\\"\"");
     358             : 
     359           5 :   CHECK_EQ(all_names[18], "v8.Test2.1");
     360           5 :   CHECK_EQ(all_args[18], "\"aa\":11,\"ll\":\"100\"");
     361           5 :   CHECK_EQ(all_args[19], "\"mm1\":\"INIT\",\"mm2\":\"\\\"INIT\\\"\"");
     362             : 
     363           5 :   CHECK_EQ(all_names[20], "INIT");
     364           5 :   CHECK_EQ(all_names[21], "INIT");
     365           5 :   CHECK_EQ(all_args[21], "\"mm1\":\"INIT\",\"mm2\":\"\\\"INIT\\\"\"");
     366           5 :   CHECK_EQ(all_args[22], "\"a1\":[42,42]");
     367           5 :   CHECK_EQ(all_args[23], "\"a1\":[42,42],\"a2\":[123,123]");
     368           5 : }
     369             : 
     370             : namespace {
     371             : 
     372          15 : class TraceStateObserverImpl : public TracingController::TraceStateObserver {
     373             :  public:
     374          10 :   void OnTraceEnabled() override { ++enabled_count; }
     375           5 :   void OnTraceDisabled() override { ++disabled_count; }
     376             : 
     377             :   int enabled_count = 0;
     378             :   int disabled_count = 0;
     379             : };
     380             : 
     381             : }  // namespace
     382             : 
     383       26644 : TEST(TracingObservers) {
     384           5 :   v8::Platform* old_platform = i::V8::GetCurrentPlatform();
     385             :   std::unique_ptr<v8::Platform> default_platform(
     386          10 :       v8::platform::NewDefaultPlatform());
     387           5 :   i::V8::SetPlatformForTesting(default_platform.get());
     388             : 
     389             :   auto tracing = base::make_unique<v8::platform::tracing::TracingController>();
     390             :   v8::platform::tracing::TracingController* tracing_controller = tracing.get();
     391             :   static_cast<v8::platform::DefaultPlatform*>(default_platform.get())
     392          10 :       ->SetTracingController(std::move(tracing));
     393           5 :   MockTraceWriter* writer = new MockTraceWriter();
     394             :   v8::platform::tracing::TraceBuffer* ring_buffer =
     395             :       v8::platform::tracing::TraceBuffer::CreateTraceBufferRingBuffer(1,
     396           5 :                                                                       writer);
     397           5 :   tracing_controller->Initialize(ring_buffer);
     398             :   v8::platform::tracing::TraceConfig* trace_config =
     399           5 :       new v8::platform::tracing::TraceConfig();
     400           5 :   trace_config->AddIncludedCategory("v8");
     401             : 
     402           5 :   TraceStateObserverImpl observer;
     403           5 :   tracing_controller->AddTraceStateObserver(&observer);
     404             : 
     405           5 :   CHECK_EQ(0, observer.enabled_count);
     406           5 :   CHECK_EQ(0, observer.disabled_count);
     407             : 
     408           5 :   tracing_controller->StartTracing(trace_config);
     409             : 
     410           5 :   CHECK_EQ(1, observer.enabled_count);
     411           5 :   CHECK_EQ(0, observer.disabled_count);
     412             : 
     413           5 :   TraceStateObserverImpl observer2;
     414           5 :   tracing_controller->AddTraceStateObserver(&observer2);
     415             : 
     416           5 :   CHECK_EQ(1, observer2.enabled_count);
     417           5 :   CHECK_EQ(0, observer2.disabled_count);
     418             : 
     419           5 :   tracing_controller->RemoveTraceStateObserver(&observer2);
     420             : 
     421           5 :   CHECK_EQ(1, observer2.enabled_count);
     422           5 :   CHECK_EQ(0, observer2.disabled_count);
     423             : 
     424           5 :   tracing_controller->StopTracing();
     425             : 
     426           5 :   CHECK_EQ(1, observer.enabled_count);
     427           5 :   CHECK_EQ(1, observer.disabled_count);
     428           5 :   CHECK_EQ(1, observer2.enabled_count);
     429           5 :   CHECK_EQ(0, observer2.disabled_count);
     430             : 
     431           5 :   tracing_controller->RemoveTraceStateObserver(&observer);
     432             : 
     433           5 :   CHECK_EQ(1, observer.enabled_count);
     434           5 :   CHECK_EQ(1, observer.disabled_count);
     435             : 
     436           5 :   trace_config = new v8::platform::tracing::TraceConfig();
     437           5 :   tracing_controller->StartTracing(trace_config);
     438           5 :   tracing_controller->StopTracing();
     439             : 
     440           5 :   CHECK_EQ(1, observer.enabled_count);
     441           5 :   CHECK_EQ(1, observer.disabled_count);
     442             : 
     443           5 :   i::V8::SetPlatformForTesting(old_platform);
     444           5 : }
     445             : 
     446           5 : class TraceWritingThread : public base::Thread {
     447             :  public:
     448             :   TraceWritingThread(
     449             :       v8::platform::tracing::TracingController* tracing_controller)
     450             :       : base::Thread(base::Thread::Options("TraceWritingThread")),
     451           5 :         tracing_controller_(tracing_controller) {}
     452             : 
     453           5 :   void Run() override {
     454       10005 :     for (int i = 0; i < 1000; i++) {
     455       15000 :       TRACE_EVENT0("v8", "v8.Test");
     456        5000 :       tracing_controller_->AddTraceEvent('A', nullptr, "v8", "", 1, 1, 0,
     457        5000 :                                          nullptr, nullptr, nullptr, nullptr, 0);
     458        5000 :       tracing_controller_->AddTraceEventWithTimestamp('A', nullptr, "v8", "", 1,
     459             :                                                       1, 0, nullptr, nullptr,
     460        5000 :                                                       nullptr, nullptr, 0, 0);
     461        5000 :       base::OS::Sleep(base::TimeDelta::FromMilliseconds(1));
     462             :     }
     463           5 :   }
     464             : 
     465             :  private:
     466             :   v8::platform::tracing::TracingController* tracing_controller_;
     467             : };
     468             : 
     469       26644 : TEST(AddTraceEventMultiThreaded) {
     470           5 :   v8::Platform* old_platform = i::V8::GetCurrentPlatform();
     471             :   std::unique_ptr<v8::Platform> default_platform(
     472          10 :       v8::platform::NewDefaultPlatform());
     473           5 :   i::V8::SetPlatformForTesting(default_platform.get());
     474             : 
     475             :   auto tracing = base::make_unique<v8::platform::tracing::TracingController>();
     476             :   v8::platform::tracing::TracingController* tracing_controller = tracing.get();
     477             :   static_cast<v8::platform::DefaultPlatform*>(default_platform.get())
     478          10 :       ->SetTracingController(std::move(tracing));
     479             : 
     480           5 :   MockTraceWriter* writer = new MockTraceWriter();
     481             :   TraceBuffer* ring_buffer =
     482           5 :       TraceBuffer::CreateTraceBufferRingBuffer(1, writer);
     483           5 :   tracing_controller->Initialize(ring_buffer);
     484           5 :   TraceConfig* trace_config = new TraceConfig();
     485           5 :   trace_config->AddIncludedCategory("v8");
     486           5 :   tracing_controller->StartTracing(trace_config);
     487             : 
     488             :   TraceWritingThread thread(tracing_controller);
     489           5 :   thread.StartSynchronously();
     490             : 
     491           5 :   base::OS::Sleep(base::TimeDelta::FromMilliseconds(100));
     492           5 :   tracing_controller->StopTracing();
     493             : 
     494           5 :   thread.Join();
     495             : 
     496           5 :   i::V8::SetPlatformForTesting(old_platform);
     497           5 : }
     498             : 
     499             : }  // namespace tracing
     500             : }  // namespace platform
     501       79917 : }  // namespace v8

Generated by: LCOV version 1.10