Skip to content

Commit 3d1e11b

Browse files
Updated UserInfo method to accept a stats flag.
Updated integration tests to allow for uploading random file to seed statistics, which unfortunately requires another dep.
1 parent 72fd18b commit 3d1e11b

9 files changed

+286
-84
lines changed

adminapi_integration_test.go

+137-22
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,20 @@ package radosgwadmin
44

55
import (
66
"context"
7+
"io"
78
"io/ioutil"
9+
"math/rand"
810
"os"
911
"strconv"
1012
"testing"
1113

14+
"github.com/aws/aws-sdk-go/aws"
15+
"github.com/aws/aws-sdk-go/aws/awserr"
16+
"github.com/aws/aws-sdk-go/aws/credentials"
17+
"github.com/aws/aws-sdk-go/aws/session"
18+
"github.com/aws/aws-sdk-go/service/s3"
19+
"github.com/aws/aws-sdk-go/service/s3/s3manager"
20+
1221
"github.com/BurntSushi/toml"
1322
"github.com/davecgh/go-spew/spew"
1423
"github.com/stretchr/testify/suite"
@@ -19,7 +28,7 @@ type IntegrationsSuite struct {
1928
aa *AdminAPI
2029
randFilePath string
2130
lf *os.File
22-
i *Integration
31+
ic *IntegrationConfig
2332
}
2433

2534
type IntegrationConfig struct {
@@ -61,8 +70,9 @@ func (is *IntegrationsSuite) SetupSuite() {
6170
is.T().Logf("cannot parse config file at location '%s' : %s", cfgFile, err)
6271
os.Exit(1)
6372
}
73+
74+
is.ic = cfg
6475
is.aa, err = NewAdminAPI(cfg.RGW)
65-
is.i = cfg.Integration
6676
if err != nil {
6777
is.T().Logf("Error initializing AdminAPI: %s", err)
6878
os.Exit(1)
@@ -80,7 +90,7 @@ func (is *IntegrationsSuite) Test01Usage() {
8090
usage, err := is.aa.Usage(context.Background(), nil)
8191
is.NoError(err, "Got error getting Usage")
8292
is.T().Logf("usage: %#v", usage)
83-
err = is.aa.UsageTrim(context.Background(), &TrimUsageRequest{UID: is.i.TestUID})
93+
err = is.aa.UsageTrim(context.Background(), &TrimUsageRequest{UID: is.ic.Integration.TestUID})
8494
is.NoError(err, "Got error trimming usage")
8595
}
8696

@@ -92,24 +102,24 @@ func (is *IntegrationsSuite) Test02Metadata() {
92102

93103
func (is *IntegrationsSuite) Test03UserCreate() {
94104
ur := new(UserCreateRequest)
95-
ur.UID = is.i.TestUID
96-
ur.Email = is.i.TestEmail
97-
ur.DisplayName = is.i.TestDisplayName
105+
ur.UID = is.ic.Integration.TestUID
106+
ur.Email = is.ic.Integration.TestEmail
107+
ur.DisplayName = is.ic.Integration.TestDisplayName
98108
ur.UserCaps = []UserCap{{"users", "*"}, {"metadata", "*"}, {"buckets", "read"}}
99109

100110
resp, err := is.aa.UserCreate(context.Background(), ur)
101111
is.NoError(err, "Got error running UserCreate")
102112
is.T().Logf("%#v", resp)
103113
sur := new(SubUserCreateModifyRequest)
104-
sur.UID = is.i.TestUID
114+
sur.UID = is.ic.Integration.TestUID
105115
sur.Access = "full"
106116
sur.KeyType = "s3"
107-
sur.SubUser = is.i.TestSubUser
117+
sur.SubUser = is.ic.Integration.TestSubUser
108118
sur.GenerateSecret = true
109119
nresp, err := is.aa.SubUserCreate(context.Background(), sur)
110120
is.NoError(err)
111121
is.T().Logf("%#v", nresp)
112-
sur.SubUser = is.i.TesTSubUser2
122+
sur.SubUser = is.ic.Integration.TesTSubUser2
113123
sur.Access = "read"
114124
nresp, err = is.aa.SubUserCreate(context.Background(), sur)
115125
is.NoError(err)
@@ -120,21 +130,37 @@ func (is *IntegrationsSuite) Test04Quota() {
120130
qsr := new(QuotaSetRequest)
121131
qsr.Enabled = true
122132
qsr.MaximumObjects = -1 // unlimited
123-
qsr.MaximumSizeKb = 8192
133+
qsr.MaximumSizeKb = 61440
124134
qsr.QuotaType = "user"
125-
qsr.UID = is.i.TestUID
135+
qsr.UID = is.ic.Integration.TestUID
126136
err := is.aa.QuotaSet(context.Background(), qsr)
127137
is.NoError(err, "Got error running SetQuota")
128138
// read it back
129-
qresp, err := is.aa.QuotaUser(context.Background(), is.i.TestUID)
139+
qresp, err := is.aa.QuotaUser(context.Background(), is.ic.Integration.TestUID)
130140
is.T().Logf("%#v", qresp)
131141
is.NoError(err, "Got error fetching user quota")
132142
is.True(qresp.Enabled == true, "quota not enabled")
133143
is.Equal(qresp.MaxObjects, int64(-1), "MaxObjects not -1")
134-
is.Equal(qresp.MaxSizeKb, int64(8192), "MaxSizeKb not 8192")
144+
is.Equal(qresp.MaxSizeKb, int64(61440), "MaxSizeKb not 61440")
135145
}
136146

137147
func (is *IntegrationsSuite) Test05Bucket() {
148+
// Write 50mb to it.
149+
is.writeRandomFile("bigrandomfile.bin", 1024*10)
150+
is.aa.BucketIndex(context.Background(), &BucketIndexRequest{
151+
Bucket: is.ic.Integration.TestBucket,
152+
CheckObjects: true,
153+
Fix: true,
154+
})
155+
156+
// see if we can now get stats.
157+
158+
ui, err := is.aa.UserInfo(context.Background(), is.ic.Integration.TestUID, true)
159+
160+
is.NoError(err)
161+
is.NotNil(ui.Stats)
162+
163+
is.T().Logf("%#v", ui)
138164
bucketnames, err := is.aa.BucketList(context.Background(), "")
139165
is.NoError(err, "Got error fetching bucket names")
140166
is.T().Logf("bucket names: %#v\n", bucketnames)
@@ -144,26 +170,25 @@ func (is *IntegrationsSuite) Test05Bucket() {
144170
is.T().Log(spew.Sdump(bucketstats))
145171

146172
// bucketstats with bucket filter
147-
bucketstatsf, err := is.aa.BucketStats(context.Background(), "", is.i.TestBucket)
173+
bucketstatsf, err := is.aa.BucketStats(context.Background(), "", is.ic.Integration.TestBucket)
148174
is.NoError(err, "got error fetching bucket stats filtered by bucket")
149175
is.T().Log(spew.Sdump(bucketstatsf))
150176

151177
// TODO: - make code that creates a bucket and does stuff to test
152178
// bucket index code. -- for now, do one I know already exists
153179

154180
bireq := &BucketIndexRequest{}
155-
bireq.Bucket = is.i.TestBucket
181+
bireq.Bucket = is.ic.Integration.TestBucket
156182
bireq.CheckObjects = true
157183
bireq.Fix = true
158184
bucketindresp, err := is.aa.BucketIndex(context.Background(), bireq)
159185
is.NoError(err, "Got error from BucketIndex()")
160186
is.T().Logf(spew.Sdump(bucketindresp))
161-
162187
}
163188

164189
func (is *IntegrationsSuite) Test06Caps() {
165190
ucr := &UserCapsRequest{
166-
UID: is.i.TestUID,
191+
UID: is.ic.Integration.TestUID,
167192
UserCaps: []UserCap{{"usage", "read"}},
168193
}
169194
newcaps, err := is.aa.CapsAdd(context.Background(), ucr)
@@ -202,15 +227,14 @@ func (is *IntegrationsSuite) Test06Caps() {
202227
}
203228
}
204229
is.Equal(goodct, 2, "not expected removal of perms")
205-
206230
}
207231

208232
func (is *IntegrationsSuite) Test07Keys() {
209233
accessKey := "TESTACCESSKEY"
210234
secretKey := "TESTSECRETKEY"
211235
generateKey := false
212236
kc := &KeyCreateRequest{
213-
UID: is.i.TestUID,
237+
UID: is.ic.Integration.TestUID,
214238
AccessKey: accessKey,
215239
SecretKey: secretKey,
216240
GenerateKey: &generateKey,
@@ -236,7 +260,7 @@ func (is *IntegrationsSuite) Test07Keys() {
236260
is.NoError(err1, "Unexpected error deleting key")
237261

238262
// check if the key was really deleted
239-
userInfo, err2 := is.aa.UserInfo(context.Background(), is.i.TestUID)
263+
userInfo, err2 := is.aa.UserInfo(context.Background(), is.ic.Integration.TestUID, false)
240264
is.NoError(err2, "Unexpected error reading user info")
241265
found = false
242266
for i := range userInfo.Keys {
@@ -257,20 +281,111 @@ func (is *IntegrationsSuite) Test08RmUser() {
257281
return
258282
}
259283
}
260-
err := is.aa.UserRm(context.Background(), is.i.TestUID, true)
284+
err := is.aa.UserRm(context.Background(), is.ic.Integration.TestUID, true)
261285
is.NoError(err, "got error removing user")
262286
users, err := is.aa.MListUsers(context.Background())
263287
is.NoError(err, "got error listing users")
264288
found := false
265289
for _, user := range users {
266-
if user == is.i.TestUID {
290+
if user == is.ic.Integration.TestUID {
267291
found = true
268292
break
269293
}
270294
}
271295
is.False(found, "user not successfully deleted")
272296
}
273297

298+
func (is *IntegrationsSuite) writeRandomFile(path string, sizekb int) {
299+
var (
300+
s3c *s3.S3
301+
err error
302+
ui *UserInfoResponse
303+
creds *credentials.Credentials
304+
)
305+
306+
// grab creds for subuser s3 user
307+
ui, err = is.aa.UserInfo(context.Background(), is.ic.Integration.TestUID, false)
308+
309+
is.NoError(err)
310+
for _, k := range ui.Keys {
311+
if k.User == is.ic.Integration.TestUID {
312+
creds = credentials.NewStaticCredentials(k.AccessKey, k.SecretKey, "")
313+
break
314+
}
315+
}
316+
317+
is.NotNil(creds, "credentials not found")
318+
if creds == nil {
319+
return
320+
}
321+
cfg := aws.NewConfig()
322+
cfg.Region = aws.String("us-east")
323+
cfg.Endpoint = aws.String(is.ic.RGW.ServerURL)
324+
cfg.WithS3ForcePathStyle(true)
325+
326+
cfg.Credentials = creds
327+
sess := session.Must(session.NewSession(cfg))
328+
s3c = s3.New(sess)
329+
330+
_, err = s3c.CreateBucket(&s3.CreateBucketInput{
331+
Bucket: aws.String(is.ic.Integration.TestBucket),
332+
CreateBucketConfiguration: &s3.CreateBucketConfiguration{
333+
LocationConstraint: aws.String(""),
334+
},
335+
})
336+
if err != nil {
337+
338+
// ignore non-fatal creation errors
339+
if awsErr, ok := err.(awserr.Error); ok {
340+
if awsErr.Code() != s3.ErrCodeBucketAlreadyExists &&
341+
awsErr.Code() != s3.ErrCodeBucketAlreadyOwnedByYou {
342+
is.FailNow(err.Error())
343+
}
344+
} else {
345+
is.FailNow(err.Error())
346+
}
347+
}
348+
349+
rr := NewRandoReader(0, int64(1024*sizekb))
350+
351+
uploader := s3manager.NewUploader(sess)
352+
353+
_, err = uploader.Upload(&s3manager.UploadInput{
354+
Bucket: aws.String(is.ic.Integration.TestBucket),
355+
Key: aws.String(path),
356+
Body: rr,
357+
})
358+
if err != nil {
359+
is.Fail(err.Error())
360+
}
361+
362+
}
363+
364+
type RandoReader struct {
365+
r *rand.Rand
366+
max int64
367+
read int64
368+
}
369+
370+
func NewRandoReader(seed int64, bytes int64) *RandoReader {
371+
return &RandoReader{
372+
r: rand.New(rand.NewSource(seed)),
373+
max: bytes,
374+
read: 0,
375+
}
376+
}
377+
378+
func (rr *RandoReader) Read(p []byte) (n int, err error) {
379+
if rr.read >= rr.max {
380+
return 0, io.EOF
381+
} else if rr.max < (rr.read + int64(len(p))) {
382+
p = p[:(rr.max - rr.read)]
383+
}
384+
c, err := rr.r.Read(p)
385+
rr.read += int64(c)
386+
return c, err
387+
}
388+
274389
func TestIntegrations(t *testing.T) {
275390
suite.Run(t, new(IntegrationsSuite))
276391
}

adminapi_test.go

+14
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,20 @@ func (ms *ModelsSuite) Test05Quotas() {
180180
ms.Equal(resp.UserQuota.MaxSizeKb, int64(-1), "Value not expected")
181181
}
182182

183+
func (ms *ModelsSuite) Test06User() {
184+
userjson := ms.dbags["user"]
185+
userstatjson := ms.dbags["userstat"]
186+
resp := &UserInfoResponse{}
187+
err := json.Unmarshal(userjson, resp)
188+
ms.NoError(err, "Error unmarshaling user json")
189+
ms.Nil(resp.Stats, "stats not nil as expected")
190+
resp = &UserInfoResponse{}
191+
err = json.Unmarshal(userstatjson, resp)
192+
ms.NoError(err, "Error unmsrshaling userstat json")
193+
ms.NotNil(resp.Stats, "userstat Stats is nil when it shouldn't be")
194+
195+
}
196+
183197
func TestAdminAPI(t *testing.T) {
184198
suite.Run(t, new(ModelsSuite))
185199
}

glide.lock

+11-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

glide.yaml

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ package: github.com/myENA/radosgwadmin
22
import:
33
- package: github.com/BurntSushi/toml
44
version: ^0.2.0
5+
- package: github.com/google/go-querystring
6+
- package: gopkg.in/go-playground/validator.v9
7+
version: ^9.6.0
58
- package: github.com/smartystreets/go-aws-auth
9+
testImport:
610
- package: github.com/stretchr/testify
711
version: ^1.1.4
8-
- package: github.com/google/go-querystring
9-
- package: gopkg.in/go-playground/validator.v9
12+
- package: github.com/aws/aws-sdk-go
13+
version: ^1.10.38

testdata/config.toml.example

+1
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
AdminPath = "admin"
1313
AccessKeyID = "ABC123BLAHBLAHBLAH"
1414
SecretAccessKey = "IMASUPERSECRETACCESSKEY"
15+
DisableSSL = true

0 commit comments

Comments
 (0)