LCOV - code coverage report
Current view: top level - test/cctest - cctest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 128 134 95.5 %
Date: 2017-10-20 Functions: 22 24 91.7 %

          Line data    Source code
       1             : // Copyright 2008 the V8 project authors. All rights reserved.
       2             : // Redistribution and use in source and binary forms, with or without
       3             : // modification, are permitted provided that the following conditions are
       4             : // met:
       5             : //
       6             : //     * Redistributions of source code must retain the above copyright
       7             : //       notice, this list of conditions and the following disclaimer.
       8             : //     * Redistributions in binary form must reproduce the above
       9             : //       copyright notice, this list of conditions and the following
      10             : //       disclaimer in the documentation and/or other materials provided
      11             : //       with the distribution.
      12             : //     * Neither the name of Google Inc. nor the names of its
      13             : //       contributors may be used to endorse or promote products derived
      14             : //       from this software without specific prior written permission.
      15             : //
      16             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      17             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      18             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      19             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      20             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      21             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      22             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      23             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      24             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      26             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27             : 
      28             : #include "include/v8.h"
      29             : #include "test/cctest/cctest.h"
      30             : 
      31             : #include "include/libplatform/libplatform.h"
      32             : #include "src/debug/debug.h"
      33             : #include "src/objects-inl.h"
      34             : #include "src/trap-handler/trap-handler.h"
      35             : #include "test/cctest/print-extension.h"
      36             : #include "test/cctest/profiler-extension.h"
      37             : #include "test/cctest/trace-extension.h"
      38             : 
      39             : #if V8_OS_WIN
      40             : #include <windows.h>  // NOLINT
      41             : #if V8_CC_MSVC
      42             : #include <crtdbg.h>
      43             : #endif
      44             : #endif
      45             : 
      46             : enum InitializationState { kUnset, kUninitialized, kInitialized };
      47             : static InitializationState initialization_state_ = kUnset;
      48             : static bool disable_automatic_dispose_ = false;
      49             : 
      50             : CcTest* CcTest::last_ = nullptr;
      51             : bool CcTest::initialize_called_ = false;
      52             : v8::base::Atomic32 CcTest::isolate_used_ = 0;
      53             : v8::ArrayBuffer::Allocator* CcTest::allocator_ = nullptr;
      54             : v8::Isolate* CcTest::isolate_ = nullptr;
      55             : 
      56   101868810 : CcTest::CcTest(TestFunction* callback, const char* file, const char* name,
      57             :                bool enabled, bool initialize)
      58             :     : callback_(callback),
      59             :       name_(name),
      60             :       enabled_(enabled),
      61             :       initialize_(initialize),
      62   101868810 :       prev_(last_) {
      63             :   // Find the base name of this test (const_cast required on Windows).
      64             :   char *basename = strrchr(const_cast<char *>(file), '/');
      65   101868810 :   if (!basename) {
      66             :     basename = strrchr(const_cast<char *>(file), '\\');
      67             :   }
      68   101868810 :   if (!basename) {
      69           0 :     basename = v8::internal::StrDup(file);
      70             :   } else {
      71   101868810 :     basename = v8::internal::StrDup(basename + 1);
      72             :   }
      73             :   // Drop the extension, if there is one.
      74             :   char *extension = strrchr(basename, '.');
      75   101868810 :   if (extension) *extension = 0;
      76             :   // Install this test in the list of tests
      77   101868810 :   file_ = basename;
      78   101868810 :   prev_ = last_;
      79   101868810 :   last_ = this;
      80   101868810 : }
      81             : 
      82             : 
      83       23717 : void CcTest::Run() {
      84       23717 :   if (!initialize_) {
      85         192 :     CHECK_NE(initialization_state_, kInitialized);
      86         192 :     initialization_state_ = kUninitialized;
      87         192 :     CHECK_NULL(CcTest::isolate_);
      88             :   } else {
      89       23525 :     CHECK_NE(initialization_state_, kUninitialized);
      90       23525 :     initialization_state_ = kInitialized;
      91       23525 :     if (isolate_ == nullptr) {
      92             :       v8::Isolate::CreateParams create_params;
      93       23525 :       create_params.array_buffer_allocator = allocator_;
      94       23525 :       isolate_ = v8::Isolate::New(create_params);
      95             :     }
      96       23525 :     isolate_->Enter();
      97             :   }
      98             : #ifdef DEBUG
      99             :   const size_t active_isolates = i::Isolate::non_disposed_isolates();
     100             : #endif  // DEBUG
     101       23717 :   callback_();
     102             : #ifdef DEBUG
     103             :   // This DCHECK ensures that all Isolates are properly disposed after finishing
     104             :   // the test. Stray Isolates lead to stray tasks in the platform which can
     105             :   // interact weirdly when swapping in new platforms (for testing) or during
     106             :   // shutdown.
     107             :   DCHECK_EQ(active_isolates, i::Isolate::non_disposed_isolates());
     108             : #endif  // DEBUG
     109       23699 :   if (initialize_) {
     110       23507 :     if (v8::Locker::IsActive()) {
     111         124 :       v8::Locker locker(isolate_);
     112         124 :       EmptyMessageQueues(isolate_);
     113             :     } else {
     114       23383 :       EmptyMessageQueues(isolate_);
     115             :     }
     116       23507 :     isolate_->Exit();
     117             :   }
     118       23699 : }
     119             : 
     120      652986 : i::Heap* CcTest::heap() { return i_isolate()->heap(); }
     121             : 
     122        2366 : void CcTest::CollectGarbage(i::AllocationSpace space) {
     123        2366 :   heap()->CollectGarbage(space, i::GarbageCollectionReason::kTesting);
     124        2366 : }
     125             : 
     126        3090 : void CcTest::CollectAllGarbage() {
     127        3090 :   CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
     128        3090 : }
     129             : 
     130        3728 : void CcTest::CollectAllGarbage(int flags) {
     131        3728 :   heap()->CollectAllGarbage(flags, i::GarbageCollectionReason::kTesting);
     132        3728 : }
     133             : 
     134         301 : void CcTest::CollectAllAvailableGarbage() {
     135         301 :   heap()->CollectAllAvailableGarbage(i::GarbageCollectionReason::kTesting);
     136         301 : }
     137             : 
     138          29 : v8::base::RandomNumberGenerator* CcTest::random_number_generator() {
     139          29 :   return InitIsolateOnce()->random_number_generator();
     140             : }
     141             : 
     142        7899 : v8::Local<v8::Object> CcTest::global() {
     143       15798 :   return isolate()->GetCurrentContext()->Global();
     144             : }
     145             : 
     146       14949 : void CcTest::InitializeVM() {
     147       14949 :   CHECK(!v8::base::Relaxed_Load(&isolate_used_));
     148       14949 :   CHECK(!initialize_called_);
     149       14949 :   initialize_called_ = true;
     150       14949 :   v8::HandleScope handle_scope(CcTest::isolate());
     151       29898 :   v8::Context::New(CcTest::isolate())->Enter();
     152       14949 : }
     153             : 
     154           0 : void CcTest::TearDown() {
     155       23700 :   if (isolate_ != nullptr) isolate_->Dispose();
     156           0 : }
     157             : 
     158          88 : v8::Local<v8::Context> CcTest::NewContext(CcTestExtensionFlags extensions,
     159             :                                           v8::Isolate* isolate) {
     160             :     const char* extension_names[kMaxExtensions];
     161             :     int extension_count = 0;
     162             :   #define CHECK_EXTENSION_FLAG(Name, Id) \
     163             :     if (extensions.Contains(Name##_ID)) extension_names[extension_count++] = Id;
     164         352 :     EXTENSION_LIST(CHECK_EXTENSION_FLAG)
     165             :   #undef CHECK_EXTENSION_FLAG
     166             :     v8::ExtensionConfiguration config(extension_count, extension_names);
     167          88 :     v8::Local<v8::Context> context = v8::Context::New(isolate, &config);
     168          88 :     CHECK(!context.IsEmpty());
     169          88 :     return context;
     170             : }
     171             : 
     172             : 
     173           5 : void CcTest::DisableAutomaticDispose() {
     174           5 :   CHECK_EQ(kUninitialized, initialization_state_);
     175           5 :   disable_automatic_dispose_ = true;
     176           5 : }
     177             : 
     178        9733 : LocalContext::~LocalContext() {
     179        9733 :   v8::HandleScope scope(isolate_);
     180       19466 :   v8::Local<v8::Context>::New(isolate_, context_)->Exit();
     181        9733 :   context_.Reset();
     182        9733 : }
     183             : 
     184        9733 : void LocalContext::Initialize(v8::Isolate* isolate,
     185             :                               v8::ExtensionConfiguration* extensions,
     186             :                               v8::Local<v8::ObjectTemplate> global_template,
     187             :                               v8::Local<v8::Value> global_object) {
     188        9733 :   v8::HandleScope scope(isolate);
     189             :   v8::Local<v8::Context> context =
     190        9733 :       v8::Context::New(isolate, extensions, global_template, global_object);
     191             :   context_.Reset(isolate, context);
     192        9733 :   context->Enter();
     193             :   // We can't do this later perhaps because of a fatal error.
     194        9733 :   isolate_ = isolate;
     195        9733 : }
     196             : 
     197             : // This indirection is needed because HandleScopes cannot be heap-allocated, and
     198             : // we don't want any unnecessary #includes in cctest.h.
     199             : class InitializedHandleScopeImpl {
     200             :  public:
     201             :   explicit InitializedHandleScopeImpl(i::Isolate* isolate)
     202             :       : handle_scope_(isolate) {}
     203             : 
     204             :  private:
     205             :   i::HandleScope handle_scope_;
     206             : };
     207             : 
     208      447909 : InitializedHandleScope::InitializedHandleScope()
     209      447909 :     : main_isolate_(CcTest::InitIsolateOnce()),
     210             :       initialized_handle_scope_impl_(
     211      895818 :           new InitializedHandleScopeImpl(main_isolate_)) {}
     212             : 
     213        4104 : InitializedHandleScope::~InitializedHandleScope() {}
     214             : 
     215      445857 : HandleAndZoneScope::HandleAndZoneScope()
     216      891714 :     : main_zone_(new i::Zone(&allocator_, ZONE_NAME)) {}
     217             : 
     218     1337571 : HandleAndZoneScope::~HandleAndZoneScope() {}
     219             : 
     220       12886 : static void PrintTestList(CcTest* current) {
     221        8592 :   if (current == nullptr) return;
     222        4295 :   PrintTestList(current->prev());
     223             :   printf("%s/%s\n", current->file(), current->name());
     224             : }
     225             : 
     226             : 
     227             : static void SuggestTestHarness(int tests) {
     228       23717 :   if (tests == 0) return;
     229             :   printf("Running multiple tests in sequence is deprecated and may cause "
     230             :          "bogus failure.  Consider using tools/run-tests.py instead.\n");
     231             : }
     232             : 
     233             : 
     234       23718 : int main(int argc, char* argv[]) {
     235             : #if V8_OS_WIN
     236             :   UINT new_flags =
     237             :       SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX;
     238             :   UINT existing_flags = SetErrorMode(new_flags);
     239             :   SetErrorMode(existing_flags | new_flags);
     240             : #if V8_CC_MSVC
     241             :   _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
     242             :   _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
     243             :   _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
     244             :   _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
     245             :   _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
     246             :   _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
     247             :   _set_error_mode(_OUT_TO_STDERR);
     248             : #endif  // V8_CC_MSVC
     249             : #endif  // V8_OS_WIN
     250             : 
     251             :   // hack to print cctest specific flags
     252      129522 :   for (int i = 1; i < argc; i++) {
     253      105804 :     char* arg = argv[i];
     254      105804 :     if ((strcmp(arg, "--help") == 0) || (strcmp(arg, "-h") == 0)) {
     255           0 :       printf("Usage: %s [--list] [[V8_FLAGS] CCTEST]\n", argv[0]);
     256             :       printf("\n");
     257             :       printf("Options:\n");
     258             :       printf("  --list:   list all cctests\n");
     259             :       printf("  CCTEST:   cctest identfier returned by --list\n");
     260             :       printf("  D8_FLAGS: see d8 output below\n");
     261             :       printf("\n\n");
     262             :     }
     263             :   }
     264             : 
     265       23718 :   v8::V8::InitializeICUDefaultLocation(argv[0]);
     266       23718 :   v8::Platform* platform = v8::platform::CreateDefaultPlatform();
     267       23718 :   v8::V8::InitializePlatform(platform);
     268       23718 :   v8::internal::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
     269       23718 :   v8::V8::Initialize();
     270       23718 :   v8::V8::InitializeExternalStartupData(argv[0]);
     271             : 
     272       23718 :   if (i::trap_handler::UseTrapHandler()) {
     273        2475 :     v8::V8::RegisterDefaultSignalHandler();
     274             :   }
     275             : 
     276             :   CcTest::set_array_buffer_allocator(
     277       23718 :       v8::ArrayBuffer::Allocator::NewDefaultAllocator());
     278             : 
     279       23718 :   i::PrintExtension print_extension;
     280       23718 :   v8::RegisterExtension(&print_extension);
     281       23718 :   i::ProfilerExtension profiler_extension;
     282       23718 :   v8::RegisterExtension(&profiler_extension);
     283       23718 :   i::TraceExtension trace_extension;
     284       23718 :   v8::RegisterExtension(&trace_extension);
     285             : 
     286             :   int tests_run = 0;
     287             :   bool print_run_count = true;
     288       54137 :   for (int i = 1; i < argc; i++) {
     289       30437 :     char* arg = argv[i];
     290       30437 :     if (strcmp(arg, "--list") == 0) {
     291           1 :       PrintTestList(CcTest::last());
     292             :       print_run_count = false;
     293             : 
     294             :     } else {
     295       30436 :       char* arg_copy = v8::internal::StrDup(arg);
     296             :       char* testname = strchr(arg_copy, '/');
     297       30436 :       if (testname) {
     298             :         // Split the string in two by nulling the slash and then run
     299             :         // exact matches.
     300       23717 :         *testname = 0;
     301             :         char* file = arg_copy;
     302       23717 :         char* name = testname + 1;
     303   310128259 :         CcTest* test = CcTest::last();
     304   101888117 :         while (test != nullptr) {
     305   101840701 :           if (test->enabled()
     306   101840701 :               && strcmp(test->file(), file) == 0
     307   106446875 :               && strcmp(test->name(), name) == 0) {
     308       23717 :             SuggestTestHarness(tests_run++);
     309       23717 :             test->Run();
     310             :           }
     311             :           test = test->prev();
     312             :         }
     313             : 
     314             :       } else {
     315             :         // Run all tests with the specified file or test name.
     316             :         char* file_or_name = arg_copy;
     317   115432420 :         CcTest* test = CcTest::last();
     318    28871543 :         while (test != nullptr) {
     319    28858105 :           if (test->enabled()
     320    57716210 :               && (strcmp(test->file(), file_or_name) == 0
     321    28858105 :                   || strcmp(test->name(), file_or_name) == 0)) {
     322           0 :             SuggestTestHarness(tests_run++);
     323           0 :             test->Run();
     324             :           }
     325             :           test = test->prev();
     326             :         }
     327             :       }
     328             :       v8::internal::DeleteArray<char>(arg_copy);
     329             :     }
     330             :   }
     331       23700 :   if (print_run_count && tests_run != 1)
     332             :     printf("Ran %i tests.\n", tests_run);
     333             :   CcTest::TearDown();
     334             :   // TODO(svenpanne) See comment above.
     335             :   // if (!disable_automatic_dispose_) v8::V8::Dispose();
     336       23700 :   v8::V8::ShutdownPlatform();
     337       23700 :   delete platform;
     338             :   return 0;
     339             : }
     340             : 
     341             : RegisterThreadedTest* RegisterThreadedTest::first_ = nullptr;
     342       71154 : int RegisterThreadedTest::count_ = 0;

Generated by: LCOV version 1.10