diff --git a/lib/tasks/exec.js b/lib/tasks/exec.js index 63969c9..35d0d9a 100644 --- a/lib/tasks/exec.js +++ b/lib/tasks/exec.js @@ -28,7 +28,7 @@ class ExecTask { }; const exec = await container.exec(opt); - const bufferStream = util.buildBufferStream(); + const bufferStream = util.buildOutputBufferStream(); const outputStream = await exec.start(); await new Promise((res, rej) => { diff --git a/lib/tasks/run.js b/lib/tasks/run.js index e549e78..d144b56 100644 --- a/lib/tasks/run.js +++ b/lib/tasks/run.js @@ -46,7 +46,6 @@ class RunTask { log.info('Started task'); try { - const bufferStream = util.buildBufferStream(); await this.checkOrPull(this.image, log); const opt = { User: this.user, @@ -59,6 +58,7 @@ class RunTask { if (this.environment) opt.Env = this.environment; if (this.volumes) opt.HostConfig.Binds = this.volumes; + const bufferStream = util.buildOutputBufferStream(); const [res, container] = await this.docker.run(this.image, this.command, bufferStream.stream, opt); const { Error: error, StatusCode: exitCode } = res; diff --git a/lib/util.js b/lib/util.js index e6f0b8b..d450473 100644 --- a/lib/util.js +++ b/lib/util.js @@ -3,6 +3,8 @@ const dockerUtil = require('dockerode/lib/util'); const { Writable } = require('stream'); const { StringDecoder } = require('string_decoder'); +const MAX_OUTPUT_BUFFER_SIZE = 200000; // 200KB + class Util { static parseRepositoryTag(image) { @@ -21,12 +23,16 @@ class Util { return Object.entries(env).map(([k, v]) => `${k}${v ? `=${v}` : ''}`); } - static buildBufferStream() { + static buildOutputBufferStream() { const decoder = new StringDecoder('utf8'); const res = { buffer: '' }; res.stream = new Writable({ write(chunk, encoding, callback) { res.buffer += decoder.write(chunk); + if (res.buffer.length > Util.MAX_OUTPUT_BUFFER_SIZE) { + const start = res.buffer.length - Util.MAX_OUTPUT_BUFFER_SIZE; + res.buffer = res.buffer.substring(start); + } callback(); } }); @@ -47,4 +53,6 @@ class Util { } +Util.MAX_OUTPUT_BUFFER_SIZE = MAX_OUTPUT_BUFFER_SIZE; + module.exports = Util; diff --git a/package.json b/package.json index f6d1d91..1f85d22 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ }, "scripts": { "start": "node ./bin/cli.js", - "test": "ava", + "test": "ava -T 1m --verbose", "lint": "eslint ." }, "author": "Nicolas Martinez", diff --git a/test/tasks/run.js b/test/tasks/run.js index 1562b0a..3e00541 100644 --- a/test/tasks/run.js +++ b/test/tasks/run.js @@ -2,6 +2,7 @@ const path = require('path'); const test = require('ava'); const dockerUtil = require('../util/docker'); const MockLog = require('../mock/log'); +const util = require('../../lib/util'); const RunTask = require('../../lib/tasks/run'); const log = new MockLog(); @@ -202,3 +203,15 @@ test('run: custom workingdir', async (t) => { t.is(exitCode, 0); t.is(output, '/tmp'); }); + +test('run: very long output', async (t) => { + const task = new RunTask('test', { + image: 'busybox', + command: 'sh -c "yes 0123456789 | head -1000000"' + }); + + const { exitCode, output } = await task.execute(log); + t.is(task.name, 'test'); + t.is(exitCode, 0); + t.true(output.length <= util.MAX_OUTPUT_BUFFER_SIZE); +});