open-nomad/ui/tests/integration/components/agent-monitor-test.js
Michael Lange d44e0772f7 Always include the region param in server monitor requests
The region will naturally be appended to URLs via
token.authorizedRequest but agent members includes all servers across
all regions so relying on the application-level region isn't good
enough.
2021-02-01 09:54:46 -08:00

184 lines
5.8 KiB
JavaScript

import { run } from '@ember/runloop';
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { find, render, settled } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import Pretender from 'pretender';
import sinon from 'sinon';
import { logEncode } from '../../../mirage/data/logs';
import { selectOpen, selectOpenChoose } from '../../utils/ember-power-select-extensions';
import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit';
module('Integration | Component | agent-monitor', function(hooks) {
setupRenderingTest(hooks);
const LOG_MESSAGE = 'log message goes here';
hooks.beforeEach(function() {
// Normally this would be called server, but server is a prop of this component.
this.pretender = new Pretender(function() {
this.get('/v1/regions', () => [200, {}, '[]']);
this.get('/v1/agent/monitor', ({ queryParams }) => [
200,
{},
logEncode([`[${(queryParams.log_level || 'info').toUpperCase()}] ${LOG_MESSAGE}\n`], 0),
]);
});
});
hooks.afterEach(function() {
this.pretender.shutdown();
});
const INTERVAL = 200;
const commonTemplate = hbs`
<AgentMonitor
@level={{this.level}}
@client={{this.client}}
@server={{this.server}}
@onLevelChange={{this.onLevelChange}} />
`;
test('basic appearance', async function(assert) {
this.setProperties({
level: 'info',
client: { id: 'client1' },
});
run.later(run, run.cancelTimers, INTERVAL);
await render(commonTemplate);
assert.ok(find('[data-test-level-switcher]'));
assert.ok(find('[data-test-toggle]'));
assert.ok(find('[data-test-log-box]'));
assert.ok(find('[data-test-log-box].is-full-bleed.is-dark'));
await componentA11yAudit(this.element, assert);
});
test('when provided with a client, AgentMonitor streams logs for the client', async function(assert) {
this.setProperties({
level: 'info',
client: { id: 'client1', region: 'us-west-1' },
});
run.later(run, run.cancelTimers, INTERVAL);
await render(commonTemplate);
const logRequest = this.pretender.handledRequests[1];
assert.ok(logRequest.url.startsWith('/v1/agent/monitor'));
assert.ok(logRequest.url.includes('client_id=client1'));
assert.ok(logRequest.url.includes('log_level=info'));
assert.notOk(logRequest.url.includes('server_id'));
assert.notOk(logRequest.url.includes('region='));
});
test('when provided with a server, AgentMonitor streams logs for the server', async function(assert) {
this.setProperties({
level: 'warn',
server: { id: 'server1', region: 'us-west-1' },
});
run.later(run, run.cancelTimers, INTERVAL);
await render(commonTemplate);
const logRequest = this.pretender.handledRequests[1];
assert.ok(logRequest.url.startsWith('/v1/agent/monitor'));
assert.ok(logRequest.url.includes('server_id=server1'));
assert.ok(logRequest.url.includes('log_level=warn'));
assert.ok(logRequest.url.includes('region=us-west-1'));
assert.notOk(logRequest.url.includes('client_id'));
});
test('switching levels calls onLevelChange and restarts the logger', async function(assert) {
const onLevelChange = sinon.spy();
const newLevel = 'trace';
this.setProperties({
level: 'info',
client: { id: 'client1' },
onLevelChange,
});
run.later(run, run.cancelTimers, INTERVAL);
await render(commonTemplate);
await settled();
const contentId = await selectOpen('[data-test-level-switcher]');
run.later(run, run.cancelTimers, INTERVAL);
await selectOpenChoose(contentId, newLevel.capitalize());
await settled();
assert.ok(onLevelChange.calledOnce);
assert.ok(onLevelChange.calledWith(newLevel));
const secondLogRequest = this.pretender.handledRequests[2];
assert.ok(secondLogRequest.url.includes(`log_level=${newLevel}`));
});
test('when switching levels, the scrollback is preserved and annotated with a switch message', async function(assert) {
const newLevel = 'trace';
const onLevelChange = sinon.spy();
this.setProperties({
level: 'info',
client: { id: 'client1' },
onLevelChange,
});
run.later(run, run.cancelTimers, INTERVAL);
await render(commonTemplate);
await settled();
assert.equal(find('[data-test-log-cli]').textContent, `[INFO] ${LOG_MESSAGE}\n`);
const contentId = await selectOpen('[data-test-level-switcher]');
run.later(run, run.cancelTimers, INTERVAL);
await selectOpenChoose(contentId, newLevel.capitalize());
await settled();
assert.equal(
find('[data-test-log-cli]').textContent,
`[INFO] ${LOG_MESSAGE}\n\n...changing log level to ${newLevel}...\n\n[TRACE] ${LOG_MESSAGE}\n`
);
});
test('when switching levels and there is no scrollback, there is no appended switch message', async function(assert) {
const newLevel = 'trace';
const onLevelChange = sinon.spy();
// Emit nothing for the first request
this.pretender.get('/v1/agent/monitor', ({ queryParams }) => [
200,
{},
queryParams.log_level === 'info'
? logEncode([''], 0)
: logEncode([`[${(queryParams.log_level || 'info').toUpperCase()}] ${LOG_MESSAGE}\n`], 0),
]);
this.setProperties({
level: 'info',
client: { id: 'client1' },
onLevelChange,
});
run.later(run, run.cancelTimers, INTERVAL);
await render(commonTemplate);
await settled();
assert.equal(find('[data-test-log-cli]').textContent, '');
const contentId = await selectOpen('[data-test-level-switcher]');
run.later(run, run.cancelTimers, INTERVAL);
await selectOpenChoose(contentId, newLevel.capitalize());
await settled();
assert.equal(find('[data-test-log-cli]').textContent, `[TRACE] ${LOG_MESSAGE}\n`);
});
});