add e2e test & ci

This commit is contained in:
lyyyuna 2021-07-22 19:57:56 +08:00
parent 9aeb1da8f8
commit b839cb5659
15 changed files with 261 additions and 5 deletions

View File

@ -12,7 +12,7 @@ on:
- '**.png'
jobs:
job_1:
name: Build goc binary
name: e2e test
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
@ -27,6 +27,11 @@ jobs:
- name: Go build
run: |
go build .
go install .
- name: Use goc to build self
run: |
./goc build -o ./gocc .
./goc build -o ./gocc .
- name: run e2e test
run: |
go get github.com/onsi/ginkgo/ginkgo
make e2e

View File

@ -12,7 +12,7 @@ on:
- '**.png'
jobs:
job_1:
name: Build goc binary
name: e2e test
strategy:
matrix:
os: [windows-latest]
@ -27,6 +27,11 @@ jobs:
- name: Go build
run: |
go build .
go install .
- name: Use goc to build self
run: |
.\goc.exe build -o gocc .
.\goc.exe build -o gocc .
- name: run e2e test
run: |
go get github.com/onsi/ginkgo/ginkgo
ginkgo tests/e2e/...

1
.gitignore vendored
View File

@ -0,0 +1 @@
tests/e2e/tmp/*

View File

@ -15,7 +15,11 @@ fmt:
govet-check:
go vet ./...
e2e:
ginkgo tests/e2e/...
clean:
find ./ -type f -name 'coverage.txt' -delete
find ./ -type f -name 'goc' -delete
find ./ -type f -name 'gocc' -delete
find ./ -type f -name 'gocc' -delete
rm -rf ./tests/e2e/tmp

3
go.mod
View File

@ -10,6 +10,8 @@ require (
github.com/mattn/go-isatty v0.0.13 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
github.com/olekukonko/tablewriter v0.0.5
github.com/onsi/ginkgo v1.16.4
github.com/onsi/gomega v1.14.0
github.com/spf13/cobra v1.1.3
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.7.0
@ -19,6 +21,7 @@ require (
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 // indirect
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d
golang.org/x/tools v0.1.3
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
k8s.io/kubectl v0.21.2
k8s.io/test-infra v0.0.0-20210618100605-34aa2f2aa75b
)

6
go.sum
View File

@ -365,6 +365,7 @@ github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/frankban/quicktest v1.8.1/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsouza/fake-gcs-server v0.0.0-20180612165233-e85be23bdaa8/go.mod h1:1/HufuJ+eaDf4KTnYdS6HJMGvMRU8d4cYTuu/1QaBbI=
github.com/fsouza/fake-gcs-server v1.19.4/go.mod h1:I0/88nHCASqJJ5M7zVF0zKODkYTcuXFW5J5yajsNJnE=
@ -929,6 +930,7 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/octago/sflags v0.2.0/go.mod h1:G0bjdxh4qPRycF74a2B8pU36iTp9QHGx0w0dFZXPt80=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
@ -946,6 +948,7 @@ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@ -958,6 +961,8 @@ github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
github.com/onsi/gomega v1.14.0 h1:ep6kpPVwmr/nTbklSx2nrLNSIO62DoYAhnPNIMhK8gI=
github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@ -1826,6 +1831,7 @@ gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=

1
tests/README.md Normal file
View File

@ -0,0 +1 @@
# How to run e2e test

83
tests/e2e/cmd.go Normal file
View File

@ -0,0 +1,83 @@
package e2e
import (
"bytes"
"context"
"fmt"
"os/exec"
"time"
)
// LongRunCmd defines a cmd which run for a long time
type LongRunCmd struct {
cancel context.CancelFunc
cmd *exec.Cmd
stderrBuf bytes.Buffer
stdoutBuf bytes.Buffer
err error
done bool
}
func NewLongRunCmd(dir string, args []string) *LongRunCmd {
ctx, cancel := context.WithCancel(context.Background())
cmd := exec.CommandContext(ctx, args[0], args[1:]...)
cmd.Dir = dir
var stderrBuf bytes.Buffer
var stdoutBuf bytes.Buffer
cmd.Stdout = &stdoutBuf
cmd.Stderr = &stderrBuf
return &LongRunCmd{
cmd: cmd,
cancel: cancel,
stderrBuf: stderrBuf,
stdoutBuf: stdoutBuf,
}
}
// Run in backend
func (l *LongRunCmd) Run() {
go func() {
err := l.cmd.Start()
if err != nil {
l.err = err
}
err = l.cmd.Wait()
if err != nil {
l.err = err
}
l.err = nil
l.done = true
}()
time.Sleep(time.Millisecond * 100)
}
func (l *LongRunCmd) Stop() {
l.cancel()
}
func (l *LongRunCmd) CheckExitStatus() error {
if l.done == true {
return l.err
} else {
return fmt.Errorf("running")
}
}
func (l *LongRunCmd) GetStdoutStdErr() (string, string) {
return l.stdoutBuf.String(), l.stderrBuf.String()
}
// RunShortRunCmd defines a cmd which run and exits immediately
func RunShortRunCmd(dir string, args []string) (string, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
cmd := exec.CommandContext(ctx, args[0], args[1:]...)
cmd.Dir = dir
output, err := cmd.CombinedOutput()
return string(output), err
}

View File

@ -0,0 +1,13 @@
package e2e
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
func TestGoc(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Goc e2e Test Suite")
}

44
tests/e2e/e2e_test.go Normal file
View File

@ -0,0 +1,44 @@
package e2e
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("1 [基础测试]", func() {
var (
mgr *SamplesMgr
)
BeforeEach(func() {
mgr = NewSamplesMgr()
})
Describe("1 测试 build 命令", func() {
It("1.1.1 简单工程", func() {
dir, err := mgr.GetSampleByKey("basic")
Expect(err).To(BeNil(), "找不到 sample")
By("使用 goc build 命令编译")
_, err = RunShortRunCmd(dir, []string{"goc", "build", "."})
Expect(err).To(BeNil(), "goc build 运行错误")
})
})
Describe("2 测试 server 命令", func() {
It("1.2.1 测试 API 接口", func() {
dir, err := mgr.GetSampleByKey("basic")
Expect(err).To(BeNil(), "找不到 sample")
By("启动 goc server")
lc := NewLongRunCmd(dir, []string{"goc", "server", "."})
lc.Run()
defer lc.Stop()
By("使用 goc list 获取服务列表")
output, err := RunShortRunCmd(dir, []string{"goc", "list"})
Expect(err).To(BeNil(), "goc list 运行错误")
Expect(output).To(ContainSubstring("REMOTEIP"), "goc list 输出应该包含 REMOTEIP")
})
})
})

View File

@ -0,0 +1 @@
module basic

View File

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("hello, world")
}

1
tests/e2e/samples/go.mod Normal file
View File

@ -0,0 +1 @@
module fake

View File

@ -0,0 +1,4 @@
samples:
basic:
dir: basic-project
description: a basic project only print hello world

78
tests/e2e/samples_mgr.go Normal file
View File

@ -0,0 +1,78 @@
package e2e
import (
"fmt"
"log"
"os"
"path/filepath"
"regexp"
. "github.com/onsi/ginkgo"
"github.com/tongjingran/copy"
"gopkg.in/yaml.v3"
)
type Sample struct {
Dir string `yaml:"dir"`
Description string `yaml:"description"`
}
// SamplesMgr create and return sample for test case
//
// ginkgo 的运行模型是多进程模型,每一个 test case 是一个独立的进程
// Ginkgo has support for running specs in parallel. It does this by spawning separate go test processes and serving specs to each process off of a shared queue.
// 所以这里会单独在一个临时目录中生成 sample以便将来测试用例可以并发执行
type SamplesMgr struct {
Samples map[string]Sample `yaml:"samples"`
path string `yaml:"-"`
}
func NewSamplesMgr() *SamplesMgr {
path, _ := os.Getwd()
metaData, err := os.ReadFile(filepath.Join(path, "samples", "meta.yaml"))
if err != nil {
log.Fatalf("fail to read sample meta")
}
mgr := SamplesMgr{}
err = yaml.Unmarshal(metaData, &mgr)
if err != nil {
log.Fatalf("fail to parse the meta yaml")
}
mgr.path = path
return &mgr
}
// GetSampleByKey return the sample folder location for test use
func (m *SamplesMgr) GetSampleByKey(key string) (string, error) {
sample, ok := m.Samples[key]
if !ok {
return "", fmt.Errorf("no sample found")
}
desc := CurrentGinkgoTestDescription()
caseTitle := desc.FullTestText + " " + key
m1 := regexp.MustCompile(`[/\\?%*:|"<>]`)
caseTitle = m1.ReplaceAllString(caseTitle, "-")
dst := filepath.Join(m.path, "tmp", caseTitle)
err := os.RemoveAll(dst)
if err != nil {
log.Fatalf("fail to clean the temp sample: %v", err)
}
err = os.MkdirAll(dst, os.ModePerm)
if err != nil {
log.Fatalf("fail to create sample dir: %v", err)
}
src := filepath.Join(m.path, "samples", sample.Dir)
err = copy.Copy(src, dst)
if err != nil {
log.Fatalf("fail to copy the sample project: %v", err)
}
return dst, nil
}