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  });