diff --git a/source/extensions/common/wasm/wasm.cc b/source/extensions/common/wasm/wasm.cc index fa6d6de1dd..3b09142d29 100644 --- a/source/extensions/common/wasm/wasm.cc +++ b/source/extensions/common/wasm/wasm.cc @@ -555,18 +555,18 @@ static void createWasmInternal(const VmConfig& vm_config, PluginSharedPtr plugin wasm = std::make_shared(std::make_shared( vm_config.runtime(), vm_config.vm_id(), vm_config.configuration(), vm_key, scope, cluster_manager, dispatcher)); + if (!wasm->wasm()->initialize(code, vm_config.allow_precompiled())) { + throw WasmException(fmt::format("Failed to initialize WASM code from {}", source)); + } + if (!context) { + wasm->wasm()->start(plugin); + } else { + wasm->wasm()->startForTesting(std::move(context), plugin); + } (*base_wasms_)[vm_key] = wasm; } } - if (!wasm->wasm()->initialize(code, vm_config.allow_precompiled())) { - throw WasmException(fmt::format("Failed to initialize WASM code from {}", source)); - } - if (!context) { - wasm->wasm()->start(plugin); - } else { - wasm->wasm()->startForTesting(std::move(context), plugin); - } cb(std::move(wasm)); }; diff --git a/test/extensions/common/wasm/wasm_test.cc b/test/extensions/common/wasm/wasm_test.cc index 43a924b092..df9fae5fbd 100644 --- a/test/extensions/common/wasm/wasm_test.cc +++ b/test/extensions/common/wasm/wasm_test.cc @@ -23,7 +23,9 @@ namespace Wasm { class TestContext : public Extensions::Common::Wasm::Context { public: - TestContext(Extensions::Common::Wasm::Wasm* wasm) : Extensions::Common::Wasm::Context(wasm) {} + TestContext() : Extensions::Common::Wasm::Context() {} + explicit TestContext(Extensions::Common::Wasm::Wasm* wasm) + : Extensions::Common::Wasm::Context(wasm) {} ~TestContext() override {} void scriptLog(spdlog::level::level_enum level, absl::string_view message) override { std::cerr << std::string(message) << "\n"; @@ -352,6 +354,66 @@ TEST_P(WasmCommonTest, Foreign) { wasm->startForTesting(std::move(context), plugin); } +TEST_P(WasmCommonTest, VmCache) { + Stats::IsolatedStoreImpl stats_store; + Api::ApiPtr api = Api::createApiForTest(stats_store); + NiceMock cluster_manager; + NiceMock init_manager; + Event::DispatcherPtr dispatcher(api->allocateDispatcher()); + Config::DataSource::RemoteAsyncDataProviderPtr remote_data_provider; + auto scope = Stats::ScopeSharedPtr(stats_store.createScope("wasm.")); + NiceMock local_info; + auto name = ""; + auto root_id = ""; + auto vm_id = ""; + auto vm_configuration = "vm_cache"; + auto plugin = std::make_shared( + name, root_id, vm_id, envoy::config::core::v3::TrafficDirection::UNSPECIFIED, local_info, + nullptr); + + VmConfig vm_config; + vm_config.set_runtime(absl::StrCat("envoy.wasm.runtime.", GetParam())); + vm_config.set_configuration(vm_configuration); + std::string code; + if (GetParam() != "null") { + code = TestEnvironment::readFileToStringForTest(TestEnvironment::substitute( + absl::StrCat("{{ test_rundir }}/test/extensions/common/wasm/test_data/test_cpp.wasm"))); + } else { + // The name of the Null VM plugin. + code = "CommonWasmTestCpp"; + } + EXPECT_FALSE(code.empty()); + vm_config.mutable_code()->mutable_local()->set_inline_bytes(code); + WasmHandleSharedPtr wasm_handle; + auto root_context = new Extensions::Common::Wasm::TestContext(); + EXPECT_CALL(*root_context, scriptLog_(spdlog::level::info, Eq("on_vm_start vm_cache"))); + EXPECT_CALL(*root_context, scriptLog_(spdlog::level::info, Eq("on_done logging"))); + EXPECT_CALL(*root_context, scriptLog_(spdlog::level::info, Eq("on_delete logging"))); + createWasmForTesting(vm_config, plugin, scope, cluster_manager, init_manager, *dispatcher, *api, + std::unique_ptr(root_context), remote_data_provider, + [&wasm_handle](WasmHandleSharedPtr w) { wasm_handle = w; }); + + EXPECT_NE(wasm_handle, nullptr); + + WasmHandleSharedPtr wasm_handle2; + auto root_context2 = new Extensions::Common::Wasm::Context(); + createWasmForTesting(vm_config, plugin, scope, cluster_manager, init_manager, *dispatcher, *api, + std::unique_ptr(root_context2), remote_data_provider, + [&wasm_handle2](WasmHandleSharedPtr w) { wasm_handle2 = w; }); + EXPECT_NE(wasm_handle2, nullptr); + EXPECT_EQ(wasm_handle, wasm_handle2); + + plugin.reset(); + auto wasm = wasm_handle->wasm().get(); + wasm_handle.reset(); + wasm_handle2.reset(); + + dispatcher->run(Event::Dispatcher::RunType::NonBlock); + wasm->configure(root_context, plugin, "done"); + dispatcher->run(Event::Dispatcher::RunType::NonBlock); + dispatcher->clearDeferredDeleteList(); +} + } // namespace Wasm } // namespace Common } // namespace Extensions