OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library gcloud.storage; |
| 6 |
| 7 import 'dart:async'; |
| 8 |
| 9 import 'package:gcloud/storage.dart'; |
| 10 import 'package:googleapis/common/common.dart' as common; |
| 11 import 'package:unittest/unittest.dart'; |
| 12 |
| 13 import '../common_e2e.dart'; |
| 14 |
| 15 String generateBucketName() { |
| 16 var id = new DateTime.now().millisecondsSinceEpoch; |
| 17 return 'dart-e2e-test-$id'; |
| 18 } |
| 19 |
| 20 bool testDetailedApiError(e) => e is common.DetailedApiRequestError; |
| 21 |
| 22 // Generate a list just above the limit when changing to resumable upload. |
| 23 const int MB = 1024 * 1024; |
| 24 const int maxNormalUpload = 1 * MB; |
| 25 const int minResumableUpload = maxNormalUpload + 1; |
| 26 var bytesResumableUpload = |
| 27 new List.generate(minResumableUpload, (e) => e & 255); |
| 28 |
| 29 runTests(Storage storage, Bucket testBucket) { |
| 30 group('bucket', () { |
| 31 test('create-info-delete', () { |
| 32 var bucketName = generateBucketName(); |
| 33 return storage.createBucket(bucketName).then(expectAsync((result) { |
| 34 expect(result, isNull); |
| 35 return storage.bucketInfo(bucketName).then(expectAsync((info) { |
| 36 expect(info.bucketName, bucketName); |
| 37 expect(info.etag, isNotNull); |
| 38 expect(info.created is DateTime, isTrue); |
| 39 expect(info.id, isNotNull); |
| 40 return storage.deleteBucket(bucketName) |
| 41 .then(expectAsync((result) { |
| 42 expect(result, isNull); |
| 43 })); |
| 44 })); |
| 45 })); |
| 46 }); |
| 47 |
| 48 test('create-with-predefined-acl-delete', () { |
| 49 Future<Acl> test(predefinedAcl, expectedLength) { |
| 50 var bucketName = generateBucketName(); |
| 51 return storage.createBucket(bucketName, predefinedAcl: predefinedAcl) |
| 52 .then(expectAsync((result) { |
| 53 expect(result, isNull); |
| 54 return storage.bucketInfo(bucketName).then(expectAsync((info) { |
| 55 var acl = info.acl; |
| 56 expect(info.bucketName, bucketName); |
| 57 expect(acl.entries.length, expectedLength); |
| 58 return storage.deleteBucket(bucketName) |
| 59 .then(expectAsync((result) { |
| 60 expect(result, isNull); |
| 61 })); |
| 62 })); |
| 63 })); |
| 64 } |
| 65 |
| 66 return Future.forEach([ |
| 67 // TODO: Figure out why some returned ACLs are empty. |
| 68 () => test(PredefinedAcl.authenticatedRead, 0), |
| 69 // [test, [PredefinedAcl.private, 0]], // TODO: Cannot delete. |
| 70 () => test(PredefinedAcl.projectPrivate, 3), |
| 71 () => test(PredefinedAcl.publicRead, 0), |
| 72 () => test(PredefinedAcl.publicReadWrite, 0) |
| 73 ], (f) => f().then(expectAsync((_) {}))); |
| 74 }); |
| 75 |
| 76 test('create-error', () { |
| 77 var bucketName = generateBucketName(); |
| 78 |
| 79 storage.createBucket('goog-reserved').catchError(expectAsync((e) { |
| 80 expect(e, isNotNull); |
| 81 }), test: testDetailedApiError); |
| 82 }); |
| 83 }); |
| 84 |
| 85 // TODO: Remove solo_ here when the rate-limit issue have been resolved. |
| 86 solo_group('object', () { |
| 87 // Run all object tests in the same bucket to try to avoid the rate-limit |
| 88 // for creating and deleting buckets while testing. |
| 89 Future withTestBucket(function) { |
| 90 return function(testBucket).whenComplete(() { |
| 91 // TODO: Clean the bucket. |
| 92 }); |
| 93 } |
| 94 |
| 95 test('create-read-delete', () { |
| 96 Future test(name, bytes) { |
| 97 return withTestBucket((Bucket bucket) { |
| 98 return bucket.writeBytes('test', bytes).then(expectAsync((info) { |
| 99 expect(info, isNotNull); |
| 100 return bucket.read('test') |
| 101 .fold([], (p, e) => p..addAll(e)) |
| 102 .then(expectAsync((result) { |
| 103 expect(result, bytes); |
| 104 return bucket.delete('test').then(expectAsync((result) { |
| 105 expect(result, isNull); |
| 106 })); |
| 107 })); |
| 108 })); |
| 109 }); |
| 110 } |
| 111 |
| 112 return Future.forEach([ |
| 113 () => test('test-1', [1, 2, 3]), |
| 114 () => test('test-2', bytesResumableUpload) |
| 115 ], (f) => f().then(expectAsync((_) {}))); |
| 116 }); |
| 117 |
| 118 test('create-with-predefined-acl-delete', () { |
| 119 return withTestBucket((Bucket bucket) { |
| 120 Future test(objectName, predefinedAcl, expectedLength) { |
| 121 var bucketName = generateBucketName(); |
| 122 return bucket.writeBytes( |
| 123 objectName, [1, 2, 3], predefinedAcl: predefinedAcl) |
| 124 .then(expectAsync((result) { |
| 125 expect(result, isNotNull); |
| 126 return bucket.info(objectName).then(expectAsync((info) { |
| 127 var acl = info.metadata.acl; |
| 128 expect(info.name, objectName); |
| 129 expect(info.etag, isNotNull); |
| 130 expect(acl.entries.length, expectedLength); |
| 131 return bucket.delete(objectName).then(expectAsync((result) { |
| 132 expect(result, isNull); |
| 133 })); |
| 134 })); |
| 135 })); |
| 136 } |
| 137 |
| 138 return Future.forEach([ |
| 139 () => test('test-1', PredefinedAcl.authenticatedRead, 2), |
| 140 () => test('test-2', PredefinedAcl.private, 1), |
| 141 () => test('test-3', PredefinedAcl.projectPrivate, 4), |
| 142 () => test('test-4', PredefinedAcl.publicRead, 2), |
| 143 () => test('test-5', PredefinedAcl.bucketOwnerFullControl, 2), |
| 144 () => test('test-6', PredefinedAcl.bucketOwnerRead, 2) |
| 145 ], (f) => f().then(expectAsync((_) {}))); |
| 146 }); |
| 147 }); |
| 148 |
| 149 test('create-with-acl-delete', () { |
| 150 return withTestBucket((Bucket bucket) { |
| 151 Future test(objectName, acl, expectedLength) { |
| 152 var bucketName = generateBucketName(); |
| 153 return bucket.writeBytes(objectName, [1, 2, 3], acl: acl) |
| 154 .then(expectAsync((result) { |
| 155 expect(result, isNotNull); |
| 156 return bucket.info(objectName).then(expectAsync((info) { |
| 157 var acl = info.metadata.acl; |
| 158 expect(info.name, objectName); |
| 159 expect(info.etag, isNotNull); |
| 160 expect(acl.entries.length, expectedLength); |
| 161 return bucket.delete(objectName).then(expectAsync((result) { |
| 162 expect(result, isNull); |
| 163 })); |
| 164 })); |
| 165 })); |
| 166 } |
| 167 |
| 168 Acl acl1 = new Acl( |
| 169 [new AclEntry(AclScope.allAuthenticated, AclPermission.WRITE)]); |
| 170 Acl acl2 = new Acl( |
| 171 [new AclEntry(AclScope.allUsers, AclPermission.WRITE), |
| 172 new AclEntry(new AccountScope('sgjesse@google.com'), |
| 173 AclPermission.WRITE)]); |
| 174 Acl acl3 = new Acl( |
| 175 [new AclEntry(AclScope.allUsers, AclPermission.WRITE), |
| 176 new AclEntry(new AccountScope('sgjesse@google.com'), |
| 177 AclPermission.WRITE), |
| 178 new AclEntry(new AccountScope('misc@dartlang.org'), |
| 179 AclPermission.READ)]); |
| 180 Acl acl4 = new Acl( |
| 181 [new AclEntry(AclScope.allUsers, AclPermission.WRITE), |
| 182 new AclEntry(new AccountScope('sgjesse@google.com'), |
| 183 AclPermission.WRITE), |
| 184 new AclEntry(new GroupScope('misc@dartlang.org'), |
| 185 AclPermission.READ), |
| 186 new AclEntry(new DomainScope('dartlang.org'), |
| 187 AclPermission.FULL_CONTROL)]); |
| 188 |
| 189 return Future.forEach([ |
| 190 () => test('test-1', acl1, 1), |
| 191 () => test('test-2', acl2, 2), |
| 192 () => test('test-3', acl3, 3), |
| 193 () => test('test-4', acl4, 4) |
| 194 ], (f) => f().then(expectAsync((_) {}))); |
| 195 }); |
| 196 }); |
| 197 |
| 198 test('create-with-metadata-delete', () { |
| 199 return withTestBucket((Bucket bucket) { |
| 200 Future test(objectName, metadata, bytes) { |
| 201 var bucketName = generateBucketName(); |
| 202 return bucket.writeBytes(objectName, bytes, metadata: metadata) |
| 203 .then(expectAsync((result) { |
| 204 expect(result, isNotNull); |
| 205 return bucket.info(objectName).then(expectAsync((info) { |
| 206 var acl = info.metadata.acl; |
| 207 expect(info.name, objectName); |
| 208 expect(info.length, bytes.length); |
| 209 expect(info.updated is DateTime, isTrue); |
| 210 expect(info.md5Hash, isNotNull); |
| 211 expect(info.crc32CChecksum, isNotNull); |
| 212 expect(info.downloadLink is Uri, isTrue); |
| 213 expect(info.generation.objectGeneration, isNotNull); |
| 214 expect(info.generation.metaGeneration, 1); |
| 215 expect(info.metadata.contentType, metadata.contentType); |
| 216 expect(info.metadata.cacheControl, metadata.cacheControl); |
| 217 expect(info.metadata.contentDisposition, |
| 218 metadata.contentDisposition); |
| 219 expect(info.metadata.contentEncoding, |
| 220 metadata.contentEncoding); |
| 221 expect(info.metadata.contentLanguage, |
| 222 metadata.contentLanguage); |
| 223 expect(info.metadata.custom, metadata.custom); |
| 224 return bucket.delete(objectName).then(expectAsync((result) { |
| 225 expect(result, isNull); |
| 226 })); |
| 227 })); |
| 228 })); |
| 229 } |
| 230 |
| 231 var metadata1 = new ObjectMetadata(contentType: 'text/plain'); |
| 232 var metadata2 = new ObjectMetadata( |
| 233 contentType: 'text/plain', |
| 234 cacheControl: 'no-cache', |
| 235 contentDisposition: 'attachment; filename="test.txt"', |
| 236 contentEncoding: 'gzip', |
| 237 contentLanguage: 'da', |
| 238 custom: {'a': 'b', 'c': 'd'}); |
| 239 |
| 240 return Future.forEach([ |
| 241 () => test('test-1', metadata1, [65, 66, 67]), |
| 242 () => test('test-2', metadata2, [65, 66, 67]), |
| 243 () => test('test-3', metadata1, bytesResumableUpload), |
| 244 () => test('test-4', metadata2, bytesResumableUpload) |
| 245 ], (f) => f().then(expectAsync((_) {}))); |
| 246 }); |
| 247 }); |
| 248 }); |
| 249 } |
| 250 |
| 251 main() { |
| 252 withAuthClient(Storage.SCOPES, (String project, httpClient) { |
| 253 var testBucket = generateBucketName(); |
| 254 |
| 255 // Share the same storage connection for all tests. |
| 256 var storage = new Storage(httpClient, project); |
| 257 |
| 258 // Create a shared bucket for all object tests. |
| 259 return storage.createBucket(testBucket).then((_) { |
| 260 return runE2EUnittest(() { |
| 261 runTests(storage, storage.bucket(testBucket)); |
| 262 }).whenComplete(() { |
| 263 // Deleting a bucket relies on eventually consistent behaviour, hence |
| 264 // the delay in attempt to prevent test flakiness. |
| 265 return new Future.delayed(STORAGE_LIST_DELAY, () { |
| 266 return storage.deleteBucket(testBucket); |
| 267 }); |
| 268 }); |
| 269 }); |
| 270 }); |
| 271 } |
OLD | NEW |