LCOV - code coverage report
Current view: top level - test/cctest - test-trace-event.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 202 202 100.0 %
Date: 2019-01-20 Functions: 23 25 92.0 %

          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             : 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         140 :         timestamp(timestamp) {}
      35             : };
      36             : 
      37             : typedef std::vector<MockTraceObject*> MockTraceObjectList;
      38             : 
      39             : class MockTracingController : public v8::TracingController {
      40             :  public:
      41          55 :   MockTracingController() = default;
      42          55 :   ~MockTracingController() override {
      43         390 :     for (size_t i = 0; i < trace_object_list_.size(); ++i) {
      44         475 :       delete trace_object_list_[i];
      45             :     }
      46             :     trace_object_list_.clear();
      47          55 :   }
      48             : 
      49         115 :   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             :     return AddTraceEventWithTimestamp(
      57             :         phase, category_enabled_flag, name, scope, id, bind_id, num_args,
      58         115 :         arg_names, arg_types, arg_values, arg_convertables, flags, 0);
      59             :   }
      60             : 
      61         140 :   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         420 :         phase, std::string(name), id, bind_id, num_args, flags, timestamp);
      70         140 :     trace_object_list_.push_back(to);
      71         140 :     return 0;
      72             :   }
      73             : 
      74          35 :   void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
      75          35 :                                 const char* name, uint64_t handle) override {}
      76             : 
      77         180 :   const uint8_t* GetCategoryGroupEnabled(const char* name) override {
      78         180 :     if (strncmp(name, "v8-cat", 6)) {
      79             :       static uint8_t no = 0;
      80             :       return &no;
      81             :     } else {
      82             :       static uint8_t yes = 0x7;
      83         150 :       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         110 :   MockTracingPlatform() {
      98             :     // Now that it's completely constructed, make this the current platform.
      99          55 :     i::V8::SetPlatformForTesting(this);
     100          55 :   }
     101         110 :   ~MockTracingPlatform() override = default;
     102             : 
     103         355 :   v8::TracingController* GetTracingController() override {
     104         355 :     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       28342 : 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       28342 : 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          10 :   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       28342 : TEST(TraceEventWithOneArg) {
     145           5 :   MockTracingPlatform platform;
     146             : 
     147          15 :   TRACE_EVENT_BEGIN1("v8-cat", "e1", "arg1", 42);
     148          15 :   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          10 :   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       28342 : TEST(TraceEventWithTwoArgs) {
     162           5 :   MockTracingPlatform platform;
     163             : 
     164          15 :   TRACE_EVENT_BEGIN2("v8-cat", "e1", "arg1", 42, "arg2", "abc");
     165          15 :   TRACE_EVENT_END2("v8-cat", "e1", "arg1", 42, "arg2", "abc");
     166          15 :   TRACE_EVENT_BEGIN2("v8-cat", "e2", "arg1", "abc", "arg2", 43);
     167          15 :   TRACE_EVENT_END2("v8-cat", "e2", "arg1", "abc", "arg2", 43);
     168             : 
     169          10 :   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       28342 : TEST(ScopedTraceEvent) {
     179           5 :   MockTracingPlatform platform;
     180             : 
     181          15 :   { TRACE_EVENT0("v8-cat", "e"); }
     182             : 
     183          10 :   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          10 :   CHECK_EQ(2, GET_TRACE_OBJECTS_LIST->size());
     189           5 :   CHECK_EQ(1, GET_TRACE_OBJECT(1)->num_args);
     190             : 
     191          20 :   { TRACE_EVENT2("v8-cat", "e1", "arg1", "abc", "arg2", 42); }
     192             : 
     193          10 :   CHECK_EQ(3, GET_TRACE_OBJECTS_LIST->size());
     194           5 :   CHECK_EQ(2, GET_TRACE_OBJECT(2)->num_args);
     195           5 : }
     196             : 
     197             : 
     198       28342 : 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          10 :     TRACE_EVENT_WITH_FLOW0(
     207             :         "v8-cat", "f2", bind_id,
     208           5 :         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          10 :   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       28342 : 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          10 :   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       28342 : TEST(TestEventInContext) {
     238           5 :   MockTracingPlatform platform;
     239             : 
     240             :   static uint64_t isolate_id = 0x20151021;
     241             :   {
     242          45 :     TRACE_EVENT_SCOPED_CONTEXT("v8-cat", "Isolate", isolate_id);
     243          15 :     TRACE_EVENT0("v8-cat", "e");
     244             :   }
     245             : 
     246          10 :   CHECK_EQ(3, GET_TRACE_OBJECTS_LIST->size());
     247           5 :   CHECK_EQ(TRACE_EVENT_PHASE_ENTER_CONTEXT, GET_TRACE_OBJECT(0)->phase);
     248          10 :   CHECK_EQ("Isolate", GET_TRACE_OBJECT(0)->name);
     249           5 :   CHECK_EQ(isolate_id, GET_TRACE_OBJECT(0)->id);
     250           5 :   CHECK_EQ(TRACE_EVENT_PHASE_COMPLETE, GET_TRACE_OBJECT(1)->phase);
     251          10 :   CHECK_EQ("e", GET_TRACE_OBJECT(1)->name);
     252           5 :   CHECK_EQ(TRACE_EVENT_PHASE_LEAVE_CONTEXT, GET_TRACE_OBJECT(2)->phase);
     253          10 :   CHECK_EQ("Isolate", GET_TRACE_OBJECT(2)->name);
     254           5 :   CHECK_EQ(isolate_id, GET_TRACE_OBJECT(2)->id);
     255           5 : }
     256             : 
     257       28342 : TEST(TestEventWithTimestamp) {
     258           5 :   MockTracingPlatform platform;
     259             : 
     260          10 :   TRACE_EVENT_INSTANT_WITH_TIMESTAMP0("v8-cat", "0arg",
     261             :                                       TRACE_EVENT_SCOPE_GLOBAL, 1729);
     262          15 :   TRACE_EVENT_INSTANT_WITH_TIMESTAMP1("v8-cat", "1arg",
     263             :                                       TRACE_EVENT_SCOPE_GLOBAL, 4104, "val", 1);
     264          15 :   TRACE_EVENT_MARK_WITH_TIMESTAMP2("v8-cat", "mark", 13832, "a", 1, "b", 2);
     265             : 
     266          10 :   TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0("v8-cat", "begin", 5,
     267             :                                                         20683);
     268          10 :   TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TIMESTAMP0("v8-cat", "end", 5,
     269             :                                                       32832);
     270             : 
     271          10 :   CHECK_EQ(5, GET_TRACE_OBJECTS_LIST->size());
     272             : 
     273           5 :   CHECK_EQ(1729, GET_TRACE_OBJECT(0)->timestamp);
     274           5 :   CHECK_EQ(0, GET_TRACE_OBJECT(0)->num_args);
     275             : 
     276           5 :   CHECK_EQ(4104, GET_TRACE_OBJECT(1)->timestamp);
     277           5 :   CHECK_EQ(1, GET_TRACE_OBJECT(1)->num_args);
     278             : 
     279           5 :   CHECK_EQ(13832, GET_TRACE_OBJECT(2)->timestamp);
     280           5 :   CHECK_EQ(2, GET_TRACE_OBJECT(2)->num_args);
     281             : 
     282           5 :   CHECK_EQ(20683, GET_TRACE_OBJECT(3)->timestamp);
     283           5 :   CHECK_EQ(32832, GET_TRACE_OBJECT(4)->timestamp);
     284           5 : }
     285             : 
     286       28342 : TEST(BuiltinsIsTraceCategoryEnabled) {
     287           5 :   CcTest::InitializeVM();
     288           5 :   MockTracingPlatform platform;
     289             : 
     290           5 :   v8::Isolate* isolate = CcTest::isolate();
     291          10 :   v8::HandleScope handle_scope(isolate);
     292          10 :   LocalContext env;
     293             : 
     294           5 :   v8::Local<v8::Object> binding = env->GetExtrasBindingObject();
     295           5 :   CHECK(!binding.IsEmpty());
     296             : 
     297             :   auto undefined = v8::Undefined(isolate);
     298             :   auto isTraceCategoryEnabled =
     299          15 :       binding->Get(env.local(), v8_str("isTraceCategoryEnabled"))
     300           5 :           .ToLocalChecked()
     301             :           .As<v8::Function>();
     302             : 
     303             :   {
     304             :     // Test with an enabled category
     305           5 :     v8::Local<v8::Value> argv[] = {v8_str("v8-cat")};
     306          10 :     auto result = isTraceCategoryEnabled->Call(env.local(), undefined, 1, argv)
     307           5 :                       .ToLocalChecked()
     308             :                       .As<v8::Boolean>();
     309             : 
     310           5 :     CHECK(result->BooleanValue(isolate));
     311             :   }
     312             : 
     313             :   {
     314             :     // Test with a disabled category
     315           5 :     v8::Local<v8::Value> argv[] = {v8_str("cat")};
     316          10 :     auto result = isTraceCategoryEnabled->Call(env.local(), undefined, 1, argv)
     317           5 :                       .ToLocalChecked()
     318             :                       .As<v8::Boolean>();
     319             : 
     320           5 :     CHECK(!result->BooleanValue(isolate));
     321             :   }
     322             : 
     323             :   {
     324             :     // Test with an enabled utf8 category
     325           5 :     v8::Local<v8::Value> argv[] = {v8_str("v8-cat\u20ac")};
     326          10 :     auto result = isTraceCategoryEnabled->Call(env.local(), undefined, 1, argv)
     327           5 :                       .ToLocalChecked()
     328             :                       .As<v8::Boolean>();
     329             : 
     330           5 :     CHECK(result->BooleanValue(isolate));
     331           5 :   }
     332           5 : }
     333             : 
     334       28342 : TEST(BuiltinsTrace) {
     335           5 :   CcTest::InitializeVM();
     336           5 :   MockTracingPlatform platform;
     337             : 
     338           5 :   v8::Isolate* isolate = CcTest::isolate();
     339          10 :   v8::HandleScope handle_scope(isolate);
     340           5 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
     341          10 :   LocalContext env;
     342             : 
     343           5 :   v8::Local<v8::Object> binding = env->GetExtrasBindingObject();
     344           5 :   CHECK(!binding.IsEmpty());
     345             : 
     346             :   auto undefined = v8::Undefined(isolate);
     347          15 :   auto trace = binding->Get(env.local(), v8_str("trace"))
     348           5 :                    .ToLocalChecked()
     349             :                    .As<v8::Function>();
     350             : 
     351             :   // Test with disabled category
     352             :   {
     353           5 :     v8::Local<v8::String> category = v8_str("cat");
     354           5 :     v8::Local<v8::String> name = v8_str("name");
     355             :     v8::Local<v8::Value> argv[] = {
     356             :         v8::Integer::New(isolate, 'b'),                // phase
     357             :         category, name, v8::Integer::New(isolate, 0),  // id
     358             :         undefined                                      // data
     359          10 :     };
     360          10 :     auto result = trace->Call(env.local(), undefined, 5, argv)
     361           5 :                       .ToLocalChecked()
     362             :                       .As<v8::Boolean>();
     363             : 
     364           5 :     CHECK(!result->BooleanValue(isolate));
     365          10 :     CHECK_EQ(0, GET_TRACE_OBJECTS_LIST->size());
     366             :   }
     367             : 
     368             :   // Test with enabled category
     369             :   {
     370           5 :     v8::Local<v8::String> category = v8_str("v8-cat");
     371           5 :     v8::Local<v8::String> name = v8_str("name");
     372           5 :     v8::Local<v8::Object> data = v8::Object::New(isolate);
     373          20 :     data->Set(context, v8_str("foo"), v8_str("bar")).FromJust();
     374             :     v8::Local<v8::Value> argv[] = {
     375             :         v8::Integer::New(isolate, 'b'),                  // phase
     376             :         category, name, v8::Integer::New(isolate, 123),  // id
     377             :         data                                             // data arg
     378          10 :     };
     379          10 :     auto result = trace->Call(env.local(), undefined, 5, argv)
     380           5 :                       .ToLocalChecked()
     381             :                       .As<v8::Boolean>();
     382             : 
     383           5 :     CHECK(result->BooleanValue(isolate));
     384          10 :     CHECK_EQ(1, GET_TRACE_OBJECTS_LIST->size());
     385             : 
     386          10 :     CHECK_EQ(123, GET_TRACE_OBJECT(0)->id);
     387           5 :     CHECK_EQ('b', GET_TRACE_OBJECT(0)->phase);
     388          10 :     CHECK_EQ("name", GET_TRACE_OBJECT(0)->name);
     389           5 :     CHECK_EQ(1, GET_TRACE_OBJECT(0)->num_args);
     390             :   }
     391             : 
     392             :   // Test with enabled utf8 category
     393             :   {
     394           5 :     v8::Local<v8::String> category = v8_str("v8-cat\u20ac");
     395           5 :     v8::Local<v8::String> name = v8_str("name\u20ac");
     396           5 :     v8::Local<v8::Object> data = v8::Object::New(isolate);
     397          20 :     data->Set(context, v8_str("foo"), v8_str("bar")).FromJust();
     398             :     v8::Local<v8::Value> argv[] = {
     399             :         v8::Integer::New(isolate, 'b'),                  // phase
     400             :         category, name, v8::Integer::New(isolate, 123),  // id
     401             :         data                                             // data arg
     402          10 :     };
     403          10 :     auto result = trace->Call(env.local(), undefined, 5, argv)
     404           5 :                       .ToLocalChecked()
     405             :                       .As<v8::Boolean>();
     406             : 
     407           5 :     CHECK(result->BooleanValue(isolate));
     408          10 :     CHECK_EQ(2, GET_TRACE_OBJECTS_LIST->size());
     409             : 
     410          10 :     CHECK_EQ(123, GET_TRACE_OBJECT(1)->id);
     411           5 :     CHECK_EQ('b', GET_TRACE_OBJECT(1)->phase);
     412          10 :     CHECK_EQ("name\u20ac", GET_TRACE_OBJECT(1)->name);
     413           5 :     CHECK_EQ(1, GET_TRACE_OBJECT(1)->num_args);
     414           5 :   }
     415       85016 : }

Generated by: LCOV version 1.10