diff --git a/.gitattributes b/.gitattributes index fcadb2cf9..cf58c827d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,9 @@ -* text eol=lf +*.go text eol=lf +*.vue text eol=lf +*.js text eol=lf +*.css text eol=lf +*.html text eol=lf +*.md text eol=lf +*.yaml text eol=lf +*.json text eol=lf +*.yml text eol=lf diff --git a/.gitignore b/.gitignore index 8a97a22e7..5c0ca3c7b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ console/atest-desktop/node_modules console/atest-desktop/atest console/atest-desktop/atest.exe console/atest-desktop/coverage +atest-store-git diff --git a/README.md b/README.md index 1863c8077..80c6650b4 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ This is an awesome API testing tool. 🚀 * Pre and post handle with the API request * Run in server mode, and provide the [gRPC](pkg/server/server.proto) and HTTP endpoint * [VS Code extension](https://github.com/LinuxSuRen/vscode-api-testing) support +* Simple Database query support * Multiple storage backends supported(Local, ORM Database, S3, Git, Etcd, etc.) * [HTTP API record](https://github.com/LinuxSuRen/atest-ext-collector) * Install in multiple use cases(CLI, Container, Native-Service, [Operator](https://github.com/LinuxSuRen/atest-operator), Helm, etc.) diff --git a/atest-store-git b/atest-store-git deleted file mode 100755 index 36e395e3c..000000000 Binary files a/atest-store-git and /dev/null differ diff --git a/cmd/server.go b/cmd/server.go index f7afddb33..8a904d1c5 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -102,7 +102,7 @@ func createServerCmd(execer fakeruntime.Execer, httpServer server.HTTPServer) (c flags.StringArrayVarP(&opt.mockConfig, "mock-config", "", nil, "The mock config files") flags.StringVarP(&opt.mockPrefix, "mock-prefix", "", "/mock", "The mock server API prefix") flags.StringVarP(&opt.extensionRegistry, "extension-registry", "", "docker.io", "The extension registry URL") - flags.DurationVarP(&opt.downloadTimeout, "download-timeout", "", time.Second*10, "The timeout of extension download") + flags.DurationVarP(&opt.downloadTimeout, "download-timeout", "", time.Minute, "The timeout of extension download") // gc related flags flags.IntVarP(&opt.gcPercent, "gc-percent", "", 100, "The GC percent of Go") @@ -288,6 +288,7 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) { } server.RegisterRunnerServer(s, remoteServer) server.RegisterMockServer(s, mockServerController) + server.RegisterDataServerServer(s, remoteServer.(server.DataServerServer)) serverLogger.Info("gRPC server listening at", "addr", lis.Addr()) s.Serve(lis) }() @@ -322,11 +323,14 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) { } err = errors.Join( server.RegisterRunnerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, []grpc.DialOption{grpc.WithTransportCredentials(creds)}), - server.RegisterMockHandlerFromEndpoint(ctx, mux, gRPCServerAddr, []grpc.DialOption{grpc.WithTransportCredentials(creds)})) + server.RegisterMockHandlerFromEndpoint(ctx, mux, gRPCServerAddr, []grpc.DialOption{grpc.WithTransportCredentials(creds)}), + server.RegisterDataServerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, []grpc.DialOption{grpc.WithTransportCredentials(creds)})) } else { + dialOption := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} err = errors.Join( - server.RegisterRunnerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}), - server.RegisterMockHandlerFromEndpoint(ctx, mux, gRPCServerAddr, []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())})) + server.RegisterRunnerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, dialOption), + server.RegisterMockHandlerFromEndpoint(ctx, mux, gRPCServerAddr, dialOption), + server.RegisterDataServerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, dialOption)) } if err == nil { diff --git a/console/atest-ui/src/App.vue b/console/atest-ui/src/App.vue index 5132e9ff0..0f051aa6d 100644 --- a/console/atest-ui/src/App.vue +++ b/console/atest-ui/src/App.vue @@ -7,6 +7,7 @@ import { Share, ArrowDown, Guide, + DataAnalysis } from '@element-plus/icons-vue' import { ref, watch } from 'vue' import { API } from './views/net' @@ -17,6 +18,7 @@ import MockManager from './views/MockManager.vue' import StoreManager from './views/StoreManager.vue' import SecretManager from './views/SecretManager.vue' import WelcomePage from './views/WelcomePage.vue' +import DataManager from './views/DataManager.vue' import { useI18n } from 'vue-i18n' const { t, locale: i18nLocale } = useI18n() @@ -114,6 +116,10 @@ const toHistoryPanel = ({ ID: selectID, panelName: historyPanelName }) => { + + + + @@ -142,6 +148,7 @@ const toHistoryPanel = ({ ID: selectID, panelName: historyPanelName }) => { + diff --git a/console/atest-ui/src/locales/en.json b/console/atest-ui/src/locales/en.json index 9c93a0afd..002dfe7bb 100644 --- a/console/atest-ui/src/locales/en.json +++ b/console/atest-ui/src/locales/en.json @@ -50,7 +50,8 @@ "functionQuery": "Functions Query", "output": "Output", "proxy": "Proxy", - "secure": "Secure" + "secure": "Secure", + "data": "Data" }, "tip": { "filter": "Filter Keyword", diff --git a/console/atest-ui/src/locales/zh.json b/console/atest-ui/src/locales/zh.json index 381c69d56..577a668df 100644 --- a/console/atest-ui/src/locales/zh.json +++ b/console/atest-ui/src/locales/zh.json @@ -45,7 +45,8 @@ "functionQuery": "函数查询", "output": "输出", "proxy": "代理", - "secure": "安全" + "secure": "安全", + "data": "数据" }, "tip": { "filter": "过滤", diff --git a/console/atest-ui/src/views/DataManager.vue b/console/atest-ui/src/views/DataManager.vue new file mode 100644 index 000000000..2005c7ded --- /dev/null +++ b/console/atest-ui/src/views/DataManager.vue @@ -0,0 +1,132 @@ + + + diff --git a/console/atest-ui/src/views/net.ts b/console/atest-ui/src/views/net.ts index 4ef085cab..9705caac4 100644 --- a/console/atest-ui/src/views/net.ts +++ b/console/atest-ui/src/views/net.ts @@ -773,6 +773,29 @@ var SBOM = (callback: (d: any) => void) => { .then(callback) } +var DataQuery = (store: string, kind: string, query: string, callback: (d: any) => void, errHandler: (d: any) => void) => { + const queryObj = {} + switch (kind) { + case 'atest-store-orm': + queryObj['sql'] = query; + break; + case 'atest-store-etcd': + queryObj['key'] = query; + break; + } + const requestOptions = { + method: 'POST', + headers: { + 'X-Store-Name': store + }, + body: JSON.stringify(queryObj) + } + fetch(`/api/v1/data/query`, requestOptions) + .then(DefaultResponseProcess) + .then(callback) + .catch(errHandler) +} + export const API = { DefaultResponseProcess, GetVersion, @@ -785,6 +808,6 @@ export const API = { FunctionsQuery, GetSecrets, DeleteSecret, CreateOrUpdateSecret, GetSuggestedAPIs, - ReloadMockServer, GetMockConfig, SBOM, + ReloadMockServer, GetMockConfig, SBOM, DataQuery, getToken } diff --git a/extensions/README.md b/extensions/README.md index 497a631ec..453ecf3c1 100644 --- a/extensions/README.md +++ b/extensions/README.md @@ -1,34 +1,34 @@ -Ports in extensions: - -| Type | Name | Port | -|------|------|------| -| Store | [orm](https://github.com/LinuxSuRen/atest-ext-store-orm) | 4071 | -| Store | [s3](https://github.com/LinuxSuRen/atest-ext-store-s3) | 4072 | -| Store | [etcd](https://github.com/LinuxSuRen/atest-ext-store-etcd) | 4073 | -| Store | [git](https://github.com/LinuxSuRen/atest-ext-store-git) | 4074 | -| Store | [mongodb](https://github.com/LinuxSuRen/atest-ext-store-mongodb) | 4075 | -| Monitor | [docker-monitor](https://github.com/LinuxSuRen/atest-ext-monitor-docker) | | -| Agent | [collector](https://github.com/LinuxSuRen/atest-ext-collector) | | -| Secret | [Vault](https://github.com/LinuxSuRen/api-testing-vault-extension) | | - -## Contribute a new extension - -* First, create a repository. And please keep the same naming convertion. -* Second, implement the `Loader` gRPC service which defined by [this proto](../pkg/testing/remote/loader.proto). -* Finally, add the extension's name into function [SupportedExtensions](../console/atest-ui/src/views/store.ts). - -## Naming conventions -Please follow the following conventions if you want to add a new store extension: - -`store-xxx` - -`xxx` should be a type of a backend storage. - -## Test - -First, build and copy the binary file into the system path. You can run the following -command in the root directory of this project: - -```shell -make build-ext-etcd copy-ext -``` +Ports in extensions: + +| Type | Name | Port | +|------|------|------| +| Store | [orm](https://github.com/LinuxSuRen/atest-ext-store-orm) | 4071 | +| Store | [s3](https://github.com/LinuxSuRen/atest-ext-store-s3) | 4072 | +| Store | [etcd](https://github.com/LinuxSuRen/atest-ext-store-etcd) | 4073 | +| Store | [git](https://github.com/LinuxSuRen/atest-ext-store-git) | 4074 | +| Store | [mongodb](https://github.com/LinuxSuRen/atest-ext-store-mongodb) | 4075 | +| Monitor | [docker-monitor](https://github.com/LinuxSuRen/atest-ext-monitor-docker) | | +| Agent | [collector](https://github.com/LinuxSuRen/atest-ext-collector) | | +| Secret | [Vault](https://github.com/LinuxSuRen/api-testing-vault-extension) | | + +## Contribute a new extension + +* First, create a repository. And please keep the same naming convertion. +* Second, implement the `Loader` gRPC service which defined by [this proto](../pkg/testing/remote/loader.proto). +* Finally, add the extension's name into function [SupportedExtensions](../console/atest-ui/src/views/store.ts). + +## Naming conventions +Please follow the following conventions if you want to add a new store extension: + +`store-xxx` + +`xxx` should be a type of a backend storage. + +## Test + +First, build and copy the binary file into the system path. You can run the following +command in the root directory of this project: + +```shell +make build-ext-etcd copy-ext +``` diff --git a/pkg/mock/in_memory.go b/pkg/mock/in_memory.go index f397e5ade..9ea8337c8 100644 --- a/pkg/mock/in_memory.go +++ b/pkg/mock/in_memory.go @@ -453,10 +453,15 @@ func runWebhook(ctx context.Context, objCtx interface{}, wh *Webhook) (err error req.Header.Set(k, v) } + memLogger.Info("send webhook request", "api", api) resp, err := client.Do(req) if err != nil { err = fmt.Errorf("error when sending webhook") } else { + if resp.StatusCode != http.StatusOK { + memLogger.Info("unexpected status", "code", resp.StatusCode) + } + data, _ := io.ReadAll(resp.Body) memLogger.V(7).Info("received from webhook", "code", resp.StatusCode, "response", string(data)) } diff --git a/pkg/runner/writer_templates/example.tpl b/pkg/runner/writer_templates/example.tpl index a1c35a1ee..741166c12 100644 --- a/pkg/runner/writer_templates/example.tpl +++ b/pkg/runner/writer_templates/example.tpl @@ -1,15 +1,15 @@ -[ -{{range $index, $result := .}} - { - "Name": "{{$result.Name}}", - "API": "{{$result.API}}", - "Count": {{$result.Count}}, - "Average": "{{$result.Average}}", - "Max": "{{$result.Max}}", - "Min": "{{$result.Min}}", - "QPS": {{$result.QPS}}, - "Error": {{$result.Error}}, - "LastErrorMessage": "{{$result.LastErrorMessage}}" - } -{{end}} -] +[ +{{range $index, $result := .}} + { + "Name": "{{$result.Name}}", + "API": "{{$result.API}}", + "Count": {{$result.Count}}, + "Average": "{{$result.Average}}", + "Max": "{{$result.Max}}", + "Min": "{{$result.Min}}", + "QPS": {{$result.QPS}}, + "Error": {{$result.Error}}, + "LastErrorMessage": "{{$result.LastErrorMessage}}" + } +{{end}} +] diff --git a/pkg/server/remote_server.go b/pkg/server/remote_server.go index 5fd2ad037..a12e3ff18 100644 --- a/pkg/server/remote_server.go +++ b/pkg/server/remote_server.go @@ -17,72 +17,73 @@ limitations under the License. package server import ( - "bytes" - "context" - "errors" - "fmt" - "io" - "mime" - "net/http" - "os" - "path/filepath" - reflect "reflect" - "regexp" - "strconv" - "strings" - "time" - - "github.com/expr-lang/expr/builtin" - - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" - - "github.com/linuxsuren/api-testing/pkg/util/home" - - "github.com/linuxsuren/api-testing/pkg/mock" - - _ "embed" - - "github.com/linuxsuren/api-testing/pkg/generator" - "github.com/linuxsuren/api-testing/pkg/logging" - "github.com/linuxsuren/api-testing/pkg/oauth" - "github.com/linuxsuren/api-testing/pkg/render" - "github.com/linuxsuren/api-testing/pkg/runner" - "github.com/linuxsuren/api-testing/pkg/testing" - "github.com/linuxsuren/api-testing/pkg/util" - "github.com/linuxsuren/api-testing/pkg/version" - "github.com/linuxsuren/api-testing/sample" - - "google.golang.org/grpc/metadata" - "gopkg.in/yaml.v3" + "bytes" + "context" + "errors" + "fmt" + "io" + "mime" + "net/http" + "os" + "path/filepath" + reflect "reflect" + "regexp" + "strconv" + "strings" + "time" + + "github.com/expr-lang/expr/builtin" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/linuxsuren/api-testing/pkg/util/home" + + "github.com/linuxsuren/api-testing/pkg/mock" + + _ "embed" + + "github.com/linuxsuren/api-testing/pkg/generator" + "github.com/linuxsuren/api-testing/pkg/logging" + "github.com/linuxsuren/api-testing/pkg/oauth" + "github.com/linuxsuren/api-testing/pkg/render" + "github.com/linuxsuren/api-testing/pkg/runner" + "github.com/linuxsuren/api-testing/pkg/testing" + "github.com/linuxsuren/api-testing/pkg/util" + "github.com/linuxsuren/api-testing/pkg/version" + "github.com/linuxsuren/api-testing/sample" + + "google.golang.org/grpc/metadata" + "gopkg.in/yaml.v3" ) var ( - remoteServerLogger = logging.DefaultLogger(logging.LogLevelInfo).WithName("remote_server") - GrpcMaxRecvMsgSize int + remoteServerLogger = logging.DefaultLogger(logging.LogLevelInfo).WithName("remote_server") + GrpcMaxRecvMsgSize int ) type server struct { - UnimplementedRunnerServer - loader testing.Writer - storeWriterFactory testing.StoreWriterFactory - configDir string - storeExtMgr ExtManager + UnimplementedRunnerServer + UnimplementedDataServerServer + loader testing.Writer + storeWriterFactory testing.StoreWriterFactory + configDir string + storeExtMgr ExtManager - secretServer SecretServiceServer + secretServer SecretServiceServer - grpcMaxRecvMsgSize int + grpcMaxRecvMsgSize int } type SecretServiceServer interface { - GetSecrets(context.Context, *Empty) (*Secrets, error) - CreateSecret(context.Context, *Secret) (*CommonResult, error) - DeleteSecret(context.Context, *Secret) (*CommonResult, error) - UpdateSecret(context.Context, *Secret) (*CommonResult, error) + GetSecrets(context.Context, *Empty) (*Secrets, error) + CreateSecret(context.Context, *Secret) (*CommonResult, error) + DeleteSecret(context.Context, *Secret) (*CommonResult, error) + UpdateSecret(context.Context, *Secret) (*CommonResult, error) } type SecertServiceGetable interface { - GetSecret(context.Context, *Secret) (*Secret, error) + GetSecret(context.Context, *Secret) (*Secret, error) } type fakeSecretServer struct{} @@ -90,1306 +91,1326 @@ type fakeSecretServer struct{} var errNoSecretService = errors.New("no secret service found") func (f *fakeSecretServer) GetSecrets(ctx context.Context, in *Empty) (reply *Secrets, err error) { - err = errNoSecretService - return + err = errNoSecretService + return } func (f *fakeSecretServer) CreateSecret(ctx context.Context, in *Secret) (reply *CommonResult, err error) { - err = errNoSecretService - return + err = errNoSecretService + return } func (f *fakeSecretServer) DeleteSecret(ctx context.Context, in *Secret) (reply *CommonResult, err error) { - err = errNoSecretService - return + err = errNoSecretService + return } func (f *fakeSecretServer) UpdateSecret(ctx context.Context, in *Secret) (reply *CommonResult, err error) { - err = errNoSecretService - return + err = errNoSecretService + return } // NewRemoteServer creates a remote server instance func NewRemoteServer(loader testing.Writer, storeWriterFactory testing.StoreWriterFactory, secretServer SecretServiceServer, storeExtMgr ExtManager, configDir string, grpcMaxRecvMsgSize int) RunnerServer { - if secretServer == nil { - secretServer = &fakeSecretServer{} - } - GrpcMaxRecvMsgSize = grpcMaxRecvMsgSize - return &server{ - loader: loader, - storeWriterFactory: storeWriterFactory, - configDir: configDir, - secretServer: secretServer, - storeExtMgr: storeExtMgr, - grpcMaxRecvMsgSize: grpcMaxRecvMsgSize, - } + if secretServer == nil { + secretServer = &fakeSecretServer{} + } + GrpcMaxRecvMsgSize = grpcMaxRecvMsgSize + return &server{ + loader: loader, + storeWriterFactory: storeWriterFactory, + configDir: configDir, + secretServer: secretServer, + storeExtMgr: storeExtMgr, + grpcMaxRecvMsgSize: grpcMaxRecvMsgSize, + } } func withDefaultValue(old, defVal any) any { - if old == "" || old == nil { - old = defVal - } - return old + if old == "" || old == nil { + old = defVal + } + return old } func parseSuiteWithItems(data []byte) (suite *testing.TestSuite, err error) { - suite, err = testing.ParseFromData(data) - if err == nil && (suite == nil || suite.Items == nil) { - err = errNoTestSuiteFound - } - return + suite, err = testing.ParseFromData(data) + if err == nil && (suite == nil || suite.Items == nil) { + err = errNoTestSuiteFound + } + return } func (s *server) getSuiteFromTestTask(task *TestTask) (suite *testing.TestSuite, err error) { - switch task.Kind { - case "suite": - suite, err = parseSuiteWithItems([]byte(task.Data)) - case "testcase": - var testCase *testing.TestCase - if testCase, err = testing.ParseTestCaseFromData([]byte(task.Data)); err != nil { - return - } - suite = &testing.TestSuite{ - Items: []testing.TestCase{*testCase}, - } - case "testcaseInSuite": - suite, err = parseSuiteWithItems([]byte(task.Data)) - if err != nil { - return - } - - var targetTestcase *testing.TestCase - for _, item := range suite.Items { - if item.Name == task.CaseName { - targetTestcase = &item - break - } - } - - if targetTestcase != nil { - parentCases := findParentTestCases(targetTestcase, suite) - remoteServerLogger.Info("find parent cases", "num", len(parentCases)) - suite.Items = append(parentCases, *targetTestcase) - } else { - err = fmt.Errorf("cannot found testcase %s", task.CaseName) - } - default: - err = fmt.Errorf("not support '%s'", task.Kind) - } - return + switch task.Kind { + case "suite": + suite, err = parseSuiteWithItems([]byte(task.Data)) + case "testcase": + var testCase *testing.TestCase + if testCase, err = testing.ParseTestCaseFromData([]byte(task.Data)); err != nil { + return + } + suite = &testing.TestSuite{ + Items: []testing.TestCase{*testCase}, + } + case "testcaseInSuite": + suite, err = parseSuiteWithItems([]byte(task.Data)) + if err != nil { + return + } + + var targetTestcase *testing.TestCase + for _, item := range suite.Items { + if item.Name == task.CaseName { + targetTestcase = &item + break + } + } + + if targetTestcase != nil { + parentCases := findParentTestCases(targetTestcase, suite) + remoteServerLogger.Info("find parent cases", "num", len(parentCases)) + suite.Items = append(parentCases, *targetTestcase) + } else { + err = fmt.Errorf("cannot found testcase %s", task.CaseName) + } + default: + err = fmt.Errorf("not support '%s'", task.Kind) + } + return } func resetEnv(oldEnv map[string]string) { - for key, val := range oldEnv { - os.Setenv(key, val) - } + for key, val := range oldEnv { + os.Setenv(key, val) + } } func (s *server) getLoader(ctx context.Context) (loader testing.Writer) { - var ok bool - loader = s.loader - - var mdd metadata.MD - if mdd, ok = metadata.FromIncomingContext(ctx); ok { - storeNameMeta := mdd.Get(HeaderKeyStoreName) - if len(storeNameMeta) > 0 { - storeName := strings.TrimSpace(storeNameMeta[0]) - if storeName == "local" || storeName == "" { - return - } - - var err error - if loader, err = s.getLoaderByStoreName(storeName); err != nil { - remoteServerLogger.Info("failed to get loader", "name", storeName, "error", err) - loader = testing.NewNonWriter() - } - } - } - return + var ok bool + loader = s.loader + + var mdd metadata.MD + if mdd, ok = metadata.FromIncomingContext(ctx); ok { + storeNameMeta := mdd.Get(HeaderKeyStoreName) + if len(storeNameMeta) > 0 { + storeName := strings.TrimSpace(storeNameMeta[0]) + if storeName == "local" || storeName == "" { + return + } + + var err error + if loader, err = s.getLoaderByStoreName(storeName); err != nil { + remoteServerLogger.Info("failed to get loader", "name", storeName, "error", err) + loader = testing.NewNonWriter() + } + } + } + return } // Run start to run the test task func (s *server) Run(ctx context.Context, task *TestTask) (reply *TestResult, err error) { - task.Level = withDefaultValue(task.Level, "info").(string) - task.Env = withDefaultValue(task.Env, map[string]string{}).(map[string]string) - - var suite *testing.TestSuite - // TODO may not safe in multiple threads - oldEnv := map[string]string{} - for key, val := range task.Env { - oldEnv[key] = os.Getenv(key) - os.Setenv(key, val) - } - - defer func() { - resetEnv(oldEnv) - }() - - if suite, err = s.getSuiteFromTestTask(task); err != nil { - return - } - - remoteServerLogger.Info("prepare to run", "name", suite.Name, " with level: ", task.Level) - remoteServerLogger.Info("task kind to run", "kind", task.Kind, "lens", len(suite.Items)) - dataContext := map[string]interface{}{} - - if err = suite.Render(dataContext); err != nil { - reply.Error = err.Error() - err = nil - return - } - // inject the parameters from input - if len(task.Parameters) > 0 { - dataContext[testing.ContextKeyGlobalParam] = pairToMap(task.Parameters) - } - - buf := new(bytes.Buffer) - reply = &TestResult{} - - for _, testCase := range suite.Items { - suiteRunner := runner.GetTestSuiteRunner(suite) - suiteRunner.WithOutputWriter(buf) - suiteRunner.WithWriteLevel(task.Level) - suiteRunner.WithSecure(suite.Spec.Secure) - suiteRunner.WithSuite(suite) - - // reuse the API prefix - testCase.Request.RenderAPI(suite.API) - historyHeader := make(map[string]string) - for k, v := range testCase.Request.Header { - historyHeader[k] = v - } - - output, testErr := suiteRunner.RunTestCase(&testCase, dataContext, ctx) - if getter, ok := suiteRunner.(runner.ResponseRecord); ok { - resp := getter.GetResponseRecord() - //resp, err = runner.HandleLargeResponseBody(resp, suite.Name, testCase.Name) - reply.TestCaseResult = append(reply.TestCaseResult, &TestCaseResult{ - StatusCode: int32(resp.StatusCode), - Body: resp.Body, - Header: mapToPair(resp.Header), - Id: testCase.ID, - Output: buf.String(), - }) - } - - if testErr == nil { - dataContext[testCase.Name] = output - } else { - reply.Error = testErr.Error() - break - } - // create history record - go func(historyHeader map[string]string) { - loader := s.getLoader(ctx) - defer loader.Close() - for _, testCaseResult := range reply.TestCaseResult { - err = loader.CreateHistoryTestCase(ToNormalTestCaseResult(testCaseResult), suite, historyHeader) - if err != nil { - remoteServerLogger.Info("error create history") - } - } - }(historyHeader) - } - - if reply.Error != "" { - fmt.Fprintln(buf, reply.Error) - } - reply.Message = buf.String() - return + task.Level = withDefaultValue(task.Level, "info").(string) + task.Env = withDefaultValue(task.Env, map[string]string{}).(map[string]string) + + var suite *testing.TestSuite + // TODO may not safe in multiple threads + oldEnv := map[string]string{} + for key, val := range task.Env { + oldEnv[key] = os.Getenv(key) + os.Setenv(key, val) + } + + defer func() { + resetEnv(oldEnv) + }() + + if suite, err = s.getSuiteFromTestTask(task); err != nil { + return + } + + remoteServerLogger.Info("prepare to run", "name", suite.Name, " with level: ", task.Level) + remoteServerLogger.Info("task kind to run", "kind", task.Kind, "lens", len(suite.Items)) + dataContext := map[string]interface{}{} + + if err = suite.Render(dataContext); err != nil { + reply.Error = err.Error() + err = nil + return + } + // inject the parameters from input + if len(task.Parameters) > 0 { + dataContext[testing.ContextKeyGlobalParam] = pairToMap(task.Parameters) + } + + buf := new(bytes.Buffer) + reply = &TestResult{} + + for _, testCase := range suite.Items { + suiteRunner := runner.GetTestSuiteRunner(suite) + suiteRunner.WithOutputWriter(buf) + suiteRunner.WithWriteLevel(task.Level) + suiteRunner.WithSecure(suite.Spec.Secure) + suiteRunner.WithSuite(suite) + + // reuse the API prefix + testCase.Request.RenderAPI(suite.API) + historyHeader := make(map[string]string) + for k, v := range testCase.Request.Header { + historyHeader[k] = v + } + + output, testErr := suiteRunner.RunTestCase(&testCase, dataContext, ctx) + if getter, ok := suiteRunner.(runner.ResponseRecord); ok { + resp := getter.GetResponseRecord() + //resp, err = runner.HandleLargeResponseBody(resp, suite.Name, testCase.Name) + reply.TestCaseResult = append(reply.TestCaseResult, &TestCaseResult{ + StatusCode: int32(resp.StatusCode), + Body: resp.Body, + Header: mapToPair(resp.Header), + Id: testCase.ID, + Output: buf.String(), + }) + } + + if testErr == nil { + dataContext[testCase.Name] = output + } else { + reply.Error = testErr.Error() + break + } + // create history record + go func(historyHeader map[string]string) { + loader := s.getLoader(ctx) + defer loader.Close() + for _, testCaseResult := range reply.TestCaseResult { + err = loader.CreateHistoryTestCase(ToNormalTestCaseResult(testCaseResult), suite, historyHeader) + if err != nil { + remoteServerLogger.Info("error create history") + } + } + }(historyHeader) + } + + if reply.Error != "" { + fmt.Fprintln(buf, reply.Error) + } + reply.Message = buf.String() + return } func (s *server) BatchRun(srv Runner_BatchRunServer) (err error) { - ctx := srv.Context() - for { - select { - case <-ctx.Done(): - return ctx.Err() - default: - var in *BatchTestTask - in, err = srv.Recv() - if err != nil { - if err == io.EOF { - return nil - } - return err - } - - for i := 0; i < int(in.Count); i++ { - var reply *TestCaseResult - if reply, err = s.RunTestCase(ctx, &TestCaseIdentity{ - Suite: in.SuiteName, - Testcase: in.CaseName, - }); err != nil { - return - } - - if err = srv.Send(&TestResult{ - TestCaseResult: []*TestCaseResult{reply}, - Error: reply.Error, - }); err != nil { - return err - } - - var interval string - if interval, err = render.Render("batch run interval", in.Interval, nil); err != nil { - return - } - - var duration time.Duration - if duration, err = time.ParseDuration(interval); err != nil { - return - } - time.Sleep(duration) - } - } - } + ctx := srv.Context() + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + var in *BatchTestTask + in, err = srv.Recv() + if err != nil { + if err == io.EOF { + return nil + } + return err + } + + for i := 0; i < int(in.Count); i++ { + var reply *TestCaseResult + if reply, err = s.RunTestCase(ctx, &TestCaseIdentity{ + Suite: in.SuiteName, + Testcase: in.CaseName, + }); err != nil { + return + } + + if err = srv.Send(&TestResult{ + TestCaseResult: []*TestCaseResult{reply}, + Error: reply.Error, + }); err != nil { + return err + } + + var interval string + if interval, err = render.Render("batch run interval", in.Interval, nil); err != nil { + return + } + + var duration time.Duration + if duration, err = time.ParseDuration(interval); err != nil { + return + } + time.Sleep(duration) + } + } + } } func (s *server) DownloadResponseFile(ctx context.Context, in *TestCase) (reply *FileData, err error) { - if in.Response != nil { - tempFileName := in.Response.Body - if tempFileName == "" { - return nil, errors.New("file name is empty") - } - - tempDir := os.TempDir() - filePath := filepath.Join(tempDir, tempFileName) - if filepath.Clean(filePath) != filepath.Join(tempDir, filepath.Base(tempFileName)) { - return nil, errors.New("invalid file path") - } - - fmt.Println("get file from", filePath) - fileContent, err := os.ReadFile(filePath) - if err != nil { - return nil, fmt.Errorf("failed to read file: %s", filePath) - } - - mimeType := mime.TypeByExtension(filepath.Ext(filePath)) - if mimeType == "" { - mimeType = "application/octet-stream" - } - - filename := filepath.Base(filePath) - // try to get the original filename - var originalFileName []byte - if originalFileName, err = os.ReadFile(filePath + "name"); err == nil && len(originalFileName) > 0 { - filename = string(originalFileName) - } - - reply = &FileData{ - Data: fileContent, - ContentType: mimeType, - Filename: filename, - } - - return reply, nil - } else { - return reply, errors.New("response is empty") - } + if in.Response != nil { + tempFileName := in.Response.Body + if tempFileName == "" { + return nil, errors.New("file name is empty") + } + + tempDir := os.TempDir() + filePath := filepath.Join(tempDir, tempFileName) + if filepath.Clean(filePath) != filepath.Join(tempDir, filepath.Base(tempFileName)) { + return nil, errors.New("invalid file path") + } + + fmt.Println("get file from", filePath) + fileContent, err := os.ReadFile(filePath) + if err != nil { + return nil, fmt.Errorf("failed to read file: %s", filePath) + } + + mimeType := mime.TypeByExtension(filepath.Ext(filePath)) + if mimeType == "" { + mimeType = "application/octet-stream" + } + + filename := filepath.Base(filePath) + // try to get the original filename + var originalFileName []byte + if originalFileName, err = os.ReadFile(filePath + "name"); err == nil && len(originalFileName) > 0 { + filename = string(originalFileName) + } + + reply = &FileData{ + Data: fileContent, + ContentType: mimeType, + Filename: filename, + } + + return reply, nil + } else { + return reply, errors.New("response is empty") + } } func (s *server) RunTestSuite(srv Runner_RunTestSuiteServer) (err error) { - ctx := srv.Context() - for { - select { - case <-ctx.Done(): - return ctx.Err() - default: - var in *TestSuiteIdentity - in, err = srv.Recv() - if err != nil { - if err == io.EOF { - return nil - } - return err - } - - var suite *Suite - if suite, err = s.ListTestCase(ctx, in); err != nil { - return - } - - for _, item := range suite.Items { - var reply *TestCaseResult - if reply, err = s.RunTestCase(ctx, &TestCaseIdentity{ - Suite: in.Name, - Testcase: item.Name, - }); err != nil { - return - } - - if err = srv.Send(&TestResult{ - TestCaseResult: []*TestCaseResult{reply}, - Error: reply.Error, - }); err != nil { - return err - } - } - } - } + ctx := srv.Context() + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + var in *TestSuiteIdentity + in, err = srv.Recv() + if err != nil { + if err == io.EOF { + return nil + } + return err + } + + var suite *Suite + if suite, err = s.ListTestCase(ctx, in); err != nil { + return + } + + for _, item := range suite.Items { + var reply *TestCaseResult + if reply, err = s.RunTestCase(ctx, &TestCaseIdentity{ + Suite: in.Name, + Testcase: item.Name, + }); err != nil { + return + } + + if err = srv.Send(&TestResult{ + TestCaseResult: []*TestCaseResult{reply}, + Error: reply.Error, + }); err != nil { + return err + } + } + } + } } // GetVersion returns the version func (s *server) GetVersion(ctx context.Context, in *Empty) (reply *Version, err error) { - reply = &Version{ - Version: version.GetVersion(), - Date: version.GetDate(), - Commit: version.GetCommit(), - } - return + reply = &Version{ + Version: version.GetVersion(), + Date: version.GetDate(), + Commit: version.GetCommit(), + } + return } func (s *server) GetSuites(ctx context.Context, in *Empty) (reply *Suites, err error) { - loader := s.getLoader(ctx) - defer loader.Close() - reply = &Suites{ - Data: make(map[string]*Items), - } - - var suites []testing.TestSuite - if suites, err = loader.ListTestSuite(); err == nil && suites != nil { - for _, suite := range suites { - items := &Items{} - for _, item := range suite.Items { - items.Data = append(items.Data, item.Name) - } - items.Kind = suite.Spec.Kind - reply.Data[suite.Name] = items - } - } - - return + loader := s.getLoader(ctx) + defer loader.Close() + reply = &Suites{ + Data: make(map[string]*Items), + } + + var suites []testing.TestSuite + if suites, err = loader.ListTestSuite(); err == nil && suites != nil { + for _, suite := range suites { + items := &Items{} + for _, item := range suite.Items { + items.Data = append(items.Data, item.Name) + } + items.Kind = suite.Spec.Kind + reply.Data[suite.Name] = items + } + } + + return } func (s *server) GetHistorySuites(ctx context.Context, in *Empty) (reply *HistorySuites, err error) { - loader := s.getLoader(ctx) - defer loader.Close() - reply = &HistorySuites{ - Data: make(map[string]*HistoryItems), - } - - var suites []testing.HistoryTestSuite - if suites, err = loader.ListHistoryTestSuite(); err == nil && suites != nil { - for _, suite := range suites { - items := &HistoryItems{} - for _, item := range suite.Items { - data := &HistoryCaseIdentity{ - ID: item.ID, - HistorySuiteName: item.HistorySuiteName, - Kind: item.SuiteSpec.Kind, - Suite: item.SuiteName, - Testcase: item.CaseName, - } - items.Data = append(items.Data, data) - } - reply.Data[suite.HistorySuiteName] = items - } - } - return + loader := s.getLoader(ctx) + defer loader.Close() + reply = &HistorySuites{ + Data: make(map[string]*HistoryItems), + } + + var suites []testing.HistoryTestSuite + if suites, err = loader.ListHistoryTestSuite(); err == nil && suites != nil { + for _, suite := range suites { + items := &HistoryItems{} + for _, item := range suite.Items { + data := &HistoryCaseIdentity{ + ID: item.ID, + HistorySuiteName: item.HistorySuiteName, + Kind: item.SuiteSpec.Kind, + Suite: item.SuiteName, + Testcase: item.CaseName, + } + items.Data = append(items.Data, data) + } + reply.Data[suite.HistorySuiteName] = items + } + } + return } func (s *server) CreateTestSuite(ctx context.Context, in *TestSuiteIdentity) (reply *HelloReply, err error) { - reply = &HelloReply{} - loader := s.getLoader(ctx) - defer loader.Close() - if loader == nil { - reply.Error = "no loader found" - } else { - if err = loader.CreateSuite(in.Name, in.Api); err == nil { - toUpdate := testing.TestSuite{ - Name: in.Name, - API: in.Api, - Spec: testing.APISpec{ - Kind: in.Kind, - }, - } - - switch strings.ToLower(in.Kind) { - case "grpc", "trpc": - toUpdate.Spec.RPC = &testing.RPCDesc{} - } - - err = loader.UpdateSuite(toUpdate) - } - } - return + reply = &HelloReply{} + loader := s.getLoader(ctx) + defer loader.Close() + if loader == nil { + reply.Error = "no loader found" + } else { + if err = loader.CreateSuite(in.Name, in.Api); err == nil { + toUpdate := testing.TestSuite{ + Name: in.Name, + API: in.Api, + Spec: testing.APISpec{ + Kind: in.Kind, + }, + } + + switch strings.ToLower(in.Kind) { + case "grpc", "trpc": + toUpdate.Spec.RPC = &testing.RPCDesc{} + } + + err = loader.UpdateSuite(toUpdate) + } + } + return } func (s *server) ImportTestSuite(ctx context.Context, in *TestSuiteSource) (result *CommonResult, err error) { - result = &CommonResult{} - var dataImporter generator.Importer - switch in.Kind { - case "postman": - dataImporter = generator.NewPostmanImporter() - case "native", "": - dataImporter = generator.NewNativeImporter() - default: - result.Success = false - result.Message = fmt.Sprintf("not support kind: %s", in.Kind) - return - } - - remoteServerLogger.Logger.Info("import test suite", "kind", in.Kind, "url", in.Url) - var suite *testing.TestSuite - if in.Url != "" { - suite, err = dataImporter.ConvertFromURL(in.Url) - } else if in.Data != "" { - suite, err = dataImporter.Convert([]byte(in.Data)) - } else { - err = errors.New("url or data is required") - } - - if err != nil { - result.Success = false - result.Message = err.Error() - return - } - - loader := s.getLoader(ctx) - defer loader.Close() - - if err = loader.CreateSuite(suite.Name, suite.API); err != nil { - return - } - - for _, item := range suite.Items { - if err = loader.CreateTestCase(suite.Name, item); err != nil { - break - } - } - result.Success = true - return + result = &CommonResult{} + var dataImporter generator.Importer + switch in.Kind { + case "postman": + dataImporter = generator.NewPostmanImporter() + case "native", "": + dataImporter = generator.NewNativeImporter() + default: + result.Success = false + result.Message = fmt.Sprintf("not support kind: %s", in.Kind) + return + } + + remoteServerLogger.Logger.Info("import test suite", "kind", in.Kind, "url", in.Url) + var suite *testing.TestSuite + if in.Url != "" { + suite, err = dataImporter.ConvertFromURL(in.Url) + } else if in.Data != "" { + suite, err = dataImporter.Convert([]byte(in.Data)) + } else { + err = errors.New("url or data is required") + } + + if err != nil { + result.Success = false + result.Message = err.Error() + return + } + + loader := s.getLoader(ctx) + defer loader.Close() + + if err = loader.CreateSuite(suite.Name, suite.API); err != nil { + return + } + + for _, item := range suite.Items { + if err = loader.CreateTestCase(suite.Name, item); err != nil { + break + } + } + result.Success = true + return } func (s *server) GetTestSuite(ctx context.Context, in *TestSuiteIdentity) (result *TestSuite, err error) { - loader := s.getLoader(ctx) - defer loader.Close() - var suite *testing.TestSuite - if suite, _, err = loader.GetSuite(in.Name); err == nil && suite != nil { - result = ToGRPCSuite(suite) - } - return + loader := s.getLoader(ctx) + defer loader.Close() + var suite *testing.TestSuite + if suite, _, err = loader.GetSuite(in.Name); err == nil && suite != nil { + result = ToGRPCSuite(suite) + } + return } func (s *server) UpdateTestSuite(ctx context.Context, in *TestSuite) (reply *HelloReply, err error) { - reply = &HelloReply{} - loader := s.getLoader(ctx) - defer loader.Close() - err = loader.UpdateSuite(*ToNormalSuite(in)) - return + reply = &HelloReply{} + loader := s.getLoader(ctx) + defer loader.Close() + err = loader.UpdateSuite(*ToNormalSuite(in)) + return } func (s *server) DeleteTestSuite(ctx context.Context, in *TestSuiteIdentity) (reply *HelloReply, err error) { - reply = &HelloReply{} - loader := s.getLoader(ctx) - defer loader.Close() - err = loader.DeleteSuite(in.Name) - return + reply = &HelloReply{} + loader := s.getLoader(ctx) + defer loader.Close() + err = loader.DeleteSuite(in.Name) + return } func (s *server) DuplicateTestSuite(ctx context.Context, in *TestSuiteDuplicate) (reply *HelloReply, err error) { - reply = &HelloReply{} - loader := s.getLoader(ctx) - defer loader.Close() - - if in.SourceSuiteName == in.TargetSuiteName { - reply.Error = "source and target suite name should be different" - return - } - - var suite testing.TestSuite - if suite, err = loader.GetTestSuite(in.SourceSuiteName, true); err == nil { - suite.Name = in.TargetSuiteName - if err = loader.CreateSuite(suite.Name, suite.API); err == nil { - for _, testCase := range suite.Items { - if err = loader.CreateTestCase(suite.Name, testCase); err != nil { - break - } - } - } - } - return + reply = &HelloReply{} + loader := s.getLoader(ctx) + defer loader.Close() + + if in.SourceSuiteName == in.TargetSuiteName { + reply.Error = "source and target suite name should be different" + return + } + + var suite testing.TestSuite + if suite, err = loader.GetTestSuite(in.SourceSuiteName, true); err == nil { + suite.Name = in.TargetSuiteName + if err = loader.CreateSuite(suite.Name, suite.API); err == nil { + for _, testCase := range suite.Items { + if err = loader.CreateTestCase(suite.Name, testCase); err != nil { + break + } + } + } + } + return } func (s *server) RenameTestSuite(ctx context.Context, in *TestSuiteDuplicate) (reply *HelloReply, err error) { - reply = &HelloReply{} - loader := s.getLoader(ctx) - defer loader.Close() - err = loader.RenameTestSuite(in.SourceSuiteName, in.TargetSuiteName) - return + reply = &HelloReply{} + loader := s.getLoader(ctx) + defer loader.Close() + err = loader.RenameTestSuite(in.SourceSuiteName, in.TargetSuiteName) + return } func (s *server) ListTestCase(ctx context.Context, in *TestSuiteIdentity) (result *Suite, err error) { - var items []testing.TestCase - loader := s.getLoader(ctx) - defer loader.Close() - if items, err = loader.ListTestCase(in.Name); err == nil { - result = &Suite{} - for _, item := range items { - result.Items = append(result.Items, ToGRPCTestCase(item)) - } - } - return + var items []testing.TestCase + loader := s.getLoader(ctx) + defer loader.Close() + if items, err = loader.ListTestCase(in.Name); err == nil { + result = &Suite{} + for _, item := range items { + result.Items = append(result.Items, ToGRPCTestCase(item)) + } + } + return } func (s *server) GetTestSuiteYaml(ctx context.Context, in *TestSuiteIdentity) (reply *YamlData, err error) { - var data []byte - loader := s.getLoader(ctx) - defer loader.Close() - if data, err = loader.GetTestSuiteYaml(in.Name); err == nil { - reply = &YamlData{ - Data: data, - } - } - return + var data []byte + loader := s.getLoader(ctx) + defer loader.Close() + if data, err = loader.GetTestSuiteYaml(in.Name); err == nil { + reply = &YamlData{ + Data: data, + } + } + return } func (s *server) GetTestCase(ctx context.Context, in *TestCaseIdentity) (reply *TestCase, err error) { - var result testing.TestCase - loader := s.getLoader(ctx) - defer loader.Close() - if result, err = loader.GetTestCase(in.Suite, in.Testcase); err == nil { - reply = ToGRPCTestCase(result) + var result testing.TestCase + loader := s.getLoader(ctx) + defer loader.Close() + if result, err = loader.GetTestCase(in.Suite, in.Testcase); err == nil { + reply = ToGRPCTestCase(result) - var suite testing.TestSuite - if suite, err = loader.GetTestSuite(in.Suite, false); err == nil { - reply.Server = suite.API - } - } - return + var suite testing.TestSuite + if suite, err = loader.GetTestSuite(in.Suite, false); err == nil { + reply.Server = suite.API + } + } + return } func (s *server) GetHistoryTestCaseWithResult(ctx context.Context, in *HistoryTestCase) (reply *HistoryTestResult, err error) { - var result testing.HistoryTestResult - loader := s.getLoader(ctx) - defer loader.Close() - if result, err = loader.GetHistoryTestCaseWithResult(in.ID); err == nil { - reply = ToGRPCHistoryTestCaseResult(result) - } - return + var result testing.HistoryTestResult + loader := s.getLoader(ctx) + defer loader.Close() + if result, err = loader.GetHistoryTestCaseWithResult(in.ID); err == nil { + reply = ToGRPCHistoryTestCaseResult(result) + } + return } func (s *server) GetHistoryTestCase(ctx context.Context, in *HistoryTestCase) (reply *HistoryTestCase, err error) { - var result testing.HistoryTestCase - loader := s.getLoader(ctx) - defer loader.Close() - if result, err = loader.GetHistoryTestCase(in.ID); err == nil { - reply = ConvertToGRPCHistoryTestCase(result) - } - return + var result testing.HistoryTestCase + loader := s.getLoader(ctx) + defer loader.Close() + if result, err = loader.GetHistoryTestCase(in.ID); err == nil { + reply = ConvertToGRPCHistoryTestCase(result) + } + return } var ExecutionCountNum = promauto.NewCounter(prometheus.CounterOpts{ - Name: "atest_execution_count", - Help: "The total number of request execution", + Name: "atest_execution_count", + Help: "The total number of request execution", }) var ExecutionSuccessNum = promauto.NewCounter(prometheus.CounterOpts{ - Name: "atest_execution_success", - Help: "The total number of request execution success", + Name: "atest_execution_success", + Help: "The total number of request execution success", }) var ExecutionFailNum = promauto.NewCounter(prometheus.CounterOpts{ - Name: "atest_execution_fail", - Help: "The total number of request execution fail", + Name: "atest_execution_fail", + Help: "The total number of request execution fail", }) func (s *server) GetTestCaseAllHistory(ctx context.Context, in *TestCase) (result *HistoryTestCases, err error) { - var items []testing.HistoryTestCase - loader := s.getLoader(ctx) - defer loader.Close() - if items, err = loader.GetTestCaseAllHistory(in.SuiteName, in.Name); err == nil { - result = &HistoryTestCases{} - for _, item := range items { - result.Data = append(result.Data, ConvertToGRPCHistoryTestCase(item)) - } - } - return + var items []testing.HistoryTestCase + loader := s.getLoader(ctx) + defer loader.Close() + if items, err = loader.GetTestCaseAllHistory(in.SuiteName, in.Name); err == nil { + result = &HistoryTestCases{} + for _, item := range items { + result.Data = append(result.Data, ConvertToGRPCHistoryTestCase(item)) + } + } + return } func (s *server) RunTestCase(ctx context.Context, in *TestCaseIdentity) (result *TestCaseResult, err error) { - var targetTestSuite testing.TestSuite - ExecutionCountNum.Inc() - defer func() { - if result.Error == "" { - ExecutionSuccessNum.Inc() - } else { - ExecutionFailNum.Inc() - } - }() - - result = &TestCaseResult{} - loader := s.getLoader(ctx) - defer loader.Close() - targetTestSuite, err = loader.GetTestSuite(in.Suite, true) - if err != nil || targetTestSuite.Name == "" { - err = nil - result.Error = fmt.Sprintf("not found suite: %s", in.Suite) - return - } - - var data []byte - if data, err = yaml.Marshal(targetTestSuite); err == nil { - task := &TestTask{ - Kind: "testcaseInSuite", - Data: string(data), - CaseName: in.Testcase, - Level: "debug", - Parameters: in.Parameters, - } - - var reply *TestResult - var lastItem *TestCaseResult - if reply, err = s.Run(ctx, task); err == nil && len(reply.TestCaseResult) > 0 { - lastIndex := len(reply.TestCaseResult) - 1 - lastItem = reply.TestCaseResult[lastIndex] - - if len(lastItem.Body) > GrpcMaxRecvMsgSize { - e := "the HTTP response body exceeded the maximum message size limit received by the gRPC client" - result = &TestCaseResult{ - Output: reply.Message, - Error: e, - Body: "", - Header: lastItem.Header, - StatusCode: http.StatusOK, - } - return - } - - result = &TestCaseResult{ - Output: reply.Message, - Error: reply.Error, - Body: lastItem.Body, - Header: lastItem.Header, - StatusCode: lastItem.StatusCode, - } - } else if err != nil { - result.Error = err.Error() - } else { - result = &TestCaseResult{ - Output: reply.Message, - Error: reply.Error, - } - } - - if reply != nil { - result.Output = reply.Message - result.Error = reply.Error - } - if lastItem != nil { - result.Body = lastItem.Body - result.Header = lastItem.Header - result.StatusCode = lastItem.StatusCode - } - } - return + var targetTestSuite testing.TestSuite + ExecutionCountNum.Inc() + defer func() { + if result.Error == "" { + ExecutionSuccessNum.Inc() + } else { + ExecutionFailNum.Inc() + } + }() + + result = &TestCaseResult{} + loader := s.getLoader(ctx) + defer loader.Close() + targetTestSuite, err = loader.GetTestSuite(in.Suite, true) + if err != nil || targetTestSuite.Name == "" { + err = nil + result.Error = fmt.Sprintf("not found suite: %s", in.Suite) + return + } + + var data []byte + if data, err = yaml.Marshal(targetTestSuite); err == nil { + task := &TestTask{ + Kind: "testcaseInSuite", + Data: string(data), + CaseName: in.Testcase, + Level: "debug", + Parameters: in.Parameters, + } + + var reply *TestResult + var lastItem *TestCaseResult + if reply, err = s.Run(ctx, task); err == nil && len(reply.TestCaseResult) > 0 { + lastIndex := len(reply.TestCaseResult) - 1 + lastItem = reply.TestCaseResult[lastIndex] + + if len(lastItem.Body) > GrpcMaxRecvMsgSize { + e := "the HTTP response body exceeded the maximum message size limit received by the gRPC client" + result = &TestCaseResult{ + Output: reply.Message, + Error: e, + Body: "", + Header: lastItem.Header, + StatusCode: http.StatusOK, + } + return + } + + result = &TestCaseResult{ + Output: reply.Message, + Error: reply.Error, + Body: lastItem.Body, + Header: lastItem.Header, + StatusCode: lastItem.StatusCode, + } + } else if err != nil { + result.Error = err.Error() + } else { + result = &TestCaseResult{ + Output: reply.Message, + Error: reply.Error, + } + } + + if reply != nil { + result.Output = reply.Message + result.Error = reply.Error + } + if lastItem != nil { + result.Body = lastItem.Body + result.Header = lastItem.Header + result.StatusCode = lastItem.StatusCode + } + } + return } func mapInterToPair(data map[string]interface{}) (pairs []*Pair) { - pairs = make([]*Pair, 0) - for k, v := range data { - pairs = append(pairs, &Pair{ - Key: k, - Value: fmt.Sprintf("%v", v), - }) - } - return + pairs = make([]*Pair, 0) + for k, v := range data { + pairs = append(pairs, &Pair{ + Key: k, + Value: fmt.Sprintf("%v", v), + }) + } + return } func mapToPair(data map[string]string) (pairs []*Pair) { - pairs = make([]*Pair, 0) - for k, v := range data { - pairs = append(pairs, &Pair{ - Key: k, - Value: v, - }) - } - return + pairs = make([]*Pair, 0) + for k, v := range data { + pairs = append(pairs, &Pair{ + Key: k, + Value: v, + }) + } + return } func pairToInterMap(pairs []*Pair) (data map[string]interface{}) { - data = make(map[string]interface{}) - for _, pair := range pairs { - if pair.Key == "" { - continue - } - data[pair.Key] = pair.Value - } - return + data = make(map[string]interface{}) + for _, pair := range pairs { + if pair.Key == "" { + continue + } + data[pair.Key] = pair.Value + } + return } func pairToMap(pairs []*Pair) (data map[string]string) { - data = make(map[string]string) - for _, pair := range pairs { - if pair.Key == "" { - continue - } - data[pair.Key] = pair.Value - } - return + data = make(map[string]string) + for _, pair := range pairs { + if pair.Key == "" { + continue + } + data[pair.Key] = pair.Value + } + return } func convertConditionalVerify(verify []*ConditionalVerify) (result []testing.ConditionalVerify) { - if verify != nil { - result = make([]testing.ConditionalVerify, 0) + if verify != nil { + result = make([]testing.ConditionalVerify, 0) - for _, item := range verify { - result = append(result, testing.ConditionalVerify{ - Condition: item.Condition, - Verify: item.Verify, - }) - } - } - return + for _, item := range verify { + result = append(result, testing.ConditionalVerify{ + Condition: item.Condition, + Verify: item.Verify, + }) + } + } + return } func (s *server) CreateTestCase(ctx context.Context, in *TestCaseWithSuite) (reply *HelloReply, err error) { - reply = &HelloReply{} - if in.Data == nil { - err = errors.New("data is required") - } else { - loader := s.getLoader(ctx) - defer loader.Close() - err = loader.CreateTestCase(in.SuiteName, ToNormalTestCase(in.Data)) - } - return + reply = &HelloReply{} + if in.Data == nil { + err = errors.New("data is required") + } else { + loader := s.getLoader(ctx) + defer loader.Close() + err = loader.CreateTestCase(in.SuiteName, ToNormalTestCase(in.Data)) + } + return } func (s *server) UpdateTestCase(ctx context.Context, in *TestCaseWithSuite) (reply *HelloReply, err error) { - reply = &HelloReply{} - if in.Data == nil { - err = errors.New("data is required") - return - } - loader := s.getLoader(ctx) - defer loader.Close() - err = loader.UpdateTestCase(in.SuiteName, ToNormalTestCase(in.Data)) - return + reply = &HelloReply{} + if in.Data == nil { + err = errors.New("data is required") + return + } + loader := s.getLoader(ctx) + defer loader.Close() + err = loader.UpdateTestCase(in.SuiteName, ToNormalTestCase(in.Data)) + return } func (s *server) DeleteTestCase(ctx context.Context, in *TestCaseIdentity) (reply *HelloReply, err error) { - loader := s.getLoader(ctx) - defer loader.Close() - reply = &HelloReply{} - err = loader.DeleteTestCase(in.Suite, in.Testcase) - return + loader := s.getLoader(ctx) + defer loader.Close() + reply = &HelloReply{} + err = loader.DeleteTestCase(in.Suite, in.Testcase) + return } func (s *server) DeleteHistoryTestCase(ctx context.Context, in *HistoryTestCase) (reply *HelloReply, err error) { - loader := s.getLoader(ctx) - defer loader.Close() - reply = &HelloReply{} - err = loader.DeleteHistoryTestCase(in.ID) - return + loader := s.getLoader(ctx) + defer loader.Close() + reply = &HelloReply{} + err = loader.DeleteHistoryTestCase(in.ID) + return } func (s *server) DeleteAllHistoryTestCase(ctx context.Context, in *HistoryTestCase) (reply *HelloReply, err error) { - loader := s.getLoader(ctx) - defer loader.Close() - reply = &HelloReply{} - err = loader.DeleteAllHistoryTestCase(in.SuiteName, in.CaseName) - return + loader := s.getLoader(ctx) + defer loader.Close() + reply = &HelloReply{} + err = loader.DeleteAllHistoryTestCase(in.SuiteName, in.CaseName) + return } func (s *server) DuplicateTestCase(ctx context.Context, in *TestCaseDuplicate) (reply *HelloReply, err error) { - loader := s.getLoader(ctx) - defer loader.Close() - reply = &HelloReply{} + loader := s.getLoader(ctx) + defer loader.Close() + reply = &HelloReply{} - if in.SourceCaseName == in.TargetCaseName { - reply.Error = "source and target case name should be different" - return - } + if in.SourceCaseName == in.TargetCaseName { + reply.Error = "source and target case name should be different" + return + } - var testcase testing.TestCase - if testcase, err = loader.GetTestCase(in.SourceSuiteName, in.SourceCaseName); err == nil { - testcase.Name = in.TargetCaseName - err = loader.CreateTestCase(in.TargetSuiteName, testcase) - } - return + var testcase testing.TestCase + if testcase, err = loader.GetTestCase(in.SourceSuiteName, in.SourceCaseName); err == nil { + testcase.Name = in.TargetCaseName + err = loader.CreateTestCase(in.TargetSuiteName, testcase) + } + return } func (s *server) RenameTestCase(ctx context.Context, in *TestCaseDuplicate) (result *HelloReply, err error) { - result = &HelloReply{} - loader := s.getLoader(ctx) - defer loader.Close() - err = loader.RenameTestCase(in.SourceSuiteName, in.SourceCaseName, in.TargetCaseName) - return + result = &HelloReply{} + loader := s.getLoader(ctx) + defer loader.Close() + err = loader.RenameTestCase(in.SourceSuiteName, in.SourceCaseName, in.TargetCaseName) + return } // code generator func (s *server) ListCodeGenerator(ctx context.Context, in *Empty) (reply *SimpleList, err error) { - reply = &SimpleList{} + reply = &SimpleList{} - generators := generator.GetCodeGenerators() - for name := range generators { - reply.Data = append(reply.Data, &Pair{ - Key: name, - }) - } - return + generators := generator.GetCodeGenerators() + for name := range generators { + reply.Data = append(reply.Data, &Pair{ + Key: name, + }) + } + return } func (s *server) GenerateCode(ctx context.Context, in *CodeGenerateRequest) (reply *CommonResult, err error) { - reply = &CommonResult{} - instance := generator.GetCodeGenerator(in.Generator) - if instance == nil { - reply.Success = false - reply.Message = fmt.Sprintf("generator '%s' not found", in.Generator) - } else { - var result testing.TestCase - var suite testing.TestSuite - - loader := s.getLoader(ctx) - if suite, err = loader.GetTestSuite(in.TestSuite, true); err != nil { - return - } - - dataContext := map[string]interface{}{} - if err = suite.Render(dataContext); err != nil { - return - } - - var output string - var genErr error - if in.TestCase == "" { - output, genErr = instance.Generate(&suite, nil) - } else { - if result, err = loader.GetTestCase(in.TestSuite, in.TestCase); err == nil { - result.Request.RenderAPI(suite.API) - - output, genErr = instance.Generate(&suite, &result) - } - } - reply.Success = genErr == nil - reply.Message = util.OrErrorMessage(genErr, output) - } - return + reply = &CommonResult{} + instance := generator.GetCodeGenerator(in.Generator) + if instance == nil { + reply.Success = false + reply.Message = fmt.Sprintf("generator '%s' not found", in.Generator) + } else { + var result testing.TestCase + var suite testing.TestSuite + + loader := s.getLoader(ctx) + if suite, err = loader.GetTestSuite(in.TestSuite, true); err != nil { + return + } + + dataContext := map[string]interface{}{} + if err = suite.Render(dataContext); err != nil { + return + } + + var output string + var genErr error + if in.TestCase == "" { + output, genErr = instance.Generate(&suite, nil) + } else { + if result, err = loader.GetTestCase(in.TestSuite, in.TestCase); err == nil { + result.Request.RenderAPI(suite.API) + + output, genErr = instance.Generate(&suite, &result) + } + } + reply.Success = genErr == nil + reply.Message = util.OrErrorMessage(genErr, output) + } + return } func (s *server) HistoryGenerateCode(ctx context.Context, in *CodeGenerateRequest) (reply *CommonResult, err error) { - reply = &CommonResult{} - instance := generator.GetCodeGenerator(in.Generator) - if instance == nil { - reply.Success = false - reply.Message = fmt.Sprintf("generator '%s' not found", in.Generator) - } else { - loader := s.getLoader(ctx) - var result testing.HistoryTestCase - result, err = loader.GetHistoryTestCase(in.ID) - var testCase testing.TestCase - var suite testing.TestSuite - testCase = result.Data - suite.Name = result.SuiteName - suite.API = result.SuiteAPI - suite.Spec = result.SuiteSpec - suite.Param = result.SuiteParam - - output, genErr := instance.Generate(&suite, &testCase) - reply.Success = genErr == nil - reply.Message = util.OrErrorMessage(genErr, output) - } - return + reply = &CommonResult{} + instance := generator.GetCodeGenerator(in.Generator) + if instance == nil { + reply.Success = false + reply.Message = fmt.Sprintf("generator '%s' not found", in.Generator) + } else { + loader := s.getLoader(ctx) + var result testing.HistoryTestCase + result, err = loader.GetHistoryTestCase(in.ID) + var testCase testing.TestCase + var suite testing.TestSuite + testCase = result.Data + suite.Name = result.SuiteName + suite.API = result.SuiteAPI + suite.Spec = result.SuiteSpec + suite.Param = result.SuiteParam + + output, genErr := instance.Generate(&suite, &testCase) + reply.Success = genErr == nil + reply.Message = util.OrErrorMessage(genErr, output) + } + return } // converter func (s *server) ListConverter(ctx context.Context, in *Empty) (reply *SimpleList, err error) { - reply = &SimpleList{} - converters := generator.GetTestSuiteConverters() - for name := range converters { - reply.Data = append(reply.Data, &Pair{ - Key: name, - }) - } - return + reply = &SimpleList{} + converters := generator.GetTestSuiteConverters() + for name := range converters { + reply.Data = append(reply.Data, &Pair{ + Key: name, + }) + } + return } func (s *server) ConvertTestSuite(ctx context.Context, in *CodeGenerateRequest) (reply *CommonResult, err error) { - reply = &CommonResult{} - - instance := generator.GetTestSuiteConverter(in.Generator) - if instance == nil { - reply.Success = false - reply.Message = fmt.Sprintf("converter '%s' not found", in.Generator) - } else { - var result testing.TestSuite - loader := s.getLoader(ctx) - defer loader.Close() - if result, err = loader.GetTestSuite(in.TestSuite, true); err == nil { - output, genErr := instance.Convert(&result) - reply.Success = genErr == nil - reply.Message = util.OrErrorMessage(genErr, output) - } - } - return + reply = &CommonResult{} + + instance := generator.GetTestSuiteConverter(in.Generator) + if instance == nil { + reply.Success = false + reply.Message = fmt.Sprintf("converter '%s' not found", in.Generator) + } else { + var result testing.TestSuite + loader := s.getLoader(ctx) + defer loader.Close() + if result, err = loader.GetTestSuite(in.TestSuite, true); err == nil { + output, genErr := instance.Convert(&result) + reply.Success = genErr == nil + reply.Message = util.OrErrorMessage(genErr, output) + } + } + return } // Sample returns a sample of the test task func (s *server) Sample(ctx context.Context, in *Empty) (reply *HelloReply, err error) { - reply = &HelloReply{Message: sample.TestSuiteGitLab} - return + reply = &HelloReply{Message: sample.TestSuiteGitLab} + return } // PopularHeaders returns a list of popular headers func (s *server) PopularHeaders(ctx context.Context, in *Empty) (pairs *Pairs, err error) { - pairs = &Pairs{ - Data: []*Pair{}, - } + pairs = &Pairs{ + Data: []*Pair{}, + } - err = yaml.Unmarshal(popularHeaders, &pairs.Data) - return + err = yaml.Unmarshal(popularHeaders, &pairs.Data) + return } // GetSuggestedAPIs returns a list of suggested APIs func (s *server) GetSuggestedAPIs(ctx context.Context, in *TestSuiteIdentity) (reply *TestCases, err error) { - reply = &TestCases{} + reply = &TestCases{} - var suite *testing.TestSuite - loader := s.getLoader(ctx) - defer loader.Close() - if suite, _, err = loader.GetSuite(in.Name); err != nil || suite == nil { - return - } + var suite *testing.TestSuite + loader := s.getLoader(ctx) + defer loader.Close() + if suite, _, err = loader.GetSuite(in.Name); err != nil || suite == nil { + return + } - remoteServerLogger.Info("Finding APIs from", "name", in.Name, "with loader", reflect.TypeOf(loader)) + remoteServerLogger.Info("Finding APIs from", "name", in.Name, "with loader", reflect.TypeOf(loader)) - suiteRunner := runner.GetTestSuiteRunner(suite) - var result []*testing.TestCase - if result, err = suiteRunner.GetSuggestedAPIs(suite, in.Api); err == nil && result != nil { - for i := range result { - reply.Data = append(reply.Data, ToGRPCTestCase(*result[i])) - } - } - return + suiteRunner := runner.GetTestSuiteRunner(suite) + var result []*testing.TestCase + if result, err = suiteRunner.GetSuggestedAPIs(suite, in.Api); err == nil && result != nil { + for i := range result { + reply.Data = append(reply.Data, ToGRPCTestCase(*result[i])) + } + } + return } // FunctionsQuery returns a list of functions func (s *server) FunctionsQuery(ctx context.Context, in *SimpleQuery) (reply *Pairs, err error) { - reply = &Pairs{} - in.Name = strings.ToLower(in.Name) - - if in.Kind == "verify" { - for _, fn := range builtin.Builtins { - lowerName := strings.ToLower(fn.Name) - if in.Name == "" || strings.Contains(lowerName, in.Name) { - reply.Data = append(reply.Data, &Pair{ - Key: fn.Name, - Value: fmt.Sprintf("%v", reflect.TypeOf(fn.Func)), - }) - } - } - } else { - for name, fn := range render.FuncMap() { - lowerName := strings.ToLower(name) - if in.Name == "" || strings.Contains(lowerName, in.Name) { - reply.Data = append(reply.Data, &Pair{ - Key: name, - Value: fmt.Sprintf("%v", reflect.TypeOf(fn)), - Description: render.FuncUsage(name), - }) - } - } - } - return + reply = &Pairs{} + in.Name = strings.ToLower(in.Name) + + if in.Kind == "verify" { + for _, fn := range builtin.Builtins { + lowerName := strings.ToLower(fn.Name) + if in.Name == "" || strings.Contains(lowerName, in.Name) { + reply.Data = append(reply.Data, &Pair{ + Key: fn.Name, + Value: fmt.Sprintf("%v", reflect.TypeOf(fn.Func)), + }) + } + } + } else { + for name, fn := range render.FuncMap() { + lowerName := strings.ToLower(name) + if in.Name == "" || strings.Contains(lowerName, in.Name) { + reply.Data = append(reply.Data, &Pair{ + Key: name, + Value: fmt.Sprintf("%v", reflect.TypeOf(fn)), + Description: render.FuncUsage(name), + }) + } + } + } + return } // FunctionsQueryStream works like FunctionsQuery but is implemented in bidirectional streaming func (s *server) FunctionsQueryStream(srv Runner_FunctionsQueryStreamServer) error { - ctx := srv.Context() - for { - select { - case <-ctx.Done(): - return ctx.Err() - default: - in, err := srv.Recv() - if err != nil { - if err == io.EOF { - return nil - } - return err - } - reply := &Pairs{} - in.Name = strings.ToLower(in.Name) - - for name, fn := range render.FuncMap() { - lowerCaseName := strings.ToLower(name) - if in.Name == "" || strings.Contains(lowerCaseName, in.Name) { - reply.Data = append(reply.Data, &Pair{ - Key: name, - Value: fmt.Sprintf("%v", reflect.TypeOf(fn)), - }) - } - } - if err := srv.Send(reply); err != nil { - return err - } - } - } + ctx := srv.Context() + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + in, err := srv.Recv() + if err != nil { + if err == io.EOF { + return nil + } + return err + } + reply := &Pairs{} + in.Name = strings.ToLower(in.Name) + + for name, fn := range render.FuncMap() { + lowerCaseName := strings.ToLower(name) + if in.Name == "" || strings.Contains(lowerCaseName, in.Name) { + reply.Data = append(reply.Data, &Pair{ + Key: name, + Value: fmt.Sprintf("%v", reflect.TypeOf(fn)), + }) + } + } + if err := srv.Send(reply); err != nil { + return err + } + } + } } func (s *server) GetStoreKinds(context.Context, *Empty) (kinds *StoreKinds, err error) { - storeFactory := testing.NewStoreFactory(s.configDir) - var stores []testing.StoreKind - if stores, err = storeFactory.GetStoreKinds(); err == nil { - kinds = &StoreKinds{} - for _, store := range stores { - kinds.Data = append(kinds.Data, &StoreKind{ - Name: store.Name, - Enabled: store.Enabled, - Url: store.URL, - }) - } - } - return + storeFactory := testing.NewStoreFactory(s.configDir) + var stores []testing.StoreKind + if stores, err = storeFactory.GetStoreKinds(); err == nil { + kinds = &StoreKinds{} + for _, store := range stores { + kinds.Data = append(kinds.Data, &StoreKind{ + Name: store.Name, + Enabled: store.Enabled, + Url: store.URL, + }) + } + } + return } func (s *server) GetStores(ctx context.Context, in *Empty) (reply *Stores, err error) { - user := oauth.GetUserFromContext(ctx) - storeFactory := testing.NewStoreFactory(s.configDir) - var stores []testing.Store - var owner string - if user != nil { - owner = user.Name - } - if stores, err = storeFactory.GetStoresByOwner(owner); err == nil { - reply = &Stores{ - Data: make([]*Store, 0), - } - for _, item := range stores { - grpcStore := ToGRPCStore(item) - - storeStatus, sErr := s.VerifyStore(ctx, &SimpleQuery{Name: item.Name}) - grpcStore.Ready = sErr == nil && storeStatus.Ready - grpcStore.ReadOnly = storeStatus.ReadOnly - grpcStore.Password = "******" // return a placeholder instead of the actual value for the security reason - - reply.Data = append(reply.Data, grpcStore) - } - reply.Data = append(reply.Data, &Store{ - Name: "local", - Kind: &StoreKind{}, - Ready: true, - }) - } - return + user := oauth.GetUserFromContext(ctx) + storeFactory := testing.NewStoreFactory(s.configDir) + var stores []testing.Store + var owner string + if user != nil { + owner = user.Name + } + if stores, err = storeFactory.GetStoresByOwner(owner); err == nil { + reply = &Stores{ + Data: make([]*Store, 0), + } + for _, item := range stores { + grpcStore := ToGRPCStore(item) + + storeStatus, sErr := s.VerifyStore(ctx, &SimpleQuery{Name: item.Name}) + grpcStore.Ready = sErr == nil && storeStatus.Ready + grpcStore.ReadOnly = storeStatus.ReadOnly + grpcStore.Password = "******" // return a placeholder instead of the actual value for the security reason + + reply.Data = append(reply.Data, grpcStore) + } + reply.Data = append(reply.Data, &Store{ + Name: "local", + Kind: &StoreKind{}, + Ready: true, + }) + } + return } func (s *server) CreateStore(ctx context.Context, in *Store) (reply *Store, err error) { - reply = &Store{} - user := oauth.GetUserFromContext(ctx) - if user != nil { - in.Owner = user.Name - } + reply = &Store{} + user := oauth.GetUserFromContext(ctx) + if user != nil { + in.Owner = user.Name + } - storeFactory := testing.NewStoreFactory(s.configDir) - store := ToNormalStore(in) + storeFactory := testing.NewStoreFactory(s.configDir) + store := ToNormalStore(in) - if store.Kind.URL == "" { - store.Kind.URL = fmt.Sprintf("unix://%s", home.GetExtensionSocketPath(store.Kind.Name)) - } + if store.Kind.URL == "" { + store.Kind.URL = fmt.Sprintf("unix://%s", home.GetExtensionSocketPath(store.Kind.Name)) + } - if err = storeFactory.CreateStore(store); err == nil && s.storeExtMgr != nil { - err = s.storeExtMgr.Start(store.Kind.Name, store.Kind.URL) - } - return + if err = storeFactory.CreateStore(store); err == nil && s.storeExtMgr != nil { + err = s.storeExtMgr.Start(store.Kind.Name, store.Kind.URL) + } + return } func (s *server) UpdateStore(ctx context.Context, in *Store) (reply *Store, err error) { - reply = &Store{} - storeFactory := testing.NewStoreFactory(s.configDir) - store := ToNormalStore(in) - if err = storeFactory.UpdateStore(store); err == nil && s.storeExtMgr != nil { - // TODO need to restart extension if config was changed - err = s.storeExtMgr.Start(store.Kind.Name, store.Kind.URL) - } - return + reply = &Store{} + storeFactory := testing.NewStoreFactory(s.configDir) + store := ToNormalStore(in) + if err = storeFactory.UpdateStore(store); err == nil && s.storeExtMgr != nil { + // TODO need to restart extension if config was changed + err = s.storeExtMgr.Start(store.Kind.Name, store.Kind.URL) + } + return } func (s *server) DeleteStore(ctx context.Context, in *Store) (reply *Store, err error) { - reply = &Store{} - storeFactory := testing.NewStoreFactory(s.configDir) - err = storeFactory.DeleteStore(in.Name) - return + reply = &Store{} + storeFactory := testing.NewStoreFactory(s.configDir) + err = storeFactory.DeleteStore(in.Name) + return } func (s *server) VerifyStore(ctx context.Context, in *SimpleQuery) (reply *ExtensionStatus, err error) { - reply = &ExtensionStatus{} - var loader testing.Writer - if loader, err = s.getLoaderByStoreName(in.Name); err == nil && loader != nil { - readOnly, verifyErr := loader.Verify() - reply.Ready = verifyErr == nil - reply.ReadOnly = readOnly - reply.Message = util.OKOrErrorMessage(verifyErr) - } - return + reply = &ExtensionStatus{} + var loader testing.Writer + if loader, err = s.getLoaderByStoreName(in.Name); err == nil && loader != nil { + readOnly, verifyErr := loader.Verify() + reply.Ready = verifyErr == nil + reply.ReadOnly = readOnly + reply.Message = util.OKOrErrorMessage(verifyErr) + } + return } // secret related interfaces func (s *server) GetSecrets(ctx context.Context, in *Empty) (reply *Secrets, err error) { - return s.secretServer.GetSecrets(ctx, in) + return s.secretServer.GetSecrets(ctx, in) } func (s *server) CreateSecret(ctx context.Context, in *Secret) (reply *CommonResult, err error) { - return s.secretServer.CreateSecret(ctx, in) + return s.secretServer.CreateSecret(ctx, in) } func (s *server) DeleteSecret(ctx context.Context, in *Secret) (reply *CommonResult, err error) { - return s.secretServer.DeleteSecret(ctx, in) + return s.secretServer.DeleteSecret(ctx, in) } func (s *server) UpdateSecret(ctx context.Context, in *Secret) (reply *CommonResult, err error) { - return s.secretServer.UpdateSecret(ctx, in) + return s.secretServer.UpdateSecret(ctx, in) } func (s *server) PProf(ctx context.Context, in *PProfRequest) (reply *PProfData, err error) { - loader := s.getLoader(ctx) - defer loader.Close() - reply = &PProfData{ - Data: loader.PProf(in.Name), - } - return + loader := s.getLoader(ctx) + defer loader.Close() + reply = &PProfData{ + Data: loader.PProf(in.Name), + } + return +} +func (s *server) Query(ctx context.Context, query *DataQuery) (result *DataQueryResult, err error) { + loader := s.getLoader(ctx) + defer loader.Close() + var dataResult map[string]string + var items []map[string]string + if dataResult, items, err = loader.Query(map[string]string{ + "sql": query.Sql, + "key": query.Key, + }); err == nil { + result = &DataQueryResult{ + Data: mapToPair(dataResult), + } + for _, item := range items { + result.Items = append(result.Items, &Pairs{ + Data: mapToPair(item), + }) + } + } + return } // implement the mock server // Start starts the mock server type mockServerController struct { - UnimplementedMockServer - mockWriter mock.ReaderAndWriter - loader mock.Loadable - reader mock.Reader - prefix string - combinePort int + UnimplementedMockServer + mockWriter mock.ReaderAndWriter + loader mock.Loadable + reader mock.Reader + prefix string + combinePort int } func NewMockServerController(mockWriter mock.ReaderAndWriter, loader mock.Loadable, combinePort int) MockServer { - return &mockServerController{ - mockWriter: mockWriter, - loader: loader, - prefix: "/mock/server", - combinePort: combinePort, - } + return &mockServerController{ + mockWriter: mockWriter, + loader: loader, + prefix: "/mock/server", + combinePort: combinePort, + } } func (s *mockServerController) Reload(ctx context.Context, in *MockConfig) (reply *Empty, err error) { - s.mockWriter.Write([]byte(in.Config)) - s.prefix = in.Prefix - if dServer, ok := s.loader.(mock.DynamicServer); ok && dServer.GetPort() != strconv.Itoa(int(in.GetPort())) { - if strconv.Itoa(s.combinePort) != dServer.GetPort() { - if stopErr := dServer.Stop(); stopErr != nil { - remoteServerLogger.Info("failed to stop old server", "error", stopErr) - } else { - remoteServerLogger.Info("old server stopped", "port", dServer.GetPort()) - } - } - - server := mock.NewInMemoryServer(ctx, int(in.GetPort())) - server.Start(s.mockWriter, in.Prefix) - s.loader = server - } - err = s.loader.Load() - return + s.mockWriter.Write([]byte(in.Config)) + s.prefix = in.Prefix + if dServer, ok := s.loader.(mock.DynamicServer); ok && dServer.GetPort() != strconv.Itoa(int(in.GetPort())) { + if strconv.Itoa(s.combinePort) != dServer.GetPort() { + if stopErr := dServer.Stop(); stopErr != nil { + remoteServerLogger.Info("failed to stop old server", "error", stopErr) + } else { + remoteServerLogger.Info("old server stopped", "port", dServer.GetPort()) + } + } + + server := mock.NewInMemoryServer(ctx, int(in.GetPort())) + server.Start(s.mockWriter, in.Prefix) + s.loader = server + } + err = s.loader.Load() + return } func (s *mockServerController) GetConfig(ctx context.Context, in *Empty) (reply *MockConfig, err error) { - reply = &MockConfig{ - Prefix: s.prefix, - Config: string(s.mockWriter.GetData()), - } - if dServer, ok := s.loader.(mock.DynamicServer); ok { - if port, pErr := strconv.ParseInt(dServer.GetPort(), 10, 32); pErr == nil { - reply.Port = int32(port) - } - } - return + reply = &MockConfig{ + Prefix: s.prefix, + Config: string(s.mockWriter.GetData()), + } + if dServer, ok := s.loader.(mock.DynamicServer); ok { + if port, pErr := strconv.ParseInt(dServer.GetPort(), 10, 32); pErr == nil { + reply.Port = int32(port) + } + } + return } func (s *server) getLoaderByStoreName(storeName string) (loader testing.Writer, err error) { - var store *testing.Store - store, err = testing.NewStoreFactory(s.configDir).GetStore(storeName) - if err == nil && store != nil { - loader, err = s.storeWriterFactory.NewInstance(*store) - if err != nil { - err = fmt.Errorf("failed to new grpc loader from store %s, err: %v", store.Name, err) - } - } else { - err = fmt.Errorf("failed to get store %s, err: %v", storeName, err) - } - return + var store *testing.Store + store, err = testing.NewStoreFactory(s.configDir).GetStore(storeName) + if err == nil && store != nil { + loader, err = s.storeWriterFactory.NewInstance(*store) + if err != nil { + err = fmt.Errorf("failed to new grpc loader from store %s, err: %v", store.Name, err) + } + } else { + err = fmt.Errorf("failed to get store %s, err: %v", storeName, err) + } + return } //go:embed data/headers.yaml var popularHeaders []byte func findParentTestCases(testcase *testing.TestCase, suite *testing.TestSuite) (testcases []testing.TestCase) { - reg, matchErr := regexp.Compile(`(.*?\{\{.*\.\w*.*?\}\})`) - targetReg, targetErr := regexp.Compile(`\.\w*`) - - expectNames := new(UniqueSlice[string]) - if matchErr == nil && targetErr == nil { - var expectName string - for _, val := range testcase.Request.Header { - if matched := reg.MatchString(val); matched { - expectName = targetReg.FindString(val) - expectName = strings.TrimPrefix(expectName, ".") - expectNames.Push(expectName) - } - } - - findExpectNames(testcase.Request.API, expectNames) - findExpectNames(testcase.Request.Body.String(), expectNames) - - remoteServerLogger.Info("expect test case names", "name", expectNames.GetAll()) - for _, item := range suite.Items { - if expectNames.Exist(item.Name) { - testcases = append(testcases, item) - } - } - } - return + reg, matchErr := regexp.Compile(`(.*?\{\{.*\.\w*.*?\}\})`) + targetReg, targetErr := regexp.Compile(`\.\w*`) + + expectNames := new(UniqueSlice[string]) + if matchErr == nil && targetErr == nil { + var expectName string + for _, val := range testcase.Request.Header { + if matched := reg.MatchString(val); matched { + expectName = targetReg.FindString(val) + expectName = strings.TrimPrefix(expectName, ".") + expectNames.Push(expectName) + } + } + + findExpectNames(testcase.Request.API, expectNames) + findExpectNames(testcase.Request.Body.String(), expectNames) + + remoteServerLogger.Info("expect test case names", "name", expectNames.GetAll()) + for _, item := range suite.Items { + if expectNames.Exist(item.Name) { + testcases = append(testcases, item) + } + } + } + return } func findExpectNames(target string, expectNames *UniqueSlice[string]) { - reg, _ := regexp.Compile(`(.*?\{\{.*\.\w*.*?\}\})`) - targetReg, _ := regexp.Compile(`\.\w*`) + reg, _ := regexp.Compile(`(.*?\{\{.*\.\w*.*?\}\})`) + targetReg, _ := regexp.Compile(`\.\w*`) - for _, sub := range reg.FindStringSubmatch(target) { - // remove {{ and }} - if left, leftErr := regexp.Compile(`.*\{\{`); leftErr == nil { - body := left.ReplaceAllString(sub, "") + for _, sub := range reg.FindStringSubmatch(target) { + // remove {{ and }} + if left, leftErr := regexp.Compile(`.*\{\{`); leftErr == nil { + body := left.ReplaceAllString(sub, "") - expectName := targetReg.FindString(body) - expectName = strings.TrimPrefix(expectName, ".") - expectNames.Push(expectName) - } - } + expectName := targetReg.FindString(body) + expectName = strings.TrimPrefix(expectName, ".") + expectNames.Push(expectName) + } + } } // UniqueSlice represents an unique slice type UniqueSlice[T comparable] struct { - data []T + data []T } // Push pushes an item if it's not exist func (s *UniqueSlice[T]) Push(item T) *UniqueSlice[T] { - if s.data == nil { - s.data = []T{item} - } else { - for _, it := range s.data { - if it == item { - return s - } - } - s.data = append(s.data, item) - } - return s + if s.data == nil { + s.data = []T{item} + } else { + for _, it := range s.data { + if it == item { + return s + } + } + s.data = append(s.data, item) + } + return s } // Exist checks if the item exist, return true it exists func (s *UniqueSlice[T]) Exist(item T) bool { - if s.data != nil { - for _, it := range s.data { - if it == item { - return true - } - } - } - return false + if s.data != nil { + for _, it := range s.data { + if it == item { + return true + } + } + } + return false } // GetAll returns all the items func (s *UniqueSlice[T]) GetAll() []T { - return s.data + return s.data } var errNoTestSuiteFound = errors.New("no test suite found") diff --git a/pkg/server/server.pb.go b/pkg/server/server.pb.go index 6c2581984..44d24f6ad 100644 --- a/pkg/server/server.pb.go +++ b/pkg/server/server.pb.go @@ -3369,6 +3369,124 @@ func (x *ProxyConfig) GetNo() string { return "" } +type DataQuery struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + Sql string `protobuf:"bytes,3,opt,name=sql,proto3" json:"sql,omitempty"` +} + +func (x *DataQuery) Reset() { + *x = DataQuery{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_server_server_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DataQuery) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataQuery) ProtoMessage() {} + +func (x *DataQuery) ProtoReflect() protoreflect.Message { + mi := &file_pkg_server_server_proto_msgTypes[52] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataQuery.ProtoReflect.Descriptor instead. +func (*DataQuery) Descriptor() ([]byte, []int) { + return file_pkg_server_server_proto_rawDescGZIP(), []int{52} +} + +func (x *DataQuery) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *DataQuery) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *DataQuery) GetSql() string { + if x != nil { + return x.Sql + } + return "" +} + +type DataQueryResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data []*Pair `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"` + Items []*Pairs `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` +} + +func (x *DataQueryResult) Reset() { + *x = DataQueryResult{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_server_server_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DataQueryResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataQueryResult) ProtoMessage() {} + +func (x *DataQueryResult) ProtoReflect() protoreflect.Message { + mi := &file_pkg_server_server_proto_msgTypes[53] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataQueryResult.ProtoReflect.Descriptor instead. +func (*DataQueryResult) Descriptor() ([]byte, []int) { + return file_pkg_server_server_proto_rawDescGZIP(), []int{53} +} + +func (x *DataQueryResult) GetData() []*Pair { + if x != nil { + return x.Data + } + return nil +} + +func (x *DataQueryResult) GetItems() []*Pairs { + if x != nil { + return x.Items + } + return nil +} + var File_pkg_server_server_proto protoreflect.FileDescriptor var file_pkg_server_server_proto_rawDesc = []byte{ @@ -3749,326 +3867,342 @@ var file_pkg_server_server_proto_rawDesc = []byte{ 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x68, 0x74, 0x74, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x68, 0x74, 0x74, 0x70, 0x73, 0x12, 0x0e, 0x0a, - 0x02, 0x6e, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6e, 0x6f, 0x32, 0xa1, 0x25, - 0x0a, 0x06, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x43, 0x0a, 0x03, 0x52, 0x75, 0x6e, 0x12, - 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x54, 0x61, 0x73, - 0x6b, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x22, 0x0b, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x75, 0x6e, 0x3a, 0x01, 0x2a, 0x12, 0x5f, 0x0a, - 0x0c, 0x52, 0x75, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, 0x19, 0x2e, + 0x02, 0x6e, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6e, 0x6f, 0x22, 0x43, 0x0a, + 0x09, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x73, 0x71, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, + 0x71, 0x6c, 0x22, 0x58, 0x0a, 0x0f, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x20, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x69, + 0x72, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x23, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x50, 0x61, 0x69, 0x72, 0x73, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x32, 0xa1, 0x25, 0x0a, + 0x06, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x43, 0x0a, 0x03, 0x52, 0x75, 0x6e, 0x12, 0x10, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, + 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x22, 0x0b, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x75, 0x6e, 0x3a, 0x01, 0x2a, 0x12, 0x5f, 0x0a, 0x0c, + 0x52, 0x75, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x1c, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x16, 0x22, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x75, 0x6e, + 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x28, 0x01, 0x30, 0x01, 0x12, 0x42, 0x0a, + 0x09, 0x47, 0x65, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x10, 0x12, 0x0e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, + 0x73, 0x12, 0x5b, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, + 0x75, 0x69, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, + 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, + 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x22, 0x0e, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x62, + 0x0a, 0x0f, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, + 0x65, 0x12, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, + 0x75, 0x69, 0x74, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x3a, + 0x01, 0x2a, 0x12, 0x5b, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, + 0x74, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, + 0x53, 0x75, 0x69, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x1c, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x16, 0x22, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x75, - 0x6e, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x28, 0x01, 0x30, 0x01, 0x12, 0x42, - 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x12, 0x0d, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0e, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, - 0x65, 0x73, 0x12, 0x5b, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, - 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, - 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x22, 0x0e, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x12, - 0x62, 0x0a, 0x0f, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, - 0x74, 0x65, 0x12, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, - 0x53, 0x75, 0x69, 0x74, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0x14, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x3a, 0x01, 0x2a, 0x12, 0x5b, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, - 0x69, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, - 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x11, + 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, + 0x5a, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, + 0x74, 0x65, 0x12, 0x11, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, + 0x53, 0x75, 0x69, 0x74, 0x65, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, + 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x1a, 0x1a, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, + 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x5f, 0x0a, 0x0f, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, - 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1d, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x2a, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, + 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x7b, 0x0a, 0x12, + 0x44, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, + 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, + 0x53, 0x75, 0x69, 0x74, 0x65, 0x44, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x1a, 0x12, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x22, 0x2a, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x75, 0x69, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x64, 0x75, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x75, 0x0a, 0x0f, 0x52, 0x65, 0x6e, + 0x61, 0x6d, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x44, + 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x32, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x2c, 0x22, 0x27, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, + 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x75, 0x69, 0x74, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x01, 0x2a, + 0x12, 0x63, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, + 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, + 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, + 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x59, 0x61, 0x6d, 0x6c, 0x44, 0x61, 0x74, + 0x61, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, - 0x12, 0x5a, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, - 0x69, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, - 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1a, 0x1a, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, - 0x65, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x5f, 0x0a, 0x0f, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, - 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, - 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1d, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x2a, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, - 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x7b, 0x0a, - 0x12, 0x44, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, - 0x69, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, - 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x44, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x1a, - 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x22, 0x2a, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x53, 0x75, 0x69, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x64, 0x75, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x75, 0x0a, 0x0f, 0x52, 0x65, - 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, 0x1a, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, - 0x44, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x32, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x22, 0x27, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, - 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x75, 0x69, - 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x01, - 0x2a, 0x12, 0x63, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, - 0x65, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, + 0x2f, 0x79, 0x61, 0x6d, 0x6c, 0x12, 0x5d, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, + 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x1a, 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x59, 0x61, 0x6d, 0x6c, 0x44, 0x61, - 0x74, 0x61, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, - 0x7d, 0x2f, 0x79, 0x61, 0x6d, 0x6c, 0x12, 0x5d, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, - 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x75, 0x69, 0x74, 0x65, - 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, - 0x63, 0x61, 0x73, 0x65, 0x73, 0x12, 0x77, 0x0a, 0x0b, 0x52, 0x75, 0x6e, 0x54, 0x65, 0x73, 0x74, + 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x75, 0x69, 0x74, 0x65, 0x22, + 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x63, + 0x61, 0x73, 0x65, 0x73, 0x12, 0x77, 0x0a, 0x0b, 0x52, 0x75, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x43, + 0x61, 0x73, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, + 0x74, 0x43, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x16, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x22, 0x2b, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, + 0x75, 0x69, 0x74, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x73, + 0x74, 0x63, 0x61, 0x73, 0x65, 0x7d, 0x2f, 0x72, 0x75, 0x6e, 0x3a, 0x01, 0x2a, 0x12, 0x56, 0x0a, + 0x08, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6e, 0x12, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x54, 0x65, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, + 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x22, 0x10, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6e, 0x3a, 0x01, + 0x2a, 0x28, 0x01, 0x30, 0x01, 0x12, 0x6a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, - 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x16, + 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x22, 0x2b, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, - 0x73, 0x75, 0x69, 0x74, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x65, - 0x73, 0x74, 0x63, 0x61, 0x73, 0x65, 0x7d, 0x2f, 0x72, 0x75, 0x6e, 0x3a, 0x01, 0x2a, 0x12, 0x56, - 0x0a, 0x08, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6e, 0x12, 0x15, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x54, 0x65, 0x73, 0x74, 0x54, 0x61, 0x73, - 0x6b, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x22, 0x10, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6e, 0x3a, - 0x01, 0x2a, 0x28, 0x01, 0x30, 0x01, 0x12, 0x6a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, - 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, - 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, - 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, - 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x75, 0x69, 0x74, 0x65, - 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x73, 0x74, 0x63, 0x61, 0x73, - 0x65, 0x7d, 0x12, 0x6c, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, - 0x43, 0x61, 0x73, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, - 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, 0x75, 0x69, 0x74, 0x65, 0x1a, - 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x22, 0x20, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x75, 0x69, - 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x3a, 0x01, 0x2a, - 0x12, 0x78, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, - 0x73, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, - 0x43, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, 0x75, 0x69, 0x74, 0x65, 0x1a, 0x12, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, - 0x79, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x1a, 0x2c, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x75, 0x69, 0x74, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x7b, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x6f, 0x0a, 0x0e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x18, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x29, 0x2a, 0x27, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, - 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x75, 0x69, 0x74, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, - 0x2f, 0x7b, 0x74, 0x65, 0x73, 0x74, 0x63, 0x61, 0x73, 0x65, 0x7d, 0x12, 0x90, 0x01, 0x0a, 0x11, - 0x44, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, - 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, - 0x61, 0x73, 0x65, 0x44, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x1a, 0x12, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x4c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x46, 0x22, 0x41, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x53, 0x75, 0x69, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, - 0x2f, 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x7d, 0x2f, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x8a, - 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, + 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x75, 0x69, 0x74, 0x65, 0x7d, + 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x73, 0x74, 0x63, 0x61, 0x73, 0x65, + 0x7d, 0x12, 0x6c, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, + 0x61, 0x73, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, + 0x74, 0x43, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, 0x75, 0x69, 0x74, 0x65, 0x1a, 0x12, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x22, 0x20, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x75, 0x69, 0x74, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x12, + 0x78, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, - 0x61, 0x73, 0x65, 0x44, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x1a, 0x12, 0x2e, 0x73, + 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, 0x75, 0x69, 0x74, 0x65, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x49, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x43, 0x22, 0x3e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x53, 0x75, 0x69, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, - 0x2f, 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x7d, 0x2f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x5f, 0x0a, 0x10, 0x47, - 0x65, 0x74, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x65, 0x64, 0x41, 0x50, 0x49, 0x73, 0x12, - 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, - 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x73, 0x22, 0x1d, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, - 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x65, 0x64, 0x41, 0x50, 0x49, 0x73, 0x12, 0x57, 0x0a, 0x10, - 0x47, 0x65, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, - 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, - 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, - 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x22, 0x15, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, - 0x75, 0x69, 0x74, 0x65, 0x73, 0x12, 0x82, 0x01, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x48, 0x69, 0x73, - 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x1a, - 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, - 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x28, 0x12, 0x26, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x69, 0x73, 0x74, + 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x1a, 0x2c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x75, 0x69, 0x74, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x7b, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x6f, 0x0a, 0x0e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, + 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x29, 0x2a, 0x27, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, + 0x73, 0x2f, 0x7b, 0x73, 0x75, 0x69, 0x74, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2f, + 0x7b, 0x74, 0x65, 0x73, 0x74, 0x63, 0x61, 0x73, 0x65, 0x7d, 0x12, 0x90, 0x01, 0x0a, 0x11, 0x44, + 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, + 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, + 0x73, 0x65, 0x44, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x1a, 0x12, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, + 0x4c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x46, 0x22, 0x41, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, + 0x75, 0x69, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2f, + 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, + 0x2f, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x8a, 0x01, + 0x0a, 0x0e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, + 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, + 0x73, 0x65, 0x44, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x1a, 0x12, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, + 0x49, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x43, 0x22, 0x3e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, + 0x75, 0x69, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2f, + 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, + 0x2f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x5f, 0x0a, 0x10, 0x47, 0x65, + 0x74, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x65, 0x64, 0x41, 0x50, 0x49, 0x73, 0x12, 0x19, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, + 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x73, 0x22, 0x1d, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, + 0x67, 0x67, 0x65, 0x73, 0x74, 0x65, 0x64, 0x41, 0x50, 0x49, 0x73, 0x12, 0x57, 0x0a, 0x10, 0x47, + 0x65, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x12, + 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x15, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, + 0x75, 0x69, 0x74, 0x65, 0x73, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x22, 0x15, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x75, + 0x69, 0x74, 0x65, 0x73, 0x12, 0x82, 0x01, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2f, 0x7b, 0x49, 0x44, 0x7d, 0x12, 0x6c, 0x0a, 0x12, 0x47, 0x65, - 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x1a, 0x19, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, + 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x28, 0x12, 0x26, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x69, 0x73, 0x74, 0x6f, + 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x2f, 0x7b, 0x49, 0x44, 0x7d, 0x12, 0x6c, 0x0a, 0x12, 0x47, 0x65, 0x74, + 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, + 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, + 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x1a, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, + 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x76, 0x31, 0x2f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, + 0x73, 0x65, 0x2f, 0x7b, 0x49, 0x44, 0x7d, 0x12, 0x6a, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, - 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x1a, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, - 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, - 0x61, 0x73, 0x65, 0x2f, 0x7b, 0x49, 0x44, 0x7d, 0x12, 0x6a, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, - 0x65, 0x12, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, - 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x24, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x2a, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, - 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x2f, - 0x7b, 0x49, 0x44, 0x7d, 0x12, 0x83, 0x01, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, - 0x6c, 0x6c, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, - 0x65, 0x12, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, - 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x3a, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x2a, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, - 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, - 0x75, 0x69, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2f, - 0x7b, 0x63, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x74, 0x0a, 0x15, 0x47, 0x65, - 0x74, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x41, 0x6c, 0x6c, 0x48, 0x69, 0x73, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, - 0x74, 0x43, 0x61, 0x73, 0x65, 0x1a, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, - 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x73, 0x22, - 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x22, 0x27, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, - 0x2f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x75, 0x69, 0x74, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, - 0x12, 0x56, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, - 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, + 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x24, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x2a, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x68, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x2f, 0x7b, + 0x49, 0x44, 0x7d, 0x12, 0x83, 0x01, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, + 0x6c, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, + 0x12, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x3a, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x2a, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x68, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x75, + 0x69, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x7b, + 0x63, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x74, 0x0a, 0x15, 0x47, 0x65, 0x74, + 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x41, 0x6c, 0x6c, 0x48, 0x69, 0x73, 0x74, 0x6f, + 0x72, 0x79, 0x12, 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, + 0x43, 0x61, 0x73, 0x65, 0x1a, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x69, + 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x73, 0x22, 0x2f, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x22, 0x27, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, + 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x75, 0x69, 0x74, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x7d, 0x2f, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, + 0x56, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, + 0x70, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, + 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x6d, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x24, 0x22, 0x1f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x64, 0x65, + 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x7c, 0x0a, 0x13, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x79, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x22, 0x27, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x31, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, + 0x2f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x4e, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x69, - 0x6d, 0x70, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, - 0x12, 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x47, 0x65, - 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x6d, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x6d, 0x70, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, + 0x12, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x74, 0x65, 0x72, 0x73, 0x12, 0x6c, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x54, + 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x2a, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x24, 0x22, 0x1f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x64, - 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x7c, 0x0a, 0x13, 0x48, 0x69, 0x73, 0x74, 0x6f, - 0x72, 0x79, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1b, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x22, 0x27, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, - 0x73, 0x2f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x4e, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x74, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, - 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x14, 0x12, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, - 0x72, 0x74, 0x65, 0x72, 0x73, 0x12, 0x6c, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, - 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x25, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x1f, 0x22, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, - 0x3a, 0x01, 0x2a, 0x12, 0x4e, 0x0a, 0x0e, 0x50, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x48, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x61, - 0x69, 0x72, 0x73, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x73, 0x12, 0x4f, 0x0a, 0x0e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x13, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, - 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x73, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x13, 0x12, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5e, 0x0a, 0x14, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x13, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x73, - 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x31, 0x2f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x28, 0x01, 0x30, 0x01, 0x12, 0x45, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x0f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x43, 0x0a, 0x06, 0x53, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, - 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, - 0x12, 0x0e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x12, 0x6b, 0x0a, 0x14, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x1a, 0x10, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x22, 0x2f, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x29, 0x22, 0x24, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x6f, - 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x50, 0x0a, - 0x0d, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x73, 0x12, 0x0d, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x69, 0x6e, 0x64, - 0x73, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x76, 0x31, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x2f, 0x6b, 0x69, 0x6e, 0x64, 0x73, 0x12, - 0x42, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x0d, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0e, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x22, 0x16, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x73, 0x12, 0x46, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, - 0x72, 0x65, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, - 0x65, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, - 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x22, 0x0e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x31, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x4d, 0x0a, 0x0b, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, - 0x1a, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, - 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x4a, 0x0a, 0x0b, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x25, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1f, 0x22, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x3a, + 0x01, 0x2a, 0x12, 0x4e, 0x0a, 0x0e, 0x50, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x73, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x69, + 0x72, 0x73, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x12, 0x4f, 0x0a, 0x0e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x12, 0x13, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x69, + 0x6d, 0x70, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x73, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, + 0x12, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x5e, 0x0a, 0x14, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x13, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x73, 0x22, + 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x28, + 0x01, 0x30, 0x01, 0x12, 0x45, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x0f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x76, 0x31, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x43, 0x0a, 0x06, 0x53, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x6c, + 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, + 0x0e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, + 0x6b, 0x0a, 0x14, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x1a, 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x22, 0x2f, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x29, 0x22, 0x24, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x6f, 0x77, + 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x50, 0x0a, 0x0d, + 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x73, 0x12, 0x0d, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x73, + 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x31, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x2f, 0x6b, 0x69, 0x6e, 0x64, 0x73, 0x12, 0x42, + 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x0d, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0e, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x73, 0x12, 0x46, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, + 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x22, + 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x22, 0x0e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x4d, 0x0a, 0x0b, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x2a, + 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x1a, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x2f, - 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x5d, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x13, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, - 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x17, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x15, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x2f, 0x76, 0x65, 0x72, 0x69, - 0x66, 0x79, 0x3a, 0x01, 0x2a, 0x12, 0x45, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x73, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x73, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x50, 0x0a, 0x0c, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x22, 0x0f, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x54, - 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x0e, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x14, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x2a, 0x16, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x2f, 0x7b, 0x4e, - 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x57, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, - 0x63, 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, - 0x63, 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1b, 0x1a, 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x73, 0x2f, 0x7b, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x32, 0x0a, - 0x05, 0x50, 0x50, 0x72, 0x6f, 0x66, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x50, 0x50, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x50, 0x72, 0x6f, 0x66, 0x44, 0x61, 0x74, 0x61, 0x22, - 0x00, 0x32, 0x6b, 0x0a, 0x0f, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x58, 0x0a, 0x03, 0x52, 0x75, 0x6e, 0x12, 0x19, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x57, 0x69, - 0x74, 0x68, 0x43, 0x61, 0x73, 0x65, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x20, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, - 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x72, 0x75, 0x6e, 0x3a, 0x01, 0x2a, 0x32, 0xa0, - 0x01, 0x0a, 0x04, 0x4d, 0x6f, 0x63, 0x6b, 0x12, 0x4b, 0x0a, 0x06, 0x52, 0x65, 0x6c, 0x6f, 0x61, - 0x64, 0x12, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x63, 0x6b, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x22, 0x13, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x6f, 0x63, 0x6b, 0x2f, 0x72, 0x65, 0x6c, 0x6f, 0x61, - 0x64, 0x3a, 0x01, 0x2a, 0x12, 0x4b, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x63, 0x6b, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x6f, 0x63, 0x6b, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x73, 0x75, 0x72, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2d, 0x74, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x4a, 0x0a, 0x0b, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x2a, 0x15, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x2f, 0x7b, + 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x5d, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x12, 0x13, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x69, + 0x6d, 0x70, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x15, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x2f, 0x76, 0x65, 0x72, 0x69, 0x66, + 0x79, 0x3a, 0x01, 0x2a, 0x12, 0x45, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x73, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x1a, 0x0f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x73, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x50, 0x0a, 0x0c, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x22, 0x0f, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x54, 0x0a, + 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x2a, 0x16, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x2f, 0x7b, 0x4e, 0x61, + 0x6d, 0x65, 0x7d, 0x12, 0x57, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x1b, 0x1a, 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x73, 0x2f, 0x7b, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x32, 0x0a, 0x05, + 0x50, 0x50, 0x72, 0x6f, 0x66, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, + 0x50, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x50, 0x72, 0x6f, 0x66, 0x44, 0x61, 0x74, 0x61, 0x22, 0x00, + 0x32, 0x6b, 0x0a, 0x0f, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x58, 0x0a, 0x03, 0x52, 0x75, 0x6e, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x57, 0x69, 0x74, + 0x68, 0x43, 0x61, 0x73, 0x65, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x20, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1a, 0x22, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x72, 0x75, 0x6e, 0x3a, 0x01, 0x2a, 0x32, 0xa0, 0x01, + 0x0a, 0x04, 0x4d, 0x6f, 0x63, 0x6b, 0x12, 0x4b, 0x0a, 0x06, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, + 0x12, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x63, 0x6b, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x22, 0x13, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x6f, 0x63, 0x6b, 0x2f, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, + 0x3a, 0x01, 0x2a, 0x12, 0x4b, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, + 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x63, 0x6b, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x6f, 0x63, 0x6b, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x32, 0x60, 0x0a, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x52, + 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x11, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x17, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x22, 0x12, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x3a, + 0x01, 0x2a, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x73, 0x75, 0x72, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2d, + 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -4083,7 +4217,7 @@ func file_pkg_server_server_proto_rawDescGZIP() []byte { return file_pkg_server_server_proto_rawDescData } -var file_pkg_server_server_proto_msgTypes = make([]protoimpl.MessageInfo, 55) +var file_pkg_server_server_proto_msgTypes = make([]protoimpl.MessageInfo, 57) var file_pkg_server_server_proto_goTypes = []interface{}{ (*Suites)(nil), // 0: server.Suites (*Items)(nil), // 1: server.Items @@ -4137,168 +4271,174 @@ var file_pkg_server_server_proto_goTypes = []interface{}{ (*MockConfig)(nil), // 49: server.MockConfig (*Version)(nil), // 50: server.Version (*ProxyConfig)(nil), // 51: server.ProxyConfig - nil, // 52: server.Suites.DataEntry - nil, // 53: server.HistorySuites.DataEntry - nil, // 54: server.TestTask.EnvEntry - (*timestamppb.Timestamp)(nil), // 55: google.protobuf.Timestamp + (*DataQuery)(nil), // 52: server.DataQuery + (*DataQueryResult)(nil), // 53: server.DataQueryResult + nil, // 54: server.Suites.DataEntry + nil, // 55: server.HistorySuites.DataEntry + nil, // 56: server.TestTask.EnvEntry + (*timestamppb.Timestamp)(nil), // 57: google.protobuf.Timestamp } var file_pkg_server_server_proto_depIdxs = []int32{ - 52, // 0: server.Suites.data:type_name -> server.Suites.DataEntry - 53, // 1: server.HistorySuites.data:type_name -> server.HistorySuites.DataEntry - 4, // 2: server.HistoryItems.data:type_name -> server.HistoryCaseIdentity - 31, // 3: server.TestCaseIdentity.parameters:type_name -> server.Pair - 31, // 4: server.TestSuite.param:type_name -> server.Pair - 9, // 5: server.TestSuite.spec:type_name -> server.APISpec - 51, // 6: server.TestSuite.proxy:type_name -> server.ProxyConfig - 7, // 7: server.TestSuiteWithCase.suite:type_name -> server.TestSuite - 24, // 8: server.TestSuiteWithCase.case:type_name -> server.TestCase - 11, // 9: server.APISpec.rpc:type_name -> server.RPC - 10, // 10: server.APISpec.secure:type_name -> server.Secure - 54, // 11: server.TestTask.env:type_name -> server.TestTask.EnvEntry - 31, // 12: server.TestTask.parameters:type_name -> server.Pair - 31, // 13: server.BatchTestTask.parameters:type_name -> server.Pair - 30, // 14: server.TestResult.testCaseResult:type_name -> server.TestCaseResult - 30, // 15: server.HistoryTestResult.testCaseResult:type_name -> server.TestCaseResult - 25, // 16: server.HistoryTestResult.data:type_name -> server.HistoryTestCase - 55, // 17: server.HistoryTestResult.createTime:type_name -> google.protobuf.Timestamp - 24, // 18: server.Suite.items:type_name -> server.TestCase - 24, // 19: server.TestCaseWithSuite.data:type_name -> server.TestCase - 24, // 20: server.TestCases.data:type_name -> server.TestCase - 27, // 21: server.TestCase.request:type_name -> server.Request - 28, // 22: server.TestCase.response:type_name -> server.Response - 55, // 23: server.HistoryTestCase.createTime:type_name -> google.protobuf.Timestamp - 31, // 24: server.HistoryTestCase.suiteParam:type_name -> server.Pair - 9, // 25: server.HistoryTestCase.suiteSpec:type_name -> server.APISpec - 27, // 26: server.HistoryTestCase.request:type_name -> server.Request - 28, // 27: server.HistoryTestCase.response:type_name -> server.Response - 31, // 28: server.HistoryTestCase.historyHeader:type_name -> server.Pair - 25, // 29: server.HistoryTestCases.data:type_name -> server.HistoryTestCase - 31, // 30: server.Request.header:type_name -> server.Pair - 31, // 31: server.Request.query:type_name -> server.Pair - 31, // 32: server.Request.cookie:type_name -> server.Pair - 31, // 33: server.Request.form:type_name -> server.Pair - 31, // 34: server.Response.header:type_name -> server.Pair - 31, // 35: server.Response.bodyFieldsExpect:type_name -> server.Pair - 29, // 36: server.Response.ConditionalVerify:type_name -> server.ConditionalVerify - 31, // 37: server.TestCaseResult.header:type_name -> server.Pair - 31, // 38: server.Pairs.data:type_name -> server.Pair - 35, // 39: server.Stores.data:type_name -> server.Store - 31, // 40: server.Store.properties:type_name -> server.Pair - 37, // 41: server.Store.kind:type_name -> server.StoreKind - 37, // 42: server.StoreKinds.data:type_name -> server.StoreKind - 31, // 43: server.SimpleList.data:type_name -> server.Pair - 43, // 44: server.Secrets.data:type_name -> server.Secret - 1, // 45: server.Suites.DataEntry.value:type_name -> server.Items - 3, // 46: server.HistorySuites.DataEntry.value:type_name -> server.HistoryItems - 15, // 47: server.Runner.Run:input_type -> server.TestTask - 12, // 48: server.Runner.RunTestSuite:input_type -> server.TestSuiteIdentity - 48, // 49: server.Runner.GetSuites:input_type -> server.Empty - 12, // 50: server.Runner.CreateTestSuite:input_type -> server.TestSuiteIdentity - 6, // 51: server.Runner.ImportTestSuite:input_type -> server.TestSuiteSource - 12, // 52: server.Runner.GetTestSuite:input_type -> server.TestSuiteIdentity - 7, // 53: server.Runner.UpdateTestSuite:input_type -> server.TestSuite - 12, // 54: server.Runner.DeleteTestSuite:input_type -> server.TestSuiteIdentity - 13, // 55: server.Runner.DuplicateTestSuite:input_type -> server.TestSuiteDuplicate - 13, // 56: server.Runner.RenameTestSuite:input_type -> server.TestSuiteDuplicate - 12, // 57: server.Runner.GetTestSuiteYaml:input_type -> server.TestSuiteIdentity - 12, // 58: server.Runner.ListTestCase:input_type -> server.TestSuiteIdentity - 5, // 59: server.Runner.RunTestCase:input_type -> server.TestCaseIdentity - 16, // 60: server.Runner.BatchRun:input_type -> server.BatchTestTask - 5, // 61: server.Runner.GetTestCase:input_type -> server.TestCaseIdentity - 22, // 62: server.Runner.CreateTestCase:input_type -> server.TestCaseWithSuite - 22, // 63: server.Runner.UpdateTestCase:input_type -> server.TestCaseWithSuite - 5, // 64: server.Runner.DeleteTestCase:input_type -> server.TestCaseIdentity - 14, // 65: server.Runner.DuplicateTestCase:input_type -> server.TestCaseDuplicate - 14, // 66: server.Runner.RenameTestCase:input_type -> server.TestCaseDuplicate - 12, // 67: server.Runner.GetSuggestedAPIs:input_type -> server.TestSuiteIdentity - 48, // 68: server.Runner.GetHistorySuites:input_type -> server.Empty - 25, // 69: server.Runner.GetHistoryTestCaseWithResult:input_type -> server.HistoryTestCase - 25, // 70: server.Runner.GetHistoryTestCase:input_type -> server.HistoryTestCase - 25, // 71: server.Runner.DeleteHistoryTestCase:input_type -> server.HistoryTestCase - 25, // 72: server.Runner.DeleteAllHistoryTestCase:input_type -> server.HistoryTestCase - 24, // 73: server.Runner.GetTestCaseAllHistory:input_type -> server.TestCase - 48, // 74: server.Runner.ListCodeGenerator:input_type -> server.Empty - 41, // 75: server.Runner.GenerateCode:input_type -> server.CodeGenerateRequest - 41, // 76: server.Runner.HistoryGenerateCode:input_type -> server.CodeGenerateRequest - 48, // 77: server.Runner.ListConverter:input_type -> server.Empty - 41, // 78: server.Runner.ConvertTestSuite:input_type -> server.CodeGenerateRequest - 48, // 79: server.Runner.PopularHeaders:input_type -> server.Empty - 33, // 80: server.Runner.FunctionsQuery:input_type -> server.SimpleQuery - 33, // 81: server.Runner.FunctionsQueryStream:input_type -> server.SimpleQuery - 48, // 82: server.Runner.GetVersion:input_type -> server.Empty - 48, // 83: server.Runner.Sample:input_type -> server.Empty - 24, // 84: server.Runner.DownloadResponseFile:input_type -> server.TestCase - 48, // 85: server.Runner.GetStoreKinds:input_type -> server.Empty - 48, // 86: server.Runner.GetStores:input_type -> server.Empty - 35, // 87: server.Runner.CreateStore:input_type -> server.Store - 35, // 88: server.Runner.UpdateStore:input_type -> server.Store - 35, // 89: server.Runner.DeleteStore:input_type -> server.Store - 33, // 90: server.Runner.VerifyStore:input_type -> server.SimpleQuery - 48, // 91: server.Runner.GetSecrets:input_type -> server.Empty - 43, // 92: server.Runner.CreateSecret:input_type -> server.Secret - 43, // 93: server.Runner.DeleteSecret:input_type -> server.Secret - 43, // 94: server.Runner.UpdateSecret:input_type -> server.Secret - 45, // 95: server.Runner.PProf:input_type -> server.PProfRequest - 8, // 96: server.RunnerExtension.Run:input_type -> server.TestSuiteWithCase - 49, // 97: server.Mock.Reload:input_type -> server.MockConfig - 48, // 98: server.Mock.GetConfig:input_type -> server.Empty - 17, // 99: server.Runner.Run:output_type -> server.TestResult - 17, // 100: server.Runner.RunTestSuite:output_type -> server.TestResult - 0, // 101: server.Runner.GetSuites:output_type -> server.Suites - 19, // 102: server.Runner.CreateTestSuite:output_type -> server.HelloReply - 38, // 103: server.Runner.ImportTestSuite:output_type -> server.CommonResult - 7, // 104: server.Runner.GetTestSuite:output_type -> server.TestSuite - 19, // 105: server.Runner.UpdateTestSuite:output_type -> server.HelloReply - 19, // 106: server.Runner.DeleteTestSuite:output_type -> server.HelloReply - 19, // 107: server.Runner.DuplicateTestSuite:output_type -> server.HelloReply - 19, // 108: server.Runner.RenameTestSuite:output_type -> server.HelloReply - 20, // 109: server.Runner.GetTestSuiteYaml:output_type -> server.YamlData - 21, // 110: server.Runner.ListTestCase:output_type -> server.Suite - 30, // 111: server.Runner.RunTestCase:output_type -> server.TestCaseResult - 17, // 112: server.Runner.BatchRun:output_type -> server.TestResult - 24, // 113: server.Runner.GetTestCase:output_type -> server.TestCase - 19, // 114: server.Runner.CreateTestCase:output_type -> server.HelloReply - 19, // 115: server.Runner.UpdateTestCase:output_type -> server.HelloReply - 19, // 116: server.Runner.DeleteTestCase:output_type -> server.HelloReply - 19, // 117: server.Runner.DuplicateTestCase:output_type -> server.HelloReply - 19, // 118: server.Runner.RenameTestCase:output_type -> server.HelloReply - 23, // 119: server.Runner.GetSuggestedAPIs:output_type -> server.TestCases - 2, // 120: server.Runner.GetHistorySuites:output_type -> server.HistorySuites - 18, // 121: server.Runner.GetHistoryTestCaseWithResult:output_type -> server.HistoryTestResult - 25, // 122: server.Runner.GetHistoryTestCase:output_type -> server.HistoryTestCase - 19, // 123: server.Runner.DeleteHistoryTestCase:output_type -> server.HelloReply - 19, // 124: server.Runner.DeleteAllHistoryTestCase:output_type -> server.HelloReply - 26, // 125: server.Runner.GetTestCaseAllHistory:output_type -> server.HistoryTestCases - 39, // 126: server.Runner.ListCodeGenerator:output_type -> server.SimpleList - 38, // 127: server.Runner.GenerateCode:output_type -> server.CommonResult - 38, // 128: server.Runner.HistoryGenerateCode:output_type -> server.CommonResult - 39, // 129: server.Runner.ListConverter:output_type -> server.SimpleList - 38, // 130: server.Runner.ConvertTestSuite:output_type -> server.CommonResult - 32, // 131: server.Runner.PopularHeaders:output_type -> server.Pairs - 32, // 132: server.Runner.FunctionsQuery:output_type -> server.Pairs - 32, // 133: server.Runner.FunctionsQueryStream:output_type -> server.Pairs - 50, // 134: server.Runner.GetVersion:output_type -> server.Version - 19, // 135: server.Runner.Sample:output_type -> server.HelloReply - 47, // 136: server.Runner.DownloadResponseFile:output_type -> server.FileData - 36, // 137: server.Runner.GetStoreKinds:output_type -> server.StoreKinds - 34, // 138: server.Runner.GetStores:output_type -> server.Stores - 35, // 139: server.Runner.CreateStore:output_type -> server.Store - 35, // 140: server.Runner.UpdateStore:output_type -> server.Store - 35, // 141: server.Runner.DeleteStore:output_type -> server.Store - 44, // 142: server.Runner.VerifyStore:output_type -> server.ExtensionStatus - 42, // 143: server.Runner.GetSecrets:output_type -> server.Secrets - 38, // 144: server.Runner.CreateSecret:output_type -> server.CommonResult - 38, // 145: server.Runner.DeleteSecret:output_type -> server.CommonResult - 38, // 146: server.Runner.UpdateSecret:output_type -> server.CommonResult - 46, // 147: server.Runner.PProf:output_type -> server.PProfData - 38, // 148: server.RunnerExtension.Run:output_type -> server.CommonResult - 48, // 149: server.Mock.Reload:output_type -> server.Empty - 49, // 150: server.Mock.GetConfig:output_type -> server.MockConfig - 99, // [99:151] is the sub-list for method output_type - 47, // [47:99] is the sub-list for method input_type - 47, // [47:47] is the sub-list for extension type_name - 47, // [47:47] is the sub-list for extension extendee - 0, // [0:47] is the sub-list for field type_name + 54, // 0: server.Suites.data:type_name -> server.Suites.DataEntry + 55, // 1: server.HistorySuites.data:type_name -> server.HistorySuites.DataEntry + 4, // 2: server.HistoryItems.data:type_name -> server.HistoryCaseIdentity + 31, // 3: server.TestCaseIdentity.parameters:type_name -> server.Pair + 31, // 4: server.TestSuite.param:type_name -> server.Pair + 9, // 5: server.TestSuite.spec:type_name -> server.APISpec + 51, // 6: server.TestSuite.proxy:type_name -> server.ProxyConfig + 7, // 7: server.TestSuiteWithCase.suite:type_name -> server.TestSuite + 24, // 8: server.TestSuiteWithCase.case:type_name -> server.TestCase + 11, // 9: server.APISpec.rpc:type_name -> server.RPC + 10, // 10: server.APISpec.secure:type_name -> server.Secure + 56, // 11: server.TestTask.env:type_name -> server.TestTask.EnvEntry + 31, // 12: server.TestTask.parameters:type_name -> server.Pair + 31, // 13: server.BatchTestTask.parameters:type_name -> server.Pair + 30, // 14: server.TestResult.testCaseResult:type_name -> server.TestCaseResult + 30, // 15: server.HistoryTestResult.testCaseResult:type_name -> server.TestCaseResult + 25, // 16: server.HistoryTestResult.data:type_name -> server.HistoryTestCase + 57, // 17: server.HistoryTestResult.createTime:type_name -> google.protobuf.Timestamp + 24, // 18: server.Suite.items:type_name -> server.TestCase + 24, // 19: server.TestCaseWithSuite.data:type_name -> server.TestCase + 24, // 20: server.TestCases.data:type_name -> server.TestCase + 27, // 21: server.TestCase.request:type_name -> server.Request + 28, // 22: server.TestCase.response:type_name -> server.Response + 57, // 23: server.HistoryTestCase.createTime:type_name -> google.protobuf.Timestamp + 31, // 24: server.HistoryTestCase.suiteParam:type_name -> server.Pair + 9, // 25: server.HistoryTestCase.suiteSpec:type_name -> server.APISpec + 27, // 26: server.HistoryTestCase.request:type_name -> server.Request + 28, // 27: server.HistoryTestCase.response:type_name -> server.Response + 31, // 28: server.HistoryTestCase.historyHeader:type_name -> server.Pair + 25, // 29: server.HistoryTestCases.data:type_name -> server.HistoryTestCase + 31, // 30: server.Request.header:type_name -> server.Pair + 31, // 31: server.Request.query:type_name -> server.Pair + 31, // 32: server.Request.cookie:type_name -> server.Pair + 31, // 33: server.Request.form:type_name -> server.Pair + 31, // 34: server.Response.header:type_name -> server.Pair + 31, // 35: server.Response.bodyFieldsExpect:type_name -> server.Pair + 29, // 36: server.Response.ConditionalVerify:type_name -> server.ConditionalVerify + 31, // 37: server.TestCaseResult.header:type_name -> server.Pair + 31, // 38: server.Pairs.data:type_name -> server.Pair + 35, // 39: server.Stores.data:type_name -> server.Store + 31, // 40: server.Store.properties:type_name -> server.Pair + 37, // 41: server.Store.kind:type_name -> server.StoreKind + 37, // 42: server.StoreKinds.data:type_name -> server.StoreKind + 31, // 43: server.SimpleList.data:type_name -> server.Pair + 43, // 44: server.Secrets.data:type_name -> server.Secret + 31, // 45: server.DataQueryResult.data:type_name -> server.Pair + 32, // 46: server.DataQueryResult.items:type_name -> server.Pairs + 1, // 47: server.Suites.DataEntry.value:type_name -> server.Items + 3, // 48: server.HistorySuites.DataEntry.value:type_name -> server.HistoryItems + 15, // 49: server.Runner.Run:input_type -> server.TestTask + 12, // 50: server.Runner.RunTestSuite:input_type -> server.TestSuiteIdentity + 48, // 51: server.Runner.GetSuites:input_type -> server.Empty + 12, // 52: server.Runner.CreateTestSuite:input_type -> server.TestSuiteIdentity + 6, // 53: server.Runner.ImportTestSuite:input_type -> server.TestSuiteSource + 12, // 54: server.Runner.GetTestSuite:input_type -> server.TestSuiteIdentity + 7, // 55: server.Runner.UpdateTestSuite:input_type -> server.TestSuite + 12, // 56: server.Runner.DeleteTestSuite:input_type -> server.TestSuiteIdentity + 13, // 57: server.Runner.DuplicateTestSuite:input_type -> server.TestSuiteDuplicate + 13, // 58: server.Runner.RenameTestSuite:input_type -> server.TestSuiteDuplicate + 12, // 59: server.Runner.GetTestSuiteYaml:input_type -> server.TestSuiteIdentity + 12, // 60: server.Runner.ListTestCase:input_type -> server.TestSuiteIdentity + 5, // 61: server.Runner.RunTestCase:input_type -> server.TestCaseIdentity + 16, // 62: server.Runner.BatchRun:input_type -> server.BatchTestTask + 5, // 63: server.Runner.GetTestCase:input_type -> server.TestCaseIdentity + 22, // 64: server.Runner.CreateTestCase:input_type -> server.TestCaseWithSuite + 22, // 65: server.Runner.UpdateTestCase:input_type -> server.TestCaseWithSuite + 5, // 66: server.Runner.DeleteTestCase:input_type -> server.TestCaseIdentity + 14, // 67: server.Runner.DuplicateTestCase:input_type -> server.TestCaseDuplicate + 14, // 68: server.Runner.RenameTestCase:input_type -> server.TestCaseDuplicate + 12, // 69: server.Runner.GetSuggestedAPIs:input_type -> server.TestSuiteIdentity + 48, // 70: server.Runner.GetHistorySuites:input_type -> server.Empty + 25, // 71: server.Runner.GetHistoryTestCaseWithResult:input_type -> server.HistoryTestCase + 25, // 72: server.Runner.GetHistoryTestCase:input_type -> server.HistoryTestCase + 25, // 73: server.Runner.DeleteHistoryTestCase:input_type -> server.HistoryTestCase + 25, // 74: server.Runner.DeleteAllHistoryTestCase:input_type -> server.HistoryTestCase + 24, // 75: server.Runner.GetTestCaseAllHistory:input_type -> server.TestCase + 48, // 76: server.Runner.ListCodeGenerator:input_type -> server.Empty + 41, // 77: server.Runner.GenerateCode:input_type -> server.CodeGenerateRequest + 41, // 78: server.Runner.HistoryGenerateCode:input_type -> server.CodeGenerateRequest + 48, // 79: server.Runner.ListConverter:input_type -> server.Empty + 41, // 80: server.Runner.ConvertTestSuite:input_type -> server.CodeGenerateRequest + 48, // 81: server.Runner.PopularHeaders:input_type -> server.Empty + 33, // 82: server.Runner.FunctionsQuery:input_type -> server.SimpleQuery + 33, // 83: server.Runner.FunctionsQueryStream:input_type -> server.SimpleQuery + 48, // 84: server.Runner.GetVersion:input_type -> server.Empty + 48, // 85: server.Runner.Sample:input_type -> server.Empty + 24, // 86: server.Runner.DownloadResponseFile:input_type -> server.TestCase + 48, // 87: server.Runner.GetStoreKinds:input_type -> server.Empty + 48, // 88: server.Runner.GetStores:input_type -> server.Empty + 35, // 89: server.Runner.CreateStore:input_type -> server.Store + 35, // 90: server.Runner.UpdateStore:input_type -> server.Store + 35, // 91: server.Runner.DeleteStore:input_type -> server.Store + 33, // 92: server.Runner.VerifyStore:input_type -> server.SimpleQuery + 48, // 93: server.Runner.GetSecrets:input_type -> server.Empty + 43, // 94: server.Runner.CreateSecret:input_type -> server.Secret + 43, // 95: server.Runner.DeleteSecret:input_type -> server.Secret + 43, // 96: server.Runner.UpdateSecret:input_type -> server.Secret + 45, // 97: server.Runner.PProf:input_type -> server.PProfRequest + 8, // 98: server.RunnerExtension.Run:input_type -> server.TestSuiteWithCase + 49, // 99: server.Mock.Reload:input_type -> server.MockConfig + 48, // 100: server.Mock.GetConfig:input_type -> server.Empty + 52, // 101: server.DataServer.Query:input_type -> server.DataQuery + 17, // 102: server.Runner.Run:output_type -> server.TestResult + 17, // 103: server.Runner.RunTestSuite:output_type -> server.TestResult + 0, // 104: server.Runner.GetSuites:output_type -> server.Suites + 19, // 105: server.Runner.CreateTestSuite:output_type -> server.HelloReply + 38, // 106: server.Runner.ImportTestSuite:output_type -> server.CommonResult + 7, // 107: server.Runner.GetTestSuite:output_type -> server.TestSuite + 19, // 108: server.Runner.UpdateTestSuite:output_type -> server.HelloReply + 19, // 109: server.Runner.DeleteTestSuite:output_type -> server.HelloReply + 19, // 110: server.Runner.DuplicateTestSuite:output_type -> server.HelloReply + 19, // 111: server.Runner.RenameTestSuite:output_type -> server.HelloReply + 20, // 112: server.Runner.GetTestSuiteYaml:output_type -> server.YamlData + 21, // 113: server.Runner.ListTestCase:output_type -> server.Suite + 30, // 114: server.Runner.RunTestCase:output_type -> server.TestCaseResult + 17, // 115: server.Runner.BatchRun:output_type -> server.TestResult + 24, // 116: server.Runner.GetTestCase:output_type -> server.TestCase + 19, // 117: server.Runner.CreateTestCase:output_type -> server.HelloReply + 19, // 118: server.Runner.UpdateTestCase:output_type -> server.HelloReply + 19, // 119: server.Runner.DeleteTestCase:output_type -> server.HelloReply + 19, // 120: server.Runner.DuplicateTestCase:output_type -> server.HelloReply + 19, // 121: server.Runner.RenameTestCase:output_type -> server.HelloReply + 23, // 122: server.Runner.GetSuggestedAPIs:output_type -> server.TestCases + 2, // 123: server.Runner.GetHistorySuites:output_type -> server.HistorySuites + 18, // 124: server.Runner.GetHistoryTestCaseWithResult:output_type -> server.HistoryTestResult + 25, // 125: server.Runner.GetHistoryTestCase:output_type -> server.HistoryTestCase + 19, // 126: server.Runner.DeleteHistoryTestCase:output_type -> server.HelloReply + 19, // 127: server.Runner.DeleteAllHistoryTestCase:output_type -> server.HelloReply + 26, // 128: server.Runner.GetTestCaseAllHistory:output_type -> server.HistoryTestCases + 39, // 129: server.Runner.ListCodeGenerator:output_type -> server.SimpleList + 38, // 130: server.Runner.GenerateCode:output_type -> server.CommonResult + 38, // 131: server.Runner.HistoryGenerateCode:output_type -> server.CommonResult + 39, // 132: server.Runner.ListConverter:output_type -> server.SimpleList + 38, // 133: server.Runner.ConvertTestSuite:output_type -> server.CommonResult + 32, // 134: server.Runner.PopularHeaders:output_type -> server.Pairs + 32, // 135: server.Runner.FunctionsQuery:output_type -> server.Pairs + 32, // 136: server.Runner.FunctionsQueryStream:output_type -> server.Pairs + 50, // 137: server.Runner.GetVersion:output_type -> server.Version + 19, // 138: server.Runner.Sample:output_type -> server.HelloReply + 47, // 139: server.Runner.DownloadResponseFile:output_type -> server.FileData + 36, // 140: server.Runner.GetStoreKinds:output_type -> server.StoreKinds + 34, // 141: server.Runner.GetStores:output_type -> server.Stores + 35, // 142: server.Runner.CreateStore:output_type -> server.Store + 35, // 143: server.Runner.UpdateStore:output_type -> server.Store + 35, // 144: server.Runner.DeleteStore:output_type -> server.Store + 44, // 145: server.Runner.VerifyStore:output_type -> server.ExtensionStatus + 42, // 146: server.Runner.GetSecrets:output_type -> server.Secrets + 38, // 147: server.Runner.CreateSecret:output_type -> server.CommonResult + 38, // 148: server.Runner.DeleteSecret:output_type -> server.CommonResult + 38, // 149: server.Runner.UpdateSecret:output_type -> server.CommonResult + 46, // 150: server.Runner.PProf:output_type -> server.PProfData + 38, // 151: server.RunnerExtension.Run:output_type -> server.CommonResult + 48, // 152: server.Mock.Reload:output_type -> server.Empty + 49, // 153: server.Mock.GetConfig:output_type -> server.MockConfig + 53, // 154: server.DataServer.Query:output_type -> server.DataQueryResult + 102, // [102:155] is the sub-list for method output_type + 49, // [49:102] is the sub-list for method input_type + 49, // [49:49] is the sub-list for extension type_name + 49, // [49:49] is the sub-list for extension extendee + 0, // [0:49] is the sub-list for field type_name } func init() { file_pkg_server_server_proto_init() } @@ -4931,6 +5071,30 @@ func file_pkg_server_server_proto_init() { return nil } } + file_pkg_server_server_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DataQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_server_server_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DataQueryResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -4938,9 +5102,9 @@ func file_pkg_server_server_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_pkg_server_server_proto_rawDesc, NumEnums: 0, - NumMessages: 55, + NumMessages: 57, NumExtensions: 0, - NumServices: 3, + NumServices: 4, }, GoTypes: file_pkg_server_server_proto_goTypes, DependencyIndexes: file_pkg_server_server_proto_depIdxs, diff --git a/pkg/server/server.pb.gw.go b/pkg/server/server.pb.gw.go index 2b949b95a..b28e0dc9d 100644 --- a/pkg/server/server.pb.gw.go +++ b/pkg/server/server.pb.gw.go @@ -2472,6 +2472,32 @@ func local_request_Mock_GetConfig_0(ctx context.Context, marshaler runtime.Marsh } +func request_DataServer_Query_0(ctx context.Context, marshaler runtime.Marshaler, client DataServerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DataQuery + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Query(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_DataServer_Query_0(ctx context.Context, marshaler runtime.Marshaler, server DataServerServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DataQuery + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Query(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterRunnerHandlerServer registers the http handlers for service Runner to "mux". // UnaryRPC :call RunnerServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -3745,6 +3771,40 @@ func RegisterMockHandlerServer(ctx context.Context, mux *runtime.ServeMux, serve return nil } +// RegisterDataServerHandlerServer registers the http handlers for service DataServer to "mux". +// UnaryRPC :call DataServerServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterDataServerHandlerFromEndpoint instead. +func RegisterDataServerHandlerServer(ctx context.Context, mux *runtime.ServeMux, server DataServerServer) error { + + mux.Handle("POST", pattern_DataServer_Query_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/server.DataServer/Query", runtime.WithHTTPPathPattern("/api/v1/data/query")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_DataServer_Query_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_DataServer_Query_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + // RegisterRunnerHandlerFromEndpoint is same as RegisterRunnerHandler but // automatically dials to "endpoint" and closes the connection when "ctx" gets done. func RegisterRunnerHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { @@ -5231,3 +5291,74 @@ var ( forward_Mock_GetConfig_0 = runtime.ForwardResponseMessage ) + +// RegisterDataServerHandlerFromEndpoint is same as RegisterDataServerHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterDataServerHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.DialContext(ctx, endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterDataServerHandler(ctx, mux, conn) +} + +// RegisterDataServerHandler registers the http handlers for service DataServer to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterDataServerHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterDataServerHandlerClient(ctx, mux, NewDataServerClient(conn)) +} + +// RegisterDataServerHandlerClient registers the http handlers for service DataServer +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "DataServerClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "DataServerClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "DataServerClient" to call the correct interceptors. +func RegisterDataServerHandlerClient(ctx context.Context, mux *runtime.ServeMux, client DataServerClient) error { + + mux.Handle("POST", pattern_DataServer_Query_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/server.DataServer/Query", runtime.WithHTTPPathPattern("/api/v1/data/query")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_DataServer_Query_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_DataServer_Query_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_DataServer_Query_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "data", "query"}, "")) +) + +var ( + forward_DataServer_Query_0 = runtime.ForwardResponseMessage +) diff --git a/pkg/server/server.proto b/pkg/server/server.proto index 7e8872186..c04300d32 100644 --- a/pkg/server/server.proto +++ b/pkg/server/server.proto @@ -188,7 +188,7 @@ service Runner { post: "/api/v1/codeGenerators/history/generate" body: "*" }; - } + } // converter rpc ListConverter(Empty) returns (SimpleList) { @@ -644,3 +644,23 @@ message ProxyConfig { string https = 2; // HTTPS proxy URL string no = 3; // Comma-separated list of hosts to exclude from proxying } + +service DataServer { + rpc Query(DataQuery) returns (DataQueryResult) { + option (google.api.http) = { + post: "/api/v1/data/query" + body: "*" + }; + } +} + +message DataQuery { + string type = 1; + string key = 2; + string sql = 3; +} + +message DataQueryResult { + repeated Pair data = 1; + repeated Pairs items = 2; +} diff --git a/pkg/server/server.swagger.json b/pkg/server/server.swagger.json index b90b66c9d..79f4189cf 100644 --- a/pkg/server/server.swagger.json +++ b/pkg/server/server.swagger.json @@ -13,6 +13,9 @@ }, { "name": "Mock" + }, + { + "name": "DataServer" } ], "consumes": [ @@ -206,6 +209,38 @@ ] } }, + "/api/v1/data/query": { + "post": { + "operationId": "DataServer_Query", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/serverDataQueryResult" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/serverDataQuery" + } + } + ], + "tags": [ + "DataServer" + ] + } + }, "/api/v1/downloadFile/{response.body}": { "post": { "operationId": "Runner_DownloadResponseFile", @@ -2784,6 +2819,39 @@ } } }, + "serverDataQuery": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "key": { + "type": "string" + }, + "sql": { + "type": "string" + } + } + }, + "serverDataQueryResult": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/serverPair" + } + }, + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/serverPairs" + } + } + } + }, "serverEmpty": { "type": "object" }, diff --git a/pkg/server/server_grpc.pb.go b/pkg/server/server_grpc.pb.go index f80c04523..529234cd7 100644 --- a/pkg/server/server_grpc.pb.go +++ b/pkg/server/server_grpc.pb.go @@ -2158,3 +2158,89 @@ var Mock_ServiceDesc = grpc.ServiceDesc{ Streams: []grpc.StreamDesc{}, Metadata: "pkg/server/server.proto", } + +// DataServerClient is the client API for DataServer service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type DataServerClient interface { + Query(ctx context.Context, in *DataQuery, opts ...grpc.CallOption) (*DataQueryResult, error) +} + +type dataServerClient struct { + cc grpc.ClientConnInterface +} + +func NewDataServerClient(cc grpc.ClientConnInterface) DataServerClient { + return &dataServerClient{cc} +} + +func (c *dataServerClient) Query(ctx context.Context, in *DataQuery, opts ...grpc.CallOption) (*DataQueryResult, error) { + out := new(DataQueryResult) + err := c.cc.Invoke(ctx, "/server.DataServer/Query", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DataServerServer is the server API for DataServer service. +// All implementations must embed UnimplementedDataServerServer +// for forward compatibility +type DataServerServer interface { + Query(context.Context, *DataQuery) (*DataQueryResult, error) + mustEmbedUnimplementedDataServerServer() +} + +// UnimplementedDataServerServer must be embedded to have forward compatible implementations. +type UnimplementedDataServerServer struct { +} + +func (UnimplementedDataServerServer) Query(context.Context, *DataQuery) (*DataQueryResult, error) { + return nil, status.Errorf(codes.Unimplemented, "method Query not implemented") +} +func (UnimplementedDataServerServer) mustEmbedUnimplementedDataServerServer() {} + +// UnsafeDataServerServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to DataServerServer will +// result in compilation errors. +type UnsafeDataServerServer interface { + mustEmbedUnimplementedDataServerServer() +} + +func RegisterDataServerServer(s grpc.ServiceRegistrar, srv DataServerServer) { + s.RegisterService(&DataServer_ServiceDesc, srv) +} + +func _DataServer_Query_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DataQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DataServerServer).Query(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/server.DataServer/Query", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DataServerServer).Query(ctx, req.(*DataQuery)) + } + return interceptor(ctx, in, info, handler) +} + +// DataServer_ServiceDesc is the grpc.ServiceDesc for DataServer service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var DataServer_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "server.DataServer", + HandlerType: (*DataServerServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Query", + Handler: _DataServer_Query_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "pkg/server/server.proto", +} diff --git a/pkg/server/store_ext_manager.go b/pkg/server/store_ext_manager.go index 7b47cce92..c6148de2c 100644 --- a/pkg/server/store_ext_manager.go +++ b/pkg/server/store_ext_manager.go @@ -103,7 +103,7 @@ func (s *storeExtManager) Start(name, socket string) (err error) { } else { binaryPath, err = s.execer.LookPath(name) if err != nil { - err = fmt.Errorf("not found extension, try to download it.") + err = fmt.Errorf("not found extension, try to download it, error: %v", err) go func() { reader, dErr := s.ociDownloader.Download(name, "", "") if dErr != nil { diff --git a/pkg/testing/loader.go b/pkg/testing/loader.go index 6348c4061..81cc44a9c 100644 --- a/pkg/testing/loader.go +++ b/pkg/testing/loader.go @@ -26,6 +26,8 @@ type Loader interface { Verify() (readOnly bool, err error) PProf(name string) []byte + + Query(query map[string]string) (result map[string]string, items []map[string]string, err error) } type Writer interface { diff --git a/pkg/testing/loader_file.go b/pkg/testing/loader_file.go index a1e381875..a686f5f5b 100644 --- a/pkg/testing/loader_file.go +++ b/pkg/testing/loader_file.go @@ -514,3 +514,10 @@ func (l *fileLoader) PProf(string) []byte { func (l *fileLoader) Close() { // not support } + +func (l *fileLoader) Query(query map[string]string) (result map[string]string, items []map[string]string, err error) { + result = map[string]string{ + "message": "not support", + } + return +} diff --git a/pkg/testing/loader_non.go b/pkg/testing/loader_non.go index a15d17fa4..9ab0bcdeb 100644 --- a/pkg/testing/loader_non.go +++ b/pkg/testing/loader_non.go @@ -149,3 +149,7 @@ func (l *nonLoader) PProf(string) []byte { func (l *nonLoader) Close() { // not support } + +func (l *nonLoader) Query(query map[string]string) (result map[string]string, items []map[string]string, err error) { + return +} diff --git a/pkg/testing/local/local_secret_service.go b/pkg/testing/local/local_secret_service.go index e59eab458..eedf766d9 100644 --- a/pkg/testing/local/local_secret_service.go +++ b/pkg/testing/local/local_secret_service.go @@ -121,6 +121,11 @@ func (s *localSecretService) UpdateSecret(ctx context.Context, in *server.Secret return } +func (s *localSecretService) Query(query map[string]string) (result map[string]string, err error) { + result = make(map[string]string) + return +} + func (s *localSecretService) getDataFilePath() string { return filepath.Join(s.dataDir, "secret.yaml") } diff --git a/pkg/testing/remote/grpc_store.go b/pkg/testing/remote/grpc_store.go index 429873d34..bf1c26e86 100644 --- a/pkg/testing/remote/grpc_store.go +++ b/pkg/testing/remote/grpc_store.go @@ -17,297 +17,311 @@ limitations under the License. package remote import ( - context "context" - "errors" - "time" + context "context" + "errors" + "time" - "github.com/linuxsuren/api-testing/pkg/logging" - server "github.com/linuxsuren/api-testing/pkg/server" - "github.com/linuxsuren/api-testing/pkg/testing" + "github.com/linuxsuren/api-testing/pkg/logging" + server "github.com/linuxsuren/api-testing/pkg/server" + "github.com/linuxsuren/api-testing/pkg/testing" - "google.golang.org/grpc" + "google.golang.org/grpc" ) var ( - grpcLogger = logging.DefaultLogger(logging.LogLevelInfo).WithName("grpc") + grpcLogger = logging.DefaultLogger(logging.LogLevelInfo).WithName("grpc") ) type gRPCLoader struct { - store *testing.Store - client LoaderClient - ctx context.Context - conn *grpc.ClientConn + store *testing.Store + client LoaderClient + ctx context.Context + conn *grpc.ClientConn } func NewGRPCloaderFromStore() testing.StoreWriterFactory { - return &gRPCLoader{} + return &gRPCLoader{} } func (g *gRPCLoader) NewInstance(store testing.Store) (writer testing.Writer, err error) { - address := store.Kind.URL + address := store.Kind.URL - var conn *grpc.ClientConn - if conn, err = grpc.Dial(address, grpc.WithInsecure()); err == nil { - writer = &gRPCLoader{ - store: &store, - ctx: WithStoreContext(context.Background(), &store), - client: NewLoaderClient(conn), - conn: conn, - } - } - return + var conn *grpc.ClientConn + if conn, err = grpc.Dial(address, grpc.WithInsecure()); err == nil { + writer = &gRPCLoader{ + store: &store, + ctx: WithStoreContext(context.Background(), &store), + client: NewLoaderClient(conn), + conn: conn, + } + } + return } func (g *gRPCLoader) HasMore() bool { - // nothing to do - return false + // nothing to do + return false } func (g *gRPCLoader) Load() ([]byte, error) { - // nothing to do - return nil, nil + // nothing to do + return nil, nil } func (g *gRPCLoader) Put(path string) error { - // nothing to do - return nil + // nothing to do + return nil } func (g *gRPCLoader) GetContext() string { - // nothing to do - return "" + // nothing to do + return "" } func (g *gRPCLoader) GetCount() int { - // nothing to do - return 0 + // nothing to do + return 0 } func (g *gRPCLoader) Reset() { - // nothing to do + // nothing to do } func (g *gRPCLoader) GetTestSuiteYaml(suite string) (testSuiteYaml []byte, err error) { - var testSuite testing.TestSuite - if testSuite, err = g.GetTestSuite(suite, true); err == nil { - testSuiteYaml, err = testing.ToYAML(&testSuite) - } - return + var testSuite testing.TestSuite + if testSuite, err = g.GetTestSuite(suite, true); err == nil { + testSuiteYaml, err = testing.ToYAML(&testSuite) + } + return } func (g *gRPCLoader) ListTestCase(suite string) (testcases []testing.TestCase, err error) { - var testCases *server.TestCases - testCases, err = g.client.ListTestCases(g.ctx, &TestSuite{ - Name: suite, - }) - - if err == nil && testCases.Data != nil { - for _, item := range testCases.Data { - if item.Name == "" { - continue - } - testcases = append(testcases, ConvertToNormalTestCase(item)) - } - } - return + var testCases *server.TestCases + testCases, err = g.client.ListTestCases(g.ctx, &TestSuite{ + Name: suite, + }) + + if err == nil && testCases.Data != nil { + for _, item := range testCases.Data { + if item.Name == "" { + continue + } + testcases = append(testcases, ConvertToNormalTestCase(item)) + } + } + return } func (g *gRPCLoader) GetTestCase(suite, name string) (testcase testing.TestCase, err error) { - var result *server.TestCase - result, err = g.client.GetTestCase(g.ctx, &server.TestCase{ - Name: name, - SuiteName: suite, - }) - if err == nil && result != nil { - testcase = ConvertToNormalTestCase(result) - } - return + var result *server.TestCase + result, err = g.client.GetTestCase(g.ctx, &server.TestCase{ + Name: name, + SuiteName: suite, + }) + if err == nil && result != nil { + testcase = ConvertToNormalTestCase(result) + } + return } func (g *gRPCLoader) GetHistoryTestCaseWithResult(id string) (result testing.HistoryTestResult, err error) { - var historyTestResult *server.HistoryTestResult - historyTestResult, err = g.client.GetHistoryTestCaseWithResult(g.ctx, &server.HistoryTestCase{ - ID: id, - }) - if err == nil && historyTestResult != nil { - result = ConvertToNormalTestCaseResult(historyTestResult) - } - return + var historyTestResult *server.HistoryTestResult + historyTestResult, err = g.client.GetHistoryTestCaseWithResult(g.ctx, &server.HistoryTestCase{ + ID: id, + }) + if err == nil && historyTestResult != nil { + result = ConvertToNormalTestCaseResult(historyTestResult) + } + return } func (g *gRPCLoader) GetHistoryTestCase(id string) (result testing.HistoryTestCase, err error) { - var historyTestCase *server.HistoryTestCase - historyTestCase, err = g.client.GetHistoryTestCase(g.ctx, &server.HistoryTestCase{ - ID: id, - }) - if err == nil && historyTestCase != nil { - result = ConvertToNormalHistoryTestCase(historyTestCase) - } - return + var historyTestCase *server.HistoryTestCase + historyTestCase, err = g.client.GetHistoryTestCase(g.ctx, &server.HistoryTestCase{ + ID: id, + }) + if err == nil && historyTestCase != nil { + result = ConvertToNormalHistoryTestCase(historyTestCase) + } + return } func (g *gRPCLoader) CreateTestCase(suite string, testcase testing.TestCase) (err error) { - payload := ConvertToGRPCTestCase(testcase) - payload.SuiteName = suite - _, err = g.client.CreateTestCase(g.ctx, payload) - return + payload := ConvertToGRPCTestCase(testcase) + payload.SuiteName = suite + _, err = g.client.CreateTestCase(g.ctx, payload) + return } func (g *gRPCLoader) UpdateTestCase(suite string, testcase testing.TestCase) (err error) { - payload := ConvertToGRPCTestCase(testcase) - payload.SuiteName = suite - _, err = g.client.UpdateTestCase(g.ctx, payload) - return + payload := ConvertToGRPCTestCase(testcase) + payload.SuiteName = suite + _, err = g.client.UpdateTestCase(g.ctx, payload) + return } func (g *gRPCLoader) DeleteTestCase(suite, testcase string) (err error) { - _, err = g.client.DeleteTestCase(g.ctx, &server.TestCase{ - Name: testcase, - SuiteName: suite, - }) - return + _, err = g.client.DeleteTestCase(g.ctx, &server.TestCase{ + Name: testcase, + SuiteName: suite, + }) + return } func (g *gRPCLoader) RenameTestCase(suite, oldName, newName string) (err error) { - _, err = g.client.RenameTestCase(g.ctx, &server.TestCaseDuplicate{ - SourceCaseName: oldName, - SourceSuiteName: suite, - TargetCaseName: newName, - }) - return + _, err = g.client.RenameTestCase(g.ctx, &server.TestCaseDuplicate{ + SourceCaseName: oldName, + SourceSuiteName: suite, + TargetCaseName: newName, + }) + return } func (g *gRPCLoader) CreateHistoryTestCase(testcaseResult testing.TestCaseResult, testSuite *testing.TestSuite, historyHeader map[string]string) (err error) { - payload := ConvertToGRPCHistoryTestCaseResult(testcaseResult, testSuite, historyHeader) - _, err = g.client.CreateTestCaseHistory(g.ctx, payload) - return + payload := ConvertToGRPCHistoryTestCaseResult(testcaseResult, testSuite, historyHeader) + _, err = g.client.CreateTestCaseHistory(g.ctx, payload) + return } func (g *gRPCLoader) ListHistoryTestSuite() (suites []testing.HistoryTestSuite, err error) { - var items *HistoryTestSuites - items, err = g.client.ListHistoryTestSuite(g.ctx, &server.Empty{}) - if err == nil && items != nil { - for _, item := range items.Data { - suites = append(suites, *ConvertToNormalHistoryTestSuite(item)) - } - } - return + var items *HistoryTestSuites + items, err = g.client.ListHistoryTestSuite(g.ctx, &server.Empty{}) + if err == nil && items != nil { + for _, item := range items.Data { + suites = append(suites, *ConvertToNormalHistoryTestSuite(item)) + } + } + return } func (g *gRPCLoader) DeleteHistoryTestCase(id string) (err error) { - _, err = g.client.DeleteHistoryTestCase(g.ctx, &server.HistoryTestCase{ - ID: id, - }) - return + _, err = g.client.DeleteHistoryTestCase(g.ctx, &server.HistoryTestCase{ + ID: id, + }) + return } func (g *gRPCLoader) DeleteAllHistoryTestCase(suite, name string) (err error) { - _, err = g.client.DeleteAllHistoryTestCase(g.ctx, &server.HistoryTestCase{ - SuiteName: suite, - CaseName: name, - }) - return + _, err = g.client.DeleteAllHistoryTestCase(g.ctx, &server.HistoryTestCase{ + SuiteName: suite, + CaseName: name, + }) + return } func (g *gRPCLoader) GetTestCaseAllHistory(suite, name string) (historyTestcases []testing.HistoryTestCase, err error) { - var historyTestCases *server.HistoryTestCases - historyTestCases, err = g.client.GetTestCaseAllHistory(g.ctx, &server.TestCase{ - Name: name, - SuiteName: suite, - }) - if err == nil && historyTestCases.Data != nil { - for _, item := range historyTestCases.Data { - historyTestcases = append(historyTestcases, ConvertToNormalHistoryTestCase(item)) - } - } - return + var historyTestCases *server.HistoryTestCases + historyTestCases, err = g.client.GetTestCaseAllHistory(g.ctx, &server.TestCase{ + Name: name, + SuiteName: suite, + }) + if err == nil && historyTestCases.Data != nil { + for _, item := range historyTestCases.Data { + historyTestcases = append(historyTestcases, ConvertToNormalHistoryTestCase(item)) + } + } + return } func (g *gRPCLoader) ListTestSuite() (suites []testing.TestSuite, err error) { - var items *TestSuites - items, err = g.client.ListTestSuite(g.ctx, &server.Empty{}) - if err == nil && items != nil { - for _, item := range items.Data { - suites = append(suites, *ConvertToNormalTestSuite(item)) - } - } - return + var items *TestSuites + items, err = g.client.ListTestSuite(g.ctx, &server.Empty{}) + if err == nil && items != nil { + for _, item := range items.Data { + suites = append(suites, *ConvertToNormalTestSuite(item)) + } + } + return } func (g *gRPCLoader) GetTestSuite(name string, full bool) (suite testing.TestSuite, err error) { - var result *TestSuite - if result, err = g.client.GetTestSuite(g.ctx, - &TestSuite{Name: name, Full: full}); err == nil { - suite = *ConvertToNormalTestSuite(result) - } - return + var result *TestSuite + if result, err = g.client.GetTestSuite(g.ctx, + &TestSuite{Name: name, Full: full}); err == nil { + suite = *ConvertToNormalTestSuite(result) + } + return } func (g *gRPCLoader) CreateSuite(name, api string) (err error) { - _, err = g.client.CreateTestSuite(g.ctx, &TestSuite{ - Name: name, - Api: api, - }) - return + _, err = g.client.CreateTestSuite(g.ctx, &TestSuite{ + Name: name, + Api: api, + }) + return } func (g *gRPCLoader) GetSuite(name string) (reply *testing.TestSuite, _ string, err error) { - var suite *TestSuite - if suite, err = g.client.GetTestSuite(g.ctx, - &TestSuite{Name: name}); err != nil { - return - } + var suite *TestSuite + if suite, err = g.client.GetTestSuite(g.ctx, + &TestSuite{Name: name}); err != nil { + return + } - reply = ConvertToNormalTestSuite(suite) - return + reply = ConvertToNormalTestSuite(suite) + return } func (g *gRPCLoader) UpdateSuite(suite testing.TestSuite) (err error) { - _, err = g.client.UpdateTestSuite(g.ctx, ConvertToGRPCTestSuite(&suite)) - return + _, err = g.client.UpdateTestSuite(g.ctx, ConvertToGRPCTestSuite(&suite)) + return } func (g *gRPCLoader) DeleteSuite(name string) (err error) { - _, err = g.client.DeleteTestSuite(g.ctx, &TestSuite{ - Name: name, - }) - return + _, err = g.client.DeleteTestSuite(g.ctx, &TestSuite{ + Name: name, + }) + return } func (g *gRPCLoader) RenameTestSuite(oldName, newName string) (err error) { - _, err = g.client.RenameTestSuite(g.ctx, &server.TestSuiteDuplicate{ - SourceSuiteName: oldName, - TargetSuiteName: newName, - }) - return + _, err = g.client.RenameTestSuite(g.ctx, &server.TestSuiteDuplicate{ + SourceSuiteName: oldName, + TargetSuiteName: newName, + }) + return } func (g *gRPCLoader) Verify() (readOnly bool, err error) { - // avoid to long to wait the response - ctx, cancel := context.WithTimeout(g.ctx, time.Second*5) - defer cancel() + // avoid to long to wait the response + ctx, cancel := context.WithTimeout(g.ctx, time.Second*5) + defer cancel() - var result *server.ExtensionStatus - if result, err = g.client.Verify(ctx, &server.Empty{}); err == nil { - readOnly = result.ReadOnly - if !result.Ready { - err = errors.New(result.Message) - } - } - return + var result *server.ExtensionStatus + if result, err = g.client.Verify(ctx, &server.Empty{}); err == nil { + readOnly = result.ReadOnly + if !result.Ready { + err = errors.New(result.Message) + } + } + return } func (g *gRPCLoader) PProf(name string) []byte { - data, err := g.client.PProf(context.Background(), &server.PProfRequest{ - Name: name, - }) - if err != nil { - grpcLogger.Info("failed to get pprof:", "error", err) - } - return data.Data + data, err := g.client.PProf(context.Background(), &server.PProfRequest{ + Name: name, + }) + if err != nil { + grpcLogger.Info("failed to get pprof:", "error", err) + } + return data.Data +} + +func (g *gRPCLoader) Query(query map[string]string) (result map[string]string, items []map[string]string, err error) { + var dataResult *server.DataQueryResult + if dataResult, err = g.client.Query(g.ctx, &server.DataQuery{ + Sql: query["sql"], + Key: query["key"], + }); err == nil { + result = pairToMap(dataResult.Data) + for _, item := range dataResult.Items { + items = append(items, pairToMap(item.Data)) + } + } + return } func (g *gRPCLoader) Close() { - if g.conn != nil { - g.conn.Close() - } + if g.conn != nil { + g.conn.Close() + } } diff --git a/pkg/testing/remote/loader.pb.go b/pkg/testing/remote/loader.pb.go index 5d6aed531..a4a4e2819 100644 --- a/pkg/testing/remote/loader.pb.go +++ b/pkg/testing/remote/loader.pb.go @@ -408,7 +408,7 @@ var file_pkg_testing_remote_loader_proto_rawDesc = []byte{ 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0xc8, 0x0a, 0x0a, 0x06, 0x4c, 0x6f, 0x61, 0x64, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0xff, 0x0a, 0x0a, 0x06, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x54, 0x65, 0x73, 0x74, @@ -493,46 +493,50 @@ var file_pkg_testing_remote_loader_proto_rawDesc = []byte{ 0x0a, 0x05, 0x50, 0x50, 0x72, 0x6f, 0x66, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x50, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x50, 0x72, 0x6f, 0x66, 0x44, 0x61, 0x74, 0x61, - 0x22, 0x00, 0x32, 0x96, 0x02, 0x0a, 0x0d, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, - 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, - 0x74, 0x1a, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, - 0x74, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, - 0x73, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x0f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, - 0x73, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x63, - 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, - 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0c, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x35, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x11, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x17, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x32, 0x96, 0x02, 0x0a, 0x0d, 0x53, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x09, 0x47, + 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x0a, 0x47, 0x65, + 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0c, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0c, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x22, 0x00, 0x32, 0x9e, 0x02, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x73, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x1a, 0x0f, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x73, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x0e, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, + 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, + 0x36, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x0e, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, + 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x63, - 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, - 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x32, 0x9e, 0x02, 0x0a, 0x0d, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2e, 0x0a, - 0x0a, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x0d, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x72, 0x65, 0x6d, - 0x6f, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0x00, 0x12, 0x31, 0x0a, - 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x0e, - 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x00, - 0x12, 0x36, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x0e, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, - 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, - 0x12, 0x3a, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x42, 0x36, 0x5a, 0x34, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x6e, 0x75, 0x78, - 0x73, 0x75, 0x72, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x67, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x72, 0x65, - 0x6d, 0x6f, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x22, 0x00, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x73, 0x75, 0x72, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, + 0x2d, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -564,16 +568,18 @@ var file_pkg_testing_remote_loader_proto_goTypes = []interface{}{ (*server.TestCaseDuplicate)(nil), // 12: server.TestCaseDuplicate (*server.HistoryTestResult)(nil), // 13: server.HistoryTestResult (*server.PProfRequest)(nil), // 14: server.PProfRequest - (*server.Secret)(nil), // 15: server.Secret - (*server.SimpleName)(nil), // 16: server.SimpleName - (*server.HelloReply)(nil), // 17: server.HelloReply - (*server.TestCases)(nil), // 18: server.TestCases - (*server.HistoryTestCases)(nil), // 19: server.HistoryTestCases - (*server.Version)(nil), // 20: server.Version - (*server.ExtensionStatus)(nil), // 21: server.ExtensionStatus - (*server.PProfData)(nil), // 22: server.PProfData - (*server.Secrets)(nil), // 23: server.Secrets - (*server.CommonResult)(nil), // 24: server.CommonResult + (*server.DataQuery)(nil), // 15: server.DataQuery + (*server.Secret)(nil), // 16: server.Secret + (*server.SimpleName)(nil), // 17: server.SimpleName + (*server.HelloReply)(nil), // 18: server.HelloReply + (*server.TestCases)(nil), // 19: server.TestCases + (*server.HistoryTestCases)(nil), // 20: server.HistoryTestCases + (*server.Version)(nil), // 21: server.Version + (*server.ExtensionStatus)(nil), // 22: server.ExtensionStatus + (*server.PProfData)(nil), // 23: server.PProfData + (*server.DataQueryResult)(nil), // 24: server.DataQueryResult + (*server.Secrets)(nil), // 25: server.Secrets + (*server.CommonResult)(nil), // 26: server.CommonResult } var file_pkg_testing_remote_loader_proto_depIdxs = []int32{ 1, // 0: remote.TestSuites.data:type_name -> remote.TestSuite @@ -605,50 +611,52 @@ var file_pkg_testing_remote_loader_proto_depIdxs = []int32{ 10, // 26: remote.Loader.GetVersion:input_type -> server.Empty 10, // 27: remote.Loader.Verify:input_type -> server.Empty 14, // 28: remote.Loader.PProf:input_type -> server.PProfRequest - 15, // 29: remote.SecretService.GetSecret:input_type -> server.Secret - 10, // 30: remote.SecretService.GetSecrets:input_type -> server.Empty - 15, // 31: remote.SecretService.CreateSecret:input_type -> server.Secret - 15, // 32: remote.SecretService.DeleteSecret:input_type -> server.Secret - 15, // 33: remote.SecretService.UpdateSecret:input_type -> server.Secret - 10, // 34: remote.ConfigService.GetConfigs:input_type -> server.Empty - 16, // 35: remote.ConfigService.GetConfig:input_type -> server.SimpleName - 5, // 36: remote.ConfigService.CreateConfig:input_type -> remote.Config - 5, // 37: remote.ConfigService.UpdateConfig:input_type -> remote.Config - 16, // 38: remote.ConfigService.DeleteConfig:input_type -> server.SimpleName - 0, // 39: remote.Loader.ListTestSuite:output_type -> remote.TestSuites - 10, // 40: remote.Loader.CreateTestSuite:output_type -> server.Empty - 1, // 41: remote.Loader.GetTestSuite:output_type -> remote.TestSuite - 1, // 42: remote.Loader.UpdateTestSuite:output_type -> remote.TestSuite - 10, // 43: remote.Loader.DeleteTestSuite:output_type -> server.Empty - 17, // 44: remote.Loader.RenameTestSuite:output_type -> server.HelloReply - 18, // 45: remote.Loader.ListTestCases:output_type -> server.TestCases - 10, // 46: remote.Loader.CreateTestCase:output_type -> server.Empty - 8, // 47: remote.Loader.GetTestCase:output_type -> server.TestCase - 8, // 48: remote.Loader.UpdateTestCase:output_type -> server.TestCase - 10, // 49: remote.Loader.DeleteTestCase:output_type -> server.Empty - 17, // 50: remote.Loader.RenameTestCase:output_type -> server.HelloReply - 2, // 51: remote.Loader.ListHistoryTestSuite:output_type -> remote.HistoryTestSuites - 10, // 52: remote.Loader.CreateTestCaseHistory:output_type -> server.Empty - 13, // 53: remote.Loader.GetHistoryTestCaseWithResult:output_type -> server.HistoryTestResult - 9, // 54: remote.Loader.GetHistoryTestCase:output_type -> server.HistoryTestCase - 10, // 55: remote.Loader.DeleteHistoryTestCase:output_type -> server.Empty - 10, // 56: remote.Loader.DeleteAllHistoryTestCase:output_type -> server.Empty - 19, // 57: remote.Loader.GetTestCaseAllHistory:output_type -> server.HistoryTestCases - 20, // 58: remote.Loader.GetVersion:output_type -> server.Version - 21, // 59: remote.Loader.Verify:output_type -> server.ExtensionStatus - 22, // 60: remote.Loader.PProf:output_type -> server.PProfData - 15, // 61: remote.SecretService.GetSecret:output_type -> server.Secret - 23, // 62: remote.SecretService.GetSecrets:output_type -> server.Secrets - 24, // 63: remote.SecretService.CreateSecret:output_type -> server.CommonResult - 24, // 64: remote.SecretService.DeleteSecret:output_type -> server.CommonResult - 24, // 65: remote.SecretService.UpdateSecret:output_type -> server.CommonResult - 4, // 66: remote.ConfigService.GetConfigs:output_type -> remote.Configs - 5, // 67: remote.ConfigService.GetConfig:output_type -> remote.Config - 24, // 68: remote.ConfigService.CreateConfig:output_type -> server.CommonResult - 24, // 69: remote.ConfigService.UpdateConfig:output_type -> server.CommonResult - 24, // 70: remote.ConfigService.DeleteConfig:output_type -> server.CommonResult - 39, // [39:71] is the sub-list for method output_type - 7, // [7:39] is the sub-list for method input_type + 15, // 29: remote.Loader.Query:input_type -> server.DataQuery + 16, // 30: remote.SecretService.GetSecret:input_type -> server.Secret + 10, // 31: remote.SecretService.GetSecrets:input_type -> server.Empty + 16, // 32: remote.SecretService.CreateSecret:input_type -> server.Secret + 16, // 33: remote.SecretService.DeleteSecret:input_type -> server.Secret + 16, // 34: remote.SecretService.UpdateSecret:input_type -> server.Secret + 10, // 35: remote.ConfigService.GetConfigs:input_type -> server.Empty + 17, // 36: remote.ConfigService.GetConfig:input_type -> server.SimpleName + 5, // 37: remote.ConfigService.CreateConfig:input_type -> remote.Config + 5, // 38: remote.ConfigService.UpdateConfig:input_type -> remote.Config + 17, // 39: remote.ConfigService.DeleteConfig:input_type -> server.SimpleName + 0, // 40: remote.Loader.ListTestSuite:output_type -> remote.TestSuites + 10, // 41: remote.Loader.CreateTestSuite:output_type -> server.Empty + 1, // 42: remote.Loader.GetTestSuite:output_type -> remote.TestSuite + 1, // 43: remote.Loader.UpdateTestSuite:output_type -> remote.TestSuite + 10, // 44: remote.Loader.DeleteTestSuite:output_type -> server.Empty + 18, // 45: remote.Loader.RenameTestSuite:output_type -> server.HelloReply + 19, // 46: remote.Loader.ListTestCases:output_type -> server.TestCases + 10, // 47: remote.Loader.CreateTestCase:output_type -> server.Empty + 8, // 48: remote.Loader.GetTestCase:output_type -> server.TestCase + 8, // 49: remote.Loader.UpdateTestCase:output_type -> server.TestCase + 10, // 50: remote.Loader.DeleteTestCase:output_type -> server.Empty + 18, // 51: remote.Loader.RenameTestCase:output_type -> server.HelloReply + 2, // 52: remote.Loader.ListHistoryTestSuite:output_type -> remote.HistoryTestSuites + 10, // 53: remote.Loader.CreateTestCaseHistory:output_type -> server.Empty + 13, // 54: remote.Loader.GetHistoryTestCaseWithResult:output_type -> server.HistoryTestResult + 9, // 55: remote.Loader.GetHistoryTestCase:output_type -> server.HistoryTestCase + 10, // 56: remote.Loader.DeleteHistoryTestCase:output_type -> server.Empty + 10, // 57: remote.Loader.DeleteAllHistoryTestCase:output_type -> server.Empty + 20, // 58: remote.Loader.GetTestCaseAllHistory:output_type -> server.HistoryTestCases + 21, // 59: remote.Loader.GetVersion:output_type -> server.Version + 22, // 60: remote.Loader.Verify:output_type -> server.ExtensionStatus + 23, // 61: remote.Loader.PProf:output_type -> server.PProfData + 24, // 62: remote.Loader.Query:output_type -> server.DataQueryResult + 16, // 63: remote.SecretService.GetSecret:output_type -> server.Secret + 25, // 64: remote.SecretService.GetSecrets:output_type -> server.Secrets + 26, // 65: remote.SecretService.CreateSecret:output_type -> server.CommonResult + 26, // 66: remote.SecretService.DeleteSecret:output_type -> server.CommonResult + 26, // 67: remote.SecretService.UpdateSecret:output_type -> server.CommonResult + 4, // 68: remote.ConfigService.GetConfigs:output_type -> remote.Configs + 5, // 69: remote.ConfigService.GetConfig:output_type -> remote.Config + 26, // 70: remote.ConfigService.CreateConfig:output_type -> server.CommonResult + 26, // 71: remote.ConfigService.UpdateConfig:output_type -> server.CommonResult + 26, // 72: remote.ConfigService.DeleteConfig:output_type -> server.CommonResult + 40, // [40:73] is the sub-list for method output_type + 7, // [7:40] is the sub-list for method input_type 7, // [7:7] is the sub-list for extension type_name 7, // [7:7] is the sub-list for extension extendee 0, // [0:7] is the sub-list for field type_name diff --git a/pkg/testing/remote/loader.proto b/pkg/testing/remote/loader.proto index 4306ec2d7..bef771112 100644 --- a/pkg/testing/remote/loader.proto +++ b/pkg/testing/remote/loader.proto @@ -32,6 +32,8 @@ service Loader { rpc GetVersion(server.Empty) returns (server.Version) {} rpc Verify(server.Empty) returns (server.ExtensionStatus) {} rpc PProf(server.PProfRequest) returns (server.PProfData) {} + + rpc Query(server.DataQuery) returns (server.DataQueryResult) {} } message TestSuites { diff --git a/pkg/testing/remote/loader_grpc.pb.go b/pkg/testing/remote/loader_grpc.pb.go index e75aff647..6f09f1b35 100644 --- a/pkg/testing/remote/loader_grpc.pb.go +++ b/pkg/testing/remote/loader_grpc.pb.go @@ -45,6 +45,7 @@ type LoaderClient interface { GetVersion(ctx context.Context, in *server.Empty, opts ...grpc.CallOption) (*server.Version, error) Verify(ctx context.Context, in *server.Empty, opts ...grpc.CallOption) (*server.ExtensionStatus, error) PProf(ctx context.Context, in *server.PProfRequest, opts ...grpc.CallOption) (*server.PProfData, error) + Query(ctx context.Context, in *server.DataQuery, opts ...grpc.CallOption) (*server.DataQueryResult, error) } type loaderClient struct { @@ -253,6 +254,15 @@ func (c *loaderClient) PProf(ctx context.Context, in *server.PProfRequest, opts return out, nil } +func (c *loaderClient) Query(ctx context.Context, in *server.DataQuery, opts ...grpc.CallOption) (*server.DataQueryResult, error) { + out := new(server.DataQueryResult) + err := c.cc.Invoke(ctx, "/remote.Loader/Query", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // LoaderServer is the server API for Loader service. // All implementations must embed UnimplementedLoaderServer // for forward compatibility @@ -279,6 +289,7 @@ type LoaderServer interface { GetVersion(context.Context, *server.Empty) (*server.Version, error) Verify(context.Context, *server.Empty) (*server.ExtensionStatus, error) PProf(context.Context, *server.PProfRequest) (*server.PProfData, error) + Query(context.Context, *server.DataQuery) (*server.DataQueryResult, error) mustEmbedUnimplementedLoaderServer() } @@ -352,6 +363,9 @@ func (UnimplementedLoaderServer) Verify(context.Context, *server.Empty) (*server func (UnimplementedLoaderServer) PProf(context.Context, *server.PProfRequest) (*server.PProfData, error) { return nil, status.Errorf(codes.Unimplemented, "method PProf not implemented") } +func (UnimplementedLoaderServer) Query(context.Context, *server.DataQuery) (*server.DataQueryResult, error) { + return nil, status.Errorf(codes.Unimplemented, "method Query not implemented") +} func (UnimplementedLoaderServer) mustEmbedUnimplementedLoaderServer() {} // UnsafeLoaderServer may be embedded to opt out of forward compatibility for this service. @@ -761,6 +775,24 @@ func _Loader_PProf_Handler(srv interface{}, ctx context.Context, dec func(interf return interceptor(ctx, in, info, handler) } +func _Loader_Query_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(server.DataQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LoaderServer).Query(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/remote.Loader/Query", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LoaderServer).Query(ctx, req.(*server.DataQuery)) + } + return interceptor(ctx, in, info, handler) +} + // Loader_ServiceDesc is the grpc.ServiceDesc for Loader service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -856,6 +888,10 @@ var Loader_ServiceDesc = grpc.ServiceDesc{ MethodName: "PProf", Handler: _Loader_PProf_Handler, }, + { + MethodName: "Query", + Handler: _Loader_Query_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "pkg/testing/remote/loader.proto", diff --git a/tools/make/run.mk b/tools/make/run.mk index 26ab916bb..18869e9f2 100644 --- a/tools/make/run.mk +++ b/tools/make/run.mk @@ -13,7 +13,7 @@ run-server: ## Run the API Testing server run-server: build-ui run-backend run-backend: go run . server --local-storage 'bin/*.yaml' --console-path ${ATEST_UI}/dist \ - --extension-registry ghcr.io --download-timeout 90s + --extension-registry ghcr.io --download-timeout 10m .PHONY: run-console run-console: ## Run the API Testing console