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

Generated by: LCOV version 1.10