Skip to content

Commit e6c445a

Browse files
committed
Add tests for secondary canary test
Signed-off-by: Ingwon Song <[email protected]>
1 parent 0da9fd0 commit e6c445a

File tree

7 files changed

+161
-14
lines changed

7 files changed

+161
-14
lines changed

WORKSPACE

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,11 @@ proxy_wasm_cpp_host_repositories()
77
load("@proxy_wasm_cpp_host//bazel:dependencies.bzl", "proxy_wasm_cpp_host_dependencies")
88

99
proxy_wasm_cpp_host_dependencies()
10+
11+
load("@proxy_wasm_cpp_sdk//bazel/dep:deps.bzl", "wasm_dependencies")
12+
13+
wasm_dependencies()
14+
15+
load("@proxy_wasm_cpp_sdk//bazel/dep:deps_extra.bzl", "wasm_dependencies_extra")
16+
17+
wasm_dependencies_extra()

include/proxy-wasm/context.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,11 @@ class ContextBase : public RootInterface,
315315
}
316316

317317
// Properties
318-
WasmResult getProperty(std::string_view /* path */, std::string * /* result */) override {
318+
WasmResult getProperty(std::string_view path, std::string *result) override {
319+
if (path == "plugin_root_id") {
320+
*result = root_id_;
321+
return WasmResult::Ok;
322+
}
319323
return unimplemented();
320324
}
321325
WasmResult setProperty(std::string_view /* key */,

src/wasm.cc

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,6 @@ std::shared_ptr<WasmHandleBase> createWasm(const std::string &vm_key, const std:
478478
const WasmHandleCloneFactory &clone_factory,
479479
bool allow_precompiled) {
480480
std::shared_ptr<WasmHandleBase> wasm_handle;
481-
bool is_new_wasm = false;
482481
{
483482
std::lock_guard<std::mutex> guard(base_wasms_mutex);
484483
if (base_wasms == nullptr) {
@@ -492,25 +491,25 @@ std::shared_ptr<WasmHandleBase> createWasm(const std::string &vm_key, const std:
492491
}
493492
}
494493
if (!wasm_handle) {
494+
// If no cached base_wasm, creates a new base_wasm, loads the code and initializes it.
495495
wasm_handle = factory(vm_key);
496496
if (!wasm_handle) {
497497
return nullptr;
498498
}
499-
is_new_wasm = true;
499+
if (!wasm_handle->wasm()->load(code, allow_precompiled)) {
500+
wasm_handle->wasm()->fail(FailState::UnableToInitializeCode, "Failed to load Wasm code");
501+
return nullptr;
502+
}
503+
if (!wasm_handle->wasm()->initialize()) {
504+
wasm_handle->wasm()->fail(FailState::UnableToInitializeCode,
505+
"Failed to initialize Wasm code");
506+
return nullptr;
507+
}
500508
(*base_wasms)[vm_key] = wasm_handle;
501509
}
502510
}
503-
if (is_new_wasm) {
504-
if (!wasm_handle->wasm()->load(code, allow_precompiled)) {
505-
wasm_handle->wasm()->fail(FailState::UnableToInitializeCode, "Failed to load Wasm code");
506-
return nullptr;
507-
}
508-
if (!wasm_handle->wasm()->initialize()) {
509-
wasm_handle->wasm()->fail(FailState::UnableToInitializeCode,
510-
"Failed to initialize Wasm code");
511-
return nullptr;
512-
}
513-
}
511+
512+
// Either creating new one or reusing the existing one, apply canary for each plugin.
514513
if (!canary(wasm_handle, plugin, clone_factory)) {
515514
return nullptr;
516515
}

test/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ cc_test(
9191
srcs = ["wasm_test.cc"],
9292
data = [
9393
"//test/test_data:abi_export.wasm",
94+
"//test/test_data:configure_check.wasm",
9495
],
9596
linkstatic = 1,
9697
deps = [

test/test_data/BUILD

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
load("@proxy_wasm_cpp_host//bazel:wasm.bzl", "wasm_rust_binary")
2+
load("@proxy_wasm_cpp_sdk//bazel/wasm:wasm.bzl", "wasm_cc_binary")
23

34
licenses(["notice"]) # Apache 2
45

@@ -59,3 +60,11 @@ wasm_rust_binary(
5960
srcs = ["random.rs"],
6061
wasi = True,
6162
)
63+
64+
wasm_cc_binary(
65+
name = "configure_check.wasm",
66+
srcs = ["configure_check.cc"],
67+
deps = [
68+
"@proxy_wasm_cpp_sdk//:proxy_wasm_intrinsics",
69+
],
70+
)

test/test_data/configure_check.cc

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <string>
16+
#include <string_view>
17+
#include <unordered_map>
18+
19+
#include "proxy_wasm_intrinsics.h"
20+
21+
class TestRootContext1 : public RootContext {
22+
public:
23+
explicit TestRootContext1(uint32_t id, std::string_view root_id) : RootContext(id, root_id) {}
24+
bool onConfigure(size_t s) override {
25+
// LOG_TRACE("onConfigure in TestRootContext1");
26+
return true;
27+
}
28+
};
29+
30+
class TestContext1 : public Context {
31+
public:
32+
explicit TestContext1(uint32_t id, RootContext *root) : Context(id, root) {}
33+
};
34+
35+
class TestRootContext2 : public RootContext {
36+
public:
37+
explicit TestRootContext2(uint32_t id, std::string_view root_id) : RootContext(id, root_id) {}
38+
bool onConfigure(size_t s) override {
39+
// LOG_TRACE("onConfigure in TestRootContext2");
40+
return true;
41+
}
42+
};
43+
44+
class TestContext2 : public Context {
45+
public:
46+
explicit TestContext2(uint32_t id, RootContext *root) : Context(id, root) {}
47+
};
48+
49+
static RegisterContextFactory register_TestContext1(CONTEXT_FACTORY(TestContext1),
50+
ROOT_FACTORY(TestRootContext1), "root_id_1");
51+
52+
static RegisterContextFactory register_TestContext2(CONTEXT_FACTORY(TestContext2),
53+
ROOT_FACTORY(TestRootContext2), "root_id_2");

test/wasm_test.cc

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,77 @@ TEST_P(TestVm, GetOrCreateThreadLocalWasmFailCallbacks) {
113113
ASSERT_NE(thread_local_plugin3->wasm(), thread_local_plugin2->wasm());
114114
}
115115

116+
// Tests the canary is always applied when making a call `createWasm`
117+
TEST_P(TestVm, AlwaysApplyCanaryForDifferentRootID) {
118+
// Use different root_id, but the others are the same
119+
const auto *const root_id_1 = "root_id_1";
120+
const auto *const root_id_2 = "root_id_2";
121+
const auto *const plugin_name = "plugin_name";
122+
const auto *const vm_id = "vm_id";
123+
const auto *const vm_config = "vm_config";
124+
const auto *const plugin_config = "plugin_config";
125+
const auto *const vm_key = "vm_key";
126+
const auto *const plugin_key = "plugin_key";
127+
const auto fail_open = false;
128+
129+
// Define callbacks.
130+
WasmHandleFactory wasm_handle_factory =
131+
[this, vm_id, vm_config](std::string_view vm_key) -> std::shared_ptr<WasmHandleBase> {
132+
auto base_wasm = std::make_shared<WasmBase>(newVm(), vm_id, vm_config, vm_key,
133+
std::unordered_map<std::string, std::string>{},
134+
AllowedCapabilitiesMap{});
135+
return std::make_shared<WasmHandleBase>(base_wasm);
136+
};
137+
138+
WasmHandleCloneFactory wasm_handle_clone_factory =
139+
[this](const std::shared_ptr<WasmHandleBase> &base_wasm_handle)
140+
-> std::shared_ptr<WasmHandleBase> {
141+
auto wasm = std::make_shared<WasmBase>(base_wasm_handle,
142+
[this]() -> std::unique_ptr<WasmVm> { return newVm(); });
143+
return std::make_shared<WasmHandleBase>(wasm);
144+
};
145+
146+
auto canary_count = 0;
147+
WasmHandleCloneFactory wasm_handle_clone_factory_for_canary =
148+
[&canary_count, this](const std::shared_ptr<WasmHandleBase> &base_wasm_handle)
149+
-> std::shared_ptr<WasmHandleBase> {
150+
auto wasm = std::make_shared<WasmBase>(base_wasm_handle,
151+
[this]() -> std::unique_ptr<WasmVm> { return newVm(); });
152+
canary_count++;
153+
return std::make_shared<WasmHandleBase>(wasm);
154+
};
155+
156+
PluginHandleFactory plugin_handle_factory =
157+
[](const std::shared_ptr<WasmHandleBase> &base_wasm,
158+
const std::shared_ptr<PluginBase> &plugin) -> std::shared_ptr<PluginHandleBase> {
159+
return std::make_shared<PluginHandleBase>(base_wasm, plugin);
160+
};
161+
162+
// Read the minimal loadable binary.
163+
auto source = readTestWasmFile("configure_check.wasm");
164+
165+
// Create a first plugin.
166+
const auto plugin_1 = std::make_shared<PluginBase>(plugin_name, root_id_1, vm_id, engine_,
167+
plugin_config, fail_open, plugin_key);
168+
// Create base Wasm via createWasm.
169+
auto base_wasm_handle_1 = createWasm(vm_key, source, plugin_1, wasm_handle_factory,
170+
wasm_handle_clone_factory_for_canary, false);
171+
ASSERT_TRUE(base_wasm_handle_1 && base_wasm_handle_1->wasm());
172+
173+
// Create a first plugin.
174+
const auto plugin_2 = std::make_shared<PluginBase>(plugin_name, root_id_2, vm_id, engine_,
175+
plugin_config, fail_open, plugin_key);
176+
// Create base Wasm via createWasm.
177+
auto base_wasm_handle_2 = createWasm(vm_key, source, plugin_2, wasm_handle_factory,
178+
wasm_handle_clone_factory_for_canary, false);
179+
ASSERT_TRUE(base_wasm_handle_2 && base_wasm_handle_2->wasm());
180+
181+
// Base Wasm
182+
EXPECT_EQ(base_wasm_handle_1->wasm(), base_wasm_handle_2->wasm());
183+
// Plugin key should be different with each other, because root_id is different.
184+
EXPECT_NE(plugin_1->key(), plugin_2->key());
185+
// For each create Wasm, canary should be done.
186+
EXPECT_EQ(canary_count, 2);
187+
}
188+
116189
} // namespace proxy_wasm

0 commit comments

Comments
 (0)