Skip to content

Commit

Permalink
fix egbuilder bug, add integration tests for egbuilder (#1164)
Browse files Browse the repository at this point in the history
* fix egbuilder bug, add integration tests for egbuilder

* update integration test
  • Loading branch information
suchen-sci authored Dec 8, 2023
1 parent d0b0605 commit 48e60b5
Show file tree
Hide file tree
Showing 5 changed files with 255 additions and 5 deletions.
17 changes: 15 additions & 2 deletions build/test/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,20 @@ import (
"strings"
)

func egctlCmd(args ...string) *exec.Cmd {
func egctlWithServer(server string, args ...string) *exec.Cmd {
egctl := os.Getenv("EGCTL")
if egctl == "" {
egctl = "egctl"
}
cmd := exec.Command(egctl, args...)
cmd.Args = append(cmd.Args, "--server", "http://127.0.0.1:12381")
cmd.Args = append(cmd.Args, "--server", server)
return cmd
}

func egctlCmd(args ...string) *exec.Cmd {
return egctlWithServer("http://127.0.0.1:12381", args...)
}

func runCmd(cmd *exec.Cmd) (string, string, error) {
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
Expand Down Expand Up @@ -110,3 +114,12 @@ func matchTable(array []string, output string) bool {
// Check if the regular expression matches the output string
return re.MatchString(output)
}

func egbuilderCmd(args ...string) *exec.Cmd {
egbuilder := os.Getenv("EGBUILDER")
if egbuilder == "" {
egbuilder = "egbuilder"
}
cmd := exec.Command(egbuilder, args...)
return cmd
}
236 changes: 236 additions & 0 deletions build/test/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"io"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
"sync/atomic"
Expand Down Expand Up @@ -1076,3 +1077,238 @@ filters:
assert.Nil(err)
assert.Equal("hello from websocket", string(data))
}

func TestEgbuilder(t *testing.T) {
assert := assert.New(t)

tempDir, err := os.MkdirTemp("", "easegress-test")
require.Nil(t, err)
defer os.RemoveAll(tempDir)

// init a new plugin repo
initCmd := egbuilderCmd(
"init",
"--repo", "github.com/test/repo",
"--filters=MyFilter1",
"--controllers=MyController1,MyController2",
)
initCmd.Dir = tempDir
stdout, stderr, err := runCmd(initCmd)
fmt.Printf("init stdout:\n%s\n", stdout)
fmt.Printf("init stderr:\n%s\n", stderr)
assert.NoError(err)

// add a new filters and controllers
addCmd := egbuilderCmd(
"add",
"--filters=MyFilter2",
"--controllers=MyController3",
)
addCmd.Dir = tempDir
stdout, stderr, err = runCmd(addCmd)
fmt.Printf("add stdout:\n%s\n", stdout)
fmt.Printf("add stderr:\n%s\n", stderr)
assert.NoError(err)

// build easegress with new plugins
buildConfig := `
plugins:
- module: github.com/test/repo
version: ""
replacement: %s
output: "%s/easegress-server"
`
buildConfig = fmt.Sprintf(buildConfig, tempDir, tempDir)
err = os.WriteFile(filepath.Join(tempDir, "build.yaml"), []byte(buildConfig), os.ModePerm)
assert.NoError(err)

buildCmd := egbuilderCmd(
"build",
"-f",
"build.yaml",
)
buildCmd.Dir = tempDir
stdout, stderr, err = runCmd(buildCmd)
fmt.Printf("build stdout:\n%s\n", stdout)
fmt.Printf("build stderr:\n%s\n", stderr)
assert.NoError(err)

// run easegress with new plugins
egserverConfig := `
name: egbuilder
cluster-name: egbuilder-test
cluster-role: primary
cluster:
listen-peer-urls:
- http://localhost:22380
listen-client-urls:
- http://localhost:22379
advertise-client-urls:
- http://localhost:22379
initial-advertise-peer-urls:
- http://localhost:22380
initial-cluster:
- egbuilder: http://localhost:22380
api-addr: 127.0.0.1:22381
`
apiURL := "http://127.0.0.1:22381"
err = os.WriteFile(filepath.Join(tempDir, "config.yaml"), []byte(egserverConfig), os.ModePerm)
assert.Nil(err)

runEgCmd := exec.Command(
filepath.Join(tempDir, "easegress-server"),
"--config-file",
"config.yaml",
)
runEgCmd.Dir = tempDir
var stdoutBuf, stderrBuf bytes.Buffer
runEgCmd.Stdout = &stdoutBuf
runEgCmd.Stderr = &stderrBuf
err = runEgCmd.Start()
assert.Nil(err)
defer func() {
err := runEgCmd.Process.Signal(os.Interrupt)
assert.Nil(err)
err = runEgCmd.Wait()
assert.Nil(err)
assert.NotContains(stderrBuf.String(), "panic")
assert.NotContains(stdoutBuf.String(), "panic")
}()

started := checkServerStart(func() *http.Request {
req, err := http.NewRequest(http.MethodGet, apiURL+"/apis/v2/healthz", nil)
assert.Nil(err)
return req
})
assert.True(started)

egctl := func(args ...string) *exec.Cmd {
return egctlWithServer(apiURL, args...)
}

// create, apply, delete new controllers
controllers := `
name: c1
kind: MyController1
---
name: c2
kind: MyController2
---
name: c3
kind: MyController3
`
controllerNames := []string{"c1", "c2", "c3"}
controllerKinds := []string{"MyController1", "MyController2", "MyController3"}

cmd := egctl("create", "-f", "-")
cmd.Stdin = strings.NewReader(controllers)
stdout, stderr, err = runCmd(cmd)
fmt.Printf("egctl create stdout:\n%s\n", stdout)
assert.Contains(stdout, "create MyController1 c1 successfully")
assert.Contains(stdout, "create MyController2 c2 successfully")
assert.Contains(stdout, "create MyController3 c3 successfully")
assert.Empty(stderr)
assert.NoError(err)

cmd = egctl("get", "all")
stdout, stderr, err = runCmd(cmd)
for i := range controllerNames {
assert.Contains(stdout, controllerNames[i])
assert.Contains(stdout, controllerKinds[i])
}
assert.Empty(stderr)
assert.NoError(err)

cmd = egctl("apply", "-f", "-")
cmd.Stdin = strings.NewReader(controllers)
stdout, stderr, err = runCmd(cmd)
fmt.Printf("egctl apply stdout:\n%s\n", stdout)
assert.Contains(stdout, "update MyController1 c1 successfully")
assert.Contains(stdout, "update MyController2 c2 successfully")
assert.Contains(stdout, "update MyController3 c3 successfully")
assert.Empty(stderr)
assert.NoError(err)

for i := range controllerNames {
cmd = egctl("delete", controllerKinds[i], controllerNames[i])
stdout, stderr, err = runCmd(cmd)
fmt.Printf("egctl delete stdout:\n%s\n", stdout)
assert.Contains(stdout, fmt.Sprintf("delete %s %s successfully", controllerKinds[i], controllerNames[i]))
assert.Empty(stderr)
assert.NoError(err)
}

cmd = egctl("get", "all")
stdout, stderr, err = runCmd(cmd)
for i := range controllerNames {
assert.NotContains(stdout, controllerNames[i])
assert.NotContains(stdout, controllerKinds[i])
}
assert.Empty(stderr)
assert.NoError(err)

// create, apply, delete new filters
filters := `
name: httpserver
kind: HTTPServer
port: 22399
rules:
- paths:
- backend: pipeline
---
name: pipeline
kind: Pipeline
flow:
- filter: filter1
- filter: filter2
- filter: mock
filters:
- name: filter1
kind: MyFilter1
- name: filter2
kind: MyFilter2
- name: mock
kind: ResponseBuilder
template: |
statusCode: 200
body: "body from response builder"
`

cmd = egctl("create", "-f", "-")
cmd.Stdin = strings.NewReader(filters)
stdout, stderr, err = runCmd(cmd)
fmt.Printf("egctl create stdout:\n%s\n", stdout)
assert.Empty(stderr)
assert.NoError(err)

cmd = egctl("apply", "-f", "-")
cmd.Stdin = strings.NewReader(filters)
stdout, stderr, err = runCmd(cmd)
fmt.Printf("egctl apply stdout:\n%s\n", stdout)
assert.Empty(stderr)
assert.NoError(err)

started = checkServerStart(func() *http.Request {
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:22399", nil)
assert.Nil(err)
return req
})
assert.True(started)

req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:22399", nil)
assert.Nil(err)
resp, err := http.DefaultClient.Do(req)
assert.Nil(err)
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
assert.Nil(err)
// get this body means our pipeline is working.
assert.Equal("body from response builder", string(data))
}
3 changes: 2 additions & 1 deletion build/test/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pushd $SCRIPTPATH"/../../example" > /dev/null
EXAMPLEDIR="$SCRIPTPATH"/../../example
PRIMARYDIR=$EXAMPLEDIR"/primary-single"
EGCTL=$PRIMARYDIR"/bin/egctl"
EGBUILDER=$PRIMARYDIR"/bin/egbuilder"

# target file related define.
server="primary-single/bin/easegress-server"
Expand Down Expand Up @@ -75,7 +76,7 @@ else
fi

# run go test
env EGCTL=$EGCTL go test -v $SCRIPTPATH
env EGCTL=$EGCTL EGBUILDER=$EGBUILDER go test -v $SCRIPTPATH

popd > /dev/null
exit 0
2 changes: 1 addition & 1 deletion cmd/builder/gen/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func defineFilterMethods(file *j.File, info *FilterInfo) {
nameFunc := receiver()
nameFunc.Name = "Name"
nameFunc.Returns = []j.Code{j.String()}
nameFunc.Block = []j.Code{j.Return(j.Lit(info.Name))}
nameFunc.Block = []j.Code{j.Return(j.Id(info.ReceiverName).Dot("spec").Dot("Name()"))}
file.Add(nameFunc.Def())

// define filter Kind method
Expand Down
2 changes: 1 addition & 1 deletion pkg/object/pipeline/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ func (p *Pipeline) reload(previousGeneration *Pipeline) {

// add the filter to pipeline, and if the pipeline does not define a
// flow, append it to the flow we just created.
p.filters[filter.Name()] = filter
p.filters[spec.Name()] = filter
if len(p.spec.Flow) == 0 {
flow = append(flow, FlowNode{FilterName: spec.Name()})
}
Expand Down

0 comments on commit 48e60b5

Please sign in to comment.