diff --git a/go.mod b/go.mod index 2ef09dfdcc..dbb5115b10 100755 --- a/go.mod +++ b/go.mod @@ -41,6 +41,7 @@ require ( github.com/gocql/gocql v0.0.0-20200131111108-92af2e088537 github.com/gocraft/dbr/v2 v2.7.0 github.com/gogo/protobuf v1.3.1 + github.com/google/go-cmp v0.5.0 github.com/google/gofuzz v1.1.0 github.com/gorilla/mux v1.7.1 github.com/hashicorp/go-version v1.2.0 diff --git a/go.sum b/go.sum index 7d00c9df1d..47181348d3 100644 --- a/go.sum +++ b/go.sum @@ -331,6 +331,8 @@ github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-replayers/grpcreplay v0.1.0 h1:eNb1y9rZFmY4ax45uEEECSa8fsxGRU+8Bil52ASAwic= github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= diff --git a/internal/info/info.go b/internal/info/info.go index 7e045e8786..e80142cd39 100644 --- a/internal/info/info.go +++ b/internal/info/info.go @@ -30,6 +30,7 @@ import ( "github.com/vdaas/vald/internal/log" ) +// Detail represents environment information of system and stacktrace information. type Detail struct { Version string `json:"vald_version,omitempty" yaml:"vald_version,omitempty"` ServerName string `json:"server_name,omitempty" yaml:"server_name,omitempty"` @@ -45,6 +46,7 @@ type Detail struct { PrepOnce sync.Once `json:"-" yaml:"-"` } +// StackTrace represents stacktrace information about url, function name, file, line ..etc. type StackTrace struct { URL string `json:"url,omitempty" yaml:"url,omitempty"` FuncName string `json:"function_name,omitempty" yaml:"func_name,omitempty"` @@ -75,14 +77,17 @@ var ( detail Detail ) +// String calls String method of global detail object. func String() string { return detail.String() } +// Get calls Get method of global detail object. func Get() Detail { return detail.Get() } +// String returns summary of Detail object. func (d Detail) String() string { if len(d.StackTrace) == 0 { d = d.Get() @@ -143,6 +148,7 @@ func (d Detail) String() string { return "\n" + strings.Join(strs, "\n") } +// Get returns parased Detail object. func (d Detail) Get() Detail { d.prepare() valdRepo := fmt.Sprintf("github.com/%s/%s", Organization, Repository) @@ -221,6 +227,7 @@ func (d *Detail) prepare() { }) } +// Init initializes Detail object only once. func Init(name string) { once.Do(func() { detail = Detail{ diff --git a/internal/info/info_test.go b/internal/info/info_test.go index c5ab07a45e..d680bbba06 100644 --- a/internal/info/info_test.go +++ b/internal/info/info_test.go @@ -19,9 +19,12 @@ package info import ( "reflect" + "runtime" "sync" "testing" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/vdaas/vald/internal/errors" ) @@ -392,76 +395,240 @@ func TestDetail_prepare(t *testing.T) { NGTVersion string BuildCPUInfoFlags []string StackTrace []StackTrace - PrepOnce sync.Once } type want struct { + want *Detail } type test struct { name string fields fields want want - checkFunc func(want) error + checkFunc func(want, *Detail) error beforeFunc func() afterFunc func() } - defaultCheckFunc := func(w want) error { + defaultCheckFunc := func(w want, got *Detail) error { + opts := []cmp.Option{ + cmpopts.IgnoreFields(*w.want, "PrepOnce"), + } + if diff := cmp.Diff(*w.want, *got, opts...); len(diff) != 0 { + return errors.Errorf("err: %s", diff) + } return nil } + defaultBeforeFunc := func() { + Version = "" + GitCommit = "gitcommit" + BuildTime = "1s" + CGOEnabled = "true" + NGTVersion = "v1.11.6" + BuildCPUInfoFlags = "\t\tavx512f avx512dq\t" + + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - fields: fields { - Version: "", - ServerName: "", - GitCommit: "", - BuildTime: "", - GoVersion: "", - GoOS: "", - GoArch: "", - CGOEnabled: "", - NGTVersion: "", - BuildCPUInfoFlags: nil, - StackTrace: nil, - PrepOnce: sync.Once{}, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ + { + name: "set success when all fields are empty", + want: want{ + want: &Detail{ + GitCommit: "master", + Version: "gitcommit", + BuildTime: "1s", + GoVersion: runtime.Version(), + GoOS: runtime.GOOS, + GoArch: runtime.GOARCH, + CGOEnabled: "true", + NGTVersion: "v1.11.6", + BuildCPUInfoFlags: []string{ + "avx512f", "avx512dq", + }, + }, + }, + }, - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - fields: fields { - Version: "", - ServerName: "", - GitCommit: "", - BuildTime: "", - GoVersion: "", - GoOS: "", - GoArch: "", - CGOEnabled: "", - NGTVersion: "", - BuildCPUInfoFlags: nil, - StackTrace: nil, - PrepOnce: sync.Once{}, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "GitCommit and Version field is not overwritten when GitCommit field is `internal`", + fields: fields{ + GitCommit: "internal", + }, + want: want{ + want: &Detail{ + GitCommit: "internal", + Version: "gitcommit", + BuildTime: "1s", + GoVersion: runtime.Version(), + GoOS: runtime.GOOS, + GoArch: runtime.GOARCH, + CGOEnabled: "true", + NGTVersion: "v1.11.6", + BuildCPUInfoFlags: []string{ + "avx512f", "avx512dq", + }, + }, + }, + }, + + { + name: "BuildTime field is not overwritten when BuildTime field is `10`", + fields: fields{ + BuildTime: "10s", + }, + want: want{ + want: &Detail{ + GitCommit: "master", + Version: "gitcommit", + BuildTime: "10s", + GoVersion: runtime.Version(), + GoOS: runtime.GOOS, + GoArch: runtime.GOARCH, + CGOEnabled: "true", + NGTVersion: "v1.11.6", + BuildCPUInfoFlags: []string{ + "avx512f", "avx512dq", + }, + }, + }, + }, + + { + name: "GoVersion field is not overwritten when GoVersion field is `1.14`", + fields: fields{ + GoVersion: "1.14", + }, + want: want{ + want: &Detail{ + GitCommit: "master", + Version: "gitcommit", + BuildTime: "1s", + GoVersion: "1.14", + GoOS: runtime.GOOS, + GoArch: runtime.GOARCH, + CGOEnabled: "true", + NGTVersion: "v1.11.6", + BuildCPUInfoFlags: []string{ + "avx512f", "avx512dq", + }, + }, + }, + }, + + { + name: "GoOS field is not overwritten when GoOS field is `linux`", + fields: fields{ + GoOS: "linux", + }, + want: want{ + want: &Detail{ + GitCommit: "master", + Version: "gitcommit", + BuildTime: "1s", + GoVersion: runtime.Version(), + GoOS: "linux", + GoArch: runtime.GOARCH, + CGOEnabled: "true", + NGTVersion: "v1.11.6", + BuildCPUInfoFlags: []string{ + "avx512f", "avx512dq", + }, + }, + }, + }, + + { + name: "GoArch fields is not overwritten when GoArch field is `amd`", + fields: fields{ + GoArch: "amd", + }, + want: want{ + want: &Detail{ + GitCommit: "master", + Version: "gitcommit", + BuildTime: "1s", + GoVersion: runtime.Version(), + GoOS: runtime.GOOS, + GoArch: "amd", + CGOEnabled: "true", + NGTVersion: "v1.11.6", + BuildCPUInfoFlags: []string{ + "avx512f", "avx512dq", + }, + }, + }, + }, + + { + name: "CGOEnabled field is not overwritten when CGOEnabled field is `1`", + fields: fields{ + CGOEnabled: "1", + }, + want: want{ + want: &Detail{ + GitCommit: "master", + Version: "gitcommit", + BuildTime: "1s", + GoVersion: runtime.Version(), + GoOS: runtime.GOOS, + GoArch: runtime.GOARCH, + CGOEnabled: "1", + NGTVersion: "v1.11.6", + BuildCPUInfoFlags: []string{ + "avx512f", "avx512dq", + }, + }, + }, + }, + + { + name: "NGTVersion field is not overwritten when NGTVersion field is `v1.11.5`", + fields: fields{ + NGTVersion: "v1.11.5", + }, + want: want{ + want: &Detail{ + GitCommit: "master", + Version: "gitcommit", + BuildTime: "1s", + GoVersion: runtime.Version(), + GoOS: runtime.GOOS, + GoArch: runtime.GOARCH, + CGOEnabled: "true", + NGTVersion: "v1.11.5", + BuildCPUInfoFlags: []string{ + "avx512f", "avx512dq", + }, + }, + }, + }, + + { + name: "BuildCPUInfoFlags is not overwritten when BuildCPUInfoFlags field is `test`", + fields: fields{ + BuildCPUInfoFlags: []string{"test"}, + }, + want: want{ + want: &Detail{ + GitCommit: "master", + Version: "gitcommit", + BuildTime: "1s", + GoVersion: runtime.Version(), + GoOS: runtime.GOOS, + GoArch: runtime.GOARCH, + CGOEnabled: "true", + NGTVersion: "v1.11.6", + BuildCPUInfoFlags: []string{ + "test", + }, + }, + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - if test.beforeFunc != nil { - test.beforeFunc() + if test.beforeFunc == nil { + test.beforeFunc = defaultBeforeFunc } + test.beforeFunc() + if test.afterFunc != nil { defer test.afterFunc() } @@ -480,11 +647,10 @@ func TestDetail_prepare(t *testing.T) { NGTVersion: test.fields.NGTVersion, BuildCPUInfoFlags: test.fields.BuildCPUInfoFlags, StackTrace: test.fields.StackTrace, - PrepOnce: test.fields.PrepOnce, } d.prepare() - if err := test.checkFunc(test.want); err != nil { + if err := test.checkFunc(test.want, d); err != nil { tt.Errorf("error = %v", err) } }) @@ -496,44 +662,56 @@ func TestInit(t *testing.T) { name string } type want struct { + want *Detail } type test struct { name string args args want want - checkFunc func(want) error + checkFunc func(want, *Detail) error beforeFunc func(args) afterFunc func(args) } - defaultCheckFunc := func(w want) error { + defaultCheckFunc := func(w want, got *Detail) error { + opts := []cmp.Option{ + cmpopts.IgnoreFields(*w.want, "PrepOnce"), + } + if diff := cmp.Diff(*w.want, *got, opts...); len(diff) != 0 { + return errors.Errorf("err: %s", diff) + } return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - name: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - name: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "set success when all fields are empty", + args: args{ + name: "gateway", + }, + want: want{ + want: &Detail{ + GitCommit: "gitcommit", + ServerName: "gateway", + Version: "gitcommit", + BuildTime: "1s", + GoVersion: runtime.Version(), + GoOS: runtime.GOOS, + GoArch: runtime.GOARCH, + CGOEnabled: "true", + NGTVersion: "v1.11.6", + BuildCPUInfoFlags: []string{ + "avx512f", "avx512dq", + }, + }, + }, + beforeFunc: func(args) { + GitCommit = "gitcommit" + Version = "" + BuildTime = "1s" + CGOEnabled = "true" + NGTVersion = "v1.11.6" + BuildCPUInfoFlags = "\t\tavx512f avx512dq\t" + }, + }, } for _, test := range tests { @@ -549,7 +727,7 @@ func TestInit(t *testing.T) { } Init(test.args.name) - if err := test.checkFunc(test.want); err != nil { + if err := test.checkFunc(test.want, &detail); err != nil { tt.Errorf("error = %v", err) } })