LCOV - code coverage report
Current view: top level - test/cctest - test-trace-event.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 176 176 100.0 %
Date: 2019-04-17 Functions: 19 22 86.4 %

          Line data    Source code
       1             : // Copyright 2015 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 <stdlib.h>
       5             : #include <string.h>
       6             : 
       7             : #include "src/v8.h"
       8             : 
       9             : #include "src/base/template-utils.h"
      10             : #include "test/cctest/cctest.h"
      11             : 
      12             : #include "src/tracing/trace-event.h"
      13             : 
      14             : namespace {
      15             : 
      16         125 : struct MockTraceObject {
      17             :   char phase;
      18             :   std::string name;
      19             :   uint64_t id;
      20             :   uint64_t bind_id;
      21             :   int num_args;
      22             :   unsigned int flags;
      23             :   int64_t timestamp;
      24             :   MockTraceObject(char phase, std::string name, uint64_t id, uint64_t bind_id,
      25             :                   int num_args, int flags, int64_t timestamp)
      26             :       : phase(phase),
      27             :         name(name),
      28             :         id(id),
      29             :         bind_id(bind_id),
      30             :         num_args(num_args),
      31             :         flags(flags),
      32         250 :         timestamp(timestamp) {}
      33             : };
      34             : 
      35         100 : class MockTracingController : public v8::TracingController {
      36             :  public:
      37          50 :   MockTracingController() = default;
      38             : 
      39         100 :   uint64_t AddTraceEvent(
      40             :       char phase, const uint8_t* category_enabled_flag, const char* name,
      41             :       const char* scope, uint64_t id, uint64_t bind_id, int num_args,
      42             :       const char** arg_names, const uint8_t* arg_types,
      43             :       const uint64_t* arg_values,
      44             :       std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
      45             :       unsigned int flags) override {
      46         100 :     return AddTraceEventWithTimestamp(
      47             :         phase, category_enabled_flag, name, scope, id, bind_id, num_args,
      48         100 :         arg_names, arg_types, arg_values, arg_convertables, flags, 0);
      49             :   }
      50             : 
      51         125 :   uint64_t AddTraceEventWithTimestamp(
      52             :       char phase, const uint8_t* category_enabled_flag, const char* name,
      53             :       const char* scope, uint64_t id, uint64_t bind_id, int num_args,
      54             :       const char** arg_names, const uint8_t* arg_types,
      55             :       const uint64_t* arg_values,
      56             :       std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
      57             :       unsigned int flags, int64_t timestamp) override {
      58             :     std::unique_ptr<MockTraceObject> to =
      59             :         v8::base::make_unique<MockTraceObject>(
      60         250 :             phase, std::string(name), id, bind_id, num_args, flags, timestamp);
      61         125 :     trace_objects_.push_back(std::move(to));
      62         125 :     return 0;
      63             :   }
      64             : 
      65          30 :   void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
      66          30 :                                 const char* name, uint64_t handle) override {}
      67             : 
      68         166 :   const uint8_t* GetCategoryGroupEnabled(const char* name) override {
      69         166 :     if (strncmp(name, "v8-cat", 6)) {
      70             :       static uint8_t no = 0;
      71             :       return &no;
      72             :     } else {
      73             :       static uint8_t yes = 0x7;
      74         135 :       return &yes;
      75             :     }
      76             :   }
      77             : 
      78             :   const std::vector<std::unique_ptr<MockTraceObject>>& GetMockTraceObjects()
      79             :       const {
      80             :     return trace_objects_;
      81             :   }
      82             : 
      83             :  private:
      84             :   std::vector<std::unique_ptr<MockTraceObject>> trace_objects_;
      85             : 
      86             :   DISALLOW_COPY_AND_ASSIGN(MockTracingController);
      87             : };
      88             : 
      89             : class MockTracingPlatform : public TestPlatform {
      90             :  public:
      91         100 :   MockTracingPlatform() {
      92             :     // Now that it's completely constructed, make this the current platform.
      93          50 :     i::V8::SetPlatformForTesting(this);
      94          50 :   }
      95         100 :   ~MockTracingPlatform() override = default;
      96             : 
      97         321 :   v8::TracingController* GetTracingController() override {
      98         321 :     return &tracing_controller_;
      99             :   }
     100             : 
     101             :   size_t NumberOfTraceObjects() {
     102             :     return tracing_controller_.GetMockTraceObjects().size();
     103             :   }
     104             : 
     105             :   MockTraceObject* GetTraceObject(size_t index) {
     106             :     return tracing_controller_.GetMockTraceObjects().at(index).get();
     107             :   }
     108             : 
     109             :  private:
     110             :   MockTracingController tracing_controller_;
     111             : };
     112             : 
     113             : }  // namespace
     114             : 
     115       26644 : TEST(TraceEventDisabledCategory) {
     116          10 :   MockTracingPlatform platform;
     117             : 
     118             :   // Disabled category, will not add events.
     119          10 :   TRACE_EVENT_BEGIN0("cat", "e1");
     120          10 :   TRACE_EVENT_END0("cat", "e1");
     121           5 :   CHECK_EQ(0, platform.NumberOfTraceObjects());
     122           5 : }
     123             : 
     124       26644 : TEST(TraceEventNoArgs) {
     125          10 :   MockTracingPlatform platform;
     126             : 
     127             :   // Enabled category will add 2 events.
     128          10 :   TRACE_EVENT_BEGIN0("v8-cat", "e1");
     129          10 :   TRACE_EVENT_END0("v8-cat", "e1");
     130             : 
     131           5 :   CHECK_EQ(2, platform.NumberOfTraceObjects());
     132           5 :   CHECK_EQ('B', platform.GetTraceObject(0)->phase);
     133          10 :   CHECK_EQ("e1", platform.GetTraceObject(0)->name);
     134           5 :   CHECK_EQ(0, platform.GetTraceObject(0)->num_args);
     135             : 
     136           5 :   CHECK_EQ('E', platform.GetTraceObject(1)->phase);
     137          10 :   CHECK_EQ("e1", platform.GetTraceObject(1)->name);
     138           5 :   CHECK_EQ(0, platform.GetTraceObject(1)->num_args);
     139           5 : }
     140             : 
     141       26644 : TEST(TraceEventWithOneArg) {
     142          10 :   MockTracingPlatform platform;
     143             : 
     144          10 :   TRACE_EVENT_BEGIN1("v8-cat", "e1", "arg1", 42);
     145          10 :   TRACE_EVENT_END1("v8-cat", "e1", "arg1", 42);
     146          10 :   TRACE_EVENT_BEGIN1("v8-cat", "e2", "arg1", "abc");
     147          10 :   TRACE_EVENT_END1("v8-cat", "e2", "arg1", "abc");
     148             : 
     149           5 :   CHECK_EQ(4, platform.NumberOfTraceObjects());
     150             : 
     151           5 :   CHECK_EQ(1, platform.GetTraceObject(0)->num_args);
     152           5 :   CHECK_EQ(1, platform.GetTraceObject(1)->num_args);
     153           5 :   CHECK_EQ(1, platform.GetTraceObject(2)->num_args);
     154           5 :   CHECK_EQ(1, platform.GetTraceObject(3)->num_args);
     155           5 : }
     156             : 
     157       26644 : TEST(TraceEventWithTwoArgs) {
     158          10 :   MockTracingPlatform platform;
     159             : 
     160          10 :   TRACE_EVENT_BEGIN2("v8-cat", "e1", "arg1", 42, "arg2", "abc");
     161          10 :   TRACE_EVENT_END2("v8-cat", "e1", "arg1", 42, "arg2", "abc");
     162          10 :   TRACE_EVENT_BEGIN2("v8-cat", "e2", "arg1", "abc", "arg2", 43);
     163          10 :   TRACE_EVENT_END2("v8-cat", "e2", "arg1", "abc", "arg2", 43);
     164             : 
     165           5 :   CHECK_EQ(4, platform.NumberOfTraceObjects());
     166             : 
     167           5 :   CHECK_EQ(2, platform.GetTraceObject(0)->num_args);
     168           5 :   CHECK_EQ(2, platform.GetTraceObject(1)->num_args);
     169           5 :   CHECK_EQ(2, platform.GetTraceObject(2)->num_args);
     170           5 :   CHECK_EQ(2, platform.GetTraceObject(3)->num_args);
     171           5 : }
     172             : 
     173       26644 : TEST(ScopedTraceEvent) {
     174          10 :   MockTracingPlatform platform;
     175             : 
     176          15 :   { TRACE_EVENT0("v8-cat", "e"); }
     177             : 
     178           5 :   CHECK_EQ(1, platform.NumberOfTraceObjects());
     179           5 :   CHECK_EQ(0, platform.GetTraceObject(0)->num_args);
     180             : 
     181          15 :   { TRACE_EVENT1("v8-cat", "e1", "arg1", "abc"); }
     182             : 
     183           5 :   CHECK_EQ(2, platform.NumberOfTraceObjects());
     184           5 :   CHECK_EQ(1, platform.GetTraceObject(1)->num_args);
     185             : 
     186          15 :   { TRACE_EVENT2("v8-cat", "e1", "arg1", "abc", "arg2", 42); }
     187             : 
     188           5 :   CHECK_EQ(3, platform.NumberOfTraceObjects());
     189           5 :   CHECK_EQ(2, platform.GetTraceObject(2)->num_args);
     190           5 : }
     191             : 
     192       26644 : TEST(TestEventWithFlow) {
     193          10 :   MockTracingPlatform platform;
     194             : 
     195             :   static uint64_t bind_id = 21;
     196             :   {
     197          15 :     TRACE_EVENT_WITH_FLOW0("v8-cat", "f1", bind_id, TRACE_EVENT_FLAG_FLOW_OUT);
     198             :   }
     199             :   {
     200          15 :     TRACE_EVENT_WITH_FLOW0(
     201             :         "v8-cat", "f2", bind_id,
     202             :         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
     203             :   }
     204          15 :   { TRACE_EVENT_WITH_FLOW0("v8-cat", "f3", bind_id, TRACE_EVENT_FLAG_FLOW_IN); }
     205             : 
     206           5 :   CHECK_EQ(3, platform.NumberOfTraceObjects());
     207           5 :   CHECK_EQ(bind_id, platform.GetTraceObject(0)->bind_id);
     208           5 :   CHECK_EQ(TRACE_EVENT_FLAG_FLOW_OUT, platform.GetTraceObject(0)->flags);
     209           5 :   CHECK_EQ(bind_id, platform.GetTraceObject(1)->bind_id);
     210           5 :   CHECK_EQ(TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
     211             :            platform.GetTraceObject(1)->flags);
     212           5 :   CHECK_EQ(bind_id, platform.GetTraceObject(2)->bind_id);
     213           5 :   CHECK_EQ(TRACE_EVENT_FLAG_FLOW_IN, platform.GetTraceObject(2)->flags);
     214           5 : }
     215             : 
     216       26644 : TEST(TestEventWithId) {
     217          10 :   MockTracingPlatform platform;
     218             : 
     219             :   static uint64_t event_id = 21;
     220          10 :   TRACE_EVENT_ASYNC_BEGIN0("v8-cat", "a1", event_id);
     221          10 :   TRACE_EVENT_ASYNC_END0("v8-cat", "a1", event_id);
     222             : 
     223           5 :   CHECK_EQ(2, platform.NumberOfTraceObjects());
     224           5 :   CHECK_EQ(TRACE_EVENT_PHASE_ASYNC_BEGIN, platform.GetTraceObject(0)->phase);
     225           5 :   CHECK_EQ(event_id, platform.GetTraceObject(0)->id);
     226           5 :   CHECK_EQ(TRACE_EVENT_PHASE_ASYNC_END, platform.GetTraceObject(1)->phase);
     227           5 :   CHECK_EQ(event_id, platform.GetTraceObject(1)->id);
     228           5 : }
     229             : 
     230       26644 : TEST(TestEventWithTimestamp) {
     231          10 :   MockTracingPlatform platform;
     232             : 
     233          10 :   TRACE_EVENT_INSTANT_WITH_TIMESTAMP0("v8-cat", "0arg",
     234             :                                       TRACE_EVENT_SCOPE_GLOBAL, 1729);
     235          10 :   TRACE_EVENT_INSTANT_WITH_TIMESTAMP1("v8-cat", "1arg",
     236             :                                       TRACE_EVENT_SCOPE_GLOBAL, 4104, "val", 1);
     237          10 :   TRACE_EVENT_MARK_WITH_TIMESTAMP2("v8-cat", "mark", 13832, "a", 1, "b", 2);
     238             : 
     239          10 :   TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0("v8-cat", "begin", 5,
     240             :                                                         20683);
     241          10 :   TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TIMESTAMP0("v8-cat", "end", 5,
     242             :                                                       32832);
     243             : 
     244           5 :   CHECK_EQ(5, platform.NumberOfTraceObjects());
     245             : 
     246           5 :   CHECK_EQ(1729, platform.GetTraceObject(0)->timestamp);
     247           5 :   CHECK_EQ(0, platform.GetTraceObject(0)->num_args);
     248             : 
     249           5 :   CHECK_EQ(4104, platform.GetTraceObject(1)->timestamp);
     250           5 :   CHECK_EQ(1, platform.GetTraceObject(1)->num_args);
     251             : 
     252           5 :   CHECK_EQ(13832, platform.GetTraceObject(2)->timestamp);
     253           5 :   CHECK_EQ(2, platform.GetTraceObject(2)->num_args);
     254             : 
     255           5 :   CHECK_EQ(20683, platform.GetTraceObject(3)->timestamp);
     256           5 :   CHECK_EQ(32832, platform.GetTraceObject(4)->timestamp);
     257           5 : }
     258             : 
     259       26644 : TEST(BuiltinsIsTraceCategoryEnabled) {
     260           5 :   CcTest::InitializeVM();
     261          10 :   MockTracingPlatform platform;
     262             : 
     263           5 :   v8::Isolate* isolate = CcTest::isolate();
     264          10 :   v8::HandleScope handle_scope(isolate);
     265           5 :   LocalContext env;
     266             : 
     267           5 :   v8::Local<v8::Object> binding = env->GetExtrasBindingObject();
     268           5 :   CHECK(!binding.IsEmpty());
     269             : 
     270             :   auto undefined = v8::Undefined(isolate);
     271             :   auto isTraceCategoryEnabled =
     272          15 :       binding->Get(env.local(), v8_str("isTraceCategoryEnabled"))
     273             :           .ToLocalChecked()
     274             :           .As<v8::Function>();
     275             : 
     276             :   {
     277             :     // Test with an enabled category
     278           5 :     v8::Local<v8::Value> argv[] = {v8_str("v8-cat")};
     279          10 :     auto result = isTraceCategoryEnabled->Call(env.local(), undefined, 1, argv)
     280             :                       .ToLocalChecked()
     281             :                       .As<v8::Boolean>();
     282             : 
     283           5 :     CHECK(result->BooleanValue(isolate));
     284             :   }
     285             : 
     286             :   {
     287             :     // Test with a disabled category
     288           5 :     v8::Local<v8::Value> argv[] = {v8_str("cat")};
     289          10 :     auto result = isTraceCategoryEnabled->Call(env.local(), undefined, 1, argv)
     290             :                       .ToLocalChecked()
     291             :                       .As<v8::Boolean>();
     292             : 
     293           5 :     CHECK(!result->BooleanValue(isolate));
     294             :   }
     295             : 
     296             :   {
     297             :     // Test with an enabled utf8 category
     298           5 :     v8::Local<v8::Value> argv[] = {v8_str("v8-cat\u20ac")};
     299          10 :     auto result = isTraceCategoryEnabled->Call(env.local(), undefined, 1, argv)
     300             :                       .ToLocalChecked()
     301             :                       .As<v8::Boolean>();
     302             : 
     303           5 :     CHECK(result->BooleanValue(isolate));
     304             :   }
     305           5 : }
     306             : 
     307       26644 : TEST(BuiltinsTrace) {
     308           5 :   CcTest::InitializeVM();
     309          10 :   MockTracingPlatform platform;
     310             : 
     311           5 :   v8::Isolate* isolate = CcTest::isolate();
     312          10 :   v8::HandleScope handle_scope(isolate);
     313           5 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
     314           5 :   LocalContext env;
     315             : 
     316           5 :   v8::Local<v8::Object> binding = env->GetExtrasBindingObject();
     317           5 :   CHECK(!binding.IsEmpty());
     318             : 
     319             :   auto undefined = v8::Undefined(isolate);
     320          15 :   auto trace = binding->Get(env.local(), v8_str("trace"))
     321             :                    .ToLocalChecked()
     322             :                    .As<v8::Function>();
     323             : 
     324             :   // Test with disabled category
     325             :   {
     326           5 :     v8::Local<v8::String> category = v8_str("cat");
     327           5 :     v8::Local<v8::String> name = v8_str("name");
     328             :     v8::Local<v8::Value> argv[] = {
     329             :         v8::Integer::New(isolate, 'b'),                // phase
     330             :         category, name, v8::Integer::New(isolate, 0),  // id
     331             :         undefined                                      // data
     332          10 :     };
     333          10 :     auto result = trace->Call(env.local(), undefined, 5, argv)
     334             :                       .ToLocalChecked()
     335             :                       .As<v8::Boolean>();
     336             : 
     337           5 :     CHECK(!result->BooleanValue(isolate));
     338           5 :     CHECK_EQ(0, platform.NumberOfTraceObjects());
     339             :   }
     340             : 
     341             :   // Test with enabled category
     342             :   {
     343           5 :     v8::Local<v8::String> category = v8_str("v8-cat");
     344           5 :     v8::Local<v8::String> name = v8_str("name");
     345           5 :     v8::Local<v8::Object> data = v8::Object::New(isolate);
     346          20 :     data->Set(context, v8_str("foo"), v8_str("bar")).FromJust();
     347             :     v8::Local<v8::Value> argv[] = {
     348             :         v8::Integer::New(isolate, 'b'),                  // phase
     349             :         category, name, v8::Integer::New(isolate, 123),  // id
     350             :         data                                             // data arg
     351          10 :     };
     352          10 :     auto result = trace->Call(env.local(), undefined, 5, argv)
     353             :                       .ToLocalChecked()
     354             :                       .As<v8::Boolean>();
     355             : 
     356           5 :     CHECK(result->BooleanValue(isolate));
     357           5 :     CHECK_EQ(1, platform.NumberOfTraceObjects());
     358             : 
     359          10 :     CHECK_EQ(123, platform.GetTraceObject(0)->id);
     360           5 :     CHECK_EQ('b', platform.GetTraceObject(0)->phase);
     361          10 :     CHECK_EQ("name", platform.GetTraceObject(0)->name);
     362           5 :     CHECK_EQ(1, platform.GetTraceObject(0)->num_args);
     363             :   }
     364             : 
     365             :   // Test with enabled utf8 category
     366             :   {
     367           5 :     v8::Local<v8::String> category = v8_str("v8-cat\u20ac");
     368           5 :     v8::Local<v8::String> name = v8_str("name\u20ac");
     369           5 :     v8::Local<v8::Object> data = v8::Object::New(isolate);
     370          20 :     data->Set(context, v8_str("foo"), v8_str("bar")).FromJust();
     371             :     v8::Local<v8::Value> argv[] = {
     372             :         v8::Integer::New(isolate, 'b'),                  // phase
     373             :         category, name, v8::Integer::New(isolate, 123),  // id
     374             :         data                                             // data arg
     375          10 :     };
     376          10 :     auto result = trace->Call(env.local(), undefined, 5, argv)
     377             :                       .ToLocalChecked()
     378             :                       .As<v8::Boolean>();
     379             : 
     380           5 :     CHECK(result->BooleanValue(isolate));
     381           5 :     CHECK_EQ(2, platform.NumberOfTraceObjects());
     382             : 
     383          10 :     CHECK_EQ(123, platform.GetTraceObject(1)->id);
     384           5 :     CHECK_EQ('b', platform.GetTraceObject(1)->phase);
     385          10 :     CHECK_EQ("name\u20ac", platform.GetTraceObject(1)->name);
     386           5 :     CHECK_EQ(1, platform.GetTraceObject(1)->num_args);
     387             :   }
     388       79922 : }

Generated by: LCOV version 1.10