Move class EmbedderTestEnvironment to standalone V8TestEnvironment.
This will then allow tests involving garbage-collected objects to
be lighter-weight unittests, rather than embeddertests. In particular,
an object with an existing unit test shouldn't have to become an
embeddertest when it becomes gc'd.
-- add environment setup to unittest main.
-- move two tests back to unittest as a result.
Change-Id: I25c205f3a9dc12854230ed851aebf7d3cb553ace
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/71810
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index f22617e..24d61e1 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -254,6 +254,7 @@
configs += [ "//v8:external_startup_data" ]
deps += [
"fxjs:unittests",
+ "testing:pdfium_v8_gtest_support",
"//v8",
]
}
@@ -289,6 +290,9 @@
"fxjs/*",
"xfa/*",
]
+ if (pdf_enable_v8) {
+ public_deps += [ "testing:pdfium_v8_gtest_support" ]
+ }
}
test("pdfium_embeddertests") {
diff --git a/fxjs/BUILD.gn b/fxjs/BUILD.gn
index c7f42d7..bfff222 100644
--- a/fxjs/BUILD.gn
+++ b/fxjs/BUILD.gn
@@ -229,6 +229,19 @@
configs = [ "//v8:external_startup_data" ]
deps = [ ":fxjs" ]
pdfium_root_dir = "../"
+ if (pdf_enable_xfa) {
+ sources += [
+ "gc/fxgc_unittest.cpp",
+ "gc/fxgc_unittest.h",
+ "gc/gced_tree_node_unittest.cpp",
+ "gc/heap_unittest.cpp",
+ ]
+ deps += [
+ "../testing:pdfium_v8_gtest_support",
+ "../testing:unit_test_support",
+ "//v8:cppgc",
+ ]
+ }
}
pdfium_embeddertest_source_set("embeddertests") {
@@ -244,8 +257,6 @@
pdfium_root_dir = "../"
if (pdf_enable_xfa) {
sources += [
- "gc/gced_tree_node_embeddertest.cpp",
- "gc/heap_embeddertest.cpp",
"xfa/cfxjse_app_embeddertest.cpp",
"xfa/cfxjse_formcalc_context_embeddertest.cpp",
"xfa/cfxjse_value_embeddertest.cpp",
diff --git a/fxjs/cfx_v8_unittest.cpp b/fxjs/cfx_v8_unittest.cpp
index 226a8e2..c969009 100644
--- a/fxjs/cfx_v8_unittest.cpp
+++ b/fxjs/cfx_v8_unittest.cpp
@@ -20,6 +20,7 @@
CFXV8UnitTest() = default;
~CFXV8UnitTest() override = default;
+ // FXV8UnitTest:
void SetUp() override {
FXV8UnitTest::SetUp();
cfx_v8_ = std::make_unique<CFX_V8>(isolate());
diff --git a/fxjs/cfxjs_engine_unittest.cpp b/fxjs/cfxjs_engine_unittest.cpp
index 6566d82..b1a2f85 100644
--- a/fxjs/cfxjs_engine_unittest.cpp
+++ b/fxjs/cfxjs_engine_unittest.cpp
@@ -15,12 +15,12 @@
FXJSEngineUnitTest() = default;
~FXJSEngineUnitTest() override = default;
+ // FXV8UnitTest:
void SetUp() override {
FXV8UnitTest::SetUp();
FXJS_Initialize(1, isolate());
engine_ = std::make_unique<CFXJS_Engine>(isolate());
}
-
void TearDown() override { FXJS_Release(); }
CFXJS_Engine* engine() const { return engine_.get(); }
diff --git a/fxjs/gc/fxgc_unittest.cpp b/fxjs/gc/fxgc_unittest.cpp
new file mode 100644
index 0000000..74a329b
--- /dev/null
+++ b/fxjs/gc/fxgc_unittest.cpp
@@ -0,0 +1,26 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fxjs/gc/fxgc_unittest.h"
+
+#include "fxjs/gc/heap.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/v8_test_environment.h"
+
+FXGCUnitTest::FXGCUnitTest() = default;
+
+FXGCUnitTest::~FXGCUnitTest() = default;
+
+void FXGCUnitTest::SetUp() {
+ FXV8UnitTest::SetUp();
+ FXGC_Initialize(V8TestEnvironment::GetInstance()->platform());
+ heap_ = FXGC_CreateHeap();
+ ASSERT_TRUE(heap_);
+}
+
+void FXGCUnitTest::TearDown() {
+ heap_.reset();
+ FXGC_Release();
+ FXV8UnitTest::TearDown();
+}
diff --git a/fxjs/gc/fxgc_unittest.h b/fxjs/gc/fxgc_unittest.h
new file mode 100644
index 0000000..6467e3b
--- /dev/null
+++ b/fxjs/gc/fxgc_unittest.h
@@ -0,0 +1,26 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FXJS_GC_FXGC_UNITTEST_H_
+#define FXJS_GC_FXGC_UNITTEST_H_
+
+#include "fxjs/fxv8_unittest.h"
+#include "fxjs/gc/heap.h"
+
+class FXGCUnitTest : public FXV8UnitTest {
+ public:
+ FXGCUnitTest();
+ ~FXGCUnitTest() override;
+
+ // FXV8UnitTest:
+ void SetUp() override;
+ void TearDown() override;
+
+ cppgc::Heap* heap() const { return heap_.get(); }
+
+ private:
+ FXGCScopedHeap heap_;
+};
+
+#endif // FXJS_GC_FXGC_UNITTEST_H_
diff --git a/fxjs/gc/gced_tree_node_embeddertest.cpp b/fxjs/gc/gced_tree_node_unittest.cpp
similarity index 79%
rename from fxjs/gc/gced_tree_node_embeddertest.cpp
rename to fxjs/gc/gced_tree_node_unittest.cpp
index cbda307..2fbc592 100644
--- a/fxjs/gc/gced_tree_node_embeddertest.cpp
+++ b/fxjs/gc/gced_tree_node_unittest.cpp
@@ -7,9 +7,10 @@
#include <map>
#include "core/fxcrt/observed_ptr.h"
+#include "fxjs/gc/fxgc_unittest.h"
#include "fxjs/gc/heap.h"
-#include "testing/gced_embeddertest.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/v8_test_environment.h"
#include "third_party/base/stl_util.h"
#include "v8/include/cppgc/allocation.h"
#include "v8/include/cppgc/persistent.h"
@@ -28,39 +29,36 @@
} // namespace
-class GCedTreeNodeEmbedderTest : public GCedEmbedderTest {
+class GCedTreeNodeUnitTest : public FXGCUnitTest {
public:
static cppgc::Persistent<ObservableGCedTreeNodeForTest> s_root;
- void SetUp() override {
- GCedEmbedderTest::SetUp();
- heap_ = FXGC_CreateHeap();
- }
+ GCedTreeNodeUnitTest() = default;
+ ~GCedTreeNodeUnitTest() override = default;
+ // FXGCUnitTest:
void TearDown() override {
s_root = nullptr; // Can't (yet) outlive |heap_|.
- heap_.reset();
- GCedEmbedderTest::TearDown();
+ FXGCUnitTest::TearDown();
}
- cppgc::Heap* heap() const { return heap_.get(); }
ObservableGCedTreeNodeForTest* CreateNode() {
return cppgc::MakeGarbageCollected<ObservableGCedTreeNodeForTest>(
- heap_->GetAllocationHandle());
+ heap()->GetAllocationHandle());
}
void ForceGCAndPump() {
heap()->ForceGarbageCollectionSlow(
- "GCedTreeNodeEmbedderTest", "test",
+ "GCedTreeNodeUnitTest", "test",
cppgc::Heap::StackState::kNoHeapPointers);
- PumpPlatformMessageLoop();
+ V8TestEnvironment::PumpPlatformMessageLoop(isolate());
}
void AddClutterToFront(ObservableGCedTreeNodeForTest* parent) {
for (int i = 0; i < 4; ++i) {
parent->AppendFirstChild(
cppgc::MakeGarbageCollected<ObservableGCedTreeNodeForTest>(
- heap_->GetAllocationHandle()));
+ heap()->GetAllocationHandle()));
}
}
@@ -68,7 +66,7 @@
for (int i = 0; i < 4; ++i) {
parent->AppendLastChild(
cppgc::MakeGarbageCollected<ObservableGCedTreeNodeForTest>(
- heap_->GetAllocationHandle()));
+ heap()->GetAllocationHandle()));
}
}
@@ -76,23 +74,22 @@
FXGCScopedHeap heap_;
};
-cppgc::Persistent<ObservableGCedTreeNodeForTest>
- GCedTreeNodeEmbedderTest::s_root;
+cppgc::Persistent<ObservableGCedTreeNodeForTest> GCedTreeNodeUnitTest::s_root;
-TEST_F(GCedTreeNodeEmbedderTest, OneRefence) {
+TEST_F(GCedTreeNodeUnitTest, OneRefence) {
s_root = CreateNode();
ObservedPtr<ObservableGCedTreeNodeForTest> watcher(s_root);
ForceGCAndPump();
EXPECT_TRUE(watcher);
}
-TEST_F(GCedTreeNodeEmbedderTest, NoReferences) {
+TEST_F(GCedTreeNodeUnitTest, NoReferences) {
ObservedPtr<ObservableGCedTreeNodeForTest> watcher(CreateNode());
ForceGCAndPump();
EXPECT_FALSE(watcher);
}
-TEST_F(GCedTreeNodeEmbedderTest, FirstHasParent) {
+TEST_F(GCedTreeNodeUnitTest, FirstHasParent) {
s_root = CreateNode();
ObservedPtr<ObservableGCedTreeNodeForTest> watcher(CreateNode());
s_root->AppendFirstChild(watcher.Get());
@@ -118,7 +115,7 @@
EXPECT_FALSE(watcher);
}
-TEST_F(GCedTreeNodeEmbedderTest, RemoveSelf) {
+TEST_F(GCedTreeNodeUnitTest, RemoveSelf) {
s_root = CreateNode();
ObservedPtr<ObservableGCedTreeNodeForTest> watcher(CreateNode());
s_root->AppendFirstChild(watcher.Get());
@@ -131,7 +128,7 @@
EXPECT_FALSE(watcher);
}
-TEST_F(GCedTreeNodeEmbedderTest, InsertBeforeAfter) {
+TEST_F(GCedTreeNodeUnitTest, InsertBeforeAfter) {
s_root = CreateNode();
AddClutterToFront(s_root);
ObservedPtr<ObservableGCedTreeNodeForTest> watcher(CreateNode());
@@ -147,7 +144,7 @@
EXPECT_FALSE(watcher);
}
-TEST_F(GCedTreeNodeEmbedderTest, AsMapKey) {
+TEST_F(GCedTreeNodeUnitTest, AsMapKey) {
std::map<cppgc::Persistent<ObservableGCedTreeNodeForTest>, int> score;
ObservableGCedTreeNodeForTest* node = CreateNode();
score[node] = 100;
diff --git a/fxjs/gc/heap_embeddertest.cpp b/fxjs/gc/heap_unittest.cpp
similarity index 91%
rename from fxjs/gc/heap_embeddertest.cpp
rename to fxjs/gc/heap_unittest.cpp
index b7cac35..33e1bb1 100644
--- a/fxjs/gc/heap_embeddertest.cpp
+++ b/fxjs/gc/heap_unittest.cpp
@@ -8,7 +8,7 @@
#include <set>
#include "core/fxcrt/autorestorer.h"
-#include "testing/gced_embeddertest.h"
+#include "fxjs/gc/fxgc_unittest.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/base/stl_util.h"
#include "v8/include/cppgc/allocation.h"
@@ -48,15 +48,19 @@
} // namespace
-class HeapEmbedderTest : public GCedEmbedderTest {
+class HeapUnitTest : public FXGCUnitTest {
public:
+ HeapUnitTest() = default;
+ ~HeapUnitTest() override = default;
+
+ // FXGCUnitTest:
void TearDown() override {
PseudoCollectible::ClearCounts();
- GCedEmbedderTest::TearDown();
+ FXGCUnitTest::TearDown();
}
};
-TEST_F(HeapEmbedderTest, SeveralHeaps) {
+TEST_F(HeapUnitTest, SeveralHeaps) {
FXGCScopedHeap heap1 = FXGC_CreateHeap();
EXPECT_TRUE(heap1);
@@ -73,7 +77,7 @@
EXPECT_FALSE(heap3);
}
-TEST_F(HeapEmbedderTest, NoReferences) {
+TEST_F(HeapUnitTest, NoReferences) {
FXGCScopedHeap heap1 = FXGC_CreateHeap();
ASSERT_TRUE(heap1);
{
@@ -95,7 +99,7 @@
EXPECT_EQ(1u, PseudoCollectible::DeadCount());
}
-TEST_F(HeapEmbedderTest, HasReferences) {
+TEST_F(HeapUnitTest, HasReferences) {
FXGCScopedHeap heap1 = FXGC_CreateHeap();
ASSERT_TRUE(heap1);
{
@@ -121,7 +125,7 @@
}
// TODO(tsepez): enable when CPPGC fixes this segv.
-TEST_F(HeapEmbedderTest, DISABLED_DeleteHeapHasReferences) {
+TEST_F(HeapUnitTest, DISABLED_DeleteHeapHasReferences) {
FXGCScopedHeap heap1 = FXGC_CreateHeap();
ASSERT_TRUE(heap1);
{
@@ -144,7 +148,7 @@
}
}
-TEST_F(HeapEmbedderTest, DeleteHeapNoReferences) {
+TEST_F(HeapUnitTest, DeleteHeapNoReferences) {
FXGCScopedHeap heap1 = FXGC_CreateHeap();
ASSERT_TRUE(heap1);
{
diff --git a/testing/BUILD.gn b/testing/BUILD.gn
index 33ee6ec..4f04ce0 100644
--- a/testing/BUILD.gn
+++ b/testing/BUILD.gn
@@ -51,6 +51,27 @@
}
}
+if (pdf_enable_v8) {
+ source_set("pdfium_v8_gtest_support") {
+ testonly = true
+ sources = [
+ "v8_test_environment.cpp",
+ "v8_test_environment.h",
+ ]
+ deps = [
+ ":test_support",
+ "../core/fxcrt",
+ "//testing/gtest",
+ "//v8",
+ "//v8:v8_libplatform",
+ ]
+ configs += [
+ "../:pdfium_core_config",
+ "//v8:external_startup_data",
+ ]
+ }
+}
+
source_set("unit_test_support") {
testonly = true
sources = []
@@ -58,17 +79,21 @@
configs += [ "../:pdfium_core_config" ]
visibility = [ "../*" ]
- if (pdf_enable_xfa) {
- sources += [
- "xfa_unit_test_support.cpp",
- "xfa_unit_test_support.h",
- ]
- deps += [
- "../:pdfium",
- "../core/fxge",
- "../xfa/fgas",
- "//testing/gtest",
- ]
+ if (pdf_enable_v8) {
+ deps += [ ":pdfium_v8_gtest_support" ]
+
+ if (pdf_enable_xfa) {
+ sources += [
+ "xfa_unit_test_support.cpp",
+ "xfa_unit_test_support.h",
+ ]
+ deps += [
+ "../:pdfium",
+ "../core/fxge",
+ "../xfa/fgas",
+ "//testing/gtest",
+ ]
+ }
}
}
@@ -105,13 +130,14 @@
"js_embedder_test.cpp",
"js_embedder_test.h",
]
- deps += [ "../fxjs" ]
+ deps += [
+ ":pdfium_v8_gtest_support",
+ "../fxjs",
+ ]
configs += [ "//v8:external_startup_data" ]
if (pdf_enable_xfa) {
sources += [
- "gced_embeddertest.cpp",
- "gced_embeddertest.h",
"xfa_js_embedder_test.cpp",
"xfa_js_embedder_test.h",
]
diff --git a/testing/embedder_test.cpp b/testing/embedder_test.cpp
index ae09cf9..ccfd40c 100644
--- a/testing/embedder_test.cpp
+++ b/testing/embedder_test.cpp
@@ -27,15 +27,13 @@
#include "third_party/base/stl_util.h"
#ifdef PDF_ENABLE_V8
-#include "testing/v8_initializer.h"
+#include "testing/v8_test_environment.h"
#include "v8/include/v8-platform.h"
#include "v8/include/v8.h"
#endif // PDF_ENABLE_V8
namespace {
-EmbedderTestEnvironment* g_environment = nullptr;
-
int GetBitmapBytesPerPixel(FPDF_BITMAP bitmap) {
return EmbedderTest::BytesPerPixelForFormat(FPDFBitmap_GetFormat(bitmap));
}
@@ -54,55 +52,6 @@
} // namespace
-EmbedderTestEnvironment::EmbedderTestEnvironment(const char* exe_name)
-#ifdef PDF_ENABLE_V8
- : exe_path_(exe_name)
-#endif
-{
- ASSERT(!g_environment);
- g_environment = this;
-}
-
-EmbedderTestEnvironment::~EmbedderTestEnvironment() {
- ASSERT(g_environment);
- g_environment = nullptr;
-
-#ifdef PDF_ENABLE_V8
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
- if (v8_snapshot_)
- free(const_cast<char*>(v8_snapshot_->data));
-#endif // V8_USE_EXTERNAL_STARTUP_DATA
-#endif // PDF_ENABLE_V8
-}
-
-// static
-EmbedderTestEnvironment* EmbedderTestEnvironment::GetInstance() {
- return g_environment;
-}
-
-void EmbedderTestEnvironment::SetUp() {
-#ifdef PDF_ENABLE_V8
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
- if (v8_snapshot_) {
- platform_ =
- InitializeV8ForPDFiumWithStartupData(exe_path_, std::string(), nullptr);
- } else {
- v8_snapshot_ = std::make_unique<v8::StartupData>();
- platform_ = InitializeV8ForPDFiumWithStartupData(exe_path_, std::string(),
- v8_snapshot_.get());
- }
-#else
- platform_ = InitializeV8ForPDFium(exe_path_);
-#endif // V8_USE_EXTERNAL_STARTUP_DATA
-#endif // FPDF_ENABLE_V8
-}
-
-void EmbedderTestEnvironment::TearDown() {
-#ifdef PDF_ENABLE_V8
- v8::V8::ShutdownPlatform();
-#endif // PDF_ENABLE_V8
-}
-
EmbedderTest::EmbedderTest()
: default_delegate_(std::make_unique<EmbedderTest::Delegate>()),
delegate_(default_delegate_.get()) {
@@ -119,7 +68,7 @@
config.m_v8EmbedderSlot = 0;
config.m_pIsolate = external_isolate_;
#ifdef PDF_ENABLE_V8
- config.m_pPlatform = EmbedderTestEnvironment::GetInstance()->platform();
+ config.m_pPlatform = V8TestEnvironment::GetInstance()->platform();
#else // PDF_ENABLE_V8
config.m_pPlatform = nullptr;
#endif // PDF_ENABLE_V8
diff --git a/testing/embedder_test.h b/testing/embedder_test.h
index 45e2a5d..a1fbac8 100644
--- a/testing/embedder_test.h
+++ b/testing/embedder_test.h
@@ -23,44 +23,11 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/base/span.h"
-#ifdef PDF_ENABLE_V8
-namespace v8 {
-class Platform;
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
-class StartupData;
-#endif // V8_USE_EXTERNAL_STARTUP_DATA
-} // namespace v8
-#endif // PDF_ENABLE_V8
-
class TestLoader;
// The loading time of the CFGAS_FontMgr is linear in the number of times it is
// loaded. So, if a test suite has a lot of tests that need a font manager they
// can end up executing very, very slowly.
-class EmbedderTestEnvironment final : public testing::Environment {
- public:
- explicit EmbedderTestEnvironment(const char* exe_path);
- ~EmbedderTestEnvironment() override;
-
- // Note: does not create one if it does not exist.
- static EmbedderTestEnvironment* GetInstance();
-
- void SetUp() override;
- void TearDown() override;
-
-#ifdef PDF_ENABLE_V8
- v8::Platform* platform() const { return platform_.get(); }
-#endif // PDF_ENABLE_V8
-
- private:
-#ifdef PDF_ENABLE_V8
- const char* const exe_path_;
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
- std::unique_ptr<v8::StartupData> v8_snapshot_;
-#endif // V8_USE_EXTERNAL_STARTUP_DATA
- std::unique_ptr<v8::Platform> platform_;
-#endif // PDF_ENABLE_V8
-};
// This class is used to load a PDF document, and then run programatic
// API tests against it.
diff --git a/testing/embedder_test_main.cpp b/testing/embedder_test_main.cpp
index d4318d1..798c9cf 100644
--- a/testing/embedder_test_main.cpp
+++ b/testing/embedder_test_main.cpp
@@ -2,19 +2,25 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "build/build_config.h"
#include "core/fxcrt/fx_memory.h"
-#include "testing/embedder_test.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#ifdef PDF_ENABLE_V8
+#include "testing/v8_test_environment.h"
+#endif // PDF_ENABLE_V8
+
// Can't use gtest-provided main since we need to create our own
// testing environment which needs the executable path in order to
// find the external V8 binary data files.
int main(int argc, char** argv) {
FXMEM_InitializePartitionAlloc();
+#ifdef PDF_ENABLE_V8
// The env will be deleted by gtest.
- AddGlobalTestEnvironment(new EmbedderTestEnvironment(argv[0]));
+ AddGlobalTestEnvironment(new V8TestEnvironment(argv[0]));
+#endif // PDF_ENABLE_V8
testing::InitGoogleTest(&argc, argv);
testing::InitGoogleMock(&argc, argv);
diff --git a/testing/gced_embeddertest.cpp b/testing/gced_embeddertest.cpp
deleted file mode 100644
index fb8d9c1..0000000
--- a/testing/gced_embeddertest.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2020 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "testing/gced_embeddertest.h"
-
-#include "public/fpdfview.h"
-#include "v8/include/cppgc/allocation.h"
-#include "v8/include/cppgc/persistent.h"
-#include "v8/include/libplatform/libplatform.h"
-#include "v8/include/v8.h"
-
-void GCedEmbedderTest::PumpPlatformMessageLoop() {
- v8::Platform* platform = EmbedderTestEnvironment::GetInstance()->platform();
- while (v8::platform::PumpMessageLoop(platform, isolate()))
- continue;
-}
diff --git a/testing/gced_embeddertest.h b/testing/gced_embeddertest.h
deleted file mode 100644
index 2295bc0..0000000
--- a/testing/gced_embeddertest.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2020 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef TESTING_GCED_EMBEDDER_TEST_H_
-#define TESTING_GCED_EMBEDDER_TEST_H_
-
-#include <memory>
-
-#include "testing/js_embedder_test.h"
-
-class GCedEmbedderTest : public JSEmbedderTest {
- public:
- void PumpPlatformMessageLoop();
-};
-
-#endif // TESTING_GCED_EMBEDDER_TEST_H_
diff --git a/testing/unit_test_main.cpp b/testing/unit_test_main.cpp
index 5d50249..b36ac80 100644
--- a/testing/unit_test_main.cpp
+++ b/testing/unit_test_main.cpp
@@ -11,7 +11,7 @@
#include "testing/test_support.h"
#ifdef PDF_ENABLE_V8
-#include "testing/v8_initializer.h"
+#include "testing/v8_test_environment.h"
#include "v8/include/v8-platform.h"
#include "v8/include/v8.h"
#endif // PDF_ENABLE_V8
@@ -26,18 +26,14 @@
FXMEM_InitializePartitionAlloc();
#ifdef PDF_ENABLE_V8
- std::unique_ptr<v8::Platform> platform;
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
- static v8::StartupData* snapshot = new v8::StartupData;
- platform =
- InitializeV8ForPDFiumWithStartupData(argv[0], std::string(), snapshot);
-#else // V8_USE_EXTERNAL_STARTUP_DATA
- platform = InitializeV8ForPDFium(argv[0]);
-#endif // V8_USE_EXTERNAL_STARTUP_DATA
+ // V8 test environment will be deleted by gtest.
+ AddGlobalTestEnvironment(new V8TestEnvironment(argv[0]));
#endif // PDF_ENABLE_V8
InitializePDFTestEnvironment();
+
#ifdef PDF_ENABLE_XFA
+ // XFA test environment will be deleted by gtest.
InitializeXFATestEnvironment();
#endif // PDF_ENABLE_XFA
@@ -47,11 +43,7 @@
int ret_val = RUN_ALL_TESTS();
DestroyPDFTestEnvironment();
- // NOTE: XFA test environment, if present, destroyed by gtest.
-#ifdef PDF_ENABLE_V8
- v8::V8::ShutdownPlatform();
-#endif // PDF_ENABLE_V8
return ret_val;
}
diff --git a/testing/v8_test_environment.cpp b/testing/v8_test_environment.cpp
new file mode 100644
index 0000000..08a8840
--- /dev/null
+++ b/testing/v8_test_environment.cpp
@@ -0,0 +1,66 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "testing/v8_test_environment.h"
+
+#include <string>
+
+#include "core/fxcrt/fx_system.h"
+#include "testing/v8_initializer.h"
+#include "v8/include/libplatform/libplatform.h"
+#include "v8/include/v8-platform.h"
+#include "v8/include/v8.h"
+
+namespace {
+
+V8TestEnvironment* g_environment = nullptr;
+
+} // namespace
+
+V8TestEnvironment::V8TestEnvironment(const char* exe_name)
+ : exe_path_(exe_name) {
+ ASSERT(!g_environment);
+ g_environment = this;
+}
+
+V8TestEnvironment::~V8TestEnvironment() {
+ ASSERT(g_environment);
+ g_environment = nullptr;
+
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ if (v8_snapshot_)
+ free(const_cast<char*>(v8_snapshot_->data));
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
+}
+
+// static
+V8TestEnvironment* V8TestEnvironment::GetInstance() {
+ return g_environment;
+}
+
+// static
+void V8TestEnvironment::PumpPlatformMessageLoop(v8::Isolate* isolate) {
+ v8::Platform* platform = GetInstance()->platform();
+ while (v8::platform::PumpMessageLoop(platform, isolate))
+ continue;
+}
+
+void V8TestEnvironment::SetUp() {
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ if (v8_snapshot_) {
+ platform_ =
+ InitializeV8ForPDFiumWithStartupData(exe_path_, std::string(), nullptr);
+ } else {
+ v8_snapshot_ = std::make_unique<v8::StartupData>();
+ platform_ = InitializeV8ForPDFiumWithStartupData(exe_path_, std::string(),
+ v8_snapshot_.get());
+ }
+#else
+ platform_ = InitializeV8ForPDFium(exe_path_);
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
+}
+
+void V8TestEnvironment::TearDown() {
+ v8::V8::ShutdownPlatform();
+}
diff --git a/testing/v8_test_environment.h b/testing/v8_test_environment.h
new file mode 100644
index 0000000..3cce117
--- /dev/null
+++ b/testing/v8_test_environment.h
@@ -0,0 +1,45 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TESTING_V8_TEST_ENVIRONMENT_H_
+#define TESTING_V8_TEST_ENVIRONMENT_H_
+
+#include <memory>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+class Isolate;
+class Platform;
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+class StartupData;
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
+} // namespace v8
+
+class TestLoader;
+
+class V8TestEnvironment : public testing::Environment {
+ public:
+ explicit V8TestEnvironment(const char* exe_path);
+ ~V8TestEnvironment() override;
+
+ // Note: GetInstance() does not create one if it does not exist.
+ static V8TestEnvironment* GetInstance();
+ static void PumpPlatformMessageLoop(v8::Isolate* pIsolate);
+
+ // testing::Environment:
+ void SetUp() override;
+ void TearDown() override;
+
+ v8::Platform* platform() const { return platform_.get(); }
+
+ private:
+ const char* const exe_path_;
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ std::unique_ptr<v8::StartupData> v8_snapshot_;
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
+ std::unique_ptr<v8::Platform> platform_;
+};
+
+#endif // TESTING_V8_TEST_ENVIRONMENT_H_