├── .dockerignore
├── .editorconfig
├── .gitattributes
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── config.yml
│ ├── feature_reuqest.md
│ ├── non--crash-security--bug.md
│ └── other.md
├── PULL_REQUEST_TEMPLATE.md
├── dependabot.yml
├── markdown_lint_config.json
├── pre-commit
├── release-drafter.yml
├── testing
│ ├── core.yaml
│ ├── grpc.yaml
│ └── grpc_ref.yaml
└── workflows
│ ├── build.yaml
│ ├── docs.yaml
│ ├── issue-comment.yml
│ ├── license-check.yaml
│ ├── release-drafter.yml
│ └── release.yaml
├── .gitignore
├── .gitpod.yml
├── .goreleaser.yaml
├── .licenserc.yaml
├── .remarkrc
├── .vscode
└── extensions.json
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING-ZH.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README-ZH.md
├── README.md
├── SECURITY.md
├── action.yml
├── checklink_config.json
├── cmd
├── compose.go
├── convert.go
├── convert_test.go
├── data
│ ├── favicon.ico
│ ├── font
│ │ └── .keep
│ ├── image
│ │ └── warn.jpg
│ ├── index.css
│ ├── index.html
│ └── index.js
├── extension.go
├── extension_test.go
├── function.go
├── function_test.go
├── init.go
├── jsonschema.go
├── jsonschema_test.go
├── mock-compose.go
├── mock.go
├── mock_test.go
├── root.go
├── root_test.go
├── run.go
├── run_test.go
├── sample.go
├── sample_test.go
├── server.go
├── server_test.go
├── service.go
└── testdata
│ ├── invalid-api.yaml
│ ├── invalid-schema.yaml
│ ├── postman.json
│ ├── simple-suite.yaml
│ └── stores.yaml
├── console
├── atest-desktop
│ ├── README.md
│ ├── api-testing.icns
│ ├── api-testing.ico
│ ├── api-testing.png
│ ├── api.js
│ ├── api.test.js
│ ├── forge.config.js
│ ├── index.html
│ ├── main.js
│ ├── package-lock.json
│ ├── package.json
│ └── preload.js
└── atest-ui
│ ├── .eslintrc.cjs
│ ├── .gitignore
│ ├── .prettierrc.json
│ ├── .vscode
│ └── extensions.json
│ ├── README.md
│ ├── cypress.config.ts
│ ├── cypress
│ ├── e2e
│ │ ├── gRPC.cy.ts
│ │ ├── http.cy.ts
│ │ ├── tsconfig.json
│ │ └── util.ts
│ ├── fixtures
│ │ └── example.json
│ └── support
│ │ ├── commands.ts
│ │ └── e2e.ts
│ ├── env.d.ts
│ ├── gen.sh
│ ├── index.html
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ └── favicon.ico
│ ├── src
│ ├── App.vue
│ ├── assets
│ │ ├── base.css
│ │ ├── logo.svg
│ │ └── main.css
│ ├── components
│ │ ├── Button.vue
│ │ ├── EditButton.vue
│ │ ├── HistoryInput.vue
│ │ ├── LoginDialog.vue
│ │ ├── TestSuiteCreationDialog.vue
│ │ └── TestSuiteImportDialog.vue
│ ├── i18n.ts
│ ├── locales
│ │ ├── en.json
│ │ └── zh.json
│ ├── main.ts
│ ├── theme.ts
│ └── views
│ │ ├── APIInput.vue
│ │ ├── DataManager.vue
│ │ ├── MockManager.vue
│ │ ├── SecretManager.vue
│ │ ├── StoreManager.vue
│ │ ├── TemplateFunctions.vue
│ │ ├── TestCase.vue
│ │ ├── TestSuite.vue
│ │ ├── TestingHistoryPanel.vue
│ │ ├── TestingPanel.vue
│ │ ├── WelcomePage.vue
│ │ ├── __test__
│ │ ├── cache.spec.ts
│ │ ├── common.ts
│ │ ├── net.spec.ts
│ │ ├── store.spec.ts
│ │ └── types.spec.ts
│ │ ├── cache.ts
│ │ ├── magicKeys.ts
│ │ ├── net-vue.ts
│ │ ├── net.ts
│ │ ├── store.ts
│ │ └── types.ts
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ ├── tsconfig.vitest.json
│ ├── ui.go
│ ├── vite.config.ts
│ └── vitest.config.ts
├── docs
├── README.md
├── api-testing-mock-schema.json
├── api-testing-schema.json
├── constants.go
├── manifests
│ ├── argocd
│ │ └── simple.yaml
│ ├── docker-compose.yml
│ ├── kubernetes
│ │ ├── default
│ │ │ ├── kustomization.yaml
│ │ │ └── manifest.yaml
│ │ └── docker.io
│ │ │ └── kustomization.yaml
│ └── podman.yaml
├── package-lock.json
└── site
│ ├── .dockerignore
│ ├── .gitignore
│ ├── .nvmrc
│ ├── Dockerfile
│ ├── assets
│ ├── atest-vscode.png
│ ├── icons
│ │ ├── logo.png
│ │ └── logo.svg
│ └── scss
│ │ └── _variables_project.scss
│ ├── config.yaml
│ ├── content
│ ├── en
│ │ ├── _index.md
│ │ ├── about
│ │ │ └── index.md
│ │ ├── contributions
│ │ │ ├── CODE_OF_CONDUCT.md
│ │ │ ├── CONTRIBUTING.md
│ │ │ ├── SECURITY.md
│ │ │ ├── _index.md
│ │ │ ├── design
│ │ │ │ ├── Todo.md
│ │ │ │ └── _index.md
│ │ │ └── roadmap.md
│ │ ├── latest
│ │ │ ├── _index.md
│ │ │ ├── api
│ │ │ │ ├── _index.md
│ │ │ │ └── extension_types.md
│ │ │ ├── install
│ │ │ │ ├── _index.md
│ │ │ │ └── install-locally.md
│ │ │ ├── releases
│ │ │ │ ├── _index.md
│ │ │ │ └── v0.1.0.md
│ │ │ └── tasks
│ │ │ │ ├── _index.md
│ │ │ │ ├── grpc-manual.md
│ │ │ │ ├── mock-server.md
│ │ │ │ ├── prometheus.md
│ │ │ │ ├── quickstart.md
│ │ │ │ └── secure.md
│ │ ├── news
│ │ │ ├── _index.md
│ │ │ ├── blogs
│ │ │ │ └── _index.md
│ │ │ ├── presentations
│ │ │ │ └── _index.md
│ │ │ └── releases
│ │ │ │ └── _index.md
│ │ └── search.md
│ └── zh
│ │ ├── _index.md
│ │ ├── about
│ │ └── index.md
│ │ ├── contributions
│ │ ├── CONTRIBUTING-ZH.md
│ │ ├── _index.md
│ │ ├── design
│ │ │ ├── Goals.md
│ │ │ ├── _index.md
│ │ │ └── security-policy.md
│ │ └── roadmap.md
│ │ ├── latest
│ │ ├── _index.md
│ │ ├── api
│ │ │ ├── _index.md
│ │ │ └── extension_types.md
│ │ ├── install
│ │ │ ├── _index.md
│ │ │ ├── install-helm.md
│ │ │ └── install-local.md
│ │ └── tasks
│ │ │ ├── _index.md
│ │ │ ├── code-generator.md
│ │ │ ├── e2e.md
│ │ │ ├── extension.md
│ │ │ ├── grpc-TLS.md
│ │ │ ├── grpc-manual.md
│ │ │ ├── job.md
│ │ │ ├── mock.md
│ │ │ ├── mock
│ │ │ ├── image-registry.yaml
│ │ │ ├── object.yaml
│ │ │ └── simple.yaml
│ │ │ ├── quickstart.md
│ │ │ ├── secure.md
│ │ │ ├── template.md
│ │ │ ├── testsuite.yaml
│ │ │ └── verify.md
│ │ ├── news
│ │ ├── _index.md
│ │ ├── blogs
│ │ │ ├── _index.md
│ │ │ └── glcc-2023-announce.md
│ │ ├── presentations
│ │ │ └── _index.md
│ │ └── releases
│ │ │ └── _index.md
│ │ ├── releases
│ │ ├── _index.md
│ │ ├── release-note-v0.0.12.md
│ │ ├── release-note-v0.0.13.md
│ │ ├── release-note-v0.0.14.md
│ │ ├── release-note-v0.0.15.md
│ │ ├── release-note-v0.0.17.md
│ │ └── release-note-v0.0.18.md
│ │ └── search.md
│ ├── data
│ └── adopters.yaml
│ ├── docker-compose.yaml
│ ├── go.mod
│ ├── go.sum
│ ├── hugo.toml
│ ├── layouts
│ ├── 404.html
│ └── shortcodes
│ │ └── adopters.html
│ ├── package.json
│ └── static
│ ├── favicons
│ ├── favicons.ico
│ └── site.webmanifest
│ ├── img
│ └── logo.png
│ └── logos
│ ├── airspacelink.svg
│ └── logo.png
├── e2e
├── Dockerfile
├── README.md
├── code-generator
│ ├── Dockerfile
│ ├── JavaScript.sh
│ ├── compose.yaml
│ ├── curl.sh
│ ├── entrypoint.sh
│ ├── golang.sh
│ ├── java.sh
│ ├── python.sh
│ ├── robot-framework.sh
│ ├── start.sh
│ └── test-suites
│ │ └── test-suite.yaml
├── compose-external.yaml
├── compose-k8s.yaml
├── compose.yaml
├── entrypoint.sh
├── git.yaml
├── k8s.sh
├── openssl.cnf
├── start.sh
└── test-suite-common.yaml
├── extensions
└── README.md
├── go.mod
├── go.sum
├── helm
└── api-testing
│ ├── .helmignore
│ ├── Chart.lock
│ ├── Chart.yaml
│ ├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── pvc.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ ├── servicemonitor.yaml
│ └── tests
│ │ └── test-connection.yaml
│ └── values.yaml
├── main.go
├── pkg
├── apispec
│ ├── data
│ │ └── proto
│ │ │ ├── google
│ │ │ ├── api
│ │ │ │ ├── annotations.proto
│ │ │ │ └── http.proto
│ │ │ └── protobuf
│ │ │ │ ├── annotations.proto
│ │ │ │ ├── any.proto
│ │ │ │ ├── descriptor.proto
│ │ │ │ ├── duration.proto
│ │ │ │ ├── struct.proto
│ │ │ │ └── timestamp.proto
│ │ │ ├── protoc-gen-openapiv2
│ │ │ └── options
│ │ │ │ ├── annotations.proto
│ │ │ │ └── openapiv2.proto
│ │ │ └── validate
│ │ │ └── validate.proto
│ ├── fake.go
│ ├── fake_test.go
│ ├── grpc.go
│ ├── grpc_test.go
│ ├── remote_swagger.go
│ ├── swagger.go
│ ├── swagger_test.go
│ └── testdata
│ │ └── swagger.json
├── compare
│ ├── compare.go
│ ├── compare_test.go
│ ├── error.go
│ └── error_test.go
├── downloader
│ ├── extension.go
│ ├── oci.go
│ ├── oci_test.go
│ ├── progress.go
│ └── testdata
│ │ └── registry.yaml
├── extension
│ ├── option.go
│ ├── option_test.go
│ ├── pprof.go
│ ├── signal.go
│ └── singal_test.go
├── generator
│ ├── code_generator.go
│ ├── code_generator_test.go
│ ├── converter_jmeter.go
│ ├── converter_jmeter_test.go
│ ├── converter_raw.go
│ ├── converter_raw_test.go
│ ├── curl_generator.go
│ ├── curl_generator_test.go
│ ├── data
│ │ ├── curl.tpl
│ │ ├── main.go.tpl
│ │ ├── main.java.tpl
│ │ ├── main.javascript.tpl
│ │ ├── main.python.tpl
│ │ ├── robot-suite.tpl
│ │ └── robot.tpl
│ ├── golang_generator.go
│ ├── helper.go
│ ├── importer.go
│ ├── importer_native.go
│ ├── importer_native_test.go
│ ├── importer_test.go
│ ├── java_generator.go
│ ├── javascript_generator.go
│ ├── payload_generator.go
│ ├── payload_generator_test.go
│ ├── python_generator.go
│ ├── robot_generator.go
│ ├── robot_generator_test.go
│ └── testdata
│ │ ├── expected_go_body_request_code.txt
│ │ ├── expected_go_code.txt
│ │ ├── expected_go_cookie_request_code.txt
│ │ ├── expected_go_form_request_code.txt
│ │ ├── expected_java_code.txt
│ │ ├── expected_java_cookie_request_code.txt
│ │ ├── expected_java_form_request_code.txt
│ │ ├── expected_javascript_body_request_code.txt
│ │ ├── expected_javascript_code.txt
│ │ ├── expected_javascript_cookie_request_code.txt
│ │ ├── expected_javascript_form_request_code.txt
│ │ ├── expected_jmeter.jmx
│ │ ├── expected_python_code.txt
│ │ ├── expected_python_cookie_request_code.txt
│ │ ├── expected_python_form_request_code.txt
│ │ ├── expected_suite_from_postman.yaml
│ │ ├── expected_suite_from_sub_postman.yaml
│ │ ├── expected_testsuite.yaml
│ │ ├── native.json
│ │ ├── postman-sub.json
│ │ ├── postman.json
│ │ ├── simple.robot
│ │ ├── suite.robot
│ │ ├── test.proto
│ │ └── with-headers.robot
├── limit
│ ├── limiter.go
│ ├── limiter_long_test.go
│ └── limiter_test.go
├── logging
│ ├── log.go
│ └── log_test.go
├── mock
│ ├── in_memory.go
│ ├── in_memory_test.go
│ ├── metrics.go
│ ├── reader.go
│ ├── server.go
│ ├── testdata
│ │ └── api.yaml
│ └── types.go
├── oauth
│ ├── interceptor.go
│ └── interceptor_test.go
├── render
│ ├── data
│ │ └── templateUsage.yaml
│ ├── doc.go
│ ├── image.go
│ ├── image_test.go
│ ├── local.go
│ ├── local_test.go
│ ├── pdf.go
│ ├── pdf_test.go
│ ├── secret.go
│ ├── template.go
│ ├── template_test.go
│ ├── zip.go
│ └── zip_test.go
├── runner
│ ├── data
│ │ ├── html.html
│ │ └── report.md
│ ├── doc.go
│ ├── expr_function.go
│ ├── expr_function_test.go
│ ├── graphql.go
│ ├── graphql_test.go
│ ├── grpc.go
│ ├── grpc_test.go
│ ├── grpc_test
│ │ ├── server.go
│ │ ├── test.pb
│ │ ├── test.pb.go
│ │ ├── test.proto
│ │ ├── test_grpc.pb.go
│ │ └── testassets
│ │ │ ├── server.key
│ │ │ └── server.pem
│ ├── http.go
│ ├── http_reverse.go
│ ├── http_reverse_test.go
│ ├── http_test.go
│ ├── kubernetes
│ │ ├── client.go
│ │ ├── client_test.go
│ │ ├── doc.go
│ │ ├── verify.go
│ │ └── verify_test.go
│ ├── logger.go
│ ├── monitor
│ │ ├── dumy_monitor.go
│ │ ├── monitor.pb.go
│ │ ├── monitor.proto
│ │ └── monitor_grpc.pb.go
│ ├── reporter.go
│ ├── reporter_discard.go
│ ├── reporter_discard_test.go
│ ├── reporter_memory.go
│ ├── reporter_memory_test.go
│ ├── reporter_prometheus.go
│ ├── reporter_prometheus_test.go
│ ├── runner.go
│ ├── runner_factory.go
│ ├── runner_test.go
│ ├── testdata
│ │ ├── generic_response.json
│ │ ├── json-result.json
│ │ ├── report.html
│ │ └── swagger.json
│ ├── verify.go
│ ├── verify_test.go
│ ├── writer.go
│ ├── writer_github_pr_comment.go
│ ├── writer_github_pr_comment_test.go
│ ├── writer_grpc.go
│ ├── writer_grpc_test.go
│ ├── writer_html.go
│ ├── writer_html_test.go
│ ├── writer_http.go
│ ├── writer_http_test.go
│ ├── writer_json.go
│ ├── writer_json_test.go
│ ├── writer_markdown.go
│ ├── writer_markdown_test.go
│ ├── writer_pdf.go
│ ├── writer_pdf_test.go
│ ├── writer_std.go
│ ├── writer_std_test.go
│ └── writer_templates
│ │ ├── example.tpl
│ │ ├── server.go
│ │ ├── writer.pb.go
│ │ ├── writer.proto
│ │ └── writer_grpc.pb.go
├── secret
│ └── types.go
├── server
│ ├── constant.go
│ ├── convert.go
│ ├── convert_test.go
│ ├── data
│ │ └── headers.yaml
│ ├── fake.yaml
│ ├── fake_server.go
│ ├── gateway.go
│ ├── gateway_test.go
│ ├── http.go
│ ├── http_test.go
│ ├── proto.go
│ ├── proto_test.go
│ ├── remote_runner.go
│ ├── remote_server.go
│ ├── remote_server_test.go
│ ├── server.pb.go
│ ├── server.pb.gw.go
│ ├── server.proto
│ ├── server.swagger.json
│ ├── server_grpc.pb.go
│ ├── server_grpc_test.go
│ ├── store_ext_manager.go
│ ├── store_ext_manager_test.go
│ └── testdata
│ │ ├── postman.json
│ │ ├── simple.yaml
│ │ ├── simple_testcase.yaml
│ │ └── swagger.json
├── service
│ ├── runner.go
│ └── sbom.go
├── testing
│ ├── case.go
│ ├── case_test.go
│ ├── doc.go
│ ├── loader.go
│ ├── loader_file.go
│ ├── loader_file_test.go
│ ├── loader_non.go
│ ├── loader_non_test.go
│ ├── local
│ │ ├── local_secret_service.go
│ │ └── local_secret_service_test.go
│ ├── parser.go
│ ├── parser_test.go
│ ├── remote
│ │ ├── context.go
│ │ ├── context_test.go
│ │ ├── converter.go
│ │ ├── converter_test.go
│ │ ├── grpc_secret.go
│ │ ├── grpc_secret_test.go
│ │ ├── grpc_store.go
│ │ ├── grpc_store_test.go
│ │ ├── loader.pb.go
│ │ ├── loader.proto
│ │ └── loader_grpc.pb.go
│ ├── store.go
│ ├── store_test.go
│ └── testdata
│ │ ├── duplicated-names.yaml
│ │ ├── generic_body.json
│ │ ├── invalid-testcase.yaml
│ │ ├── stores.yaml
│ │ └── testcase.yaml
├── util
│ ├── base64.go
│ ├── default.go
│ ├── default_test.go
│ ├── error.go
│ ├── error_test.go
│ ├── expand.go
│ ├── expand_test.go
│ ├── grpc.go
│ ├── grpc_test.go
│ ├── home
│ │ ├── common.go
│ │ ├── common_test.go
│ │ ├── darwin.go
│ │ ├── doc.go
│ │ ├── linux.go
│ │ └── windows.go
│ ├── http.go
│ ├── http_test.go
│ ├── map.go
│ ├── map_test.go
│ ├── net.go
│ ├── path.go
│ ├── path_test.go
│ ├── rand.go
│ ├── rand_test.go
│ ├── slice.go
│ ├── slice_test.go
│ └── testdata
│ │ ├── fuzz
│ │ ├── FuzzEmptyThenDefault
│ │ │ └── a5d1a2517d90f203
│ │ └── FuzzZeroThenDefault
│ │ │ └── 26953e5f8daf8575
│ │ ├── report.html
│ │ ├── test.proto
│ │ └── test.zip
└── version
│ ├── constants.go
│ ├── constants_test.go
│ ├── mod.go
│ ├── mod_test.go
│ └── testdata
│ └── go.mod.txt
├── qodana.yaml
├── sample
├── constants.go
├── grpc-sample.yaml
├── kubernetes.yaml
├── testsuite-gitee.yaml
└── testsuite-gitlab.yaml
├── sonar-project.properties
└── tools
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── SECURITY.md
├── github-actions
└── setup-deps
│ └── action.yml
├── linter
├── golangci-lint
│ └── .golangci.yml
└── yamlint
│ └── .yamllint
├── make
├── common.mk
├── desktop.mk
├── docs.mk
├── env.mk
├── golang.mk
├── helm.mk
├── image.mk
├── lint.mk
├── proto.mk
├── run.mk
├── test.mk
├── tools.mk
└── ui.mk
└── src
├── golangci-lint
├── go.mod
├── go.sum
└── pin.go
└── yamllint
└── requirements.txt
/.dockerignore:
--------------------------------------------------------------------------------
1 | bin/
2 | extensions/
3 | dist/
4 | console/atest-desktop/
5 | console/atest-ui/node_modules/
6 | docs/site/node_modules/
7 | docs/site/public/
8 | docs/site/resources/
9 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: https://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 | charset = utf-8
11 |
12 | # 4 space indentation
13 | [*.{py,proto,go,js,ts,json,vue}]
14 | indent_style = space
15 | indent_size = 4
16 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.go text eol=lf
2 | *.vue text eol=lf
3 | *.js text eol=lf
4 | *.css text eol=lf
5 | *.html text eol=lf
6 | *.md text eol=lf
7 | *.yaml text eol=lf
8 | *.json text eol=lf
9 | *.yml text eol=lf
10 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # see also https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
2 | # pkg/runner/grpc.go @Ink-33
3 | # pkg/runner/grpc_test.go @Ink-33
4 | # pkg/runner/verify.go @Ink-33
5 |
6 | tools/ @yuluo-yx
7 | docs/site @yuluo-yx
8 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: "Crash bug"
4 | url: https://github.com/LinuxSuRen/api-testing/SECURITY.md
5 | about: "Please file any crash bug with api-testing-security@googlegroups.com."
6 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_reuqest.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement,triage
6 | assignees: ''
7 |
8 | ---
9 |
10 | *Description*:
11 | >Describe the desired behavior, what scenario it enables and how it
12 | would be used.
13 |
14 | [optional *Relevant Links*:]
15 | >Any extra documentation required to understand the issue.
16 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/non--crash-security--bug.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug
3 | about: Bugs
4 | title: ''
5 | labels: bug,triage
6 | assignees: ''
7 |
8 | ---
9 |
10 | *Description*:
11 | >What issue is being seen? Describe what should be happening instead of
12 | the bug, for example: api-testing should not crash, the expected value isn't
13 | returned, etc.
14 |
15 | *Repro steps*:
16 | > Include sample requests, environment, etc. All data and inputs
17 | required to reproduce the bug.
18 |
19 | >**Note**: If there are privacy concerns, sanitize the data prior to
20 | sharing.
21 |
22 | *Environment*:
23 | >Include the environment like api-testing version, os version and so on.
24 |
25 | *Logs*:
26 | >Include the access logs and the api-testing logs.
27 | >
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/other.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Other
3 | about: Questions, design proposals, tech debt, etc.
4 | title: ''
5 | labels: triage
6 | assignees: ''
7 |
8 | ---
9 |
10 | *Description*:
11 | >Describe the issue.
12 |
13 | [optional *Relevant Links*:]
14 | >Any extra documentation required to understand the issue.
15 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
6 |
7 | > We highly recommend you read [the contributor's documentation](https://github.com/LinuxSuRen/api-testing/blob/master/CONTRIBUTING.md) before starting the review process especially since this is your first contribution to this project.
8 | >
9 | > It was updated on 2024/5/27
10 |
11 | **What type of PR is this?**
12 |
21 |
22 | **What this PR does / why we need it**:
23 |
24 | **Which issue(s) this PR fixes**:
25 |
29 | Fixes #
30 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "gomod" # See documentation for possible values
9 | directory: "/" # Location of package manifests
10 | schedule:
11 | interval: "weekly"
12 | - package-ecosystem: "npm" # See documentation for possible values
13 | directory: "/console/atest-ui" # Location of package manifests
14 | schedule:
15 | interval: "weekly"
16 |
--------------------------------------------------------------------------------
/.github/markdown_lint_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "MD001": true,
3 | "MD002": false,
4 | "MD003": false,
5 | "MD004": false,
6 | "MD005": false,
7 | "MD006": false,
8 | "MD007": false,
9 | "MD008": false,
10 | "MD009": false,
11 | "MD010": false,
12 | "MD011": false,
13 | "MD012": false,
14 | "MD013": false,
15 | "MD014": false,
16 | "MD015": false,
17 | "MD016": false,
18 | "MD017": false,
19 | "MD018": false,
20 | "MD019": false,
21 | "MD020": false,
22 | "MD021": false,
23 | "MD022": false,
24 | "MD023": false,
25 | "MD024": false,
26 | "MD025": false,
27 | "MD026": false,
28 | "MD027": false,
29 | "MD028": false,
30 | "MD029": false,
31 | "MD030": false,
32 | "MD031": true,
33 | "MD032": false,
34 | "MD033": false,
35 | "MD034": false,
36 | "MD035": false,
37 | "MD036": false,
38 | "MD037": true,
39 | "MD038": true,
40 | "MD039": false,
41 | "MD040": false,
42 | "MD041": false,
43 | "MD042": false,
44 | "MD043": false,
45 | "MD044": false,
46 | "MD045": false,
47 | "MD046": false,
48 | "MD047": false,
49 | "MD048": false,
50 | "MD049": false,
51 | "MD050": false,
52 | "MD051": false
53 | }
54 |
--------------------------------------------------------------------------------
/.github/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | make fmt test
4 |
--------------------------------------------------------------------------------
/.github/testing/core.yaml:
--------------------------------------------------------------------------------
1 | #!api-testing
2 | # yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-schema.json
3 | name: atest
4 | api: |
5 | {{default "http://localhost:8080/api/v1" (env "SERVER")}}
6 | param:
7 | name: "{{randAlpha 6}}"
8 | items:
9 | - name: createSuite
10 | request:
11 | api: /suites
12 | method: POST
13 | body: |
14 | {"name": "{{.param.name}}"}
15 |
--------------------------------------------------------------------------------
/.github/testing/grpc.yaml:
--------------------------------------------------------------------------------
1 | #!api-testing
2 | # yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-schema.json
3 | # see also https://github.com/LinuxSuRen/api-testing
4 | name: grpc-sample
5 | api: 127.0.0.1:7070
6 | spec:
7 | kind: grpc
8 | rpc:
9 | import:
10 | - ./pkg/server
11 | - ./pkg/apispec/data/proto
12 | protofile: server.proto
13 | items:
14 | - name: GetVersion
15 | request:
16 | api: /server.Runner/GetVersion
17 | - name: FunctionsQuery
18 | request:
19 | api: /server.Runner/FunctionsQuery
20 | body: |
21 | {
22 | "name": "hello"
23 | }
24 | expect:
25 | body: |
26 | {
27 | "data": [
28 | {
29 | "key": "hello",
30 | "value": "func() string"
31 | }
32 | ]
33 | }
34 | - name: FunctionsQueryStream
35 | request:
36 | api: /server.Runner/FunctionsQueryStream
37 | body: |
38 | [
39 | {
40 | "name": "hello"
41 | },
42 | {
43 | "name": "title"
44 | }
45 | ]
46 | expect:
47 | verify:
48 | - "len(data) == 2"
49 |
--------------------------------------------------------------------------------
/.github/testing/grpc_ref.yaml:
--------------------------------------------------------------------------------
1 | #!api-testing
2 | # yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-schema.json
3 | # see also https://github.com/LinuxSuRen/api-testing
4 | name: grpc-sample-reflection
5 | api: 127.0.0.1:7070
6 | spec:
7 | kind: grpc
8 | rpc:
9 | import:
10 | - ./pkg/apispec/data/proto
11 | serverReflection: true
12 | items:
13 | - name: GetVersion
14 | request:
15 | api: /server.Runner/GetVersion
16 | - name: FunctionsQuery
17 | request:
18 | api: /server.Runner/FunctionsQuery
19 | body: |
20 | {
21 | "name": "hello"
22 | }
23 | expect:
24 | body: |
25 | {
26 | "data": [
27 | {
28 | "key": "hello",
29 | "value": "func() string"
30 | }
31 | ]
32 | }
33 | - name: FunctionsQueryStream
34 | request:
35 | api: /server.Runner/FunctionsQueryStream
36 | body: |
37 | [
38 | {
39 | "name": "hello"
40 | },
41 | {
42 | "name": "title"
43 | }
44 | ]
45 | expect:
46 | verify:
47 | - "len(data) == 2"
48 |
--------------------------------------------------------------------------------
/.github/workflows/issue-comment.yml:
--------------------------------------------------------------------------------
1 | name: Issue and PR comment commands
2 |
3 | permissions: {}
4 |
5 | on:
6 | issue_comment:
7 | types:
8 | - created
9 | - edited
10 |
11 | jobs:
12 | execute:
13 | runs-on: ubuntu-latest
14 | permissions:
15 | issues: write
16 | pull-requests: write
17 | steps:
18 | - uses: jpmcb/prow-github-actions@f4d01dd4b13f289014c23fe5a19878a2479cb35b # v1.1.3
19 | with:
20 | prow-commands: '/assign
21 | /unassign
22 | /area
23 | /kind
24 | /priority
25 | /remove
26 | /close
27 | /reopen
28 | /lock
29 | /milestone
30 | /hold
31 | /cc
32 | /uncc'
33 | github-token: "${{ secrets.GITHUB_TOKEN }}"
34 |
--------------------------------------------------------------------------------
/.github/workflows/license-check.yaml:
--------------------------------------------------------------------------------
1 | name: License check
2 |
3 | on:
4 | - pull_request
5 |
6 | jobs:
7 | Test:
8 | runs-on: ubuntu-22.04
9 | steps:
10 | - name: Check License Header
11 | uses: apache/skywalking-eyes@v0.4.0
12 |
--------------------------------------------------------------------------------
/.github/workflows/release-drafter.yml:
--------------------------------------------------------------------------------
1 | name: Release Drafter
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | UpdateReleaseDraft:
10 | runs-on: ubuntu-22.04
11 | steps:
12 | - uses: release-drafter/release-drafter@v5
13 | env:
14 | GITHUB_TOKEN: ${{ secrets.GH_PUBLISH_SECRETS }}
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | .idea/
3 | coverage.out
4 | *-coverage.out
5 | dist/
6 | .vscode/launch.json
7 | sample.yaml
8 | .DS_Store
9 | console/atest-ui/node_modules
10 | cmd/data/index.html
11 | cmd/data/index.js
12 | cmd/data/index.css
13 | helm/*.tgz
14 | helm/api-testing/*.tgz
15 | oryxBuildBinary
16 | /helm/api-testing/charts/
17 | console/atest-desktop/out
18 | console/atest-desktop/node_modules
19 | console/atest-desktop/atest
20 | console/atest-desktop/atest.exe
21 | console/atest-desktop/coverage
22 | atest-store-git
23 | .db
24 |
--------------------------------------------------------------------------------
/.gitpod.yml:
--------------------------------------------------------------------------------
1 |
2 | tasks:
3 | - init: make init-env install-precheck
4 | before: IMG_TOOL=docker GOPROXY= make build-image
5 | command: cd console/atest-ui/ && npm i
6 |
7 | ports:
8 | - port: 5713 # console interactive port
9 |
10 | vscode:
11 | extensions:
12 | - linuxsuren.api-testing
13 | - golang.go
14 | - Vue.volar
15 |
--------------------------------------------------------------------------------
/.goreleaser.yaml:
--------------------------------------------------------------------------------
1 | # This is an example .goreleaser.yml file with some sensible defaults.
2 | # Make sure to check the documentation at https://goreleaser.com
3 | before:
4 | hooks:
5 | # You may remove this if you don't use go modules.
6 | - go mod tidy
7 | - make embed-ui
8 | builds:
9 | - env:
10 | - CGO_ENABLED=0
11 | id: atest
12 | binary: atest
13 | goos:
14 | - linux
15 | - windows
16 | - darwin
17 | goarch:
18 | - amd64
19 | - arm64
20 | ldflags:
21 | - -w
22 | - -s
23 | - -X github.com/linuxsuren/api-testing/pkg/version.version={{.Version}}
24 | archives:
25 | - name_template: "{{ .Binary }}-{{ .Os }}-{{ .Arch }}"
26 | builds:
27 | - atest
28 | format_overrides:
29 | - goos: windows
30 | format: zip
31 | files:
32 | - README.md
33 | checksum:
34 | name_template: 'checksums.txt'
35 | snapshot:
36 | name_template: "{{ incpatch .Version }}-next"
37 | changelog:
38 | sort: asc
39 | filters:
40 | exclude:
41 | - '^docs:'
42 | - '^test:'
43 |
--------------------------------------------------------------------------------
/.licenserc.yaml:
--------------------------------------------------------------------------------
1 | header:
2 | license:
3 | spdx-id: Apache License
4 | copyright-owner: API Testing Authors
5 |
6 | paths-ignore:
7 | - 'dist'
8 | - 'licenses'
9 | - '**/*.md'
10 | - 'LICENSE'
11 | - 'NOTICE'
12 |
13 | comment: on-failure
14 |
--------------------------------------------------------------------------------
/.remarkrc:
--------------------------------------------------------------------------------
1 | listItemIndent=one
2 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "linuxsuren.api-testing",
4 | "redhat.vscode-yaml"
5 | ]
6 | }
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # All make targets should be implemented in tools/make/*.mk
2 | # ====================================================================================================
3 | # Supported Targets: (Run `make help` to see more API Testing information)
4 | # ====================================================================================================
5 |
6 | # An wrapper around `make` so that we can force on the,
7 | # --warn-undefined-variables flag. Sure, you can set
8 | # `MAKEFLAGS += --warn-undefined-variables` from inside of a Makefile,
9 | # but then it won't turn on until the second phase (recipe execution),
10 | # and won't actually be on during the initial phase (parsing).
11 | # See: https://www.gnu.org/software/make/manual/make.html#Reading-Makefiles
12 |
13 | # Have everything-else ("%") depend on _run (which uses
14 | # $(MAKECMDGOALS) to decide what to run), rather than having
15 | # everything else run $(MAKE) directly, since that'd end up running
16 | # multiple sub-Makes if you give multiple targets on the CLI.
17 |
18 | _run:
19 | @$(MAKE) --warn-undefined-variables -f tools/make/common.mk $(MAKECMDGOALS)
20 |
21 | .PHONY: _run
22 | $(if $(MAKECMDGOALS),$(MAKECMDGOALS): %: _run)
23 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | ## Reporting Security Issues
2 |
3 | The API Testing commnity takes a rigorous standpoint in annihilating the security issues in its software projects. API Testing is highly sensitive and forthcoming to issues pertaining to its features and functionality.
4 |
5 | ## REPORTING VULNERABILITY
6 |
7 | If you have apprehensions regarding API Testing's security or you discover vulnerability or potential threat, don’t hesitate to get in touch with the api-testing Security Team by dropping a mail at [api-testing-security@googlegroups.com](mailto:api-testing-security@googlegroups.com). In the mail, specify the description of the issue or potential threat. You are also urged to recommend the way to reproduce and replicate the issue. The API Testing community will get back to you after assessing and analysing the findings.
8 |
9 | PLEASE PAY ATTENTION to report the security issue on the security email before disclosing it on public domain.
10 |
11 | ## VULNERABILITY HANDLING
12 |
13 | An overview of the vulnerability handling process is:
14 |
15 | The reporter reports the vulnerability privately to API Testing community.
16 | The appropriate project's security team works privately with the reporter to resolve the vulnerability.
17 | A new release of the API Testing product concerned is made that includes the fix.
18 | The vulnerability is publically announced.
19 |
--------------------------------------------------------------------------------
/action.yml:
--------------------------------------------------------------------------------
1 | name: 'API testing with Kubernetes'
2 | description: 'API testing with Kubernetes'
3 | inputs:
4 | pattern:
5 | description: 'The pattern of the items'
6 | required: true
7 | default: 'testcase-*.yaml'
8 | kustomization:
9 | description: 'The kustomization file path'
10 | required: true
11 | waitNamespace:
12 | description: 'waitNamespace'
13 | required: true
14 | waitResource:
15 | description: 'waitResource'
16 | required: true
17 | runs:
18 | using: 'docker'
19 | image: 'Dockerfile'
20 | args:
21 | - ${{ inputs.pattern }}
22 | - ${{ inputs.kustomization }}
23 | - ${{ inputs.waitNamespace }}
24 | - ${{ inputs.waitResource }}
25 |
--------------------------------------------------------------------------------
/checklink_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignorePatterns": [
3 | {
4 | "pattern": "^(https?://)?(127.0.0.1|localhost|192.168.33.1|somehost\\.com)"
5 | }
6 | ],
7 | "aliveStatusCodes": [
8 | 200
9 | ]
10 | }
--------------------------------------------------------------------------------
/cmd/data/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/cmd/data/favicon.ico
--------------------------------------------------------------------------------
/cmd/data/font/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/cmd/data/font/.keep
--------------------------------------------------------------------------------
/cmd/data/image/warn.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/cmd/data/image/warn.jpg
--------------------------------------------------------------------------------
/cmd/data/index.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/cmd/data/index.css
--------------------------------------------------------------------------------
/cmd/data/index.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/cmd/data/index.html
--------------------------------------------------------------------------------
/cmd/data/index.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/cmd/data/index.js
--------------------------------------------------------------------------------
/cmd/jsonschema.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2025 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package cmd
18 |
19 | import (
20 | "encoding/json"
21 |
22 | "github.com/invopop/jsonschema"
23 | "github.com/linuxsuren/api-testing/pkg/testing"
24 | "github.com/spf13/cobra"
25 | )
26 |
27 | func createJSONSchemaCmd() (c *cobra.Command) {
28 | c = &cobra.Command{
29 | Use: "json",
30 | Short: "Print the JSON schema of the test suites struct",
31 | RunE: func(cmd *cobra.Command, args []string) (err error) {
32 | var data []byte
33 | schema := jsonschema.Reflect(&testing.TestSuite{})
34 | if data, err = json.MarshalIndent(schema, "", " "); err == nil {
35 | cmd.Println(string(data))
36 | }
37 | return
38 | },
39 | }
40 | return
41 | }
42 |
--------------------------------------------------------------------------------
/cmd/jsonschema_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2025 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package cmd_test
18 |
19 | import (
20 | "bytes"
21 | "strings"
22 | "testing"
23 |
24 | "github.com/linuxsuren/api-testing/cmd"
25 | "github.com/linuxsuren/api-testing/pkg/server"
26 | fakeruntime "github.com/linuxsuren/go-fake-runtime"
27 | "github.com/stretchr/testify/assert"
28 | )
29 |
30 | func TestJSONSchemaCmd(t *testing.T) {
31 | c := cmd.NewRootCmd(&fakeruntime.FakeExecer{ExpectOS: "linux"},
32 | server.NewFakeHTTPServer())
33 |
34 | buf := new(bytes.Buffer)
35 | c.SetOut(buf)
36 |
37 | c.SetArgs([]string{"json"})
38 | err := c.Execute()
39 | assert.Nil(t, err)
40 | assert.True(t, strings.Contains(buf.String(), "schema"))
41 | }
42 |
--------------------------------------------------------------------------------
/cmd/sample.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package cmd
18 |
19 | import (
20 | "github.com/linuxsuren/api-testing/sample"
21 | "github.com/spf13/cobra"
22 | )
23 |
24 | func createSampleCmd() (c *cobra.Command) {
25 | c = &cobra.Command{
26 | Use: "sample",
27 | Short: "Generate a sample test case YAML file",
28 | RunE: func(cmd *cobra.Command, args []string) (err error) {
29 | cmd.Println(sample.TestSuiteGitLab)
30 | return
31 | },
32 | }
33 | return
34 | }
35 |
--------------------------------------------------------------------------------
/cmd/sample_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package cmd_test
18 |
19 | import (
20 | "bytes"
21 | "testing"
22 |
23 | "github.com/linuxsuren/api-testing/cmd"
24 | "github.com/linuxsuren/api-testing/pkg/server"
25 | "github.com/linuxsuren/api-testing/sample"
26 | fakeruntime "github.com/linuxsuren/go-fake-runtime"
27 | "github.com/stretchr/testify/assert"
28 | )
29 |
30 | func TestSampleCmd(t *testing.T) {
31 | c := cmd.NewRootCmd(&fakeruntime.FakeExecer{ExpectOS: "linux"},
32 | server.NewFakeHTTPServer())
33 |
34 | buf := new(bytes.Buffer)
35 | c.SetOut(buf)
36 |
37 | c.SetArgs([]string{"sample"})
38 | err := c.Execute()
39 | assert.Nil(t, err)
40 | assert.Equal(t, sample.TestSuiteGitLab+"\n", buf.String())
41 | }
42 |
--------------------------------------------------------------------------------
/cmd/testdata/invalid-api.yaml:
--------------------------------------------------------------------------------
1 | name: Simple
2 | api: "{{.api}"
3 | items:
4 | - request:
5 | api: /bar
6 | name: bar
7 |
--------------------------------------------------------------------------------
/cmd/testdata/invalid-schema.yaml:
--------------------------------------------------------------------------------
1 | name: Simple
2 | api: "{{.api}"
3 | item:
4 | - requests:
5 | api: /bar
6 | method: POSt
7 |
--------------------------------------------------------------------------------
/cmd/testdata/postman.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "_postman_id": "0da1f6bf-fdbb-46a5-ac46-873564e2259c",
4 | "name": "New Collection",
5 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
6 | "_exporter_id": "6795120",
7 | "_collection_link": "https://www.postman.com/ks-devops/workspace/kubesphere-devops/collection/6795120-0da1f6bf-fdbb-46a5-ac46-873564e2259c?action=share&creator=6795120&source=collection_link"
8 | },
9 | "item": [
10 | {
11 | "name": "New Request",
12 | "protocolProfileBehavior": {
13 | "disableBodyPruning": true
14 | },
15 | "request": {
16 | "method": "GET",
17 | "header": [
18 | {
19 | "key": "key",
20 | "value": "value",
21 | "description": "description",
22 | "type": "text"
23 | }
24 | ],
25 | "body": {
26 | "mode": "raw",
27 | "raw": "{}"
28 | },
29 | "url": {
30 | "raw": "http://localhost?key=value"
31 | }
32 | }
33 | }
34 | ]
35 | }
--------------------------------------------------------------------------------
/cmd/testdata/simple-suite.yaml:
--------------------------------------------------------------------------------
1 | name: Simple
2 | api: http://foo
3 | items:
4 | - request:
5 | api: /bar
6 | name: bar
7 |
--------------------------------------------------------------------------------
/cmd/testdata/stores.yaml:
--------------------------------------------------------------------------------
1 | stores:
2 | - name: git
3 | kind:
4 | name: atest-store-git
5 | enabled: true
6 | url: xxx
7 | readonly: false
8 | disabled: false
9 | plugins:
10 | - name: atest-store-git
11 | url: unix:///tmp/atest-store-git.sock
12 | enabled: true
13 |
--------------------------------------------------------------------------------
/console/atest-desktop/README.md:
--------------------------------------------------------------------------------
1 | ```shell
2 | npx electron-forge import
3 | ```
4 |
5 | ```shell
6 | npm config set registry https://registry.npmmirror.com
7 | ```
8 |
9 | ## Package
10 |
11 | ```shell
12 | npm run package -- --platform=darwin
13 | npm run package -- --platform=win32
14 | npm run package -- --platform=linux
15 | ```
16 |
17 | ## For Linux
18 |
19 | You need to install tools if you want to package Windows on Linux:
20 | ```shell
21 | apt install wine64 zip -y
22 | ```
23 |
24 | ## For Windows
25 |
26 | ```powershell
27 | dotnet tool install --global wix
28 | ```
29 |
30 | ## Publish
31 |
32 | export GITHUB_TOKEN=your-token
33 |
34 | ```shell
35 | npm run publish -- --platform=darwin
36 | npm run publish -- --platform=linux
37 | ```
38 |
--------------------------------------------------------------------------------
/console/atest-desktop/api-testing.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/console/atest-desktop/api-testing.icns
--------------------------------------------------------------------------------
/console/atest-desktop/api-testing.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/console/atest-desktop/api-testing.ico
--------------------------------------------------------------------------------
/console/atest-desktop/api-testing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/console/atest-desktop/api-testing.png
--------------------------------------------------------------------------------
/console/atest-desktop/api.test.js:
--------------------------------------------------------------------------------
1 | const { getPort, getHealthzUrl, getHomePage } = require('./api');
2 |
3 | describe('getPort function', () => {
4 | test('should return the default port number 7788', () => {
5 | const port = getPort();
6 | expect(port).toBe(7788);
7 | });
8 | });
9 |
10 | describe('getHealthzUrl function', () => {
11 | test('should return the default healthz url', () => {
12 | const url = getHealthzUrl();
13 | expect(url).toBe('http://localhost:7788/healthz');
14 | });
15 | });
16 |
17 | describe('getHomePage function', () => {
18 | test('should return the default home page url', () => {
19 | const url = getHomePage();
20 | expect(url).toBe('http://localhost:7788');
21 | });
22 | })
23 |
--------------------------------------------------------------------------------
/console/atest-ui/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | /* eslint-env node */
2 | require('@rushstack/eslint-patch/modern-module-resolution')
3 |
4 | module.exports = {
5 | root: true,
6 | 'extends': [
7 | 'plugin:vue/vue3-essential',
8 | 'eslint:recommended',
9 | '@vue/eslint-config-typescript',
10 | '@vue/eslint-config-prettier/skip-formatting'
11 | ],
12 | overrides: [
13 | {
14 | files: [
15 | 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}'
16 | ],
17 | 'extends': [
18 | 'plugin:cypress/recommended'
19 | ]
20 | }
21 | ],
22 | parserOptions: {
23 | ecmaVersion: 'latest'
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/console/atest-ui/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | .DS_Store
12 | dist
13 | dist-ssr
14 | coverage
15 | *.local
16 |
17 | /cypress/videos/
18 | /cypress/screenshots/
19 |
20 | # Editor directories and files
21 | .vscode/*
22 | !.vscode/extensions.json
23 | .idea
24 | *.suo
25 | *.ntvs*
26 | *.njsproj
27 | *.sln
28 | *.sw?
29 |
--------------------------------------------------------------------------------
/console/atest-ui/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/prettierrc",
3 | "semi": false,
4 | "tabWidth": 2,
5 | "singleQuote": true,
6 | "printWidth": 100,
7 | "trailingComma": "none"
8 | }
--------------------------------------------------------------------------------
/console/atest-ui/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
3 | }
4 |
--------------------------------------------------------------------------------
/console/atest-ui/cypress.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'cypress'
2 |
3 | export default defineConfig({
4 | e2e: {
5 | specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
6 | baseUrl: 'http://localhost:4173'
7 | }
8 | })
9 |
--------------------------------------------------------------------------------
/console/atest-ui/cypress/e2e/gRPC.cy.ts:
--------------------------------------------------------------------------------
1 | import { createTestCase, createTestSuite, selectTestCase, selectTestCaseTab, userID_Alpha } from './util'
2 |
3 | describe('gRPC', () => {
4 | const suiteName = userID_Alpha()
5 | const store = "local"
6 | const sampleAPIAddress = "http://foo"
7 |
8 | it('Create Suite', () => {
9 | cy.visit('/')
10 | cy.get('.introjs-skipbutton').click()
11 | cy.get('[test-id="testing-menu"]').click()
12 |
13 | createTestSuite(store, 'gRPC', suiteName, sampleAPIAddress)
14 | })
15 |
16 | const caseName = userID_Alpha()
17 | const caseAPI = "/api/v2"
18 | it('New Test Case', () => {
19 | cy.visit('/')
20 | cy.get('.introjs-skipbutton').click()
21 | createTestCase(suiteName, caseName, caseAPI)
22 | })
23 |
24 | it('Update Test Case', () => {
25 | cy.visit('/')
26 | cy.get('.introjs-skipbutton').click()
27 | selectTestCase(caseName)
28 | selectTestCaseTab('tab-second')
29 | })
30 | })
31 |
--------------------------------------------------------------------------------
/console/atest-ui/cypress/e2e/http.cy.ts:
--------------------------------------------------------------------------------
1 | // https://on.cypress.io/api
2 | // https://docs.cypress.io/api/table-of-contents
3 | import { createTestCase, createTestSuite, selectTestCase, selectTestSuite, userID_Alpha } from './util'
4 |
5 | describe('Suite Manage', () => {
6 | const suiteName = userID_Alpha()
7 | const store = "local"
8 | const sampleAPIAddress = "http://foo"
9 |
10 | it('Create Suite', () => {
11 | cy.visit('/')
12 | cy.get('.introjs-skipbutton').click()
13 | cy.get('[test-id="testing-menu"]').click()
14 |
15 | cy.contains('span', 'Tool Box')
16 | createTestSuite(store, 'HTTP', suiteName, sampleAPIAddress)
17 | })
18 |
19 | const caseName = userID_Alpha()
20 | const caseMethod = "GET"
21 | const caseAPI = "/api/v2"
22 | it('New Test Case', () => {
23 | cy.visit('/')
24 | cy.get('.introjs-skipbutton').click()
25 | createTestCase(suiteName, caseName, caseAPI)
26 | })
27 |
28 | it('Find Test Case', () => {
29 | cy.visit('/')
30 | cy.get('.introjs-skipbutton').click()
31 | selectTestCase(caseName)
32 |
33 | // verify the value
34 | cy.get('[test-id="case-editor-method"] input').should('have.value', caseMethod)
35 | })
36 |
37 | it('Delete Suite', () => {
38 | cy.visit('/')
39 | cy.get('.introjs-skipbutton').click()
40 | selectTestSuite(suiteName)
41 |
42 | cy.get('[test-id="suite-editor-api"]').should('have.value', sampleAPIAddress)
43 | cy.get('[test-id="suite-del-but"]').click()
44 | })
45 | })
46 |
--------------------------------------------------------------------------------
/console/atest-ui/cypress/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@vue/tsconfig/tsconfig.dom.json",
3 | "include": ["./**/*", "../support/**/*"],
4 | "compilerOptions": {
5 | "isolatedModules": false,
6 | "target": "es5",
7 | "lib": ["es5", "dom"],
8 | "types": ["cypress"]
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/console/atest-ui/cypress/fixtures/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Using fixtures to represent data",
3 | "email": "hello@cypress.io",
4 | "body": "Fixtures are a great way to mock data for responses to routes"
5 | }
6 |
--------------------------------------------------------------------------------
/console/atest-ui/cypress/support/e2e.ts:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | // Import commands.js using ES2015 syntax:
17 | import './commands'
18 |
19 | // Alternatively you can use CommonJS syntax:
20 | // require('./commands')
21 |
--------------------------------------------------------------------------------
/console/atest-ui/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/console/atest-ui/gen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ./node_modules/.bin/grpc_tools_node_protoc --plugin=protoc-gen-ts=. --ts_out=../../pkg/server -I ../../pkg/server ../../pkg/server/server.proto
--------------------------------------------------------------------------------
/console/atest-ui/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | API Testing
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/console/atest-ui/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/console/atest-ui/public/favicon.ico
--------------------------------------------------------------------------------
/console/atest-ui/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/console/atest-ui/src/assets/main.css:
--------------------------------------------------------------------------------
1 | @import './base.css';
2 |
3 | #app {
4 | margin: 0 auto;
5 | padding: 1rem;
6 | padding-top: 40px;
7 | height: 100vh;
8 | font-weight: normal;
9 | }
10 |
11 | .top-menu {
12 | position: absolute;
13 | top: 10px;
14 | right: 20px;
15 | }
16 |
17 | a,
18 | .green {
19 | text-decoration: none;
20 | color: hsla(160, 100%, 37%, 1);
21 | transition: 0.4s;
22 | }
23 |
24 | @media (hover: hover) {
25 | a:hover {
26 | background-color: hsla(160, 100%, 37%, 0.2);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/console/atest-ui/src/components/Button.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/console/atest-ui/src/components/EditButton.vue:
--------------------------------------------------------------------------------
1 |
31 |
32 |
33 |
34 |
43 |
44 | {{ value }}
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/console/atest-ui/src/theme.ts:
--------------------------------------------------------------------------------
1 | const lightTheme: { [k: string]: string } = {
2 | '--color-background': 'var(--vt-c-white)',
3 | '--color-background-soft': 'var(--vt-c-white-soft)',
4 | '--color-background-mute': 'var(--vt-c-white-mute)',
5 | '--color-border': 'var(--vt-c-divider-light-2)',
6 | '--color-border-hover': 'var(--vt-c-divider-light-1)',
7 | '--color-heading': 'var(--vt-c-text-light-1)',
8 | '--color-text': 'var(--vt-c-text-light-1)'
9 | }
10 |
11 | const darkTheme: { [k: string]: string } = {
12 | '--color-background': 'var(--vt-c-black)',
13 | '--color-background-soft': 'var(--vt-c-black-soft)',
14 | '--color-background-mute': 'var(--vt-c-black-mute)',
15 | '--color-border': 'var(--vt-c-divider-dark-2)',
16 | '--color-border-hover': 'var(--vt-c-divider-dark-1)',
17 | '--color-heading': 'var(--vt-c-text-dark-1)',
18 | '--color-text': 'var(--vt-c-text-dark-2)'
19 | }
20 |
21 |
22 | export default function setAsDarkTheme(darkMode: boolean) {
23 | const theme = darkMode ? darkTheme : lightTheme
24 | Object.keys(theme).forEach((key) => {
25 | document.documentElement.style.setProperty(key, theme[key])
26 | })
27 | }
28 |
--------------------------------------------------------------------------------
/console/atest-ui/src/views/APIInput.vue:
--------------------------------------------------------------------------------
1 |
20 |
21 |
22 |
30 |
31 | {{ item.request.method }}
32 | {{ item.request.api }}
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/console/atest-ui/src/views/__test__/store.spec.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | import { SupportedExtension, SupportedExtensions } from "../store";
18 |
19 | describe("SupportedExtensions", () => {
20 | test('length check', () => {
21 | const extensions = SupportedExtensions()
22 | expect(extensions.length).toBe(10)
23 | })
24 |
25 | for (const extension of SupportedExtensions()) {
26 | test(`${extension.name} check`, () => {
27 | expect(SupportedExtension(extension.name)).not.toBeUndefined()
28 | })
29 | }
30 | })
31 |
--------------------------------------------------------------------------------
/console/atest-ui/src/views/magicKeys.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | import { watch } from 'vue'
18 | import { useMagicKeys } from '@vueuse/core'
19 |
20 | function Keys(func: (() => void) | ((k: string) => void), keys: string[]) {
21 | const magicKeys = useMagicKeys()
22 | keys.forEach(k => {
23 | watch(magicKeys[k], (v) => {
24 | if (v) func(k)
25 | })
26 | })
27 | }
28 |
29 | export const Magic = {
30 | Keys
31 | }
32 |
--------------------------------------------------------------------------------
/console/atest-ui/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@vue/tsconfig/tsconfig.dom.json",
3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "vue.config.ts"],
4 | "exclude": ["src/**/__tests__/*"],
5 | "compilerOptions": {
6 | "composite": true,
7 | "baseUrl": ".",
8 | "paths": {
9 | "@/*": ["./src/*"]
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/console/atest-ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "compilerOptions":{
4 | "module":"commonjs",
5 | "allowJs": true,
6 | "target": "es6",
7 | "esModuleInterop": true
8 | },
9 | "references": [
10 | {
11 | "path": "./tsconfig.node.json"
12 | },
13 | {
14 | "path": "./tsconfig.app.json"
15 | },
16 | {
17 | "path": "./tsconfig.vitest.json"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/console/atest-ui/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@tsconfig/node18/tsconfig.json",
3 | "include": [
4 | "vite.config.*",
5 | "vitest.config.*",
6 | "cypress.config.*",
7 | "nightwatch.conf.*",
8 | "playwright.config.*"
9 | ],
10 | "compilerOptions": {
11 | "composite": true,
12 | "module": "ESNext",
13 | "types": ["node"]
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/console/atest-ui/tsconfig.vitest.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.app.json",
3 | "exclude": [],
4 | "compilerOptions": {
5 | "composite": true,
6 | "lib": [],
7 | "types": ["node", "jsdom"]
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/console/atest-ui/ui.go:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import (
4 | _ "embed"
5 | "encoding/json"
6 | )
7 |
8 | //go:embed package.json
9 | var packageJSON []byte
10 |
11 | type JSON struct {
12 | Dependencies map[string]string `json:"dependencies"`
13 | DevDependencies map[string]string `json:"devDependencies"`
14 | }
15 |
16 | func GetPackageJSON() (data JSON) {
17 | data = JSON{}
18 | _ = json.Unmarshal(packageJSON, &data)
19 | return
20 | }
21 |
--------------------------------------------------------------------------------
/console/atest-ui/vitest.config.ts:
--------------------------------------------------------------------------------
1 | import { fileURLToPath } from 'node:url'
2 | import { mergeConfig } from 'vite'
3 | import { configDefaults, defineConfig } from 'vitest/config'
4 | import viteConfig from './vite.config'
5 |
6 | export default mergeConfig(
7 | viteConfig,
8 | defineConfig({
9 | test: {
10 | globals:true,
11 | // environment: 'jsdom',
12 | environment: 'happy-dom',
13 | exclude: [...configDefaults.exclude, 'e2e/*'],
14 | root: fileURLToPath(new URL('./', import.meta.url)),
15 | transformMode: {
16 | web: [/\.[jt]sx$/]
17 | }
18 | }
19 | })
20 | )
21 |
--------------------------------------------------------------------------------
/docs/constants.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package docs
17 |
18 | import (
19 | _ "embed"
20 | "fmt"
21 | yamlconv "github.com/ghodss/yaml"
22 | "github.com/xeipuuv/gojsonschema"
23 | )
24 |
25 | //go:embed api-testing-schema.json
26 | var Schema string
27 |
28 | //go:embed api-testing-mock-schema.json
29 | var MockSchema string
30 |
31 | func Validate(data []byte, schema string) (err error) {
32 | // convert YAML to JSON
33 | var jsonData []byte
34 | if jsonData, err = yamlconv.YAMLToJSON(data); err == nil {
35 | schemaLoader := gojsonschema.NewStringLoader(schema)
36 | documentLoader := gojsonschema.NewBytesLoader(jsonData)
37 |
38 | var result *gojsonschema.Result
39 | if result, err = gojsonschema.Validate(schemaLoader, documentLoader); err == nil {
40 | if !result.Valid() {
41 | err = fmt.Errorf("%v", result.Errors())
42 | }
43 | }
44 | }
45 | return
46 | }
47 |
--------------------------------------------------------------------------------
/docs/manifests/argocd/simple.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Application
3 | metadata:
4 | name: api-testing
5 | namespace: argocd
6 | spec:
7 | destination:
8 | namespace: default
9 | server: https://kubernetes.default.svc
10 | project: default
11 | source:
12 | path: sample/kubernetes/default
13 | repoURL: https://github.com/LinuxSuRen/api-testing
14 | targetRevision: master
15 | # see also https://argo-cd.readthedocs.io/en/stable/user-guide/kustomize/
16 | kustomize:
17 | images:
18 | - ghcr.io/linuxsuren/api-testing=ghcr.io/linuxsuren/api-testing:master
19 | syncPolicy:
20 | syncOptions:
21 | - CreateNamespace=true
22 | - RespectIgnoreDifferences=true
23 | automated:
24 | prune: true
25 | selfHeal: true
26 |
--------------------------------------------------------------------------------
/docs/manifests/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.1'
2 | services:
3 | testing:
4 | image: "linuxsuren.docker.scarf.sh/linuxsuren/api-testing:master"
5 | ports:
6 | - 8080:8080
7 | etcd:
8 | image: "bitnami/etcd:3.5.10"
9 | expose:
10 | - "2379"
11 | environment:
12 | ALLOW_NONE_AUTHENTICATION: "yes"
13 |
--------------------------------------------------------------------------------
/docs/manifests/kubernetes/default/kustomization.yaml:
--------------------------------------------------------------------------------
1 | resources:
2 | - manifest.yaml
3 | apiVersion: kustomize.config.k8s.io/v1beta1
4 | kind: Kustomization
5 | images:
6 | - name: ghcr.io/linuxsuren/api-testing:master
7 | newName: ghcr.io/linuxsuren/api-testing
8 | newTag: master
9 |
--------------------------------------------------------------------------------
/docs/manifests/kubernetes/docker.io/kustomization.yaml:
--------------------------------------------------------------------------------
1 | bases:
2 | - ../default
3 |
4 | apiVersion: kustomize.config.k8s.io/v1beta1
5 | kind: Kustomization
6 | images:
7 | - name: ghcr.io/linuxsuren/api-testing:master
8 | newName: linuxsuren/api-testing
9 | newTag: master
10 |
--------------------------------------------------------------------------------
/docs/manifests/podman.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Pod
3 | metadata:
4 | labels:
5 | app: api-testing
6 | name: api-testing
7 | spec:
8 | containers:
9 | - image: ghcr.io/linuxsuren/api-testing:master
10 | name: web
11 | ports:
12 | - containerPort: 8080
13 | hostPort: 8080
14 | protocol: TCP
15 | volumeMounts:
16 | - mountPath: /root/.config/atest/
17 | name: config
18 | tty: true
19 | workingDir: /
20 | - image: ghcr.io/linuxsuren/api-testing:master
21 | name: extension-orm
22 | command: [atest-store-orm]
23 | tty: true
24 | workingDir: /
25 | - image: ghcr.io/linuxsuren/api-testing:master
26 | name: extension-s3
27 | command: [atest-store-s3]
28 | tty: true
29 | workingDir: /
30 | - image: ghcr.io/linuxsuren/api-testing:master
31 | name: extension-git
32 | command: [atest-store-git]
33 | tty: true
34 | workingDir: /
35 | volumes:
36 | - name: config
37 | hostPath:
38 | path: /root/.config/atest/
39 | type: DirectoryOrCreate
40 |
--------------------------------------------------------------------------------
/docs/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "docs",
3 | "lockfileVersion": 3,
4 | "requires": true,
5 | "packages": {}
6 | }
7 |
--------------------------------------------------------------------------------
/docs/site/.dockerignore:
--------------------------------------------------------------------------------
1 | console/atest-ui/node_modules
2 | console/atest-ui/dist
3 | .git/
4 | bin/
5 | dist/
6 | .vscode/
7 |
--------------------------------------------------------------------------------
/docs/site/.gitignore:
--------------------------------------------------------------------------------
1 | /public
2 | resources/
3 | node_modules/
4 | package-lock.json
5 | .hugo_build.lock
--------------------------------------------------------------------------------
/docs/site/.nvmrc:
--------------------------------------------------------------------------------
1 | lts/*
2 |
--------------------------------------------------------------------------------
/docs/site/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM klakegg/hugo:ext-alpine@sha256:536dd4805d0493ee13bf1f3df3852ed1f26d1625983507c8c56242fc029b44c7
2 |
3 | RUN apk add git && \
4 | git config --global --add safe.directory /src
5 |
--------------------------------------------------------------------------------
/docs/site/assets/atest-vscode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/docs/site/assets/atest-vscode.png
--------------------------------------------------------------------------------
/docs/site/assets/icons/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/docs/site/assets/icons/logo.png
--------------------------------------------------------------------------------
/docs/site/assets/scss/_variables_project.scss:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Add styles or override variables from the theme here.
4 |
5 | */
6 |
7 | $primary: #1e71ec;
8 | $secondary: #ffffff;
9 | $dark: #4a9ff5;
10 |
--------------------------------------------------------------------------------
/docs/site/config.yaml:
--------------------------------------------------------------------------------
1 | # THIS IS A TEST CONFIG ONLY!
2 | # FOR THE CONFIGURATION OF YOUR SITE USE hugo.yaml.
3 | #
4 | # As of Docsy 0.7.0, Hugo 0.110.0 or later must be used.
5 | #
6 | # The sole purpose of this config file is to detect Hugo-module builds that use
7 | # an older version of Hugo.
8 | #
9 | # DO NOT add any config parameters to this file. You can safely delete this file
10 | # if your project is using the required Hugo version.
11 |
12 | module:
13 | hugoVersion:
14 | extended: true
15 | min: 0.110.0
16 |
--------------------------------------------------------------------------------
/docs/site/content/en/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: API Testing
3 | ---
4 |
5 | {{< blocks/cover title="Welcome to API Testing!" image_anchor="top" height="full" >}}
6 | }}">
7 | GET STARTED
8 |
9 | }}">
10 | CONTRIBUTING
11 |
12 | YAML based API testing tool. interface debug and test tools.
13 | {{< blocks/link-down color="white" >}}
14 | Let's improve the code quality together.
15 | {{< /blocks/cover >}}
16 |
--------------------------------------------------------------------------------
/docs/site/content/en/about/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: About API Testing
3 | linkTitle: About
4 | ---
5 |
6 | {{% blocks/cover title="About API Testing" height="auto" %}}
7 |
8 | API Testing is an open source project for interface debug and test tools.
9 |
10 | Read on to find out more, or visit our [documentation](/latest/) to get started!
11 | {{% /blocks/cover %}}
12 |
13 | {{% blocks/section color="black" %}}
14 |
15 | ## Objectives
16 |
17 | ---
18 |
19 | // TBD.
20 |
21 | {{% /blocks/section %}}
22 |
--------------------------------------------------------------------------------
/docs/site/content/en/contributions/_index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "Get Involved"
3 | description = "This section includes contents related to Contributions"
4 | linktitle = "Get Involved"
5 |
6 | [[cascade]]
7 | type = "docs"
8 | +++
--------------------------------------------------------------------------------
/docs/site/content/en/contributions/design/Todo.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Todo Add Design"
3 | weight: -100
4 | description: Todo.
5 | ---
6 |
7 | // TBD
8 |
--------------------------------------------------------------------------------
/docs/site/content/en/contributions/design/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Design"
3 | weight: -100
4 | description: This section includes Designs of API Testing.
5 | ---
6 |
--------------------------------------------------------------------------------
/docs/site/content/en/contributions/roadmap.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Roadmap"
3 | weight: -1
4 | description: "This section records the roadmap of API Testing."
5 | ---
6 |
7 | // TBD
8 |
--------------------------------------------------------------------------------
/docs/site/content/en/latest/_index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "Welcome to API Testing"
3 | linktitle = "Documentation"
4 | description = "API Testing Documents"
5 |
6 | [[cascade]]
7 | type = "docs"
8 | +++
9 |
10 | {{% alert title="Note" color="primary" %}}
11 |
12 | This project is under **active** development. Many features are not complete. We would love for you to [Get Involved](/contributions)!
13 |
14 | {{% /alert %}}
15 |
16 | // TBD.
17 |
18 | ## Ready to get started?
19 |
--------------------------------------------------------------------------------
/docs/site/content/en/latest/api/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "API"
3 | description: This section includes APIs of API Testing.
4 | weight: 80
5 | ---
6 |
--------------------------------------------------------------------------------
/docs/site/content/en/latest/api/extension_types.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "API Reference"
3 | +++
4 |
5 | // TBD.
6 |
--------------------------------------------------------------------------------
/docs/site/content/en/latest/install/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Installation"
3 | description: This section includes installation related contents of API Testing.
4 | weight: 70
5 | ---
6 |
--------------------------------------------------------------------------------
/docs/site/content/en/latest/install/install-locally.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "Install with Locally"
3 | weight = -99
4 | +++
5 |
6 | // TBD
7 |
8 | Install API Testing.
9 |
--------------------------------------------------------------------------------
/docs/site/content/en/latest/releases/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Releases"
3 | weight: 90
4 | description: This section includes Releases of API Testing.
5 | ---
6 |
--------------------------------------------------------------------------------
/docs/site/content/en/latest/releases/v0.1.0.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "v0.1.0"
3 | publishdate: 2022-05-16
4 | ---
5 |
6 | Date: 2024 06 01
7 |
8 | // TBD
9 |
--------------------------------------------------------------------------------
/docs/site/content/en/latest/tasks/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Tasks"
3 | weight: 2
4 | description: Learn API Testing hands-on through tasks
5 | ---
6 |
--------------------------------------------------------------------------------
/docs/site/content/en/latest/tasks/mock-server.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "Mock server get started"
3 | weight = -99
4 | +++
5 |
6 | ## Get started
7 |
8 | You can start a mock server of [container registry](https://distribution.github.io/distribution/) with below command:
9 |
10 | ```shell
11 | atest mock --prefix / mock/image-registry.yaml
12 | ```
13 |
14 | then, you can pull images from it:
15 |
16 | ```shell
17 | docker pull localhost:6060/repo/name:tag
18 | ```
19 |
--------------------------------------------------------------------------------
/docs/site/content/en/latest/tasks/prometheus.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "Pushing the test results into Prometheus"
3 | +++
4 |
5 | You can use the following command to do it:
6 |
7 | ```shell
8 | atest run --report prometheus --report-file http://localhost:9091 \
9 | -p sample/testsuite-gitee.yaml --duration 30m --qps 1
10 | ```
11 |
12 | It will push the test results data into Prometheus [PushGateway](https://github.com/prometheus/pushgateway).
13 | Then Prometheus could get the metrics from it.
14 |
15 | Skip the following instructions if you are familiar with Prometheus:
16 |
17 | ```shell
18 | docker run \
19 | -p 9090:9090 \
20 | -v /etc/timezone:/etc/timezone:ro \
21 | -v /etc/localtime:/etc/localtime:ro \
22 | -v /root/prometheus.yml:/etc/prometheus/prometheus.yml \
23 | prom/prometheus
24 |
25 | docker run -p 9091:9091 \
26 | -v /etc/timezone:/etc/timezone:ro \
27 | -v /etc/localtime:/etc/localtime:ro \
28 | prom/pushgateway
29 |
30 | docker run -p 3000:3000 docker.io/grafana/grafana
31 | ```
32 |
--------------------------------------------------------------------------------
/docs/site/content/en/latest/tasks/quickstart.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Quickstart"
3 | weight: 1
4 | description: Get started with API Testing in a few simple steps.
5 | ---
6 |
7 | // TBD
8 |
--------------------------------------------------------------------------------
/docs/site/content/en/news/_index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "News"
3 | linktitle = "News"
4 | description = "API Testing News"
5 |
6 | [[cascade]]
7 | type = "docs"
8 | +++
9 |
10 | This is the **News** section. It is organized into three categories: blogs, presentations and releases.
11 |
12 | The files in these directories will be listed in reverse chronological order.
13 |
--------------------------------------------------------------------------------
/docs/site/content/en/news/blogs/_index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "Blogs"
3 | description = "API Testing Blogs"
4 | linktitle = "Blogs"
5 |
6 | [[cascade]]
7 | type = "docs"
8 | +++
9 |
--------------------------------------------------------------------------------
/docs/site/content/en/news/presentations/_index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "Presentations"
3 | description = "API Testing Presentations and activities."
4 | linktitle = "Presentations"
5 |
6 | [[cascade]]
7 | type = "docs"
8 | +++
9 |
--------------------------------------------------------------------------------
/docs/site/content/en/news/releases/_index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "Posting Notice"
3 | description = "API Testing posting notice"
4 | linktitle = "Posting"
5 |
6 | [[cascade]]
7 | type = "docs"
8 | +++
9 |
10 | This document provides details on API Testing releases.
11 | API Testing follows the Semantic Version Control [v2.0.0 specification](https://semver.org/) for release version control.
12 | Since API Testing is a new project, minor versions are the only versions defined.
13 | Additional release details, such as patch versions, will be created by API Testing maintainers at a future date.
14 |
15 | ## Stable releases {#stable-releases}
16 |
17 |
18 |
19 | ## Release management {#release-management}}
20 |
21 |
22 |
23 | ## Release schedule} {#release-schedule}
24 |
--------------------------------------------------------------------------------
/docs/site/content/en/search.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Search Results
3 | layout: search
4 | ---
5 |
--------------------------------------------------------------------------------
/docs/site/content/zh/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: API Testing
3 | ---
4 |
5 | {{< blocks/cover title="欢迎访问 API Testing!" image_anchor="top" height="full" >}}
6 | }}">
7 | 开始使用
8 |
9 | }}">
10 | 参与贡献
11 |
12 | 开源接口调试 & 测试工具
13 |
14 | {{< blocks/link-down color="white" >}}
15 | 让我们一起提高代码质量吧!
16 | {{< /blocks/cover >}}
17 |
--------------------------------------------------------------------------------
/docs/site/content/zh/about/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 关于 API Testing.
3 | linkTitle: 关于
4 | ---
5 |
6 | {{% blocks/cover title="About API Testing" height="auto" %}}
7 |
8 | API Testing (atest)是一个接口调试和测试工具的开源项目。
9 |
10 | 请继续阅读以了解更多信息,或访问我们的 [文档](/latest/) 开始使用!
11 |
12 | {{% /blocks/cover %}}
13 |
14 | {{% blocks/section color="black" %}}
15 |
16 | ## Objectives
17 |
18 | ---
19 |
20 | // TBD.
21 |
22 | {{% /blocks/section %}}
23 |
--------------------------------------------------------------------------------
/docs/site/content/zh/contributions/_index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "参与其中"
3 | description = "本节包含与贡献相关的内容"
4 | linktitle = "参与其中"
5 |
6 | [[cascade]]
7 | type = "docs"
8 | +++
--------------------------------------------------------------------------------
/docs/site/content/zh/contributions/design/Goals.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "目标"
3 | weight: -1
4 | description: "API Testing goals."
5 | ---
6 |
7 | // TBD
8 |
--------------------------------------------------------------------------------
/docs/site/content/zh/contributions/design/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "设计"
3 | weight: -100
4 | description: 这部分包含 API Testing 的设计细节.
5 | ---
6 |
--------------------------------------------------------------------------------
/docs/site/content/zh/contributions/design/security-policy.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "安全策略"
3 | weight: -2
4 | description: "API Testing 安全策略。"
5 | ---
6 |
7 | // TBD
8 |
--------------------------------------------------------------------------------
/docs/site/content/zh/contributions/roadmap.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "发展规划"
3 | weight: -1
4 | description: "API Testing roadmap."
5 | ---
6 |
7 | // TBD
8 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/api/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "API"
3 | description: 本节内容包含 API Testing 的 API。
4 | weight: 3
5 | ---
6 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/api/extension_types.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "API 引用"
3 | +++
4 |
5 | // TBD.
6 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/install/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 安装
3 | description: 本节包含关于安装 API Testing 的内容。
4 | weight: 1
5 | ---
6 |
7 | atest 支持如下的安装使用场景:
8 |
9 | * 命令行
10 | * 持续集成流水线
11 | * 桌面应用
12 | * Web 页面
13 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/install/install-helm.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "Helm"
3 | description = "通过 Helm 安装的方式使用 API Testing"
4 | weight = -98
5 | +++
6 |
7 | You could install `api-testing` via Helm chart:
8 |
9 | ```shell
10 | helm install atest oci://docker.io/linuxsuren/api-testing \
11 | --version v0.0.2-helm \
12 | --set service.type=NodePort
13 | ```
14 |
15 | or upgrade it:
16 |
17 | ```shell
18 | helm upgrade atest oci://docker.io/surenpi/api-testing \
19 | --version v0.0.2-helm \
20 | --set image.tag=master \
21 | --set replicaCount=3
22 | ```
23 |
24 | ## SkyWalking
25 |
26 | ```shell
27 | helm install atest oci://docker.io/linuxsuren/api-testing \
28 | --version v0.0.2-helm \
29 | --set image.tag=master \
30 | --set service.type=NodePort \
31 | --set service.nodePort=30154 \
32 | --set skywalking.endpoint.http=http://skywalking-skywalking-helm-oap.skywalking.svc:12800 \
33 | --set skywalking.endpoint.grpc=skywalking-skywalking-helm-oap.skywalking.svc:11800
34 | ```
35 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/install/install-local.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "本地安装"
3 | weight = -99
4 | +++
5 |
6 | ## 手动下载
7 |
8 | 您可以通过下面的链接下载最新版本的安装包:
9 |
10 | [](https://github.com/LinuxSuRen/api-testing/releases/latest)
11 |
12 | | Package | GitHub | Mirror from DaoCloud |
13 | |---|---|---|
14 | | `atest-desktop.msi` | [link](https://github.com/LinuxSuRen/api-testing/releases/latest/download/atest-desktop.msi) | [link](https://files.m.daocloud.io/github.com/LinuxSuRen/api-testing/releases/latest/download/atest-desktop.msi) |
15 | | `atest-linux-amd64.tar.gz` | [link](https://github.com/LinuxSuRen/api-testing/releases/latest/download/atest-linux-amd64.tar.gz) | [link](https://files.m.daocloud.io/github.com/LinuxSuRen/api-testing/releases/latest/download/atest-linux-amd64.tar.gz) |
16 | | `atest-darwin-amd64.tar.gz` | [link](https://github.com/LinuxSuRen/api-testing/releases/latest/download/atest-darwin-amd64.tar.gz) | [link](https://files.m.daocloud.io/github.com/LinuxSuRen/api-testing/releases/latest/download/atest-darwin-amd64.tar.gz) |
17 |
18 | ## 通过工具下载
19 |
20 | [hd](https://github.com/LinuxSuRen/http-downloader) 是一个支持多线程下载的工具:
21 |
22 | ```shell
23 | hd i atest
24 | ```
25 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/tasks/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "任务"
3 | weight: 2
4 | description: 通过任务学习 API Testing 实践。
5 | ---
6 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/tasks/code-generator.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "代码生成"
3 | weight = 104
4 | +++
5 |
6 | `atest` 支持把测试用例生成多种开发语言的代码:
7 |
8 | * curl
9 | * Java
10 | * Golang
11 | * Python
12 | * JavaScript
13 | * [Robot Framework](https://robotframework.org/)
14 |
15 | > 该功能需要在 Web UI 上使用。
16 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/tasks/job.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "任务"
3 | weight = 101
4 | +++
5 |
6 | 在特定情况下,执行接口测试用例前需要执行相应的任务,例如:数据初始化、等待服务就绪等等。 `atest` 的任务功能,就是为了满足这类场景而设计的。
7 |
8 | > 任务的执行引擎为 [expr](https://expr.medv.io),如果当前页面给出的示例无法满足你的需求,可以查阅相关的官方文档。
9 |
10 | ## 等待接口响应码为 200
11 |
12 | 以下的例子会每隔一秒请求一次指定的接口,并检查响应码(Status Code)是否为 200,如果不是的话,则最多会重试 3 次:
13 |
14 | ```yaml
15 | name: demo
16 | api: http://localhost
17 | items:
18 | - name: login
19 | before:
20 | items:
21 | - httpReady("http://localhost/health", 3)
22 | request:
23 | api: /demo
24 | ```
25 |
26 | 如果希望检查响应体的话,则可以用下面的表达式:
27 |
28 | ```
29 | httpReady("http://localhost:17001/actuator/health", 3, 'components.discoveryComposite.components.eureka.details.applications["AUTH"] == 1')
30 | ```
31 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/tasks/mock/object.yaml:
--------------------------------------------------------------------------------
1 | #!api-testing-mock
2 | # yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-mock-schema.json
3 | objects:
4 | - name: projects
5 | initCount: 3
6 | sample: |
7 | {
8 | "name": "atest",
9 | "color": "{{ randEnum "blue" "read" "pink" }}"
10 | }
11 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/tasks/quickstart.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "快速入门"
3 | weight: 1
4 | description: 只需几个简单的步骤即可开始使用 API Testing。
5 | ---
6 |
7 | 本指南将帮助您通过几个简单的步骤开始使用 API Testing。
8 |
9 | ## 执行部分测试用例
10 |
11 | 下面的命令会执行名称中包含 `sbom` 的所有测试用例:
12 |
13 | ```shell
14 | atest run -p test-suite.yaml --case-filter sbom
15 | ```
16 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/tasks/secure.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "关于安全"
3 | weight = 8
4 | +++
5 |
6 | 通常在不使用 TLS 证书认证时,gRPC 客户端与服务端之间进行的是明文通信,信息易被第三方监听或篡改。所以大多数情况下均推荐使用 SSL/TLS 保护 gRPC 服务。目前`atest`已实现服务端 TLS,双向 TLS(mTLS) 需等待后续实现。
7 |
8 | 默认情况下`atest`不使用任何安全策略,等价于`spec.secure.insecure = true`。启用 TLS 仅需 yaml 中添加以下内容:
9 |
10 | ```yaml
11 | spec:
12 | secure:
13 | cert: server.pem
14 | serverName: atest
15 | ```
16 |
17 | ## 字段说明
18 |
19 | `secure`共有以下五个字段:
20 |
21 | | 字段名 | 类型 | 是否可选 |
22 | | ---------- | ------ | -------- |
23 | | cert | string | x |
24 | | ca | string | √ |
25 | | key | string | √ |
26 | | serverName | string | x |
27 | | insecure | bool | √ |
28 |
29 | `cert`为客户端需要配置的证书的文件路径,格式为`PEM`。
30 |
31 | `serverName`为 TLS 所需的服务名,通常为签发证书时使用的 x509 SAN。
32 |
33 | `ca`为 CA 证书的路径,`key`为与`cert`对应的私钥,这两项填写后代表启用 mTLS。(mTLS 尚未实现)
34 |
35 | 当`insecure`为`false`时,`cert`和`serverName`为必填项。
36 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/tasks/template.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "用例模板"
3 | weight = 100
4 | +++
5 |
6 | `atest` 采用 [sprig](https://masterminds.github.io/sprig/) 作为测试用例的模板引擎。通过模板函数可以生成很多随机数据:
7 |
8 | ## 手机号
9 |
10 | 下面的代码可以生成 `182` 开头的手机号:
11 |
12 | ```
13 | 182{{shuffle "09876543"}}
14 | ```
15 |
16 | ## 带权重的随机枚举
17 |
18 | 下面的代码以 80% 的概率返回 `open`,以 20% 的概率返回 `closed`:
19 |
20 | ```
21 | {{randWeightEnum (weightObject 4 "open") (weightObject 1 "closed")}}
22 | ```
23 |
24 | ## 时间
25 |
26 | 下面的代码可以生成当前时间,并制定时间格式:
27 |
28 | ```
29 | {{ now.Format "2006-01-02T15:04:05Z07:00" }}
30 | ```
31 |
32 | 如果想要获取其他时间,则可以参考如下写法:
33 |
34 | ```gotemplate
35 | {{(now | date_modify "2h") | date "2006-01-02T15:04:05"}}
36 | ```
37 |
38 | ## 环境变量
39 |
40 | 下面的代码可以获取环境变量 `SHELL` 的值,在需要使用一个全局变量的时候,可以使用这个模板函数:
41 |
42 | ```
43 | {{ env "SHELL" }}
44 | ```
45 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/tasks/testsuite.yaml:
--------------------------------------------------------------------------------
1 | #!api-testing
2 | # yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-schema.json
3 | name: SpringBoot
4 | api: |
5 | {{default "http://localhost:8080" (env "SERVER")}}
6 | items:
7 | - name: health
8 | request:
9 | api: /health
10 |
--------------------------------------------------------------------------------
/docs/site/content/zh/latest/tasks/verify.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "测试用例验证"
3 | weight = 102
4 | +++
5 |
6 | `atest` 采用 https://expr.medv.io 对 HTTP 请求响应的验证,比如:返回的数据列表长度验证、具体值的验证等等。下面给出一些例子:
7 |
8 | > 需要注意的是,`data` 指的是 HTTP Response Body(响应体)的 JSON 对象。
9 |
10 | ## 数组长度判断
11 |
12 | ```yaml
13 | - name: projectKinds
14 | request:
15 | api: /api/resources/projectKinds
16 | expect:
17 | verify:
18 | - len(data.data) == 6
19 | ```
20 |
21 | ## 数组值检查
22 |
23 | ### 检查数组中是否有元素的字段包含特定值
24 |
25 | 示例数据:
26 |
27 | ```json
28 | {
29 | "data": [{
30 | "key": "Content-Type"
31 | }]
32 | }
33 | ```
34 |
35 | 校验配置:
36 |
37 | ```yaml
38 | - name: popularHeaders
39 | request:
40 | api: /popularHeaders
41 | expect:
42 | verify:
43 | - any(data.data, {.key == "Content-Type"})
44 | ```
45 |
46 | ### 检查数组中是否有元素的字段只包含特定值
47 |
48 | 校验配置:
49 |
50 | ```yaml
51 | - name: popularHeaders
52 | request:
53 | api: /popularHeaders
54 | expect:
55 | verify:
56 | - all(data.data, {.key == "Content-Type" or .key == "Target"})
57 | ```
58 |
59 | [更多用法](https://expr-lang.org/docs/language-definition#any).
60 |
61 | ## 字符串判断
62 |
63 | ```yaml
64 | - name: metrics
65 | request:
66 | api: |
67 | {{.param.server}}/metrics
68 | expect:
69 | verify:
70 | - indexOf(data, "atest_execution_count") != -1
71 | ```
72 |
73 | [更多用法](https://expr-lang.org/docs/language-definition#indexOf).
74 |
--------------------------------------------------------------------------------
/docs/site/content/zh/news/_index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "新闻"
3 | linktitle = "新闻"
4 | description = "有关 API Testing 的新闻"
5 |
6 | [[cascade]]
7 | type = "docs"
8 | +++
9 |
10 | 这是**新闻**部分。它分为三个类别:博客、演讲和发布。
11 |
12 | 这些目录中的文件将按时间倒序列出。
13 |
--------------------------------------------------------------------------------
/docs/site/content/zh/news/blogs/_index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "博客"
3 | description = "关于 API Testing 的博客"
4 | linktitle = "博客"
5 |
6 | [[cascade]]
7 | type = "docs"
8 | +++
9 |
--------------------------------------------------------------------------------
/docs/site/content/zh/news/presentations/_index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "演讲"
3 | description = "有关 API Testing 的演讲、讲座和活动"
4 | linktitle = "演讲"
5 |
6 | [[cascade]]
7 | type = "docs"
8 | +++
9 |
--------------------------------------------------------------------------------
/docs/site/content/zh/news/releases/_index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "发布公告"
3 | description = "API Testing 发布公告"
4 | linktitle = "发布"
5 |
6 | [[cascade]]
7 | type = "docs"
8 | +++
9 |
10 | 本文档提供了 API Testing 版本的详细信息。
11 | API Testing 遵循语义版本控制 [v2.0.0 规范](https://semver.org/)进行发布版本控制。
12 | 由于 API Testing 是一个新项目,因此次要版本是唯一被定义的版本。
13 | API Testing 维护人员在未来的某个日期将建立额外的发布详细信息,例如补丁版本。
14 |
15 | ## 稳定版本 {#stable-releases}
16 |
17 |
18 |
19 | ## 发布管理 {#release-management}
20 |
21 |
22 |
23 | ## 发布时间表 {#release-schedule}
24 |
25 |
26 |
--------------------------------------------------------------------------------
/docs/site/content/zh/releases/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "版本发布"
3 | weight: 90
4 | description: 本节内容包含 API Testing 的版本概述。
5 | ---
6 |
--------------------------------------------------------------------------------
/docs/site/content/zh/releases/release-note-v0.0.12.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "v0.0.12"
3 | +++
4 |
5 | `atest` 版本发布 v0.0.12
6 |
7 | `atest` 是一款用 Golang 编写的、基于 YAML 格式的开源接口测试工具,可以方便地在本地、服务端、持续集成等场景中使用。
8 | 我们希望提供一个简单、强大、高质量的测试工具,方便测试、研发人员快速、低成本地借助接口测试为产品研发质量保驾护航。
9 |
10 | 通过以下命令启动 HTTP 代理服务器后,给您的浏览器配置该代理,打开业务系统就会自动录制:
11 |
12 | ```shell
13 | docker run -p 1234:8080 -v /var/tmp:/var/tmp \
14 | ghcr.io/linuxsuren/api-testing atest-collector \
15 | --filter-path /api \
16 | -o /var/tmp/sample.yaml
17 | # --filter-path /api 会过滤所有以 /api 为前缀的 HTTP 请求
18 | # 关闭服务后,您可以在 /var/tmp/sample 这个目录中找到生成的测试用文件
19 | ```
20 |
21 | ## 更新重点
22 |
23 | * 支持通过基于 HTTP 代理服务生成测试用例
24 | * 支持根据 Swagger 数据生成接口测试覆盖率
25 | * 增加 HTML、Markdown 等格式的测试报告
26 | * 代码重构,包括:包结构、原文件名整理,逻辑抽象为接口以及不同实现
27 | * 支持打印所有支持的模板函数
28 | * 优化 Kubernetes 的部署清单文件
29 | * 修复已知缺陷
30 |
31 | 本次版本发布,包含了以下三位 contributor 的努力:
32 |
33 | * [@LinuxSuRen](https://github.com/LinuxSuRen)
34 | * [@wongearl](https://github.com/wongearl)
35 | * [@yJunS](https://github.com/yJunS)
36 |
37 | ## 相关数据
38 |
39 | 下面是 `atest` 截止到 v0.0.12 的部分数据:
40 |
41 | * watch 3
42 | * fork 9
43 | * star 33
44 | * contributor 4
45 | * 二进制文件下载量 561
46 | * 代码行数 7.6k
47 | * 单元测试覆盖率 94%
48 |
49 | 想了解完整信息的话,请访问 https://github.com/LinuxSuRen/api-testing/releases/tag/v0.0.12
50 |
--------------------------------------------------------------------------------
/docs/site/content/zh/releases/release-note-v0.0.14.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "v0.0.14"
3 | +++
4 |
5 | `atest` 版本发布 `v0.0.14`
6 |
7 | `atest` 是一款用 Golang 编写的、开源的接口测试工具。
8 |
9 | 你可以在容器中启动:
10 |
11 | ```shell
12 | docker run --network host \
13 | linuxsuren/api-testing:v0.0.14
14 | ```
15 |
16 | 或者,直接[下载二进制文件](https://github.com/LinuxSuRen/api-testing/releases/tag/v0.0.14)后启动:
17 |
18 | ```shell
19 | atest server --local-storage /var/www/sample
20 | ```
21 |
22 | ## 主要的新功能
23 |
24 | * 增加了对 `tRPC` 和 `gRPC` 协议的(命令行与 Web 界面)支持
25 | * 新增了 Helm Chart 的安装方式
26 | * 支持通过按钮切换暗模式
27 | * 支持启动启动插件
28 | * 支持在 Web 界面中参数化执行
29 | * 支持生成 `curl` 与 `Golang` 代码
30 | * 支持从 Postman 中导入测试用例
31 | * 可观测方便,增加了对 Apache SkyWalking 和 Prometheus 的支持
32 | * 一些 Web 界面操作的优化(例如:多语言、测试结果缓存、自动保存)
33 |
34 | 本次版本发布,包含了以下 5 位 contributor 的努力:
35 |
36 | * [@Ink-33](https://github.com/Ink-33)
37 | * [@LinuxSuRen](https://github.com/LinuxSuRen)
38 | * [@hellojukay](https://github.com/hellojukay)
39 | * [@kuv2707](https://github.com/kuv2707)
40 | * [@yuluo-yx](https://github.com/yuluo-yx)
41 |
42 | ## 相关数据
43 |
44 | 下面是 `atest` 截止到 `v0.0.14` 的部分数据:
45 |
46 | * watch 7
47 | * fork 23
48 | * star 104
49 | * contributor 12
50 | * 二进制文件下载量 1.1k
51 | * 代码行数 45k
52 | * 单元测试覆盖率 88%
53 |
54 | 想了解完整信息的话,请访问 https://github.com/LinuxSuRen/api-testing/releases/tag/v0.0.14
55 |
--------------------------------------------------------------------------------
/docs/site/content/zh/releases/release-note-v0.0.15.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "v0.0.15"
3 | +++
4 |
5 | `atest` 发布 `v0.0.15`
6 |
7 | `atest` 是致力于帮助开发者持续保持高质量 API 的开源接口工具。
8 |
9 | 你可以在命令行终端或者容器中启动:
10 |
11 | ```shell
12 | docker run -p 8080:8080 linuxsuren/api-testing:v0.0.15
13 | ```
14 |
15 | ## 亮点
16 |
17 | 在本次版本发布之前,成功地为以下开源项目实现了 API 的 E2E 测试:
18 |
19 | * [halo-dev/halo](https://github.com/halo-dev/halo/pull/4892),一款 Java 实现的开源建站工具
20 | * [dromara/hertzbeat](https://github.com/dromara/hertzbeat/pull/1387),一款监控系统
21 |
22 | 非常期待 `atest` 可以帮助更多的项目持续提升、保持 API 稳定性。
23 |
24 | ## 主要的新功能
25 |
26 | * 支持复用 Cookies(简化了基于 Cookie 做会话认证) (#301) @LinuxSuRen
27 | * 增加了基于 Docker 的应用性能监控 (#300) @LinuxSuRen
28 | * 支持以 Comment 的方式发送测试报告到 GitHub PR (#298) @LinuxSuRen
29 | * UI 布局重构 (#297) @LinuxSuRen
30 | * 增加对 OAuth 认证的支持(包括 Device 模式) (#290) @LinuxSuRen
31 | * 支持设置 gRPC 的元数据 (#282) @LinuxSuRen
32 | * 增加了新的后端存储: Mongodb (#278) @LinuxSuRen
33 |
34 | ## 致谢
35 |
36 | 本次版本发布,包含了以下 2 位 contributor 的努力:
37 |
38 | * [@im-jinxinwang](https://github.com/im-jinxinwang)
39 | * [@LinuxSuRen](https://github.com/LinuxSuRen)
40 |
41 | ## 相关数据
42 |
43 | 下面是 `atest` 截止到 `v0.0.15` 的部分数据:
44 |
45 | * watch 7
46 | * fork 23
47 | * star 123 (+19)
48 | * contributor 13 (+1)
49 | * 二进制文件下载量 1.3k (+0.2k)
50 | * 部分镜像 2.2k
51 | * 单元测试覆盖率 82% (-6%)
52 |
53 | 想了解完整信息的话,请访问 https://github.com/LinuxSuRen/api-testing/releases/tag/v0.0.15
54 |
--------------------------------------------------------------------------------
/docs/site/content/zh/search.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 搜索结果
3 | layout: search
4 | ---
5 |
--------------------------------------------------------------------------------
/docs/site/data/adopters.yaml:
--------------------------------------------------------------------------------
1 | adopters:
2 | # todo
3 |
--------------------------------------------------------------------------------
/docs/site/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: "3.3"
2 |
3 | services:
4 |
5 | site:
6 | image: docsy/docsy-example
7 | build:
8 | context: .
9 | command: server
10 | ports:
11 | - "1313:1313"
12 | volumes:
13 | - .:/src
14 |
--------------------------------------------------------------------------------
/docs/site/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/google/docsy-example
2 |
3 | go 1.22.1
4 |
5 | require (
6 | github.com/FortAwesome/Font-Awesome v0.0.0-20230327165841-0698449d50f2 // indirect
7 | github.com/google/docsy v0.7.1 // indirect
8 | github.com/twbs/bootstrap v5.2.3+incompatible // indirect
9 | )
10 |
--------------------------------------------------------------------------------
/docs/site/layouts/404.html:
--------------------------------------------------------------------------------
1 | {{ define "main" -}}
2 |
3 |
Not found
4 |
Oops! This page doesn't exist. Try going back to the home page.
5 |
6 | {{- end }}
7 |
--------------------------------------------------------------------------------
/docs/site/static/favicons/favicons.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/docs/site/static/favicons/favicons.ico
--------------------------------------------------------------------------------
/docs/site/static/favicons/site.webmanifest:
--------------------------------------------------------------------------------
1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
--------------------------------------------------------------------------------
/docs/site/static/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/docs/site/static/img/logo.png
--------------------------------------------------------------------------------
/docs/site/static/logos/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/docs/site/static/logos/logo.png
--------------------------------------------------------------------------------
/e2e/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ghcr.io/linuxsuren/api-testing:master
2 |
3 | WORKDIR /workspace
4 | COPY e2e/* .
5 | COPY helm/api-testing api-testing
6 | RUN apk add curl openssh-client bash openssl
7 | RUN curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
8 | RUN chmod 700 get_helm.sh
9 | RUN ./get_helm.sh
10 | RUN chmod +x entrypoint.sh
11 | RUN chmod +x k8s.sh
12 |
13 | CMD [ "/workspace/entrypoint.sh" ]
14 |
--------------------------------------------------------------------------------
/e2e/README.md:
--------------------------------------------------------------------------------
1 | You can build the image locally in the repository root directory:
2 |
3 | If you are a Linux/MacOS user, you can use the following command:
4 | ```shell
5 | REGISTRY=ghcr.io TAG=master make image
6 | ```
7 |
8 | If you are a Windows user, you can use the following command:
9 | ```powershell
10 | Set-Content -Path "env:REGISTRY" -Value "ghcr.io"
11 | Set-Content -Path "env:TAG" -Value "master"
12 | make image
13 | ```
14 |
--------------------------------------------------------------------------------
/e2e/code-generator/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG LAN_ENV=docker.io/library/golang:1.21
2 |
3 | FROM ghcr.io/linuxsuren/api-testing:master AS atest
4 | FROM ghcr.io/linuxsuren/hd:v0.0.42 as downloader
5 | RUN hd install jq
6 | FROM $LAN_ENV
7 |
8 | WORKDIR /workspace
9 | COPY . .
10 | COPY --from=downloader /usr/local/bin/jq /usr/local/bin/jq
11 | COPY --from=atest /usr/local/bin/atest /usr/local/bin/atest
12 |
13 | CMD [ "/workspace/entrypoint.sh" ]
14 |
--------------------------------------------------------------------------------
/e2e/code-generator/JavaScript.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | export sourcefile=$1
5 | # exit if no source file is specified
6 | if [ -z "$sourcefile" ]
7 | then
8 | echo "no source file is specified"
9 | exit 1
10 | fi
11 |
12 | mv ${sourcefile} main.js
13 | node main.js
14 |
--------------------------------------------------------------------------------
/e2e/code-generator/compose.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | golang:
3 | build:
4 | context: .
5 | dockerfile: Dockerfile
6 | args:
7 | - LAN_ENV=docker.io/library/golang:1.21
8 | command:
9 | - /workspace/entrypoint.sh
10 | - golang
11 | java:
12 | build:
13 | context: .
14 | dockerfile: Dockerfile
15 | args:
16 | - LAN_ENV=docker.io/library/openjdk:23
17 | command:
18 | - /workspace/entrypoint.sh
19 | - java
20 | python:
21 | build:
22 | context: .
23 | dockerfile: Dockerfile
24 | args:
25 | - LAN_ENV=docker.io/library/python:3.8
26 | command:
27 | - /workspace/entrypoint.sh
28 | - python
29 | robot-framework:
30 | build:
31 | context: .
32 | dockerfile: Dockerfile
33 | args:
34 | - LAN_ENV=docker.io/library/python:3.8
35 | command:
36 | - /workspace/entrypoint.sh
37 | - robot-framework
38 | javascript:
39 | build:
40 | context: .
41 | dockerfile: Dockerfile
42 | args:
43 | - LAN_ENV=docker.io/library/node:22
44 | command:
45 | - /workspace/entrypoint.sh
46 | - JavaScript
47 | curl:
48 | build:
49 | context: .
50 | dockerfile: Dockerfile
51 | args:
52 | - LAN_ENV=docker.io/library/openjdk:23
53 | command:
54 | - /workspace/entrypoint.sh
55 | - curl
56 |
--------------------------------------------------------------------------------
/e2e/code-generator/curl.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | export sourcefile=$1
5 | # exit if no source file is specified
6 | if [ -z "$sourcefile" ]
7 | then
8 | echo "no source file is specified"
9 | exit 1
10 | fi
11 |
12 | mv ${sourcefile} main.sh
13 | sh main.sh
14 |
--------------------------------------------------------------------------------
/e2e/code-generator/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | export lang=$1
5 | # exit if no language is specified
6 | if [ -z "$lang" ]
7 | then
8 | echo "no language is specified"
9 | exit 1
10 | fi
11 |
12 | mkdir -p /root/.config/atest
13 | mkdir -p /var/data
14 |
15 | nohup atest server --local-storage '/workspace/test-suites/*.yaml'&
16 | sleep 1
17 |
18 | # test_cases=("postRequest" "requestWithHeader" "requestWithoutHeader")
19 | test_cases=("requestWithHeader" "requestWithoutHeader")
20 |
21 | for test_case in "${test_cases[@]}"
22 | do
23 | curl http://localhost:8080/api/v1/codeGenerators/generate -X POST \
24 | -d '{"TestSuite": "test", "TestCase": "'"${test_case}"'", "Generator": "'"$lang"'"}' > code.json
25 |
26 | cat code.json | jq .message -r | sed 's/\\n/\n/g' | sed 's/\\t/\t/g' | sed 's/\\\"/"/g' > code.txt
27 | cat code.txt
28 |
29 | sh /workspace/${lang}.sh code.txt
30 | done
31 |
32 | exit 0
33 |
--------------------------------------------------------------------------------
/e2e/code-generator/golang.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | export sourcefile=$1
5 | # exit if no source file is specified
6 | if [ -z "$sourcefile" ]
7 | then
8 | echo "no source file is specified"
9 | exit 1
10 | fi
11 |
12 | mv ${sourcefile} main.go
13 | go run main.go
14 |
--------------------------------------------------------------------------------
/e2e/code-generator/java.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | export sourcefile=$1
5 | # exit if no source file is specified
6 | if [ -z "$sourcefile" ]
7 | then
8 | echo "no source file is specified"
9 | exit 1
10 | fi
11 |
12 | mv ${sourcefile} Main.java
13 | java Main.java
14 |
--------------------------------------------------------------------------------
/e2e/code-generator/python.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | export sourcefile=$1
5 | # exit if no source file is specified
6 | if [ -z "$sourcefile" ]
7 | then
8 | echo "no source file is specified"
9 | exit 1
10 | fi
11 |
12 | mv ${sourcefile} main.py
13 | pip install requests
14 | python main.py
15 |
--------------------------------------------------------------------------------
/e2e/code-generator/robot-framework.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | export sourcefile=$1
5 | # exit if no source file is specified
6 | if [ -z "$sourcefile" ]
7 | then
8 | echo "no source file is specified"
9 | exit 1
10 | fi
11 |
12 | mv ${sourcefile} test.robot
13 | pip install robotframework robotframework-requests
14 | robot test.robot
15 |
--------------------------------------------------------------------------------
/e2e/code-generator/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | docker compose version
5 |
6 | targets=(golang java python javascript curl robot-framework)
7 | for target in "${targets[@]}"
8 | do
9 | docker compose down
10 | docker compose up --build $target --exit-code-from $target
11 | done
12 |
--------------------------------------------------------------------------------
/e2e/code-generator/test-suites/test-suite.yaml:
--------------------------------------------------------------------------------
1 | #!api-testing
2 | # yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-schema.json
3 | name: test
4 | api: http://localhost:8080/api/v1
5 | param:
6 | suiteName: test
7 | caseName: test
8 | items:
9 | - name: postRequest
10 | request:
11 | api: /suites
12 | method: POST
13 | body: |
14 | {
15 | "name": "hello",
16 | "api": "http://localhost:8080/api/v1"
17 | }
18 | - name: requestWithHeader
19 | request:
20 | api: /suites
21 | header:
22 | auth: fake
23 | - name: requestWithoutHeader
24 | request:
25 | api: /suites
26 |
--------------------------------------------------------------------------------
/e2e/compose-external.yaml:
--------------------------------------------------------------------------------
1 | version: '3.1'
2 | services:
3 | testing:
4 | image: ghcr.io/linuxsuren/api-testing:master
5 | command: ["atest", "run", "-p=/workspace/e2e/test-suite.yaml"]
6 | pull_policy: never
7 | environment:
8 | SERVER: http://server:8080
9 | volumes:
10 | - type: volume
11 | source: cache
12 | target: /workspace/e2e
13 | depends_on:
14 | server:
15 | condition: service_healthy
16 | links:
17 | - server
18 | server:
19 | image: ghcr.io/devops-ws/learn-springboot:master
20 | healthcheck:
21 | test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/8080"]
22 | interval: 3s
23 | timeout: 60s
24 | retries: 10
25 | start_period: 3s
26 | volumes:
27 | - type: volume
28 | source: cache
29 | target: /workspace/e2e
30 |
31 | volumes:
32 | cache:
33 |
--------------------------------------------------------------------------------
/e2e/git.yaml:
--------------------------------------------------------------------------------
1 | #!api-testing
2 | # yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-schema.json
3 | # https://docs.gitlab.com/ee/api/api_resources.html
4 | name: atest
5 | api: |
6 | {{default "http://localhost:8080" (env "SERVER")}}/server.Runner
7 | param:
8 | server: |
9 | {{default "http://localhost:8080" (env "SERVER")}}
10 | items:
11 | - name: healthz
12 | before:
13 | items:
14 | - httpReady("{{.param.server}}/healthz", 6000)
15 | request:
16 | api: |
17 | {{default "http://localhost:8080" (env "SERVER")}}/healthz
18 | - name: CreateStore
19 | request:
20 | api: /CreateStore
21 | method: POST
22 | body: |
23 | {
24 | "name": "git",
25 | "url": "https://gitee.com/linuxsuren/api-testing-hub",
26 | "kind": {
27 | "name": "atest-store-git"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/e2e/k8s.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | sleep 6
5 | echo "Running k8s.sh"
6 |
7 | ls -hal
8 | cd api-testing
9 | echo "build helm dependency"
10 | helm dependency build
11 |
12 | echo "install helm chart"
13 | helm install --kube-apiserver https://server:6443 --kube-token abcd --kube-insecure-skip-tls-verify \
14 | api-testing . \
15 | --set service.type=NodePort \
16 | --set service.nodePort=30000 \
17 | --set persistence.enabled=false \
18 | --set image.registry=ghcr.io \
19 | --set image.repository=linuxsuren/api-testing \
20 | --set image.tag=master \
21 | --set extension.registry=ghcr.io
22 |
23 | SERVER=http://server:30000 atest run -p git.yaml
24 |
--------------------------------------------------------------------------------
/e2e/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | file=$1
4 | if [ "$file" == "" ]
5 | then
6 | file=compose.yaml
7 | fi
8 |
9 | docker compose version
10 | docker compose -f "$file" down
11 | docker compose -f "$file" up --build testing --exit-code-from testing --remove-orphans
12 |
--------------------------------------------------------------------------------
/helm/api-testing/.helmignore:
--------------------------------------------------------------------------------
1 | # Patterns to ignore when building packages.
2 | # This supports shell glob matching, relative path matching, and
3 | # negation (prefixed with !). Only one pattern per line.
4 | .DS_Store
5 | # Common VCS dirs
6 | .git/
7 | .gitignore
8 | .bzr/
9 | .bzrignore
10 | .hg/
11 | .hgignore
12 | .svn/
13 | # Common backup files
14 | *.swp
15 | *.bak
16 | *.tmp
17 | *.orig
18 | *~
19 | # Various IDEs
20 | .project
21 | .idea/
22 | *.tmproj
23 | .vscode/
24 |
--------------------------------------------------------------------------------
/helm/api-testing/Chart.lock:
--------------------------------------------------------------------------------
1 | dependencies:
2 | - name: mongodb
3 | repository: oci://registry-1.docker.io/bitnamicharts
4 | version: 15.1.7
5 | digest: sha256:e573c76d3c75c7e5bc61cbf1e7de46bbf59837de68ac06ebdfe1fa32337a6f58
6 | generated: "2024-05-09T11:36:47.7429098+08:00"
7 |
--------------------------------------------------------------------------------
/helm/api-testing/Chart.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v2
2 | name: api-testing
3 | description: YAML based API testing tool
4 |
5 | # A chart can be either an 'application' or a 'library' chart.
6 | #
7 | # Application charts are a collection of templates that can be packaged into versioned archives
8 | # to be deployed.
9 | #
10 | # Library charts provide useful utilities or functions for the chart developer. They're included as
11 | # a dependency of application charts to inject those utilities and functions into the rendering
12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed.
13 | type: application
14 |
15 | # This is the chart version. This version number should be incremented each time you make changes
16 | # to the chart and its templates, including the app version.
17 | # Versions are expected to follow Semantic Versioning (https://semver.org/)
18 | version: v0.0.4
19 |
20 | # This is the version number of the application being deployed. This version number should be
21 | # incremented each time you make changes to the application. Versions are not expected to
22 | # follow Semantic Versioning. They should reflect the version the application is using.
23 | # It is recommended to use it with quotes.
24 | appVersion: "v0.0.15"
25 |
26 | dependencies:
27 | - name: mongodb
28 | version: ^15.0.1
29 | repository: oci://registry-1.docker.io/bitnamicharts
30 | condition: mongodb.enabled
31 |
--------------------------------------------------------------------------------
/helm/api-testing/templates/hpa.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.autoscaling.enabled }}
2 | apiVersion: autoscaling/v2
3 | kind: HorizontalPodAutoscaler
4 | metadata:
5 | name: {{ include "api-testing.fullname" . }}
6 | labels:
7 | {{- include "api-testing.labels" . | nindent 4 }}
8 | spec:
9 | scaleTargetRef:
10 | apiVersion: apps/v1
11 | kind: Deployment
12 | name: {{ include "api-testing.fullname" . }}
13 | minReplicas: {{ .Values.autoscaling.minReplicas }}
14 | maxReplicas: {{ .Values.autoscaling.maxReplicas }}
15 | metrics:
16 | {{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
17 | - type: Resource
18 | resource:
19 | name: cpu
20 | target:
21 | type: Utilization
22 | averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
23 | {{- end }}
24 | {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
25 | - type: Resource
26 | resource:
27 | name: memory
28 | target:
29 | type: Utilization
30 | averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
31 | {{- end }}
32 | {{- end }}
33 |
--------------------------------------------------------------------------------
/helm/api-testing/templates/pvc.yaml:
--------------------------------------------------------------------------------
1 | {{- $core := .Values.persistence.persistentVolumeClaim.core -}}
2 | {{- if and .Values.persistence.enabled (not $core.existingClaim) }}
3 | kind: PersistentVolumeClaim
4 | apiVersion: v1
5 | metadata:
6 | name: {{ include "api-testing.fullname" . }}
7 | labels:
8 | {{- include "api-testing.labels" . | nindent 4 }}
9 | spec:
10 | accessModes:
11 | - {{ $core.accessMode }}
12 | resources:
13 | requests:
14 | storage: {{ $core.size }}
15 | {{- if $core.storageClass }}
16 | {{- if eq "-" $core.storageClass }}
17 | storageClassName: ""
18 | {{- else }}
19 | storageClassName: {{ $core.storageClass }}
20 | {{- end }}
21 | {{- end }}
22 | volumeMode: {{ $core.volumeMode }}
23 | {{- end }}
24 |
--------------------------------------------------------------------------------
/helm/api-testing/templates/service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: {{ include "api-testing.fullname" . }}
5 | labels:
6 | {{- include "api-testing.labels" . | nindent 4 }}
7 | spec:
8 | type: {{ .Values.service.type }}
9 | ports:
10 | - port: {{ .Values.service.port }}
11 | targetPort: http
12 | protocol: TCP
13 | name: http
14 | {{- if and .Values.service.nodePort }}
15 | nodePort: {{ .Values.service.nodePort }}
16 | {{- end}}
17 | selector:
18 | {{- include "api-testing.selectorLabels" . | nindent 4 }}
19 |
--------------------------------------------------------------------------------
/helm/api-testing/templates/serviceaccount.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.serviceAccount.create -}}
2 | apiVersion: v1
3 | kind: ServiceAccount
4 | metadata:
5 | name: {{ include "api-testing.serviceAccountName" . }}
6 | labels:
7 | {{- include "api-testing.labels" . | nindent 4 }}
8 | {{- with .Values.serviceAccount.annotations }}
9 | annotations:
10 | {{- toYaml . | nindent 4 }}
11 | {{- end }}
12 | {{- end }}
13 |
--------------------------------------------------------------------------------
/helm/api-testing/templates/servicemonitor.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.serviceMonitor.enabled }}
2 | apiVersion: monitoring.coreos.com/v1
3 | kind: ServiceMonitor
4 | metadata:
5 | name: {{ include "api-testing.fullname" . }}-servicemonitor
6 | labels:
7 | {{- include "api-testing.labels" . | nindent 4 }}
8 | spec:
9 | selector:
10 | matchLabels:
11 | {{- include "api-testing.selectorLabels" . | nindent 6 }}
12 | endpoints:
13 | - port: http
14 | interval: {{ .Values.serviceMonitor.interval }}
15 | path: /metrics
16 | {{- end }}
--------------------------------------------------------------------------------
/helm/api-testing/templates/tests/test-connection.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Pod
3 | metadata:
4 | name: "{{ include "api-testing.fullname" . }}-test-connection"
5 | labels:
6 | {{- include "api-testing.labels" . | nindent 4 }}
7 | annotations:
8 | "helm.sh/hook": test
9 | spec:
10 | containers:
11 | - name: wget
12 | image: busybox
13 | command: ['wget']
14 | args: ['{{ include "api-testing.fullname" . }}:{{ .Values.service.port }}']
15 | restartPolicy: Never
16 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | _ "embed"
5 | "os"
6 |
7 | "github.com/linuxsuren/api-testing/pkg/version"
8 |
9 | "github.com/linuxsuren/api-testing/cmd"
10 | "github.com/linuxsuren/api-testing/pkg/server"
11 | exec "github.com/linuxsuren/go-fake-runtime"
12 | )
13 |
14 | func main() {
15 | version.SetMod(goMod)
16 | c := cmd.NewRootCmd(exec.NewDefaultExecer(), server.NewDefaultHTTPServer())
17 | if err := c.Execute(); err != nil {
18 | os.Exit(1)
19 | }
20 | }
21 |
22 | //go:embed go.mod
23 | var goMod string
24 |
--------------------------------------------------------------------------------
/pkg/apispec/data/proto/google/api/annotations.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | syntax = "proto3";
16 |
17 | package google.api;
18 |
19 | import "google/api/http.proto";
20 | import "google/protobuf/descriptor.proto";
21 |
22 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations";
23 | option java_multiple_files = true;
24 | option java_outer_classname = "AnnotationsProto";
25 | option java_package = "com.google.api";
26 | option objc_class_prefix = "GAPI";
27 |
28 | extend google.protobuf.MethodOptions {
29 | // See `HttpRule`.
30 | HttpRule http = 72295728;
31 | }
--------------------------------------------------------------------------------
/pkg/apispec/data/proto/google/protobuf/annotations.proto:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/pkg/apispec/data/proto/google/protobuf/annotations.proto
--------------------------------------------------------------------------------
/pkg/apispec/fake.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package apispec
18 |
19 | type fakeAPISpec struct {
20 | apis [][]string
21 | }
22 |
23 | // NewFakeAPISpec creates a new instance of fakeAPISpec
24 | func NewFakeAPISpec(apis [][]string) APICoverage {
25 | return &fakeAPISpec{apis: apis}
26 | }
27 |
28 | // HaveAPI is fake method
29 | func (f *fakeAPISpec) HaveAPI(path, method string) (exist bool) {
30 | for _, item := range f.apis {
31 | if len(item) >= 2 && item[0] == path && item[1] == method {
32 | exist = true
33 | break
34 | }
35 | }
36 | return
37 | }
38 |
39 | // APICount is fake method
40 | func (f *fakeAPISpec) APICount() (count int) {
41 | count = len(f.apis)
42 | return
43 | }
44 |
--------------------------------------------------------------------------------
/pkg/apispec/grpc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package apispec
18 |
19 | import (
20 | "embed"
21 | "io/fs"
22 | "strings"
23 | )
24 |
25 | //go:embed data/proto
26 | var res embed.FS
27 |
28 | func GetProtoFiles() (files map[string]string, err error) {
29 | efs := &res
30 | files = make(map[string]string)
31 | if err := fs.WalkDir(efs, ".", func(path string, d fs.DirEntry, err error) error {
32 | if d.IsDir() {
33 | return nil
34 | }
35 |
36 | var data []byte
37 | if data, err = fs.ReadFile(efs, path); err == nil {
38 | files[strings.TrimPrefix(path, "data/proto/")] = string(data)
39 | } else {
40 | return err
41 | }
42 | return nil
43 | }); err != nil {
44 | return nil, err
45 | }
46 |
47 | return files, nil
48 | }
49 |
--------------------------------------------------------------------------------
/pkg/apispec/grpc_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package apispec
18 |
19 | import (
20 | "strings"
21 | "testing"
22 |
23 | "github.com/stretchr/testify/assert"
24 | )
25 |
26 | func TestFindProto(t *testing.T) {
27 | files, err := GetProtoFiles()
28 | assert.NoError(t, err)
29 | for file := range files {
30 | if !strings.HasPrefix(file, "google") &&
31 | !strings.HasPrefix(file, "protoc-gen-openapiv2") &&
32 | !strings.HasPrefix(file, "validate") {
33 | t.Fatal("unknown file path")
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/pkg/apispec/testdata/swagger.json:
--------------------------------------------------------------------------------
1 | {
2 | "swagger": "2.0",
3 | "info": {
4 | "description": "sample",
5 | "title": "sample",
6 | "version": "1.0.0"
7 | },
8 | "paths": {
9 | "/api/v1/users": {
10 | "get": {
11 | "summary": "summary",
12 | "operationId": "getUsers"
13 | },
14 | "post": {
15 | "summary": "summary",
16 | "operationId": "createUser"
17 | }
18 | },
19 | "/api/v1/users/{user}": {
20 | "get": {
21 | "summary": "summary",
22 | "operationId": "getUser"
23 | },
24 | "delete": {
25 | "summary": "summary",
26 | "operationId": "deleteUser"
27 | },
28 | "put": {
29 | "summary": "summary",
30 | "operationId": "updateUser"
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/pkg/compare/error_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package compare
18 |
19 | import (
20 | "fmt"
21 | "testing"
22 |
23 | "github.com/stretchr/testify/assert"
24 | )
25 |
26 | func TestNewNoEqualErr(t *testing.T) {
27 | err := newNoEqualErr("data", fmt.Errorf("this is msg"))
28 | err = newNoEqualErr("to", err)
29 | err = newNoEqualErr("path", err)
30 | assert.Equal(t, "compare: field path.to.data: this is msg", err.Error())
31 | }
32 |
--------------------------------------------------------------------------------
/pkg/extension/pprof.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package extension
17 |
18 | import (
19 | "bytes"
20 | "runtime/pprof"
21 | )
22 |
23 | func LoadPProf(name string) []byte {
24 | buf := new(bytes.Buffer)
25 | if p := pprof.Lookup(name); p != nil {
26 | p.WriteTo(buf, 0)
27 | }
28 | return buf.Bytes()
29 | }
30 |
--------------------------------------------------------------------------------
/pkg/extension/signal.go:
--------------------------------------------------------------------------------
1 | package extension
2 |
3 | import (
4 | "context"
5 | "os"
6 | "os/signal"
7 | "syscall"
8 |
9 | "github.com/linuxsuren/api-testing/pkg/logging"
10 | )
11 |
12 | var (
13 | signalLogger = logging.DefaultLogger(logging.LogLevelInfo).WithName("signal")
14 | )
15 |
16 | type StopAble interface {
17 | Stop()
18 | }
19 |
20 | func RegisterStopSignal(ctx context.Context, callback func(), servers ...StopAble) {
21 | endChan := make(chan os.Signal, 1)
22 | signal.Notify(endChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT)
23 | go func(ctx context.Context) {
24 | select {
25 | case <-endChan:
26 | case <-ctx.Done():
27 | }
28 | if callback != nil {
29 | callback()
30 | }
31 | for _, server := range servers {
32 | signalLogger.Info("Stopping the server...")
33 | server.Stop()
34 | }
35 | }(ctx)
36 | }
37 |
--------------------------------------------------------------------------------
/pkg/extension/singal_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package extension
17 |
18 | import (
19 | "context"
20 | "testing"
21 | "time"
22 |
23 | "github.com/stretchr/testify/assert"
24 | )
25 |
26 | func TestRegisterStopSignal(t *testing.T) {
27 | var stoppedA bool
28 | fs := &fakeServer{}
29 | ctx, cancel := context.WithTimeout(context.TODO(), time.Second)
30 | cancel()
31 | RegisterStopSignal(ctx, func() {
32 | stoppedA = true
33 | }, fs)
34 | time.Sleep(time.Second * 2)
35 | assert.True(t, stoppedA)
36 | assert.True(t, fs.signal)
37 | }
38 |
39 | type fakeServer struct {
40 | signal bool
41 | }
42 |
43 | func (s *fakeServer) Stop() {
44 | s.signal = true
45 | }
46 |
--------------------------------------------------------------------------------
/pkg/generator/converter_raw.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package generator
17 |
18 | import (
19 | "github.com/linuxsuren/api-testing/pkg/testing"
20 | "gopkg.in/yaml.v3"
21 | )
22 |
23 | type rawConverter struct {
24 | }
25 |
26 | func init() {
27 | RegisterTestSuiteConverter("raw", &rawConverter{})
28 | }
29 |
30 | func (c *rawConverter) Convert(testSuite *testing.TestSuite) (result string, err error) {
31 | if err = testSuite.Render(make(map[string]interface{})); err == nil {
32 | for _, item := range testSuite.Items {
33 | item.Request.RenderAPI(testSuite.API)
34 | }
35 |
36 | var data []byte
37 | if data, err = yaml.Marshal(testSuite); err == nil {
38 | result = string(data)
39 | }
40 | }
41 | return
42 | }
43 |
--------------------------------------------------------------------------------
/pkg/generator/converter_raw_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package generator
17 |
18 | import (
19 | "testing"
20 |
21 | _ "embed"
22 |
23 | "github.com/stretchr/testify/assert"
24 | )
25 |
26 | func TestRawConvert(t *testing.T) {
27 | rawConvert := GetTestSuiteConverter("raw")
28 | assert.NotNil(t, rawConvert)
29 |
30 | output, err := rawConvert.Convert(createTestSuiteForTest())
31 | assert.NoError(t, err)
32 | assert.Equal(t, expectedTestSuite, output)
33 | }
34 |
35 | //go:embed testdata/expected_testsuite.yaml
36 | var expectedTestSuite string
37 |
--------------------------------------------------------------------------------
/pkg/generator/data/curl.tpl:
--------------------------------------------------------------------------------
1 | curl -k -X {{.Request.Method}} '{{.Request.API}}' \
2 | {{- range $key, $val := .Request.Header}}
3 | -H '{{$key}}: {{$val}}' \
4 | {{- end}}
5 | {{- if .Request.Body.String }}
6 | --data-raw '{{.Request.Body.String}}'
7 | {{- end}}
8 |
--------------------------------------------------------------------------------
/pkg/generator/data/robot-suite.tpl:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Library RequestsLibrary
3 |
4 | *** Test Cases ***
5 | {{- range $item := .Items}}
6 | {{$item.Name}}
7 | {{- if $item.Request.Header}}
8 | ${headers}= Create Dictionary {{- range $key, $val := $item.Request.Header}} {{$key}} {{$val}}{{- end}}
9 | {{- end}}
10 | ${response}= {{$item.Request.Method}} {{$item.Request.API}}{{- if .Request.Header}} headers=${headers}{{end}}
11 | {{- end}}
12 |
--------------------------------------------------------------------------------
/pkg/generator/data/robot.tpl:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Library RequestsLibrary
3 |
4 | *** Test Cases ***
5 | {{.Name}}
6 | {{- if .Request.Header}}
7 | ${headers}= Create Dictionary {{- range $key, $val := .Request.Header}} {{$key}} {{$val}}{{- end}}
8 | {{- end}}
9 | ${response}= {{.Request.Method}} {{.Request.API}}{{- if .Request.Header}} headers=${headers}{{end}}
10 |
--------------------------------------------------------------------------------
/pkg/generator/helper.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package generator
17 |
18 | import (
19 | "html/template"
20 | )
21 |
22 | func safeString(str string) template.HTML {
23 | return template.HTML(str)
24 | }
25 |
--------------------------------------------------------------------------------
/pkg/generator/javascript_generator.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package generator
17 |
18 | import (
19 | _ "embed"
20 |
21 | "github.com/linuxsuren/api-testing/pkg/testing"
22 | )
23 |
24 | type javascriptGenerator struct {
25 | }
26 |
27 | func NewJavaScriptGenerator() CodeGenerator {
28 | return &javascriptGenerator{}
29 | }
30 |
31 | func (g *javascriptGenerator) Generate(testSuite *testing.TestSuite, testcase *testing.TestCase) (string, error) {
32 | return generate(testSuite, testcase, "javascript template", javascriptTemplate)
33 | }
34 |
35 | func init() {
36 | RegisterCodeGenerator("JavaScript", NewJavaScriptGenerator())
37 | }
38 |
39 | //go:embed data/main.javascript.tpl
40 | var javascriptTemplate string
41 |
--------------------------------------------------------------------------------
/pkg/generator/python_generator.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package generator
17 |
18 | import (
19 | _ "embed"
20 |
21 | "github.com/linuxsuren/api-testing/pkg/testing"
22 | )
23 |
24 | type pythonGenerator struct {
25 | }
26 |
27 | func NewPythonGenerator() CodeGenerator {
28 | return &pythonGenerator{}
29 | }
30 |
31 | func (g *pythonGenerator) Generate(testSuite *testing.TestSuite, testcase *testing.TestCase) (result string, err error) {
32 | return generate(testSuite, testcase, "python template", pythonTemplate)
33 | }
34 |
35 | func init() {
36 | RegisterCodeGenerator("python", NewPythonGenerator())
37 | }
38 |
39 | //go:embed data/main.python.tpl
40 | var pythonTemplate string
41 |
--------------------------------------------------------------------------------
/pkg/generator/robot_generator.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package generator
17 |
18 | import (
19 | _ "embed"
20 |
21 | "github.com/linuxsuren/api-testing/pkg/testing"
22 | )
23 |
24 | type robotGenerator struct {
25 | }
26 |
27 | func NewRobotGenerator() CodeGenerator {
28 | return &robotGenerator{}
29 | }
30 |
31 | func (g *robotGenerator) Generate(testSuite *testing.TestSuite, testcase *testing.TestCase) (string, error) {
32 | tpl := robotTemplate
33 | if testcase == nil {
34 | tpl = robotSuiteTemplate
35 | }
36 | return generate(testSuite, testcase, "robot-framework", tpl)
37 | }
38 |
39 | func init() {
40 | RegisterCodeGenerator("robot-framework", NewRobotGenerator())
41 | }
42 |
43 | //go:embed data/robot.tpl
44 | var robotTemplate string
45 |
46 | //go:embed data/robot-suite.tpl
47 | var robotSuiteTemplate string
48 |
--------------------------------------------------------------------------------
/pkg/generator/testdata/expected_go_body_request_code.txt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 | http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software
8 | distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | See the License for the specific language governing permissions and
11 | limitations under the License.
12 | */
13 | package main
14 |
15 | import (
16 | "bytes"
17 | "io"
18 | "net/http"
19 | )
20 |
21 | func main() {
22 | body := bytes.NewBufferString(`{"key": "value"}`)
23 |
24 | req, err := http.NewRequest("GET", "https://www.baidu.com", body)
25 | if err != nil {
26 | panic(err)
27 | }
28 | req.Header.Set("User-Agent", "atest")
29 |
30 | resp, err := http.DefaultClient.Do(req)
31 | if err != nil {
32 | panic(err)
33 | }
34 |
35 | if resp.StatusCode != http.StatusOK {
36 | panic("status code is not 200")
37 | }
38 |
39 | data, err := io.ReadAll(resp.Body)
40 | println(string(data))
41 | }
42 |
--------------------------------------------------------------------------------
/pkg/generator/testdata/expected_go_code.txt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 | http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software
8 | distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | See the License for the specific language governing permissions and
11 | limitations under the License.
12 | */
13 | package main
14 |
15 | import (
16 | "bytes"
17 | "io"
18 | "net/http"
19 | )
20 |
21 | func main() {
22 | body := bytes.NewBufferString(``)
23 |
24 | req, err := http.NewRequest("GET", "https://www.baidu.com", body)
25 | if err != nil {
26 | panic(err)
27 | }
28 | req.Header.Set("User-Agent", "atest")
29 |
30 | resp, err := http.DefaultClient.Do(req)
31 | if err != nil {
32 | panic(err)
33 | }
34 |
35 | if resp.StatusCode != http.StatusOK {
36 | panic("status code is not 200")
37 | }
38 |
39 | data, err := io.ReadAll(resp.Body)
40 | println(string(data))
41 | }
42 |
--------------------------------------------------------------------------------
/pkg/generator/testdata/expected_go_cookie_request_code.txt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 | http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software
8 | distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | See the License for the specific language governing permissions and
11 | limitations under the License.
12 | */
13 | package main
14 |
15 | import (
16 | "io"
17 | "net/http"
18 | )
19 |
20 | func main() {
21 | data := url.Values{}
22 | data.Set("key", "value")
23 | body := strings.NewReader(data.Encode())
24 |
25 | req, err := http.NewRequest("GET", "https://www.baidu.com", body)
26 | if err != nil {
27 | panic(err)
28 | }
29 | req.Header.Set("User-Agent", "atest")
30 | req.AddCookie(&http.Cookie{
31 | Name: "name",
32 | Value: "value",
33 | })
34 |
35 | resp, err := http.DefaultClient.Do(req)
36 | if err != nil {
37 | panic(err)
38 | }
39 |
40 | if resp.StatusCode != http.StatusOK {
41 | panic("status code is not 200")
42 | }
43 |
44 | data, err := io.ReadAll(resp.Body)
45 | println(string(data))
46 | }
47 |
--------------------------------------------------------------------------------
/pkg/generator/testdata/expected_go_form_request_code.txt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 | http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software
8 | distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | See the License for the specific language governing permissions and
11 | limitations under the License.
12 | */
13 | package main
14 |
15 | import (
16 | "io"
17 | "net/http"
18 | )
19 |
20 | func main() {
21 | data := url.Values{}
22 | data.Set("key", "value")
23 | body := strings.NewReader(data.Encode())
24 |
25 | req, err := http.NewRequest("GET", "https://www.baidu.com", body)
26 | if err != nil {
27 | panic(err)
28 | }
29 | req.Header.Set("User-Agent", "atest")
30 |
31 | resp, err := http.DefaultClient.Do(req)
32 | if err != nil {
33 | panic(err)
34 | }
35 |
36 | if resp.StatusCode != http.StatusOK {
37 | panic("status code is not 200")
38 | }
39 |
40 | data, err := io.ReadAll(resp.Body)
41 | println(string(data))
42 | }
43 |
--------------------------------------------------------------------------------
/pkg/generator/testdata/expected_javascript_code.txt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 | http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software
8 | distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | See the License for the specific language governing permissions and
11 | limitations under the License.
12 | */
13 |
14 | async function makeRequest() {
15 | const headers = new Headers();
16 | headers.append("User-Agent", "atest");
17 |
18 | const requestOptions = {
19 | method: "GET",
20 | headers: headers,
21 | redirect: "follow"
22 | };
23 |
24 | try {
25 | const response = await fetch("https://www.baidu.com", requestOptions);
26 | if (response.ok) { // Check if HTTP status code is 200/OK
27 | const text = await response.text();
28 | console.log(text);
29 | } else {
30 | throw new Error('Network response was not ok. Status code: ' + response.status);
31 | }
32 | } catch (error) {
33 | console.error('Fetch error:', error);
34 | }
35 | }
36 |
37 | makeRequest();
38 |
--------------------------------------------------------------------------------
/pkg/generator/testdata/expected_python_code.txt:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2024-2025 API Testing Authors.
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 | http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software
8 | distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | See the License for the specific language governing permissions and
11 | limitations under the License.
12 | '''
13 | import io
14 | import requests
15 | from urllib.parse import urlencode
16 |
17 | def main():
18 | body = io.BytesIO(b"""""")
19 | headers = {"User-Agent": "atest"}
20 | try:
21 | req = requests.Request("GET", "https://www.baidu.com", headers=headers, data=body)
22 | except requests.RequestException as e:
23 | raise e
24 |
25 | resp = requests.Session().send(req.prepare(), verify=False)
26 | if resp.status_code != 200:
27 | raise Exception("status code is not 200")
28 |
29 | data = resp.content
30 | print(data.decode("utf-8"))
31 |
32 | if __name__ == "__main__":
33 | main()
34 |
--------------------------------------------------------------------------------
/pkg/generator/testdata/expected_python_cookie_request_code.txt:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2024-2025 API Testing Authors.
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 | http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software
8 | distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | See the License for the specific language governing permissions and
11 | limitations under the License.
12 | '''
13 | import io
14 | import requests
15 | from urllib.parse import urlencode
16 |
17 | def main():
18 | data = {}
19 | data["key"] = "value"
20 | encoded_data = urlencode(data)
21 | body = io.BytesIO(encoded_data.encode("utf-8"))
22 | headers = {"User-Agent": "atest"}
23 | cookies = {"name": "value"}
24 | try:
25 | req = requests.Request("GET", "https://www.baidu.com", headers=headers, cookies=cookies, data=body)
26 | except requests.RequestException as e:
27 | raise e
28 |
29 | resp = requests.Session().send(req.prepare(), verify=False)
30 | if resp.status_code != 200:
31 | raise Exception("status code is not 200")
32 |
33 | data = resp.content
34 | print(data.decode("utf-8"))
35 |
36 | if __name__ == "__main__":
37 | main()
38 |
--------------------------------------------------------------------------------
/pkg/generator/testdata/expected_python_form_request_code.txt:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2024-2025 API Testing Authors.
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 | http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software
8 | distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | See the License for the specific language governing permissions and
11 | limitations under the License.
12 | '''
13 | import io
14 | import requests
15 | from urllib.parse import urlencode
16 |
17 | def main():
18 | data = {}
19 | data["key"] = "value"
20 | encoded_data = urlencode(data)
21 | body = io.BytesIO(encoded_data.encode("utf-8"))
22 | headers = {"User-Agent": "atest"}
23 | try:
24 | req = requests.Request("GET", "https://www.baidu.com", headers=headers, data=body)
25 | except requests.RequestException as e:
26 | raise e
27 |
28 | resp = requests.Session().send(req.prepare(), verify=False)
29 | if resp.status_code != 200:
30 | raise Exception("status code is not 200")
31 |
32 | data = resp.content
33 | print(data.decode("utf-8"))
34 |
35 | if __name__ == "__main__":
36 | main()
37 |
--------------------------------------------------------------------------------
/pkg/generator/testdata/expected_suite_from_postman.yaml:
--------------------------------------------------------------------------------
1 | name: New Collection
2 | items:
3 | - name: New Request
4 | request:
5 | api: http://localhost?key=value
6 | method: GET
7 | header:
8 | key: value
9 | body: '{}'
--------------------------------------------------------------------------------
/pkg/generator/testdata/expected_suite_from_sub_postman.yaml:
--------------------------------------------------------------------------------
1 | name: Sub
2 | items:
3 | - name: Get Sub Get New Request
4 | request:
5 | api: http://localhost?key=value
6 | method: GET
7 | header:
8 | key: value
9 | body: '{}'
--------------------------------------------------------------------------------
/pkg/generator/testdata/expected_testsuite.yaml:
--------------------------------------------------------------------------------
1 | name: API Testing
2 | api: http://localhost:8080/server.Runner
3 | items:
4 | - name: hello-jmeter
5 | request:
6 | api: /GetSuites
7 | method: POST
8 | body: sample
9 |
--------------------------------------------------------------------------------
/pkg/generator/testdata/native.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": "IyFhcGktdGVzdGluZwojIHlhbWwtbGFuZ3VhZ2Utc2VydmVyOiAkc2NoZW1hPWh0dHBzOi8vbGludXhzdXJlbi5naXRodWIuaW8vYXBpLXRlc3RpbmcvYXBpLXRlc3Rpbmctc2NoZW1hLmpzb24KbmFtZTogYmFkCmFwaTogYmFkCml0ZW1zOgogICAgLSBuYW1lOiBvbmUKICAgICAgcmVxdWVzdDoKICAgICAgICBhcGk6IC9vbmUKICAgICAgICBtZXRob2Q6IEdFVAogICAgLSBuYW1lOiB0d28KICAgICAgcmVxdWVzdDoKICAgICAgICBhcGk6IC90d28KICAgICAgICBtZXRob2Q6IFBPU1QKICAgICAgICBxdWVyeToKICAgICAgICAgICAgYmJiOiBiYmIKICAgICAgICBoZWFkZXI6CiAgICAgICAgICAgIGFhYTogYWFhCiAgICAgIGV4cGVjdDoKICAgICAgICBzdGF0dXNDb2RlOiAyMDAK"
3 | }
--------------------------------------------------------------------------------
/pkg/generator/testdata/postman-sub.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "_postman_id": "84b8940a-009e-4127-b84e-f4d6fd6b9972",
4 | "name": "Sub",
5 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
6 | "_exporter_id": "19536120"
7 | },
8 | "item": [
9 | {
10 | "name": "Get",
11 | "item": [
12 | {
13 | "name": "Sub Get",
14 | "item": [
15 | {
16 | "name": "New Request",
17 | "request": {
18 | "method": "GET",
19 | "header": [
20 | {
21 | "key": "key",
22 | "value": "value",
23 | "description": "description",
24 | "type": "text"
25 | }
26 | ],
27 | "body": {
28 | "mode": "raw",
29 | "raw": "{}"
30 | },
31 | "url": {
32 | "raw": "http://localhost?key=value"
33 | }
34 | }
35 | }
36 | ]
37 | }
38 | ]
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/pkg/generator/testdata/postman.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "_postman_id": "0da1f6bf-fdbb-46a5-ac46-873564e2259c",
4 | "name": "New Collection",
5 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
6 | "_exporter_id": "6795120",
7 | "_collection_link": "https://www.postman.com/ks-devops/workspace/kubesphere-devops/collection/6795120-0da1f6bf-fdbb-46a5-ac46-873564e2259c?action=share&creator=6795120&source=collection_link"
8 | },
9 | "item": [
10 | {
11 | "name": "New Request",
12 | "protocolProfileBehavior": {
13 | "disableBodyPruning": true
14 | },
15 | "request": {
16 | "method": "GET",
17 | "header": [
18 | {
19 | "key": "key",
20 | "value": "value",
21 | "description": "description",
22 | "type": "text"
23 | }
24 | ],
25 | "body": {
26 | "mode": "raw",
27 | "raw": "{}"
28 | },
29 | "url": {
30 | "raw": "http://localhost?key=value"
31 | }
32 | }
33 | }
34 | ]
35 | }
--------------------------------------------------------------------------------
/pkg/generator/testdata/simple.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Library RequestsLibrary
3 |
4 | *** Test Cases ***
5 | simple
6 | ${response}= GET http://foo
7 |
--------------------------------------------------------------------------------
/pkg/generator/testdata/suite.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Library RequestsLibrary
3 |
4 | *** Test Cases ***
5 | one
6 | ${headers}= Create Dictionary key1 value1
7 | ${response}= GET http://foo headers=${headers}
8 | two
9 | ${headers}= Create Dictionary key2 value2
10 | ${response}= GET http://foo headers=${headers}
11 |
--------------------------------------------------------------------------------
/pkg/generator/testdata/with-headers.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Library RequestsLibrary
3 |
4 | *** Test Cases ***
5 | simple
6 | ${headers}= Create Dictionary key value
7 | ${response}= GET http://foo headers=${headers}
8 |
--------------------------------------------------------------------------------
/pkg/limit/limiter_long_test.go:
--------------------------------------------------------------------------------
1 | //go:build longtest
2 | // +build longtest
3 |
4 | /*
5 | Copyright 2023 API Testing Authors.
6 |
7 | Licensed under the Apache License, Version 2.0 (the "License");
8 | you may not use this file except in compliance with the License.
9 | You may obtain a copy of the License at
10 |
11 | http://www.apache.org/licenses/LICENSE-2.0
12 |
13 | Unless required by applicable law or agreed to in writing, software
14 | distributed under the License is distributed on an "AS IS" BASIS,
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | See the License for the specific language governing permissions and
17 | limitations under the License.
18 | */
19 |
20 | package limit_test
21 |
22 | import (
23 | "testing"
24 | "time"
25 |
26 | "github.com/linuxsuren/api-testing/pkg/limit"
27 | "github.com/stretchr/testify/assert"
28 | )
29 |
30 | func TestLimiterWithLongTime(t *testing.T) {
31 | for i := 0; i < 10; i++ {
32 | testLimiter(t, int32(8+i*2))
33 | }
34 | }
35 |
36 | func testLimiter(t *testing.T, count int32) {
37 | t.Log("test limit with count", count)
38 | limiter := limit.NewDefaultRateLimiter(count, 1)
39 | num := int32(0)
40 |
41 | loop := true
42 | go func(l limit.RateLimiter) {
43 | for loop {
44 | l.Accept()
45 | num += 1
46 | }
47 | }(limiter)
48 |
49 | select {
50 | case <-time.After(time.Second):
51 | loop = false
52 | }
53 | assert.True(t, num <= count+1, num)
54 | }
55 |
--------------------------------------------------------------------------------
/pkg/limit/limiter_test.go:
--------------------------------------------------------------------------------
1 | package limit
2 |
3 | import (
4 | "testing"
5 | "time"
6 |
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func TestLimiter(t *testing.T) {
11 | t.Log("run rate limit test")
12 | limiter := NewDefaultRateLimiter(0, 0)
13 | num := 0
14 |
15 | loop := true
16 | go func(l RateLimiter) {
17 | for loop {
18 | l.Accept()
19 | num += 1
20 | }
21 | }(limiter)
22 |
23 | select {
24 | case <-time.After(time.Second):
25 | loop = false
26 | limiter.Stop()
27 | }
28 | assert.True(t, num <= 10, num)
29 | }
30 |
--------------------------------------------------------------------------------
/pkg/mock/server.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package mock
17 |
18 | import (
19 | "net/http"
20 | )
21 |
22 | type Loadable interface {
23 | Load() error
24 | }
25 |
26 | type DynamicServer interface {
27 | Start(reader Reader, prefix string) error
28 | SetupHandler(reader Reader, prefix string) (http.Handler, error)
29 | Stop() error
30 | GetPort() string
31 | EnableMetrics()
32 | Loadable
33 | }
34 |
35 | const (
36 | headerMockServer = "Mock-Server"
37 | )
38 |
--------------------------------------------------------------------------------
/pkg/render/data/templateUsage.yaml:
--------------------------------------------------------------------------------
1 | randImage: |
2 | {{ randImage 100 100 }}
3 | randAscii: |
4 | {{ randAscii 5 }}
5 | randPdf: |
6 | {{ randPdf "content" }}
7 | randZip: |
8 | {{ randZip 5 }}
9 |
--------------------------------------------------------------------------------
/pkg/render/doc.go:
--------------------------------------------------------------------------------
1 | // Package render provides a simple way to render as template
2 | package render
3 |
--------------------------------------------------------------------------------
/pkg/render/image_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language 24 permissions and
14 | limitations under the License.
15 | */
16 | package render
17 |
18 | import (
19 | "encoding/base64"
20 | "strings"
21 | "testing"
22 |
23 | "github.com/linuxsuren/api-testing/pkg/util"
24 | "github.com/stretchr/testify/assert"
25 | )
26 |
27 | func TestRandImage(t *testing.T) {
28 | tests := []struct {
29 | width, height int
30 | }{{
31 | width: 0,
32 | height: 10,
33 | }, {
34 | width: 10,
35 | height: -1,
36 | }, {
37 | width: 10240,
38 | height: 10240,
39 | }}
40 | for _, tt := range tests {
41 | data, err := generateRandomImage(tt.width, tt.height)
42 | assert.NoError(t, err, err)
43 |
44 | imageStr := strings.TrimPrefix(string(data), util.ImageBase64Prefix)
45 | _, err = base64.StdEncoding.DecodeString(imageStr)
46 | assert.NoError(t, err, err)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/pkg/render/local.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language 24 permissions and
14 | limitations under the License.
15 | */
16 | package render
17 |
18 | import (
19 | "encoding/base64"
20 | "fmt"
21 | "os"
22 |
23 | "github.com/linuxsuren/api-testing/pkg/util"
24 | )
25 |
26 | func readFile(filename string) (data string, err error) {
27 | var rawData []byte
28 | if rawData, err = os.ReadFile(filename); err == nil {
29 | data = fmt.Sprintf("%s%s", util.BinaryBase64Prefix, base64.StdEncoding.EncodeToString(rawData))
30 | }
31 | return
32 | }
33 |
--------------------------------------------------------------------------------
/pkg/render/local_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language 24 permissions and
14 | limitations under the License.
15 | */
16 | package render
17 |
18 | import (
19 | "testing"
20 |
21 | "github.com/stretchr/testify/assert"
22 | )
23 |
24 | func TestReadFile(t *testing.T) {
25 | data, err := readFile("data/templateUsage.yaml")
26 | assert.Nil(t, err)
27 | assert.Equal(t, "data:application/octet-stream;base64,cmFuZEltYWdlOiB8CiAge3sgcmFuZEltYWdlIDEwMCAxMDAgfX0KcmFuZEFzY2lpOiB8CiAge3sgcmFuZEFzY2lpIDUgfX0KcmFuZFBkZjogfAogIHt7IHJhbmRQZGYgImNvbnRlbnQiIH19CnJhbmRaaXA6IHwKICB7eyByYW5kWmlwIDUgfX0K", data)
28 | }
29 |
--------------------------------------------------------------------------------
/pkg/render/pdf_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language 24 permissions and
14 | limitations under the License.
15 | */
16 | package render
17 |
18 | import (
19 | "testing"
20 |
21 | "github.com/stretchr/testify/assert"
22 | )
23 |
24 | func TestRandPdf(t *testing.T) {
25 | data, err := generateRandomPdf("hello")
26 | assert.NotEmpty(t, data)
27 | assert.NoError(t, err, err)
28 | }
29 |
--------------------------------------------------------------------------------
/pkg/render/secret.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package render
17 |
18 | import (
19 | "github.com/linuxsuren/api-testing/pkg/secret"
20 | )
21 |
22 | type nonSecretGetter struct {
23 | value string
24 | err error
25 | }
26 |
27 | func (n *nonSecretGetter) GetSecret(name string) (s secret.Secret, err error) {
28 | s.Value = n.value
29 | s.Name = name
30 | err = n.err
31 | return
32 | }
33 |
--------------------------------------------------------------------------------
/pkg/render/zip.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language 24 permissions and
14 | limitations under the License.
15 | */
16 | package render
17 |
18 | import (
19 | "archive/zip"
20 | "bytes"
21 | "encoding/base64"
22 | "fmt"
23 | "io"
24 |
25 | "github.com/linuxsuren/api-testing/pkg/util"
26 | )
27 |
28 | func generateRandomZip(count int) (data string, err error) {
29 | var buf bytes.Buffer
30 | w := zip.NewWriter(&buf)
31 |
32 | if count < 1 {
33 | count = 1
34 | }
35 | if count > 100 {
36 | count = 100
37 | }
38 |
39 | for i := 0; i < count; i++ {
40 | name := fmt.Sprintf("%d.txt", i)
41 | var f io.Writer
42 | f, err = w.Create(name)
43 | if err == nil {
44 | _, err = f.Write([]byte(name))
45 | }
46 |
47 | if err != nil {
48 | return
49 | }
50 | }
51 |
52 | if err = w.Close(); err == nil {
53 | data = fmt.Sprintf("%s%s", util.ZIPBase64Prefix, base64.StdEncoding.EncodeToString(buf.Bytes()))
54 | }
55 | return
56 | }
57 |
--------------------------------------------------------------------------------
/pkg/render/zip_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language 24 permissions and
14 | limitations under the License.
15 | */
16 | package render
17 |
18 | import (
19 | "testing"
20 |
21 | "github.com/stretchr/testify/assert"
22 | )
23 |
24 | func TestRandZip(t *testing.T) {
25 | for i := 0; i < 110; i++ {
26 | data, err := generateRandomZip(i)
27 | assert.NotEmpty(t, data)
28 | assert.NoError(t, err, err)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/pkg/runner/doc.go:
--------------------------------------------------------------------------------
1 | // Package runner responsible for excute the test case
2 | package runner
3 |
--------------------------------------------------------------------------------
/pkg/runner/grpc_test/test.pb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/pkg/runner/grpc_test/test.pb
--------------------------------------------------------------------------------
/pkg/runner/grpc_test/testassets/server.key:
--------------------------------------------------------------------------------
1 | -----BEGIN EC PRIVATE KEY-----
2 | MHcCAQEEIAVkpfC5iACaZYvvaf1NevIosGhBKwLS5ZwwnBkokjEhoAoGCCqGSM49
3 | AwEHoUQDQgAE8/i0CVHM+az+k7rS0WkxlkoSWOm9T5f8J1q3KnIGu00rOXRRviiy
4 | bw3czSo8eruRtFv28A0VFZdEnYraHK/2tg==
5 | -----END EC PRIVATE KEY-----
6 |
--------------------------------------------------------------------------------
/pkg/runner/http_reverse_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package runner
18 |
19 | import (
20 | "testing"
21 |
22 | atest "github.com/linuxsuren/api-testing/pkg/testing"
23 | "github.com/linuxsuren/api-testing/pkg/util"
24 | "github.com/stretchr/testify/assert"
25 | )
26 |
27 | func TestAuthHeaderMutator(t *testing.T) {
28 | mutator := &authHeaderMissingMutator{}
29 | testcase := &atest.TestCase{
30 | Request: atest.Request{
31 | Header: map[string]string{
32 | util.Authorization: "Basic xxyy",
33 | },
34 | },
35 | }
36 | result := mutator.Render(testcase)
37 | _, ok := result.Request.Header[util.Authorization]
38 | assert.False(t, ok)
39 | assert.NotEmpty(t, testcase.Request.Header[util.Authorization])
40 | }
41 |
--------------------------------------------------------------------------------
/pkg/runner/kubernetes/doc.go:
--------------------------------------------------------------------------------
1 | // Package kubernetes provides a low level client for small footprint consideration
2 | package kubernetes
3 |
--------------------------------------------------------------------------------
/pkg/runner/kubernetes/verify.go:
--------------------------------------------------------------------------------
1 | package kubernetes
2 |
3 | import "github.com/expr-lang/expr"
4 |
5 | // PodValidatorFunc returns a expr for checking pod existing
6 | func PodValidatorFunc() expr.Option {
7 | return expr.Function("pod", podValidator, new(func(...string) ResourceValidator))
8 | }
9 |
10 | // KubernetesValidatorFunc returns a expr for checking the generic Kubernetes resources
11 | func KubernetesValidatorFunc() expr.Option {
12 | return expr.Function("k8s", resourceValidator, new(func(interface{}, ...string) ResourceValidator))
13 | }
14 |
--------------------------------------------------------------------------------
/pkg/runner/monitor/dumy_monitor.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package monitor
18 |
19 | import (
20 | context "context"
21 |
22 | grpc "google.golang.org/grpc"
23 | )
24 |
25 | type dumyMonitor struct{}
26 |
27 | func NewDumyMonitor() MonitorClient {
28 | return &dumyMonitor{}
29 | }
30 |
31 | func (m *dumyMonitor) GetResourceUsage(ctx context.Context, in *Target, opts ...grpc.CallOption) (*ResourceUsage, error) {
32 | return &ResourceUsage{}, nil
33 | }
34 |
--------------------------------------------------------------------------------
/pkg/runner/monitor/monitor.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option go_package = "github.com/linuxsuren/api-testing/pkg/runner/monitor";
4 |
5 | package monitor;
6 |
7 | service Monitor {
8 | rpc GetResourceUsage(Target) returns (ResourceUsage) {}
9 | }
10 |
11 | message ResourceUsage {
12 | uint64 memory = 1;
13 | uint64 cpu = 2;
14 | }
15 |
16 | message Target {
17 | string name = 1;
18 | }
19 |
--------------------------------------------------------------------------------
/pkg/runner/reporter_discard.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package runner
18 |
19 | type discardTestReporter struct {
20 | }
21 |
22 | // NewDiscardTestReporter creates a test reporter which discard everything
23 | func NewDiscardTestReporter() TestReporter {
24 | return &discardTestReporter{}
25 | }
26 |
27 | // PutRecord does nothing
28 | func (r *discardTestReporter) PutRecord(*ReportRecord) {
29 | // Do nothing which is the design purpose
30 | }
31 |
32 | // GetAllRecords does nothing
33 | func (r *discardTestReporter) GetAllRecords() []*ReportRecord {
34 | return nil
35 | }
36 |
37 | // ExportAllReportResults does nothing
38 | func (r *discardTestReporter) ExportAllReportResults() (ReportResultSlice, error) {
39 | return nil, nil
40 | }
41 |
42 | func (r *discardTestReporter) GetResourceUsage() []ResourceUsage {
43 | return nil
44 | }
45 |
--------------------------------------------------------------------------------
/pkg/runner/reporter_discard_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package runner_test
18 |
19 | import (
20 | "testing"
21 |
22 | "github.com/linuxsuren/api-testing/pkg/runner"
23 | "github.com/stretchr/testify/assert"
24 | )
25 |
26 | func TestDiscardTestReporter(t *testing.T) {
27 | reporter := runner.NewDiscardTestReporter()
28 | assert.NotNil(t, reporter)
29 | assert.Nil(t, reporter.GetAllRecords())
30 |
31 | result, err := reporter.ExportAllReportResults()
32 | assert.Nil(t, result)
33 | assert.Nil(t, err)
34 |
35 | reporter.PutRecord(&runner.ReportRecord{})
36 | }
37 |
--------------------------------------------------------------------------------
/pkg/runner/testdata/generic_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "linuxsuren",
3 | "number": 1
4 | }
5 |
--------------------------------------------------------------------------------
/pkg/runner/testdata/json-result.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "Name": "foo",
4 | "API": "api",
5 | "Count": 3,
6 | "Average": 3,
7 | "Max": 4,
8 | "Min": 2,
9 | "QPS": 0,
10 | "Error": 0,
11 | "LastErrorMessage": ""
12 | },
13 | {
14 | "Name": "bar",
15 | "API": "api",
16 | "Count": 3,
17 | "Average": 3,
18 | "Max": 4,
19 | "Min": 2,
20 | "QPS": 0,
21 | "Error": 0,
22 | "LastErrorMessage": ""
23 | }
24 | ]
--------------------------------------------------------------------------------
/pkg/runner/writer.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package runner
18 |
19 | import (
20 | "io"
21 |
22 | "github.com/linuxsuren/api-testing/pkg/apispec"
23 | )
24 |
25 | // ReportResultWriter is the interface of the report writer
26 | type ReportResultWriter interface {
27 | Output([]ReportResult) error
28 | WithAPICoverage(apiCoverage apispec.APICoverage) ReportResultWriter
29 | WithResourceUsage([]ResourceUsage) ReportResultWriter
30 | GetWriter() io.Writer
31 | }
32 |
--------------------------------------------------------------------------------
/pkg/runner/writer_templates/example.tpl:
--------------------------------------------------------------------------------
1 | [
2 | {{range $index, $result := .}}
3 | {
4 | "Name": "{{$result.Name}}",
5 | "API": "{{$result.API}}",
6 | "Count": {{$result.Count}},
7 | "Average": "{{$result.Average}}",
8 | "Max": "{{$result.Max}}",
9 | "Min": "{{$result.Min}}",
10 | "QPS": {{$result.QPS}},
11 | "Error": {{$result.Error}},
12 | "LastErrorMessage": "{{$result.LastErrorMessage}}"
13 | }
14 | {{end}}
15 | ]
16 |
--------------------------------------------------------------------------------
/pkg/runner/writer_templates/server.go:
--------------------------------------------------------------------------------
1 | package writer_templates
2 |
3 | import (
4 | "context"
5 | "log"
6 | )
7 |
8 | type ReportServer struct {
9 | UnimplementedReportWriterServer
10 | }
11 |
12 | func (s *ReportServer) SendReportResult(ctx context.Context, req *ReportResultRepeated) (*Empty, error) {
13 | // print received data
14 | for _, result := range req.Data {
15 | log.Printf("Received report: %+v", result)
16 | }
17 | return &Empty{}, nil
18 | }
19 |
--------------------------------------------------------------------------------
/pkg/runner/writer_templates/writer.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option go_package = "github.com/linuxsuren/api-testing/pkg/runner/writer_templates";
4 |
5 | package writer_templates;
6 |
7 | service ReportWriter{
8 | rpc SendReportResult(ReportResultRepeated)returns(Empty);
9 | }
10 |
11 | message ReportResultRepeated{
12 | repeated ReportResult data= 1;
13 | }
14 |
15 | message ReportResult {
16 | string Name = 1;
17 | string API = 2;
18 | int32 Count = 3;
19 | int64 Average = 4;
20 | int64 Max = 5;
21 | int64 Min = 6;
22 | int32 QPS = 7;
23 | int32 Error = 8;
24 | string LastErrorMessage = 9;
25 | }
26 |
27 | message Empty {
28 | }
--------------------------------------------------------------------------------
/pkg/secret/types.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package secret
18 |
19 | type Secret struct {
20 | Name string
21 | Value string
22 | }
23 |
24 | type SecretGetter interface {
25 | GetSecret(name string) (secret Secret, err error)
26 | }
27 |
--------------------------------------------------------------------------------
/pkg/server/constant.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package server
18 |
19 | import _ "embed"
20 |
21 | const (
22 | HeaderKeyStoreName = "X-Store-Name"
23 | )
24 |
25 | //go:embed server.swagger.json
26 | var SwaggerJSON []byte
27 |
--------------------------------------------------------------------------------
/pkg/server/data/headers.yaml:
--------------------------------------------------------------------------------
1 | - key: User-Agent
2 | value: ""
3 | - key: Content-Type
4 | value: application/json
5 | - key: Content-Type
6 | value: application/json-patch+json
7 | - key: Content-Type
8 | value: application/merge-patch+json
9 | - key: Content-Type
10 | value: application/apply-patch+yaml
11 | - key: Content-Type
12 | value: application/x-www-form-urlencoded
13 | - key: Content-Type
14 | value: multipart/form-data
15 | - key: Accept-Language
16 | value: en-US,en;q=0.5
17 | - key: Authorization
18 | value: "Bearer token"
19 | - key: Authorization
20 | value: Basic {{ base64 "admin:123456" }}
21 |
--------------------------------------------------------------------------------
/pkg/server/fake.yaml:
--------------------------------------------------------------------------------
1 | #!api-testing
2 | # yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-schema.json
3 | name: fake
4 |
--------------------------------------------------------------------------------
/pkg/server/gateway.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package server
17 |
18 | import (
19 | "context"
20 | "net/http"
21 |
22 | "google.golang.org/grpc/metadata"
23 | )
24 |
25 | // MetadataStoreFunc is a function that extracts metadata from a request.
26 | func MetadataStoreFunc(ctx context.Context, r *http.Request) (md metadata.MD) {
27 | store := r.Header.Get(HeaderKeyStoreName)
28 | md = metadata.Pairs(HeaderKeyStoreName, store)
29 |
30 | if auth := r.Header.Get("X-Auth"); auth != "" {
31 | md.Set("Auth", auth)
32 | }
33 | return
34 | }
35 |
--------------------------------------------------------------------------------
/pkg/server/gateway_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package server
17 |
18 | import (
19 | "context"
20 | "net/http"
21 | "testing"
22 |
23 | "github.com/stretchr/testify/assert"
24 | )
25 |
26 | func TestMetadataStoreFunc(t *testing.T) {
27 | req, err := http.NewRequest(http.MethodGet, "/", nil)
28 | req.Header.Set(HeaderKeyStoreName, "test")
29 | if !assert.NoError(t, err) {
30 | return
31 | }
32 |
33 | md := MetadataStoreFunc(context.TODO(), req)
34 | assert.Equal(t, "test", md.Get(HeaderKeyStoreName)[0])
35 | }
36 |
--------------------------------------------------------------------------------
/pkg/server/proto.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package server
17 |
18 | import _ "embed"
19 |
20 | // GetProtos returns the proto files.
21 | // Key is filename, value is the content.
22 | func GetProtos() map[string]string {
23 | return map[string]string{
24 | "server.proto": protoServer,
25 | }
26 | }
27 |
28 | //go:embed server.proto
29 | var protoServer string
30 |
--------------------------------------------------------------------------------
/pkg/server/proto_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package server_test
17 |
18 | import (
19 | "testing"
20 |
21 | "github.com/linuxsuren/api-testing/pkg/server"
22 | "github.com/stretchr/testify/assert"
23 | )
24 |
25 | func TestGetProtos(t *testing.T) {
26 | protos := server.GetProtos()
27 | assert.Equal(t, 1, len(protos))
28 |
29 | exists := []string{"server.proto"}
30 | for _, key := range exists {
31 | content, ok := protos[key]
32 | assert.True(t, ok)
33 | assert.NotEmpty(t, content)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/pkg/server/testdata/postman.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "_postman_id": "0da1f6bf-fdbb-46a5-ac46-873564e2259c",
4 | "name": "NewCollection",
5 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
6 | "_exporter_id": "6795120",
7 | "_collection_link": "https://www.postman.com/ks-devops/workspace/kubesphere-devops/collection/6795120-0da1f6bf-fdbb-46a5-ac46-873564e2259c?action=share&creator=6795120&source=collection_link"
8 | },
9 | "item": [
10 | {
11 | "name": "New Request",
12 | "protocolProfileBehavior": {
13 | "disableBodyPruning": true
14 | },
15 | "request": {
16 | "method": "GET",
17 | "header": [
18 | {
19 | "key": "key",
20 | "value": "value",
21 | "description": "description",
22 | "type": "text"
23 | }
24 | ],
25 | "body": {
26 | "mode": "raw",
27 | "raw": "{}"
28 | },
29 | "url": {
30 | "raw": "http://localhost?key=value"
31 | }
32 | }
33 | }
34 | ]
35 | }
--------------------------------------------------------------------------------
/pkg/server/testdata/simple.yaml:
--------------------------------------------------------------------------------
1 | name: simple
2 | api: http://foo
3 | items:
4 | - name: get
5 | request:
6 | api: http://foo
7 | header:
8 | key: value
9 | - name: query
10 | request:
11 | api: /
--------------------------------------------------------------------------------
/pkg/server/testdata/simple_testcase.yaml:
--------------------------------------------------------------------------------
1 | name: get
2 | request:
3 | api: http://bar
--------------------------------------------------------------------------------
/pkg/server/testdata/swagger.json:
--------------------------------------------------------------------------------
1 | {
2 | "swagger": "2.0",
3 | "info": {
4 | "description": "sample",
5 | "title": "sample",
6 | "version": "1.0.0"
7 | },
8 | "paths": {
9 | "/api/v1/users": {
10 | "get": {
11 | "summary": "summary",
12 | "operationId": "getUsers"
13 | },
14 | "post": {
15 | "summary": "summary",
16 | "operationId": "createUser"
17 | }
18 | },
19 | "/api/v1/users/{user}": {
20 | "get": {
21 | "summary": "summary",
22 | "operationId": "getUser"
23 | },
24 | "delete": {
25 | "summary": "summary",
26 | "operationId": "deleteUser"
27 | },
28 | "put": {
29 | "summary": "summary",
30 | "operationId": "updateUser"
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/pkg/service/runner.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package service
17 |
18 | import (
19 | "fmt"
20 | "net/http"
21 | )
22 |
23 | // WebRunnerHandler accepts the HTTP requests and run the testSuite
24 | func WebRunnerHandler(w http.ResponseWriter, r *http.Request,
25 | params map[string]string) {
26 | testSuite := params["suite"]
27 | testCase := params["case"]
28 |
29 | fmt.Println(testSuite, testCase)
30 | fmt.Println(r.URL.Query())
31 | }
32 |
--------------------------------------------------------------------------------
/pkg/service/sbom.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package service
18 |
19 | import (
20 | "net/http"
21 |
22 | ui "github.com/linuxsuren/api-testing/console/atest-ui"
23 | "github.com/linuxsuren/api-testing/pkg/util"
24 | "github.com/linuxsuren/api-testing/pkg/version"
25 | )
26 |
27 | func SBomHandler(w http.ResponseWriter, r *http.Request,
28 | params map[string]string) {
29 | modMap, err := version.GetModVersions("")
30 | packageJSON := ui.GetPackageJSON()
31 | if err != nil {
32 | w.WriteHeader(http.StatusInternalServerError)
33 | w.Write([]byte(err.Error()))
34 | } else {
35 | data := make(map[string]interface{})
36 | data["js"] = packageJSON
37 | data["go"] = modMap
38 | util.WriteAsJSON(data, w)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/pkg/testing/doc.go:
--------------------------------------------------------------------------------
1 | // Package testing provide the test case functions
2 | package testing
3 |
--------------------------------------------------------------------------------
/pkg/testing/testdata/duplicated-names.yaml:
--------------------------------------------------------------------------------
1 | name: duplicated names
2 | items:
3 | - name: projects
4 | request:
5 | api: https://foo
6 | - name: projects
7 | request:
8 | api: https://foo
--------------------------------------------------------------------------------
/pkg/testing/testdata/generic_body.json:
--------------------------------------------------------------------------------
1 | {"name": "{{.Name}}"}
2 |
--------------------------------------------------------------------------------
/pkg/testing/testdata/invalid-testcase.yaml:
--------------------------------------------------------------------------------
1 | name: projects
2 | request:
3 | api: https://foo
4 | expect:
5 | statuscode: 200
--------------------------------------------------------------------------------
/pkg/testing/testdata/stores.yaml:
--------------------------------------------------------------------------------
1 | stores:
2 | - name: db
3 | owner: ""
4 | kind:
5 | name: database
6 | url: localhost:7071
7 | enabled: true
8 | description: ""
9 | url: localhost:4000
10 | username: root
11 | password: ""
12 | readonly: false
13 | disabled: false
14 | properties:
15 | database: test
16 | - name: git
17 | owner: rick
18 | kind:
19 | name: ""
20 | url: ""
21 | enabled: false
22 | description: ""
23 | url: ""
24 | username: ""
25 | password: ""
26 | readonly: false
27 | disabled: false
28 | properties: {}
29 | plugins:
30 | - name: database
31 | url: localhost:7071
32 | enabled: true
33 |
--------------------------------------------------------------------------------
/pkg/testing/testdata/testcase.yaml:
--------------------------------------------------------------------------------
1 | name: projects
2 | request:
3 | api: https://foo
4 | expect:
5 | statusCode: 200
--------------------------------------------------------------------------------
/pkg/util/base64.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package util
18 |
19 | const (
20 | ImageBase64Prefix = "data:image/png;base64,"
21 | PDFBase64Prefix = "data:application/pdf;base64,"
22 | ZIPBase64Prefix = "data:application/zip;base64,"
23 | BinaryBase64Prefix = "data:application/octet-stream;base64,"
24 | )
25 |
--------------------------------------------------------------------------------
/pkg/util/error.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package util
17 |
18 | import (
19 | "fmt"
20 | "net/http"
21 | )
22 |
23 | // OKOrErrorMessage returns OK or error message
24 | func OKOrErrorMessage(err error) string {
25 | return OrErrorMessage(err, "OK")
26 | }
27 |
28 | // OrErrorMessage returns error message or message
29 | func OrErrorMessage(err error, message string) string {
30 | if err != nil {
31 | return err.Error()
32 | }
33 | return message
34 | }
35 |
36 | func ErrorWrap(err error, msg string, args ...interface{}) error {
37 | if err != nil {
38 | err = fmt.Errorf(msg, args...)
39 | }
40 | return err
41 | }
42 |
43 | // IgnoreErrServerClosed ignores ErrServerClosed
44 | func IgnoreErrServerClosed(err error) error {
45 | if err == http.ErrServerClosed {
46 | return nil
47 | }
48 | return err
49 | }
50 |
--------------------------------------------------------------------------------
/pkg/util/error_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package util_test
17 |
18 | import (
19 | "errors"
20 | "net/http"
21 | "testing"
22 |
23 | "github.com/linuxsuren/api-testing/pkg/util"
24 | "github.com/stretchr/testify/assert"
25 | )
26 |
27 | func TestOkOrErrorMessage(t *testing.T) {
28 | assert.Equal(t, "OK", util.OKOrErrorMessage(nil))
29 | assert.Equal(t, "test", util.OKOrErrorMessage(errors.New("test")))
30 | }
31 |
32 | func TestIgnoreErrServerClosed(t *testing.T) {
33 | assert.Nil(t, util.IgnoreErrServerClosed(nil))
34 | assert.Nil(t, util.IgnoreErrServerClosed(http.ErrServerClosed))
35 | assert.Error(t, util.IgnoreErrServerClosed(errors.New("test")))
36 | }
37 |
--------------------------------------------------------------------------------
/pkg/util/expand.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package util
17 |
18 | import (
19 | "regexp"
20 | "strings"
21 | )
22 |
23 | // Expand the text with brace syntax.
24 | // Such as: /home/{good,bad} -> [/home/good, /home/bad]
25 | func Expand(text string) (result []string) {
26 | reg := regexp.MustCompile(`\{.*\}`)
27 | if reg.MatchString(text) {
28 | brace := reg.FindString(text)
29 | braceItem := strings.TrimPrefix(brace, "{")
30 | braceItem = strings.TrimSuffix(braceItem, "}")
31 | items := strings.Split(braceItem, ",")
32 |
33 | for _, item := range items {
34 | result = append(result, strings.ReplaceAll(text, brace, item))
35 | }
36 | } else {
37 | result = []string{text}
38 | }
39 | return
40 | }
41 |
--------------------------------------------------------------------------------
/pkg/util/expand_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package util_test
17 |
18 | import (
19 | "testing"
20 |
21 | "github.com/linuxsuren/api-testing/pkg/util"
22 | "github.com/stretchr/testify/assert"
23 | )
24 |
25 | func TestExpand(t *testing.T) {
26 | tests := []struct {
27 | name string
28 | input string
29 | expect []string
30 | }{{
31 | name: "without brace",
32 | input: "/home",
33 | expect: []string{"/home"},
34 | }, {
35 | name: "with brace",
36 | input: "/home/{good,bad}",
37 | expect: []string{"/home/good", "/home/bad"},
38 | }, {
39 | name: "with brace, have suffix",
40 | input: "/home/{good,bad}.yaml",
41 | expect: []string{"/home/good.yaml", "/home/bad.yaml"},
42 | }}
43 | for _, tt := range tests {
44 | t.Run(tt.name, func(t *testing.T) {
45 | got := util.Expand(tt.input)
46 | assert.Equal(t, tt.expect, got, got)
47 | })
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/pkg/util/home/common_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2025 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package home
18 |
19 | import (
20 | "github.com/stretchr/testify/assert"
21 | "testing"
22 | )
23 |
24 | func TestGetUserBinDir(t *testing.T) {
25 | assert.Contains(t, GetUserConfigDir(), "atest")
26 | assert.Contains(t, GetUserBinDir(), "bin")
27 | assert.Contains(t, GetUserDataDir(), "data")
28 | assert.Contains(t, GetExtensionSocketPath("fake"), "fake.sock")
29 | }
30 |
--------------------------------------------------------------------------------
/pkg/util/home/darwin.go:
--------------------------------------------------------------------------------
1 | //go:build darwin
2 |
3 | /*
4 | Copyright 2024 API Testing Authors.
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | */
18 |
19 | package home
20 |
21 | import (
22 | "bytes"
23 | "os/exec"
24 | "strings"
25 | )
26 |
27 | func Dir() string {
28 | // First prefer the HOME environmental variable
29 | if home := getCommonHomeDir(); home != "" {
30 | return home
31 | }
32 |
33 | var stdout bytes.Buffer
34 | cmd := exec.Command("sh", "-c", `dscl -q . -read /Users/"$(whoami)" NFSHomeDirectory | sed 's/^[^ ]*: //'`)
35 | cmd.Stdout = &stdout
36 | if err := cmd.Run(); err == nil {
37 | result := strings.TrimSpace(stdout.String())
38 | if result != "" {
39 | return result
40 | }
41 | }
42 |
43 | return getHomeDirViaShell()
44 | }
45 |
--------------------------------------------------------------------------------
/pkg/util/home/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | // Package home provides a way to get the home directory of OS
18 | // Copied from https://github.com/mitchellh/go-homedir
19 | package home
20 |
--------------------------------------------------------------------------------
/pkg/util/home/windows.go:
--------------------------------------------------------------------------------
1 | //go:build windows
2 |
3 | /*
4 | Copyright 2024 API Testing Authors.
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | */
18 |
19 | package home
20 |
21 | import (
22 | "os"
23 | )
24 |
25 | func Dir() string {
26 | // First prefer the HOME environmental variable
27 | if home := getCommonHomeDir(); home != "" {
28 | return home
29 | }
30 |
31 | // Prefer standard environment variable USERPROFILE
32 | if home := os.Getenv("USERPROFILE"); home != "" {
33 | return home
34 | }
35 |
36 | drive := os.Getenv("HOMEDRIVE")
37 | path := os.Getenv("HOMEPATH")
38 | home := drive + path
39 | if drive == "" || path == "" {
40 | return ""
41 | }
42 |
43 | return home
44 | }
45 |
--------------------------------------------------------------------------------
/pkg/util/map.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package util
17 |
18 | // Keys returns a list of keys
19 | func Keys[T interface{}](data map[string]T) (keys []string) {
20 | keys = make([]string, len(data))
21 | index := 0
22 | for k := range data {
23 | keys[index] = k
24 | index++
25 | }
26 | return
27 | }
28 |
--------------------------------------------------------------------------------
/pkg/util/map_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package util_test
17 |
18 | import (
19 | "testing"
20 |
21 | "github.com/linuxsuren/api-testing/pkg/util"
22 | "github.com/stretchr/testify/assert"
23 | )
24 |
25 | func TestKeys(t *testing.T) {
26 | t.Run("normal", func(t *testing.T) {
27 | assert.ElementsMatch(t, []string{"foo", "bar"},
28 | util.Keys(map[string]interface{}{"foo": "xx", "bar": "xx"}))
29 | })
30 | }
31 |
--------------------------------------------------------------------------------
/pkg/util/net.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2024 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package util
17 |
18 | import (
19 | "net"
20 | "strings"
21 | )
22 |
23 | // GetPort returns the port of the listener
24 | func GetPort(listener net.Listener) string {
25 | if listener == nil {
26 | return ""
27 | }
28 | addr := listener.Addr().String()
29 | items := strings.Split(addr, ":")
30 | return items[len(items)-1]
31 | }
32 |
--------------------------------------------------------------------------------
/pkg/util/path.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package util
17 |
18 | import "os"
19 |
20 | // PathExists checks if the target path exist or not
21 | func PathExists(path string) (ok bool, err error) {
22 | _, err = os.Stat(path)
23 | if err != nil && os.IsNotExist(err) {
24 | ok = false
25 | err = nil
26 | } else {
27 | ok = true
28 | }
29 | return
30 | }
31 |
--------------------------------------------------------------------------------
/pkg/util/path_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package util_test
17 |
18 | import (
19 | "os"
20 | "path"
21 | "testing"
22 | "time"
23 |
24 | "github.com/linuxsuren/api-testing/pkg/util"
25 | "github.com/stretchr/testify/assert"
26 | )
27 |
28 | func TestPathExists(t *testing.T) {
29 | t.Run("exist", func(t *testing.T) {
30 | ok, err := util.PathExists(os.TempDir())
31 | assert.True(t, ok)
32 | assert.NoError(t, err)
33 | })
34 |
35 | t.Run("not exist", func(t *testing.T) {
36 | ok, err := util.PathExists(path.Join(os.TempDir(), time.Now().String()))
37 | assert.False(t, ok)
38 | assert.NoError(t, err)
39 | })
40 | }
41 |
--------------------------------------------------------------------------------
/pkg/util/rand_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 The Kubernetes Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package util
18 |
19 | import (
20 | "strings"
21 | "testing"
22 | )
23 |
24 | const (
25 | maxRangeTestCount = 500
26 | testStringLength = 32
27 | )
28 |
29 | func TestString(t *testing.T) {
30 | valid := "bcdfghjklmnpqrstvwxz2456789"
31 | for _, l := range []int{0, 1, 2, 10, 123} {
32 | s := String(l)
33 | if len(s) != l {
34 | t.Errorf("expected string of size %d, got %q", l, s)
35 | }
36 | for _, c := range s {
37 | if !strings.ContainsRune(valid, c) {
38 | t.Errorf("expected valid characters, got %v", c)
39 | }
40 | }
41 | }
42 | }
43 |
44 | func BenchmarkRandomStringGeneration(b *testing.B) {
45 | b.ResetTimer()
46 | var s string
47 | for i := 0; i < b.N; i++ {
48 | s = String(testStringLength)
49 | }
50 | b.StopTimer()
51 | if len(s) == 0 {
52 | b.Fatal(s)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/pkg/util/slice.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package util
17 |
18 | func RemoeEmptyFromSlice(items []string) []string {
19 | for i := 0; i < len(items); {
20 | if items[i] == "" {
21 | items = append(items[:i], items[i+1:]...)
22 | i++
23 | }
24 | }
25 | return items
26 | }
27 |
--------------------------------------------------------------------------------
/pkg/util/slice_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package util_test
17 |
18 | import (
19 | "testing"
20 |
21 | "github.com/linuxsuren/api-testing/pkg/util"
22 | "github.com/stretchr/testify/assert"
23 | )
24 |
25 | func TestRemoeEmptyFromSlice(t *testing.T) {
26 | assert.Equal(t, []string{"a", "b"}, util.RemoeEmptyFromSlice([]string{"", "a", "", "b"}))
27 | assert.Equal(t, []string{}, util.RemoeEmptyFromSlice([]string{""}))
28 | }
29 |
--------------------------------------------------------------------------------
/pkg/util/testdata/fuzz/FuzzEmptyThenDefault/a5d1a2517d90f203:
--------------------------------------------------------------------------------
1 | go test fuzz v1
2 | string("\u00a0")
3 | string("0")
4 |
--------------------------------------------------------------------------------
/pkg/util/testdata/fuzz/FuzzZeroThenDefault/26953e5f8daf8575:
--------------------------------------------------------------------------------
1 | go test fuzz v1
2 | int(59)
3 | int(69)
4 |
--------------------------------------------------------------------------------
/pkg/util/testdata/test.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LinuxSuRen/api-testing/b572c780dd0d16bcdb78341cccf3dbe64d78e71b/pkg/util/testdata/test.zip
--------------------------------------------------------------------------------
/pkg/version/constants.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | // Package version provides the version access of this app
17 | package version
18 |
19 | import "fmt"
20 |
21 | const UnknownVersion = "unknown"
22 |
23 | // should be injected during the build process
24 | var version string
25 | var date string
26 | var commit string
27 |
28 | // GetVersion returns the version
29 | func GetVersion() string {
30 | if version == "" {
31 | return UnknownVersion
32 | }
33 | return version
34 | }
35 |
36 | func GetDate() string {
37 | return date
38 | }
39 |
40 | func GetCommit() string {
41 | return commit
42 | }
43 |
44 | func GetDetailedVersion() string {
45 | return fmt.Sprintf(`Version: %s
46 | Date: %s`, version, date)
47 | }
48 |
--------------------------------------------------------------------------------
/pkg/version/constants_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 API Testing Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package version_test
17 |
18 | import (
19 | "testing"
20 |
21 | "github.com/linuxsuren/api-testing/pkg/version"
22 | "github.com/stretchr/testify/assert"
23 | )
24 |
25 | func TestVersion(t *testing.T) {
26 | ver := version.GetVersion()
27 | assert.Equal(t, "unknown", ver)
28 | }
29 |
--------------------------------------------------------------------------------
/pkg/version/testdata/go.mod.txt:
--------------------------------------------------------------------------------
1 | module github.com/linuxsuren/api-testing
2 |
3 | go 1.22.4
4 |
5 | require (
6 | github.com/a/b v0.0.1
7 | )
8 |
--------------------------------------------------------------------------------
/qodana.yaml:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------------------------------------#
2 | # Qodana analysis is configured by qodana.yaml file #
3 | # https://www.jetbrains.com/help/qodana/qodana-yaml.html #
4 | #-------------------------------------------------------------------------------#
5 | version: "1.0"
6 |
7 | #Specify inspection profile for code analysis
8 | profile:
9 | name: qodana.starter
10 |
11 | #Enable inspections
12 | #include:
13 | # - name:
14 |
15 | #Disable inspections
16 | #exclude:
17 | # - name:
18 | # paths:
19 | # -
20 |
21 | #Execute shell command before Qodana execution (Applied in CI/CD pipeline)
22 | #bootstrap: sh ./prepare-qodana.sh
23 |
24 | #Install IDE plugins before Qodana execution (Applied in CI/CD pipeline)
25 | #plugins:
26 | # - id: #(plugin id can be found at https://plugins.jetbrains.com)
27 |
28 | #Specify Qodana linter for analysis (Applied in CI/CD pipeline)
29 | linter: jetbrains/qodana-go:latest
30 |
--------------------------------------------------------------------------------
/sample/constants.go:
--------------------------------------------------------------------------------
1 | package sample
2 |
3 | import _ "embed"
4 |
5 | //go:embed testsuite-gitlab.yaml
6 | var TestSuiteGitLab string
7 |
--------------------------------------------------------------------------------
/sample/grpc-sample.yaml:
--------------------------------------------------------------------------------
1 | #!api-testing
2 | # yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-schema.json
3 | # see also https://github.com/LinuxSuRen/api-testing
4 | name: grpc-sample
5 | api: 127.0.0.1:7070
6 | spec:
7 | grpc:
8 | import:
9 | - ./pkg/server
10 | protofile: server.proto
11 | serverReflection: true
12 | items:
13 | - name: GetVersion
14 | request:
15 | api: /server.Runner/GetVersion
16 | - name: FunctionsQuery
17 | request:
18 | api: /server.Runner/FunctionsQuery
19 | body: |
20 | {
21 | "name": "hello"
22 | }
23 | expect:
24 | body: |
25 | {
26 | "data": [
27 | {
28 | "key": "hello",
29 | "value": "func() string"
30 | }
31 | ]
32 | }
33 | - name: FunctionsQueryStream
34 | request:
35 | api: /server.Runner/FunctionsQueryStream
36 | body: |
37 | [
38 | {
39 | "name": "hello"
40 | },
41 | {
42 | "name": "title"
43 | }
44 | ]
45 | expect:
46 | verify:
47 | - "len(data) == 2"
48 |
--------------------------------------------------------------------------------
/sample/testsuite-gitee.yaml:
--------------------------------------------------------------------------------
1 | #!api-testing
2 | # yaml-language-server: $schema=/workspace/api-testing/docs/api-testing-schema.json
3 | name: Gitee
4 | api: https://gitee.com/api/v5
5 | param:
6 | repo: api-testing
7 | items:
8 | - name: stargazers
9 | before:
10 | items:
11 | - sleep(1)
12 | request:
13 | api: /repos/linuxsuren/{{.param.repo}}/stargazers
14 | expect:
15 | verify:
16 | - len(["data"]) > 0
17 | - name: branches
18 | request:
19 | api: /repos/linuxsuren/{{.param.repo}}/branches
20 | expect:
21 | verify:
22 | - len(filter(data, .name == "master")) == 1
23 | - name: branch
24 | request:
25 | api: /repos/linuxsuren/{{.param.repo}}/branches/{{(index .branches 0).name}}
26 | expect:
27 | verify:
28 | - len(data.name) > 0
29 | spec:
30 | kind: swagger
31 | url: https://gitee.com/api/v5/doc_json
--------------------------------------------------------------------------------
/sample/testsuite-gitlab.yaml:
--------------------------------------------------------------------------------
1 | #!api-testing
2 | # yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-schema.json
3 | # https://docs.gitlab.com/ee/api/api_resources.html
4 | name: Gitlab
5 | api: https://gitlab.com/api/v4
6 | param:
7 | user: linuxsuren
8 | items:
9 | - name: projects
10 | request:
11 | api: /projects
12 | expect:
13 | statusCode: 200
14 | schema: |
15 | {
16 | "type": "array"
17 | }
18 | before:
19 | items:
20 | - "sleep(1)"
21 | after:
22 | items:
23 | - "sleep(1)"
24 | - name: project
25 | request:
26 | api: /projects/{{int64 (index .projects 0).id}}
27 | expect:
28 | statusCode: 200
29 | # bodyFieldsExpect:
30 | # http_url_to_repo: https://gitlab.com/senghuy/sr_chea_senghuy_spring_homework001.git
31 | verify:
32 | - data.http_url_to_repo startsWith "https"
33 | - data.http_url_to_repo endsWith ".git"
34 | - data.default_branch == 'master' or data.default_branch == 'main'
35 | - len(data.topics) >= 0
36 |
--------------------------------------------------------------------------------
/sonar-project.properties:
--------------------------------------------------------------------------------
1 | sonar.exclusions=extensions/store-etcd/remote/*.pb.go, pkg/server/*.pb.go, pkg/server/*.pb.gw.go, pkg/testing/remote/*.pb.go
2 | sonar.cpd.exclusions=extensions/store-etcd/remote/*.pb.go, pkg/server/*.pb.go, pkg/server/*.pb.gw.go, pkg/testing/remote/*.pb.go
--------------------------------------------------------------------------------
/tools/SECURITY.md:
--------------------------------------------------------------------------------
1 | ## Reporting Security Issues
2 |
3 | The API Testing commnity takes a rigorous standpoint in annihilating the security issues in its software projects. API Testing is highly sensitive and forthcoming to issues pertaining to its features and functionality.
4 |
5 | ## REPORTING VULNERABILITY
6 |
7 | If you have apprehensions regarding API Testing's security or you discover vulnerability or potential threat, don’t hesitate to get in touch with the api-testing Security Team by dropping a mail at [api-testing-security@googlegroups.com](mailto:api-testing-security@googlegroups.com). In the mail, specify the description of the issue or potential threat. You are also urged to recommend the way to reproduce and replicate the issue. The API Testing community will get back to you after assessing and analysing the findings.
8 |
9 | PLEASE PAY ATTENTION to report the security issue on the security email before disclosing it on public domain.
10 |
11 | ## VULNERABILITY HANDLING
12 |
13 | An overview of the vulnerability handling process is:
14 |
15 | The reporter reports the vulnerability privately to API Testing community.
16 | The appropriate project's security team works privately with the reporter to resolve the vulnerability.
17 | A new release of the API Testing product concerned is made that includes the fix.
18 | The vulnerability is publically announced.
19 |
--------------------------------------------------------------------------------
/tools/github-actions/setup-deps/action.yml:
--------------------------------------------------------------------------------
1 | name: setup-deps
2 | description: Install host system dependencies
3 |
4 | runs:
5 | using: composite
6 | steps:
7 | - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
8 | with:
9 | go-version: 1.23.x
10 | cache: true
11 |
--------------------------------------------------------------------------------
/tools/make/desktop.mk:
--------------------------------------------------------------------------------
1 | # Building docs makefile defined.
2 | #
3 | # All make targets related to docs are defined in this file.
4 |
5 | ##@ Desktop
6 |
7 | .PHONY: desktop-start
8 | desktop-start: ## Start Electron Desktop
9 | desktop-start:
10 | cd console/atest-desktop && npm run start
11 |
12 | desktop-package: ## Package Electron Desktop
13 | desktop-package: build.embed.ui copy-to-desktop
14 | cd console/atest-desktop && npm i && npm run package
15 |
16 | desktop-make: build.embed.ui ## Make an Electron Desktop
17 | cd console/atest-desktop && npm i && npm run make
18 |
19 | desktop-publish: build.embed.ui ## Publish the Electron Desktop
20 | cd console/atest-desktop && npm i && npm run publish
21 |
22 | desktop-test: ## Run unit tests of the Electron Desktop
23 | cd console/atest-desktop && npm i && npm test
24 |
--------------------------------------------------------------------------------
/tools/make/docs.mk:
--------------------------------------------------------------------------------
1 | # Building docs makefile defined.
2 | #
3 | # All make targets related to docs are defined in this file.
4 |
5 | DOCS_OUTPUT_DIR := site/public
6 |
7 | ##@ Docs
8 |
9 | .PHONY: docs
10 | docs: docs.clean
11 | @$(LOG_TARGET)
12 | cd $(ROOT_DIR)/docs/site && npm install
13 | cd $(ROOT_DIR)/docs/site && npm run build:production
14 |
15 | .PHONY: check-links
16 | check-links: ## Check for broken links in the docs.
17 | check-links: docs-check-links
18 |
19 |
20 | .PHONY: docs-check-links
21 | docs-check-links:
22 | @$(LOG_TARGET)
23 | # Check for broken links
24 | npm install -g linkinator@6.0.4
25 | # https://github.com/JustinBeckwith/linkinator?tab=readme-ov-file#command-usage
26 | linkinator docs/site/public -r --concurrency 25 -s "github.com _print v0.0.1"
27 |
28 | # Docs site, make by hexo.
29 |
30 | .PHONY: docs-serve
31 | docs-serve: ## Start API Testing Site Locally.
32 | @$(LOG_TARGET)
33 | cd $(ROOT_DIR)/docs/site && npm run serve
34 |
35 | .PHONY: docs-clean
36 | docs-clean: ## Remove all files that are created during builds.
37 | docs-clean: docs.clean
38 |
39 | .PHONY: docs.clean
40 | docs.clean:
41 | @$(LOG_TARGET)
42 | rm -rf $(DOCS_OUTPUT_DIR)
43 | rm -rf docs/site/node_modules
44 | rm -rf docs/site/resources
45 | rm -f docs/site/package-lock.json
46 | rm -f docs/site/.hugo_build.lock
47 |
--------------------------------------------------------------------------------
/tools/make/env.mk:
--------------------------------------------------------------------------------
1 | # A wrapper to hold common environment variables used in other make wrappers
2 | #
3 | # This file does not contain any specific make targets.
4 |
5 | # Docker variables
6 |
7 | HELM_VERSION ?= v0.0.3
8 |
9 | # Docker repo
10 | REGISTRY ?= docker.io
11 |
12 | REGISTRY_NAMESPACE ?= linuxsuren
13 |
14 | # Set image tools
15 | IMAGE_TOOL ?= docker
16 |
17 | TOOLEXEC ?= #-toolexec="skywalking-go-agent"
18 |
19 | GOPROXY ?= direct
20 |
21 | TAG ?= ${REV}
22 |
23 | FRONT_RUNTIMES ?= npm
24 |
--------------------------------------------------------------------------------
/tools/make/helm.mk:
--------------------------------------------------------------------------------
1 | # A wrapper to manage helm charts
2 | #
3 | # All make targets related to helmß are defined in this file.
4 |
5 | include tools/make/env.mk
6 |
7 | OCI_REGISTRY ?= oci://${REGISTRY}/${REGISTRY_NAMESPACE}
8 |
9 | CHART_NAME ?= api-testing
10 | CHART_VERSION ?= ${HELM_VERSION}
11 |
12 | ##@ Helm
13 |
14 | .PHONY: helm-pkg
15 | helm-pkg: ## Package API Testing helm chart.
16 | helm-pkg: helm-dev-update
17 | @$(LOG_TARGET)
18 | # e.g. api-testing-v0.0.3-helm.tgz
19 | helm package helm/${CHART_NAME} --version ${CHART_VERSION}-helm --app-version ${CHART_VERSION} --destination ${OUTPUT_DIR}/charts/
20 |
21 | .PHONY: helm-push
22 | helm-push:
23 | helm-push: ## Push API Testing helm chart to OCI registry.
24 | @$(LOG_TARGET)
25 | helm push ${OUTPUT_DIR}/charts/${CHART_NAME}-${CHART_VERSION}-helm.tgz ${OCI_REGISTRY}
26 |
27 | .PHONY: helm-lint
28 | helm-lint: ## Helm lint API Testing helm chart.
29 | helm-lint: helm-dev-update
30 | helm lint helm/${CHART_NAME}
31 |
32 | helm-dev-update:
33 | helm-dev-update:
34 | helm dep update helm/${CHART_NAME}
35 |
--------------------------------------------------------------------------------
/tools/make/image.mk:
--------------------------------------------------------------------------------
1 | # A wrapper to build and push docker image
2 | #
3 | # All make targets related to docker image are defined in this file.
4 |
5 | include tools/make/env.mk
6 |
7 |
8 | # Determine image files by looking into ./Dockerfile
9 | IMAGES_DIR ?= $(wildcard ${ROOT_DIR}tools/docker/*)
10 | # Determine images names by stripping out the dir names
11 | IMAGES ?= api-testing
12 | IMAGE_NAME ?= ${REGISTRY}/${REGISTRY_NAMESPACE}/${IMAGES}:${TAG}
13 |
14 | ifeq (${IMAGES},)
15 | $(error Could not determine IMAGES, set ROOT_DIR or run in source dir)
16 | endif
17 |
18 | .PHONY: image.build
19 | image.build: $(addprefix image.build., $(IMAGES))
20 |
21 | .PHONY: image.build.%
22 | # Maybe can use: image.build.%: go.build.$(GOOS)_$(GOARCH).%
23 | # then to move binary file to docker context.
24 | image.build.%:
25 | @$(LOG_TARGET)
26 | @$(call log, "Building image $(GOOS)-$(GOARCH) $(IMAGES):$(TAG)")
27 | ${IMAGE_TOOL} build -f $(ROOT_DIR)/Dockerfile \
28 | -t ${IMAGE_NAME} . \
29 | --build-arg GOPROXY=${GOPROXY} \
30 | --build-arg VERSION=$(TAG)
31 |
32 | .PHONY: run.image
33 | run.image:
34 | @$(LOG_TARGET)
35 | ${IMAGE_TOOL} run -p 7070:7070 -p 8080:8080 ${IMAGE_NAME}
36 |
37 | ##@ Image
38 |
39 | .PHONY: image
40 | image: ## Build docker images for host platform. See Option PLATFORM and IMAGES.
41 | image: image.build
42 |
43 | .PHONY: run-container
44 | run-container: ## Run the docker container for the image. See Option IMAGES and TAG.
45 | run-container: run.image
46 |
--------------------------------------------------------------------------------
/tools/make/lint.mk:
--------------------------------------------------------------------------------
1 | # A wrapper to do lint checks
2 | #
3 | # All make targets related to lint are defined in this file.
4 |
5 | ##@ Lint
6 |
7 | GITHUB_ACTION ?=
8 |
9 | .PHONY: lint
10 | lint: ## Run all linter of code sources, including golint, yamllint.
11 |
12 | # lint-deps is run separately in CI to separate the tooling install logs from the actual output logs generated
13 | # by the lint tooling.
14 | .PHONY: lint-deps
15 | lint-deps: ## Everything necessary to lint
16 |
17 | GOLANGCI_LINT_FLAGS ?= $(if $(GITHUB_ACTION),--out-format=github-actions)
18 |
19 | .PHONY: lint.golint
20 | lint: lint.golint
21 | lint-deps: $(tools/golangci-lint)
22 | lint.golint: $(tools/golangci-lint)
23 | @$(LOG_TARGET)
24 | $(tools/golangci-lint) run $(GOLANGCI_LINT_FLAGS) --build-tags=e2e,celvalidation --config=tools/linter/golangci-lint/.golangci.yml
25 |
26 | .PHONY: lint.yamllint
27 | lint: lint.yamllint
28 | lint-deps: $(tools/yamllint)
29 | lint.yamllint: $(tools/yamllint)
30 | @$(LOG_TARGET)
31 | $(tools/yamllint) --config-file=tools/linter/yamllint/.yamllint $$(git ls-files :*.yml :*.yaml | xargs -L1 dirname | sort -u)
32 |
--------------------------------------------------------------------------------
/tools/make/test.mk:
--------------------------------------------------------------------------------
1 | # A wrapper to test.
2 | #
3 | # All make targets related to e2e,full test are defined in this file.
4 |
5 | .PHONY: test.e2e
6 | test.e2e:
7 | cd e2e && ./start.sh && ./start.sh compose-k8s.yaml && ./start.sh compose-external.yaml
8 |
9 | .PHONY: test.fuzz
10 | test.fuzz:
11 | cd pkg/util && go test -fuzz FuzzZeroThenDefault -fuzztime 6s
12 |
13 | ##@ Other Test
14 |
15 | .PHONY: test-e2e
16 | test-e2e: ## Run e2e tests
17 | test-e2e: test.e2e
18 |
19 | .PHONY: full-test-e2e
20 | full-test-e2e: ## Build image then run e2e tests
21 | full-test-e2e:
22 | TAG=master REGISTRY=ghcr.io make image test-e2e
23 |
24 | .PHONY: test-fuzz
25 | test-fuzz: ## Run fuzz tests
26 | test-fuzz: test.fuzz
27 |
--------------------------------------------------------------------------------
/tools/src/golangci-lint/pin.go:
--------------------------------------------------------------------------------
1 | //go:build pin
2 | // +build pin
3 |
4 | /*
5 | Copyright 2024 API Testing Authors.
6 |
7 | Licensed under the Apache License, Version 2.0 (the "License");
8 | you may not use this file except in compliance with the License.
9 | You may obtain a copy of the License at
10 |
11 | http://www.apache.org/licenses/LICENSE-2.0
12 |
13 | Unless required by applicable law or agreed to in writing, software
14 | distributed under the License is distributed on an "AS IS" BASIS,
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | See the License for the specific language governing permissions and
17 | limitations under the License.
18 | */
19 |
20 | package ignore
21 |
22 | import _ "github.com/golangci/golangci-lint/cmd/golangci-lint"
23 |
--------------------------------------------------------------------------------
/tools/src/yamllint/requirements.txt:
--------------------------------------------------------------------------------
1 | yamllint==1.35.1
2 |
--------------------------------------------------------------------------------