diff --git a/cmd/server.go b/cmd/server.go index 9960a82..2d818d5 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -42,6 +42,7 @@ import ( "github.com/linuxsuren/api-testing/pkg/downloader" "github.com/linuxsuren/api-testing/pkg/logging" "github.com/linuxsuren/api-testing/pkg/mock" + atestoauth "github.com/linuxsuren/api-testing/pkg/oauth" template "github.com/linuxsuren/api-testing/pkg/render" "github.com/linuxsuren/api-testing/pkg/server" "github.com/linuxsuren/api-testing/pkg/service" @@ -50,7 +51,6 @@ import ( "github.com/linuxsuren/api-testing/pkg/testing/remote" "github.com/linuxsuren/api-testing/pkg/util" fakeruntime "github.com/linuxsuren/go-fake-runtime" - atestoauth "github.com/linuxsuren/api-testing/pkg/oauth" "github.com/linuxsuren/oauth-hub" "github.com/prometheus/client_golang/prometheus" @@ -469,7 +469,7 @@ func debugHandler(mux *runtime.ServeMux, remoteServer server.RunnerServer) { Name: sub, }) if err == nil { - w.Header().Set("Content-Type", "application/octet-stream") + w.Header().Set(util.ContentType, "application/octet-stream") w.Write(data.Data) } else { w.WriteHeader(http.StatusBadRequest) diff --git a/console/atest-ui/package-lock.json b/console/atest-ui/package-lock.json index 09fb49e..43b6755 100644 --- a/console/atest-ui/package-lock.json +++ b/console/atest-ui/package-lock.json @@ -8,6 +8,7 @@ "name": "atest-ui", "version": "v0.0.14", "dependencies": { + "@vueuse/core": "^10.11.0", "codemirror": "^5.65.17", "diff-match-patch": "^1.0.5", "element-plus": "^2.3.7", diff --git a/console/atest-ui/src/views/TestCase.vue b/console/atest-ui/src/views/TestCase.vue index 6a6be43..881f72a 100644 --- a/console/atest-ui/src/views/TestCase.vue +++ b/console/atest-ui/src/views/TestCase.vue @@ -85,6 +85,7 @@ const parseResponseBody = (body) => { } try { + testResult.value.bodyLength = body.length testResult.value.bodyObject = JSON.parse(body) testResult.value.originBodyObject = JSON.parse(body) } catch { @@ -103,6 +104,7 @@ const handleTestResult = (e) => { if(isFilePath){ isResponseFile.value = true } else if(e.body !== ''){ + testResult.value.bodyLength = e.body.length testResult.value.bodyObject = JSON.parse(e.body); testResult.value.originBodyObject = JSON.parse(e.body); } @@ -1210,7 +1212,9 @@ Magic.Keys(() => {
+ clearable placeholder="$.key"> + +
diff --git a/console/atest-ui/src/views/types.ts b/console/atest-ui/src/views/types.ts index f25742e..49eb57c 100644 --- a/console/atest-ui/src/views/types.ts +++ b/console/atest-ui/src/views/types.ts @@ -31,6 +31,7 @@ export interface TestResult { body: string bodyObject: {} bodyText: string + bodyLength: number output: string error: string statusCode: number diff --git a/pkg/generator/curl_generator_test.go b/pkg/generator/curl_generator_test.go index be74f8f..41e0c03 100644 --- a/pkg/generator/curl_generator_test.go +++ b/pkg/generator/curl_generator_test.go @@ -63,7 +63,7 @@ func TestCurlGenerator(t *testing.T) { Request: atest.Request{ API: fooForTest, Header: map[string]string{ - "Content-Type": util.Plain, + util.ContentType: util.Plain, "Connection": "keep-alive", }, }, diff --git a/pkg/mock/in_memory.go b/pkg/mock/in_memory.go index 4e1122b..f91ae69 100644 --- a/pkg/mock/in_memory.go +++ b/pkg/mock/in_memory.go @@ -292,7 +292,7 @@ func (h *advanceHandler) handle(w http.ResponseWriter, req *http.Request) { h.item.Response.Header = make(map[string]string) } h.item.Response.Header[headerMockServer] = fmt.Sprintf("api-testing: %s", version.GetVersion()) - h.item.Response.Header["content-length"] = fmt.Sprintf("%d", len(h.item.Response.BodyData)) + h.item.Response.Header[util.ContentLength] = fmt.Sprintf("%d", len(h.item.Response.BodyData)) for k, v := range h.item.Response.Header { hv, hErr := render.Render("mock-server-header", v, &h.item) if hErr != nil { diff --git a/pkg/mock/in_memory_test.go b/pkg/mock/in_memory_test.go index d9ea791..5edfe99 100644 --- a/pkg/mock/in_memory_test.go +++ b/pkg/mock/in_memory_test.go @@ -22,6 +22,7 @@ import ( "strings" "testing" + "github.com/linuxsuren/api-testing/pkg/util" "github.com/stretchr/testify/assert" ) @@ -137,7 +138,7 @@ func TestInMemoryServer(t *testing.T) { assert.NoError(t, err) assert.Equal(t, http.StatusOK, resp.StatusCode) - assert.Equal(t, "176", resp.Header.Get("Content-Length")) + assert.Equal(t, "176", resp.Header.Get(util.ContentLength)) assert.Equal(t, "mock", resp.Header.Get("Server")) assert.NotEmpty(t, resp.Header.Get(headerMockServer)) diff --git a/pkg/runner/http.go b/pkg/runner/http.go index ae65132..766e508 100644 --- a/pkg/runner/http.go +++ b/pkg/runner/http.go @@ -22,6 +22,7 @@ import ( "fmt" "io" "net/http" + "strconv" "strings" "time" @@ -229,6 +230,16 @@ func (r *simpleTestCaseRunner) RunTestCase(testcase *testing.TestCase, dataConte return } +func ammendHeaders(headers http.Header, body []byte) { + // add content-length if it's missing + if val := headers.Get(util.ContentLength); val == "" { + headers.Add(util.ContentLength, strconv.Itoa(len(body))) + fmt.Printf("add content-length: %d\n", len(body)) + } else { + fmt.Printf("content-length already exist: %s\n", val) + } +} + func (r *simpleTestCaseRunner) GetSuggestedAPIs(suite *testing.TestSuite, api string) (result []*testing.TestCase, err error) { if suite.Spec.URL == "" || suite.Spec.Kind != "swagger" { return @@ -297,6 +308,9 @@ func (r *simpleTestCaseRunner) withResponseRecord(resp *http.Response) (response Header: make(map[string]string), Body: string(responseBodyData), } + + // add some headers for convienience + ammendHeaders(resp.Header, responseBodyData) for key := range resp.Header { r.simpleResponse.Header[key] = resp.Header.Get(key) } diff --git a/pkg/runner/http_test.go b/pkg/runner/http_test.go index 168ceb6..63918ce 100644 --- a/pkg/runner/http_test.go +++ b/pkg/runner/http_test.go @@ -628,6 +628,12 @@ func TestGenerateRandomValue(t *testing.T) { } } +func TestAmmendHeaders(t *testing.T) { + headers := http.Header{"Content-Type": []string{"application/json"}} + ammendHeaders(headers, []byte("good")) + assert.Equal(t, "4", headers.Get(util.ContentLength)) +} + const defaultSchemaForTest = `{"properties": { "name": {"type": "string"}, "age": {"type": "integer"} diff --git a/pkg/runner/writer_http.go b/pkg/runner/writer_http.go index fa645ad..5faf40d 100644 --- a/pkg/runner/writer_http.go +++ b/pkg/runner/writer_http.go @@ -27,6 +27,7 @@ import ( "os" "github.com/linuxsuren/api-testing/pkg/apispec" + "github.com/linuxsuren/api-testing/pkg/util" ) type httpResultWriter struct { @@ -118,7 +119,7 @@ func (w *httpResultWriter) Output(result []ReportResult) (err error) { } else { contentType = "application/json" } - req.Header.Set("Content-Type", contentType) + req.Header.Set(util.ContentType, contentType) var resp *http.Response if resp, err = http.DefaultClient.Do(req); err != nil { diff --git a/pkg/server/remote_server.go b/pkg/server/remote_server.go index 545467a..15548bc 100644 --- a/pkg/server/remote_server.go +++ b/pkg/server/remote_server.go @@ -295,10 +295,11 @@ func (s *server) Run(ctx context.Context, task *TestTask) (reply *TestResult, er } func handleLargeResponseBody(resp runner.SimpleResponse, suite string, caseName string) (reply runner.SimpleResponse, err error) { - const maxSize = 1024 + const maxSize = 5120 prefix := "isFilePath-" + strings.Join([]string{suite, caseName}, "-") if len(resp.Body) > maxSize { + remoteServerLogger.Logger.Info("response body is too large, will be saved to file", "size", len(resp.Body)) tmpFile, err := os.CreateTemp("", prefix+"-") defer tmpFile.Close() if err != nil { diff --git a/pkg/util/default.go b/pkg/util/default.go index 71dee28..b39d5b7 100644 --- a/pkg/util/default.go +++ b/pkg/util/default.go @@ -69,6 +69,7 @@ func GetFirstHeaderValue(header http.Header, key string) (val string) { // ContentType is the HTTP header key const ( ContentType = "Content-Type" + ContentLength = "Content-Length" ContentDisposition = "Content-Disposition" MultiPartFormData = "multipart/form-data" Form = "application/x-www-form-urlencoded"