Skip to content

Instantly share code, notes, and snippets.

@eschwartz
Last active September 27, 2016 21:13
Show Gist options
  • Save eschwartz/df5e2f651923517b79788960c2f642b2 to your computer and use it in GitHub Desktop.
Save eschwartz/df5e2f651923517b79788960c2f642b2 to your computer and use it in GitHub Desktop.
S3 Mock, using In-Memory key->val store
const co = require('co');
const stream = require('stream');
function S3InMemoryClient() {
var memFs = {};
const client = {
upload: (opts, cb) => co(function*() {
const data = opts.Body instanceof stream.Readable ?
yield readStream(opts.Body) : opts.Body;
const key = [opts.Bucket, opts.Key].join('/');
memFs[key] = data;
}).then(() => cb(), err => cb(err)),
getObject: (opts) => ({
createReadStream: () => {
const key = [opts.Bucket, opts.Key].join('/');
const buf = memFs[key];
return buf ? ContentStream(buf) : ErrorStream(new Error(`${key} was not mocked`));
}
}),
listObjects: (s3Opts, cb) => {
const fsPrefix = [s3Opts.Bucket, s3Opts.Prefix].join('/');
const matchingKeys = Object.keys(memFs)
.filter(fsKey => fsKey.startsWith(fsPrefix))
.map(fsKey => fsKey.slice(s3Opts.Bucket.length + 1));
cb(null, {
Contents: matchingKeys.map(Key => ({ Key }))
});
}
};
return client;
}
function ContentStream(buffer) {
const mockStream = new stream.PassThrough();
setTimeout(() => mockStream.end(buffer));
return mockStream;
}
function ErrorStream(err) {
const mockStream = new stream.PassThrough();
setTimeout(() => mockStream.emit('error', err), 10);
return mockStream;
}
/**
* @param {stream.Readable} stream
* @returns {Promise<Buffer>}
*/
function readStream(stream) {
return co(function*() {
var buf = new Buffer(0);
yield cb => stream
.on('data', data => buf = Buffer.concat([buf, data]))
.on('error', cb)
.on('end', cb);
return buf;
})
}
module.exports = S3InMemoryClient;
@eschwartz
Copy link
Author

Note that this currently only supports returning a ReadableStream from getObject,
but does not support returning a ReadableStream from listObjects

Hence, why I haven't gone through the trouble of make a fill npm package out of it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment