diff --git a/README.md b/README.md index b65ab1d..7408521 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,8 @@ const s3_cli = s3.connect("http://s3.neofs.devenv:8080") ``` ### Methods +- `createBucket(bucket, params)`. Returns dictionary with `success` boolean flag + and `error` string. The `params` is a dictionary (e.g. `{acl:'private',lock_enabled:'true',location_constraint:'ru'}`) - `put(bucket, key, payload)`. Returns dictionary with `success` boolean flag and `error` string. - `get(bucket, key)`. Returns dictionary with `success` boolean flag and `error` diff --git a/examples/s3.js b/examples/s3.js index 32c6dbe..0ad3d49 100644 --- a/examples/s3.js +++ b/examples/s3.js @@ -1,4 +1,5 @@ -import { uuidv4 } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js'; +import {uuidv4} from 'https://jslib.k6.io/k6-utils/1.2.0/index.js'; +import {fail} from 'k6' import s3 from 'k6/x/neofs/s3'; const payload = open('../go.sum', 'b'); @@ -7,13 +8,26 @@ const s3_cli = s3.connect("http://s3.neofs.devenv:8080") export const options = { stages: [ - { duration: '30s', target: 10 }, + {duration: '30s', target: 10}, ], }; +export function setup() { + const params = { + acl: 'private', + lock_enabled: 'true', + location_constraint: 'ru' + } + + const res = s3_cli.createBucket(bucket, params) + if (!res.success) { + fail(res.error) + } +} + export default function () { const key = uuidv4(); if (s3_cli.put(bucket, key, payload).success) { - s3_cli.get(bucket, key ) + s3_cli.get(bucket, key) } } diff --git a/go.mod b/go.mod index af62c40..3028f95 100644 --- a/go.mod +++ b/go.mod @@ -6,9 +6,11 @@ require ( github.com/aws/aws-sdk-go-v2 v1.16.3 github.com/aws/aws-sdk-go-v2/config v1.15.5 github.com/aws/aws-sdk-go-v2/service/s3 v1.26.9 + github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf github.com/google/uuid v1.2.0 github.com/nspcc-dev/neo-go v0.98.2 github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.3.0.20220504192402-12ea1e8d740f + github.com/nspcc-dev/tzhash v1.5.2 go.k6.io/k6 v0.38.2 ) @@ -29,7 +31,6 @@ require ( github.com/aws/smithy-go v1.11.2 // indirect github.com/btcsuite/btcd v0.22.0-beta // indirect github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect - github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf // indirect github.com/fatih/color v1.13.0 // indirect github.com/go-sourcemap/sourcemap v2.1.4-0.20211119122758-180fcef48034+incompatible // indirect github.com/golang/protobuf v1.5.2 // indirect @@ -42,7 +43,6 @@ require ( github.com/nspcc-dev/neofs-api-go/v2 v2.12.1 // indirect github.com/nspcc-dev/neofs-crypto v0.3.0 // indirect github.com/nspcc-dev/rfc6979 v0.2.0 // indirect - github.com/nspcc-dev/tzhash v1.5.2 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect github.com/pkg/errors v0.9.1 // indirect diff --git a/internal/s3/client.go b/internal/s3/client.go index f4db08e..19803ab 100644 --- a/internal/s3/client.go +++ b/internal/s3/client.go @@ -3,10 +3,12 @@ package s3 import ( "bytes" "context" + "strconv" "time" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/s3/types" "github.com/dop251/goja" "github.com/nspcc-dev/xk6-neofs/internal/stats" "go.k6.io/k6/js/modules" @@ -28,6 +30,11 @@ type ( Success bool Error string } + + CreateBucketResponse struct { + Success bool + Error string + } ) func (c *Client) Put(bucket, key string, payload goja.ArrayBuffer) PutResponse { @@ -80,3 +87,38 @@ func (c *Client) Get(bucket, key string) GetResponse { stats.ReportDataReceived(c.vu, float64(sz)) return GetResponse{Success: true} } + +func (c *Client) CreateBucket(bucket string, params map[string]string) CreateBucketResponse { + stats.Report(c.vu, createBucketTotal, 1) + + var err error + var lockEnabled bool + if lockEnabledStr, ok := params["lock_enabled"]; ok { + if lockEnabled, err = strconv.ParseBool(lockEnabledStr); err != nil { + stats.Report(c.vu, createBucketFails, 1) + return CreateBucketResponse{Success: false, Error: "invalid lock_enabled params"} + } + } + + var bucketConfiguration *types.CreateBucketConfiguration + if locationConstraint, ok := params["location_constraint"]; ok { + bucketConfiguration = &types.CreateBucketConfiguration{ + LocationConstraint: types.BucketLocationConstraint(locationConstraint), + } + } + + start := time.Now() + _, err = c.cli.CreateBucket(c.vu.Context(), &s3.CreateBucketInput{ + Bucket: aws.String(bucket), + ACL: types.BucketCannedACL(params["acl"]), + CreateBucketConfiguration: bucketConfiguration, + ObjectLockEnabledForBucket: lockEnabled, + }) + if err != nil { + stats.Report(c.vu, createBucketFails, 1) + return CreateBucketResponse{Success: false, Error: err.Error()} + } + + stats.Report(c.vu, createBucketDuration, metrics.D(time.Since(start))) + return CreateBucketResponse{Success: true} +} diff --git a/internal/s3/s3.go b/internal/s3/s3.go index 9ac7c65..1bd36ee 100644 --- a/internal/s3/s3.go +++ b/internal/s3/s3.go @@ -24,8 +24,9 @@ var ( _ modules.Instance = &S3{} _ modules.Module = &RootModule{} - objPutTotal, objPutFails, objPutDuration *metrics.Metric - objGetTotal, objGetFails, objGetDuration *metrics.Metric + objPutTotal, objPutFails, objPutDuration *metrics.Metric + objGetTotal, objGetFails, objGetDuration *metrics.Metric + createBucketTotal, createBucketFails, createBucketDuration *metrics.Metric ) func init() { @@ -75,6 +76,10 @@ func (s *S3) Connect(endpoint string) (*Client, error) { objGetFails, _ = registry.NewMetric("aws_obj_get_fails", metrics.Counter) objGetDuration, _ = registry.NewMetric("aws_obj_get_duration", metrics.Trend, metrics.Time) + createBucketTotal, _ = registry.NewMetric("aws_create_bucket_total", metrics.Counter) + createBucketFails, _ = registry.NewMetric("aws_create_bucket_fails", metrics.Counter) + createBucketDuration, _ = registry.NewMetric("aws_create_bucket_duration", metrics.Trend, metrics.Time) + return &Client{ vu: s.vu, cli: cli,