github.com/hernad/nomad@v1.6.112/ui/tests/integration/components/agent-monitor-test.js (about)

     1  /**
     2   * Copyright (c) HashiCorp, Inc.
     3   * SPDX-License-Identifier: MPL-2.0
     4   */
     5  
     6  /* eslint-disable ember/no-string-prototype-extensions */
     7  import { run } from '@ember/runloop';
     8  import { module, test } from 'qunit';
     9  import { setupRenderingTest } from 'ember-qunit';
    10  import { find, render, settled } from '@ember/test-helpers';
    11  import hbs from 'htmlbars-inline-precompile';
    12  import Pretender from 'pretender';
    13  import sinon from 'sinon';
    14  import { logEncode } from '../../../mirage/data/logs';
    15  import {
    16    selectOpen,
    17    selectOpenChoose,
    18  } from '../../utils/ember-power-select-extensions';
    19  import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit';
    20  import { capitalize } from '@ember/string';
    21  
    22  module('Integration | Component | agent-monitor', function (hooks) {
    23    setupRenderingTest(hooks);
    24  
    25    const LOG_MESSAGE = 'log message goes here';
    26  
    27    hooks.beforeEach(function () {
    28      // Normally this would be called server, but server is a prop of this component.
    29      this.pretender = new Pretender(function () {
    30        this.get('/v1/regions', () => [200, {}, '[]']);
    31        this.get('/v1/agent/monitor', ({ queryParams }) => [
    32          200,
    33          {},
    34          logEncode(
    35            [
    36              `[${(
    37                queryParams.log_level || 'info'
    38              ).toUpperCase()}] ${LOG_MESSAGE}\n`,
    39            ],
    40            0
    41          ),
    42        ]);
    43      });
    44    });
    45  
    46    hooks.afterEach(function () {
    47      this.pretender.shutdown();
    48    });
    49  
    50    const INTERVAL = 200;
    51  
    52    const commonTemplate = hbs`
    53      <AgentMonitor
    54        @level={{this.level}}
    55        @client={{this.client}}
    56        @server={{this.server}}
    57        @onLevelChange={{this.onLevelChange}} />
    58    `;
    59  
    60    test('basic appearance', async function (assert) {
    61      assert.expect(5);
    62  
    63      this.setProperties({
    64        level: 'info',
    65        client: { id: 'client1' },
    66      });
    67  
    68      run.later(run, run.cancelTimers, INTERVAL);
    69  
    70      await render(commonTemplate);
    71  
    72      assert.ok(find('[data-test-level-switcher-parent]'));
    73      assert.ok(find('[data-test-toggle]'));
    74      assert.ok(find('[data-test-log-box]'));
    75      assert.ok(find('[data-test-log-box].is-full-bleed.is-dark'));
    76  
    77      await componentA11yAudit(this.element, assert);
    78    });
    79  
    80    test('when provided with a client, AgentMonitor streams logs for the client', async function (assert) {
    81      this.setProperties({
    82        level: 'info',
    83        client: { id: 'client1', region: 'us-west-1' },
    84      });
    85  
    86      run.later(run, run.cancelTimers, INTERVAL);
    87  
    88      await render(commonTemplate);
    89  
    90      const logRequest = this.pretender.handledRequests[1];
    91      assert.ok(logRequest.url.startsWith('/v1/agent/monitor'));
    92      assert.ok(logRequest.url.includes('client_id=client1'));
    93      assert.ok(logRequest.url.includes('log_level=info'));
    94      assert.notOk(logRequest.url.includes('server_id'));
    95      assert.notOk(logRequest.url.includes('region='));
    96    });
    97  
    98    test('when provided with a server, AgentMonitor streams logs for the server', async function (assert) {
    99      this.setProperties({
   100        level: 'warn',
   101        server: { id: 'server1', region: 'us-west-1' },
   102      });
   103  
   104      run.later(run, run.cancelTimers, INTERVAL);
   105  
   106      await render(commonTemplate);
   107  
   108      const logRequest = this.pretender.handledRequests[1];
   109      assert.ok(logRequest.url.startsWith('/v1/agent/monitor'));
   110      assert.ok(logRequest.url.includes('server_id=server1'));
   111      assert.ok(logRequest.url.includes('log_level=warn'));
   112      assert.ok(logRequest.url.includes('region=us-west-1'));
   113      assert.notOk(logRequest.url.includes('client_id'));
   114    });
   115  
   116    test('switching levels calls onLevelChange and restarts the logger', async function (assert) {
   117      const onLevelChange = sinon.spy();
   118      const newLevel = 'trace';
   119  
   120      this.setProperties({
   121        level: 'info',
   122        client: { id: 'client1' },
   123        onLevelChange,
   124      });
   125  
   126      run.later(run, run.cancelTimers, INTERVAL);
   127  
   128      await render(commonTemplate);
   129  
   130      const contentId = await selectOpen('[data-test-level-switcher-parent]');
   131      run.later(run, run.cancelTimers, INTERVAL);
   132      await selectOpenChoose(contentId, capitalize(newLevel));
   133      await settled();
   134  
   135      assert.ok(onLevelChange.calledOnce);
   136      assert.ok(onLevelChange.calledWith(newLevel));
   137  
   138      const secondLogRequest = this.pretender.handledRequests[2];
   139      assert.ok(secondLogRequest.url.includes(`log_level=${newLevel}`));
   140    });
   141  
   142    test('when switching levels, the scrollback is preserved and annotated with a switch message', async function (assert) {
   143      const newLevel = 'trace';
   144      const onLevelChange = sinon.spy();
   145  
   146      this.setProperties({
   147        level: 'info',
   148        client: { id: 'client1' },
   149        onLevelChange,
   150      });
   151  
   152      run.later(run, run.cancelTimers, INTERVAL);
   153  
   154      await render(commonTemplate);
   155  
   156      assert.equal(
   157        find('[data-test-log-cli]').textContent,
   158        `[INFO] ${LOG_MESSAGE}\n`
   159      );
   160  
   161      const contentId = await selectOpen('[data-test-level-switcher-parent]');
   162      run.later(run, run.cancelTimers, INTERVAL);
   163      await selectOpenChoose(contentId, capitalize(newLevel));
   164      await settled();
   165  
   166      assert.equal(
   167        find('[data-test-log-cli]').textContent,
   168        `[INFO] ${LOG_MESSAGE}\n\n...changing log level to ${newLevel}...\n\n[TRACE] ${LOG_MESSAGE}\n`
   169      );
   170    });
   171  
   172    test('when switching levels and there is no scrollback, there is no appended switch message', async function (assert) {
   173      const newLevel = 'trace';
   174      const onLevelChange = sinon.spy();
   175  
   176      // Emit nothing for the first request
   177      this.pretender.get('/v1/agent/monitor', ({ queryParams }) => [
   178        200,
   179        {},
   180        queryParams.log_level === 'info'
   181          ? logEncode([''], 0)
   182          : logEncode(
   183              [
   184                `[${(
   185                  queryParams.log_level || 'info'
   186                ).toUpperCase()}] ${LOG_MESSAGE}\n`,
   187              ],
   188              0
   189            ),
   190      ]);
   191  
   192      this.setProperties({
   193        level: 'info',
   194        client: { id: 'client1' },
   195        onLevelChange,
   196      });
   197  
   198      run.later(run, run.cancelTimers, INTERVAL);
   199  
   200      await render(commonTemplate);
   201  
   202      assert.equal(find('[data-test-log-cli]').textContent, '');
   203  
   204      const contentId = await selectOpen('[data-test-level-switcher-parent]');
   205      run.later(run, run.cancelTimers, INTERVAL);
   206      await selectOpenChoose(contentId, capitalize(newLevel));
   207      await settled();
   208  
   209      assert.equal(
   210        find('[data-test-log-cli]').textContent,
   211        `[TRACE] ${LOG_MESSAGE}\n`
   212      );
   213    });
   214  });