github.com/hernad/nomad@v1.6.112/ui/tests/unit/utils/log-test.js (about) 1 /** 2 * Copyright (c) HashiCorp, Inc. 3 * SPDX-License-Identifier: MPL-2.0 4 */ 5 6 import EmberObject from '@ember/object'; 7 import RSVP from 'rsvp'; 8 import { run } from '@ember/runloop'; 9 import sinon from 'sinon'; 10 import { module, test } from 'qunit'; 11 import _Log from 'nomad-ui/utils/classes/log'; 12 13 import { settled } from '@ember/test-helpers'; 14 15 let startSpy, stopSpy, initSpy, fetchSpy; 16 17 const MockStreamer = EmberObject.extend({ 18 init() { 19 this.poll = { 20 isRunning: false, 21 }; 22 23 initSpy(...arguments); 24 }, 25 26 start() { 27 this.poll.isRunning = true; 28 startSpy(...arguments); 29 }, 30 31 stop() { 32 this.poll.isRunning = true; 33 stopSpy(...arguments); 34 }, 35 36 step(chunk) { 37 if (this.poll.isRunning) { 38 this.write(chunk); 39 } 40 }, 41 }); 42 43 const Log = _Log.extend({ 44 init() { 45 this._super(); 46 const props = this.logStreamer.getProperties( 47 'url', 48 'params', 49 'logFetch', 50 'write' 51 ); 52 this.set('logStreamer', MockStreamer.create(props)); 53 }, 54 }); 55 56 module('Unit | Util | Log', function (hooks) { 57 hooks.beforeEach(function () { 58 initSpy = sinon.spy(); 59 startSpy = sinon.spy(); 60 stopSpy = sinon.spy(); 61 fetchSpy = sinon.spy(); 62 }); 63 64 const makeMocks = (output) => ({ 65 url: '/test-url/', 66 params: { 67 a: 'param', 68 another: 'one', 69 }, 70 logFetch: function () { 71 fetchSpy(...arguments); 72 return RSVP.Promise.resolve({ 73 text() { 74 return output; 75 }, 76 }); 77 }, 78 }); 79 80 test('logStreamer is created on init', async function (assert) { 81 const log = Log.create(makeMocks('')); 82 83 assert.ok(log.get('logStreamer'), 'logStreamer property is defined'); 84 assert.ok(initSpy.calledOnce, 'logStreamer init was called'); 85 }); 86 87 test('gotoHead builds the correct URL', async function (assert) { 88 assert.expect(1); 89 90 const mocks = makeMocks(''); 91 const expectedUrl = `${mocks.url}?a=param&another=one&offset=0&origin=start`; 92 const log = Log.create(mocks); 93 94 run(() => { 95 log.get('gotoHead').perform(); 96 assert.ok( 97 fetchSpy.calledWith(expectedUrl), 98 `gotoHead URL was ${expectedUrl}` 99 ); 100 }); 101 }); 102 103 test('When gotoHead returns too large of a log, the log is truncated', async function (assert) { 104 const longLog = Array(50001).fill('a').join(''); 105 const encodedLongLog = `{"Offset":0,"Data":"${window.btoa(longLog)}"}`; 106 const truncationMessage = 107 '\n\n---------- TRUNCATED: Click "tail" to view the bottom of the log ----------'; 108 109 const mocks = makeMocks(encodedLongLog); 110 const log = Log.create(mocks); 111 112 run(() => { 113 log.get('gotoHead').perform(); 114 }); 115 116 await settled(); 117 assert.ok( 118 log.get('output').toString().endsWith(truncationMessage), 119 'Truncation message is shown' 120 ); 121 assert.equal( 122 log.get('output').toString().length, 123 50000 + truncationMessage.length, 124 'Output is truncated the appropriate amount' 125 ); 126 }); 127 128 test('gotoTail builds the correct URL', async function (assert) { 129 assert.expect(1); 130 131 const mocks = makeMocks(''); 132 const expectedUrl = `${mocks.url}?a=param&another=one&offset=50000&origin=end`; 133 const log = Log.create(mocks); 134 135 run(() => { 136 log.get('gotoTail').perform(); 137 assert.ok( 138 fetchSpy.calledWith(expectedUrl), 139 `gotoTail URL was ${expectedUrl}` 140 ); 141 }); 142 }); 143 144 test('startStreaming starts the log streamer', async function (assert) { 145 const log = Log.create(makeMocks('')); 146 147 log.startStreaming(); 148 assert.ok(startSpy.calledOnce, 'Streaming started'); 149 assert.equal( 150 log.get('logPointer'), 151 'tail', 152 'Streaming points the log to the tail' 153 ); 154 }); 155 156 test('When the log streamer calls `write`, the output is appended', async function (assert) { 157 const log = Log.create(makeMocks('')); 158 const chunk1 = 'Hello'; 159 const chunk2 = ' World'; 160 const chunk3 = '\n\nEOF'; 161 162 log.startStreaming(); 163 assert.equal(log.get('output'), '', 'No output yet'); 164 165 log.get('logStreamer').step(chunk1); 166 assert.equal(log.get('output'), chunk1, 'First chunk written'); 167 168 log.get('logStreamer').step(chunk2); 169 assert.equal(log.get('output'), chunk1 + chunk2, 'Second chunk written'); 170 171 log.get('logStreamer').step(chunk3); 172 assert.equal( 173 log.get('output'), 174 chunk1 + chunk2 + chunk3, 175 'Third chunk written' 176 ); 177 }); 178 179 test('stop stops the log streamer', async function (assert) { 180 const log = Log.create(makeMocks('')); 181 182 log.stop(); 183 assert.ok(stopSpy.calledOnce, 'Streaming stopped'); 184 }); 185 });