This is an automated email from the ASF dual-hosted git repository.

spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new 9df6e88  test(wasm): add fault-injection example (#5337)
9df6e88 is described below

commit 9df6e887349e31e9159f99dc7a874dba3798a299
Author: 罗泽轩 <[email protected]>
AuthorDate: Wed Oct 27 10:27:27 2021 +0800

    test(wasm): add fault-injection example (#5337)
---
 t/wasm/fault-injection.t       | 186 +++++++++++++++++++++++++++++++++++++++++
 t/wasm/fault-injection/main.go | 108 ++++++++++++++++++++++++
 t/wasm/go.mod                  |   6 +-
 t/wasm/go.sum                  |   7 ++
 4 files changed, 306 insertions(+), 1 deletion(-)

diff --git a/t/wasm/fault-injection.t b/t/wasm/fault-injection.t
new file mode 100644
index 0000000..addeddd
--- /dev/null
+++ b/t/wasm/fault-injection.t
@@ -0,0 +1,186 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+use t::APISIX;
+
+my $nginx_binary = $ENV{'TEST_NGINX_BINARY'} || 'nginx';
+my $version = eval { `$nginx_binary -V 2>&1` };
+
+if ($version !~ m/\/apisix-nginx-module/) {
+    plan(skip_all => "apisix-nginx-module not installed");
+} else {
+    plan('no_plan');
+}
+
+add_block_preprocessor(sub {
+    my ($block) = @_;
+
+    if ((!defined $block->error_log) && (!defined $block->no_error_log)) {
+        $block->set_value("no_error_log", "[error]");
+    }
+
+    if (!defined $block->request) {
+        $block->set_value("request", "GET /t");
+    }
+
+    my $extra_yaml_config = <<_EOC_;
+wasm:
+    plugins:
+        - name: wasm_fault_injection
+          priority: 7997
+          file: t/wasm/fault-injection/main.go.wasm
+_EOC_
+    $block->set_value("extra_yaml_config", $extra_yaml_config);
+});
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: fault injection
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/routes/1',
+                ngx.HTTP_PUT,
+                [[{
+                    "uri": "/hello",
+                    "upstream": {
+                        "type": "roundrobin",
+                        "nodes": {
+                            "127.0.0.1:1980": 1
+                        }
+                    },
+                    "plugins": {
+                        "wasm_fault_injection": {
+                            "conf": "{\"http_status\":401, \"body\":\"HIT\n\"}"
+                        }
+                    }
+                }]]
+            )
+
+            if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+
+            ngx.say(body)
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 2: hit
+--- request
+GET /hello
+--- error_code: 401
+--- response_body
+HIT
+
+
+
+=== TEST 3: fault injection, with 0 percentage
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/routes/1',
+                ngx.HTTP_PUT,
+                [[{
+                    "uri": "/hello",
+                    "upstream": {
+                        "type": "roundrobin",
+                        "nodes": {
+                            "127.0.0.1:1980": 1
+                        }
+                    },
+                    "plugins": {
+                        "wasm_fault_injection": {
+                            "conf": "{\"http_status\":401, \"percentage\":0}"
+                        }
+                    }
+                }]]
+            )
+
+            if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+
+            ngx.say(body)
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 4: hit
+--- request
+GET /hello
+--- response_body
+hello world
+
+
+
+=== TEST 5: fault injection without body
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/routes/1',
+                ngx.HTTP_PUT,
+                [[{
+                    "uri": "/hello",
+                    "upstream": {
+                        "type": "roundrobin",
+                        "nodes": {
+                            "127.0.0.1:1980": 1
+                        }
+                    },
+                    "plugins": {
+                        "wasm_fault_injection": {
+                            "conf": "{\"http_status\":401}"
+                        }
+                    }
+                }]]
+            )
+
+            if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+
+            ngx.say(body)
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 6: hit
+--- request
+GET /hello
+--- error_code: 401
+--- response_body_like eval
+qr/<title>401 Authorization Required<\/title>/
diff --git a/t/wasm/fault-injection/main.go b/t/wasm/fault-injection/main.go
new file mode 100644
index 0000000..698bb97
--- /dev/null
+++ b/t/wasm/fault-injection/main.go
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "math/rand"
+
+       "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
+       "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
+
+       // tinygo doesn't support encoding/json, see 
https://github.com/tinygo-org/tinygo/issues/447
+       "github.com/valyala/fastjson"
+)
+
+func main() {
+       proxywasm.SetVMContext(&vmContext{})
+}
+
+type vmContext struct {
+       types.DefaultVMContext
+}
+
+func (*vmContext) NewPluginContext(contextID uint32) types.PluginContext {
+       return &pluginContext{}
+}
+
+type pluginContext struct {
+       types.DefaultPluginContext
+       Body       []byte
+       HttpStatus uint32
+       Percentage int
+}
+
+func (ctx *pluginContext) OnPluginStart(pluginConfigurationSize int) 
types.OnPluginStartStatus {
+       data, err := proxywasm.GetPluginConfiguration()
+       if err != nil {
+               proxywasm.LogErrorf("error reading plugin configuration: %v", 
err)
+               return types.OnPluginStartStatusFailed
+       }
+
+       var p fastjson.Parser
+       v, err := p.ParseBytes(data)
+       if err != nil {
+               proxywasm.LogErrorf("erorr decoding plugin configuration: %v", 
err)
+               return types.OnPluginStartStatusFailed
+       }
+       ctx.Body = v.GetStringBytes("body")
+       ctx.HttpStatus = uint32(v.GetUint("http_status"))
+       if v.Exists("percentage") {
+               ctx.Percentage = v.GetInt("percentage")
+       } else {
+               ctx.Percentage = 100
+       }
+
+       // schema check
+       if ctx.HttpStatus < 200 {
+               proxywasm.LogError("bad http_status")
+               return types.OnPluginStartStatusFailed
+       }
+       if ctx.Percentage < 0 || ctx.Percentage > 100 {
+               proxywasm.LogError("bad percentage")
+               return types.OnPluginStartStatusFailed
+       }
+
+       return types.OnPluginStartStatusOK
+}
+
+func (ctx *pluginContext) NewHttpContext(contextID uint32) types.HttpContext {
+       return &httpLifecycle{parent: ctx}
+}
+
+type httpLifecycle struct {
+       types.DefaultHttpContext
+       parent *pluginContext
+}
+
+func sampleHit(percentage int) bool {
+       return rand.Intn(100) < percentage
+}
+
+func (ctx *httpLifecycle) OnHttpRequestHeaders(numHeaders int, endOfStream 
bool) types.Action {
+       plugin := ctx.parent
+       if !sampleHit(plugin.Percentage) {
+               return types.ActionContinue
+       }
+
+       err := proxywasm.SendHttpResponse(plugin.HttpStatus, nil, plugin.Body, 
-1)
+       if err != nil {
+               proxywasm.LogErrorf("failed to send local response: %v", err)
+               return types.ActionContinue
+       }
+       return types.ActionPause
+}
diff --git a/t/wasm/go.mod b/t/wasm/go.mod
index 9a875c8..3f9de8a 100644
--- a/t/wasm/go.mod
+++ b/t/wasm/go.mod
@@ -2,5 +2,9 @@ module github.com/api7/wasm-nginx-module
 
 go 1.15
 
-require github.com/tetratelabs/proxy-wasm-go-sdk 
v0.14.1-0.20210819090022-1e4e69881a31
+require (
+       github.com/tetratelabs/proxy-wasm-go-sdk 
v0.14.1-0.20210819090022-1e4e69881a31
+       github.com/valyala/fastjson v1.6.3
+)
+
 //replace github.com/tetratelabs/proxy-wasm-go-sdk => ../proxy-wasm-go-sdk
diff --git a/t/wasm/go.sum b/t/wasm/go.sum
index 599f226..97ddff7 100644
--- a/t/wasm/go.sum
+++ b/t/wasm/go.sum
@@ -1,8 +1,15 @@
+github.com/davecgh/go-spew v1.1.0 
h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 github.com/davecgh/go-spew v1.1.0/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 
h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod 
h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/stretchr/objx v0.1.0/go.mod 
h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.7.0 
h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod 
h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/tetratelabs/proxy-wasm-go-sdk v0.14.1-0.20210819090022-1e4e69881a31 
h1:V3GXN5nayOdIU3NypbxVegGFCVGm78qOA8Q7wkeudy8=
 github.com/tetratelabs/proxy-wasm-go-sdk 
v0.14.1-0.20210819090022-1e4e69881a31/go.mod 
h1:qZ+4i6e2wHlhnhgpH0VG4QFzqd2BEvQbQFU0npt2e2k=
+github.com/valyala/fastjson v1.6.3 
h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc=
+github.com/valyala/fastjson v1.6.3/go.mod 
h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 
h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod 
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c 
h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod 
h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

Reply via email to