Skip to content
This repository has been archived by the owner on May 16, 2024. It is now read-only.

Add higress e2e test #38

Merged
merged 10 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
target:
- coraza
- envoyDispatchCall
- higressGCTest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
Expand Down
12 changes: 12 additions & 0 deletions e2e/higress-gc-test/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
services:
envoy:
image: ${ENVOY_IMAGE:-envoyproxy/envoy:v1.28-latest}
command:
- -c
- /conf/envoy-config.yaml
volumes:
- ./build:/build
- .:/conf
ports:
- 8080:8080
- 8082:8082
58 changes: 58 additions & 0 deletions e2e/higress-gc-test/envoy-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
node:
cluster: test-cluster
id: test-idn

admin:
address:
socket_address: { address: 0.0.0.0, port_value: 8082 }

static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
per_connection_buffer_limit_bytes: 1024000000
filter_chains:
- filters:
- name: envoy.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
access_log:
- name: envoy.access_loggers.stdout
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
http_filters:
- name: gctest
typed_config:
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
name: basic_auth
vm_config:
runtime: envoy.wasm.runtime.v8
code:
local:
filename: /build/plugin.wasm
allow_precompiled: true
fail_open: true
configuration:
"@type": type.googleapis.com/google.protobuf.StringValue
value: '10485760'
- name: envoy.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: /
direct_response:
status: 200
body:
inline_string: "hello world"
7 changes: 7 additions & 0 deletions e2e/higress-gc-test/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module higress-gc-test

go 1.20

require github.com/tetratelabs/proxy-wasm-go-sdk v0.19.1-0.20220822060051-f9d179a57f8c

require github.com/stretchr/testify v1.8.0 // indirect
16 changes: 16 additions & 0 deletions e2e/higress-gc-test/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/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/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/tetratelabs/proxy-wasm-go-sdk v0.19.1-0.20220822060051-f9d179a57f8c h1:OCUFXVGixHLfNjg6/QYEhv+jHJ5mRGhpEUVFv9eWPJE=
github.com/tetratelabs/proxy-wasm-go-sdk v0.19.1-0.20220822060051-f9d179a57f8c/go.mod h1:5t/pWFNJ9eMyu/K/Z+OeGhDJ9sN9eCo8fc2pyM/Qjg4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
72 changes: 72 additions & 0 deletions e2e/higress-gc-test/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright wasilibs authors
// SPDX-License-Identifier: MIT

package main

import (
"bytes"
"fmt"
"runtime"
"strconv"

"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"

_ "github.com/wasilibs/nottinygc"
)

func main() {
proxywasm.SetVMContext(&vm{})
}

type vm struct {
types.DefaultVMContext
}

func (v *vm) NewPluginContext(contextID uint32) types.PluginContext {
return &plugin{}
}

type plugin struct {
// Embed the default plugin context here,
// so that we don't need to reimplement all the methods.
types.DefaultPluginContext

size int
}

// OnPluginStart Override types.DefaultPluginContext.
func (h *plugin) OnPluginStart(_ int) types.OnPluginStartStatus {
data, err := proxywasm.GetPluginConfiguration()
if err != nil {
panic(err)
}
sz, err := strconv.Atoi(string(bytes.TrimSpace(data)))
if err != nil {
panic(err)
}
h.size = sz
return types.OnPluginStartStatusOK
}

// NewHttpContext Override types.DefaultPluginContext to allow us to declare a request handler for each
// intercepted request the Envoy Sidecar sends us
func (h *plugin) NewHttpContext(_ uint32) types.HttpContext {
return &tester{size: h.size}
}

type tester struct {
types.DefaultHttpContext
size int
}

func (c *tester) OnHttpRequestHeaders(numHeaders int, endOfStream bool) types.Action {
b := make([]byte, c.size)
var m runtime.MemStats
runtime.ReadMemStats(&m)
proxywasm.LogInfof("alloc success, point address: %p", b)
memstats := fmt.Sprintf(`{"Sys": %d,"HeapSys": %d,"HeapIdle": %d,"HeapInuse": %d,"HeapReleased": %d}`, m.Sys, m.HeapSys, m.HeapIdle, m.HeapInuse, m.HeapReleased)
proxywasm.LogInfo(memstats)
proxywasm.SendHttpResponse(200, [][2]string{{"Content-Type", "application/json"}}, []byte(memstats), -1)
return types.ActionContinue
}
1 change: 1 addition & 0 deletions go.work
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ use (
.
./bench
./e2e/envoy-dispatch-call
./e2e/higress-gc-test
)
67 changes: 55 additions & 12 deletions magefiles/e2e.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ import (
)

func E2eCoraza() error {
if err := os.MkdirAll(filepath.Join("build", "logs"), 0o755); err != nil {
return err
}

if _, err := os.Stat(filepath.Join("e2e", "coraza-proxy-wasm")); os.IsNotExist(err) {
// Try not pinning version, there should be no compatibility issues causing unexpected failures from a
// green coraza build so we get to keep forward coverage this way.
Expand Down Expand Up @@ -66,10 +62,6 @@ func E2eCoraza() error {
}

func E2eEnvoyDispatchCall() error {
if err := os.MkdirAll(filepath.Join("build", "logs"), 0o755); err != nil {
return err
}

if err := os.MkdirAll(filepath.Join("e2e", "envoy-dispatch-call", "build"), 0o755); err != nil {
return err
}
Expand All @@ -88,7 +80,7 @@ func E2eEnvoyDispatchCall() error {
}
}()

stats, err := e2eLoad("http://localhost:8080/status/200", "http://localhost:8082/stats")
stats, err := e2eLoad("http://localhost:8080/status/200", "http://localhost:8082/stats", 40, 5000)
if err != nil {
return err
}
Expand Down Expand Up @@ -120,6 +112,53 @@ func E2eEnvoyDispatchCall() error {
return nil
}

func E2eHigressGCTest() error {
if err := os.MkdirAll(filepath.Join("e2e", "higress-gc-test", "build"), 0o755); err != nil {
return err
}

if err := sh.RunV("tinygo", "build", "-target=wasi", "-gc=custom", "-tags='custommalloc nottinygc_envoy'", "-scheduler=none",
"-o", filepath.Join("e2e", "higress-gc-test", "build", "plugin.wasm"), "./e2e/higress-gc-test"); err != nil {
return err
}

if err := sh.RunV("docker-compose", "--file", filepath.Join("e2e", "higress-gc-test", "docker-compose.yml"), "up", "-d"); err != nil {
return err
}
defer func() {
if err := sh.RunV("docker-compose", "--file", filepath.Join("e2e", "higress-gc-test", "docker-compose.yml"), "down", "-v"); err != nil {
panic(err)
}
}()

_, err := e2eLoad("http://localhost:8080/hello", "http://localhost:8082/stats", 2, 10000)
if err != nil {
return err
}

type memStats struct {
Sys int `json:"Sys"`
}

res, err := http.Get("http://localhost:8080/hello")
if err != nil {
return err
}
defer res.Body.Close()
var stats memStats
if err := json.NewDecoder(res.Body).Decode(&stats); err != nil {
return err
}

// We expect around 20MB per VM (this reports per VM stat), a conservative
// 100MB should be a fine check without flakiness
if mem := stats.Sys; mem > 100_000_000 {
return fmt.Errorf("expected <100MB memory used, actual: %d", mem)
}

return nil
}

type counterStat struct {
Name string `json:"name"`
Value int `json:"value"`
Expand All @@ -130,7 +169,7 @@ type counterStats struct {
}

// If needed, we can try being more sophisticated later but run some simple load for now.
func e2eLoad(url string, statsURL string) (*counterStats, error) {
func e2eLoad(url string, statsURL string, p int, n int) (*counterStats, error) {
wg := sync.WaitGroup{}

var success atomic.Uint32
Expand All @@ -154,8 +193,6 @@ func e2eLoad(url string, statsURL string) (*counterStats, error) {
return nil, errors.New("failed to get healthy in 100 attempts")
}

p := 40
n := 5000
for i := 0; i < p; i++ {
wg.Add(1)
go func() {
Expand Down Expand Up @@ -193,3 +230,9 @@ func e2eLoad(url string, statsURL string) (*counterStats, error) {

return &stats, nil
}

func init() {
if err := os.MkdirAll(filepath.Join("build", "logs"), 0o755); err != nil {
panic(err)
}
}