feat: support convert testSuite to JMeter file (#170)
* feat: support convert testSuite to JMeter file * chore: report API test in the comment * add a sub-command to convert to jmeter file --------- Co-authored-by: rick <linuxsuren@users.noreply.github.com>
This commit is contained in:
parent
200134093d
commit
908829738a
|
@ -2,7 +2,8 @@
|
||||||
# yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-schema.json
|
# yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-schema.json
|
||||||
# https://docs.gitlab.com/ee/api/api_resources.html
|
# https://docs.gitlab.com/ee/api/api_resources.html
|
||||||
name: atest
|
name: atest
|
||||||
api: http://localhost:8080/server.Runner
|
api: |
|
||||||
|
{{default "http://localhost:8080/server.Runner" (env "SERVER")}}
|
||||||
items:
|
items:
|
||||||
- name: suites
|
- name: suites
|
||||||
request:
|
request:
|
||||||
|
@ -80,6 +81,7 @@ items:
|
||||||
request:
|
request:
|
||||||
api: /PopularHeaders
|
api: /PopularHeaders
|
||||||
method: POST
|
method: POST
|
||||||
|
|
||||||
- name: list-code-generators
|
- name: list-code-generators
|
||||||
request:
|
request:
|
||||||
api: /ListCodeGenerator
|
api: /ListCodeGenerator
|
||||||
|
@ -87,6 +89,42 @@ items:
|
||||||
expect:
|
expect:
|
||||||
verify:
|
verify:
|
||||||
- len(data) == 1
|
- len(data) == 1
|
||||||
|
- name: GenerateCode
|
||||||
|
request:
|
||||||
|
api: /GenerateCode
|
||||||
|
method: POST
|
||||||
|
body: |
|
||||||
|
{
|
||||||
|
"TestSuite": "{{index (keys .suites.data) 0}}",
|
||||||
|
"TestCase": "{{randAlpha 6}}",
|
||||||
|
"Generator": "golang"
|
||||||
|
}
|
||||||
|
expect:
|
||||||
|
statusCode: 500 # no testcase found
|
||||||
|
verify:
|
||||||
|
- indexOf(data.message, "not found") != -1
|
||||||
|
|
||||||
|
- name: listConverters
|
||||||
|
request:
|
||||||
|
api: /ListConverter
|
||||||
|
method: POST
|
||||||
|
expect:
|
||||||
|
verify:
|
||||||
|
- len(data) == 1
|
||||||
|
- name: ConvertTestSuite
|
||||||
|
request:
|
||||||
|
api: /ConvertTestSuite
|
||||||
|
method: POST
|
||||||
|
body: |
|
||||||
|
{
|
||||||
|
"TestSuite": "{{index (keys .suites.data) 0}}",
|
||||||
|
"Generator": "jmeter"
|
||||||
|
}
|
||||||
|
expect:
|
||||||
|
verify:
|
||||||
|
- data.message != ""
|
||||||
|
- indexOf(data.message, "jmeterTestPlan") != -1
|
||||||
|
|
||||||
- name: list-stores
|
- name: list-stores
|
||||||
request:
|
request:
|
||||||
api: /GetStores
|
api: /GetStores
|
||||||
|
|
|
@ -27,15 +27,36 @@ jobs:
|
||||||
bash <(curl -Ls https://coverage.codacy.com/get.sh) report --partial --force-coverage-parser go -r store-git-coverage.out
|
bash <(curl -Ls https://coverage.codacy.com/get.sh) report --partial --force-coverage-parser go -r store-git-coverage.out
|
||||||
bash <(curl -Ls https://coverage.codacy.com/get.sh) report --partial --force-coverage-parser go -r operator/cover.out
|
bash <(curl -Ls https://coverage.codacy.com/get.sh) report --partial --force-coverage-parser go -r operator/cover.out
|
||||||
bash <(curl -Ls https://coverage.codacy.com/get.sh) final
|
bash <(curl -Ls https://coverage.codacy.com/get.sh) final
|
||||||
|
|
||||||
|
APITest:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
steps:
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: 1.18.x
|
||||||
|
- uses: actions/checkout@v3.0.0
|
||||||
- name: API Test
|
- name: API Test
|
||||||
run: |
|
run: |
|
||||||
make build copy
|
make build copy
|
||||||
sudo atest service install
|
sudo atest service install
|
||||||
sudo atest service restart
|
sudo atest service restart
|
||||||
sudo atest service status
|
sudo atest service status
|
||||||
atest run -p .github/testing/core.yaml --request-ignore-error
|
atest run -p .github/testing/core.yaml --request-ignore-error --report md --report-file .github/workflows/report.md
|
||||||
sudo atest service status
|
sudo atest service status
|
||||||
|
|
||||||
|
atest convert -p .github/testing/core.yaml --converter jmeter -t sample.jmx
|
||||||
|
- name: Report API Test
|
||||||
|
uses: harupy/comment-on-pr@c0522c44600040927a120b9309b531e3cb6f8d48
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
filename: report.md
|
||||||
|
- name: Run JMeter Tests
|
||||||
|
uses: rbhadti94/apache-jmeter-action@v0.5.0
|
||||||
|
with:
|
||||||
|
testFilePath: sample.jmx
|
||||||
|
|
||||||
Build:
|
Build:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
|
|
|
@ -9,8 +9,8 @@ This is a API testing tool.
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* Multiple test report formats: Markdown, HTML, PDF, Stdout
|
* Multiple test report formats: Markdown, HTML, PDF, Stdout
|
||||||
* Response Body fields equation check
|
* Support converting to [JMeter](https://jmeter.apache.org/) files
|
||||||
* Response Body [eval](https://expr.medv.io/)
|
* Response Body fields equation check or [eval](https://expr.medv.io/)
|
||||||
* Verify the Kubernetes resources
|
* Verify the Kubernetes resources
|
||||||
* Validate the response body with [JSON schema](https://json-schema.org/)
|
* Validate the response body with [JSON schema](https://json-schema.org/)
|
||||||
* Pre and post handle with the API request
|
* Pre and post handle with the API request
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 API Testing Authors.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/linuxsuren/api-testing/pkg/generator"
|
||||||
|
"github.com/linuxsuren/api-testing/pkg/testing"
|
||||||
|
"github.com/linuxsuren/api-testing/pkg/util"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createConvertCommand() (c *cobra.Command) {
|
||||||
|
opt := &convertOption{}
|
||||||
|
c = &cobra.Command{
|
||||||
|
Use: "convert",
|
||||||
|
Short: "Convert the API testing file to other format",
|
||||||
|
PreRunE: opt.preRunE,
|
||||||
|
RunE: opt.runE,
|
||||||
|
}
|
||||||
|
|
||||||
|
converters := generator.GetTestSuiteConverters()
|
||||||
|
|
||||||
|
flags := c.Flags()
|
||||||
|
flags.StringVarP(&opt.pattern, "pattern", "p", "test-suite-*.yaml",
|
||||||
|
"The file pattern which try to execute the test cases. Brace expansion is supported, such as: test-suite-{1,2}.yaml")
|
||||||
|
flags.StringVarP(&opt.converter, "converter", "", "",
|
||||||
|
fmt.Sprintf("The converter format, supported: %s", util.Keys(converters)))
|
||||||
|
flags.StringVarP(&opt.target, "target", "t", "", "The target file path")
|
||||||
|
|
||||||
|
_ = c.MarkFlagRequired("pattern")
|
||||||
|
_ = c.MarkFlagRequired("converter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type convertOption struct {
|
||||||
|
pattern string
|
||||||
|
converter string
|
||||||
|
target string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *convertOption) preRunE(c *cobra.Command, args []string) (err error) {
|
||||||
|
if o.target == "" {
|
||||||
|
o.target = "sample.jmx"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *convertOption) runE(c *cobra.Command, args []string) (err error) {
|
||||||
|
loader := testing.NewFileWriter("")
|
||||||
|
if err = loader.Put(o.pattern); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var output string
|
||||||
|
var suites []testing.TestSuite
|
||||||
|
if suites, err = loader.ListTestSuite(); err == nil {
|
||||||
|
if len(suites) == 0 {
|
||||||
|
err = fmt.Errorf("no suites found")
|
||||||
|
} else {
|
||||||
|
converter := generator.GetTestSuiteConverter(o.converter)
|
||||||
|
if converter == nil {
|
||||||
|
err = fmt.Errorf("no converter found")
|
||||||
|
} else {
|
||||||
|
output, err = converter.Convert(&suites[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if output != "" {
|
||||||
|
err = os.WriteFile(o.target, []byte(output), 0644)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 API Testing Authors.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmd_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/linuxsuren/api-testing/cmd"
|
||||||
|
"github.com/linuxsuren/api-testing/pkg/server"
|
||||||
|
fakeruntime "github.com/linuxsuren/go-fake-runtime"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestConvert(t *testing.T) {
|
||||||
|
c := cmd.NewRootCmd(fakeruntime.FakeExecer{ExpectOS: "linux"},
|
||||||
|
cmd.NewFakeGRPCServer(), server.NewFakeHTTPServer())
|
||||||
|
c.SetOut(io.Discard)
|
||||||
|
|
||||||
|
t.Run("normal", func(t *testing.T) {
|
||||||
|
tmpFile := path.Join(os.TempDir(), time.Now().String())
|
||||||
|
defer os.RemoveAll(tmpFile)
|
||||||
|
|
||||||
|
c.SetArgs([]string{"convert", "-p=testdata/simple-suite.yaml", "--converter=jmeter", "--target", tmpFile})
|
||||||
|
|
||||||
|
err := c.Execute()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
var data []byte
|
||||||
|
data, err = os.ReadFile(tmpFile)
|
||||||
|
if assert.NoError(t, err) {
|
||||||
|
assert.NotEmpty(t, string(data))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("no testSuite", func(t *testing.T) {
|
||||||
|
c.SetArgs([]string{"convert", "-p=testdata/fake.yaml", "--converter=jmeter"})
|
||||||
|
|
||||||
|
err := c.Execute()
|
||||||
|
assert.Error(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("no converter found", func(t *testing.T) {
|
||||||
|
c.SetArgs([]string{"convert", "-p=testdata/simple-suite.yaml", "--converter=fake"})
|
||||||
|
|
||||||
|
err := c.Execute()
|
||||||
|
assert.Error(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("flag --pattern is required", func(t *testing.T) {
|
||||||
|
c.SetArgs([]string{"convert", "--converter=fake"})
|
||||||
|
|
||||||
|
err := c.Execute()
|
||||||
|
assert.Error(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("flag --converter is required", func(t *testing.T) {
|
||||||
|
c.SetArgs([]string{"convert", "-p=fake"})
|
||||||
|
|
||||||
|
err := c.Execute()
|
||||||
|
assert.Error(t, err)
|
||||||
|
})
|
||||||
|
}
|
|
@ -21,7 +21,7 @@ func NewRootCmd(execer fakeruntime.Execer, gRPCServer gRPCServer,
|
||||||
c.AddCommand(createInitCommand(execer),
|
c.AddCommand(createInitCommand(execer),
|
||||||
createRunCommand(), createSampleCmd(),
|
createRunCommand(), createSampleCmd(),
|
||||||
createServerCmd(execer, gRPCServer, httpServer), createJSONSchemaCmd(),
|
createServerCmd(execer, gRPCServer, httpServer), createJSONSchemaCmd(),
|
||||||
createServiceCommand(execer), createFunctionCmd())
|
createServiceCommand(execer), createFunctionCmd(), createConvertCommand())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -239,10 +238,7 @@ func (o *runOption) runSuite(loader testing.Loader, dataContext map[string]inter
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// reuse the API prefix
|
testCase.Request.RenderAPI(testSuite.API)
|
||||||
if strings.HasPrefix(testCase.Request.API, "/") {
|
|
||||||
testCase.Request.API = fmt.Sprintf("%s%s", testSuite.API, testCase.Request.API)
|
|
||||||
}
|
|
||||||
|
|
||||||
var output interface{}
|
var output interface{}
|
||||||
select {
|
select {
|
||||||
|
|
|
@ -151,6 +151,43 @@ function del() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function convert() {
|
||||||
|
const requestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'X-Store-Name': props.store
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
Generator: 'jmeter',
|
||||||
|
TestSuite: props.name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fetch('/server.Runner/ConvertTestSuite', requestOptions)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((e) => {
|
||||||
|
const blob = new Blob([e.message], { type: `text/xml;charset=utf-8;` });
|
||||||
|
const link = document.createElement('a');
|
||||||
|
if (link.download !== undefined) {
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
link.setAttribute('href', url);
|
||||||
|
link.setAttribute('download', `jmeter.jmx`);
|
||||||
|
link.style.visibility = 'hidden';
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
ElMessage({
|
||||||
|
message: 'Converted.',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
emit('updated')
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
ElMessage.error('Oops, ' + e)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const suiteCreatingLoading = ref(false)
|
const suiteCreatingLoading = ref(false)
|
||||||
|
|
||||||
const apiSpecKinds = [
|
const apiSpecKinds = [
|
||||||
|
@ -218,6 +255,8 @@ function paramChange() {
|
||||||
<el-button type="primary" @click="del" test-id="suite-del-but">Delete</el-button>
|
<el-button type="primary" @click="del" test-id="suite-del-but">Delete</el-button>
|
||||||
|
|
||||||
<el-button type="primary" @click="openNewTestCaseDialog" :icon="Edit" test-id="open-new-case-dialog">New TestCase</el-button>
|
<el-button type="primary" @click="openNewTestCaseDialog" :icon="Edit" test-id="open-new-case-dialog">New TestCase</el-button>
|
||||||
|
|
||||||
|
<el-button type="primary" @click="convert" test-id="convert">Convert</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-dialog v-model="dialogVisible" title="Create Test Case" width="40%" draggable>
|
<el-dialog v-model="dialogVisible" title="Create Test Case" width="40%" draggable>
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -5,7 +5,7 @@ go 1.18
|
||||||
require (
|
require (
|
||||||
github.com/Masterminds/sprig/v3 v3.2.3
|
github.com/Masterminds/sprig/v3 v3.2.3
|
||||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883
|
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883
|
||||||
github.com/antonmedv/expr v1.12.1
|
github.com/antonmedv/expr v1.14.0
|
||||||
github.com/bufbuild/protocompile v0.6.0
|
github.com/bufbuild/protocompile v0.6.0
|
||||||
github.com/cucumber/godog v0.12.6
|
github.com/cucumber/godog v0.12.6
|
||||||
github.com/flopp/go-findfont v0.1.0
|
github.com/flopp/go-findfont v0.1.0
|
||||||
|
|
|
@ -545,6 +545,8 @@ github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3
|
||||||
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM=
|
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM=
|
||||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
|
github.com/antonmedv/expr v1.14.0 h1:C4BHw+0cVyKy/ndU3uqYo6TV5rCtq/SY2Wdlwanvo/Q=
|
||||||
|
github.com/antonmedv/expr v1.14.0/go.mod h1:FPC8iWArxls7axbVLsW+kpg1mz29A1b2M6jt+hZfDkU=
|
||||||
github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0=
|
github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0=
|
||||||
github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI=
|
github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI=
|
||||||
github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=
|
github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=
|
||||||
|
@ -872,3 +874,4 @@ google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwS
|
||||||
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
|
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
|
||||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
|
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||||
|
|
|
@ -49,3 +49,27 @@ func GetCodeGenerators() (result map[string]CodeGenerator) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestSuiteConverter is the interface of test suite converter
|
||||||
|
type TestSuiteConverter interface {
|
||||||
|
Convert(*testing.TestSuite) (result string, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
var converters = map[string]TestSuiteConverter{}
|
||||||
|
|
||||||
|
func GetTestSuiteConverter(name string) TestSuiteConverter {
|
||||||
|
return converters[name]
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterTestSuiteConverter(name string, converter TestSuiteConverter) {
|
||||||
|
converters[name] = converter
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTestSuiteConverters() (result map[string]TestSuiteConverter) {
|
||||||
|
// returns an immutable map
|
||||||
|
result = make(map[string]TestSuiteConverter, len(converters))
|
||||||
|
for k, v := range converters {
|
||||||
|
result[k] = v
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,214 @@
|
||||||
|
/**
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 API Testing Authors.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package generator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/linuxsuren/api-testing/pkg/testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type jmeterConverter struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterTestSuiteConverter("jmeter", &jmeterConverter{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *jmeterConverter) Convert(testSuite *testing.TestSuite) (result string, err error) {
|
||||||
|
var jmeterTestPlan *JmeterTestPlan
|
||||||
|
if jmeterTestPlan, err = c.buildJmeterTestPlan(testSuite); err == nil {
|
||||||
|
var data []byte
|
||||||
|
if data, err = xml.MarshalIndent(jmeterTestPlan, " ", " "); err == nil {
|
||||||
|
result = string(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *jmeterConverter) buildJmeterTestPlan(testSuite *testing.TestSuite) (result *JmeterTestPlan, err error) {
|
||||||
|
if err = testSuite.Render(make(map[string]interface{})); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
requestItems := []interface{}{}
|
||||||
|
for _, item := range testSuite.Items {
|
||||||
|
item.Request.RenderAPI(testSuite.API)
|
||||||
|
|
||||||
|
api, err := url.Parse(item.Request.API)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
requestItems = append(requestItems, &HTTPSamplerProxy{
|
||||||
|
GUIClass: "HttpTestSampleGui",
|
||||||
|
TestClass: "HTTPSamplerProxy",
|
||||||
|
Enabled: true,
|
||||||
|
Name: item.Name,
|
||||||
|
StringProp: []StringProp{{
|
||||||
|
Name: "HTTPSampler.domain",
|
||||||
|
Value: api.Host,
|
||||||
|
}, {
|
||||||
|
Name: "HTTPSampler.port",
|
||||||
|
Value: api.Port(),
|
||||||
|
}, {
|
||||||
|
Name: "HTTPSampler.path",
|
||||||
|
Value: api.Path,
|
||||||
|
}, {
|
||||||
|
Name: "HTTPSampler.method",
|
||||||
|
Value: item.Request.Method,
|
||||||
|
}},
|
||||||
|
})
|
||||||
|
requestItems = append(requestItems, HashTree{})
|
||||||
|
}
|
||||||
|
requestItems = append(requestItems, &ResultCollector{
|
||||||
|
Enabled: true,
|
||||||
|
GUIClass: "SummaryReport",
|
||||||
|
TestClass: "ResultCollector",
|
||||||
|
Name: "Summary Report",
|
||||||
|
})
|
||||||
|
|
||||||
|
result = &JmeterTestPlan{
|
||||||
|
Version: "1.2",
|
||||||
|
Properties: "5.0",
|
||||||
|
JMeter: "5.0",
|
||||||
|
HashTree: HashTree{
|
||||||
|
Items: []interface{}{
|
||||||
|
&TestPlan{
|
||||||
|
StringProp: []StringProp{{
|
||||||
|
Name: "TestPlan.comments",
|
||||||
|
Value: "comment",
|
||||||
|
}},
|
||||||
|
Name: testSuite.Name,
|
||||||
|
GUIClass: "TestPlanGui",
|
||||||
|
TestClass: "TestPlan",
|
||||||
|
Enabled: true,
|
||||||
|
},
|
||||||
|
HashTree{
|
||||||
|
Items: []interface{}{
|
||||||
|
&ThreadGroup{
|
||||||
|
StringProp: []StringProp{{
|
||||||
|
Name: "ThreadGroup.num_threads",
|
||||||
|
Value: "1",
|
||||||
|
}},
|
||||||
|
GUIClass: "ThreadGroupGui",
|
||||||
|
TestClass: "ThreadGroup",
|
||||||
|
Enabled: true,
|
||||||
|
Name: "Thread Group",
|
||||||
|
ElementProp: ElementProp{
|
||||||
|
Name: "ThreadGroup.main_controller",
|
||||||
|
Type: "LoopController",
|
||||||
|
GUIClass: "LoopControlPanel",
|
||||||
|
TestClass: "LoopController",
|
||||||
|
BoolProp: []BoolProp{{
|
||||||
|
Name: "LoopController.continue_forever",
|
||||||
|
Value: "false",
|
||||||
|
}},
|
||||||
|
StringProp: []StringProp{{
|
||||||
|
Name: "LoopController.loops",
|
||||||
|
Value: "1",
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
HashTree{
|
||||||
|
Items: requestItems,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type JmeterTestPlan struct {
|
||||||
|
XMLName xml.Name `xml:"jmeterTestPlan"`
|
||||||
|
Version string `xml:"version,attr"`
|
||||||
|
Properties string `xml:"properties,attr"`
|
||||||
|
JMeter string `xml:"jmeter,attr"`
|
||||||
|
HashTree HashTree `xml:"hashTree"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HashTree struct {
|
||||||
|
XMLName xml.Name `xml:"hashTree"`
|
||||||
|
Items []interface{} `xml:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TestPlan struct {
|
||||||
|
XMLName xml.Name `xml:"TestPlan"`
|
||||||
|
Name string `xml:"testname,attr"`
|
||||||
|
GUIClass string `xml:"guiclass,attr"`
|
||||||
|
TestClass string `xml:"testclass,attr"`
|
||||||
|
Enabled bool `xml:"enabled,attr"`
|
||||||
|
StringProp []StringProp `xml:"stringProp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ThreadGroup struct {
|
||||||
|
XMLName xml.Name `xml:"ThreadGroup"`
|
||||||
|
GUIClass string `xml:"guiclass,attr"`
|
||||||
|
TestClass string `xml:"testclass,attr"`
|
||||||
|
Enabled bool `xml:"enabled,attr"`
|
||||||
|
Name string `xml:"testname,attr"`
|
||||||
|
StringProp []StringProp `xml:"stringProp"`
|
||||||
|
ElementProp ElementProp `xml:"elementProp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HTTPSamplerProxy struct {
|
||||||
|
XMLName xml.Name `xml:"HTTPSamplerProxy"`
|
||||||
|
StringProp []StringProp `xml:"stringProp"`
|
||||||
|
Name string `xml:"testname,attr"`
|
||||||
|
GUIClass string `xml:"guiclass,attr"`
|
||||||
|
TestClass string `xml:"testclass,attr"`
|
||||||
|
Enabled bool `xml:"enabled,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResultCollector struct {
|
||||||
|
XMLName xml.Name `xml:"ResultCollector"`
|
||||||
|
Enabled bool `xml:"enabled,attr"`
|
||||||
|
GUIClass string `xml:"guiclass,attr"`
|
||||||
|
TestClass string `xml:"testclass,attr"`
|
||||||
|
Name string `xml:"testname,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ElementProp struct {
|
||||||
|
Name string `xml:"name,attr"`
|
||||||
|
Type string `xml:"elementType,attr"`
|
||||||
|
GUIClass string `xml:"guiclass,attr"`
|
||||||
|
TestClass string `xml:"testclass,attr"`
|
||||||
|
Enabled bool `xml:"enabled,attr"`
|
||||||
|
StringProp []StringProp `xml:"stringProp"`
|
||||||
|
BoolProp []BoolProp `xml:"boolProp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type StringProp struct {
|
||||||
|
Name string `xml:"name,attr"`
|
||||||
|
Value string `xml:",chardata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BoolProp struct {
|
||||||
|
Name string `xml:"name,attr"`
|
||||||
|
Value string `xml:",chardata"`
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/**
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 API Testing Authors.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package generator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
_ "embed"
|
||||||
|
|
||||||
|
atest "github.com/linuxsuren/api-testing/pkg/testing"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestJmeterConvert(t *testing.T) {
|
||||||
|
t.Run("common", func(t *testing.T) {
|
||||||
|
jmeterConvert := GetTestSuiteConverter("jmeter")
|
||||||
|
assert.NotNil(t, jmeterConvert)
|
||||||
|
|
||||||
|
converters := GetTestSuiteConverters()
|
||||||
|
assert.Equal(t, 1, len(converters))
|
||||||
|
})
|
||||||
|
|
||||||
|
testSuite := &atest.TestSuite{
|
||||||
|
Name: "API Testing",
|
||||||
|
API: "http://localhost:8080",
|
||||||
|
Items: []atest.TestCase{{
|
||||||
|
Name: "hello-jmeter",
|
||||||
|
Request: atest.Request{
|
||||||
|
Method: "POST",
|
||||||
|
API: "/GetSuites",
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
|
||||||
|
converter := &jmeterConverter{}
|
||||||
|
output, err := converter.Convert(testSuite)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, expectedJmeter, output, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:embed testdata/expected_jmeter.jmx
|
||||||
|
var expectedJmeter string
|
|
@ -0,0 +1,26 @@
|
||||||
|
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.0">
|
||||||
|
<hashTree>
|
||||||
|
<TestPlan testname="API Testing" guiclass="TestPlanGui" testclass="TestPlan" enabled="true">
|
||||||
|
<stringProp name="TestPlan.comments">comment</stringProp>
|
||||||
|
</TestPlan>
|
||||||
|
<hashTree>
|
||||||
|
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" enabled="true" testname="Thread Group">
|
||||||
|
<stringProp name="ThreadGroup.num_threads">1</stringProp>
|
||||||
|
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" enabled="false">
|
||||||
|
<stringProp name="LoopController.loops">1</stringProp>
|
||||||
|
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||||
|
</elementProp>
|
||||||
|
</ThreadGroup>
|
||||||
|
<hashTree>
|
||||||
|
<HTTPSamplerProxy testname="hello-jmeter" guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" enabled="true">
|
||||||
|
<stringProp name="HTTPSampler.domain">localhost:8080</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.port">8080</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.path">/GetSuites</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.method">POST</stringProp>
|
||||||
|
</HTTPSamplerProxy>
|
||||||
|
<hashTree></hashTree>
|
||||||
|
<ResultCollector enabled="true" guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report"></ResultCollector>
|
||||||
|
</hashTree>
|
||||||
|
</hashTree>
|
||||||
|
</hashTree>
|
||||||
|
</jmeterTestPlan>
|
|
@ -3,6 +3,9 @@ package render
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
@ -91,6 +94,27 @@ var advancedFuncs = []AdvancedFunc{{
|
||||||
}
|
}
|
||||||
return err.Error()
|
return err.Error()
|
||||||
},
|
},
|
||||||
|
}, {
|
||||||
|
FuncName: "md5",
|
||||||
|
Func: func(text string) string {
|
||||||
|
hash := md5.Sum([]byte(text))
|
||||||
|
return hex.EncodeToString(hash[:])
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
FuncName: "base64",
|
||||||
|
Func: func(text string) string {
|
||||||
|
return base64.StdEncoding.EncodeToString([]byte(text))
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
FuncName: "base64Decode",
|
||||||
|
Func: func(text string) string {
|
||||||
|
result, err := base64.StdEncoding.DecodeString(text)
|
||||||
|
if err == nil {
|
||||||
|
return string(result)
|
||||||
|
} else {
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
// GetAdvancedFuncs returns all the advanced functions
|
// GetAdvancedFuncs returns all the advanced functions
|
||||||
|
|
|
@ -31,6 +31,22 @@ func TestRender(t *testing.T) {
|
||||||
verify: func(t *testing.T, s string) {
|
verify: func(t *testing.T, s string) {
|
||||||
assert.Equal(t, 8, len(s))
|
assert.Equal(t, 8, len(s))
|
||||||
},
|
},
|
||||||
|
}, {
|
||||||
|
name: "md5",
|
||||||
|
text: `{{md5 "linuxsuren"}}`,
|
||||||
|
expect: "b559b80ae1ba1c292d9b3265f265e76a",
|
||||||
|
}, {
|
||||||
|
name: "base64",
|
||||||
|
text: `{{base64 "linuxsuren"}}`,
|
||||||
|
expect: "bGludXhzdXJlbg==",
|
||||||
|
}, {
|
||||||
|
name: "base64Decode",
|
||||||
|
text: `{{base64Decode "bGludXhzdXJlbg=="}}`,
|
||||||
|
expect: "linuxsuren",
|
||||||
|
}, {
|
||||||
|
name: "base64Decode with error",
|
||||||
|
text: `{{base64Decode "error"}}`,
|
||||||
|
expect: "illegal base64 data at input byte 4",
|
||||||
}, {
|
}, {
|
||||||
name: "complex",
|
name: "complex",
|
||||||
text: `{{(index .items 0).name}}?a=a&key={{randomKubernetesName}}`,
|
text: `{{(index .items 0).name}}?a=a&key={{randomKubernetesName}}`,
|
||||||
|
|
|
@ -204,9 +204,7 @@ func (s *server) Run(ctx context.Context, task *TestTask) (reply *TestResult, er
|
||||||
suiteRunner.WithWriteLevel(task.Level)
|
suiteRunner.WithWriteLevel(task.Level)
|
||||||
|
|
||||||
// reuse the API prefix
|
// reuse the API prefix
|
||||||
if strings.HasPrefix(testCase.Request.API, "/") {
|
testCase.Request.RenderAPI(suite.API)
|
||||||
testCase.Request.API = fmt.Sprintf("%s%s", suite.API, testCase.Request.API)
|
|
||||||
}
|
|
||||||
|
|
||||||
output, testErr := suiteRunner.RunTestCase(&testCase, dataContext, ctx)
|
output, testErr := suiteRunner.RunTestCase(&testCase, dataContext, ctx)
|
||||||
if getter, ok := suiteRunner.(runner.HTTPResponseRecord); ok {
|
if getter, ok := suiteRunner.(runner.HTTPResponseRecord); ok {
|
||||||
|
@ -523,14 +521,40 @@ func (s *server) GenerateCode(ctx context.Context, in *CodeGenerateRequest) (rep
|
||||||
loader := s.getLoader(ctx)
|
loader := s.getLoader(ctx)
|
||||||
if result, err = loader.GetTestCase(in.TestSuite, in.TestCase); err == nil {
|
if result, err = loader.GetTestCase(in.TestSuite, in.TestCase); err == nil {
|
||||||
output, genErr := instance.Generate(&result)
|
output, genErr := instance.Generate(&result)
|
||||||
if genErr != nil {
|
reply.Success = genErr == nil
|
||||||
reply.Success = false
|
reply.Message = util.OrErrorMessage(genErr, output)
|
||||||
reply.Message = genErr.Error()
|
|
||||||
} else {
|
|
||||||
reply.Success = true
|
|
||||||
reply.Message = 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
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -604,6 +604,28 @@ func TestCodeGenerator(t *testing.T) {
|
||||||
assert.True(t, result.Success)
|
assert.True(t, result.Success)
|
||||||
assert.NotEmpty(t, result.Message)
|
assert.NotEmpty(t, result.Message)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("ListConverter", func(t *testing.T) {
|
||||||
|
list, err := server.ListConverter(ctx, &Empty{})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 1, len(list.Data))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("ConvertTestSuite no converter given", func(t *testing.T) {
|
||||||
|
reply, err := server.ConvertTestSuite(ctx, &CodeGenerateRequest{})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if assert.NotNil(t, reply) {
|
||||||
|
assert.False(t, reply.Success)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("ConvertTestSuite no suite found", func(t *testing.T) {
|
||||||
|
reply, err := server.ConvertTestSuite(ctx, &CodeGenerateRequest{Generator: "jmeter"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if assert.NotNil(t, reply) {
|
||||||
|
assert.True(t, reply.Success)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFunctionsQueryStream(t *testing.T) {
|
func TestFunctionsQueryStream(t *testing.T) {
|
||||||
|
|
|
@ -1979,7 +1979,7 @@ var file_pkg_server_server_proto_rawDesc = []byte{
|
||||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75,
|
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75,
|
||||||
0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
|
0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
|
||||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
|
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
|
||||||
0x69, 0x6f, 0x6e, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x32, 0xc3, 0x0d, 0x0a,
|
0x69, 0x6f, 0x6e, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x32, 0xc2, 0x0e, 0x0a,
|
||||||
0x06, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x03, 0x52, 0x75, 0x6e, 0x12, 0x10,
|
0x06, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x03, 0x52, 0x75, 0x6e, 0x12, 0x10,
|
||||||
0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b,
|
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,
|
0x1a, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65,
|
||||||
|
@ -2039,59 +2039,67 @@ var file_pkg_server_server_proto_rawDesc = []byte{
|
||||||
0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
|
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,
|
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, 0x00, 0x12,
|
0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12,
|
||||||
0x30, 0x0a, 0x0e, 0x50, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
|
0x34, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 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,
|
|
||||||
0x00, 0x12, 0x36, 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, 0x00, 0x12, 0x40, 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, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x31, 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, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65,
|
|
||||||
0x72, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x2d,
|
|
||||||
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, 0x00, 0x12, 0x34, 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, 0x00, 0x12, 0x2c, 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,
|
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,
|
0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4c,
|
||||||
0x00, 0x12, 0x2d, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65,
|
0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74,
|
||||||
0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x1a,
|
0x54, 0x65, 0x73, 0x74, 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||||
0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x00,
|
0x65, 0x72, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52,
|
||||||
0x12, 0x2d, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12,
|
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, 0x00, 0x12, 0x30,
|
||||||
|
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, 0x00,
|
||||||
|
0x12, 0x36, 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, 0x00, 0x12, 0x40, 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, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x31, 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, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||||
|
0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x2d, 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, 0x00, 0x12, 0x34, 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, 0x00, 0x12, 0x2c, 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, 0x00,
|
||||||
|
0x12, 0x2d, 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,
|
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, 0x00, 0x12,
|
0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x00, 0x12,
|
||||||
0x2d, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x0d,
|
0x2d, 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,
|
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, 0x00, 0x12, 0x3a,
|
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x00, 0x12, 0x2d,
|
||||||
0x0a, 0x0b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x13, 0x2e,
|
0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x0d, 0x2e,
|
||||||
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x51, 0x75, 0x65,
|
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x1a, 0x0d, 0x2e, 0x73,
|
||||||
0x72, 0x79, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
|
0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x00, 0x12, 0x3a, 0x0a,
|
||||||
0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x0a, 0x47, 0x65,
|
0x0b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x13, 0x2e, 0x73,
|
||||||
0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65,
|
0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72,
|
||||||
0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
|
0x79, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f,
|
||||||
0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0c, 0x43, 0x72,
|
0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x0a, 0x47, 0x65, 0x74,
|
||||||
0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72,
|
0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||||
0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72,
|
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e,
|
||||||
0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74,
|
0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0c, 0x43, 0x72, 0x65,
|
||||||
0x22, 0x00, 0x12, 0x36, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72,
|
0x61, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||||
0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72,
|
0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||||
0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
|
0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22,
|
||||||
0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0c, 0x55, 0x70,
|
0x00, 0x12, 0x36, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65,
|
||||||
0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72,
|
0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65,
|
||||||
0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72,
|
0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f,
|
||||||
0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74,
|
0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0c, 0x55, 0x70, 0x64,
|
||||||
0x22, 0x00, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
0x61, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||||
0x2f, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x73, 0x75, 0x72, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2d,
|
0x65, 0x72, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||||
0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76,
|
0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22,
|
||||||
0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x00, 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 (
|
var (
|
||||||
|
@ -2181,53 +2189,57 @@ var file_pkg_server_server_proto_depIdxs = []int32{
|
||||||
2, // 36: server.Runner.DeleteTestCase:input_type -> server.TestCaseIdentity
|
2, // 36: server.Runner.DeleteTestCase:input_type -> server.TestCaseIdentity
|
||||||
29, // 37: server.Runner.ListCodeGenerator:input_type -> server.Empty
|
29, // 37: server.Runner.ListCodeGenerator:input_type -> server.Empty
|
||||||
26, // 38: server.Runner.GenerateCode:input_type -> server.CodeGenerateRequest
|
26, // 38: server.Runner.GenerateCode:input_type -> server.CodeGenerateRequest
|
||||||
29, // 39: server.Runner.PopularHeaders:input_type -> server.Empty
|
29, // 39: server.Runner.ListConverter:input_type -> server.Empty
|
||||||
18, // 40: server.Runner.FunctionsQuery:input_type -> server.SimpleQuery
|
26, // 40: server.Runner.ConvertTestSuite:input_type -> server.CodeGenerateRequest
|
||||||
18, // 41: server.Runner.FunctionsQueryStream:input_type -> server.SimpleQuery
|
29, // 41: server.Runner.PopularHeaders:input_type -> server.Empty
|
||||||
29, // 42: server.Runner.GetVersion:input_type -> server.Empty
|
18, // 42: server.Runner.FunctionsQuery:input_type -> server.SimpleQuery
|
||||||
29, // 43: server.Runner.Sample:input_type -> server.Empty
|
18, // 43: server.Runner.FunctionsQueryStream:input_type -> server.SimpleQuery
|
||||||
29, // 44: server.Runner.GetStoreKinds:input_type -> server.Empty
|
29, // 44: server.Runner.GetVersion:input_type -> server.Empty
|
||||||
29, // 45: server.Runner.GetStores:input_type -> server.Empty
|
29, // 45: server.Runner.Sample:input_type -> server.Empty
|
||||||
20, // 46: server.Runner.CreateStore:input_type -> server.Store
|
29, // 46: server.Runner.GetStoreKinds:input_type -> server.Empty
|
||||||
20, // 47: server.Runner.UpdateStore:input_type -> server.Store
|
29, // 47: server.Runner.GetStores:input_type -> server.Empty
|
||||||
20, // 48: server.Runner.DeleteStore:input_type -> server.Store
|
20, // 48: server.Runner.CreateStore:input_type -> server.Store
|
||||||
18, // 49: server.Runner.VerifyStore:input_type -> server.SimpleQuery
|
20, // 49: server.Runner.UpdateStore:input_type -> server.Store
|
||||||
29, // 50: server.Runner.GetSecrets:input_type -> server.Empty
|
20, // 50: server.Runner.DeleteStore:input_type -> server.Store
|
||||||
28, // 51: server.Runner.CreateSecret:input_type -> server.Secret
|
18, // 51: server.Runner.VerifyStore:input_type -> server.SimpleQuery
|
||||||
28, // 52: server.Runner.DeleteSecret:input_type -> server.Secret
|
29, // 52: server.Runner.GetSecrets:input_type -> server.Empty
|
||||||
28, // 53: server.Runner.UpdateSecret:input_type -> server.Secret
|
28, // 53: server.Runner.CreateSecret:input_type -> server.Secret
|
||||||
7, // 54: server.Runner.Run:output_type -> server.TestResult
|
28, // 54: server.Runner.DeleteSecret:input_type -> server.Secret
|
||||||
0, // 55: server.Runner.GetSuites:output_type -> server.Suites
|
28, // 55: server.Runner.UpdateSecret:input_type -> server.Secret
|
||||||
8, // 56: server.Runner.CreateTestSuite:output_type -> server.HelloReply
|
7, // 56: server.Runner.Run:output_type -> server.TestResult
|
||||||
3, // 57: server.Runner.GetTestSuite:output_type -> server.TestSuite
|
0, // 57: server.Runner.GetSuites:output_type -> server.Suites
|
||||||
8, // 58: server.Runner.UpdateTestSuite:output_type -> server.HelloReply
|
8, // 58: server.Runner.CreateTestSuite:output_type -> server.HelloReply
|
||||||
8, // 59: server.Runner.DeleteTestSuite:output_type -> server.HelloReply
|
3, // 59: server.Runner.GetTestSuite:output_type -> server.TestSuite
|
||||||
9, // 60: server.Runner.ListTestCase:output_type -> server.Suite
|
8, // 60: server.Runner.UpdateTestSuite:output_type -> server.HelloReply
|
||||||
11, // 61: server.Runner.GetSuggestedAPIs:output_type -> server.TestCases
|
8, // 61: server.Runner.DeleteTestSuite:output_type -> server.HelloReply
|
||||||
15, // 62: server.Runner.RunTestCase:output_type -> server.TestCaseResult
|
9, // 62: server.Runner.ListTestCase:output_type -> server.Suite
|
||||||
12, // 63: server.Runner.GetTestCase:output_type -> server.TestCase
|
11, // 63: server.Runner.GetSuggestedAPIs:output_type -> server.TestCases
|
||||||
8, // 64: server.Runner.CreateTestCase:output_type -> server.HelloReply
|
15, // 64: server.Runner.RunTestCase:output_type -> server.TestCaseResult
|
||||||
8, // 65: server.Runner.UpdateTestCase:output_type -> server.HelloReply
|
12, // 65: server.Runner.GetTestCase:output_type -> server.TestCase
|
||||||
8, // 66: server.Runner.DeleteTestCase:output_type -> server.HelloReply
|
8, // 66: server.Runner.CreateTestCase:output_type -> server.HelloReply
|
||||||
24, // 67: server.Runner.ListCodeGenerator:output_type -> server.SimpleList
|
8, // 67: server.Runner.UpdateTestCase:output_type -> server.HelloReply
|
||||||
23, // 68: server.Runner.GenerateCode:output_type -> server.CommonResult
|
8, // 68: server.Runner.DeleteTestCase:output_type -> server.HelloReply
|
||||||
17, // 69: server.Runner.PopularHeaders:output_type -> server.Pairs
|
24, // 69: server.Runner.ListCodeGenerator:output_type -> server.SimpleList
|
||||||
17, // 70: server.Runner.FunctionsQuery:output_type -> server.Pairs
|
23, // 70: server.Runner.GenerateCode:output_type -> server.CommonResult
|
||||||
17, // 71: server.Runner.FunctionsQueryStream:output_type -> server.Pairs
|
24, // 71: server.Runner.ListConverter:output_type -> server.SimpleList
|
||||||
8, // 72: server.Runner.GetVersion:output_type -> server.HelloReply
|
23, // 72: server.Runner.ConvertTestSuite:output_type -> server.CommonResult
|
||||||
8, // 73: server.Runner.Sample:output_type -> server.HelloReply
|
17, // 73: server.Runner.PopularHeaders:output_type -> server.Pairs
|
||||||
21, // 74: server.Runner.GetStoreKinds:output_type -> server.StoreKinds
|
17, // 74: server.Runner.FunctionsQuery:output_type -> server.Pairs
|
||||||
19, // 75: server.Runner.GetStores:output_type -> server.Stores
|
17, // 75: server.Runner.FunctionsQueryStream:output_type -> server.Pairs
|
||||||
20, // 76: server.Runner.CreateStore:output_type -> server.Store
|
8, // 76: server.Runner.GetVersion:output_type -> server.HelloReply
|
||||||
20, // 77: server.Runner.UpdateStore:output_type -> server.Store
|
8, // 77: server.Runner.Sample:output_type -> server.HelloReply
|
||||||
20, // 78: server.Runner.DeleteStore:output_type -> server.Store
|
21, // 78: server.Runner.GetStoreKinds:output_type -> server.StoreKinds
|
||||||
23, // 79: server.Runner.VerifyStore:output_type -> server.CommonResult
|
19, // 79: server.Runner.GetStores:output_type -> server.Stores
|
||||||
27, // 80: server.Runner.GetSecrets:output_type -> server.Secrets
|
20, // 80: server.Runner.CreateStore:output_type -> server.Store
|
||||||
23, // 81: server.Runner.CreateSecret:output_type -> server.CommonResult
|
20, // 81: server.Runner.UpdateStore:output_type -> server.Store
|
||||||
23, // 82: server.Runner.DeleteSecret:output_type -> server.CommonResult
|
20, // 82: server.Runner.DeleteStore:output_type -> server.Store
|
||||||
23, // 83: server.Runner.UpdateSecret:output_type -> server.CommonResult
|
23, // 83: server.Runner.VerifyStore:output_type -> server.CommonResult
|
||||||
54, // [54:84] is the sub-list for method output_type
|
27, // 84: server.Runner.GetSecrets:output_type -> server.Secrets
|
||||||
24, // [24:54] is the sub-list for method input_type
|
23, // 85: server.Runner.CreateSecret:output_type -> server.CommonResult
|
||||||
|
23, // 86: server.Runner.DeleteSecret:output_type -> server.CommonResult
|
||||||
|
23, // 87: server.Runner.UpdateSecret:output_type -> server.CommonResult
|
||||||
|
56, // [56:88] is the sub-list for method output_type
|
||||||
|
24, // [24:56] is the sub-list for method input_type
|
||||||
24, // [24:24] is the sub-list for extension type_name
|
24, // [24:24] is the sub-list for extension type_name
|
||||||
24, // [24:24] is the sub-list for extension extendee
|
24, // [24:24] is the sub-list for extension extendee
|
||||||
0, // [0:24] is the sub-list for field type_name
|
0, // [0:24] is the sub-list for field type_name
|
||||||
|
|
|
@ -541,6 +541,74 @@ func local_request_Runner_GenerateCode_0(ctx context.Context, marshaler runtime.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func request_Runner_ListConverter_0(ctx context.Context, marshaler runtime.Marshaler, client RunnerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq Empty
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||||
|
if berr != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||||
|
}
|
||||||
|
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := client.ListConverter(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func local_request_Runner_ListConverter_0(ctx context.Context, marshaler runtime.Marshaler, server RunnerServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq Empty
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||||
|
if berr != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||||
|
}
|
||||||
|
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := server.ListConverter(ctx, &protoReq)
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func request_Runner_ConvertTestSuite_0(ctx context.Context, marshaler runtime.Marshaler, client RunnerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq CodeGenerateRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||||
|
if berr != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||||
|
}
|
||||||
|
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := client.ConvertTestSuite(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func local_request_Runner_ConvertTestSuite_0(ctx context.Context, marshaler runtime.Marshaler, server RunnerServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq CodeGenerateRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||||
|
if berr != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||||
|
}
|
||||||
|
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := server.ConvertTestSuite(ctx, &protoReq)
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func request_Runner_PopularHeaders_0(ctx context.Context, marshaler runtime.Marshaler, client RunnerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
func request_Runner_PopularHeaders_0(ctx context.Context, marshaler runtime.Marshaler, client RunnerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
var protoReq Empty
|
var protoReq Empty
|
||||||
var metadata runtime.ServerMetadata
|
var metadata runtime.ServerMetadata
|
||||||
|
@ -1441,6 +1509,56 @@ func RegisterRunnerHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Runner_ListConverter_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.Runner/ListConverter", runtime.WithHTTPPathPattern("/server.Runner/ListConverter"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := local_request_Runner_ListConverter_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_Runner_ListConverter_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Runner_ConvertTestSuite_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.Runner/ConvertTestSuite", runtime.WithHTTPPathPattern("/server.Runner/ConvertTestSuite"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := local_request_Runner_ConvertTestSuite_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_Runner_ConvertTestSuite_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
mux.Handle("POST", pattern_Runner_PopularHeaders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("POST", pattern_Runner_PopularHeaders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -2169,6 +2287,50 @@ func RegisterRunnerHandlerClient(ctx context.Context, mux *runtime.ServeMux, cli
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Runner_ListConverter_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.Runner/ListConverter", runtime.WithHTTPPathPattern("/server.Runner/ListConverter"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_Runner_ListConverter_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Runner_ListConverter_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Runner_ConvertTestSuite_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.Runner/ConvertTestSuite", runtime.WithHTTPPathPattern("/server.Runner/ConvertTestSuite"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_Runner_ConvertTestSuite_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Runner_ConvertTestSuite_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
mux.Handle("POST", pattern_Runner_PopularHeaders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("POST", pattern_Runner_PopularHeaders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -2533,6 +2695,10 @@ var (
|
||||||
|
|
||||||
pattern_Runner_GenerateCode_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"server.Runner", "GenerateCode"}, ""))
|
pattern_Runner_GenerateCode_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"server.Runner", "GenerateCode"}, ""))
|
||||||
|
|
||||||
|
pattern_Runner_ListConverter_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"server.Runner", "ListConverter"}, ""))
|
||||||
|
|
||||||
|
pattern_Runner_ConvertTestSuite_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"server.Runner", "ConvertTestSuite"}, ""))
|
||||||
|
|
||||||
pattern_Runner_PopularHeaders_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"server.Runner", "PopularHeaders"}, ""))
|
pattern_Runner_PopularHeaders_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"server.Runner", "PopularHeaders"}, ""))
|
||||||
|
|
||||||
pattern_Runner_FunctionsQuery_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"server.Runner", "FunctionsQuery"}, ""))
|
pattern_Runner_FunctionsQuery_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"server.Runner", "FunctionsQuery"}, ""))
|
||||||
|
@ -2595,6 +2761,10 @@ var (
|
||||||
|
|
||||||
forward_Runner_GenerateCode_0 = runtime.ForwardResponseMessage
|
forward_Runner_GenerateCode_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
|
forward_Runner_ListConverter_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
|
forward_Runner_ConvertTestSuite_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_Runner_PopularHeaders_0 = runtime.ForwardResponseMessage
|
forward_Runner_PopularHeaders_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_Runner_FunctionsQuery_0 = runtime.ForwardResponseMessage
|
forward_Runner_FunctionsQuery_0 = runtime.ForwardResponseMessage
|
||||||
|
|
|
@ -27,6 +27,10 @@ service Runner {
|
||||||
rpc ListCodeGenerator(Empty) returns (SimpleList) {}
|
rpc ListCodeGenerator(Empty) returns (SimpleList) {}
|
||||||
rpc GenerateCode(CodeGenerateRequest) returns (CommonResult) {}
|
rpc GenerateCode(CodeGenerateRequest) returns (CommonResult) {}
|
||||||
|
|
||||||
|
// converter
|
||||||
|
rpc ListConverter(Empty) returns (SimpleList) {}
|
||||||
|
rpc ConvertTestSuite(CodeGenerateRequest) returns (CommonResult) {}
|
||||||
|
|
||||||
// common services
|
// common services
|
||||||
rpc PopularHeaders(Empty) returns (Pairs) {}
|
rpc PopularHeaders(Empty) returns (Pairs) {}
|
||||||
rpc FunctionsQuery(SimpleQuery) returns (Pairs) {}
|
rpc FunctionsQuery(SimpleQuery) returns (Pairs) {}
|
||||||
|
|
|
@ -40,6 +40,9 @@ type RunnerClient interface {
|
||||||
// code generator
|
// code generator
|
||||||
ListCodeGenerator(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*SimpleList, error)
|
ListCodeGenerator(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*SimpleList, error)
|
||||||
GenerateCode(ctx context.Context, in *CodeGenerateRequest, opts ...grpc.CallOption) (*CommonResult, error)
|
GenerateCode(ctx context.Context, in *CodeGenerateRequest, opts ...grpc.CallOption) (*CommonResult, error)
|
||||||
|
// converter
|
||||||
|
ListConverter(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*SimpleList, error)
|
||||||
|
ConvertTestSuite(ctx context.Context, in *CodeGenerateRequest, opts ...grpc.CallOption) (*CommonResult, error)
|
||||||
// common services
|
// common services
|
||||||
PopularHeaders(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Pairs, error)
|
PopularHeaders(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Pairs, error)
|
||||||
FunctionsQuery(ctx context.Context, in *SimpleQuery, opts ...grpc.CallOption) (*Pairs, error)
|
FunctionsQuery(ctx context.Context, in *SimpleQuery, opts ...grpc.CallOption) (*Pairs, error)
|
||||||
|
@ -203,6 +206,24 @@ func (c *runnerClient) GenerateCode(ctx context.Context, in *CodeGenerateRequest
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *runnerClient) ListConverter(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*SimpleList, error) {
|
||||||
|
out := new(SimpleList)
|
||||||
|
err := c.cc.Invoke(ctx, "/server.Runner/ListConverter", in, out, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *runnerClient) ConvertTestSuite(ctx context.Context, in *CodeGenerateRequest, opts ...grpc.CallOption) (*CommonResult, error) {
|
||||||
|
out := new(CommonResult)
|
||||||
|
err := c.cc.Invoke(ctx, "/server.Runner/ConvertTestSuite", in, out, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *runnerClient) PopularHeaders(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Pairs, error) {
|
func (c *runnerClient) PopularHeaders(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Pairs, error) {
|
||||||
out := new(Pairs)
|
out := new(Pairs)
|
||||||
err := c.cc.Invoke(ctx, "/server.Runner/PopularHeaders", in, out, opts...)
|
err := c.cc.Invoke(ctx, "/server.Runner/PopularHeaders", in, out, opts...)
|
||||||
|
@ -382,6 +403,9 @@ type RunnerServer interface {
|
||||||
// code generator
|
// code generator
|
||||||
ListCodeGenerator(context.Context, *Empty) (*SimpleList, error)
|
ListCodeGenerator(context.Context, *Empty) (*SimpleList, error)
|
||||||
GenerateCode(context.Context, *CodeGenerateRequest) (*CommonResult, error)
|
GenerateCode(context.Context, *CodeGenerateRequest) (*CommonResult, error)
|
||||||
|
// converter
|
||||||
|
ListConverter(context.Context, *Empty) (*SimpleList, error)
|
||||||
|
ConvertTestSuite(context.Context, *CodeGenerateRequest) (*CommonResult, error)
|
||||||
// common services
|
// common services
|
||||||
PopularHeaders(context.Context, *Empty) (*Pairs, error)
|
PopularHeaders(context.Context, *Empty) (*Pairs, error)
|
||||||
FunctionsQuery(context.Context, *SimpleQuery) (*Pairs, error)
|
FunctionsQuery(context.Context, *SimpleQuery) (*Pairs, error)
|
||||||
|
@ -452,6 +476,12 @@ func (UnimplementedRunnerServer) ListCodeGenerator(context.Context, *Empty) (*Si
|
||||||
func (UnimplementedRunnerServer) GenerateCode(context.Context, *CodeGenerateRequest) (*CommonResult, error) {
|
func (UnimplementedRunnerServer) GenerateCode(context.Context, *CodeGenerateRequest) (*CommonResult, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GenerateCode not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method GenerateCode not implemented")
|
||||||
}
|
}
|
||||||
|
func (UnimplementedRunnerServer) ListConverter(context.Context, *Empty) (*SimpleList, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method ListConverter not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedRunnerServer) ConvertTestSuite(context.Context, *CodeGenerateRequest) (*CommonResult, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method ConvertTestSuite not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedRunnerServer) PopularHeaders(context.Context, *Empty) (*Pairs, error) {
|
func (UnimplementedRunnerServer) PopularHeaders(context.Context, *Empty) (*Pairs, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method PopularHeaders not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method PopularHeaders not implemented")
|
||||||
}
|
}
|
||||||
|
@ -780,6 +810,42 @@ func _Runner_GenerateCode_Handler(srv interface{}, ctx context.Context, dec func
|
||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _Runner_ListConverter_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(Empty)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(RunnerServer).ListConverter(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: "/server.Runner/ListConverter",
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(RunnerServer).ListConverter(ctx, req.(*Empty))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _Runner_ConvertTestSuite_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(CodeGenerateRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(RunnerServer).ConvertTestSuite(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: "/server.Runner/ConvertTestSuite",
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(RunnerServer).ConvertTestSuite(ctx, req.(*CodeGenerateRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
func _Runner_PopularHeaders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
func _Runner_PopularHeaders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
in := new(Empty)
|
in := new(Empty)
|
||||||
if err := dec(in); err != nil {
|
if err := dec(in); err != nil {
|
||||||
|
@ -1125,6 +1191,14 @@ var Runner_ServiceDesc = grpc.ServiceDesc{
|
||||||
MethodName: "GenerateCode",
|
MethodName: "GenerateCode",
|
||||||
Handler: _Runner_GenerateCode_Handler,
|
Handler: _Runner_GenerateCode_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "ListConverter",
|
||||||
|
Handler: _Runner_ListConverter_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "ConvertTestSuite",
|
||||||
|
Handler: _Runner_ConvertTestSuite_Handler,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MethodName: "PopularHeaders",
|
MethodName: "PopularHeaders",
|
||||||
Handler: _Runner_PopularHeaders_Handler,
|
Handler: _Runner_PopularHeaders_Handler,
|
||||||
|
|
|
@ -160,6 +160,14 @@ func (r *Request) Render(ctx interface{}, dataDir string) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RenderAPI will combine with the base API
|
||||||
|
func (r *Request) RenderAPI(base string) {
|
||||||
|
// reuse the API prefix
|
||||||
|
if strings.HasPrefix(r.API, "/") {
|
||||||
|
r.API = fmt.Sprintf("%s%s", base, r.API)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetBody returns the request body
|
// GetBody returns the request body
|
||||||
func (r *Request) GetBody() (reader io.Reader, err error) {
|
func (r *Request) GetBody() (reader io.Reader, err error) {
|
||||||
if len(r.Form) > 0 {
|
if len(r.Form) > 0 {
|
||||||
|
|
|
@ -26,8 +26,13 @@ package util
|
||||||
|
|
||||||
// OKOrErrorMessage returns OK or error message
|
// OKOrErrorMessage returns OK or error message
|
||||||
func OKOrErrorMessage(err error) string {
|
func OKOrErrorMessage(err error) string {
|
||||||
|
return OrErrorMessage(err, "OK")
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrErrorMessage returns error message or message
|
||||||
|
func OrErrorMessage(err error, message string) string {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error()
|
return err.Error()
|
||||||
}
|
}
|
||||||
return "OK"
|
return message
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/**
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 API Testing Authors.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
// Keys returns a list of keys
|
||||||
|
func Keys[T interface{}](data map[string]T) (keys []string) {
|
||||||
|
keys = make([]string, len(data))
|
||||||
|
index := 0
|
||||||
|
for k := range data {
|
||||||
|
keys[index] = k
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 API Testing Authors.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package util_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/linuxsuren/api-testing/pkg/util"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestKeys(t *testing.T) {
|
||||||
|
t.Run("normal", func(t *testing.T) {
|
||||||
|
assert.Equal(t, []string{"foo", "bar"},
|
||||||
|
util.Keys(map[string]interface{}{"foo": "xx", "bar": "xx"}))
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue