diff --git a/Makefile b/Makefile index dd730e7bef..aa5970a694 100644 --- a/Makefile +++ b/Makefile @@ -268,6 +268,11 @@ tensorflow/install: /usr/local/lib/libtensorflow.so rm -f libtensorflow-cpu-linux-x86_64-$(TENSORFLOW_C_VERSION).tar.gz ldconfig +.PHONY: gentest +## gentest +gentest: + $(call gen-test) + .PHONY: test ## run tests test: diff --git a/Makefile.d/functions.mk b/Makefile.d/functions.mk index 0c818a79c1..d80b96c704 100644 --- a/Makefile.d/functions.mk +++ b/Makefile.d/functions.mk @@ -89,3 +89,27 @@ define telepresence ## will be available after telepresence 0.105 released ## --deployment-type "$(SWAP_DEPLOYMENT_TYPE)" endef + +define gen-test + find . -type d | \ + grep "./cmd\|./hack\|./internal\|./pkg" | \ + grep -v "./cmd/cli\| \ + ./hack/benchmark/internal/client/ngtd\| \ + ./hack/benchmark/internal/starter/agent\| \ + ./hack/benchmark/internal/starter/external\| \ + ./hack/benchmark/internal/starter/gateway\| \ + ./hack/license\| \ + ./hack/swagger\| \ + ./hack/tools"| \ + while read dir; do \ + files=`find $${dir} -type f -maxdepth 1 -name "*.go" -not -name '*_test.go' -not -name 'doc.go'`; \ + for file in $${files}; do \ + path='./assets/test/templates/common'; \ + if [[ $${file} =~ .*options?\.go ]] ; then \ + path='./assets/test/templates/option'; \ + fi; \ + echo start generate test code: $${file}; \ + gotests -w -template_dir $${path} -all $${file}; \ + done; \ + done +endef diff --git a/assets/test/templates/common/call.tmpl b/assets/test/templates/common/call.tmpl new file mode 100644 index 0000000000..92570b7e53 --- /dev/null +++ b/assets/test/templates/common/call.tmpl @@ -0,0 +1 @@ +{{define "call"}}{{with .Receiver}}{{if not .IsStruct}}test.{{end}}{{Receiver .}}.{{end}}{{.Name}}({{range $i, $el := .Parameters}}{{if $i}}, {{end}}{{if not .IsWriter}}test.args.{{end}}{{Param .}}{{if .Type.IsVariadic}}...{{end}}{{end}}){{end}} diff --git a/assets/test/templates/common/fill.tmpl b/assets/test/templates/common/fill.tmpl new file mode 100644 index 0000000000..25d82c4677 --- /dev/null +++ b/assets/test/templates/common/fill.tmpl @@ -0,0 +1,28 @@ +{{define "fill" }} + {{- range . }} + {{ Param . }}: {{ $typ := .Type.String -}} + {{- if eq $typ "int8" -}} 0, + {{- else if eq $typ "uint8" -}} 0, + {{- else if eq $typ "uint16" -}} 0, + {{- else if eq $typ "uint32" -}} 0, + {{- else if eq $typ "uint64" -}} 0, + {{- else if eq $typ "uint" -}} 0, + {{- else if eq $typ "uintptr" -}} 0, + {{- else if eq $typ "int8" -}} 0, + {{- else if eq $typ "int16" -}} 0, + {{- else if eq $typ "int32" -}} 0, + {{- else if eq $typ "int64" -}} 0, + {{- else if eq $typ "int" -}} 0, + {{- else if eq $typ "float32" -}} 0, + {{- else if eq $typ "float64" -}} 0, + {{- else if eq $typ "complex64" -}} 0+0i, + {{- else if eq $typ "complex128" -}} 0+0i, + {{- else if eq $typ "byte" -}} 0, + {{- else if eq $typ "rune" -}} 0, + {{- else if eq $typ "string" -}} "", + {{- else if eq $typ "bool" -}} false, + {{- else if .IsStruct -}} {{.Type.Value}}{}, + {{- else -}} nil, + {{- end -}} + {{ end -}} +{{ end }} diff --git a/assets/test/templates/common/function.tmpl b/assets/test/templates/common/function.tmpl new file mode 100644 index 0000000000..5f78b37d85 --- /dev/null +++ b/assets/test/templates/common/function.tmpl @@ -0,0 +1,154 @@ +{{define "function"}} +{{- $f := . }} + +func {{ .TestName }}(t *testing.T) { + {{- if .TestParameters }} + type args struct { + {{- range .TestParameters }} + {{ Param . }} {{ .Type }} + {{- end}} + } + {{- end }} + {{- $hasFields := false -}} + {{- with .Receiver }} + {{- if .IsStruct }} + {{- if .Fields}} + type fields struct { {{ $hasFields = true }} + {{- range .Fields }} + {{ Field . }} {{ .Type }} + {{- end }} + } + {{- end }} + {{- end }} + {{- end }} + type want struct { + {{- range .TestResults }} + {{ Want . }} {{ .Type }} + {{- end }} + {{- if .ReturnsError }} + err error + {{- end }} + } + type test struct { + name string + {{- if .TestParameters }} + args args + {{- end }} + {{- with .Receiver}} + {{- if and .IsStruct .Fields}} + fields fields + {{- else}} + {{Receiver .}} {{.Type}} + {{- end}} + {{- end}} + want want + checkFunc func(want, + {{- range .TestResults }} {{ .Type }}, {{- end }} + {{- if .ReturnsError }} error {{- end }} ) error + beforeFunc func({{- if .TestParameters }} args {{- end}}) + afterFunc func({{- if .TestParameters }} args {{- end}}) + } + defaultCheckFunc := func(w want, + {{- range .TestResults }} {{ Got . }} {{ .Type }}, {{- end }} + {{- if .ReturnsError }} err error {{- end }} ) error { + + {{- if .ReturnsError }} + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + {{- end }} + {{- range .TestResults }} {{ $want := Want . }} {{ $got := Got . }} + if !reflect.DeepEqual({{ $got }}, w.{{ $want }}) { + return errors.Errorf("got = %v, want %v", {{ $got }}, w.{{ $want }}) + } + {{- end }} + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + {{- if .TestParameters }} + args: args { + {{- template "fill" .TestParameters }} + }, + {{- end }} + {{- if $hasFields }} + fields: fields { + {{- template "fill" .Receiver.Fields }} + }, + {{- end }} + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + {{- if .TestParameters }} + args: args { + {{- template "fill" .TestParameters }} + }, + {{- end }} + {{- if $hasFields }} + fields: fields { + {{- template "fill" .Receiver.Fields }} + }, + {{- end }} + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for {{- if (or .Subtests (not .IsNaked)) }} _, test := {{- end }} range tests { + {{- if .Subtests }} + t.Run(test.name, func(tt *testing.T) { + if test.beforeFunc != nil { + test.beforeFunc({{- if .TestParameters }} test.args {{- end }}) + } + if test.afterFunc != nil { + defer test.afterFunc({{- if .TestParameters }} test.args {{- end }}) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + {{- with .Receiver }} + {{- if .IsStruct }} + {{ Receiver . }} := {{- if .Type.IsStar }}&{{- end }}{{ .Type.Value }} { + {{- range .Fields }} + {{ Field . }}: test.fields.{{ Field . }}, + {{- end }} + } + {{- end }} + {{- end }} + + {{- range .Parameters }} + {{- if .IsWriter }} + {{ Param . }} := &bytes.Buffer{} + {{- end }} + {{- end }} + + {{ $len := len .Results }} + {{- if or (ge $len 1) (.OnlyReturnsOneValue) (.OnlyReturnsError) }} + {{ template "results" $f }} := {{ template "call" $f }} + if err := test.checkFunc(test.want, {{ template "results" $f }} ); err != nil { + tt.Errorf("error = %v", err) + } + {{ else }} + {{ template "call" $f }} + if err := test.checkFunc(test.want); err != nil { + tt.Errorf("error = %v", err) + } + {{- end }} + }) + {{- end }} + } +} +{{- end }} diff --git a/assets/test/templates/common/header.tmpl b/assets/test/templates/common/header.tmpl new file mode 100644 index 0000000000..245569df7e --- /dev/null +++ b/assets/test/templates/common/header.tmpl @@ -0,0 +1,10 @@ +{{define "header"}} +{{range .Comments}}{{.}} +{{end -}} +package {{.Package}} + +import ( +{{range .Imports}}{{.Name}} {{.Path}} +{{end}} +) +{{end}} diff --git a/assets/test/templates/common/inline.tmpl b/assets/test/templates/common/inline.tmpl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/assets/test/templates/common/inputs.tmpl b/assets/test/templates/common/inputs.tmpl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/assets/test/templates/common/message.tmpl b/assets/test/templates/common/message.tmpl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/assets/test/templates/common/results.tmpl b/assets/test/templates/common/results.tmpl new file mode 100644 index 0000000000..8b94e3d558 --- /dev/null +++ b/assets/test/templates/common/results.tmpl @@ -0,0 +1,2 @@ +{{define "results"}}{{- if .OnlyReturnsError }}err{{ else }}{{range $i, $el := .Results}}{{if $i}}, {{end}}{{Got .}}{{end}}{{if .ReturnsError}}, err{{end}} +{{- end }}{{end}} diff --git a/assets/test/templates/option/call.tmpl b/assets/test/templates/option/call.tmpl new file mode 120000 index 0000000000..9ebd7e2d8a --- /dev/null +++ b/assets/test/templates/option/call.tmpl @@ -0,0 +1 @@ +../common/call.tmpl \ No newline at end of file diff --git a/assets/test/templates/option/fill.tmpl b/assets/test/templates/option/fill.tmpl new file mode 120000 index 0000000000..873307f910 --- /dev/null +++ b/assets/test/templates/option/fill.tmpl @@ -0,0 +1 @@ +../common/fill.tmpl \ No newline at end of file diff --git a/assets/test/templates/option/function.tmpl b/assets/test/templates/option/function.tmpl new file mode 100644 index 0000000000..67a60d9647 --- /dev/null +++ b/assets/test/templates/option/function.tmpl @@ -0,0 +1,156 @@ +{{define "function"}} +{{- $f := . }} + +func {{ .TestName }}(t *testing.T) { + type T = interface{} + {{- if .TestParameters }} + type args struct { + {{- range .TestParameters }} + {{ Param . }} {{ .Type }} + {{- end}} + } + {{- end }} + {{- $hasFields := false -}} + {{- with .Receiver }} + {{- if .IsStruct }} + {{- if .Fields}} + type fields struct { {{ $hasFields = true }} + {{- range .Fields }} + {{ Field . }} {{ .Type }} + {{- end }} + } + {{- end }} + {{- end }} + {{- end }} + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + {{- if .TestParameters }} + args args + {{- end }} + {{- with .Receiver}} + {{- if and .IsStruct .Fields}} + fields fields + {{- else}} + {{Receiver .}} {{.Type}} + {{- end}} + {{- end}} + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func({{- if .TestParameters }} args {{- end}}) + afterFunc func({{- if .TestParameters }} args {{- end}}) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return fmt.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + {{- if .TestParameters }} + args: args { + {{- template "fill" .TestParameters }} + }, + {{- end }} + {{- if $hasFields }} + fields: fields { + {{- template "fill" .Receiver.Fields }} + }, + {{- end }} + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + {{- if .TestParameters }} + args: args { + {{- template "fill" .TestParameters }} + }, + {{- end }} + {{- if $hasFields }} + fields: fields { + {{- template "fill" .Receiver.Fields }} + }, + {{- end }} + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for {{- if (or .Subtests (not .IsNaked)) }} _, test := {{- end }} range tests { + {{- if .Subtests }} + t.Run(test.name, func(tt *testing.T) { + if test.beforeFunc != nil { + test.beforeFunc({{- if .TestParameters }} test.args {{- end }}) + } + if test.afterFunc != nil { + defer test.afterFunc({{- if .TestParameters }} test.args {{- end }}) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := {{ template "call" $f }} + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := {{ template "call" $f }} + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + {{- end }} + } +} +{{- end }} diff --git a/assets/test/templates/option/header.tmpl b/assets/test/templates/option/header.tmpl new file mode 120000 index 0000000000..1b01327e84 --- /dev/null +++ b/assets/test/templates/option/header.tmpl @@ -0,0 +1 @@ +../common/header.tmpl \ No newline at end of file diff --git a/assets/test/templates/option/inline.tmpl b/assets/test/templates/option/inline.tmpl new file mode 120000 index 0000000000..20800f829f --- /dev/null +++ b/assets/test/templates/option/inline.tmpl @@ -0,0 +1 @@ +../common/inline.tmpl \ No newline at end of file diff --git a/assets/test/templates/option/inputs.tmpl b/assets/test/templates/option/inputs.tmpl new file mode 120000 index 0000000000..2e62eb5e25 --- /dev/null +++ b/assets/test/templates/option/inputs.tmpl @@ -0,0 +1 @@ +../common/inputs.tmpl \ No newline at end of file diff --git a/assets/test/templates/option/message.tmpl b/assets/test/templates/option/message.tmpl new file mode 120000 index 0000000000..8fabb08f36 --- /dev/null +++ b/assets/test/templates/option/message.tmpl @@ -0,0 +1 @@ +../common/message.tmpl \ No newline at end of file diff --git a/assets/test/templates/option/results.tmpl b/assets/test/templates/option/results.tmpl new file mode 120000 index 0000000000..c8010be6e9 --- /dev/null +++ b/assets/test/templates/option/results.tmpl @@ -0,0 +1 @@ +../common/results.tmpl \ No newline at end of file diff --git a/go.mod b/go.mod index 74c999f944..a0be38ef1b 100755 --- a/go.mod +++ b/go.mod @@ -51,7 +51,7 @@ require ( go.opencensus.io v0.22.3 go.uber.org/automaxprocs v1.3.0 golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 - golang.org/x/tools v0.0.0-20200421144719-26dd2a56eb2c // indirect + golang.org/x/tools v0.0.0-20200423205358-59e73619c742 // indirect gonum.org/v1/hdf5 v0.0.0-20191105085658-fe04b73f3b53 gonum.org/v1/plot v0.7.0 google.golang.org/genproto v0.0.0-20200420144010-e5e8543f8aeb diff --git a/go.sum b/go.sum index 39cb45a8fa..16e2cf909e 100644 --- a/go.sum +++ b/go.sum @@ -595,6 +595,8 @@ golang.org/x/tools v0.0.0-20200421042724-cfa8b22178d2 h1:fVXd7Kf16vo/CTZCrBFb6Be golang.org/x/tools v0.0.0-20200421042724-cfa8b22178d2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200421144719-26dd2a56eb2c h1:DS5GY1XpuL4qXOy43NhcD9dUmBHezAABwfQ105ojI08= golang.org/x/tools v0.0.0-20200421144719-26dd2a56eb2c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200423205358-59e73619c742 h1:9OGWpORUXvk8AsaBJlpzzDx7Srv/rSK6rvjcsJq4rJo= +golang.org/x/tools v0.0.0-20200423205358-59e73619c742/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= diff --git a/hack/license/gen/main.go b/hack/license/gen/main.go index cf24f669d6..f0f0cda937 100644 --- a/hack/license/gen/main.go +++ b/hack/license/gen/main.go @@ -114,6 +114,7 @@ func dirwalk(dir string) []string { ".sum", ".svg", ".tpl", + ".tmpl", ".txt", ".whitesource", "LICENSE", diff --git a/k8s/agent/statefulset.yaml b/k8s/agent/statefulset.yaml index db67d8e094..c866d02380 100644 --- a/k8s/agent/statefulset.yaml +++ b/k8s/agent/statefulset.yaml @@ -55,10 +55,10 @@ spec: - podAffinityTerm: labelSelector: matchExpressions: - - key: app - operator: In - values: - - vald-agent-ngt + - key: app + operator: In + values: + - vald-agent-ngt topologyKey: kubernetes.io/hostname weight: 100 requiredDuringSchedulingIgnoredDuringExecution: [] diff --git a/k8s/discoverer/deployment.yaml b/k8s/discoverer/deployment.yaml index 3f9826e160..d267b5696a 100644 --- a/k8s/discoverer/deployment.yaml +++ b/k8s/discoverer/deployment.yaml @@ -54,10 +54,10 @@ spec: - podAffinityTerm: labelSelector: matchExpressions: - - key: app - operator: In - values: - - vald-discoverer + - key: app + operator: In + values: + - vald-discoverer topologyKey: kubernetes.io/hostname weight: 100 requiredDuringSchedulingIgnoredDuringExecution: [] diff --git a/k8s/gateway/vald/deployment.yaml b/k8s/gateway/vald/deployment.yaml index e70ed08a0d..8ffb98482a 100644 --- a/k8s/gateway/vald/deployment.yaml +++ b/k8s/gateway/vald/deployment.yaml @@ -98,10 +98,10 @@ spec: - podAffinityTerm: labelSelector: matchExpressions: - - key: app - operator: In - values: - - vald-gateway + - key: app + operator: In + values: + - vald-gateway topologyKey: kubernetes.io/hostname weight: 100 requiredDuringSchedulingIgnoredDuringExecution: [] diff --git a/k8s/operator/helm/valdrelease.yaml b/k8s/operator/helm/valdrelease.yaml index 61901c60b3..79efc89b8f 100644 --- a/k8s/operator/helm/valdrelease.yaml +++ b/k8s/operator/helm/valdrelease.yaml @@ -20,5 +20,4 @@ metadata: name: vald-cluster namespace: default # the values of Helm chart for Vald can be placed under the `spec` field. -spec: - {} +spec: {}