add list command

This commit is contained in:
jichangjun 2020-06-12 14:08:15 +08:00
parent e18aa10bf5
commit 45612d6f63
4 changed files with 90 additions and 23 deletions

47
cmd/list.go Normal file
View File

@ -0,0 +1,47 @@
/*
Copyright 2020 Qiniu Cloud (qiniu.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"log"
"os"
"github.com/qiniu/goc/pkg/cover"
"github.com/spf13/cobra"
)
var listCmd = &cobra.Command{
Use: "list",
Short: "Lists all the registered services",
Long: "Lists all the registered services",
Example: `
goc list [flags]
`,
Run: func(cmd *cobra.Command, args []string) {
res, err := cover.NewWorker().ListServices(center)
if err != nil {
log.Fatalf("list failed, err: %v", err)
}
fmt.Fprint(os.Stdout, string(res))
},
}
func init() {
listCmd.Flags().StringVarP(&center, "center", "", "http://127.0.0.1:7777", "cover profile host center")
rootCmd.AddCommand(listCmd)
}

View File

@ -24,21 +24,24 @@ import (
"net/http" "net/http"
) )
// Action provides methods to contact with the coverd service under test // Action provides methods to contact with the covered service under test
type Action interface { type Action interface {
Profile(host string) ([]byte, error) Profile(host string) ([]byte, error)
Clear(host string) ([]byte, error) Clear(host string) ([]byte, error)
InitSystem(host string) ([]byte, error) InitSystem(host string) ([]byte, error)
ListServices(host string) ([]byte, error)
} }
// CoverProfileAPI is provided by the covered service to get profiles const (
const CoverProfileAPI = "/v1/cover/profile" //CoverInitSystemAPI prepare a new round of testing
CoverInitSystemAPI = "/v1/cover/init"
// CoverProfileClearAPI is provided by the covered service to clear profiles //CoverProfileAPI is provided by the covered service to get profiles
const CoverProfileClearAPI = "/v1/cover/clear" CoverProfileAPI = "/v1/cover/profile"
//CoverProfileClearAPI is provided by the covered service to clear profiles
// CoverInitSystemAPI prepare a new round of testing CoverProfileClearAPI = "/v1/cover/clear"
const CoverInitSystemAPI = "/v1/cover/init" //CoverServicesListAPI list all the registered services
CoverServicesListAPI = "/v1/cover/list"
)
type client struct { type client struct {
client *http.Client client *http.Client
@ -51,36 +54,46 @@ func NewWorker() Action {
} }
} }
func (w *client) Profile(host string) ([]byte, error) { func (c *client) ListServices(host string) ([]byte, error) {
u := fmt.Sprintf("%s%s", host, CoverProfileAPI) u := fmt.Sprintf("%s%s", host, CoverServicesListAPI)
profile, err := w.do("GET", u, nil) services, err := c.do("GET", u, nil)
if err != nil && isNetworkError(err) { if err != nil && isNetworkError(err) {
profile, err = w.do("GET", u, nil) services, err = c.do("GET", u, nil)
}
return services, err
}
func (c *client) Profile(host string) ([]byte, error) {
u := fmt.Sprintf("%s%s", host, CoverProfileAPI)
profile, err := c.do("GET", u, nil)
if err != nil && isNetworkError(err) {
profile, err = c.do("GET", u, nil)
} }
return profile, err return profile, err
} }
func (w *client) Clear(host string) ([]byte, error) { func (c *client) Clear(host string) ([]byte, error) {
u := fmt.Sprintf("%s%s", host, CoverProfileClearAPI) u := fmt.Sprintf("%s%s", host, CoverProfileClearAPI)
resp, err := w.do("POST", u, nil) resp, err := c.do("POST", u, nil)
if err != nil && isNetworkError(err) { if err != nil && isNetworkError(err) {
resp, err = w.do("POST", u, nil) resp, err = c.do("POST", u, nil)
} }
return resp, err return resp, err
} }
func (w *client) InitSystem(host string) ([]byte, error) { func (c *client) InitSystem(host string) ([]byte, error) {
u := fmt.Sprintf("%s%s", host, CoverInitSystemAPI) u := fmt.Sprintf("%s%s", host, CoverInitSystemAPI)
return w.do("POST", u, nil) return c.do("POST", u, nil)
} }
func (w *client) do(method, url string, body io.Reader) ([]byte, error) { func (c *client) do(method, url string, body io.Reader) ([]byte, error) {
req, err := http.NewRequest(method, url, body) req, err := http.NewRequest(method, url, body)
if err != nil { if err != nil {
return nil, err return nil, err
} }
res, err := w.client.Do(req) res, err := c.client.Do(req)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -58,7 +58,7 @@ type FileVar struct {
} }
// Package map a package output by go list // Package map a package output by go list
// this is subset of pakcage struct in: https://github.com/golang/go/blob/master/src/cmd/go/internal/load/pkg.go#L58 // this is subset of package struct in: https://github.com/golang/go/blob/master/src/cmd/go/internal/load/pkg.go#L58
type Package struct { type Package struct {
Dir string `json:"Dir"` // directory containing package sources Dir string `json:"Dir"` // directory containing package sources
ImportPath string `json:"ImportPath"` // import path of package in dir ImportPath string `json:"ImportPath"` // import path of package in dir
@ -157,7 +157,7 @@ func AddCounters(pkg *Package, mode, newgopath string) (*PackageCover, error) {
cmd := buildCoverCmd(file, coverVar, pkg, mode, newgopath) cmd := buildCoverCmd(file, coverVar, pkg, mode, newgopath)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return nil, fmt.Errorf("execuate go tool cover -mode=atomic -var %s -o %s/%s failed, err: %v, out: %s", coverVar.Var, pkg.Dir, file, err, string(out)) return nil, fmt.Errorf("execute go tool cover -mode=atomic -var %s -o %s/%s failed, err: %v, out: %s", coverVar.Var, pkg.Dir, file, err, string(out))
} }
} }

View File

@ -54,7 +54,7 @@ func StartServer(port string) {
gin.DefaultWriter = io.MultiWriter(f, os.Stdout) gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
r := gin.Default() r := gin.Default()
// api to show the registerd services // api to show the registered services
r.StaticFile(PersistenceFile, "./"+PersistenceFile) r.StaticFile(PersistenceFile, "./"+PersistenceFile)
v1 := r.Group("/v1") v1 := r.Group("/v1")
@ -63,6 +63,7 @@ func StartServer(port string) {
v1.GET("/cover/profile", profile) v1.GET("/cover/profile", profile)
v1.POST("/cover/clear", clear) v1.POST("/cover/clear", clear)
v1.POST("/cover/init", initSystem) v1.POST("/cover/init", initSystem)
v1.GET("/cover/list", listServices)
} }
log.Fatal(r.Run(port)) log.Fatal(r.Run(port))
@ -74,6 +75,12 @@ type Service struct {
Address string `form:"address" json:"address" binding:"required"` Address string `form:"address" json:"address" binding:"required"`
} }
//listServices list all the registered services
func listServices(c *gin.Context) {
services := LocalStore.GetAll()
c.JSON(http.StatusOK, services)
}
func registerService(c *gin.Context) { func registerService(c *gin.Context) {
var service Service var service Service
if err := c.ShouldBind(&service); err != nil { if err := c.ShouldBind(&service); err != nil {