Skip to content

Commit

Permalink
test: corner case coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
jeevatkm committed Nov 2, 2024
1 parent 18e3dda commit f50470e
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 14 deletions.
6 changes: 4 additions & 2 deletions middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"mime/multipart"
"net/http"
"net/url"
"os"
"path/filepath"
"reflect"
"strconv"
Expand Down Expand Up @@ -585,6 +584,7 @@ func handleRequestBody(c *Client, r *Request) error {
} else if xmlKey == encKey {
if inferKind(r.Body) != reflect.Struct {
releaseBuffer(r.bodyBuf)
r.bodyBuf = nil
return ErrUnsupportedRequestBodyKind
}
}
Expand All @@ -593,10 +593,12 @@ func handleRequestBody(c *Client, r *Request) error {
encFunc, found := c.inferContentTypeEncoder(contentType, encKey)
if !found {
releaseBuffer(r.bodyBuf)
r.bodyBuf = nil
return fmt.Errorf("resty: content-type encoder not found for %s", contentType)
}
if err := encFunc(r.bodyBuf, r.Body); err != nil {
releaseBuffer(r.bodyBuf)
r.bodyBuf = nil
return err
}
}
Expand All @@ -617,7 +619,7 @@ func saveResponseIntoFile(c *Client, res *Response) error {
return err
}

outFile, err := os.Create(file)
outFile, err := createFile(file)
if err != nil {
return err
}
Expand Down
47 changes: 47 additions & 0 deletions middleware_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
// Copyright (c) 2015-present Jeevanandam M ([email protected]), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
// SPDX-License-Identifier: MIT

package resty

import (
"bytes"
"encoding/json"
"errors"
"io"
"mime"
"mime/multipart"
"net/http"
"net/url"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
Expand Down Expand Up @@ -1037,3 +1045,42 @@ func Benchmark_parseRequestBody_MultiPart(b *testing.B) {
}
}
}

func TestSaveResponseToFile(t *testing.T) {
c := dcnl()
tempDir := t.TempDir()

errDirMsg := "test dir error"
mkdirAll = func(_ string, _ os.FileMode) error {
return errors.New(errDirMsg)
}
errFileMsg := "test file error"
createFile = func(_ string) (*os.File, error) {
return nil, errors.New(errFileMsg)
}
t.Cleanup(func() {
mkdirAll = os.MkdirAll
createFile = os.Create
})

// dir create error
req1 := c.R()
req1.SetOutputFile(filepath.Join(tempDir, "new-res-dir", "sample.txt"))
err1 := saveResponseIntoFile(c, &Response{Request: req1})
assertEqual(t, errDirMsg, err1.Error())

// file create error
req2 := c.R()
req2.SetOutputFile(filepath.Join(tempDir, "sample.txt"))
err2 := saveResponseIntoFile(c, &Response{Request: req2})
assertEqual(t, errFileMsg, err2.Error())
}

func TestMiddlewareCoverage(t *testing.T) {
c := dcnl()

req1 := c.R()
req1.URL = "//invalid-url .local"
err1 := createHTTPRequest(c, req1)
assertEqual(t, true, strings.Contains(err1.Error(), "invalid character"))
}
7 changes: 3 additions & 4 deletions multipart.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) 2015-present Jeevanandam M ([email protected]), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
// SPDX-License-Identifier: MIT

package resty

Expand Down Expand Up @@ -98,10 +99,8 @@ func (mf *MultipartField) openFileIfRequired() error {
return err
}

fileStat, err := file.Stat()
if err != nil {
return err
}
// if file open is success, stat will succeed
fileStat, _ := file.Stat()

mf.Reader = file
mf.FileSize = fileStat.Size()
Expand Down
26 changes: 26 additions & 0 deletions multipart_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) 2015-present Jeevanandam M ([email protected]), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
// SPDX-License-Identifier: MIT

package resty

Expand All @@ -9,6 +10,7 @@ import (
"context"
"errors"
"io/fs"
"mime/multipart"
"net/http"
"net/url"
"os"
Expand Down Expand Up @@ -475,6 +477,30 @@ func TestMultipartReaderErrors(t *testing.T) {
})
}

type mpWriterError struct{}

func (mwe *mpWriterError) Write(p []byte) (int, error) {
return 0, errors.New("multipart write error")
}

func TestRequest_writeFormData(t *testing.T) {
mw := multipart.NewWriter(&mpWriterError{})

c := dcnl()
req1 := c.R().SetFormData(map[string]string{
"name1": "value1",
"name2": "value2",
})

err1 := req1.writeFormData(mw)
assertNotNil(t, err1)
assertEqual(t, "multipart write error", err1.Error())

err2 := createMultipart(mw, req1)
assertNotNil(t, err2)
assertEqual(t, "multipart write error", err2.Error())
}

type returnValueTestWriter struct {
}

Expand Down
2 changes: 1 addition & 1 deletion request.go
Original file line number Diff line number Diff line change
Expand Up @@ -1320,7 +1320,7 @@ func (r *Request) Execute(method, url string) (res *Response, err error) {
}

r.sendLoadBalancerFeedback(res, err)
releaseBuffer(r.bodyBuf)
backToBufPool(r.bodyBuf)
return
}

Expand Down
15 changes: 12 additions & 3 deletions request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2167,9 +2167,6 @@ func TestRequestPanicContext(t *testing.T) {

//lint:ignore SA1012 test case nil check
_ = c.R().WithContext(nil)

//lint:ignore SA1012 test case nil check
_ = c.R().Clone(nil)
}

// This test methods exist for test coverage purpose
Expand Down Expand Up @@ -2213,6 +2210,18 @@ func TestRequestSettingsCoverage(t *testing.T) {
invalidJsonBytes := []byte(`{\" \": "value here"}`)
result := jsonIndent(invalidJsonBytes)
assertEqual(t, string(invalidJsonBytes), string(result))

defer func() {
if rec := recover(); rec != nil {
if err, ok := rec.(error); ok {
assertEqual(t, true, strings.Contains(err.Error(), "resty: Request.Clone nil context"))
}
}
}()
r6 := c.R()
//lint:ignore SA1012 test case nil check
r62 := r6.Clone(nil)
assertEqual(t, nil, r62.ctx)
}

func TestRequestDataRace(t *testing.T) {
Expand Down
18 changes: 14 additions & 4 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,15 @@ func firstNonEmpty(v ...string) string {
return ""
}

var (
mkdirAll = os.MkdirAll
createFile = os.Create
)

func createDirectory(dir string) (err error) {
if _, err = os.Stat(dir); err != nil {
if os.IsNotExist(err) {
if err = os.MkdirAll(dir, 0755); err != nil {
if err = mkdirAll(dir, 0755); err != nil {
return
}
}
Expand Down Expand Up @@ -184,14 +189,19 @@ func acquireBuffer() *bytes.Buffer {
buf.Reset()
return buf
}
bufPool.Put(buf)
return new(bytes.Buffer)
}

func releaseBuffer(buf *bytes.Buffer) {
if buf != nil {
if buf.Len() == 0 {
buf.Reset()
}
buf.Reset()
bufPool.Put(buf)
}
}

func backToBufPool(buf *bytes.Buffer) {
if buf != nil {
bufPool.Put(buf)
}
}
Expand Down
16 changes: 16 additions & 0 deletions util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"bytes"
"errors"
"net/url"
"os"
"path/filepath"
"strings"
"testing"
)
Expand Down Expand Up @@ -108,6 +110,20 @@ func TestRestyErrorFuncs(t *testing.T) {
assertEqual(t, "inner error 1", e.Error())
}

func Test_createDirectory(t *testing.T) {
errMsg := "test dir error"
mkdirAll = func(path string, perm os.FileMode) error {
return errors.New(errMsg)
}
t.Cleanup(func() {
mkdirAll = os.MkdirAll
})

tempDir := filepath.Join(t.TempDir(), "test-dir")
err := createDirectory(tempDir)
assertEqual(t, errMsg, err.Error())
}

// This test methods exist for test coverage purpose
// to validate the getter and setter
func TestUtilMiscTestCoverage(t *testing.T) {
Expand Down

0 comments on commit f50470e

Please sign in to comment.