Merge pull request #210 from lyyyuna/v2

get next abailable port for e2e test
This commit is contained in:
Li Yiyang 2021-07-23 15:32:41 +08:00 committed by GitHub
commit 4af7734b8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 5 deletions

3
go.mod
View File

@ -4,6 +4,7 @@ go 1.16
require (
github.com/gin-gonic/gin v1.7.2
github.com/gofrs/flock v0.8.1
github.com/gorilla/websocket v1.4.2
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213
github.com/mattn/go-colorable v0.1.8 // indirect
@ -18,7 +19,7 @@ require (
github.com/tongjingran/copy v1.4.2
go.uber.org/zap v1.17.0
golang.org/x/mod v0.4.2
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 // indirect
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // 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

6
go.sum
View File

@ -503,6 +503,8 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@ -1524,8 +1526,8 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 h1:C+AwYEtBp/VQwoLntUmQ/yx3MS9vmZaKNdw5eOpoQe8=
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=

View File

@ -3,12 +3,15 @@ package e2e
import (
"fmt"
"log"
"net"
"os"
"path/filepath"
"regexp"
"strconv"
. "github.com/onsi/ginkgo"
"github.com/gofrs/flock"
"github.com/tongjingran/copy"
"gopkg.in/yaml.v3"
)
@ -20,9 +23,10 @@ type Sample struct {
// SamplesMgr create and return sample for test case
//
// ginkgo 的运行模型是多进程模型,每一个 test case 是一个独立的进程
// ginkgo 的并发执行时的运行模型是多进程模型,会有多个独立的 go test 进程。
// 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以便将来测试用例可以并发执行
//
// 所以这里设计成每个 test case 在各自的临时目录中生成 sample以便将来测试用例可以并发执行。
type SamplesMgr struct {
Samples map[string]Sample `yaml:"samples"`
path string `yaml:"-"`
@ -76,3 +80,46 @@ func (m *SamplesMgr) GetSampleByKey(key string) (string, error) {
return dst, nil
}
// GetAvailablePort get next available host port among multiprocess ginkgo test cases
//
// 利用文件锁和端口探活,获取下一个可用的 port
func (m *SamplesMgr) GetAvailablePort() (string, error) {
fileLockPath := filepath.Join(m.path, "tmp", "port.lock")
// 文件锁ginkgo parallel 模式是多进程,必须用跨平台跨进程的同步方式
lock := flock.New(fileLockPath)
lock.Lock()
defer lock.Unlock()
// 该文件记录 counter代表下一个可用的 port
portFilePath := filepath.Join(m.path, "tmp", "port.record")
data, err := os.ReadFile(portFilePath)
if err != nil {
os.Create(portFilePath)
}
port, err := strconv.Atoi(string(data))
if err != nil {
port = 7777
} else {
port += 1
}
// 循环检测直到找到可用 port
for {
if port == 65534 {
port = 7777
}
conn, err := net.Dial("tcp", ":"+strconv.Itoa(port))
if err == nil {
port += 1
conn.Close()
} else {
break
}
}
err = os.WriteFile(portFilePath, []byte(strconv.Itoa(port)), os.ModePerm)
return "127.0.0.1:" + strconv.Itoa(port), err
}