From 6526c6dd107f03883ea3c5632b8fff9e5e43250d Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Tue, 14 Nov 2017 10:15:41 +0100 Subject: [PATCH] [RCS] Add explicit tests for function callbacks This CL adds a very crude unittest to check that RuntimeCallStats work correctly with api callbacks present. This currently doesn't check that all parent timers (namely FunctionCallback) are handled properly. Drive-by-Fix: - Use Microseconds for all RCS timer tests - Add TestWithContext::SetGlobalProperty helper - Use explicit v8:: prefix in test-utils.{h,cc} Change-Id: I054e78abca0b87a3b9e07d3b06cccdad15403bae Reviewed-on: https://chromium-review.googlesource.com/766429 Commit-Queue: Camillo Bruni Reviewed-by: Georg Neis Cr-Commit-Position: refs/heads/master@{#49348} --- src/accessors.cc | 1 + src/counters.cc | 5 + src/counters.h | 2 + src/isolate.cc | 3 +- test/unittests/counters-unittest.cc | 262 +++++++++++++++++++++++----- test/unittests/test-utils.cc | 11 ++ test/unittests/test-utils.h | 23 +-- 7 files changed, 249 insertions(+), 58 deletions(-) diff --git a/src/accessors.cc b/src/accessors.cc index 4a6ee9de5f..78529fb78e 100644 --- a/src/accessors.cc +++ b/src/accessors.cc @@ -683,6 +683,7 @@ void Accessors::FunctionLengthGetter( v8::Local name, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); + RuntimeCallTimerScope timer(isolate, &RuntimeCallStats::FunctionLengthGetter); HandleScope scope(isolate); Handle function = Handle::cast(Utils::OpenHandle(*info.Holder())); diff --git a/src/counters.cc b/src/counters.cc index 46be156cb9..c754e6fdef 100644 --- a/src/counters.cc +++ b/src/counters.cc @@ -527,6 +527,11 @@ bool RuntimeCallStats::IsCalledOnTheSameThread() { return true; } +void RuntimeCallStats::Print() { + OFStream os(stdout); + Print(os); +} + void RuntimeCallStats::Print(std::ostream& os) { RuntimeCallStatEntries entries; if (current_timer_.Value() != nullptr) { diff --git a/src/counters.h b/src/counters.h index 1e334f973c..e71784c95a 100644 --- a/src/counters.h +++ b/src/counters.h @@ -803,6 +803,7 @@ class RuntimeCallTimer final { V(FunctionCallback) \ V(FunctionPrototypeGetter) \ V(FunctionPrototypeSetter) \ + V(FunctionLengthGetter) \ V(GC_Custom_AllAvailableGarbage) \ V(GC_Custom_IncrementalMarkingObserver) \ V(GC_Custom_SlowAllocateRaw) \ @@ -956,6 +957,7 @@ class RuntimeCallStats final : public ZoneObject { // Add all entries from another stats object. void Add(RuntimeCallStats* other); V8_EXPORT_PRIVATE void Print(std::ostream& os); + V8_EXPORT_PRIVATE void Print(); V8_NOINLINE void Dump(v8::tracing::TracedValue* value); ThreadId thread_id() const { return thread_id_; } diff --git a/src/isolate.cc b/src/isolate.cc index a29ea42024..5a2e695db3 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -3033,8 +3033,7 @@ void Isolate::DumpAndResetStats() { turbo_statistics_ = nullptr; if (V8_UNLIKELY(FLAG_runtime_stats == v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE)) { - OFStream os(stdout); - counters()->runtime_call_stats()->Print(os); + counters()->runtime_call_stats()->Print(); counters()->runtime_call_stats()->Reset(); } } diff --git a/test/unittests/counters-unittest.cc b/test/unittests/counters-unittest.cc index ea1a722945..d32d01060e 100644 --- a/test/unittests/counters-unittest.cc +++ b/test/unittests/counters-unittest.cc @@ -10,6 +10,8 @@ #include "src/handles-inl.h" #include "src/objects-inl.h" #include "src/tracing/tracing-category-observer.h" + +#include "test/unittests/test-utils.h" #include "testing/gtest/include/gtest/gtest.h" namespace v8 { @@ -44,50 +46,103 @@ class AggregatedMemoryHistogramTest : public ::testing::Test { }; static base::TimeTicks runtime_call_stats_test_time_ = base::TimeTicks(); +// Time source used for the RuntimeCallTimer during tests. We cannot rely on +// the native timer since it's too unpredictable on the build bots. static base::TimeTicks RuntimeCallStatsTestNow() { return runtime_call_stats_test_time_; } -class RuntimeCallStatsTest : public ::testing::Test { +class RuntimeCallStatsTest : public TestWithNativeContext { public: RuntimeCallStatsTest() { FLAG_runtime_stats = v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE; - RuntimeCallTimer::Now = &RuntimeCallStatsTestNow; // We need to set {time_} to a non-zero value since it would otherwise // cause runtime call timers to think they are uninitialized. Sleep(1); + stats()->Reset(); } - virtual ~RuntimeCallStatsTest() { + + ~RuntimeCallStatsTest() { + // Disable RuntimeCallStats before tearing down the isolate to prevent + // printing the tests table. Comment the following line for debugging + // purposes. + FLAG_runtime_stats = 0; + } + + static void SetUpTestCase() { + TestWithIsolate::SetUpTestCase(); + // Use a custom time source to precisly emulate system time. + RuntimeCallTimer::Now = &RuntimeCallStatsTestNow; + } + + static void TearDownTestCase() { + TestWithIsolate::TearDownTestCase(); + // Restore the original time source. RuntimeCallTimer::Now = &base::TimeTicks::HighResolutionNow; } - RuntimeCallStats* stats() { return &stats_; } + RuntimeCallStats* stats() { + return isolate()->counters()->runtime_call_stats(); + } + + // Print current RuntimeCallStats table. For debugging purposes. + void PrintStats() { stats()->Print(); } + RuntimeCallStats::CounterId counter_id() { return &RuntimeCallStats::TestCounter1; } + RuntimeCallStats::CounterId counter_id2() { return &RuntimeCallStats::TestCounter2; } + RuntimeCallStats::CounterId counter_id3() { return &RuntimeCallStats::TestCounter3; } + + RuntimeCallCounter* js_counter() { return &stats()->JS_Execution; } RuntimeCallCounter* counter() { return &(stats()->*counter_id()); } RuntimeCallCounter* counter2() { return &(stats()->*counter_id2()); } RuntimeCallCounter* counter3() { return &(stats()->*counter_id3()); } - void Sleep(int32_t milliseconds) { - base::TimeDelta delta = base::TimeDelta::FromMilliseconds(milliseconds); + void Sleep(int64_t microseconds) { + base::TimeDelta delta = base::TimeDelta::FromMicroseconds(microseconds); time_ += delta; runtime_call_stats_test_time_ = base::TimeTicks::FromInternalValue(time_.InMicroseconds()); } private: - RuntimeCallStats stats_; base::TimeDelta time_; }; +// Temporarily use the native time to modify the test time. +class ElapsedTimeScope { + public: + explicit ElapsedTimeScope(RuntimeCallStatsTest* test) : test_(test) { + timer_.Start(); + } + ~ElapsedTimeScope() { test_->Sleep(timer_.Elapsed().InMicroseconds()); } + + private: + base::ElapsedTimer timer_; + RuntimeCallStatsTest* test_; +}; + +// Temporarily use the default time source. +class NativeTimeScope { + public: + NativeTimeScope() { + CHECK_EQ(RuntimeCallTimer::Now, &RuntimeCallStatsTestNow); + RuntimeCallTimer::Now = &base::TimeTicks::HighResolutionNow; + } + ~NativeTimeScope() { + CHECK_EQ(RuntimeCallTimer::Now, &base::TimeTicks::HighResolutionNow); + RuntimeCallTimer::Now = &RuntimeCallStatsTestNow; + } +}; + } // namespace @@ -257,7 +312,7 @@ TEST_F(RuntimeCallStatsTest, RuntimeCallTimer) { Sleep(50); EXPECT_FALSE(timer.IsStarted()); EXPECT_EQ(1, counter()->count()); - EXPECT_EQ(100, counter()->time().InMilliseconds()); + EXPECT_EQ(100, counter()->time().InMicroseconds()); } TEST_F(RuntimeCallStatsTest, RuntimeCallTimerSubTimer) { @@ -290,8 +345,8 @@ TEST_F(RuntimeCallStatsTest, RuntimeCallTimerSubTimer) { EXPECT_FALSE(timer2.IsStarted()); EXPECT_EQ(0, counter()->count()); EXPECT_EQ(1, counter2()->count()); - EXPECT_EQ(0, counter()->time().InMilliseconds()); - EXPECT_EQ(100, counter2()->time().InMilliseconds()); + EXPECT_EQ(0, counter()->time().InMicroseconds()); + EXPECT_EQ(100, counter2()->time().InMicroseconds()); EXPECT_EQ(&timer, stats()->current_timer()); Sleep(100); @@ -300,8 +355,8 @@ TEST_F(RuntimeCallStatsTest, RuntimeCallTimerSubTimer) { EXPECT_FALSE(timer.IsStarted()); EXPECT_EQ(1, counter()->count()); EXPECT_EQ(1, counter2()->count()); - EXPECT_EQ(150, counter()->time().InMilliseconds()); - EXPECT_EQ(100, counter2()->time().InMilliseconds()); + EXPECT_EQ(150, counter()->time().InMicroseconds()); + EXPECT_EQ(100, counter2()->time().InMicroseconds()); EXPECT_EQ(nullptr, stats()->current_timer()); } @@ -329,14 +384,14 @@ TEST_F(RuntimeCallStatsTest, RuntimeCallTimerRecursive) { EXPECT_FALSE(timer2.IsStarted()); EXPECT_TRUE(timer.IsStarted()); EXPECT_EQ(1, counter()->count()); - EXPECT_EQ(50, counter()->time().InMilliseconds()); + EXPECT_EQ(50, counter()->time().InMicroseconds()); Sleep(100); RuntimeCallStats::Leave(stats(), &timer); EXPECT_FALSE(timer.IsStarted()); EXPECT_EQ(2, counter()->count()); - EXPECT_EQ(150, counter()->time().InMilliseconds()); + EXPECT_EQ(150, counter()->time().InMicroseconds()); } TEST_F(RuntimeCallStatsTest, RuntimeCallTimerScope) { @@ -346,13 +401,13 @@ TEST_F(RuntimeCallStatsTest, RuntimeCallTimerScope) { } Sleep(100); EXPECT_EQ(1, counter()->count()); - EXPECT_EQ(50, counter()->time().InMilliseconds()); + EXPECT_EQ(50, counter()->time().InMicroseconds()); { RuntimeCallTimerScope scope(stats(), counter_id()); Sleep(50); } EXPECT_EQ(2, counter()->count()); - EXPECT_EQ(100, counter()->time().InMilliseconds()); + EXPECT_EQ(100, counter()->time().InMicroseconds()); } TEST_F(RuntimeCallStatsTest, RuntimeCallTimerScopeRecursive) { @@ -360,16 +415,16 @@ TEST_F(RuntimeCallStatsTest, RuntimeCallTimerScopeRecursive) { RuntimeCallTimerScope scope(stats(), counter_id()); Sleep(50); EXPECT_EQ(0, counter()->count()); - EXPECT_EQ(0, counter()->time().InMilliseconds()); + EXPECT_EQ(0, counter()->time().InMicroseconds()); { RuntimeCallTimerScope scope(stats(), counter_id()); Sleep(50); } EXPECT_EQ(1, counter()->count()); - EXPECT_EQ(50, counter()->time().InMilliseconds()); + EXPECT_EQ(50, counter()->time().InMicroseconds()); } EXPECT_EQ(2, counter()->count()); - EXPECT_EQ(100, counter()->time().InMilliseconds()); + EXPECT_EQ(100, counter()->time().InMicroseconds()); } TEST_F(RuntimeCallStatsTest, RenameTimer) { @@ -378,8 +433,8 @@ TEST_F(RuntimeCallStatsTest, RenameTimer) { Sleep(50); EXPECT_EQ(0, counter()->count()); EXPECT_EQ(0, counter2()->count()); - EXPECT_EQ(0, counter()->time().InMilliseconds()); - EXPECT_EQ(0, counter2()->time().InMilliseconds()); + EXPECT_EQ(0, counter()->time().InMicroseconds()); + EXPECT_EQ(0, counter2()->time().InMicroseconds()); { RuntimeCallTimerScope scope(stats(), counter_id()); Sleep(100); @@ -387,13 +442,13 @@ TEST_F(RuntimeCallStatsTest, RenameTimer) { CHANGE_CURRENT_RUNTIME_COUNTER(stats(), TestCounter2); EXPECT_EQ(1, counter()->count()); EXPECT_EQ(0, counter2()->count()); - EXPECT_EQ(100, counter()->time().InMilliseconds()); - EXPECT_EQ(0, counter2()->time().InMilliseconds()); + EXPECT_EQ(100, counter()->time().InMicroseconds()); + EXPECT_EQ(0, counter2()->time().InMicroseconds()); } EXPECT_EQ(1, counter()->count()); EXPECT_EQ(1, counter2()->count()); - EXPECT_EQ(100, counter()->time().InMilliseconds()); - EXPECT_EQ(50, counter2()->time().InMilliseconds()); + EXPECT_EQ(100, counter()->time().InMicroseconds()); + EXPECT_EQ(50, counter2()->time().InMicroseconds()); } TEST_F(RuntimeCallStatsTest, BasicPrintAndSnapshot) { @@ -402,9 +457,9 @@ TEST_F(RuntimeCallStatsTest, BasicPrintAndSnapshot) { EXPECT_EQ(0, counter()->count()); EXPECT_EQ(0, counter2()->count()); EXPECT_EQ(0, counter3()->count()); - EXPECT_EQ(0, counter()->time().InMilliseconds()); - EXPECT_EQ(0, counter2()->time().InMilliseconds()); - EXPECT_EQ(0, counter3()->time().InMilliseconds()); + EXPECT_EQ(0, counter()->time().InMicroseconds()); + EXPECT_EQ(0, counter2()->time().InMicroseconds()); + EXPECT_EQ(0, counter3()->time().InMicroseconds()); { RuntimeCallTimerScope scope(stats(), counter_id()); @@ -415,9 +470,9 @@ TEST_F(RuntimeCallStatsTest, BasicPrintAndSnapshot) { EXPECT_EQ(1, counter()->count()); EXPECT_EQ(0, counter2()->count()); EXPECT_EQ(0, counter3()->count()); - EXPECT_EQ(50, counter()->time().InMilliseconds()); - EXPECT_EQ(0, counter2()->time().InMilliseconds()); - EXPECT_EQ(0, counter3()->time().InMilliseconds()); + EXPECT_EQ(50, counter()->time().InMicroseconds()); + EXPECT_EQ(0, counter2()->time().InMicroseconds()); + EXPECT_EQ(0, counter3()->time().InMicroseconds()); } TEST_F(RuntimeCallStatsTest, PrintAndSnapshot) { @@ -425,11 +480,11 @@ TEST_F(RuntimeCallStatsTest, PrintAndSnapshot) { RuntimeCallTimerScope scope(stats(), counter_id()); Sleep(100); EXPECT_EQ(0, counter()->count()); - EXPECT_EQ(0, counter()->time().InMilliseconds()); + EXPECT_EQ(0, counter()->time().InMicroseconds()); { RuntimeCallTimerScope scope(stats(), counter_id2()); EXPECT_EQ(0, counter2()->count()); - EXPECT_EQ(0, counter2()->time().InMilliseconds()); + EXPECT_EQ(0, counter2()->time().InMicroseconds()); Sleep(50); // This calls Snapshot on the current active timer and sychronizes and @@ -438,35 +493,35 @@ TEST_F(RuntimeCallStatsTest, PrintAndSnapshot) { stats()->Print(out); EXPECT_EQ(0, counter()->count()); EXPECT_EQ(0, counter2()->count()); - EXPECT_EQ(100, counter()->time().InMilliseconds()); - EXPECT_EQ(50, counter2()->time().InMilliseconds()); + EXPECT_EQ(100, counter()->time().InMicroseconds()); + EXPECT_EQ(50, counter2()->time().InMicroseconds()); // Calling Print several times shouldn't have a (big) impact on the // measured times. stats()->Print(out); EXPECT_EQ(0, counter()->count()); EXPECT_EQ(0, counter2()->count()); - EXPECT_EQ(100, counter()->time().InMilliseconds()); - EXPECT_EQ(50, counter2()->time().InMilliseconds()); + EXPECT_EQ(100, counter()->time().InMicroseconds()); + EXPECT_EQ(50, counter2()->time().InMicroseconds()); Sleep(50); stats()->Print(out); EXPECT_EQ(0, counter()->count()); EXPECT_EQ(0, counter2()->count()); - EXPECT_EQ(100, counter()->time().InMilliseconds()); - EXPECT_EQ(100, counter2()->time().InMilliseconds()); + EXPECT_EQ(100, counter()->time().InMicroseconds()); + EXPECT_EQ(100, counter2()->time().InMicroseconds()); Sleep(50); } Sleep(50); EXPECT_EQ(0, counter()->count()); EXPECT_EQ(1, counter2()->count()); - EXPECT_EQ(100, counter()->time().InMilliseconds()); - EXPECT_EQ(150, counter2()->time().InMilliseconds()); + EXPECT_EQ(100, counter()->time().InMicroseconds()); + EXPECT_EQ(150, counter2()->time().InMicroseconds()); Sleep(50); } EXPECT_EQ(1, counter()->count()); EXPECT_EQ(1, counter2()->count()); - EXPECT_EQ(200, counter()->time().InMilliseconds()); - EXPECT_EQ(150, counter2()->time().InMilliseconds()); + EXPECT_EQ(200, counter()->time().InMicroseconds()); + EXPECT_EQ(150, counter2()->time().InMicroseconds()); } TEST_F(RuntimeCallStatsTest, NestedScopes) { @@ -497,9 +552,124 @@ TEST_F(RuntimeCallStatsTest, NestedScopes) { EXPECT_EQ(1, counter()->count()); EXPECT_EQ(2, counter2()->count()); EXPECT_EQ(2, counter3()->count()); - EXPECT_EQ(250, counter()->time().InMilliseconds()); - EXPECT_EQ(300, counter2()->time().InMilliseconds()); - EXPECT_EQ(100, counter3()->time().InMilliseconds()); + EXPECT_EQ(250, counter()->time().InMicroseconds()); + EXPECT_EQ(300, counter2()->time().InMicroseconds()); + EXPECT_EQ(100, counter3()->time().InMicroseconds()); +} + +TEST_F(RuntimeCallStatsTest, BasicJavaScript) { + RuntimeCallCounter* counter = &stats()->JS_Execution; + EXPECT_EQ(0, counter->count()); + EXPECT_EQ(0, counter->time().InMicroseconds()); + + { + NativeTimeScope native_timer_scope; + RunJS("function f() { return 1; }"); + } + EXPECT_EQ(1, counter->count()); + int64_t time = counter->time().InMicroseconds(); + EXPECT_LT(0, time); + + { + NativeTimeScope native_timer_scope; + RunJS("f()"); + } + EXPECT_EQ(2, counter->count()); + EXPECT_LE(time, counter->time().InMicroseconds()); +} + +TEST_F(RuntimeCallStatsTest, FunctionLengthGetter) { + RuntimeCallCounter* getter_counter = &stats()->FunctionLengthGetter; + RuntimeCallCounter* js_counter = &stats()->JS_Execution; + EXPECT_EQ(0, getter_counter->count()); + EXPECT_EQ(0, js_counter->count()); + EXPECT_EQ(0, getter_counter->time().InMicroseconds()); + EXPECT_EQ(0, js_counter->time().InMicroseconds()); + + { + NativeTimeScope native_timer_scope; + RunJS("function f(array) { return array.length; }"); + } + EXPECT_EQ(0, getter_counter->count()); + EXPECT_EQ(1, js_counter->count()); + EXPECT_EQ(0, getter_counter->time().InMicroseconds()); + int64_t js_time = js_counter->time().InMicroseconds(); + EXPECT_LT(0, js_time); + + { + NativeTimeScope native_timer_scope; + RunJS("f.length"); + } + EXPECT_EQ(1, getter_counter->count()); + EXPECT_EQ(2, js_counter->count()); + EXPECT_LE(0, getter_counter->time().InMicroseconds()); + EXPECT_LT(js_time, js_counter->time().InMicroseconds()); + + { + NativeTimeScope native_timer_scope; + RunJS("for (let i = 0; i < 50; i++) { f.length }"); + } + EXPECT_EQ(51, getter_counter->count()); + EXPECT_EQ(3, js_counter->count()); +} + +namespace { +static RuntimeCallStatsTest* current_test; +static const int kCustomCallbackTime = 1234; +static void CustomCallback(const v8::FunctionCallbackInfo& info) { + RuntimeCallTimerScope scope(current_test->stats(), + current_test->counter_id2()); + current_test->Sleep(kCustomCallbackTime); +} +} // namespace + +TEST_F(RuntimeCallStatsTest, CustomCallback) { + current_test = this; + // Set up a function template with a custom callback. + v8::Isolate* isolate = v8_isolate(); + v8::HandleScope scope(isolate); + + v8::Local object_template = + v8::ObjectTemplate::New(isolate); + object_template->Set(isolate, "callback", + v8::FunctionTemplate::New(isolate, CustomCallback)); + v8::Local object = + object_template->NewInstance(v8_context()).ToLocalChecked(); + SetGlobalProperty("custom_object", object); + + // TODO(cbruni): Check api accessor timer (one above the custom callback). + EXPECT_EQ(0, js_counter()->count()); + EXPECT_EQ(0, counter()->count()); + EXPECT_EQ(0, counter2()->count()); + { + RuntimeCallTimerScope scope(stats(), counter_id()); + Sleep(100); + RunJS("custom_object.callback();"); + } + EXPECT_EQ(1, js_counter()->count()); + // Given that no native timers are used, only the two scopes explitly + // mentioned above will track the time. + EXPECT_EQ(0, js_counter()->time().InMicroseconds()); + EXPECT_EQ(1, counter()->count()); + EXPECT_EQ(100, counter()->time().InMicroseconds()); + EXPECT_EQ(1, counter2()->count()); + EXPECT_EQ(kCustomCallbackTime, counter2()->time().InMicroseconds()); + + RunJS("for (let i = 0; i < 9; i++) { custom_object.callback() };"); + EXPECT_EQ(2, js_counter()->count()); + EXPECT_EQ(0, js_counter()->time().InMicroseconds()); + EXPECT_EQ(1, counter()->count()); + EXPECT_EQ(100, counter()->time().InMicroseconds()); + EXPECT_EQ(10, counter2()->count()); + EXPECT_EQ(kCustomCallbackTime * 10, counter2()->time().InMicroseconds()); + + RunJS("for (let i = 0; i < 4000; i++) { custom_object.callback() };"); + EXPECT_EQ(3, js_counter()->count()); + EXPECT_EQ(0, js_counter()->time().InMicroseconds()); + EXPECT_EQ(1, counter()->count()); + EXPECT_EQ(100, counter()->time().InMicroseconds()); + EXPECT_EQ(4010, counter2()->count()); + EXPECT_EQ(kCustomCallbackTime * 4010, counter2()->time().InMicroseconds()); } } // namespace internal diff --git a/test/unittests/test-utils.cc b/test/unittests/test-utils.cc index 0228508b55..354d1b7d2d 100644 --- a/test/unittests/test-utils.cc +++ b/test/unittests/test-utils.cc @@ -68,6 +68,17 @@ TestWithContext::TestWithContext() TestWithContext::~TestWithContext() {} +void TestWithContext::SetGlobalProperty(const char* name, + v8::Local value) { + v8::Local property_name = + v8::String::NewFromUtf8(v8_isolate(), name, v8::NewStringType::kNormal) + .ToLocalChecked(); + CHECK(v8_context() + ->Global() + ->Set(v8_context(), property_name, value) + .FromJust()); +} + namespace internal { TestWithIsolate::~TestWithIsolate() {} diff --git a/test/unittests/test-utils.h b/test/unittests/test-utils.h index a059b1899e..17a5eb7c21 100644 --- a/test/unittests/test-utils.h +++ b/test/unittests/test-utils.h @@ -29,7 +29,9 @@ class TestWithIsolate : public virtual ::testing::Test { TestWithIsolate(); virtual ~TestWithIsolate(); - Isolate* isolate() const { return isolate_; } + v8::Isolate* isolate() const { return v8_isolate(); } + + v8::Isolate* v8_isolate() const { return isolate_; } v8::internal::Isolate* i_isolate() const { return reinterpret_cast(isolate()); @@ -42,25 +44,28 @@ class TestWithIsolate : public virtual ::testing::Test { private: static v8::ArrayBuffer::Allocator* array_buffer_allocator_; - static Isolate* isolate_; - Isolate::Scope isolate_scope_; - HandleScope handle_scope_; + static v8::Isolate* isolate_; + v8::Isolate::Scope isolate_scope_; + v8::HandleScope handle_scope_; DISALLOW_COPY_AND_ASSIGN(TestWithIsolate); }; // Use v8::internal::TestWithNativeContext if you are testing internals, // aka. directly work with Handles. -class TestWithContext : public virtual TestWithIsolate { +class TestWithContext : public virtual v8::TestWithIsolate { public: TestWithContext(); virtual ~TestWithContext(); - const Local& context() const { return context_; } + const Local& context() const { return v8_context(); } + const Local& v8_context() const { return context_; } + + void SetGlobalProperty(const char* name, v8::Local value); private: Local context_; - Context::Scope context_scope_; + v8::Context::Scope context_scope_; DISALLOW_COPY_AND_ASSIGN(TestWithContext); }; @@ -77,9 +82,7 @@ class TestWithIsolate : public virtual ::v8::TestWithIsolate { virtual ~TestWithIsolate(); Factory* factory() const; - Isolate* isolate() const { - return reinterpret_cast(::v8::TestWithIsolate::isolate()); - } + Isolate* isolate() const { return i_isolate(); } template Handle RunJS(const char* source) { Handle result =