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

add e2e tests on examples #40

Merged
merged 1 commit into from
Sep 10, 2020
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
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.DEFAULT_GOAL := build.examples

.PHONY: help build.examples lint test test.sdk test.e2e
.PHONY: help build.example build.examples lint test test.sdk test.e2e
help:
grep -E '^[a-z0-9A-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

Expand All @@ -20,7 +20,7 @@ test.sdk:
go test -tags=proxytest -race -v ./proxywasm/...

test.e2e:
go test -tags=proxytest -race -v ./e2e
go test -tags=proxytest -v ./e2e

run:
getenvoy run wasm:1.15 -- -c ./examples/${name}/envoy.yaml
246 changes: 245 additions & 1 deletion e2e/e2e_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,251 @@
// Copyright 2020 Tetrate
//
// Licensed 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 e2e

import (
"bytes"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"strings"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestMain(m *testing.M) {
if err := os.Chdir(".."); err != nil {
log.Fatal(err)
}
os.Exit(m.Run())
}

const (
envoyVersion = "wasm:1.15"
envoyEndpoint = "http://localhost:18000"
envoyAdminEndpoint = "http://localhost:8001"
)

func Test_examples(t *testing.T) {}
func startExample(t *testing.T, name string) (*exec.Cmd, *bytes.Buffer) {
cmd := exec.Command("getenvoy",
"run",
envoyVersion,
"--",
"--concurrency", "1",
"-c", fmt.Sprintf("./examples/%s/envoy.yaml", name))

buf := new(bytes.Buffer)
cmd.Stderr = buf
require.NoError(t, cmd.Start())

time.Sleep(time.Second * 5) // TODO: use admin endpoint to check health
return cmd, buf
}

func TestE2E_helloworld(t *testing.T) {
cmd, stdErr := startExample(t, "helloworld")
defer func() {
require.NoError(t, cmd.Process.Kill())
}()

out := stdErr.String()
fmt.Println(out)

var onVMLog, onTickOK bool
for _, line := range strings.Split(out, "\n") {
if strings.Contains(line, "wasm log helloworld: proxy_on_vm_start from Go!") {
fmt.Println(line)
onVMLog = true
}

if strings.Contains(line, "wasm log helloworld: OnTick on ") {
fmt.Println(line)
onTickOK = true
}
}

assert.True(t, onVMLog)
assert.True(t, onTickOK)
}

func TestE2E_http_auth_random(t *testing.T) {
cmd, stdErr := startExample(t, "http_auth_random")
defer func() {
require.NoError(t, cmd.Process.Kill())
}()

req, err := http.NewRequest("GET", envoyEndpoint+"/uuid", nil)
require.NoError(t, err)

key := "this-is-key"
value := "this-is-value"
req.Header.Add(key, value)

for i := 0; i < 25; i++ { // TODO: maybe flaky
r, err := http.DefaultClient.Do(req)
require.NoError(t, err)
r.Body.Close()
}

out := stdErr.String()
fmt.Println(out)
var accessForbidden bool
var accessGranted bool
for _, line := range strings.Split(out, "\n") {
if strings.Contains(line, "access forbidden") {
accessForbidden = true
}

if strings.Contains(line, "access granted") {
accessGranted = true
}
}

assert.True(t, accessForbidden)
assert.True(t, accessGranted)
}

func TestE2E_http_headers(t *testing.T) {
cmd, stdErr := startExample(t, "http_headers")
defer func() {
require.NoError(t, cmd.Process.Kill())
}()

req, err := http.NewRequest("GET", envoyEndpoint, nil)
require.NoError(t, err)

key := "this-is-key"
value := "this-is-value"
req.Header.Add(key, value)

r, err := http.DefaultClient.Do(req)
require.NoError(t, err)
defer r.Body.Close()

out := stdErr.String()
fmt.Println(out)

var keyLogged, valueLogged, responseHeaderLogged bool
for _, line := range strings.Split(out, "\n") {
if strings.Contains(line, key) {
keyLogged = true
}

if strings.Contains(line, value) {
valueLogged = true
}

if strings.Contains(line, "server: envoy") {
responseHeaderLogged = true
}
}

assert.True(t, keyLogged)
assert.True(t, valueLogged)
assert.True(t, responseHeaderLogged)
}

func TestE2E_metrics(t *testing.T) {
cmd, stdErr := startExample(t, "metrics")
defer func() {
require.NoError(t, cmd.Process.Kill())
}()

req, err := http.NewRequest("GET", envoyEndpoint, nil)
require.NoError(t, err)

count := 10
for i := 0; i < count; i++ {
r, err := http.DefaultClient.Do(req)
require.NoError(t, err)
r.Body.Close()
}

fmt.Println(stdErr.String())

req, err = http.NewRequest("GET", envoyAdminEndpoint+"/stats", nil)
require.NoError(t, err)

r, err := http.DefaultClient.Do(req)
require.NoError(t, err)
defer r.Body.Close()

b, err := ioutil.ReadAll(r.Body)
require.NoError(t, err)
assert.True(t, strings.Contains(string(b), fmt.Sprintf("proxy_wasm_go.request_counter: %d", count)))
}

func TestE2E_shared_data(t *testing.T) {
cmd, stdErr := startExample(t, "shared_data")
defer func() {
require.NoError(t, cmd.Process.Kill())
}()

req, err := http.NewRequest("GET", envoyEndpoint, nil)
require.NoError(t, err)

count := 10
for i := 0; i < count; i++ {
r, err := http.DefaultClient.Do(req)
require.NoError(t, err)
r.Body.Close()
}

out := stdErr.String()
fmt.Println(out)
assert.True(t, strings.Contains(out, fmt.Sprintf("shared value: %d", count)))
}

func TestE2E_shared_queue(t *testing.T) {
cmd, stdErr := startExample(t, "shared_queue")
defer func() {
require.NoError(t, cmd.Process.Kill())
}()

req, err := http.NewRequest("GET", envoyEndpoint, nil)
require.NoError(t, err)

count := 10
for i := 0; i < count; i++ {
r, err := http.DefaultClient.Do(req)
require.NoError(t, err)
r.Body.Close()
}

time.Sleep(time.Second * 2)

out := stdErr.String()
fmt.Println(out)
assert.True(t, strings.Contains(out, "dequed data: hello"))
assert.True(t, strings.Contains(out, "dequed data: world"))
assert.True(t, strings.Contains(out, "dequed data: proxy-wasm"))
}

func TestE2E_vm_plugin_configuration(t *testing.T) {
cmd, stdErr := startExample(t, "vm_plugin_configuration")
defer func() {
require.NoError(t, cmd.Process.Kill())
}()

out := stdErr.String()
fmt.Println(out)
assert.True(t, strings.Contains(out, "name\": \"vm configuration"))
assert.True(t, strings.Contains(out, "name\": \"plugin configuration"))
}
8 changes: 4 additions & 4 deletions examples/helloworld/envoy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ static_resources:
address:
socket_address:
address: 127.0.0.1
port_value: 1234
port_value: 18000
filter_chains:
- filters:
- name: envoy.http_connection_manager
Expand All @@ -26,10 +26,10 @@ static_resources:
- name: envoy.filters.http.wasm
config:
config:
name: "my_plugin"
root_id: "my_root_id"
name: "helloworld"
root_id: "helloworld"
vm_config:
vm_id: "my_vm_id"
vm_id: "helloworld"
runtime: "envoy.wasm.runtime.v8"
code:
local:
Expand Down
2 changes: 1 addition & 1 deletion examples/shared_queue/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type queue struct{ proxywasm.DefaultContext }

const (
queueName = "proxy_wasm_go.queue"
tickMilliseconds = 1000
tickMilliseconds = 100
)

var queueID uint32
Expand Down