2025-04-01 10:38:02 +09:00

104 lines
2.5 KiB
Go

package objectstorage
import (
"bytes"
"context"
"io"
"math"
"mime/multipart"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/stretchr/testify/require"
)
func TestPresignedURLUpload(t *testing.T) {
t.Parallel()
t.Run("successfully send data to the server", func(t *testing.T) {
t.Parallel()
ctx := context.Background()
key := "snapshot/uuid/key"
data := "sending-some-data"
reader := bytes.NewBufferString(data)
qs, err := url.ParseQuery("one=a&two=b")
require.NoError(t, err)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
contentType := r.Header.Get("Content-Type")
_, boundary, found := strings.Cut(contentType, "boundary=")
require.True(t, found)
mpr := multipart.NewReader(r.Body, boundary)
form, err := mpr.ReadForm(math.MaxInt64)
require.NoError(t, err)
require.NotNil(t, form)
require.NotNil(t, form.Value)
require.Equal(t, key, form.Value["key"][0])
require.Equal(t, qs.Get("one"), form.Value["one"][0])
require.Equal(t, qs.Get("two"), form.Value["two"][0])
require.Len(t, form.File, 1)
require.Len(t, form.File["file"], 1)
fileHeader := form.File["file"][0]
require.Equal(t, "file", fileHeader.Filename)
file, err := fileHeader.Open()
require.NoError(t, err)
contents, err := io.ReadAll(file)
require.NoError(t, err)
require.EqualValues(t, data, string(contents))
require.NoError(t, file.Close())
}))
t.Cleanup(server.Close)
s3 := NewS3(http.DefaultClient, tracing.NewNoopTracerService())
presignedURL, err := url.Parse(server.URL + "?" + qs.Encode())
require.NoError(t, err)
err = s3.PresignedURLUpload(ctx, presignedURL.String(), key, reader)
require.NoError(t, err)
})
t.Run("when the request to the server returns an error, it is propagated", func(t *testing.T) {
t.Parallel()
ctx := context.Background()
key := "snapshot/uuid/key"
data := "sending-some-data"
reader := bytes.NewBufferString(data)
body := "test error"
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(`{"message": "` + body + `}`))
}))
t.Cleanup(server.Close)
s3 := NewS3(http.DefaultClient, tracing.NewNoopTracerService())
presignedURL, err := url.Parse(server.URL)
require.NoError(t, err)
err = s3.PresignedURLUpload(ctx, presignedURL.String(), key, reader)
require.Error(t, err)
require.Contains(t, err.Error(), body)
})
}