🧪 test: 增加集测用例
This commit is contained in:
parent
c7c76efb37
commit
fae8077705
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
tests/e2e/tmp/*
|
tests/e2e/tmp/*
|
||||||
.goc.kvstore
|
.goc.kvstore
|
||||||
|
coverage.txt
|
@ -83,6 +83,7 @@ func init() {
|
|||||||
if isOffline(tmp) {
|
if isOffline(tmp) {
|
||||||
log.Printf("[goc][Error] needs re-register")
|
log.Printf("[goc][Error] needs re-register")
|
||||||
register(host)
|
register(host)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[goc][Error] rpc fail to dial to goc server: %v", err)
|
log.Printf("[goc][Error] rpc fail to dial to goc server: %v", err)
|
||||||
|
@ -15,7 +15,9 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -26,33 +28,6 @@ import (
|
|||||||
"k8s.io/test-infra/gopherage/pkg/cov"
|
"k8s.io/test-infra/gopherage/pkg/cov"
|
||||||
)
|
)
|
||||||
|
|
||||||
func idMaps(idQuery string) func(key string) bool {
|
|
||||||
idMap := make(map[string]bool)
|
|
||||||
if strings.Contains(idQuery, ",") == false {
|
|
||||||
} else {
|
|
||||||
ids := strings.Split(idQuery, ",")
|
|
||||||
for _, id := range ids {
|
|
||||||
idMap[id] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inIdMaps := func(key string) bool {
|
|
||||||
// if no id in query, then all id agent will be return
|
|
||||||
if len(idMap) == 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// other
|
|
||||||
_, ok := idMap[key]
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return inIdMaps
|
|
||||||
}
|
|
||||||
|
|
||||||
// listAgents return all service informations
|
// listAgents return all service informations
|
||||||
func (gs *gocServer) listAgents(c *gin.Context) {
|
func (gs *gocServer) listAgents(c *gin.Context) {
|
||||||
idQuery := c.Query("id")
|
idQuery := c.Query("id")
|
||||||
@ -79,22 +54,65 @@ func (gs *gocServer) listAgents(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gs *gocServer) removeAgents(c *gin.Context) {
|
||||||
|
idQuery := c.Query("id")
|
||||||
|
ifInIdMap := idMaps(idQuery)
|
||||||
|
|
||||||
|
gs.agents.Range(func(key, value interface{}) bool {
|
||||||
|
|
||||||
|
// check if id is in the query ids
|
||||||
|
if !ifInIdMap(key.(string)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
agent, ok := value.(*gocCoveredAgent)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
agent.closeConnection()
|
||||||
|
gs.agents.Delete(key)
|
||||||
|
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
gs.removeAllAgentsFromStore()
|
||||||
|
}
|
||||||
|
|
||||||
// getProfiles get and merge all agents' informations
|
// getProfiles get and merge all agents' informations
|
||||||
//
|
//
|
||||||
// it is synchronous
|
// it is synchronous
|
||||||
func (gs *gocServer) getProfiles(c *gin.Context) {
|
func (gs *gocServer) getProfiles(c *gin.Context) {
|
||||||
|
idQuery := c.Query("id")
|
||||||
|
ifInIdMap := idMaps(idQuery)
|
||||||
|
|
||||||
|
pattern := c.Query("pattern")
|
||||||
|
extra := c.Query("extra")
|
||||||
|
isExtra := filterExtra(extra)
|
||||||
|
|
||||||
var mu sync.Mutex
|
var mu sync.Mutex
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
mergedProfiles := make([][]*cover.Profile, 0)
|
mergedProfiles := make([][]*cover.Profile, 0)
|
||||||
|
|
||||||
gs.agents.Range(func(key, value interface{}) bool {
|
gs.agents.Range(func(key, value interface{}) bool {
|
||||||
|
// check if id is in the query ids
|
||||||
|
if !ifInIdMap(key.(string)) {
|
||||||
|
// not in
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
agent, ok := value.(*gocCoveredAgent)
|
agent, ok := value.(*gocCoveredAgent)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if extra matches
|
||||||
|
if !isExtra(agent.Extra) {
|
||||||
|
// not match
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
// 并发 rpc,且每个 rpc 设超时时间 10 second
|
// 并发 rpc,且每个 rpc 设超时时间 10 second
|
||||||
go func() {
|
go func() {
|
||||||
@ -140,9 +158,17 @@ func (gs *gocServer) getProfiles(c *gin.Context) {
|
|||||||
agent.closeRpcConnOnce()
|
agent.closeRpcConnOnce()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if pattern matches
|
||||||
|
newProfile, err := filterProfileByPattern(pattern, profile)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
mergedProfiles = append(mergedProfiles, profile)
|
mergedProfiles = append(mergedProfiles, newProfile)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -177,14 +203,31 @@ func (gs *gocServer) getProfiles(c *gin.Context) {
|
|||||||
//
|
//
|
||||||
// it is async, the function will return immediately
|
// it is async, the function will return immediately
|
||||||
func (gs *gocServer) resetProfiles(c *gin.Context) {
|
func (gs *gocServer) resetProfiles(c *gin.Context) {
|
||||||
|
idQuery := c.Query("id")
|
||||||
|
ifInIdMap := idMaps(idQuery)
|
||||||
|
|
||||||
|
extra := c.Query("extra")
|
||||||
|
isExtra := filterExtra(extra)
|
||||||
|
|
||||||
gs.agents.Range(func(key, value interface{}) bool {
|
gs.agents.Range(func(key, value interface{}) bool {
|
||||||
|
|
||||||
|
// check if id is in the query ids
|
||||||
|
if !ifInIdMap(key.(string)) {
|
||||||
|
// not in
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
agent, ok := value.(*gocCoveredAgent)
|
agent, ok := value.(*gocCoveredAgent)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if extra matches
|
||||||
|
if !isExtra(agent.Extra) {
|
||||||
|
// not match
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
var req ProfileReq = "resetprofile"
|
var req ProfileReq = "resetprofile"
|
||||||
var res ProfileRes
|
var res ProfileRes
|
||||||
go func() {
|
go func() {
|
||||||
@ -256,54 +299,60 @@ func (gs *gocServer) watchProfileUpdate(c *gin.Context) {
|
|||||||
<-gwc.exitCh
|
<-gwc.exitCh
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gs *gocServer) removeAgentById(c *gin.Context) {
|
func filterProfileByPattern(pattern string, profiles []*cover.Profile) ([]*cover.Profile, error) {
|
||||||
id := c.Query("id")
|
|
||||||
|
|
||||||
rawagent, ok := gs.agents.Load(id)
|
if strings.TrimSpace(pattern) == "" {
|
||||||
if !ok {
|
return profiles, nil
|
||||||
c.JSON(http.StatusNotFound, gin.H{
|
|
||||||
"msg": "agent not found",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
agent, ok := rawagent.(*gocCoveredAgent)
|
var out = make([]*cover.Profile, 0)
|
||||||
if !ok {
|
for _, profile := range profiles {
|
||||||
c.JSON(http.StatusNotFound, gin.H{
|
matched, err := regexp.MatchString(pattern, profile.FileName)
|
||||||
"msg": "agent not found",
|
if err != nil {
|
||||||
})
|
return nil, fmt.Errorf("filterProfile failed with pattern %s for profile %s, err: %v", pattern, profile.FileName, err)
|
||||||
return
|
}
|
||||||
|
if matched {
|
||||||
|
out = append(out, profile)
|
||||||
|
break // no need to check again for the file
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭相应连接
|
|
||||||
agent.closeConnection()
|
|
||||||
// 从维护 agent 池里删除
|
|
||||||
gs.agents.Delete(id)
|
|
||||||
// 从持久化中删除
|
|
||||||
gs.removeAgentFromStore(id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gs *gocServer) removeAgents(c *gin.Context) {
|
return out, nil
|
||||||
idQuery := c.Query("id")
|
}
|
||||||
ifInIdMap := idMaps(idQuery)
|
|
||||||
|
|
||||||
gs.agents.Range(func(key, value interface{}) bool {
|
func idMaps(idQuery string) func(key string) bool {
|
||||||
|
idMap := make(map[string]bool)
|
||||||
|
if len(strings.TrimSpace(idQuery)) == 0 {
|
||||||
|
} else {
|
||||||
|
ids := strings.Split(idQuery, ",")
|
||||||
|
for _, id := range ids {
|
||||||
|
idMap[id] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check if id is in the query ids
|
inIdMaps := func(key string) bool {
|
||||||
if !ifInIdMap(key.(string)) {
|
// if no id in query, then all id agent will be return
|
||||||
|
if len(idMap) == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
// other
|
||||||
agent, ok := value.(*gocCoveredAgent)
|
_, ok := idMap[key]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
} else {
|
||||||
|
|
||||||
agent.closeConnection()
|
|
||||||
gs.agents.Delete(key)
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
})
|
}
|
||||||
|
}
|
||||||
gs.removeAllAgentsFromStore()
|
|
||||||
|
return inIdMaps
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterExtra(extraPattern string) func(string) bool {
|
||||||
|
|
||||||
|
re := regexp.MustCompile(extraPattern)
|
||||||
|
|
||||||
|
return func(extra string) bool {
|
||||||
|
return re.Match([]byte(extra))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PongWait = 10 * time.Second
|
PongWait = 5 * time.Second
|
||||||
PingWait = 5 * time.Second
|
PingWait = 2 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProfileReq string
|
type ProfileReq string
|
||||||
|
@ -232,7 +232,7 @@ func (gs *gocServer) restoreAgents() {
|
|||||||
|
|
||||||
id, err := strconv.Atoi(agent.Id)
|
id, err := strconv.Atoi(agent.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("fail to transfer id to number: %v", err)
|
log.Fatalf("fail to transform id to number: %v", err)
|
||||||
}
|
}
|
||||||
if maxId < id {
|
if maxId < id {
|
||||||
maxId = id
|
maxId = id
|
||||||
|
@ -48,6 +48,10 @@ func (s *FileStore) Get(key string) (string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if scanner.Err() != nil {
|
||||||
|
return "", scanner.Err()
|
||||||
|
}
|
||||||
|
|
||||||
return "", fmt.Errorf("no key found")
|
return "", fmt.Errorf("no key found")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +59,7 @@ func (s *FileStore) Set(key string, value string) error {
|
|||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
f, err := os.OpenFile(s.storePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, os.ModePerm)
|
f, err := os.OpenFile(s.storePath, os.O_RDWR, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -64,6 +68,7 @@ func (s *FileStore) Set(key string, value string) error {
|
|||||||
var outputLines string
|
var outputLines string
|
||||||
scanner := bufio.NewScanner(f)
|
scanner := bufio.NewScanner(f)
|
||||||
isFound := false
|
isFound := false
|
||||||
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
items := strings.SplitN(line, " ", 2)
|
items := strings.SplitN(line, " ", 2)
|
||||||
@ -78,6 +83,10 @@ func (s *FileStore) Set(key string, value string) error {
|
|||||||
outputLines += line + "\n"
|
outputLines += line + "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if scanner.Err() != nil {
|
||||||
|
return scanner.Err()
|
||||||
|
}
|
||||||
|
|
||||||
if !isFound {
|
if !isFound {
|
||||||
outputLines += key + " " + value + "\n"
|
outputLines += key + " " + value + "\n"
|
||||||
}
|
}
|
||||||
@ -88,6 +97,7 @@ func (s *FileStore) Set(key string, value string) error {
|
|||||||
|
|
||||||
f.Seek(0, os.SEEK_SET)
|
f.Seek(0, os.SEEK_SET)
|
||||||
f.WriteString(outputLines)
|
f.WriteString(outputLines)
|
||||||
|
f.Sync()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -96,7 +106,7 @@ func (s *FileStore) Remove(key string) error {
|
|||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
f, err := os.OpenFile(s.storePath, os.O_CREATE|os.O_WRONLY, os.ModePerm)
|
f, err := os.OpenFile(s.storePath, os.O_RDWR, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -117,12 +127,17 @@ func (s *FileStore) Remove(key string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if scanner.Err() != nil {
|
||||||
|
return scanner.Err()
|
||||||
|
}
|
||||||
|
|
||||||
if err := os.Truncate(s.storePath, 0); err != nil {
|
if err := os.Truncate(s.storePath, 0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
f.Seek(0, os.SEEK_SET)
|
f.Seek(0, os.SEEK_SET)
|
||||||
f.WriteString(outputLines)
|
f.WriteString(outputLines)
|
||||||
|
f.Sync()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -151,6 +166,10 @@ func (s *FileStore) Range(pattern string) ([]string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if scanner.Err() != nil {
|
||||||
|
return nil, scanner.Err()
|
||||||
|
}
|
||||||
|
|
||||||
if len(output) == 0 {
|
if len(output) == 0 {
|
||||||
return nil, fmt.Errorf("no key found")
|
return nil, fmt.Errorf("no key found")
|
||||||
} else {
|
} else {
|
||||||
@ -162,7 +181,7 @@ func (s *FileStore) RangeRemove(pattern string) error {
|
|||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
f, err := os.OpenFile(s.storePath, os.O_CREATE|os.O_WRONLY, os.ModePerm)
|
f, err := os.OpenFile(s.storePath, os.O_RDWR, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -183,12 +202,17 @@ func (s *FileStore) RangeRemove(pattern string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if scanner.Err() != nil {
|
||||||
|
return scanner.Err()
|
||||||
|
}
|
||||||
|
|
||||||
if err := os.Truncate(s.storePath, 0); err != nil {
|
if err := os.Truncate(s.storePath, 0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
f.Seek(0, os.SEEK_SET)
|
f.Seek(0, os.SEEK_SET)
|
||||||
f.WriteString(outputLines)
|
f.WriteString(outputLines)
|
||||||
|
f.Sync()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -32,6 +33,8 @@ type LongRunCmd struct {
|
|||||||
stdoutBuf bytes.Buffer
|
stdoutBuf bytes.Buffer
|
||||||
err error
|
err error
|
||||||
done bool
|
done bool
|
||||||
|
|
||||||
|
once sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLongRunCmd defines a command which will be run forever
|
// NewLongRunCmd defines a command which will be run forever
|
||||||
@ -85,7 +88,9 @@ func (l *LongRunCmd) Run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *LongRunCmd) Stop() {
|
func (l *LongRunCmd) Stop() {
|
||||||
|
l.once.Do(func() {
|
||||||
l.cancel()
|
l.cancel()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LongRunCmd) CheckExitStatus() error {
|
func (l *LongRunCmd) CheckExitStatus() error {
|
||||||
|
@ -46,20 +46,20 @@ var _ = Describe("1 [基础测试]", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Describe("2 测试 server 命令", func() {
|
Describe("2 测试 server 命令", func() {
|
||||||
It("1.2.1 测试编译/list/profile基础场景", func() {
|
It("1.2.1 测试编译/service/profile基础场景", func() {
|
||||||
dir, err := mgr.GetSampleByKey("basic2")
|
dir, err := mgr.GetSampleByKey("basic2")
|
||||||
Expect(err).To(BeNil(), "找不到 sample")
|
Expect(err).To(BeNil(), "找不到 sample")
|
||||||
|
|
||||||
By("启动 goc server")
|
By("启动 goc server")
|
||||||
lc := NewLongRunCmd([]string{"goc", "server", "."}, dir, nil)
|
lc := NewLongRunCmd([]string{"goc", "server"}, dir, nil)
|
||||||
lc.Run()
|
lc.Run()
|
||||||
defer lc.Stop()
|
defer lc.Stop()
|
||||||
|
|
||||||
By("编译一个长时间运行的程序")
|
By("编译 basic2")
|
||||||
output, err := RunShortRunCmd([]string{"goc", "build", "."}, dir, nil)
|
output, err := RunShortRunCmd([]string{"goc", "build", "."}, dir, nil)
|
||||||
Expect(err).To(BeNil(), "编译失败:"+output)
|
Expect(err).To(BeNil(), "编译失败:"+output)
|
||||||
|
|
||||||
By("长时间运行 basic2")
|
By("运行 basic2")
|
||||||
basicC := NewLongRunCmd([]string{"./basic2"}, dir, nil)
|
basicC := NewLongRunCmd([]string{"./basic2"}, dir, nil)
|
||||||
basicC.Run()
|
basicC.Run()
|
||||||
defer basicC.Stop()
|
defer basicC.Stop()
|
||||||
@ -80,5 +80,234 @@ basic2/main.go:9.6,12.3 2 2`
|
|||||||
Expect(err).To(BeNil(), "goc profile get运行错误")
|
Expect(err).To(BeNil(), "goc profile get运行错误")
|
||||||
Expect(output).To(ContainSubstring(profileStr), "goc profile get 获取的覆盖率有误")
|
Expect(output).To(ContainSubstring(profileStr), "goc profile get 获取的覆盖率有误")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("1.2.2 测试 server 重启", func() {
|
||||||
|
dir, err := mgr.GetSampleByKey("basic2")
|
||||||
|
Expect(err).To(BeNil(), "找不到 sample")
|
||||||
|
|
||||||
|
By("启动 goc server")
|
||||||
|
lc := NewLongRunCmd([]string{"goc", "server"}, dir, nil)
|
||||||
|
lc.Run()
|
||||||
|
defer lc.Stop()
|
||||||
|
|
||||||
|
By("编译 basic2")
|
||||||
|
output, err := RunShortRunCmd([]string{"goc", "build", "."}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "编译失败:"+output)
|
||||||
|
|
||||||
|
By("运行 basic2")
|
||||||
|
basicC := NewLongRunCmd([]string{"./basic2"}, dir, nil)
|
||||||
|
basicC.Run()
|
||||||
|
defer basicC.Stop()
|
||||||
|
|
||||||
|
By("获取 service 列表")
|
||||||
|
Eventually(func() {
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "service", "get"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "goc servive get 运行错误")
|
||||||
|
Expect(output).To(ContainSubstring("1 CONNECT 127.0.0.1 ./basic2"), "goc service get 输出应该包含 basic 服务")
|
||||||
|
}, 3*time.Second, 1*time.Second).Should(Succeed())
|
||||||
|
|
||||||
|
By("重启 goc server")
|
||||||
|
lc.Stop()
|
||||||
|
lc2 := NewLongRunCmd([]string{"goc", "server"}, dir, nil)
|
||||||
|
lc2.Run()
|
||||||
|
defer lc2.Stop()
|
||||||
|
|
||||||
|
By("再次获取 service 列表")
|
||||||
|
Eventually(func() {
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "service", "get"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "goc servive get 运行错误")
|
||||||
|
Expect(output).To(ContainSubstring("1 CONNECT 127.0.0.1 ./basic2"), "goc service get 输出应该包含 basic 服务")
|
||||||
|
}, 15*time.Second, 1*time.Second).Should(Succeed(), "10s 内 basic2 服务重新注册成功,且 id 不变")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("3 测试 goc service 相关命令", func() {
|
||||||
|
It("1.3.1 get/delete 组合", func() {
|
||||||
|
dir, err := mgr.GetSampleByKey("basic2")
|
||||||
|
Expect(err).To(BeNil(), "找不到 sample")
|
||||||
|
|
||||||
|
By("启动 goc server")
|
||||||
|
lc := NewLongRunCmd([]string{"goc", "server"}, dir, nil)
|
||||||
|
lc.Run()
|
||||||
|
defer lc.Stop()
|
||||||
|
|
||||||
|
By("编译 basic2")
|
||||||
|
output, err := RunShortRunCmd([]string{"goc", "build", "."}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "编译失败:"+output)
|
||||||
|
|
||||||
|
By("长时间运行 basic2")
|
||||||
|
basicC := NewLongRunCmd([]string{"./basic2"}, dir, nil)
|
||||||
|
basicC.Run()
|
||||||
|
defer basicC.Stop()
|
||||||
|
|
||||||
|
By("再长时间运行 basic2 -f hello")
|
||||||
|
time.Sleep(time.Microsecond * 100)
|
||||||
|
basicC2 := NewLongRunCmd([]string{"./basic2", "-f", "hello"}, dir,
|
||||||
|
[]string{
|
||||||
|
"GOC_REGISTER_EXTRA=fantastic", // 额外的注册信息
|
||||||
|
})
|
||||||
|
basicC2.Run()
|
||||||
|
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
|
By("测试获取 service 信息")
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "service", "get"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "goc servive get 运行错误")
|
||||||
|
Expect(output).To(ContainSubstring("2 CONNECT 127.0.0.1 ./basic2 -f"), "goc service get 应该显示第二个服务")
|
||||||
|
|
||||||
|
By("测试获取指定 id 的 service 信息")
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "service", "get", "--id", "1"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "goc servive get 运行错误")
|
||||||
|
Expect(output).To(ContainSubstring("1 CONNECT 127.0.0.1 ./basic2"), "id=1 的服务能返回")
|
||||||
|
Expect(output).NotTo(ContainSubstring("2 CONNECT 127.0.0.1 ./basic2 -f"), "id=2 的服务没有返回")
|
||||||
|
|
||||||
|
By("测试能否获取 extra")
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "service", "get", "--wide"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "goc servive get --wide 运行错误")
|
||||||
|
Expect(output).To(ContainSubstring("fantastic"), "注入的 extra 信息没有获取到")
|
||||||
|
|
||||||
|
By("basic2 -f hello 退出")
|
||||||
|
basicC2.Stop()
|
||||||
|
|
||||||
|
By("测试 get 能否获取 DISCONNECT 状态")
|
||||||
|
Eventually(func() {
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "service", "get"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "goc servive get 运行错误")
|
||||||
|
Expect(output).To(ContainSubstring("2 DISCONNECT 127.0.0.1 ./basic2 -f"), "应该在 10s 内感知到 agent 断连")
|
||||||
|
}, 10*time.Second, 1*time.Second).Should(Succeed())
|
||||||
|
|
||||||
|
By("测试删除 id=2(已经退出) 的服务列表")
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "service", "delete", "--id", "2"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "删除服务列表失败")
|
||||||
|
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "service", "get"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "goc servive get 运行错误")
|
||||||
|
Expect(output).NotTo(ContainSubstring("./basic2 -f"), "DISCONNECT 的服务未被删除")
|
||||||
|
|
||||||
|
By("测试删除 id=1(还在运行) 的服务列表")
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "service", "delete", "--id", "1"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "删除服务列表失败")
|
||||||
|
|
||||||
|
Eventually(func() {
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "service", "get"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "goc servive get 运行错误")
|
||||||
|
Expect(output).To(ContainSubstring("3 CONNECT"), "20s 内 basic2 重新注册成功")
|
||||||
|
Expect(output).NotTo(ContainSubstring("1 "), "id=1 的服务不在")
|
||||||
|
|
||||||
|
}, 20*time.Second, 1*time.Second).Should(Succeed())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("4 测试 goc profile 相关命令", func() {
|
||||||
|
It("1.4.1 测试 get/clear", func() {
|
||||||
|
dir, err := mgr.GetSampleByKey("basic3")
|
||||||
|
Expect(err).To(BeNil(), "找不到 sample")
|
||||||
|
|
||||||
|
By("启动 goc server")
|
||||||
|
lc := NewLongRunCmd([]string{"goc", "server"}, dir, nil)
|
||||||
|
lc.Run()
|
||||||
|
defer lc.Stop()
|
||||||
|
|
||||||
|
By("编译 basic3")
|
||||||
|
output, err := RunShortRunCmd([]string{"goc", "build", "."}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "编译失败:"+output)
|
||||||
|
|
||||||
|
By("运行 basic3")
|
||||||
|
basicC := NewLongRunCmd([]string{"./basic3"}, dir, nil)
|
||||||
|
basicC.Run()
|
||||||
|
defer basicC.Stop()
|
||||||
|
|
||||||
|
By("运行 basic3 -f")
|
||||||
|
basicC2 := NewLongRunCmd([]string{"./basic3", "-f"}, dir, nil)
|
||||||
|
basicC2.Run()
|
||||||
|
defer basicC2.Stop()
|
||||||
|
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
|
By("获取覆盖率")
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "profile", "get"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "获取覆盖率失败")
|
||||||
|
Expect(output).To(ContainSubstring("basic3/main.go:8.13,11.2 2 2"))
|
||||||
|
|
||||||
|
By("只获取 id=1 的覆盖率")
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "profile", "get", "--id", "1"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "获取覆盖率失败")
|
||||||
|
Expect(output).To(ContainSubstring("basic3/main.go:8.13,11.2 2 1"), "id=1 只有 1 个覆盖率")
|
||||||
|
|
||||||
|
By("运行 basic3 -g")
|
||||||
|
basicC3 := NewLongRunCmd([]string{"./basic3", "-g"}, dir, []string{
|
||||||
|
"GOC_REGISTER_EXTRA=fantastic", // 额外的注册信息
|
||||||
|
})
|
||||||
|
basicC3.Run()
|
||||||
|
defer basicC3.Stop()
|
||||||
|
|
||||||
|
By("只获取 extra=fantastic 的覆盖率")
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "profile", "get", "--extra", "fantastic"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "获取覆盖率失败")
|
||||||
|
Expect(output).To(ContainSubstring("basic3/main.go:8.13,11.2 2 1"), "extra=fantastic 的覆盖率只有 1")
|
||||||
|
|
||||||
|
By("获取 id=10 的覆盖率")
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "profile", "get", "--id", "10"}, dir, nil)
|
||||||
|
Expect(err).NotTo(BeNil(), "获取覆盖率不应该成功")
|
||||||
|
Expect(output).To(ContainSubstring("can't merge zero profiles"), "错误信息不对")
|
||||||
|
|
||||||
|
By("清空 id=2 的覆盖率")
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "profile", "get"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "获取覆盖率失败")
|
||||||
|
Expect(output).To(ContainSubstring("basic3/main.go:8.13,11.2 2 3"))
|
||||||
|
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "profile", "clear", "--id", "2"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "清空覆盖率失败")
|
||||||
|
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "profile", "get"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "获取覆盖率失败")
|
||||||
|
Expect(output).To(ContainSubstring("basic3/main.go:8.13,11.2 2 2"))
|
||||||
|
|
||||||
|
By("清空 extra=fantastic 的覆盖率")
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "profile", "clear", "--extra", "fantastic"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "清空覆盖率失败")
|
||||||
|
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "profile", "get"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "获取覆盖率失败")
|
||||||
|
Expect(output).To(ContainSubstring("basic3/main.go:8.13,11.2 2 1"))
|
||||||
|
|
||||||
|
By("运行 basic3 -h")
|
||||||
|
basicC4 := NewLongRunCmd([]string{"./basic3", "-h"}, dir, []string{
|
||||||
|
"GOC_REGISTER_EXTRA=fantastic", // 额外的注册信息
|
||||||
|
})
|
||||||
|
basicC4.Run()
|
||||||
|
defer basicC4.Stop()
|
||||||
|
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "profile", "get"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "获取覆盖率失败")
|
||||||
|
Expect(output).To(ContainSubstring("basic3/main.go:8.13,11.2 2 2"))
|
||||||
|
|
||||||
|
By("清空所有的覆盖率")
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "profile", "clear"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "清空覆盖率失败")
|
||||||
|
|
||||||
|
output, err = RunShortRunCmd([]string{"goc", "profile", "get"}, dir, nil)
|
||||||
|
Expect(err).To(BeNil(), "获取覆盖率失败")
|
||||||
|
Expect(output).To(ContainSubstring("basic3/main.go:8.13,11.2 2 0"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("5 测试 install 命令", func() {
|
||||||
|
It("1.5.1 简单工程", func() {
|
||||||
|
dir, err := mgr.GetSampleByKey("basic")
|
||||||
|
Expect(err).To(BeNil(), "找不到 sample")
|
||||||
|
|
||||||
|
By("使用 goc install 命令编译")
|
||||||
|
gobinEnv := "GOBIN=" + dir + "/bin"
|
||||||
|
_, err = RunShortRunCmd([]string{"goc", "install", "."}, dir, []string{
|
||||||
|
gobinEnv,
|
||||||
|
})
|
||||||
|
Expect(err).To(BeNil(), "goc install 运行错误")
|
||||||
|
|
||||||
|
By("检查代码是否被插入二进制")
|
||||||
|
contain, err := SearchSymbolInBinary(dir+"/bin", "basic", "basic/goc-cover-agent-apis-auto-generated-11111-22222-package.loadFileCover")
|
||||||
|
Expect(err).To(BeNil(), "二进制检查失败")
|
||||||
|
Expect(contain).To(BeTrue(), "二进制中未找到插桩的符号")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
1
tests/e2e/samples/basic-longsleep-project/go.mod
Normal file
1
tests/e2e/samples/basic-longsleep-project/go.mod
Normal file
@ -0,0 +1 @@
|
|||||||
|
module basic3
|
11
tests/e2e/samples/basic-longsleep-project/main.go
Normal file
11
tests/e2e/samples/basic-longsleep-project/main.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("hello, world")
|
||||||
|
time.Sleep(10000 * time.Second)
|
||||||
|
}
|
@ -5,3 +5,6 @@ samples:
|
|||||||
basic2:
|
basic2:
|
||||||
dir: basic4ever-project
|
dir: basic4ever-project
|
||||||
description: a basic project which will never exist
|
description: a basic project which will never exist
|
||||||
|
basic3:
|
||||||
|
dir: basic-longsleep-project
|
||||||
|
description: a basic project which sleep a long time
|
Loading…
Reference in New Issue
Block a user