github.com/minio/console@v1.3.0/integration/objects_test.go (about) 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 "bytes" 21 "context" 22 "encoding/base64" 23 "encoding/json" 24 "fmt" 25 "log" 26 "math/rand" 27 "net/http" 28 "strings" 29 "testing" 30 "time" 31 32 "github.com/minio/minio-go/v7" 33 "github.com/minio/minio-go/v7/pkg/credentials" 34 35 "github.com/stretchr/testify/assert" 36 ) 37 38 func TestObjectGet(t *testing.T) { 39 // for setup we'll create a bucket and upload a file 40 endpoint := "localhost:9000" 41 accessKeyID := "minioadmin" 42 secretAccessKey := "minioadmin" 43 44 // Initialize minio client object. 45 minioClient, err := minio.New(endpoint, &minio.Options{ 46 Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""), 47 Secure: false, 48 }) 49 if err != nil { 50 log.Fatalln(err) 51 } 52 bucketName := fmt.Sprintf("testbucket-%d", rand.Intn(1000-1)+1) 53 err = minioClient.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: "us-east-1", ObjectLocking: true}) 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: 500, 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: 500, 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: 500, 166 expectedError: nil, 167 }, 168 } 169 170 for _, tt := range tests { 171 t.Run(tt.name, func(_ *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 fmt.Printf("Console server Response: %v\nErr: %v\n", response, err) 190 191 assert.NotNil(response, fmt.Sprintf("%s response object is nil", tt.name)) 192 assert.Nil(err, fmt.Sprintf("%s returned an error: %v", tt.name, err)) 193 if response != nil { 194 assert.Equal(tt.expectedStatus, response.StatusCode, fmt.Sprintf("%s returned the wrong status code", tt.name)) 195 } 196 }) 197 } 198 } 199 200 func downloadMultipleFiles(bucketName string, objects []string) (*http.Response, error) { 201 requestURL := fmt.Sprintf("http://localhost:9090/api/v1/buckets/%s/objects/download-multiple", bucketName) 202 203 postReqParams, _ := json.Marshal(objects) 204 reqBody := bytes.NewReader(postReqParams) 205 206 request, err := http.NewRequest( 207 "POST", requestURL, reqBody) 208 if err != nil { 209 log.Println(err) 210 return nil, nil 211 } 212 213 request.Header.Add("Cookie", fmt.Sprintf("token=%s", token)) 214 request.Header.Add("Content-Type", "application/json") 215 client := &http.Client{ 216 Timeout: 2 * time.Second, 217 } 218 response, err := client.Do(request) 219 return response, err 220 } 221 222 func TestDownloadMultipleFiles(t *testing.T) { 223 assert := assert.New(t) 224 type args struct { 225 bucketName string 226 objectLis []string 227 } 228 tests := []struct { 229 name string 230 args args 231 expectedStatus int 232 expectedError bool 233 }{ 234 { 235 name: "Test empty Bucket", 236 args: args{ 237 bucketName: "", 238 }, 239 expectedStatus: 400, 240 expectedError: true, 241 }, 242 { 243 name: "Test empty object list", 244 args: args{ 245 bucketName: "test-bucket", 246 }, 247 expectedStatus: 400, 248 expectedError: true, 249 }, 250 { 251 name: "Test with bucket and object list", 252 args: args{ 253 bucketName: "test-bucket", 254 objectLis: []string{ 255 "my-object.txt", 256 "test-prefix/", 257 "test-prefix/nested-prefix/", 258 "test-prefix/nested-prefix/deep-nested/", 259 }, 260 }, 261 expectedStatus: 200, 262 expectedError: false, 263 }, 264 } 265 266 for _, tt := range tests { 267 t.Run(tt.name, func(_ *testing.T) { 268 resp, err := downloadMultipleFiles(tt.args.bucketName, tt.args.objectLis) 269 if tt.expectedError { 270 assert.Nil(err) 271 if err != nil { 272 log.Println(err) 273 return 274 } 275 } 276 if resp != nil { 277 assert.NotNil(resp) 278 } 279 }) 280 } 281 }