diff --git a/pubsub/system-test/subscriptions.test.js b/pubsub/system-test/subscriptions.test.js index 7f601b2b7c2..7f6711221b7 100644 --- a/pubsub/system-test/subscriptions.test.js +++ b/pubsub/system-test/subscriptions.test.js @@ -39,7 +39,8 @@ describe('pubsub:subscriptions', function () { assert.ifError(err); assert.equal(subscription.name, name); assert(console.log.calledWith('Created subscription %s to topic %s', subscriptionName, topicName)); - done(); + // The next test sometimes fails, so, slow this test down + setTimeout(done, 2000); }); }); }); diff --git a/storage/README.md b/storage/README.md index 51168170418..c957e48a111 100644 --- a/storage/README.md +++ b/storage/README.md @@ -33,13 +33,19 @@ View the [documentation][buckets_docs] or the [source code][buckets_code]. __Usage:__ `node buckets --help` ``` -Usage: node buckets [COMMAND] [ARGS...] +Usage: node buckets COMMAND [ARGS...] Commands: - create [BUCKET_NAME] + create BUCKET_NAME list - delete [BUCKET_NAME] + delete BUCKET_NAME + +Examples: + + node buckets create my-bucket + node buckets list + node buckets delete my-bucket ``` [buckets_docs]: https://cloud.google.com/storage/docs @@ -52,20 +58,60 @@ View the [documentation][files_docs] or the [source code][files_code]. __Usage:__ `node files --help` ``` -Usage: node files [COMMAND] [ARGS...] +Usage: node files COMMAND [ARGS...] Commands: - list [BUCKET_NAME] - listByPrefix [BUCKET_NAME] [PREFIX] [DELIMITER] - upload [BUCKET_NAME] [FILE_NAME] - download [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME] - delete [BUCKET_NAME] [FILE_NAME] - getMetadata [BUCKET_NAME] [FILE_NAME] - makePublic [BUCKET_NAME] [FILE_NAME] - move [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME] - copy [BUCKET_NAME] [SRC_FILE_NAME] [DEST_BUCKET_NAME] [DEST_FILE_NAME] + list BUCKET_NAME + listByPrefix BUCKET_NAME PREFIX [DELIMITER] + upload BUCKET_NAME FILE_NAME + download BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME + delete BUCKET_NAME FILE_NAME + getMetadata BUCKET_NAME FILE_NAME + makePublic BUCKET_NAME FILE_NAME + move BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME + copy BUCKET_NAME SRC_FILE_NAME DEST_BUCKET_NAME DEST_FILE_NAME + +Examples: + + list my-bucket + listByPrefix my-bucket /some-folder + listByPrefix my-bucket /some-folder - + upload my-bucket ./file.txt + download my-bucket file.txt ./file.txt + delete my-bucket file.txt + getMetadata my-bucket file.txt + makePublic my-bucket file.txt + move my-bucket file.txt file2.txt + copy my-bucket file.txt my-other-bucket file.txt ``` [files_docs]: https://cloud.google.com/storage/docs [files_code]: files.js + +### Encryption + +View the [documentation][encryption_docs] or the [source code][encryption_code]. + +__Usage:__ `node encryption --help` + +``` +Usage: node encryption COMMAND [ARGS...] + +Commands: + + generate-encryption-key + upload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY + download BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY + rotate BUCKET_NAME FILE_NAME OLD_KEY NEW_KEY + +Examples: + + node encryption generate-encryption-key + node encryption upload my-bucket resources/test.txt file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q= + node encryption download my-bucket file_encrypted.txt ./file.txt QxhqaZEqBGVTW55HhQw9Q= + node encryption rotate my-bucket file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q= SxafpsdfSDFS89sds9Q= +``` + +[encryption_docs]: https://cloud.google.com/storage/docs +[encryption_code]: encryption.js diff --git a/storage/encryption.js b/storage/encryption.js index 95b4faddc26..be2c3416763 100644 --- a/storage/encryption.js +++ b/storage/encryption.js @@ -162,23 +162,23 @@ function printUsage () { // The command-line program var program = { - generate: generateEncryptionKey, - upload: uploadEncryptedFile, - download: downloadEncryptedFile, - rotate: rotateEncryptionKey, + generateEncryptionKey: generateEncryptionKey, + uploadEncryptedFile: uploadEncryptedFile, + downloadEncryptedFile: downloadEncryptedFile, + rotateEncryptionKey: rotateEncryptionKey, printUsage: printUsage, // Executed when this program is run from the command-line main: function (args, cb) { var command = args.shift(); if (command === 'generate-encryption-key') { - this.generate(cb); + this.generateEncryptionKey(); } else if (command === 'upload') { - this.upload(args[0], args[1], args[2], args[3], cb); + this.uploadEncryptedFile(args[0], args[1], args[2], args[3], cb); } else if (command === 'download') { - this.download(args[0], args[1], args[2], args[3], cb); + this.downloadEncryptedFile(args[0], args[1], args[2], args[3], cb); } else if (command === 'rotate') { - this.rotate(cb); + this.rotateEncryptionKey(cb); } else { this.printUsage(); } diff --git a/storage/files.js b/storage/files.js index 01548fa9fed..79189962228 100644 --- a/storage/files.js +++ b/storage/files.js @@ -324,17 +324,28 @@ function copyFile (name, srcFileName, destBucketName, destFileName, callback) { // [START usage] function printUsage () { - console.log('Usage: node files [COMMAND] [ARGS...]'); + console.log('Usage: node files COMMAND [ARGS...]'); console.log('\nCommands:\n'); - console.log('\tlist [BUCKET_NAME]'); - console.log('\tlistByPrefix [BUCKET_NAME] [PREFIX] [DELIMITER]'); - console.log('\tupload [BUCKET_NAME] [FILE_NAME]'); - console.log('\tdownload [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]'); - console.log('\tdelete [BUCKET_NAME] [FILE_NAME]'); - console.log('\tgetMetadata [BUCKET_NAME] [FILE_NAME]'); - console.log('\tmakePublic [BUCKET_NAME] [FILE_NAME]'); - console.log('\tmove [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]'); - console.log('\tcopy [BUCKET_NAME] [SRC_FILE_NAME] [DEST_BUCKET_NAME] [DEST_FILE_NAME]'); + console.log('\tlist BUCKET_NAME'); + console.log('\tlistByPrefix BUCKET_NAME PREFIX [DELIMITER]'); + console.log('\tupload BUCKET_NAME FILE_NAME'); + console.log('\tdownload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME'); + console.log('\tdelete BUCKET_NAME FILE_NAME'); + console.log('\tgetMetadata BUCKET_NAME FILE_NAME'); + console.log('\tmakePublic BUCKET_NAME FILE_NAME'); + console.log('\tmove BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME'); + console.log('\tcopy BUCKET_NAME SRC_FILE_NAME DEST_BUCKET_NAME DEST_FILE_NAME'); + console.log('\nExamples:\n'); + console.log('\tlist my-bucket'); + console.log('\tlistByPrefix my-bucket /some-folder'); + console.log('\tlistByPrefix my-bucket /some-folder -'); + console.log('\tupload my-bucket ./file.txt'); + console.log('\tdownload my-bucket file.txt ./file.txt'); + console.log('\tdelete my-bucket file.txt'); + console.log('\tgetMetadata my-bucket file.txt'); + console.log('\tmakePublic my-bucket file.txt'); + console.log('\tmove my-bucket file.txt file2.txt'); + console.log('\tcopy my-bucket file.txt my-other-bucket file.txt'); } // [END usage] diff --git a/storage/system-test/encryption.test.js b/storage/system-test/encryption.test.js new file mode 100644 index 00000000000..a1d4bde3db2 --- /dev/null +++ b/storage/system-test/encryption.test.js @@ -0,0 +1,73 @@ +// Copyright 2015-2016, Google, Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +var fs = require('fs'); +var path = require('path'); +var gcloud = require('gcloud'); +var uuid = require('node-uuid'); +var storage = gcloud.storage(); +var program = require('../encryption'); + +var bucketName = 'nodejs-docs-samples-test-' + uuid.v4(); +var fileName = 'test.txt'; +var filePath = path.join(__dirname, '../resources', fileName); +var downloadFilePath = path.join(__dirname, '../resources/downloaded.txt'); + +describe('storage:encryption', function () { + var key; + before(function (done) { + key = program.generateEncryptionKey(); + storage.createBucket(bucketName, done); + }); + + after(function (done) { + try { + fs.unlinkSync(downloadFilePath); + } catch (err) { + console.log(err); + } + storage.bucket(bucketName).deleteFiles({ force: true }, function (err) { + if (err) { + return done(err); + } + storage.bucket(bucketName).delete(done); + }); + }); + + describe('uploadEncryptedFile', function () { + it('should upload a file', function (done) { + program.uploadEncryptedFile(bucketName, filePath, fileName, key, function (err, file) { + assert.ifError(err); + assert(file); + assert.equal(file.name, fileName); + assert(console.log.calledWith('Uploaded encrypted file: %s', fileName)); + done(); + }); + }); + }); + + describe('downloadEncryptedFile', function () { + it('should download a file', function (done) { + program.downloadEncryptedFile(bucketName, fileName, downloadFilePath, key, function (err) { + assert.ifError(err); + assert.doesNotThrow(function () { + fs.statSync(downloadFilePath); + }); + assert(console.log.calledWith('Downloaded encrypted file: %s', downloadFilePath)); + done(); + }); + }); + }); +}); diff --git a/storage/test/encryption.test.js b/storage/test/encryption.test.js index 3aa4d125c4a..47473241857 100644 --- a/storage/test/encryption.test.js +++ b/storage/test/encryption.test.js @@ -45,17 +45,18 @@ function getSample () { gcloud: gcloudMock, storage: storageMock, files: filesMock, - bucket: bucketMock + bucket: bucketMock, + file: fileMock } }; } -describe.only('storage:encryption', function () { +describe('storage:encryption', function () { describe('generateEncryptionKey', function () { it('should generate an encryption key', function () { var program = getSample().program; - var key = program.generate(); + var key = program.generateEncryptionKey(); assert(console.log.calledWith('Base 64 encoded encryption key: %s', key)); }); }); @@ -65,7 +66,7 @@ describe.only('storage:encryption', function () { it('should upload a file', function () { var sample = getSample(); - sample.program.upload(bucketName, fileName, fileName, 'key', function (err, file) { + sample.program.uploadEncryptedFile(bucketName, fileName, fileName, 'key', function (err, file) { assert.ifError(err); assert.strictEqual(file, sample.mocks.files[0]); assert(console.log.calledWith('Uploaded encrypted file: %s', fileName)); @@ -74,7 +75,7 @@ describe.only('storage:encryption', function () { it('should require bucket', function () { var sample = getSample(); - sample.program.upload(undefined, undefined, undefined, undefined, function (err, file) { + sample.program.uploadEncryptedFile(undefined, undefined, undefined, undefined, function (err, file) { assert(err); assert(err.message = '"bucket" is required!'); assert.equal(file, undefined); @@ -83,7 +84,7 @@ describe.only('storage:encryption', function () { it('should require srcFileName', function () { var sample = getSample(); - sample.program.upload(bucketName, undefined, undefined, undefined, function (err, file) { + sample.program.uploadEncryptedFile(bucketName, undefined, undefined, undefined, function (err, file) { assert(err); assert(err.message = '"srcFileName" is required!'); assert.equal(file, undefined); @@ -92,7 +93,7 @@ describe.only('storage:encryption', function () { it('should require destFileName', function () { var sample = getSample(); - sample.program.upload(bucketName, fileName, undefined, undefined, function (err, file) { + sample.program.uploadEncryptedFile(bucketName, fileName, undefined, undefined, function (err, file) { assert(err); assert(err.message = '"destFileName" is required!'); assert.equal(file, undefined); @@ -101,7 +102,7 @@ describe.only('storage:encryption', function () { it('should require key', function () { var sample = getSample(); - sample.program.upload(bucketName, fileName, fileName, undefined, function (err, file) { + sample.program.uploadEncryptedFile(bucketName, fileName, fileName, undefined, function (err, file) { assert(err); assert(err.message = '"key" is required!'); assert.equal(file, undefined); @@ -110,10 +111,11 @@ describe.only('storage:encryption', function () { it('should handle error', function () { var error = 'error'; var sample = getSample(); - sample.mocks.bucket.upload = sinon.stub().callsArgWith(2, error); + sample.mocks.bucket.upload = sinon.stub().callsArgWith(2, new Error(error)); - sample.program.upload(bucketName, fileName, fileName, 'key', function (err, file) { - assert.equal(err, error); + sample.program.uploadEncryptedFile(bucketName, fileName, fileName, 'key', function (err, file) { + assert(err); + assert.equal(err.message, error); assert.equal(file, undefined); }); }); @@ -124,7 +126,7 @@ describe.only('storage:encryption', function () { it('should upload a file', function () { var sample = getSample(); - sample.program.download(bucketName, fileName, fileName, 'key', function (err) { + sample.program.downloadEncryptedFile(bucketName, fileName, fileName, 'key', function (err) { assert.ifError(err); assert(console.log.calledWith('Downloaded encrypted file: %s', fileName)); }); @@ -132,7 +134,7 @@ describe.only('storage:encryption', function () { it('should require bucket', function () { var sample = getSample(); - sample.program.download(undefined, undefined, undefined, undefined, function (err, file) { + sample.program.downloadEncryptedFile(undefined, undefined, undefined, undefined, function (err, file) { assert(err); assert(err.message = '"bucket" is required!'); assert.equal(file, undefined); @@ -141,7 +143,7 @@ describe.only('storage:encryption', function () { it('should require srcFileName', function () { var sample = getSample(); - sample.program.download(bucketName, undefined, undefined, undefined, function (err, file) { + sample.program.downloadEncryptedFile(bucketName, undefined, undefined, undefined, function (err, file) { assert(err); assert(err.message = '"srcFileName" is required!'); assert.equal(file, undefined); @@ -150,7 +152,7 @@ describe.only('storage:encryption', function () { it('should require destFileName', function () { var sample = getSample(); - sample.program.download(bucketName, fileName, undefined, undefined, function (err, file) { + sample.program.downloadEncryptedFile(bucketName, fileName, undefined, undefined, function (err, file) { assert(err); assert(err.message = '"destFileName" is required!'); assert.equal(file, undefined); @@ -159,24 +161,36 @@ describe.only('storage:encryption', function () { it('should require key', function () { var sample = getSample(); - sample.program.download(bucketName, fileName, fileName, undefined, function (err, file) { + sample.program.downloadEncryptedFile(bucketName, fileName, fileName, undefined, function (err, file) { assert(err); assert(err.message = '"key" is required!'); assert.equal(file, undefined); }); }); it('should handle error', function () { - var error = 'uploadError'; + var error = 'error'; var sample = getSample(); - sample.mocks.bucket.upload = sinon.stub().callsArgWith(2, error); + sample.mocks.file.download = sinon.stub().callsArgWith(1, new Error(error)); - sample.program.download(bucketName, fileName, fileName, 'key', function (err, file) { - assert.equal(err, error); + sample.program.downloadEncryptedFile(bucketName, fileName, fileName, 'key', function (err, file) { + assert(err); + assert.equal(err.message, error); assert.equal(file, undefined); }); }); }); + describe('rotateEncryptionKey', function () { + it('should rotate an encryption key', function () { + var sample = getSample(); + + sample.program.rotateEncryptionKey(function (err) { + assert(err); + assert.equal(err.message, 'This is currently not available using the Cloud Client Library.'); + }); + }); + }); + describe('printUsage', function () { it('should print usage', function () { var program = getSample().program; @@ -201,21 +215,21 @@ describe.only('storage:encryption', function () { it('should call the right commands', function () { var program = getSample().program; - sinon.stub(program, 'generate'); + sinon.stub(program, 'generateEncryptionKey'); program.main(['generate-encryption-key']); - assert(program.generate.calledOnce); + assert(program.generateEncryptionKey.calledOnce); - sinon.stub(program, 'upload'); + sinon.stub(program, 'uploadEncryptedFile'); program.main(['upload']); - assert(program.upload.calledOnce); + assert(program.uploadEncryptedFile.calledOnce); - sinon.stub(program, 'download'); + sinon.stub(program, 'downloadEncryptedFile'); program.main(['download']); - assert(program.download.calledOnce); + assert(program.downloadEncryptedFile.calledOnce); - sinon.stub(program, 'rotate'); + sinon.stub(program, 'rotateEncryptionKey'); program.main(['rotate']); - assert(program.rotate.calledOnce); + assert(program.rotateEncryptionKey.calledOnce); sinon.stub(program, 'printUsage'); program.main(['--help']); diff --git a/storage/test/files.test.js b/storage/test/files.test.js index ba21df7125e..8e2b5fcd9c4 100644 --- a/storage/test/files.test.js +++ b/storage/test/files.test.js @@ -421,17 +421,17 @@ describe('storage:files', function () { filesSample.sample.printUsage(); - assert(console.log.calledWith('Usage: node files [COMMAND] [ARGS...]')); + assert(console.log.calledWith('Usage: node files COMMAND [ARGS...]')); assert(console.log.calledWith('\nCommands:\n')); - assert(console.log.calledWith('\tlist [BUCKET_NAME]')); - assert(console.log.calledWith('\tlistByPrefix [BUCKET_NAME] [PREFIX] [DELIMITER]')); - assert(console.log.calledWith('\tupload [BUCKET_NAME] [FILE_NAME]')); - assert(console.log.calledWith('\tdownload [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]')); - assert(console.log.calledWith('\tdelete [BUCKET_NAME] [FILE_NAME]')); - assert(console.log.calledWith('\tgetMetadata [BUCKET_NAME] [FILE_NAME]')); - assert(console.log.calledWith('\tmakePublic [BUCKET_NAME] [FILE_NAME]')); - assert(console.log.calledWith('\tmove [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]')); - assert(console.log.calledWith('\tcopy [BUCKET_NAME] [SRC_FILE_NAME] [DEST_BUCKET_NAME] [DEST_FILE_NAME]')); + assert(console.log.calledWith('\tlist BUCKET_NAME')); + assert(console.log.calledWith('\tlistByPrefix BUCKET_NAME PREFIX [DELIMITER]')); + assert(console.log.calledWith('\tupload BUCKET_NAME FILE_NAME')); + assert(console.log.calledWith('\tdownload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME')); + assert(console.log.calledWith('\tdelete BUCKET_NAME FILE_NAME')); + assert(console.log.calledWith('\tgetMetadata BUCKET_NAME FILE_NAME')); + assert(console.log.calledWith('\tmakePublic BUCKET_NAME FILE_NAME')); + assert(console.log.calledWith('\tmove BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME')); + assert(console.log.calledWith('\tcopy BUCKET_NAME SRC_FILE_NAME DEST_BUCKET_NAME DEST_FILE_NAME')); }); }); describe('main', function () {