forked from Deuxfleurs/mknet
214 lines
4.9 KiB
Go
214 lines
4.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"log"
|
|
"math/rand"
|
|
"net/http"
|
|
"net/http/httptrace"
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/minio/minio-go/v7"
|
|
"github.com/minio/minio-go/v7/pkg/credentials"
|
|
|
|
"github.com/aws/aws-sdk-go-v2/aws"
|
|
"github.com/aws/aws-sdk-go-v2/config"
|
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
|
)
|
|
|
|
type PRNG struct {
|
|
rem int64
|
|
}
|
|
|
|
func (r *PRNG) Read(p []byte) (n int, err error) {
|
|
//log.Printf("rem=%d, buf=%d\n", r.rem, len(p))
|
|
if int64(len(p)) > r.rem {
|
|
p = p[:r.rem]
|
|
}
|
|
|
|
if int64(len(p)) > r.rem {
|
|
log.Fatal("LOGIC ERROR")
|
|
}
|
|
|
|
n, err = rand.Read(p)
|
|
if err != nil {
|
|
return
|
|
}
|
|
r.rem -= int64(n)
|
|
if r.rem <= 0 {
|
|
err = io.EOF
|
|
//log.Printf("PRNG file has been fully read. rem=%d,n=%d,err=%s\n", r.rem, n, err)
|
|
}
|
|
return
|
|
}
|
|
|
|
func main() {
|
|
var err error
|
|
fmt.Printf("nanoseconds\n")
|
|
|
|
// Initial setup
|
|
_, isSSL := os.LookupEnv("SSL")
|
|
opts := minio.Options{
|
|
Creds: credentials.NewStaticV4(os.Getenv("AWS_ACCESS_KEY_ID"), os.Getenv("AWS_SECRET_ACCESS_KEY"), ""),
|
|
Secure: isSSL,
|
|
}
|
|
|
|
if region, ok := os.LookupEnv("AWS_REGION"); ok {
|
|
opts.Region = region
|
|
}
|
|
|
|
if _, ok := os.LookupEnv("SSL_INSECURE"); ok {
|
|
opts.Transport = &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
|
|
}
|
|
|
|
size := 1 * 1024 * 1024 // 1 MB
|
|
if env_size, ok := os.LookupEnv("SIZE"); ok {
|
|
size, err = strconv.Atoi(env_size)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
return
|
|
}
|
|
}
|
|
|
|
repeat := 60
|
|
if env_repeat, ok := os.LookupEnv("REPEAT"); ok {
|
|
repeat, err = strconv.Atoi(env_repeat)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
return
|
|
}
|
|
}
|
|
|
|
mc, err := minio.New(os.Getenv("ENDPOINT"), &opts)
|
|
if err != nil {
|
|
log.Fatal("failed connect", err)
|
|
return
|
|
}
|
|
|
|
// AWS SDK stuff
|
|
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
|
|
return aws.Endpoint{
|
|
PartitionID: "aws",
|
|
URL: "http://"+os.Getenv("ENDPOINT"),
|
|
SigningRegion: region,
|
|
}, nil
|
|
})
|
|
|
|
|
|
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithEndpointResolverWithOptions(customResolver))
|
|
if err != nil {
|
|
log.Fatalf("failed to load configuration, %v", err)
|
|
}
|
|
|
|
// Create an Amazon S3 service client
|
|
client := s3.NewFromConfig(cfg, func(opts *s3.Options) {
|
|
opts.UsePathStyle = true
|
|
})
|
|
|
|
|
|
// Create Bucket
|
|
buck := uuid.New().String()
|
|
err = mc.MakeBucket(context.Background(), buck, minio.MakeBucketOptions{})
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
return
|
|
}
|
|
|
|
// Send an object
|
|
prng := new(PRNG)
|
|
prng.rem = int64(size)
|
|
|
|
|
|
key := uuid.New().String()
|
|
_, err = mc.PutObject(
|
|
context.Background(),
|
|
buck,
|
|
key,
|
|
prng,
|
|
int64(size),
|
|
minio.PutObjectOptions{ContentType: "application/octet-stream"},
|
|
)
|
|
if err != nil {
|
|
log.Fatal("unable to upload our test object")
|
|
return
|
|
}
|
|
|
|
for i := 0; i < repeat; i++ {
|
|
// Now, try to fetch it *repeat* times (assume no caching)
|
|
var elapsed time.Duration
|
|
|
|
var start time.Time
|
|
trace := &httptrace.ClientTrace{
|
|
GotFirstResponseByte: func() { elapsed = time.Since(start) },
|
|
}
|
|
|
|
start = time.Now()
|
|
/*object, err := mc.GetObject(httptrace.WithClientTrace(context.Background(), trace), buck, key, minio.GetObjectOptions{})
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
return
|
|
}*/
|
|
|
|
out, err := client.GetObject(httptrace.WithClientTrace(context.Background(), trace), &s3.GetObjectInput {
|
|
Bucket: aws.String(buck),
|
|
Key: aws.String(key),
|
|
})
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
return
|
|
}
|
|
object := out.Body
|
|
|
|
|
|
if _, err = io.Copy(ioutil.Discard, object) ; err != nil {
|
|
log.Fatal("failed getobject: ", err)
|
|
return
|
|
}
|
|
|
|
fmt.Printf("%v\n", elapsed.Nanoseconds())
|
|
//time.Sleep(10 * time.Second)
|
|
}
|
|
}
|
|
|
|
/*
|
|
func timeGet(url string) {
|
|
req, _ := http.NewRequest("GET", url, nil)
|
|
|
|
var start, connect, dns, tlsHandshake time.Time
|
|
|
|
trace := &httptrace.ClientTrace{
|
|
DNSStart: func(dsi httptrace.DNSStartInfo) { dns = time.Now() },
|
|
DNSDone: func(ddi httptrace.DNSDoneInfo) {
|
|
fmt.Printf("DNS Done: %v\n", time.Since(dns))
|
|
},
|
|
|
|
TLSHandshakeStart: func() { tlsHandshake = time.Now() },
|
|
TLSHandshakeDone: func(cs tls.ConnectionState, err error) {
|
|
fmt.Printf("TLS Handshake: %v\n", time.Since(tlsHandshake))
|
|
},
|
|
|
|
ConnectStart: func(network, addr string) { connect = time.Now() },
|
|
ConnectDone: func(network, addr string, err error) {
|
|
fmt.Printf("Connect time: %v\n", time.Since(connect))
|
|
},
|
|
|
|
GotFirstResponseByte: func() {
|
|
fmt.Printf("Time from start to first byte: %v\n", time.Since(start))
|
|
},
|
|
}
|
|
|
|
req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
|
|
start = time.Now()
|
|
if _, err := http.DefaultTransport.RoundTrip(req); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
fmt.Printf("Total time: %v\n", time.Since(start))
|
|
}
|
|
*/
|