From cc7ae82b4f42dd01f4d2a90d48e0855d34f487b8 Mon Sep 17 00:00:00 2001 From: tongjingran Date: Fri, 25 Sep 2020 15:13:36 +0800 Subject: [PATCH] new a goc server with New func --- cmd/run.go | 4 +--- cmd/server.go | 6 +++-- pkg/cover/client_test.go | 7 +++--- pkg/cover/server.go | 47 +++++++++++++++++++++++++++------------- pkg/cover/server_test.go | 14 +++++------- pkg/cover/store.go | 19 ++++++++-------- pkg/cover/store_test.go | 8 ++++--- 7 files changed, 60 insertions(+), 45 deletions(-) diff --git a/cmd/run.go b/cmd/run.go index 0a699dc..628293e 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -50,9 +50,7 @@ goc run . [--buildflags] [--exec] [--arguments] gocBuild.GoRunArguments = goRunArguments defer gocBuild.Clean() - server := cover.Server{ - Store: cover.NewMemoryStore(), // only save services in memory - } + server := cover.NewMemoryBasedServer() // only save services in memory // start goc server var l = newLocalListener() diff --git a/cmd/server.go b/cmd/server.go index cc33bad..36d5b5e 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -19,6 +19,7 @@ package cmd import ( "github.com/qiniu/goc/pkg/cover" "github.com/spf13/cobra" + "log" ) var serverCmd = &cobra.Command{ @@ -36,8 +37,9 @@ goc server --port=:8080 goc server --port=localhost:8080 `, Run: func(cmd *cobra.Command, args []string) { - server := &cover.Server{ - Store: cover.NewFileStore(localPersistence), + server, err := cover.NewFileBasedServer(localPersistence) + if err != nil { + log.Fatalf("New file based server failed, err: %v", err) } server.Run(port) }, diff --git a/pkg/cover/client_test.go b/pkg/cover/client_test.go index b55e25e..077acba 100644 --- a/pkg/cover/client_test.go +++ b/pkg/cover/client_test.go @@ -28,9 +28,8 @@ import ( func TestClientAction(t *testing.T) { // mock goc server - server := &Server{ - Store: NewFileStore("_svrs_address.txt"), - } + server, err := NewFileBasedServer("_svrs_address.txt") + assert.NoError(t, err) ts := httptest.NewServer(server.Route(os.Stdout)) defer ts.Close() var client = NewWorker(ts.URL) @@ -49,7 +48,7 @@ func TestClientAction(t *testing.T) { })) defer profileErrMockSvr.Close() - // regsiter server into goc server + // register service into goc server var src ServiceUnderTest src.Name = "serviceSuccess" src.Address = profileSuccessMockSvr.URL diff --git a/pkg/cover/server.go b/pkg/cover/server.go index 116e333..0ad07d9 100644 --- a/pkg/cover/server.go +++ b/pkg/cover/server.go @@ -33,18 +33,35 @@ import ( "k8s.io/test-infra/gopherage/pkg/cov" ) -//// DefaultStore implements the IPersistence interface -//var DefaultStore Store - // LogFile a file to save log. const LogFile = "goc.log" -type Server struct { - Store Store +type server struct { + PersistenceFile string + Store Store +} + +// NewFileBasedServer new a file based server with persistenceFile +func NewFileBasedServer(persistenceFile string) (*server, error) { + store, err := NewFileStore(persistenceFile) + if err != nil { + return nil, err + } + return &server{ + PersistenceFile: persistenceFile, + Store: store, + }, nil +} + +// NewMemoryBasedServer new a memory based server without persistenceFile +func NewMemoryBasedServer() *server { + return &server{ + Store: NewMemoryStore(), + } } // Run starts coverage host center -func (s *Server) Run(port string) { +func (s *server) Run(port string) { f, err := os.Create(LogFile) if err != nil { log.Fatalf("failed to create log file %s, err: %v", LogFile, err) @@ -57,13 +74,13 @@ func (s *Server) Run(port string) { } // Router init goc server engine -func (s *Server) Route(w io.Writer) *gin.Engine { +func (s *server) Route(w io.Writer) *gin.Engine { if w != nil { gin.DefaultWriter = w } r := gin.Default() // api to show the registered services - //r.StaticFile(s.Store, "./"+PersistenceFile) + r.StaticFile("static", "./"+s.PersistenceFile) v1 := r.Group("/v1") { @@ -93,12 +110,12 @@ type ProfileParam struct { } //listServices list all the registered services -func (s *Server) listServices(c *gin.Context) { +func (s *server) listServices(c *gin.Context) { services := s.Store.GetAll() c.JSON(http.StatusOK, services) } -func (s *Server) registerService(c *gin.Context) { +func (s *server) registerService(c *gin.Context) { var service ServiceUnderTest if err := c.ShouldBind(&service); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) @@ -124,7 +141,7 @@ func (s *Server) registerService(c *gin.Context) { address := s.Store.Get(service.Name) if !contains(address, service.Address) { - if err := s.Store.Add(service); err != nil { + if err := s.Store.Add(service); err != nil && err != ErrServiceAlreadyRegistered { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } @@ -137,7 +154,7 @@ func (s *Server) registerService(c *gin.Context) { // profile API examples: // POST /v1/cover/profile // { "force": "true", "service":["a","b"], "address":["c","d"],"coverfile":["e","f"] } -func (s *Server) profile(c *gin.Context) { +func (s *server) profile(c *gin.Context) { var body ProfileParam if err := c.ShouldBind(&body); err != nil { c.JSON(http.StatusExpectationFailed, gin.H{"error": err.Error()}) @@ -216,7 +233,7 @@ func filterProfile(coverFile []string, profiles []*cover.Profile) ([]*cover.Prof return out, nil } -func (s *Server) clear(c *gin.Context) { +func (s *server) clear(c *gin.Context) { var body ProfileParam if err := c.ShouldBind(&body); err != nil { c.JSON(http.StatusExpectationFailed, gin.H{"error": err.Error()}) @@ -239,7 +256,7 @@ func (s *Server) clear(c *gin.Context) { } -func (s *Server) initSystem(c *gin.Context) { +func (s *server) initSystem(c *gin.Context) { if err := s.Store.Init(); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -313,6 +330,6 @@ func filterAddrs(serviceList, addressList []string, force bool, allInfos map[str filterAddrList = addressAll } - // Return all servers when all param is nil + // Return all services when all param is nil return filterAddrList, nil } diff --git a/pkg/cover/server_test.go b/pkg/cover/server_test.go index 34cf64e..c144911 100644 --- a/pkg/cover/server_test.go +++ b/pkg/cover/server_test.go @@ -113,9 +113,8 @@ func TestFilterAddrs(t *testing.T) { } func TestRegisterService(t *testing.T) { - server := &Server{ - Store: NewFileStore("_svrs_address.txt"), - } + server, err := NewFileBasedServer("_svrs_address.txt") + assert.NoError(t, err) router := server.Route(os.Stdout) // register with empty service struct @@ -172,9 +171,8 @@ func TestRegisterService(t *testing.T) { } func TestProfileService(t *testing.T) { - server := &Server{ - Store: NewFileStore("_svrs_address.txt"), - } + server, err := NewFileBasedServer("_svrs_address.txt") + assert.NoError(t, err) router := server.Route(os.Stdout) // get profile with invalid force parameter @@ -190,7 +188,7 @@ func TestClearService(t *testing.T) { testObj := new(MockStore) testObj.On("GetAll").Return(map[string][]string{"foo": {"http://127.0.0.1:66666"}}) - server := &Server{ + server := &server{ Store: testObj, } router := server.Route(os.Stdout) @@ -231,7 +229,7 @@ func TestInitService(t *testing.T) { testObj := new(MockStore) testObj.On("Init").Return(fmt.Errorf("lala error")) - server := &Server{ + server := &server{ Store: testObj, } router := server.Route(os.Stdout) diff --git a/pkg/cover/store.go b/pkg/cover/store.go index 1c21e1d..f36520d 100644 --- a/pkg/cover/store.go +++ b/pkg/cover/store.go @@ -18,14 +18,13 @@ package cover import ( "bufio" + "errors" "fmt" + log "github.com/sirupsen/logrus" "os" + "path/filepath" "strings" "sync" - - "errors" - log "github.com/sirupsen/logrus" - "path/filepath" ) var ErrServiceAlreadyRegistered = errors.New("service already registered") @@ -57,14 +56,14 @@ type fileStore struct { } // NewFileStore creates a store using local file -func NewFileStore(persistenceFile string) Store { +func NewFileStore(persistenceFile string) (store Store, err error) { path, err := filepath.Abs(persistenceFile) if err != nil { - log.Fatalf("get absolute path of %s fail, err: %v", persistenceFile, err) + return nil, err } err = os.MkdirAll(filepath.Dir(path), os.ModePerm) if err != nil { - log.Fatalf("create full path of %s fail, err: %v", filepath.Dir(path), err) + return nil, err } l := &fileStore{ persistentFile: path, @@ -75,13 +74,13 @@ func NewFileStore(persistenceFile string) Store { log.Fatalf("load failed, file: %s, err: %v", l.persistentFile, err) } - return l + return l, nil } // Add adds the given service to file Store func (l *fileStore) Add(s ServiceUnderTest) error { - if err := l.memoryStore.Add(s); errors.Is(err, ErrServiceAlreadyRegistered) { - return nil + if err := l.memoryStore.Add(s); err != nil { + return err } // persistent to local store diff --git a/pkg/cover/store_test.go b/pkg/cover/store_test.go index ea17f32..6d5d076 100644 --- a/pkg/cover/store_test.go +++ b/pkg/cover/store_test.go @@ -22,7 +22,8 @@ import ( ) func TestLocalStore(t *testing.T) { - localStore := NewFileStore("_svrs_address.txt") + localStore, err := NewFileStore("_svrs_address.txt") + assert.NoError(t, err) var tc1 = ServiceUnderTest{ Name: "a", Address: "http://127.0.0.1", @@ -40,7 +41,7 @@ func TestLocalStore(t *testing.T) { Address: "http://127.0.0.4", } assert.NoError(t, localStore.Add(tc1)) - assert.NoError(t, localStore.Add(tc1)) + assert.Equal(t, localStore.Add(tc1), ErrServiceAlreadyRegistered) assert.NoError(t, localStore.Add(tc2)) assert.NoError(t, localStore.Add(tc3)) assert.NoError(t, localStore.Add(tc4)) @@ -59,7 +60,8 @@ func TestLocalStore(t *testing.T) { t.Error("local store check failed") } - localStoreNew := NewFileStore("_svrs_address.txt") + localStoreNew, err := NewFileStore("_svrs_address.txt") + assert.NoError(t, err) assert.Equal(t, localStore.GetAll(), localStoreNew.GetAll()) localStore.Init()