Merge pull request #112 from lyyyuna/goc-103

Clear coverage by service&addr
This commit is contained in:
qiniu-bot 2020-09-14 15:36:17 +08:00 committed by GitHub
commit a217d13046
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 119 additions and 25 deletions

View File

@ -41,7 +41,7 @@ jobs:
needs: job_1
strategy:
matrix:
go-version: [1.11.x, 1.12.x, 1.13.x, 1.14.x]
go-version: [1.11.x, 1.12.x, 1.13.x, 1.14.x, 1.15.x]
runs-on: ubuntu-latest
steps:
- name: Install Go

View File

@ -13,7 +13,7 @@ jobs:
name: vet and gofmt
strategy:
matrix:
go-version: [1.13.x, 1.14.x]
go-version: [1.13.x, 1.14.x, 1.15.x]
runs-on: ubuntu-latest
steps:
- name: Install Go

View File

@ -13,7 +13,7 @@ jobs:
name: go test
strategy:
matrix:
go-version: [1.13.x, 1.14.x]
go-version: [1.13.x, 1.14.x, 1.15.x]
runs-on: ubuntu-latest
steps:
- name: Install Go

View File

@ -18,9 +18,10 @@ package cmd
import (
"fmt"
log "github.com/sirupsen/logrus"
"os"
log "github.com/sirupsen/logrus"
"github.com/qiniu/goc/pkg/cover"
"github.com/spf13/cobra"
)
@ -37,7 +38,11 @@ goc clear
goc clear --center=http://192.168.1.1:8080
`,
Run: func(cmd *cobra.Command, args []string) {
res, err := cover.NewWorker(center).Clear()
p := cover.ProfileParam{
Service: svrList,
Address: addrList,
}
res, err := cover.NewWorker(center).Clear(p)
if err != nil {
log.Fatalf("call host %v failed, err: %v, response: %v", center, err, string(res))
}
@ -47,5 +52,7 @@ goc clear --center=http://192.168.1.1:8080
func init() {
addBasicFlags(clearCmd.Flags())
clearCmd.Flags().StringSliceVarP(&svrList, "service", "", nil, "service name to clear profile, see 'goc list' for all services.")
clearCmd.Flags().StringSliceVarP(&addrList, "address", "", nil, "address to clear profile, see 'goc list' for all addresses.")
rootCmd.AddCommand(clearCmd)
}

View File

@ -33,7 +33,7 @@ import (
// Action provides methods to contact with the covered service under test
type Action interface {
Profile(param ProfileParam) ([]byte, error)
Clear() ([]byte, error)
Clear(param ProfileParam) ([]byte, error)
InitSystem() ([]byte, error)
ListServices() ([]byte, error)
RegisterService(svr Service) ([]byte, error)
@ -97,10 +97,9 @@ func (c *client) Profile(param ProfileParam) ([]byte, error) {
return nil, fmt.Errorf("use 'service' flag and 'address' flag at the same time may cause ambiguity, please use them separately")
}
body, err := json.Marshal(param)
if err != nil {
return nil, fmt.Errorf("json.Marshal failed, param: %v, err:%v", param, err)
}
// the json.Marshal function can return two types of errors: UnsupportedTypeError or UnsupportedValueError
// so no need to check here
body, _ := json.Marshal(param)
res, profile, err := c.do("POST", u, "application/json", bytes.NewReader(body))
if err != nil && isNetworkError(err) {
@ -113,11 +112,18 @@ func (c *client) Profile(param ProfileParam) ([]byte, error) {
return profile, err
}
func (c *client) Clear() ([]byte, error) {
func (c *client) Clear(param ProfileParam) ([]byte, error) {
u := fmt.Sprintf("%s%s", c.Host, CoverProfileClearAPI)
_, resp, err := c.do("POST", u, "", nil)
if len(param.Service) != 0 && len(param.Address) != 0 {
return nil, fmt.Errorf("use 'service' flag and 'address' flag at the same time may cause ambiguity, please use them separately")
}
// the json.Marshal function can return two types of errors: UnsupportedTypeError or UnsupportedValueError
// so no need to check here
body, _ := json.Marshal(param)
_, resp, err := c.do("POST", u, "application/json", bytes.NewReader(body))
if err != nil && isNetworkError(err) {
_, resp, err = c.do("POST", u, "", nil)
_, resp, err = c.do("POST", u, "application/json", bytes.NewReader(body))
}
return resp, err
}

View File

@ -189,3 +189,16 @@ func TestClientDo(t *testing.T) {
_, _, err := c.do(" ", "http://127.0.0.1:7777", "", nil) // a invalid method
assert.Contains(t, err.Error(), "invalid method")
}
func TestClientClearWithInvalidParam(t *testing.T) {
p := ProfileParam{
Service: []string{"goc"},
Address: []string{"http://127.0.0.1:777"},
}
c := &client{
client: http.DefaultClient,
}
_, err := c.Clear(p)
assert.Error(t, err)
assert.Contains(t, err.Error(), "use 'service' flag and 'address' flag at the same time may cause ambiguity, please use them separately")
}

View File

@ -217,17 +217,26 @@ func filterProfile(coverFile []string, profiles []*cover.Profile) ([]*cover.Prof
}
func clear(c *gin.Context) {
var body ProfileParam
if err := c.ShouldBind(&body); err != nil {
c.JSON(http.StatusExpectationFailed, gin.H{"error": err.Error()})
return
}
svrsUnderTest := DefaultStore.GetAll()
for svc, addrs := range svrsUnderTest {
for _, addr := range addrs {
pp, err := NewWorker(addr).Clear()
filterAddrList, err := filterAddrs(body.Service, body.Address, true, svrsUnderTest)
if err != nil {
c.JSON(http.StatusExpectationFailed, gin.H{"error": err.Error()})
return
}
fmt.Fprintf(c.Writer, "Register service %s: %s coverage counter %s", svc, addr, string(pp))
for _, addr := range filterAddrList {
pp, err := NewWorker(addr).Clear(ProfileParam{})
if err != nil {
c.JSON(http.StatusExpectationFailed, gin.H{"error": err.Error()})
return
}
fmt.Fprintf(c.Writer, "Register service %s coverage counter %s", addr, string(pp))
}
}
func initSystem(c *gin.Context) {

View File

@ -1,6 +1,8 @@
package cover
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
@ -186,13 +188,36 @@ func TestClearService(t *testing.T) {
router := GocServer(os.Stdout)
// get profile with invalid force parameter
// clear profile with non-exist port
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/v1/cover/clear", nil)
req, _ := http.NewRequest("POST", "/v1/cover/clear", bytes.NewBuffer([]byte(`{}`)))
req.Header.Set("Content-Type", "application/json")
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusExpectationFailed, w.Code)
assert.Contains(t, w.Body.String(), "invalid port")
// clear profile with invalid service
w = httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/v1/cover/clear", nil)
req.Header.Set("Content-Type", "application/json")
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusExpectationFailed, w.Code)
assert.Contains(t, w.Body.String(), "invalid request")
// clear profile with service and address set at at the same time
p := ProfileParam{
Service: []string{"goc"},
Address: []string{"http://127.0.0.1:3333"},
}
encoded, err := json.Marshal(p)
assert.NoError(t, err)
w = httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/v1/cover/clear", bytes.NewBuffer(encoded))
req.Header.Set("Content-Type", "application/json")
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusExpectationFailed, w.Code)
assert.Contains(t, w.Body.String(), "use 'service' flag and 'address' flag at the same time may cause ambiguity, please use them separately")
}
func TestInitService(t *testing.T) {

View File

@ -38,6 +38,7 @@ setup_file() {
}
teardown_file() {
rm *_profile_listen_addr
kill -9 $GOC_PID
kill -9 $GOCC_PID
kill -9 $SAMPLE_PID
@ -66,3 +67,36 @@ teardown_file() {
wait $profile_pid
}
@test "test clear by service name" {
goc build --output=./test-service
./test-service 3>&- &
TEST_SERVICE=$!
sleep 1
# clear by wrong service name
run goc clear --service="test-servicej"
[ "$status" -eq 0 ]
[ "$output" = "" ]
# check by goc profile, as the last step is wrong
# the coverage count should be 1
run goc profile --coverfile="simple-project/a/a.go" --force
info clear3 output: $output
[ "$status" -eq 0 ]
[[ "$output" =~ "example.com/simple-project/a/a.go:4.12,6.2 1 1" ]]
# clear by right service name
run goc clear --service="test-service"
[ "$status" -eq 0 ]
[[ "$output" =~ "coverage counter clear call successfully" ]]
# check by goc profile, the coverage count should be reset to 0
run goc profile --coverfile="simple-project/a/a.go" --force
info clear4 output: $output
[ "$status" -eq 0 ]
[[ "$output" =~ "example.com/simple-project/a/a.go:4.12,6.2 1 0" ]]
kill -9 $TEST_SERVICE
}