Skip to content

Commit 3bf5f40

Browse files
authored
feat: add getProperty support to plugin tester (GoogleCloudPlatform#284)
feat: add getProperty support to plugin tester Signed-off-by: Michael Warres <mpw@google.com>
1 parent f291e07 commit 3bf5f40

File tree

5 files changed

+59
-10
lines changed

5 files changed

+59
-10
lines changed

plugins/test/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ cc_library(
88
srcs = ["framework.cc"],
99
hdrs = ["framework.h"],
1010
deps = [
11+
":runner_cc_proto",
1112
"@boost//:algorithm",
1213
"@boost//:dll",
1314
"@boost//:filesystem",

plugins/test/dynamic_test.cc

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
#include "test/dynamic_test.h"
1818

19+
#include <memory>
20+
#include <string>
21+
#include <vector>
22+
1923
#include <boost/filesystem/path.hpp>
2024

2125
#include "absl/random/distributions.h"
@@ -135,11 +139,13 @@ class AdditionalStream {
135139
};
136140

137141
AdditionalStream(std::shared_ptr<proxy_wasm::PluginHandleBase> handle,
142+
const pb::Test* cfg,
138143
const TestHttpContext::Headers* request_headers,
139144
const TestHttpContext::Headers* response_headers,
140145
const std::vector<std::string>* request_body_chunks,
141146
const std::vector<std::string>* response_body_chunks)
142147
: handle_(handle),
148+
cfg_(*cfg),
143149
request_headers_(request_headers),
144150
response_headers_(response_headers),
145151
request_body_chunks_(request_body_chunks),
@@ -155,6 +161,7 @@ class AdditionalStream {
155161

156162
private:
157163
std::shared_ptr<proxy_wasm::PluginHandleBase> handle_;
164+
const pb::Test& cfg_;
158165

159166
// These fields are owned by the caller, and assumed to remain valid and not
160167
// change over the lifetime of the AdditionalStream.
@@ -174,7 +181,7 @@ absl::Status AdditionalStream::Advance() {
174181
while (true) { // cycle through actions until one is performed
175182
switch (next_action_) {
176183
case NextAction::kCreate:
177-
stream_ = std::make_unique<TestHttpContext>(handle_);
184+
stream_ = std::make_unique<TestHttpContext>(handle_, &cfg_);
178185
if (request_body_chunks_ != nullptr) {
179186
remaining_request_body_chunks_.assign(request_body_chunks_->begin(),
180187
request_body_chunks_->end());
@@ -321,7 +328,7 @@ void DynamicTest::TestBody() {
321328
CheckSideEffects("plugin_init", cfg_.plugin_init(), *root_context);
322329

323330
// Initialize stream.
324-
auto stream = TestHttpContext(handle);
331+
auto stream = TestHttpContext(handle, &cfg_);
325332
ASSERT_VM_HEALTH("stream_init", handle, stream);
326333
CheckSideEffects("stream_init", cfg_.stream_init(), stream);
327334

@@ -474,7 +481,7 @@ void DynamicTest::BenchStreamLifecycle(benchmark::State& state) {
474481

475482
std::vector<AdditionalStream> additional_streams;
476483
for (int i = 0; i < env_.num_additional_streams(); ++i) {
477-
additional_streams.emplace_back(handle, /*request_headers=*/nullptr,
484+
additional_streams.emplace_back(handle, &cfg_, /*request_headers=*/nullptr,
478485
/*response_headers=*/nullptr,
479486
/*request_body_chunks=*/nullptr,
480487
/*response_body_chunks=*/nullptr);
@@ -484,7 +491,7 @@ void DynamicTest::BenchStreamLifecycle(benchmark::State& state) {
484491
// Benchmark stream initialization and teardown.
485492
bool first = true;
486493
for (auto _ : state) {
487-
auto stream = TestHttpContext(handle);
494+
auto stream = TestHttpContext(handle, &cfg_);
488495
benchmark::DoNotOptimize(stream);
489496
BM_RETURN_IF_FAILED(handle);
490497
stream.TearDown();
@@ -530,9 +537,10 @@ void DynamicTest::BenchHttpHandlers(benchmark::State& state) {
530537
std::vector<AdditionalStream> additional_streams;
531538
for (int i = 0; i < env_.num_additional_streams(); ++i) {
532539
additional_streams.emplace_back(
533-
handle, request_headers.has_value() ? &*request_headers : nullptr,
534-
response_headers.has_value() ? &*response_headers : nullptr,
535-
&*request_body_chunks, &*response_body_chunks);
540+
handle, &cfg_,
541+
request_headers.has_value() ? &*request_headers : nullptr,
542+
response_headers.has_value() ? &*response_headers : nullptr,
543+
&*request_body_chunks, &*response_body_chunks);
536544
// Advance twice, once to create the TestHttpContext and once to perform
537545
// an HTTP handler callback.
538546
BM_RETURN_IF_ERROR(additional_streams.back().Advance());
@@ -550,7 +558,7 @@ void DynamicTest::BenchHttpHandlers(benchmark::State& state) {
550558
// - include stream context create/destroy cost in handler benchmarks
551559
// - don't hand ownership of body chunks to stream context
552560
state.PauseTiming();
553-
stream.emplace(handle); // create/destroy TestHttpContext
561+
stream.emplace(handle, &cfg_); // create/destroy TestHttpContext
554562
std::vector<std::string> request_body_chunks_copies = *request_body_chunks;
555563
std::vector<std::string> response_body_chunks_copies =
556564
*response_body_chunks;

plugins/test/framework.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,16 @@
1414

1515
#include "test/framework.h"
1616

17+
#include <memory>
18+
#include <string>
19+
#include <utility>
20+
#include <vector>
21+
1722
#include <boost/dll/runtime_symbol_info.hpp>
1823

1924
#include "absl/strings/str_cat.h"
25+
#include "absl/strings/str_join.h"
26+
#include "absl/strings/str_split.h"
2027

2128
namespace service_extensions_samples {
2229

@@ -155,6 +162,21 @@ proxy_wasm::WasmResult TestHttpContext::setHeaderMapPairs(
155162
return proxy_wasm::WasmResult::Ok;
156163
}
157164

165+
proxy_wasm::WasmResult TestHttpContext::getProperty(std::string_view path,
166+
std::string* result) {
167+
// Proxy-Wasm SDKs use \0 as a path separator:
168+
// https://github.com/proxy-wasm/spec/pull/94
169+
std::string translated_path = absl::StrJoin(
170+
absl::StrSplit(path, absl::string_view("\0", 1), absl::SkipEmpty()), ".");
171+
for (const pb::Property& property : cfg_.properties()) {
172+
if (property.path() == translated_path) {
173+
*result = property.value();
174+
return proxy_wasm::WasmResult::Ok;
175+
}
176+
}
177+
return proxy_wasm::WasmResult::NotFound;
178+
}
179+
158180
proxy_wasm::WasmResult TestHttpContext::sendLocalResponse(
159181
uint32_t response_code, std::string_view body_text,
160182
proxy_wasm::Pairs additional_headers, uint32_t grpc_status,

plugins/test/framework.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "gtest/gtest.h"
2727
#include "include/proxy-wasm/exports.h"
2828
#include "include/proxy-wasm/wasm.h"
29+
#include "test/runner.pb.h"
2930
#include "test/utility.h"
3031

3132
namespace service_extensions_samples {
@@ -130,13 +131,15 @@ class TestContext : public proxy_wasm::TestContext {
130131
// - size checks
131132
class TestHttpContext : public TestContext {
132133
public:
133-
TestHttpContext(std::shared_ptr<proxy_wasm::PluginHandleBase> plugin_handle)
134+
TestHttpContext(std::shared_ptr<proxy_wasm::PluginHandleBase> plugin_handle,
135+
const pb::Test* cfg)
134136
: TestContext(plugin_handle->wasm().get(),
135137
plugin_handle->wasm()
136138
->getRootContext(plugin_handle->plugin(),
137139
/*allow_closed=*/false)
138140
->id(),
139-
plugin_handle) {
141+
plugin_handle),
142+
cfg_(*cfg) {
140143
this->onCreate();
141144
}
142145
~TestHttpContext() override { TearDown(); }
@@ -172,6 +175,8 @@ class TestHttpContext : public TestContext {
172175
proxy_wasm::WasmResult setHeaderMapPairs(
173176
proxy_wasm::WasmHeaderMapType type,
174177
const proxy_wasm::Pairs& pairs) override;
178+
proxy_wasm::WasmResult getProperty(std::string_view path,
179+
std::string* result) override;
175180

176181
// Ignore failStream, avoid calling unimplemented closeStream.
177182
void failStream(proxy_wasm::WasmStreamType) override {}
@@ -234,6 +239,7 @@ class TestHttpContext : public TestContext {
234239
};
235240

236241
private:
242+
const pb::Test& cfg_;
237243
// Ensure that we invoke teardown handlers just once.
238244
bool torn_down_ = false;
239245
// State tracked during a headers call. Invalid otherwise.

plugins/test/runner.proto

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ message StringMatcher {
3232
}
3333
}
3434

35+
// HTTP header.
3536
message Header {
3637
string key = 1;
3738
bytes value = 2;
@@ -90,6 +91,14 @@ message Invocation {
9091
Expectation result = 2;
9192
}
9293

94+
// Value to be returned by getProperty() hostcalls when the path matches.
95+
message Property {
96+
// Path that names the property. The '.' char acts as a path segment
97+
// separator.
98+
string path = 1;
99+
bytes value = 2;
100+
}
101+
93102
// Tests to run for a single HTTP request/response.
94103
message Test {
95104
// Unique name to identify test results.
@@ -104,6 +113,9 @@ message Test {
104113
int32 num_chunks = 10;
105114
int64 chunk_size = 11;
106115
}
116+
// Properties to return from getProperty() hostcalls in stream-level Wasm
117+
// invocations (i.e. HTTP phases, stream_init, and stream_destroy).
118+
repeated Property properties = 12;
107119
// Wasm invocations of various HTTP phases. If multiple phases are provided,
108120
// they are executed in sequence on the same HttpContext. Each phase specifies
109121
// its own expectations. If any phase results in an immediate response,

0 commit comments

Comments
 (0)