1 /**
  2  * @fileOverview Live test utilities.
  3  */
  4 
  5 /**
  6  * @name test.live.utils
  7  */
  8 (function () {
  9   var assert = require('assert'),
 10     async = require('async'),
 11     uuid = require('node-uuid'),
 12     sunnyUtils = require("../../lib/utils"),
 13     Utils;
 14 
 15   /**
 16    * @exports Utils as test.live.utils.Utils
 17    * @namespace
 18    */
 19   Utils = {
 20     /**
 21      * Create string UUID.
 22      */
 23     getUuid: function (len) {
 24       len = len || 32;
 25       return uuid().toString().replace(/-/g, '').substr(0, len);
 26     },
 27 
 28     /**
 29      * Create test container name.
 30      *
 31      * AWS:
 32      *
 33      *  - Bucket names MUST be between 3 and 255 characters long.
 34      *  - Bucket names should be between 3 and 63 characters long.
 35      *
 36      * Rackspace:
 37      *
 38      *  - The URL encoded name must be less than 256 bytes and cannot contain a
 39      *    forward slash '/' character.
 40      */
 41     testContainerName: function (len) {
 42       return "sunnyjs-livetest-" + Utils.getUuid(len);
 43     },
 44 
 45     /**
 46      * Common error handler.
 47      */
 48     errHandle: function (test) {
 49       return function (err) {
 50         test.ok(false, "Should not have error. Got: " + err);
 51         test.done();
 52       };
 53     },
 54 
 55     /**
 56      * Create a test object with test container and blobs from list.
 57      *
 58      * @param {Array}   blobs List of blobs to create.
 59      * @param {Object}  tests Object (hash) of tests.
 60      */
 61     createTestSetup: function (blobs, tests) {
 62       blobs = blobs || [];
 63       tests = tests || {};
 64 
 65       function errHandle(err) {
 66         assert.ok(false, "Should not have error. Got: " + err);
 67       }
 68 
 69       return sunnyUtils.extend({
 70         setUp: function (setUpCallback, opts) {
 71           var self = this;
 72 
 73           self.containerName = Utils.testContainerName();
 74           self.container = null;
 75           self.blobs = [];
 76 
 77           async.series([
 78             // Create a simple, random container.
 79             function (asyncCallback) {
 80               var request = opts.conn.putContainer(self.containerName);
 81               request.on('error', errHandle);
 82               request.on('end', function (results) {
 83                 self.container = results.container;
 84                 assert.ok(self.container, "Should have container.");
 85                 asyncCallback(null);
 86               });
 87               request.end();
 88             },
 89 
 90             // Fill empty blobs (parallel).
 91             function (asyncCallback) {
 92               var innerSeries = [];
 93 
 94               if (blobs.length === 0) {
 95                 asyncCallback(null);
 96 
 97               } else {
 98                 // PUT in parallel, and go to outer series when done.
 99                 blobs.forEach(function (blobName, index) {
100                   innerSeries.push(function (innerCb) {
101                     var stream = self.container.putBlob(blobName);
102                     stream.on('error', errHandle);
103                     stream.on('end', function (results) {
104                       self.blobs.push(results.blob);
105                       assert.ok(results.blob, "Should have PUT blob.");
106                       innerCb(null);
107                     });
108                     stream.end(blobName);
109                   });
110                 });
111 
112                 async.parallel(innerSeries, function (err) {
113                   assert.ok(!err, "Should not have error.");
114                   asyncCallback();
115                 });
116               }
117             }
118           ], function (err) {
119             assert.ok(!err, "Should not have error.");
120             setUpCallback();
121           });
122         },
123         tearDown: function (tearDownCallback, opts) {
124           var self = this,
125             seriesResults;
126 
127           // Find all blobs in container and delete them all.
128           async.series([
129             // Get container.
130             function (asyncCallback) {
131               var request = opts.conn.getContainer(self.containerName, {
132                 validate: true
133               });
134               request.on('error', errHandle);
135               request.on('end', function (results) {
136                 seriesResults = results;
137                 asyncCallback(null);
138               });
139               request.end();
140             },
141 
142             // Get list of blobs (assumed under default=1000)
143             function (asyncCallback) {
144               assert.ok(seriesResults.container);
145 
146               var request = seriesResults.container.getBlobs();
147               request.on('error', errHandle);
148               request.on('end', function (results) {
149                 seriesResults = results;
150                 asyncCallback(null);
151               });
152               request.end();
153             },
154 
155             // Delete all blobs.
156             function (asyncCallback) {
157               var innerSeries = [];
158 
159               assert.ok(seriesResults.blobs);
160               if (seriesResults.blobs.length === 0) {
161                 asyncCallback(null);
162 
163               } else {
164                 // DELETE in parallel, and go to outer series when done.
165                 seriesResults.blobs.forEach(function (blob, index) {
166                   innerSeries.push(function (innerCb) {
167                     var request = blob.del();
168                     request.on('error', errHandle);
169                     request.on('end', function (results) {
170                       innerCb(null);
171                     });
172                     request.end();
173                   });
174                 });
175 
176                 async.parallel(innerSeries, function (err) {
177                   assert.ok(!err, "Should not have error.");
178                   asyncCallback(null);
179                 });
180               }
181             },
182 
183             // Delete random container.
184             function (asyncCallback) {
185               var request = opts.conn.delContainer(self.containerName);
186               request.on('error', errHandle);
187               request.on('end', function (results) {
188                 asyncCallback(null);
189               });
190               request.end();
191             }
192           ], function (err) {
193             assert.ok(!err, "Should not have error.");
194             tearDownCallback();
195           });
196         }
197       }, tests);
198     }
199   };
200 
201   module.exports = Utils;
202 }());
203