github.com/hspak/nomad@v0.7.2-0.20180309000617-bc4ae22a39a5/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: 50, 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 }); 60 }, 61 afterEach() { 62 this.server.shutdown(); 63 streamPointer = 0; 64 }, 65 }); 66 67 test('Basic appearance', function(assert) { 68 this.setProperties(commonProps); 69 this.render(hbs`{{task-log allocation=allocation task=task}}`); 70 71 assert.ok(find('[data-test-log-action="stdout"]'), 'Stdout button'); 72 assert.ok(find('[data-test-log-action="stderr"]'), 'Stderr button'); 73 assert.ok(find('[data-test-log-action="head"]'), 'Head button'); 74 assert.ok(find('[data-test-log-action="tail"]'), 'Tail button'); 75 assert.ok(find('[data-test-log-action="toggle-stream"]'), 'Stream toggle button'); 76 77 assert.ok(find('[data-test-log-box].is-full-bleed.is-dark'), 'Body is full-bleed and dark'); 78 79 assert.ok(find('pre.cli-window'), 'Cli is preformatted and using the cli-window component class'); 80 }); 81 82 test('Streaming starts on creation', function(assert) { 83 run.later(run, run.cancelTimers, commonProps.interval); 84 85 this.setProperties(commonProps); 86 this.render(hbs`{{task-log allocation=allocation task=task}}`); 87 88 const logUrlRegex = new RegExp(`${HOST}/v1/client/fs/logs/${commonProps.allocation.id}`); 89 assert.ok( 90 this.server.handledRequests.filter(req => logUrlRegex.test(req.url)).length, 91 'Log requests were made' 92 ); 93 94 return wait().then(() => { 95 assert.equal( 96 find('[data-test-log-cli]').textContent, 97 streamFrames[0], 98 'First chunk of streaming log is shown' 99 ); 100 }); 101 }); 102 103 test('Clicking Head loads the log head', function(assert) { 104 this.setProperties(commonProps); 105 this.render(hbs`{{task-log allocation=allocation task=task}}`); 106 107 click('[data-test-log-action="head"]'); 108 109 return wait().then(() => { 110 assert.ok( 111 this.server.handledRequests.find( 112 ({ queryParams: qp }) => qp.origin === 'start' && qp.plain === 'true' && qp.offset === '0' 113 ), 114 'Log head request was made' 115 ); 116 assert.equal(find('[data-test-log-cli]').textContent, logHead[0], 'Head of the log is shown'); 117 }); 118 }); 119 120 test('Clicking Tail loads the log tail', function(assert) { 121 this.setProperties(commonProps); 122 this.render(hbs`{{task-log allocation=allocation task=task}}`); 123 124 click('[data-test-log-action="tail"]'); 125 126 return wait().then(() => { 127 assert.ok( 128 this.server.handledRequests.find( 129 ({ queryParams: qp }) => qp.origin === 'end' && qp.plain === 'true' 130 ), 131 'Log tail request was made' 132 ); 133 assert.equal(find('[data-test-log-cli]').textContent, logTail[0], 'Tail of the log is shown'); 134 }); 135 }); 136 137 test('Clicking toggleStream starts and stops the log stream', function(assert) { 138 const { interval } = commonProps; 139 this.setProperties(commonProps); 140 this.render(hbs`{{task-log allocation=allocation task=task interval=interval}}`); 141 142 run.later(() => { 143 click('[data-test-log-action="toggle-stream"]'); 144 }, interval); 145 146 return wait().then(() => { 147 assert.equal(find('[data-test-log-cli]').textContent, streamFrames[0], 'First frame loaded'); 148 149 run.later(() => { 150 assert.equal( 151 find('[data-test-log-cli]').textContent, 152 streamFrames[0], 153 'Still only first frame' 154 ); 155 click('[data-test-log-action="toggle-stream"]'); 156 run.later(run, run.cancelTimers, interval * 2); 157 }, interval * 2); 158 159 return wait().then(() => { 160 assert.equal( 161 find('[data-test-log-cli]').textContent, 162 streamFrames[0] + streamFrames[0] + streamFrames[1], 163 'Now includes second frame' 164 ); 165 }); 166 }); 167 }); 168 169 test('Clicking stderr switches the log to standard error', function(assert) { 170 this.setProperties(commonProps); 171 this.render(hbs`{{task-log allocation=allocation task=task}}`); 172 173 click('[data-test-log-action="stderr"]'); 174 run.later(run, run.cancelTimers, commonProps.interval); 175 176 return wait().then(() => { 177 assert.ok( 178 this.server.handledRequests.filter(req => req.queryParams.type === 'stderr').length, 179 'stderr log requests were made' 180 ); 181 }); 182 }); 183 184 test('When the client is inaccessible, task-log falls back to requesting logs through the server', function(assert) { 185 run.later(run, run.cancelTimers, allowedConnectionTime * 2); 186 187 // override client response to timeout 188 this.server.get( 189 `http://${HOST}/v1/client/fs/logs/:allocation_id`, 190 () => [400, {}, ''], 191 allowedConnectionTime * 2 192 ); 193 194 this.setProperties(commonProps); 195 this.render( 196 hbs`{{task-log 197 allocation=allocation 198 task=task 199 clientTimeout=clientTimeout 200 serverTimeout=serverTimeout}}` 201 ); 202 203 const clientUrlRegex = new RegExp(`${HOST}/v1/client/fs/logs/${commonProps.allocation.id}`); 204 assert.ok( 205 this.server.handledRequests.filter(req => clientUrlRegex.test(req.url)).length, 206 'Log request was initially made directly to the client' 207 ); 208 209 return wait().then(() => { 210 const serverUrl = `/v1/client/fs/logs/${commonProps.allocation.id}`; 211 assert.ok( 212 this.server.handledRequests.filter(req => req.url.startsWith(serverUrl)).length, 213 'Log request was later made to the server' 214 ); 215 }); 216 }); 217 218 test('When both the client and the server are inaccessible, an error message is shown', function(assert) { 219 run.later(run, run.cancelTimers, allowedConnectionTime * 5); 220 221 // override client and server responses to timeout 222 this.server.get( 223 `http://${HOST}/v1/client/fs/logs/:allocation_id`, 224 () => [400, {}, ''], 225 allowedConnectionTime * 2 226 ); 227 this.server.get( 228 '/v1/client/fs/logs/:allocation_id', 229 () => [400, {}, ''], 230 allowedConnectionTime * 2 231 ); 232 233 this.setProperties(commonProps); 234 this.render( 235 hbs`{{task-log 236 allocation=allocation 237 task=task 238 clientTimeout=clientTimeout 239 serverTimeout=serverTimeout}}` 240 ); 241 242 return wait().then(() => { 243 const clientUrlRegex = new RegExp(`${HOST}/v1/client/fs/logs/${commonProps.allocation.id}`); 244 assert.ok( 245 this.server.handledRequests.filter(req => clientUrlRegex.test(req.url)).length, 246 'Log request was initially made directly to the client' 247 ); 248 const serverUrl = `/v1/client/fs/logs/${commonProps.allocation.id}`; 249 assert.ok( 250 this.server.handledRequests.filter(req => req.url.startsWith(serverUrl)).length, 251 'Log request was later made to the server' 252 ); 253 assert.ok(find('[data-test-connection-error]'), 'An error message is shown'); 254 }); 255 });