commit
54f629a7b7
9
.github/workflows/e2e-linux.yml
vendored
9
.github/workflows/e2e-linux.yml
vendored
@ -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
|
9
.github/workflows/e2e-wins.yml
vendored
9
.github/workflows/e2e-wins.yml
vendored
@ -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
1
.gitignore
vendored
@ -0,0 +1 @@
|
||||
tests/e2e/tmp/*
|
6
Makefile
6
Makefile
@ -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
3
go.mod
@ -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
6
go.sum
@ -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=
|
||||
|
@ -43,11 +43,11 @@ func (b *Build) readProjectMetaInfo() {
|
||||
}
|
||||
|
||||
// get tmp folder name
|
||||
config.GocConfig.TmpModProjectDir = filepath.Join(os.TempDir(), tmpFolderName(config.GocConfig.CurModProjectDir))
|
||||
config.GocConfig.TmpModProjectDir = filepath.Join(os.TempDir(), TmpFolderName(config.GocConfig.CurModProjectDir))
|
||||
// get working dir in the corresponding tmp dir
|
||||
config.GocConfig.TmpWd = filepath.Join(config.GocConfig.TmpModProjectDir, config.GocConfig.CurWd[len(config.GocConfig.CurModProjectDir):])
|
||||
// get GlobalCoverVarImportPath
|
||||
config.GocConfig.GlobalCoverVarImportPath = path.Join(config.GocConfig.ImportPath, tmpFolderName(config.GocConfig.CurModProjectDir))
|
||||
config.GocConfig.GlobalCoverVarImportPath = path.Join(config.GocConfig.ImportPath, TmpFolderName(config.GocConfig.CurModProjectDir))
|
||||
log.Donef("project meta information parsed")
|
||||
}
|
||||
|
||||
|
@ -43,8 +43,8 @@ func (b *Build) copyProjectToTmp() {
|
||||
log.StopWait()
|
||||
}
|
||||
|
||||
// tmpFolderName generates a directory name according to the path
|
||||
func tmpFolderName(path string) string {
|
||||
// TmpFolderName generates a directory name according to the path
|
||||
func TmpFolderName(path string) string {
|
||||
sum := sha256.Sum256([]byte(path))
|
||||
h := fmt.Sprintf("%x", sum[:6])
|
||||
|
||||
|
1
tests/README.md
Normal file
1
tests/README.md
Normal file
@ -0,0 +1 @@
|
||||
# How to run e2e test
|
83
tests/e2e/cmd.go
Normal file
83
tests/e2e/cmd.go
Normal 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
|
||||
}
|
13
tests/e2e/e2e_suite_test.go
Normal file
13
tests/e2e/e2e_suite_test.go
Normal 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
44
tests/e2e/e2e_test.go
Normal 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")
|
||||
})
|
||||
})
|
||||
})
|
1
tests/e2e/samples/basic-project/go.mod
Normal file
1
tests/e2e/samples/basic-project/go.mod
Normal file
@ -0,0 +1 @@
|
||||
module basic
|
7
tests/e2e/samples/basic-project/main.go
Normal file
7
tests/e2e/samples/basic-project/main.go
Normal file
@ -0,0 +1,7 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println("hello, world")
|
||||
}
|
1
tests/e2e/samples/go.mod
Normal file
1
tests/e2e/samples/go.mod
Normal file
@ -0,0 +1 @@
|
||||
module fake
|
4
tests/e2e/samples/meta.yaml
Normal file
4
tests/e2e/samples/meta.yaml
Normal 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
78
tests/e2e/samples_mgr.go
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user