Skip to content

Commit 86797cd

Browse files
authored
Test for Get Object with Preview (#1848)
* Test for Get Object with Preview Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
1 parent 50bc755 commit 86797cd

File tree

4 files changed

+207
-3
lines changed

4 files changed

+207
-3
lines changed

.github/workflows/jobs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,7 @@ jobs:
11421142
result=${result%\%}
11431143
echo "result:"
11441144
echo $result
1145-
threshold=35.9
1145+
threshold=36.5
11461146
if (( $(echo "$result >= $threshold" |bc -l) )); then
11471147
echo "It is equal or greater than threshold, passed!"
11481148
else

integration/objects_test.go

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
// This file is part of MinIO Console Server
2+
// Copyright (c) 2022 MinIO, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package integration
18+
19+
import (
20+
"context"
21+
"encoding/base64"
22+
"fmt"
23+
"log"
24+
"math/rand"
25+
"net/http"
26+
"strings"
27+
"testing"
28+
"time"
29+
30+
"github.com/minio/minio-go/v7"
31+
"github.com/minio/minio-go/v7/pkg/credentials"
32+
33+
"github.com/stretchr/testify/assert"
34+
)
35+
36+
func TestObjectGet(t *testing.T) {
37+
38+
// for setup we'll create a bucket and upload a file
39+
endpoint := "localhost:9000"
40+
accessKeyID := "minioadmin"
41+
secretAccessKey := "minioadmin"
42+
43+
// Initialize minio client object.
44+
minioClient, err := minio.New(endpoint, &minio.Options{
45+
Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
46+
Secure: false,
47+
})
48+
if err != nil {
49+
log.Fatalln(err)
50+
}
51+
bucketName := fmt.Sprintf("testbucket-%d", rand.Intn(1000-1)+1)
52+
err = minioClient.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: "us-east-1", ObjectLocking: true})
53+
54+
if err != nil {
55+
fmt.Println(err)
56+
}
57+
// upload a simple file
58+
fakeFile := "12345678"
59+
fileReader := strings.NewReader(fakeFile)
60+
61+
_, err = minioClient.PutObject(
62+
context.Background(),
63+
bucketName,
64+
"myobject", fileReader, int64(len(fakeFile)), minio.PutObjectOptions{ContentType: "application/octet-stream"})
65+
if err != nil {
66+
fmt.Println(err)
67+
return
68+
}
69+
_, err = minioClient.PutObject(
70+
context.Background(),
71+
bucketName,
72+
"myobject.jpg", fileReader, int64(len(fakeFile)), minio.PutObjectOptions{ContentType: "application/octet-stream"})
73+
if err != nil {
74+
fmt.Println(err)
75+
return
76+
}
77+
78+
assert := assert.New(t)
79+
type args struct {
80+
encodedPrefix string
81+
versionID string
82+
bytesRange string
83+
}
84+
tests := []struct {
85+
name string
86+
args args
87+
expectedStatus int
88+
expectedError error
89+
}{
90+
{
91+
name: "Preview Object",
92+
args: args{
93+
encodedPrefix: base64.StdEncoding.EncodeToString([]byte("myobject")),
94+
},
95+
expectedStatus: 200,
96+
expectedError: nil,
97+
},
98+
{
99+
name: "Preview image",
100+
args: args{
101+
encodedPrefix: base64.StdEncoding.EncodeToString([]byte("myobject.jpg")),
102+
},
103+
expectedStatus: 200,
104+
expectedError: nil,
105+
},
106+
{
107+
name: "Get Range of bytes",
108+
args: args{
109+
encodedPrefix: base64.StdEncoding.EncodeToString([]byte("myobject.jpg")),
110+
bytesRange: "bytes=1-4",
111+
},
112+
expectedStatus: 206,
113+
expectedError: nil,
114+
},
115+
{
116+
name: "Get Range of bytes empty start",
117+
args: args{
118+
encodedPrefix: base64.StdEncoding.EncodeToString([]byte("myobject.jpg")),
119+
bytesRange: "bytes=-4",
120+
},
121+
expectedStatus: 206,
122+
expectedError: nil,
123+
},
124+
{
125+
name: "Get Invalid Range of bytes",
126+
args: args{
127+
encodedPrefix: base64.StdEncoding.EncodeToString([]byte("myobject.jpg")),
128+
bytesRange: "bytes=9-12",
129+
},
130+
expectedStatus: 400,
131+
expectedError: nil,
132+
},
133+
{
134+
name: "Get Larger Range of bytes empty start",
135+
args: args{
136+
encodedPrefix: base64.StdEncoding.EncodeToString([]byte("myobject.jpg")),
137+
bytesRange: "bytes=-12",
138+
},
139+
expectedStatus: 206,
140+
expectedError: nil,
141+
},
142+
{
143+
name: "Get invalid seek start Range of bytes",
144+
args: args{
145+
encodedPrefix: base64.StdEncoding.EncodeToString([]byte("myobject.jpg")),
146+
bytesRange: "bytes=12-16",
147+
},
148+
expectedStatus: 400,
149+
expectedError: nil,
150+
},
151+
{
152+
name: "Bad Preview Object",
153+
args: args{
154+
encodedPrefix: "garble",
155+
},
156+
expectedStatus: 400,
157+
expectedError: nil,
158+
},
159+
{
160+
name: "Bad Version Preview Object",
161+
args: args{
162+
encodedPrefix: base64.StdEncoding.EncodeToString([]byte("myobject")),
163+
versionID: "garble",
164+
},
165+
expectedStatus: 400,
166+
expectedError: nil,
167+
},
168+
}
169+
170+
for _, tt := range tests {
171+
t.Run(tt.name, func(t *testing.T) {
172+
client := &http.Client{
173+
Timeout: 3 * time.Second,
174+
}
175+
destination := fmt.Sprintf("/api/v1/buckets/%s/objects/download?preview=true&prefix=%s&version_id=%s", bucketName, tt.args.encodedPrefix, tt.args.versionID)
176+
finalURL := fmt.Sprintf("http://localhost:9090%s", destination)
177+
request, err := http.NewRequest("GET", finalURL, nil)
178+
if err != nil {
179+
log.Println(err)
180+
return
181+
}
182+
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
183+
request.Header.Add("Content-Type", "application/json")
184+
if tt.args.bytesRange != "" {
185+
request.Header.Add("Range", tt.args.bytesRange)
186+
}
187+
188+
response, err := client.Do(request)
189+
190+
assert.NotNil(response, fmt.Sprintf("%s response object is nil", tt.name))
191+
assert.Nil(err, fmt.Sprintf("%s returned an error: %v", tt.name, err))
192+
if response != nil {
193+
assert.Equal(tt.expectedStatus, response.StatusCode, fmt.Sprintf("%s returned the wrong status code", tt.name))
194+
}
195+
})
196+
}
197+
198+
}

integration/user_api_bucket_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2799,7 +2799,7 @@ func TestReplication(t *testing.T) {
27992799
}
28002800

28012801
assert.Greater(len(structBucketRepl.Rules), 0, "Number of expected rules is 0")
2802-
if len(structBucketRepl.Rules) == 0 {
2802+
if len(structBucketRepl.Rules) == 0 || len(structBucketRepl.Rules) < 3 {
28032803
return
28042804
}
28052805
// 4. Verify rules are enabled

restapi/user_objects.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,14 +413,19 @@ func getDownloadObjectResponse(session *models.Principal, params user_api.Downlo
413413
// indicate object size & content type
414414
stat, err := resp.Stat()
415415
if err != nil {
416-
LogError("Failed to get Stat() response from server for %s: %v", prefix, err)
416+
minErr := minio.ToErrorResponse(err)
417+
// non-200 means we requested something wrong
418+
rw.WriteHeader(minErr.StatusCode)
419+
420+
LogError("Failed to get Stat() response from server for %s (version %s): %v", prefix, opts.VersionID, minErr.Error())
417421
return
418422
}
419423

420424
// if we are getting a Range Request (video) handle that specially
421425
ranges, err := parseRange(params.HTTPRequest.Header.Get("Range"), stat.Size)
422426
if err != nil {
423427
LogError("Unable to parse range header input %s: %v", params.HTTPRequest.Header.Get("Range"), err)
428+
rw.WriteHeader(400)
424429
return
425430
}
426431
contentType := stat.ContentType
@@ -450,6 +455,7 @@ func getDownloadObjectResponse(session *models.Principal, params user_api.Downlo
450455
_, err = resp.Seek(start, io.SeekStart)
451456
if err != nil {
452457
LogError("Unable to seek at offset %d: %v", start, err)
458+
rw.WriteHeader(400)
453459
return
454460
}
455461

0 commit comments

Comments
 (0)