github.com/minio/minio-go/v6@v6.0.57/api_unit_test.go (about) 1 /* 2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage 3 * Copyright 2015-2017 MinIO, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package minio 19 20 import ( 21 "net/url" 22 "testing" 23 24 "github.com/minio/minio-go/v6/pkg/credentials" 25 "github.com/minio/minio-go/v6/pkg/policy" 26 ) 27 28 // Tests valid hosts for location. 29 func TestValidBucketLocation(t *testing.T) { 30 s3Hosts := []struct { 31 bucketLocation string 32 endpoint string 33 }{ 34 {"us-east-1", "s3.dualstack.us-east-1.amazonaws.com"}, 35 {"unknown", "s3.dualstack.us-east-1.amazonaws.com"}, 36 {"ap-southeast-1", "s3.dualstack.ap-southeast-1.amazonaws.com"}, 37 } 38 for _, s3Host := range s3Hosts { 39 endpoint := getS3Endpoint(s3Host.bucketLocation) 40 if endpoint != s3Host.endpoint { 41 t.Fatal("Error: invalid bucket location", endpoint) 42 } 43 } 44 } 45 46 // Tests error response structure. 47 func TestErrorResponse(t *testing.T) { 48 var err error 49 err = ErrorResponse{ 50 Code: "Testing", 51 } 52 errResp := ToErrorResponse(err) 53 if errResp.Code != "Testing" { 54 t.Fatal("Type conversion failed, we have an empty struct.") 55 } 56 57 // Should fail with invalid argument. 58 err = httpRespToErrorResponse(nil, "", "") 59 errResp = ToErrorResponse(err) 60 if errResp.Code != "InvalidArgument" { 61 t.Fatal("Empty response input should return invalid argument.") 62 } 63 } 64 65 // Tests signature type. 66 func TestSignatureType(t *testing.T) { 67 clnt := Client{} 68 if !clnt.overrideSignerType.IsV4() { 69 t.Fatal("Error") 70 } 71 clnt.overrideSignerType = credentials.SignatureV2 72 if !clnt.overrideSignerType.IsV2() { 73 t.Fatal("Error") 74 } 75 if clnt.overrideSignerType.IsV4() { 76 t.Fatal("Error") 77 } 78 clnt.overrideSignerType = credentials.SignatureV4 79 if !clnt.overrideSignerType.IsV4() { 80 t.Fatal("Error") 81 } 82 } 83 84 // Tests bucket policy types. 85 func TestBucketPolicyTypes(t *testing.T) { 86 want := map[string]bool{ 87 "none": true, 88 "readonly": true, 89 "writeonly": true, 90 "readwrite": true, 91 "invalid": false, 92 } 93 for bucketPolicy, ok := range want { 94 if policy.BucketPolicy(bucketPolicy).IsValidBucketPolicy() != ok { 95 t.Fatal("Error") 96 } 97 } 98 } 99 100 // Tests optimal part size. 101 func TestPartSize(t *testing.T) { 102 _, _, _, err := optimalPartInfo(5000000000000000000, minPartSize) 103 if err == nil { 104 t.Fatal("Error: should fail") 105 } 106 totalPartsCount, partSize, lastPartSize, err := optimalPartInfo(5243928576, 5*1024*1024) 107 if err != nil { 108 t.Fatal("Error: ", err) 109 } 110 if totalPartsCount != 1001 { 111 t.Fatalf("Error: expecting total parts count of 1001: got %v instead", totalPartsCount) 112 } 113 if partSize != 5242880 { 114 t.Fatalf("Error: expecting part size of 5242880: got %v instead", partSize) 115 } 116 if lastPartSize != 1048576 { 117 t.Fatalf("Error: expecting last part size of 1048576: got %v instead", lastPartSize) 118 } 119 totalPartsCount, partSize, lastPartSize, err = optimalPartInfo(5243928576, 0) 120 if err != nil { 121 t.Fatal("Error: ", err) 122 } 123 if totalPartsCount != 40 { 124 t.Fatalf("Error: expecting total parts count of 40: got %v instead", totalPartsCount) 125 } 126 if partSize != 134217728 { 127 t.Fatalf("Error: expecting part size of 134217728: got %v instead", partSize) 128 } 129 if lastPartSize != 9437184 { 130 t.Fatalf("Error: expecting last part size of 9437184: got %v instead", lastPartSize) 131 } 132 _, partSize, _, err = optimalPartInfo(5000000000, minPartSize) 133 if err != nil { 134 t.Fatal("Error:", err) 135 } 136 if partSize != minPartSize { 137 t.Fatalf("Error: expecting part size of %v: got %v instead", minPartSize, partSize) 138 } 139 // if stream and using default optimal part size determined by sdk 140 totalPartsCount, partSize, lastPartSize, err = optimalPartInfo(-1, 0) 141 if err != nil { 142 t.Fatal("Error:", err) 143 } 144 if totalPartsCount != 8192 { 145 t.Fatalf("Error: expecting total parts count of 8192: got %v instead", totalPartsCount) 146 } 147 if partSize != 671088640 { 148 t.Fatalf("Error: expecting part size of 671088640: got %v instead", partSize) 149 } 150 if lastPartSize != 671088640 { 151 t.Fatalf("Error: expecting last part size of 671088640: got %v instead", lastPartSize) 152 } 153 154 totalPartsCount, partSize, lastPartSize, err = optimalPartInfo(-1, 64*1024*1024) 155 if err != nil { 156 t.Fatal("Error:", err) 157 } 158 if totalPartsCount != 10000 { 159 t.Fatalf("Error: expecting total parts count of 10000: got %v instead", totalPartsCount) 160 } 161 if partSize != 67108864 { 162 t.Fatalf("Error: expecting part size of 67108864: got %v instead", partSize) 163 } 164 if lastPartSize != 67108864 { 165 t.Fatalf("Error: expecting part size of 67108864: got %v instead", lastPartSize) 166 } 167 } 168 169 // TestMakeTargetURL - testing makeTargetURL() 170 func TestMakeTargetURL(t *testing.T) { 171 testCases := []struct { 172 addr string 173 secure bool 174 bucketName string 175 objectName string 176 bucketLocation string 177 queryValues map[string][]string 178 expectedURL url.URL 179 expectedErr error 180 }{ 181 // Test 1 182 {"localhost:9000", false, "", "", "", nil, url.URL{Host: "localhost:9000", Scheme: "http", Path: "/"}, nil}, 183 // Test 2 184 {"localhost", true, "", "", "", nil, url.URL{Host: "localhost", Scheme: "https", Path: "/"}, nil}, 185 // Test 3 186 {"localhost:9000", true, "mybucket", "", "", nil, url.URL{Host: "localhost:9000", Scheme: "https", Path: "/mybucket/"}, nil}, 187 // Test 4, testing against google storage API 188 {"storage.googleapis.com", true, "mybucket", "", "", nil, url.URL{Host: "mybucket.storage.googleapis.com", Scheme: "https", Path: "/"}, nil}, 189 // Test 5, testing against AWS S3 API 190 {"s3.amazonaws.com", true, "mybucket", "myobject", "", nil, url.URL{Host: "mybucket.s3.dualstack.us-east-1.amazonaws.com", Scheme: "https", Path: "/myobject"}, nil}, 191 // Test 6 192 {"localhost:9000", false, "mybucket", "myobject", "", nil, url.URL{Host: "localhost:9000", Scheme: "http", Path: "/mybucket/myobject"}, nil}, 193 // Test 7, testing with query 194 {"localhost:9000", false, "mybucket", "myobject", "", map[string][]string{"param": {"val"}}, url.URL{Host: "localhost:9000", Scheme: "http", Path: "/mybucket/myobject", RawQuery: "param=val"}, nil}, 195 // Test 8, testing with port 80 196 {"localhost:80", false, "mybucket", "myobject", "", nil, url.URL{Host: "localhost", Scheme: "http", Path: "/mybucket/myobject"}, nil}, 197 // Test 9, testing with port 443 198 {"localhost:443", true, "mybucket", "myobject", "", nil, url.URL{Host: "localhost", Scheme: "https", Path: "/mybucket/myobject"}, nil}, 199 } 200 201 for i, testCase := range testCases { 202 // Initialize a MinIO client 203 c, _ := New(testCase.addr, "foo", "bar", testCase.secure) 204 isVirtualHost := c.isVirtualHostStyleRequest(*c.endpointURL, testCase.bucketName) 205 u, err := c.makeTargetURL(testCase.bucketName, testCase.objectName, testCase.bucketLocation, isVirtualHost, testCase.queryValues) 206 // Check the returned error 207 if testCase.expectedErr == nil && err != nil { 208 t.Fatalf("Test %d: Should succeed but failed with err = %v", i+1, err) 209 } 210 if testCase.expectedErr != nil && err == nil { 211 t.Fatalf("Test %d: Should fail but succeeded", i+1) 212 } 213 if err == nil { 214 // Check if the returned url is equal to what we expect 215 if u.String() != testCase.expectedURL.String() { 216 t.Fatalf("Test %d: Mismatched target url: expected = `%v`, found = `%v`", 217 i+1, testCase.expectedURL.String(), u.String()) 218 } 219 } 220 } 221 }