Skip to content

Commit 06c5d4c

Browse files
authored
test: move WasmVm tests into wasm_vm_test. (#275)
Signed-off-by: Piotr Sikora <[email protected]>
1 parent 7f63346 commit 06c5d4c

File tree

6 files changed

+231
-186
lines changed

6 files changed

+231
-186
lines changed

BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ cc_library(
7272
"//bazel:crypto_system": [],
7373
"//conditions:default": ["@boringssl//:crypto"],
7474
}),
75+
alwayslink = 1,
7576
)
7677

7778
cc_library(

src/exports.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121

2222
namespace proxy_wasm {
2323

24+
thread_local ContextBase *current_context_;
25+
thread_local uint32_t effective_context_id_ = 0;
26+
2427
// Any currently executing Wasm call context.
2528
ContextBase *contextOrEffectiveContext() {
2629
if (effective_context_id_ == 0) {

src/wasm.cc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@
3535

3636
namespace proxy_wasm {
3737

38-
thread_local ContextBase *current_context_;
39-
thread_local uint32_t effective_context_id_ = 0;
40-
4138
namespace {
4239

4340
// Map from Wasm Key to the local Wasm instance.

test/BUILD

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ cc_test(
5454
name = "runtime_test",
5555
srcs = ["runtime_test.cc"],
5656
data = [
57-
"//test/test_data:abi_export.wasm",
5857
"//test/test_data:callback.wasm",
5958
"//test/test_data:clock.wasm",
6059
"//test/test_data:infinite_loop.wasm",
@@ -133,6 +132,21 @@ cc_test(
133132
],
134133
)
135134

135+
cc_test(
136+
name = "wasm_vm_test",
137+
srcs = ["wasm_vm_test.cc"],
138+
data = [
139+
"//test/test_data:abi_export.wasm",
140+
],
141+
linkstatic = 1,
142+
deps = [
143+
":utility_lib",
144+
"//:lib",
145+
"@com_google_googletest//:gtest",
146+
"@com_google_googletest//:gtest_main",
147+
],
148+
)
149+
136150
cc_library(
137151
name = "utility_lib",
138152
testonly = True,

test/runtime_test.cc

Lines changed: 72 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,9 @@
1414

1515
#include "gtest/gtest.h"
1616

17-
#include <fstream>
18-
#include <iostream>
1917
#include <memory>
20-
#include <sstream>
2118
#include <string>
2219
#include <thread>
23-
#include <vector>
2420

2521
#include "include/proxy-wasm/context.h"
2622
#include "include/proxy-wasm/wasm.h"
@@ -35,137 +31,26 @@ INSTANTIATE_TEST_SUITE_P(WasmEngines, TestVm, testing::ValuesIn(getWasmEngines()
3531
return info.param;
3632
});
3733

38-
TEST_P(TestVm, Basic) {
39-
if (engine_ == "wamr") {
40-
EXPECT_EQ(vm_->cloneable(), proxy_wasm::Cloneable::NotCloneable);
41-
} else if (engine_ == "wasmtime" || engine_ == "v8") {
42-
EXPECT_EQ(vm_->cloneable(), proxy_wasm::Cloneable::CompiledBytecode);
43-
} else if (engine_ == "wavm") {
44-
EXPECT_EQ(vm_->cloneable(), proxy_wasm::Cloneable::InstantiatedModule);
45-
} else {
46-
FAIL();
47-
}
48-
EXPECT_EQ(vm_->getEngineName(), engine_);
49-
}
50-
51-
TEST_P(TestVm, Memory) {
52-
auto source = readTestWasmFile("abi_export.wasm");
53-
ASSERT_TRUE(vm_->load(source, {}, {}));
54-
ASSERT_TRUE(vm_->link(""));
55-
56-
Word word;
57-
ASSERT_TRUE(vm_->setWord(0x2000, Word(100)));
58-
ASSERT_TRUE(vm_->getWord(0x2000, &word));
59-
ASSERT_EQ(100, word.u64_);
60-
61-
uint32_t data[2] = {htowasm(static_cast<uint32_t>(-1)), htowasm(200)};
62-
ASSERT_TRUE(vm_->setMemory(0x200, sizeof(int32_t) * 2, static_cast<void *>(data)));
63-
ASSERT_TRUE(vm_->getWord(0x200, &word));
64-
ASSERT_EQ(-1, static_cast<int32_t>(word.u64_));
65-
ASSERT_TRUE(vm_->getWord(0x204, &word));
66-
ASSERT_EQ(200, static_cast<int32_t>(word.u64_));
67-
}
68-
69-
TEST_P(TestVm, Clone) {
70-
if (vm_->cloneable() == proxy_wasm::Cloneable::NotCloneable) {
71-
return;
72-
}
73-
auto source = readTestWasmFile("abi_export.wasm");
74-
ASSERT_TRUE(vm_->load(source, {}, {}));
75-
ASSERT_TRUE(vm_->link(""));
76-
const auto address = 0x2000;
77-
Word word;
78-
{
79-
auto clone = vm_->clone();
80-
ASSERT_TRUE(clone != nullptr);
81-
ASSERT_NE(vm_, clone);
82-
if (clone->cloneable() != proxy_wasm::Cloneable::InstantiatedModule) {
83-
ASSERT_TRUE(clone->link(""));
84-
}
85-
86-
ASSERT_TRUE(clone->setWord(address, Word(100)));
87-
ASSERT_TRUE(clone->getWord(address, &word));
88-
ASSERT_EQ(100, word.u64_);
89-
}
90-
91-
// check memory arrays are not overrapped
92-
ASSERT_TRUE(vm_->getWord(address, &word));
93-
ASSERT_NE(100, word.u64_);
94-
}
95-
96-
#if defined(__linux__) && defined(__x86_64__)
97-
98-
TEST_P(TestVm, CloneUntilOutOfMemory) {
99-
if (vm_->cloneable() == proxy_wasm::Cloneable::NotCloneable) {
100-
return;
101-
}
102-
if (engine_ == "wavm") {
103-
// TODO(PiotrSikora): Figure out why this fails on the CI.
104-
return;
105-
}
106-
107-
auto source = readTestWasmFile("abi_export.wasm");
108-
ASSERT_TRUE(vm_->load(source, {}, {}));
109-
ASSERT_TRUE(vm_->link(""));
110-
111-
size_t max_clones = 100000;
112-
#if defined(__has_feature)
113-
#if __has_feature(address_sanitizer)
114-
max_clones = 1000;
115-
#endif
116-
#endif
117-
118-
std::vector<std::unique_ptr<WasmVm>> clones;
119-
for (size_t i = 0; i < max_clones; i++) {
120-
auto clone = vm_->clone();
121-
if (clone == nullptr) {
122-
break;
123-
}
124-
if (clone->cloneable() != proxy_wasm::Cloneable::InstantiatedModule) {
125-
if (!clone->link("")) {
126-
break;
127-
}
128-
}
129-
// Prevent clone from droping out of scope and freeing memory.
130-
clones.push_back(std::move(clone));
131-
}
132-
133-
size_t min_clones = 1000;
134-
#if defined(__has_feature)
135-
#if __has_feature(thread_sanitizer)
136-
min_clones = 100;
137-
#endif
138-
#endif
139-
EXPECT_GE(clones.size(), min_clones);
140-
}
141-
142-
#endif
143-
144-
class TestCounterContext : public TestContext {
145-
public:
146-
TestCounterContext(WasmBase *wasm) : TestContext(wasm) {}
147-
148-
void increment() { counter++; }
149-
size_t getCount() { return counter; }
150-
151-
private:
152-
size_t counter = 0;
153-
};
34+
TEST_P(TestVm, BadSignature) {
35+
auto source = readTestWasmFile("clock.wasm");
36+
ASSERT_FALSE(source.empty());
37+
auto wasm = TestWasm(std::move(vm_));
38+
ASSERT_TRUE(wasm.load(source, false));
39+
ASSERT_TRUE(wasm.initialize());
15440

155-
class TestCounterWasm : public TestWasm {
156-
public:
157-
TestCounterWasm(std::unique_ptr<WasmVm> wasm_vm) : TestWasm(std::move(wasm_vm)) {}
41+
WasmCallVoid<0> non_existent;
42+
wasm.wasm_vm()->getFunction("non_existent", &non_existent);
43+
EXPECT_TRUE(non_existent == nullptr);
15844

159-
ContextBase *createVmContext() override { return new TestCounterContext(this); };
160-
};
45+
WasmCallWord<2> bad_signature_run;
46+
wasm.wasm_vm()->getFunction("run", &bad_signature_run);
47+
EXPECT_TRUE(bad_signature_run == nullptr);
16148

162-
void callback() {
163-
auto *context = dynamic_cast<TestCounterContext *>(contextOrEffectiveContext());
164-
context->increment();
49+
WasmCallVoid<0> run;
50+
wasm.wasm_vm()->getFunction("run", &run);
51+
ASSERT_TRUE(run != nullptr);
16552
}
16653

167-
Word callback2(Word val) { return val + 100; }
168-
16954
TEST_P(TestVm, StraceLogLevel) {
17055
if (engine_ == "wavm") {
17156
// TODO(mathetake): strace is yet to be implemented for WAVM.
@@ -196,58 +81,6 @@ TEST_P(TestVm, StraceLogLevel) {
19681
EXPECT_TRUE(host->isTraceLogged("[host<-vm] run return: void"));
19782
}
19883

199-
TEST_P(TestVm, BadExportFunction) {
200-
auto source = readTestWasmFile("clock.wasm");
201-
ASSERT_FALSE(source.empty());
202-
auto wasm = TestWasm(std::move(vm_));
203-
ASSERT_TRUE(wasm.load(source, false));
204-
ASSERT_TRUE(wasm.initialize());
205-
206-
WasmCallVoid<0> non_existent;
207-
wasm.wasm_vm()->getFunction("non_existent", &non_existent);
208-
EXPECT_TRUE(non_existent == nullptr);
209-
210-
WasmCallWord<2> bad_signature_run;
211-
wasm.wasm_vm()->getFunction("run", &bad_signature_run);
212-
EXPECT_TRUE(bad_signature_run == nullptr);
213-
214-
WasmCallVoid<0> run;
215-
wasm.wasm_vm()->getFunction("run", &run);
216-
ASSERT_TRUE(run != nullptr);
217-
}
218-
219-
TEST_P(TestVm, Callback) {
220-
auto source = readTestWasmFile("callback.wasm");
221-
ASSERT_FALSE(source.empty());
222-
auto wasm = TestCounterWasm(std::move(vm_));
223-
ASSERT_TRUE(wasm.load(source, false));
224-
225-
wasm.wasm_vm()->registerCallback(
226-
"env", "callback", &callback,
227-
&ConvertFunctionWordToUint32<decltype(callback), callback>::convertFunctionWordToUint32);
228-
229-
wasm.wasm_vm()->registerCallback(
230-
"env", "callback2", &callback2,
231-
&ConvertFunctionWordToUint32<decltype(callback2), callback2>::convertFunctionWordToUint32);
232-
233-
ASSERT_TRUE(wasm.initialize());
234-
235-
WasmCallVoid<0> run;
236-
wasm.wasm_vm()->getFunction("run", &run);
237-
ASSERT_TRUE(run != nullptr);
238-
for (auto i = 0; i < 5; i++) {
239-
run(wasm.vm_context());
240-
}
241-
auto *context = dynamic_cast<TestCounterContext *>(wasm.vm_context());
242-
EXPECT_EQ(context->getCount(), 5);
243-
244-
WasmCallWord<1> run2;
245-
wasm.wasm_vm()->getFunction("run2", &run2);
246-
ASSERT_TRUE(run2 != nullptr);
247-
Word res = run2(wasm.vm_context(), Word{0});
248-
EXPECT_EQ(res.u32(), 100100); // 10000 (global) + 100 (in callback)
249-
}
250-
25184
TEST_P(TestVm, TerminateExecution) {
25285
// TODO(chaoqin-li1123): implement execution termination for other runtime.
25386
if (engine_ != "v8") {
@@ -329,5 +162,62 @@ TEST_P(TestVm, Trap2) {
329162
}
330163
}
331164

165+
class TestCounterContext : public TestContext {
166+
public:
167+
TestCounterContext(WasmBase *wasm) : TestContext(wasm) {}
168+
169+
void increment() { counter++; }
170+
size_t getCount() { return counter; }
171+
172+
private:
173+
size_t counter = 0;
174+
};
175+
176+
class TestCounterWasm : public TestWasm {
177+
public:
178+
TestCounterWasm(std::unique_ptr<WasmVm> wasm_vm) : TestWasm(std::move(wasm_vm)) {}
179+
180+
ContextBase *createVmContext() override { return new TestCounterContext(this); };
181+
};
182+
183+
void callback() {
184+
auto *context = dynamic_cast<TestCounterContext *>(contextOrEffectiveContext());
185+
context->increment();
186+
}
187+
188+
Word callback2(Word val) { return val + 100; }
189+
190+
TEST_P(TestVm, Callback) {
191+
auto source = readTestWasmFile("callback.wasm");
192+
ASSERT_FALSE(source.empty());
193+
auto wasm = TestCounterWasm(std::move(vm_));
194+
ASSERT_TRUE(wasm.load(source, false));
195+
196+
wasm.wasm_vm()->registerCallback(
197+
"env", "callback", &callback,
198+
&ConvertFunctionWordToUint32<decltype(callback), callback>::convertFunctionWordToUint32);
199+
200+
wasm.wasm_vm()->registerCallback(
201+
"env", "callback2", &callback2,
202+
&ConvertFunctionWordToUint32<decltype(callback2), callback2>::convertFunctionWordToUint32);
203+
204+
ASSERT_TRUE(wasm.initialize());
205+
206+
WasmCallVoid<0> run;
207+
wasm.wasm_vm()->getFunction("run", &run);
208+
ASSERT_TRUE(run != nullptr);
209+
for (auto i = 0; i < 5; i++) {
210+
run(wasm.vm_context());
211+
}
212+
auto *context = dynamic_cast<TestCounterContext *>(wasm.vm_context());
213+
EXPECT_EQ(context->getCount(), 5);
214+
215+
WasmCallWord<1> run2;
216+
wasm.wasm_vm()->getFunction("run2", &run2);
217+
ASSERT_TRUE(run2 != nullptr);
218+
Word res = run2(wasm.vm_context(), Word{0});
219+
EXPECT_EQ(res.u32(), 100100); // 10000 (global) + 100 (in callback)
220+
}
221+
332222
} // namespace
333223
} // namespace proxy_wasm

0 commit comments

Comments
 (0)