github.com/zoomfoo/nomad@v0.8.5-0.20180907175415-f28fd3a1a056/ui/tests/integration/task-log-test.js (about) 1 import { run } from '@ember/runloop'; 2 import { test, moduleForComponent } from 'ember-qunit'; 3 import wait from 'ember-test-helpers/wait'; 4 import { find, click } from 'ember-native-dom-helpers'; 5 import hbs from 'htmlbars-inline-precompile'; 6 import Pretender from 'pretender'; 7 import { logEncode } from '../../mirage/data/logs'; 8 9 const HOST = '1.1.1.1:1111'; 10 const allowedConnectionTime = 100; 11 const commonProps = { 12 interval: 200, 13 allocation: { 14 id: 'alloc-1', 15 node: { 16 httpAddr: HOST, 17 }, 18 }, 19 task: 'task-name', 20 clientTimeout: allowedConnectionTime, 21 serverTimeout: allowedConnectionTime, 22 }; 23 24 const logHead = ['HEAD']; 25 const logTail = ['TAIL']; 26 const streamFrames = ['one\n', 'two\n', 'three\n', 'four\n', 'five\n']; 27 let streamPointer = 0; 28 29 moduleForComponent('task-log', 'Integration | Component | task log', { 30 integration: true, 31 beforeEach() { 32 const handler = ({ queryParams }) => { 33 const { origin, offset, plain, follow } = queryParams; 34 35 let frames; 36 let data; 37 38 if (origin === 'start' && offset === '0' && plain && !follow) { 39 frames = logHead; 40 } else if (origin === 'end' && plain && !follow) { 41 frames = logTail; 42 } else { 43 frames = streamFrames; 44 } 45 46 if (frames === streamFrames) { 47 data = queryParams.plain ? frames[streamPointer] : logEncode(frames, streamPointer); 48 streamPointer++; 49 } else { 50 data = queryParams.plain ? frames.join('') : logEncode(frames, frames.length - 1); 51 } 52 53 return [200, {}, data]; 54 }; 55 56 this.server = new Pretender(function() { 57 this.get(`http://${HOST}/v1/client/fs/logs/:allocation_id`, handler); 58 this.get('/v1/client/fs/logs/:allocation_id', handler); 59 this.get('/v1/regions', () => [200, {}, '[]']); 60 }); 61 }, 62 afterEach() { 63 this.server.shutdown(); 64 streamPointer = 0; 65 }, 66 }); 67 68 test('Basic appearance', function(assert) { 69 this.setProperties(commonProps); 70 this.render(hbs`{{task-log allocation=allocation task=task}}`); 71 72 assert.ok(find('[data-test-log-action="stdout"]'), 'Stdout button'); 73 assert.ok(find('[data-test-log-action="stderr"]'), 'Stderr button'); 74 assert.ok(find('[data-test-log-action="head"]'), 'Head button'); 75 assert.ok(find('[data-test-log-action="tail"]'), 'Tail button'); 76 assert.ok(find('[data-test-log-action="toggle-stream"]'), 'Stream toggle button'); 77 78 assert.ok(find('[data-test-log-box].is-full-bleed.is-dark'), 'Body is full-bleed and dark'); 79 80 assert.ok(find('pre.cli-window'), 'Cli is preformatted and using the cli-window component class'); 81 }); 82 83 test('Streaming starts on creation', function(assert) { 84 run.later(run, run.cancelTimers, commonProps.interval); 85 86 this.setProperties(commonProps); 87 this.render(hbs`{{task-log allocation=allocation task=task}}`); 88 89 const logUrlRegex = new RegExp(`${HOST}/v1/client/fs/logs/${commonProps.allocation.id}`); 90 assert.ok( 91 this.server.handledRequests.filter(req => logUrlRegex.test(req.url)).length, 92 'Log requests were made' 93 ); 94 95 return wait().then(() => { 96 assert.equal( 97 find('[data-test-log-cli]').textContent, 98 streamFrames[0], 99 'First chunk of streaming log is shown' 100 ); 101 }); 102 }); 103 104 test('Clicking Head loads the log head', function(assert) { 105 this.setProperties(commonProps); 106 this.render(hbs`{{task-log allocation=allocation task=task}}`); 107 108 click('[data-test-log-action="head"]'); 109 110 return wait().then(() => { 111 assert.ok( 112 this.server.handledRequests.find( 113 ({ queryParams: qp }) => qp.origin === 'start' && qp.plain === 'true' && qp.offset === '0' 114 ), 115 'Log head request was made' 116 ); 117 assert.equal(find('[data-test-log-cli]').textContent, logHead[0], 'Head of the log is shown'); 118 }); 119 }); 120 121 test('Clicking Tail loads the log tail', function(assert) { 122 this.setProperties(commonProps); 123 this.render(hbs`{{task-log allocation=allocation task=task}}`); 124 125 click('[data-test-log-action="tail"]'); 126 127 return wait().then(() => { 128 assert.ok( 129 this.server.handledRequests.find( 130 ({ queryParams: qp }) => qp.origin === 'end' && qp.plain === 'true' 131 ), 132 'Log tail request was made' 133 ); 134 assert.equal(find('[data-test-log-cli]').textContent, logTail[0], 'Tail of the log is shown'); 135 }); 136 }); 137 138 test('Clicking toggleStream starts and stops the log stream', function(assert) { 139 const { interval } = commonProps; 140 this.setProperties(commonProps); 141 this.render(hbs`{{task-log allocation=allocation task=task interval=interval}}`); 142 143 run.later(() => { 144 click('[data-test-log-action="toggle-stream"]'); 145 }, interval); 146 147 return wait().then(() => { 148 assert.equal(find('[data-test-log-cli]').textContent, streamFrames[0], 'First frame loaded'); 149 150 run.later(() => { 151 assert.equal( 152 find('[data-test-log-cli]').textContent, 153 streamFrames[0], 154 'Still only first frame' 155 ); 156 click('[data-test-log-action="toggle-stream"]'); 157 run.later(run, run.cancelTimers, interval * 2); 158 }, interval * 2); 159 160 return wait().then(() => { 161 assert.equal( 162 find('[data-test-log-cli]').textContent, 163 streamFrames[0] + streamFrames[0] + streamFrames[1], 164 'Now includes second frame' 165 ); 166 }); 167 }); 168 }); 169 170 test('Clicking stderr switches the log to standard error', function(assert) { 171 this.setProperties(commonProps); 172 this.render(hbs`{{task-log allocation=allocation task=task}}`); 173 174 click('[data-test-log-action="stderr"]'); 175 run.later(run, run.cancelTimers, commonProps.interval); 176 177 return wait().then(() => { 178 assert.ok( 179 this.server.handledRequests.filter(req => req.queryParams.type === 'stderr').length, 180 'stderr log requests were made' 181 ); 182 }); 183 }); 184 185 test('When the client is inaccessible, task-log falls back to requesting logs through the server', function(assert) { 186 run.later(run, run.cancelTimers, allowedConnectionTime * 2); 187 188 // override client response to timeout 189 this.server.get( 190 `http://${HOST}/v1/client/fs/logs/:allocation_id`, 191 () => [400, {}, ''], 192 allowedConnectionTime * 2 193 ); 194 195 this.setProperties(commonProps); 196 this.render( 197 hbs`{{task-log 198 allocation=allocation 199 task=task 200 clientTimeout=clientTimeout 201 serverTimeout=serverTimeout}}` 202 ); 203 204 const clientUrlRegex = new RegExp(`${HOST}/v1/client/fs/logs/${commonProps.allocation.id}`); 205 assert.ok( 206 this.server.handledRequests.filter(req => clientUrlRegex.test(req.url)).length, 207 'Log request was initially made directly to the client' 208 ); 209 210 return wait().then(() => { 211 const serverUrl = `/v1/client/fs/logs/${commonProps.allocation.id}`; 212 assert.ok( 213 this.server.handledRequests.filter(req => req.url.startsWith(serverUrl)).length, 214 'Log request was later made to the server' 215 ); 216 }); 217 }); 218 219 test('When both the client and the server are inaccessible, an error message is shown', function(assert) { 220 run.later(run, run.cancelTimers, allowedConnectionTime * 5); 221 222 // override client and server responses to timeout 223 this.server.get( 224 `http://${HOST}/v1/client/fs/logs/:allocation_id`, 225 () => [400, {}, ''], 226 allowedConnectionTime * 2 227 ); 228 this.server.get( 229 '/v1/client/fs/logs/:allocation_id', 230 () => [400, {}, ''], 231 allowedConnectionTime * 2 232 ); 233 234 this.setProperties(commonProps); 235 this.render( 236 hbs`{{task-log 237 allocation=allocation 238 task=task 239 clientTimeout=clientTimeout 240 serverTimeout=serverTimeout}}` 241 ); 242 243 return wait().then(() => { 244 const clientUrlRegex = new RegExp(`${HOST}/v1/client/fs/logs/${commonProps.allocation.id}`); 245 assert.ok( 246 this.server.handledRequests.filter(req => clientUrlRegex.test(req.url)).length, 247 'Log request was initially made directly to the client' 248 ); 249 const serverUrl = `/v1/client/fs/logs/${commonProps.allocation.id}`; 250 assert.ok( 251 this.server.handledRequests.filter(req => req.url.startsWith(serverUrl)).length, 252 'Log request was later made to the server' 253 ); 254 assert.ok(find('[data-test-connection-error]'), 'An error message is shown'); 255 }); 256 });