Skip to content

Commit 56032a0

Browse files
add system tests
1 parent ef4b4c2 commit 56032a0

4 files changed

Lines changed: 236 additions & 37 deletions

File tree

packages/storage/src/file.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1742,7 +1742,7 @@ File.prototype.move = function(destination, options, callback) {
17421742
return;
17431743
}
17441744

1745-
self.delete(function(err, apiResponse) {
1745+
self.delete(options, function(err, apiResponse) {
17461746
callback(err, destinationFile, apiResponse);
17471747
});
17481748
});

packages/storage/system-test/storage.js

Lines changed: 216 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
var assert = require('assert');
2020
var async = require('async');
2121
var crypto = require('crypto');
22+
var extend = require('extend');
2223
var fs = require('fs');
24+
var is = require('is');
2325
var normalizeNewline = require('normalize-newline');
2426
var path = require('path');
2527
var prop = require('propprop');
@@ -29,6 +31,7 @@ var tmp = require('tmp');
2931
var uuid = require('uuid');
3032

3133
var env = require('../../../system-test/env.js');
34+
var util = require('@google-cloud/common').util;
3235

3336
var Storage = require('../');
3437
var Bucket = Storage.Bucket;
@@ -76,26 +79,6 @@ describe('storage', function() {
7679
return;
7780
}
7881

79-
function deleteBucket(bucket, callback) {
80-
// After files are deleted, eventual consistency may require a bit of a
81-
// delay to ensure that the bucket recognizes that the files don't exist
82-
// anymore.
83-
var CONSISTENCY_DELAY_MS = 250;
84-
85-
bucket.deleteFiles({
86-
versions: true
87-
}, function(err) {
88-
if (err) {
89-
callback(err);
90-
return;
91-
}
92-
93-
setTimeout(function() {
94-
bucket.delete(callback);
95-
}, CONSISTENCY_DELAY_MS);
96-
});
97-
}
98-
9982
async.eachLimit(buckets, 10, deleteBucket, done);
10083
});
10184
});
@@ -224,7 +207,7 @@ describe('storage', function() {
224207
});
225208

226209
function createFileWithContent(content, callback) {
227-
writeToFile(bucket.file(generateName() + '.txt'), content, callback);
210+
bucket.file(generateName() + '.txt').save(content, callback);
228211
}
229212

230213
function isFilePublic(file, callback) {
@@ -279,7 +262,7 @@ describe('storage', function() {
279262
});
280263

281264
function createFileWithContent(content, callback) {
282-
writeToFile(bucket.file(generateName() + '.txt'), content, callback);
265+
bucket.file(generateName() + '.txt').save(content, callback);
283266
}
284267

285268
function isFilePrivate(file, callback) {
@@ -654,8 +637,15 @@ describe('storage', function() {
654637
});
655638
});
656639

640+
// These tests will verify that the requesterPays functionality works from
641+
// the perspective of another project.
657642
describe('existing bucket', function() {
658-
var bucket;
643+
var storageNonWhitelist = new Storage({
644+
projectId: env.nonWhitelistProjectId,
645+
keyFilename: env.nonWhitelistKeyFilename
646+
});
647+
var bucket; // the source bucket, which will have requesterPays enabled.
648+
var bucketNonWhitelist; // the bucket object from the requesting user.
659649

660650
function isRequesterPaysEnabled(callback) {
661651
bucket.getMetadata(function(err, metadata) {
@@ -671,6 +661,7 @@ describe('storage', function() {
671661

672662
before(function(done) {
673663
bucket = storage.bucket(generateName());
664+
bucketNonWhitelist = storageNonWhitelist.bucket(bucket.name);
674665
bucket.create(done);
675666
});
676667

@@ -711,6 +702,177 @@ describe('storage', function() {
711702
});
712703
});
713704
});
705+
706+
describe('methods that accept userProject', function() {
707+
var file;
708+
var USER_PROJECT_OPTIONS = {
709+
userProject: env.nonWhitelistProjectId
710+
};
711+
712+
// This acts as a test for the following methods:
713+
//
714+
// - file.save()
715+
// -> file.createWriteStream()
716+
before(function() {
717+
file = bucketNonWhitelist.file(generateName('file'));
718+
719+
return bucket.enableRequesterPays()
720+
.then(() => bucket.iam.getPolicy())
721+
.then(data => {
722+
var policy = data[0];
723+
var clientEmail = require(env.nonWhitelistKeyFilename)
724+
.client_email;
725+
726+
policy.bindings.push({
727+
role: 'roles/storage.admin',
728+
members: [`serviceAccount:${clientEmail}`]
729+
});
730+
731+
return bucket.iam.setPolicy(policy);
732+
})
733+
.then(() => file.save('abc', USER_PROJECT_OPTIONS));
734+
});
735+
736+
// This acts as a test for the following methods:
737+
//
738+
// - bucket.delete({ userProject: ... })
739+
// -> bucket.deleteFiles({ userProject: ... })
740+
// -> bucket.getFiles({ userProject: ... })
741+
// -> file.delete({ userProject: ... })
742+
after(function(done) {
743+
deleteBucket(bucketNonWhitelist, USER_PROJECT_OPTIONS, done);
744+
});
745+
746+
function doubleTest(testFunction) {
747+
var failureMessage =
748+
'Bucket is requester pays bucket but no user project provided.';
749+
750+
return function(done) {
751+
async.series([
752+
function(next) {
753+
testFunction({}, function(err) {
754+
assert.strictEqual(err.message, failureMessage);
755+
next();
756+
});
757+
},
758+
759+
function(next) {
760+
testFunction(USER_PROJECT_OPTIONS, next);
761+
}
762+
], done);
763+
};
764+
}
765+
766+
it('bucket#combine', function(done) {
767+
var files = [
768+
{ file: bucketNonWhitelist.file('file-one.txt'), contents: '123' },
769+
{ file: bucketNonWhitelist.file('file-two.txt'), contents: '456' }
770+
];
771+
772+
async.each(files, createFile, function(err) {
773+
assert.ifError(err);
774+
775+
var sourceFiles = files.map(prop('file'));
776+
var destinationFile = bucketNonWhitelist.file('file-one-n-two.txt');
777+
778+
bucketNonWhitelist.combine(
779+
sourceFiles,
780+
destinationFile,
781+
USER_PROJECT_OPTIONS,
782+
done
783+
);
784+
});
785+
786+
function createFile(fileObject, callback) {
787+
fileObject.file.save(
788+
fileObject.contents,
789+
USER_PROJECT_OPTIONS,
790+
callback
791+
);
792+
}
793+
});
794+
795+
it('bucket#exists', doubleTest(function(options, done) {
796+
bucketNonWhitelist.exists(options, done);
797+
}));
798+
799+
it('bucket#get', doubleTest(function(options, done) {
800+
bucketNonWhitelist.get(options, done);
801+
}));
802+
803+
it('bucket#getMetadata', doubleTest(function(options, done) {
804+
bucketNonWhitelist.get(options, done);
805+
}));
806+
807+
it('bucket#makePrivate', doubleTest(function(options, done) {
808+
bucketNonWhitelist.makePrivate(options, done);
809+
}));
810+
811+
it('bucket#setMetadata', doubleTest(function(options, done) {
812+
bucketNonWhitelist.setMetadata({ newMetadata: true }, options, done);
813+
}));
814+
815+
it('bucket#upload', doubleTest(function(options, done) {
816+
bucketNonWhitelist.upload(FILES.big.path, options, done);
817+
}));
818+
819+
it('file#copy', doubleTest(function(options, done) {
820+
file.copy('new-file.txt', options, done);
821+
}));
822+
823+
it.skip('file#createReadStream', doubleTest(function(options, done) {
824+
file.createReadStream(options)
825+
.on('error', done)
826+
.on('end', done)
827+
.on('data', util.noop);
828+
}));
829+
830+
it('file#createResumableUpload', doubleTest(function(opts, done) {
831+
file.createResumableUpload(opts, done);
832+
}));
833+
834+
it.skip('file#download', doubleTest(function(options, done) {
835+
file.download(options, done);
836+
}));
837+
838+
it('file#exists', doubleTest(function(options, done) {
839+
file.exists(options, done);
840+
}));
841+
842+
it('file#get', doubleTest(function(options, done) {
843+
file.get(options, done);
844+
}));
845+
846+
it('file#getMetadata', doubleTest(function(options, done) {
847+
file.getMetadata(options, done);
848+
}));
849+
850+
it('file#makePrivate', doubleTest(function(options, done) {
851+
file.makePrivate(options, done);
852+
}));
853+
854+
it('file#move', doubleTest(function(options, done) {
855+
var newFile = bucketNonWhitelist.file(generateName('file'));
856+
857+
file.move(newFile, options, function(err) {
858+
if (err) {
859+
done(err);
860+
return;
861+
}
862+
863+
// Re-create the file. The tests need it.
864+
file.save('newcontent', done);
865+
});
866+
}));
867+
868+
it('file#setMetadata', doubleTest(function(options, done) {
869+
file.setMetadata({ newMetadata: true }, options, done);
870+
}));
871+
872+
it('file#setStorageClass', doubleTest(function(options, done) {
873+
file.setStorageClass('multi-regional', options, done);
874+
}));
875+
});
714876
});
715877
});
716878

@@ -1185,7 +1347,7 @@ describe('storage', function() {
11851347
});
11861348

11871349
function createFile(fileObject, callback) {
1188-
writeToFile(fileObject.file, fileObject.contents, callback);
1350+
fileObject.file.save(fileObject.contents, callback);
11891351
}
11901352
});
11911353
});
@@ -1289,15 +1451,15 @@ describe('storage', function() {
12891451
it('should overwrite file, then get older version', function(done) {
12901452
var versionedFile = bucketWithVersioning.file(generateName());
12911453

1292-
writeToFile(versionedFile, 'a', function(err) {
1454+
versionedFile.save('a', function(err) {
12931455
assert.ifError(err);
12941456

12951457
versionedFile.getMetadata(function(err, metadata) {
12961458
assert.ifError(err);
12971459

12981460
var initialGeneration = metadata.generation;
12991461

1300-
writeToFile(versionedFile, 'b', function(err) {
1462+
versionedFile.save('b', function(err) {
13011463
assert.ifError(err);
13021464

13031465
var firstGenFile = bucketWithVersioning.file(versionedFile.name, {
@@ -1340,7 +1502,7 @@ describe('storage', function() {
13401502
});
13411503

13421504
function createFile(fileObject, callback) {
1343-
writeToFile(fileObject.file, fileObject.contents, callback);
1505+
fileObject.file.save(fileObject.contents, callback);
13441506
}
13451507
});
13461508
});
@@ -1447,18 +1609,38 @@ describe('storage', function() {
14471609
});
14481610
});
14491611

1612+
function deleteBucket(bucket, options, callback) {
1613+
if (is.fn(options)) {
1614+
callback = options;
1615+
options = {};
1616+
}
1617+
1618+
// After files are deleted, eventual consistency may require a bit of a
1619+
// delay to ensure that the bucket recognizes that the files don't exist
1620+
// anymore.
1621+
var CONSISTENCY_DELAY_MS = 250;
1622+
1623+
options = extend({}, options, {
1624+
versions: true
1625+
});
1626+
1627+
bucket.deleteFiles(options, function(err) {
1628+
if (err) {
1629+
callback(err);
1630+
return;
1631+
}
1632+
1633+
setTimeout(function() {
1634+
bucket.delete(options, callback);
1635+
}, CONSISTENCY_DELAY_MS);
1636+
});
1637+
}
1638+
14501639
function deleteFile(file, callback) {
14511640
file.delete(callback);
14521641
}
14531642

14541643
function generateName() {
14551644
return TESTS_PREFIX + uuid.v1();
14561645
}
1457-
1458-
function writeToFile(file, contents, callback) {
1459-
var writeStream = file.createWriteStream();
1460-
writeStream.once('error', callback);
1461-
writeStream.once('finish', callback.bind(null, null));
1462-
writeStream.end(contents);
1463-
}
14641646
});

packages/storage/test/file.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2386,12 +2386,27 @@ describe('File', function() {
23862386
});
23872387
});
23882388

2389+
it('should pass options to delete', function(done) {
2390+
var options = {};
2391+
2392+
file.copy = function(destination, options, callback) {
2393+
callback();
2394+
};
2395+
2396+
file.delete = function(options_) {
2397+
assert.strictEqual(options_, options);
2398+
done();
2399+
};
2400+
2401+
file.move('new-filename', options, assert.ifError);
2402+
});
2403+
23892404
it('should fail if delete fails', function(done) {
23902405
var error = new Error('Error.');
23912406
file.copy = function(destination, options, callback) {
23922407
callback();
23932408
};
2394-
file.delete = function(callback) {
2409+
file.delete = function(options, callback) {
23952410
callback(error);
23962411
};
23972412
file.move('new-filename', function(err) {

system-test/env.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@ module.exports = {
2020
projectId: process.env.GCLOUD_TESTS_PROJECT_ID,
2121
keyFilename: process.env.GCLOUD_TESTS_KEY,
2222
apiKey: process.env.GCLOUD_TESTS_API_KEY,
23-
projectNumber: process.env.GCLOUD_TESTS_PROJECT_NUMBER
23+
projectNumber: process.env.GCLOUD_TESTS_PROJECT_NUMBER,
24+
nonWhitelistProjectId: process.env.GCLOUD_TESTS_PROJECT_ID_NON_WHITELIST,
25+
nonWhitelistKeyFilename: process.env.GCLOUD_TESTS_KEY_NON_WHITELIST
2426
};

0 commit comments

Comments
 (0)