mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-14 11:03:09 +02:00
276 lines
9.5 KiB
Go
276 lines
9.5 KiB
Go
package http
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/SAP/jenkins-library/pkg/log"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestSendRequest(t *testing.T) {
|
|
var passedHeaders = map[string][]string{}
|
|
passedCookies := []*http.Cookie{}
|
|
var passedUsername string
|
|
var passedPassword string
|
|
// Start a local HTTP server
|
|
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
|
passedHeaders = map[string][]string{}
|
|
if req.Header != nil {
|
|
for name, headers := range req.Header {
|
|
passedHeaders[name] = headers
|
|
}
|
|
}
|
|
passedCookies = req.Cookies()
|
|
passedUsername, passedPassword, _ = req.BasicAuth()
|
|
|
|
rw.Write([]byte("OK"))
|
|
}))
|
|
// Close the server when test finishes
|
|
defer server.Close()
|
|
|
|
tt := []struct {
|
|
client Client
|
|
method string
|
|
body io.Reader
|
|
header http.Header
|
|
cookies []*http.Cookie
|
|
expected string
|
|
}{
|
|
{client: Client{logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/http")}, method: "GET", expected: "OK"},
|
|
{client: Client{logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/http")}, method: "GET", header: map[string][]string{"Testheader": []string{"Test1", "Test2"}}, expected: "OK"},
|
|
{client: Client{logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/http")}, cookies: []*http.Cookie{{Name: "TestCookie1", Value: "TestValue1"}, {Name: "TestCookie2", Value: "TestValue2"}}, method: "GET", expected: "OK"},
|
|
{client: Client{logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/http"), username: "TestUser", password: "TestPwd"}, method: "GET", expected: "OK"},
|
|
}
|
|
|
|
for key, test := range tt {
|
|
t.Run(fmt.Sprintf("Row %v", key+1), func(t *testing.T) {
|
|
response, err := test.client.SendRequest("GET", server.URL, test.body, test.header, test.cookies)
|
|
assert.NoError(t, err, "Error occured but none expected")
|
|
content, err := ioutil.ReadAll(response.Body)
|
|
assert.Equal(t, test.expected, string(content), "Returned content incorrect")
|
|
response.Body.Close()
|
|
|
|
for k, h := range test.header {
|
|
assert.Containsf(t, passedHeaders, k, "Header %v not contained", k)
|
|
assert.Equalf(t, h, passedHeaders[k], "Header %v contains different value")
|
|
}
|
|
|
|
if len(test.cookies) > 0 {
|
|
assert.Equal(t, test.cookies, passedCookies, "Passed cookies not correct")
|
|
}
|
|
|
|
if len(test.client.username) > 0 {
|
|
assert.Equal(t, test.client.username, passedUsername)
|
|
}
|
|
|
|
if len(test.client.password) > 0 {
|
|
assert.Equal(t, test.client.password, passedPassword)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSetOptions(t *testing.T) {
|
|
c := Client{}
|
|
opts := ClientOptions{TransportTimeout: 10, MaxRequestDuration: 5, Username: "TestUser", Password: "TestPassword", Token: "TestToken", Logger: log.Entry().WithField("package", "github.com/SAP/jenkins-library/pkg/http")}
|
|
c.SetOptions(opts)
|
|
|
|
assert.Equal(t, opts.TransportTimeout, c.transportTimeout)
|
|
assert.Equal(t, opts.MaxRequestDuration, c.maxRequestDuration)
|
|
assert.Equal(t, opts.Username, c.username)
|
|
assert.Equal(t, opts.Password, c.password)
|
|
assert.Equal(t, opts.Token, c.token)
|
|
}
|
|
|
|
func TestApplyDefaults(t *testing.T) {
|
|
tt := []struct {
|
|
client Client
|
|
expected Client
|
|
}{
|
|
{client: Client{}, expected: Client{transportTimeout: 3 * time.Minute, maxRequestDuration: 0, logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/http")}},
|
|
{client: Client{transportTimeout: 10, maxRequestDuration: 5}, expected: Client{transportTimeout: 10, maxRequestDuration: 5, logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/http")}},
|
|
}
|
|
|
|
for k, v := range tt {
|
|
v.client.applyDefaults()
|
|
assert.Equal(t, v.expected, v.client, fmt.Sprintf("Run %v failed", k))
|
|
}
|
|
}
|
|
|
|
func TestUploadRequest(t *testing.T) {
|
|
var passedHeaders = map[string][]string{}
|
|
passedCookies := []*http.Cookie{}
|
|
var passedUsername string
|
|
var passedPassword string
|
|
var multipartFile multipart.File
|
|
var multipartHeader *multipart.FileHeader
|
|
var passedFileContents []byte
|
|
// Start a local HTTP server
|
|
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
|
passedHeaders = map[string][]string{}
|
|
if req.Header != nil {
|
|
for name, headers := range req.Header {
|
|
passedHeaders[name] = headers
|
|
}
|
|
}
|
|
passedCookies = req.Cookies()
|
|
passedUsername, passedPassword, _ = req.BasicAuth()
|
|
err := req.ParseMultipartForm(4096)
|
|
if err != nil {
|
|
t.FailNow()
|
|
}
|
|
multipartFile, multipartHeader, err = req.FormFile("Field1")
|
|
if err != nil {
|
|
t.FailNow()
|
|
}
|
|
defer req.Body.Close()
|
|
passedFileContents, err = ioutil.ReadAll(multipartFile)
|
|
if err != nil {
|
|
t.FailNow()
|
|
}
|
|
|
|
rw.Write([]byte("OK"))
|
|
}))
|
|
// Close the server when test finishes
|
|
defer server.Close()
|
|
|
|
testFile, err := ioutil.TempFile("", "testFileUpload")
|
|
if err != nil {
|
|
t.FailNow()
|
|
}
|
|
defer os.RemoveAll(testFile.Name()) // clean up
|
|
|
|
fileContents, err := ioutil.ReadFile(testFile.Name())
|
|
if err != nil {
|
|
t.FailNow()
|
|
}
|
|
|
|
tt := []struct {
|
|
clientOptions ClientOptions
|
|
method string
|
|
body io.Reader
|
|
header http.Header
|
|
cookies []*http.Cookie
|
|
expected string
|
|
}{
|
|
{clientOptions: ClientOptions{}, method: "PUT", expected: "OK"},
|
|
{clientOptions: ClientOptions{}, method: "POST", expected: "OK"},
|
|
{clientOptions: ClientOptions{}, method: "POST", header: map[string][]string{"Testheader": []string{"Test1", "Test2"}}, expected: "OK"},
|
|
{clientOptions: ClientOptions{}, cookies: []*http.Cookie{{Name: "TestCookie1", Value: "TestValue1"}, {Name: "TestCookie2", Value: "TestValue2"}}, method: "POST", expected: "OK"},
|
|
{clientOptions: ClientOptions{Username: "TestUser", Password: "TestPwd"}, method: "POST", expected: "OK"},
|
|
}
|
|
|
|
client := Client{logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/http")}
|
|
for key, test := range tt {
|
|
t.Run(fmt.Sprintf("UploadFile Row %v", key+1), func(t *testing.T) {
|
|
client.SetOptions(test.clientOptions)
|
|
response, err := client.UploadFile(server.URL, testFile.Name(), "Field1", test.header, test.cookies)
|
|
assert.NoError(t, err, "Error occurred but none expected")
|
|
content, err := ioutil.ReadAll(response.Body)
|
|
assert.NoError(t, err, "Error occurred but none expected")
|
|
assert.Equal(t, test.expected, string(content), "Returned content incorrect")
|
|
response.Body.Close()
|
|
|
|
assert.Equal(t, testFile.Name(), multipartHeader.Filename, "Uploaded file incorrect")
|
|
assert.Equal(t, fileContents, passedFileContents, "Uploaded file incorrect")
|
|
|
|
for k, h := range test.header {
|
|
assert.Containsf(t, passedHeaders, k, "Header %v not contained", k)
|
|
assert.Equalf(t, h, passedHeaders[k], "Header %v contains different value")
|
|
}
|
|
|
|
if len(test.cookies) > 0 {
|
|
assert.Equal(t, test.cookies, passedCookies, "Passed cookies not correct")
|
|
}
|
|
|
|
if len(client.username) > 0 {
|
|
assert.Equal(t, client.username, passedUsername)
|
|
}
|
|
|
|
if len(client.password) > 0 {
|
|
assert.Equal(t, client.password, passedPassword)
|
|
}
|
|
})
|
|
t.Run(fmt.Sprintf("UploadRequest Row %v", key+1), func(t *testing.T) {
|
|
client.SetOptions(test.clientOptions)
|
|
response, err := client.UploadRequest(test.method, server.URL, testFile.Name(), "Field1", test.header, test.cookies)
|
|
assert.NoError(t, err, "Error occurred but none expected")
|
|
content, err := ioutil.ReadAll(response.Body)
|
|
assert.NoError(t, err, "Error occurred but none expected")
|
|
assert.Equal(t, test.expected, string(content), "Returned content incorrect")
|
|
response.Body.Close()
|
|
|
|
assert.Equal(t, testFile.Name(), multipartHeader.Filename, "Uploaded file incorrect")
|
|
assert.Equal(t, fileContents, passedFileContents, "Uploaded file incorrect")
|
|
|
|
for k, h := range test.header {
|
|
assert.Containsf(t, passedHeaders, k, "Header %v not contained", k)
|
|
assert.Equalf(t, h, passedHeaders[k], "Header %v contains different value")
|
|
}
|
|
|
|
if len(test.cookies) > 0 {
|
|
assert.Equal(t, test.cookies, passedCookies, "Passed cookies not correct")
|
|
}
|
|
|
|
if len(client.username) > 0 {
|
|
assert.Equal(t, client.username, passedUsername)
|
|
}
|
|
|
|
if len(client.password) > 0 {
|
|
assert.Equal(t, client.password, passedPassword)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUploadRequestWrongMethod(t *testing.T) {
|
|
client := Client{logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/http")}
|
|
_, err := client.UploadRequest("GET", "dummy", "testFile", "Field1", nil, nil)
|
|
assert.Error(t, err, "No error occured but was expected")
|
|
}
|
|
|
|
func TestTransportTimout(t *testing.T) {
|
|
t.Run("timeout works on transport level", func(t *testing.T) {
|
|
// init
|
|
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// Sleep for longer than the configured timeout
|
|
time.Sleep(2 * time.Second)
|
|
}))
|
|
defer svr.Close()
|
|
|
|
client := Client{transportTimeout: 1 * time.Second}
|
|
buffer := bytes.Buffer{}
|
|
|
|
// test
|
|
_, err := client.SendRequest(http.MethodGet, svr.URL, &buffer, nil, nil)
|
|
// assert
|
|
if assert.Error(t, err, "expected request to fail") {
|
|
assert.Contains(t, err.Error(), "timeout awaiting response headers")
|
|
}
|
|
})
|
|
t.Run("timeout is not hit on transport level", func(t *testing.T) {
|
|
// init
|
|
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// Sleep for less than the configured timeout
|
|
time.Sleep(1 * time.Second)
|
|
}))
|
|
defer svr.Close()
|
|
|
|
client := Client{transportTimeout: 2 * time.Second}
|
|
buffer := bytes.Buffer{}
|
|
// test
|
|
_, err := client.SendRequest(http.MethodGet, svr.URL, &buffer, nil, nil)
|
|
// assert
|
|
assert.NoError(t, err)
|
|
})
|
|
}
|