Skip to content

Commit

Permalink
test(tracing): make tracing_metrics test more robust
Browse files Browse the repository at this point in the history
Do not fail if another application is still up and also sending tracing
metrics (with a different PID). That is, do not expect all available
tracing metrics to have the expected PID, instead, filter the available
metrics by PID and then check that the expected metrics have been
created.
  • Loading branch information
Bastian Krol committed Feb 22, 2023
1 parent 327b9e7 commit 6717745
Showing 1 changed file with 111 additions and 143 deletions.
254 changes: 111 additions & 143 deletions packages/collector/test/tracing/misc/tracing_metrics/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,59 +32,43 @@ mochaSuiteFn('tracing/tracing metrics', function () {
});
ProcessControls.setUpHooks(controls);

it('must send internal tracing metrics to agent', () =>
controls
.sendRequest({
method: 'POST',
path: '/create-spans'
})
.then(response => {
expect(response).to.equal('OK');
return testUtils.retry(() =>
agentControls.getSpans().then(spans => {
const httpEntry = expectHttpEntry(spans, '/create-spans');
expectExit(spans, httpEntry, 'exit-1');
expectExit(spans, httpEntry, 'exit-2');
expectExit(spans, httpEntry, 'exit-3');
})
);
})
.then(() =>
testUtils.retry(
() =>
agentControls.getTracingMetrics().then(tracingMetrics => {
expect(tracingMetrics).to.have.lengthOf.at.least(3);
expectCumulativeTracingMetrics(tracingMetrics, controls.getPid(), 4, 4, 0);
}),
retryTimeout
)
));
it('must send internal tracing metrics to agent', async () => {
const response = await controls.sendRequest({
method: 'POST',
path: '/create-spans'
});
expect(response).to.equal('OK');
await testUtils.retry(async () => {
const spans = await agentControls.getSpans();
const httpEntry = expectHttpEntry(spans, '/create-spans');
expectExit(spans, httpEntry, 'exit-1');
expectExit(spans, httpEntry, 'exit-2');
expectExit(spans, httpEntry, 'exit-3');
});
await testUtils.retry(async () => {
const tracingMetrics = await fetchTracingMetricsForProcess(agentControls, controls.getPid());
expect(tracingMetrics).to.have.lengthOf.at.least(3);
expectCumulativeTracingMetrics(tracingMetrics, 4, 4, 0);
}, retryTimeout);
});

it('must reveal non-finished spans', () =>
controls
.sendRequest({
method: 'POST',
path: '/create-unfinished-spans'
})
.then(response => {
expect(response).to.equal('OK');
return testUtils.retry(() =>
agentControls.getSpans().then(spans => {
const httpEntry = expectHttpEntry(spans, '/create-unfinished-spans');
expectExit(spans, httpEntry, 'exit-1');
})
);
})
.then(() =>
testUtils.retry(
() =>
agentControls.getTracingMetrics().then(tracingMetrics => {
expect(tracingMetrics).to.have.lengthOf.at.least(3);
expectCumulativeTracingMetrics(tracingMetrics, controls.getPid(), 3, 2, 0);
}),
retryTimeout
)
));
it('must reveal non-finished spans', async () => {
const response = await controls.sendRequest({
method: 'POST',
path: '/create-unfinished-spans'
});
expect(response).to.equal('OK');
await testUtils.retry(async () => {
const spans = await agentControls.getSpans();
const httpEntry = expectHttpEntry(spans, '/create-unfinished-spans');
expectExit(spans, httpEntry, 'exit-1');
});
await testUtils.retry(async () => {
const tracingMetrics = await fetchTracingMetricsForProcess(agentControls, controls.getPid());
expect(tracingMetrics).to.have.lengthOf.at.least(3);
expectCumulativeTracingMetrics(tracingMetrics, 3, 2, 0);
}, retryTimeout);
});
});

describe('when INSTANA_TRACER_METRICS_INTERVAL is configured explicitly', () => {
Expand All @@ -97,31 +81,25 @@ mochaSuiteFn('tracing/tracing metrics', function () {
});
ProcessControls.setUpHooks(controls);

it('must send internal tracing metrics every 100 ms', () =>
controls
.sendRequest({
method: 'POST',
path: '/create-spans'
})
.then(response => {
expect(response).to.equal('OK');
return testUtils.retry(() =>
agentControls.getSpans().then(spans => {
const httpEntry = expectHttpEntry(spans, '/create-spans');
expectExit(spans, httpEntry, 'exit-1');
expectExit(spans, httpEntry, 'exit-2');
expectExit(spans, httpEntry, 'exit-3');
})
);
})
.then(() => delay(1000))
.then(() =>
testUtils.retry(() =>
agentControls.getTracingMetrics().then(tracingMetrics => {
expect(tracingMetrics).to.have.lengthOf.at.least(10);
})
)
));
it('must send internal tracing metrics every 100 ms', async () => {
const response = await controls.sendRequest({
method: 'POST',
path: '/create-spans'
});
expect(response).to.equal('OK');
await testUtils.retry(async () => {
const spans = await agentControls.getSpans();
const httpEntry = expectHttpEntry(spans, '/create-spans');
expectExit(spans, httpEntry, 'exit-1');
expectExit(spans, httpEntry, 'exit-2');
expectExit(spans, httpEntry, 'exit-3');
});
await delay(1000);
await testUtils.retry(async () => {
const tracingMetrics = await fetchTracingMetricsForProcess(agentControls, controls.getPid());
expect(tracingMetrics).to.have.lengthOf.at.least(10);
});
});
});

describe('when tracing is not enabled', () => {
Expand All @@ -132,23 +110,18 @@ mochaSuiteFn('tracing/tracing metrics', function () {
});
ProcessControls.setUpHooks(controls);

it('must not collect any tracing metrics', () =>
controls
.sendRequest({
method: 'POST',
path: '/create-spans'
})
.then(response => {
expect(response).to.equal('OK');
return testUtils.retry(
() =>
agentControls.getTracingMetrics().then(tracingMetrics => {
expect(tracingMetrics).to.have.lengthOf.at.least(3);
expectCumulativeTracingMetrics(tracingMetrics, controls.getPid(), 0, 0, 0);
}),
retryTimeout
);
}));
it('must not collect any tracing metrics', async () => {
const response = await controls.sendRequest({
method: 'POST',
path: '/create-spans'
});
expect(response).to.equal('OK');
await testUtils.retry(async () => {
const tracingMetrics = await fetchTracingMetricsForProcess(agentControls, controls.getPid());
expect(tracingMetrics).to.have.lengthOf.at.least(3);
expectCumulativeTracingMetrics(tracingMetrics, 0, 0, 0);
}, retryTimeout);
});
});

describe('when dropping spans', () => {
Expand All @@ -167,25 +140,20 @@ mochaSuiteFn('tracing/tracing metrics', function () {
}
}).registerTestHooks();

it('must reveal dropped spans', () =>
controls
.sendRequest({
method: 'POST',
path: '/create-spans'
})
.then(response => {
expect(response).to.equal('OK');
return testUtils.retry(
() =>
customeAgentControls.getTracingMetrics().then(tracingMetrics => {
expect(tracingMetrics).to.have.lengthOf.at.least(3);
// With maxSpanBuffer = 1 we always keep 1 span in the buffer which is not dropped, the test creates
// 4 spans overall (one http entry and three SDK exits), hence we only expect three dropped spans.
expectCumulativeTracingMetrics(tracingMetrics, controls.getPid(), 4, 4, 3);
}),
retryTimeout
);
}));
it('must reveal dropped spans', async () => {
const response = await controls.sendRequest({
method: 'POST',
path: '/create-spans'
});
expect(response).to.equal('OK');
await testUtils.retry(async () => {
const tracingMetrics = await fetchTracingMetricsForProcess(customeAgentControls, controls.getPid());
expect(tracingMetrics).to.have.lengthOf.at.least(3);
// With maxSpanBuffer = 1 we always keep 1 span in the buffer which is not dropped, the test creates
// 4 spans overall (one http entry and three SDK exits), hence we only expect three dropped spans.
expectCumulativeTracingMetrics(tracingMetrics, 4, 4, 3);
}, retryTimeout);
});
});

describe('when agent does not support the tracermetrics endpoint', () => {
Expand All @@ -202,44 +170,44 @@ mochaSuiteFn('tracing/tracing metrics', function () {
}
}).registerTestHooks();

it('must not call POST /tracermetrics multiple times', () =>
controls
.sendRequest({
method: 'POST',
path: '/create-spans'
})
.then(response => {
expect(response).to.equal('OK');
return testUtils.retry(() =>
customeAgentControls.getSpans().then(spans => {
const httpEntry = expectHttpEntry(spans, '/create-spans');
expectExit(spans, httpEntry, 'exit-1');
expectExit(spans, httpEntry, 'exit-2');
expectExit(spans, httpEntry, 'exit-3');
})
);
})
// Wait a bit to give the tracer a chance to call POST /tracermetrics multiple times (which it should not, but
// we need to make sure the not only passes because we terminated it to soon).
// Note that we configured INSTANA_TRACER_METRICS_INTERVAL=100 so waiting 500 ms should be plenty.
.then(() => delay(500))
.then(() =>
customeAgentControls.getTracingMetrics().then(tracingMetrics => {
// Make sure the tracer only called the tracermetrics endpoint once and then stopped doing that after
// receiving an HTTP 404.
expect(tracingMetrics).to.have.lengthOf(1);
})
));
it('must not call POST /tracermetrics multiple times', async () => {
const response = await controls.sendRequest({
method: 'POST',
path: '/create-spans'
});
expect(response).to.equal('OK');
await testUtils.retry(async () => {
const spans = await customeAgentControls.getSpans();
const httpEntry = expectHttpEntry(spans, '/create-spans');
expectExit(spans, httpEntry, 'exit-1');
expectExit(spans, httpEntry, 'exit-2');
expectExit(spans, httpEntry, 'exit-3');
});

// Wait a bit to give the tracer a chance to call POST /tracermetrics multiple times (which it should not, but
// we need to make sure the not only passes because we terminated it to soon).
// Note that we configured INSTANA_TRACER_METRICS_INTERVAL=100 so waiting 500 ms should be plenty.
await delay(500);
const tracingMetrics = await fetchTracingMetricsForProcess(customeAgentControls, controls.getPid());

// Make sure the tracer only called the tracermetrics endpoint once and then stopped doing that after
// receiving an HTTP 404.
expect(tracingMetrics).to.have.lengthOf(1);
});
});
});

function expectCumulativeTracingMetrics(tracingMetrics, expectedPid, expectedOpened, expectedClosed, expectedDropped) {
async function fetchTracingMetricsForProcess(agentControls, pid) {
const tracingMetrics = await agentControls.getTracingMetrics();
return tracingMetrics.filter(metrics => metrics.pid === pid);
}

function expectCumulativeTracingMetrics(tracingMetrics, expectedOpened, expectedClosed, expectedDropped) {
let actualOpened = 0;
let actualClosed = 0;
let actualDropped = 0;
tracingMetrics.forEach(data => {
expect(data.tracer).to.not.exist;
expect(data.pid).to.equal(expectedPid);
actualOpened += data.metrics.opened;
actualClosed += data.metrics.closed;
actualDropped += data.metrics.dropped;
Expand Down

0 comments on commit 6717745

Please sign in to comment.