frostfs-http-gw/uploader/multipart_test.go
Denis Kirillov 6f35d7198d [#24] Use build tags to run integration tests
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
2023-03-24 12:27:17 +03:00

163 lines
2.9 KiB
Go

//go:build !integration
package uploader
import (
"crypto/rand"
"fmt"
"io"
"mime/multipart"
"os"
"testing"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
)
func generateRandomFile(size int64) (string, error) {
file, err := os.CreateTemp("", "data")
if err != nil {
return "", err
}
_, err = io.CopyN(file, rand.Reader, size)
if err != nil {
return "", err
}
return file.Name(), file.Close()
}
func BenchmarkAll(b *testing.B) {
fileName, err := generateRandomFile(1024 * 1024 * 256)
require.NoError(b, err)
fmt.Println(fileName)
defer os.Remove(fileName)
b.Run("bare", func(b *testing.B) {
for i := 0; i < b.N; i++ {
err := bareRead(fileName)
require.NoError(b, err)
}
})
b.Run("default", func(b *testing.B) {
for i := 0; i < b.N; i++ {
err := defaultMultipart(fileName)
require.NoError(b, err)
}
})
b.Run("custom", func(b *testing.B) {
for i := 0; i < b.N; i++ {
err := customMultipart(fileName)
require.NoError(b, err)
}
})
}
func defaultMultipart(filename string) error {
r, bound := multipartFile(filename)
logger, err := zap.NewProduction()
if err != nil {
return err
}
file, err := fetchMultipartFileDefault(logger, r, bound)
if err != nil {
return err
}
_, err = io.Copy(io.Discard, file)
return err
}
func TestName(t *testing.T) {
fileName, err := generateRandomFile(1024 * 1024 * 256)
require.NoError(t, err)
fmt.Println(fileName)
defer os.Remove(fileName)
err = defaultMultipart(fileName)
require.NoError(t, err)
}
func customMultipart(filename string) error {
r, bound := multipartFile(filename)
logger, err := zap.NewProduction()
if err != nil {
return err
}
file, err := fetchMultipartFile(logger, r, bound)
if err != nil {
return err
}
_, err = io.Copy(io.Discard, file)
return err
}
func fetchMultipartFileDefault(l *zap.Logger, r io.Reader, boundary string) (MultipartFile, error) {
reader := multipart.NewReader(r, boundary)
for {
part, err := reader.NextPart()
if err != nil {
return nil, err
}
name := part.FormName()
if name == "" {
l.Debug("ignore part, empty form name")
continue
}
filename := part.FileName()
// ignore multipart/form-data values
if filename == "" {
l.Debug("ignore part, empty filename", zap.String("form", name))
continue
}
return part, nil
}
}
func bareRead(filename string) error {
r, _ := multipartFile(filename)
_, err := io.Copy(io.Discard, r)
return err
}
func multipartFile(filename string) (*io.PipeReader, string) {
r, w := io.Pipe()
m := multipart.NewWriter(w)
go func() {
defer w.Close()
defer m.Close()
part, err := m.CreateFormFile("myFile", "foo.txt")
if err != nil {
fmt.Println(err)
return
}
file, err := os.Open(filename)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
if _, err = io.Copy(part, file); err != nil {
fmt.Println(err)
return
}
}()
return r, m.Boundary()
}