mirror of
https://github.com/elastic/kibana.git
synced 2025-04-27 03:08:29 -04:00
Updates files outside of x-pack to be triple-licensed under Elastic License 2.0, AGPL 3.0, or SSPL 1.0.
251 lines
8.1 KiB
JavaScript
251 lines
8.1 KiB
JavaScript
/*
|
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
* or more contributor license agreements. Licensed under the "Elastic License
|
|
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
|
* Public License v 1"; you may not use this file except in compliance with, at
|
|
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
|
* License v3.0 only", or the "Server Side Public License, v 1".
|
|
*/
|
|
|
|
import expect from '@kbn/expect';
|
|
import { schema } from '@kbn/config-schema';
|
|
|
|
const processSchema = schema.object({
|
|
pid: schema.number(),
|
|
uptime_ms: schema.number(),
|
|
event_loop_delay: schema.number(),
|
|
event_loop_delay_histogram: schema.object({
|
|
min: schema.number(),
|
|
mean: schema.number(),
|
|
exceeds: schema.number(),
|
|
stddev: schema.number(),
|
|
max: schema.number(),
|
|
from_timestamp: schema.string(),
|
|
last_updated_at: schema.string(),
|
|
percentiles: schema.object({
|
|
50: schema.number(),
|
|
75: schema.number(),
|
|
95: schema.number(),
|
|
99: schema.number(),
|
|
}),
|
|
}),
|
|
event_loop_utilization: schema.object({
|
|
active: schema.number(),
|
|
idle: schema.number(),
|
|
utilization: schema.number(),
|
|
}),
|
|
memory: schema.object({
|
|
heap: schema.object({
|
|
total_bytes: schema.number(),
|
|
used_bytes: schema.number(),
|
|
size_limit: schema.number(),
|
|
}),
|
|
resident_set_size_bytes: schema.number(),
|
|
external_bytes: schema.number(),
|
|
array_buffers_bytes: schema.number(),
|
|
}),
|
|
});
|
|
|
|
const baseResponseSchema = schema.object({
|
|
last_updated: schema.string(),
|
|
collection_interval_ms: schema.number(),
|
|
usage: schema.object({}),
|
|
kibana: schema.object({
|
|
name: schema.string(),
|
|
uuid: schema.string(),
|
|
host: schema.string(),
|
|
index: schema.string(),
|
|
locale: schema.string(),
|
|
transport_address: schema.string(),
|
|
version: schema.string(),
|
|
snapshot: schema.boolean(),
|
|
status: schema.string(),
|
|
}),
|
|
process: processSchema,
|
|
processes: schema.arrayOf(processSchema),
|
|
os: schema.object({
|
|
platform: schema.string(),
|
|
platform_release: schema.string(),
|
|
distro: schema.maybe(schema.string()),
|
|
distro_release: schema.maybe(schema.string()),
|
|
memory: schema.object({
|
|
free_bytes: schema.number(),
|
|
used_bytes: schema.number(),
|
|
total_bytes: schema.number(),
|
|
}),
|
|
uptime_ms: schema.number(),
|
|
load: schema.object({
|
|
'1m': schema.number(),
|
|
'5m': schema.number(),
|
|
'15m': schema.number(),
|
|
}),
|
|
cpuacct: schema.maybe(
|
|
schema.object({
|
|
control_group: schema.string(),
|
|
usage_nanos: schema.number(),
|
|
})
|
|
),
|
|
cpu: schema.maybe(
|
|
schema.object({
|
|
control_group: schema.string(),
|
|
cfs_period_micros: schema.number(),
|
|
cfs_quota_micros: schema.number(),
|
|
stat: schema.object({
|
|
number_of_elapsed_periods: schema.number(),
|
|
number_of_times_throttled: schema.number(),
|
|
time_throttled_nanos: schema.number(),
|
|
}),
|
|
})
|
|
),
|
|
cgroup_memory: schema.maybe(
|
|
schema.object({
|
|
current_in_bytes: schema.number(),
|
|
swap_current_in_bytes: schema.number(),
|
|
})
|
|
),
|
|
}),
|
|
elasticsearch_client: schema.object({
|
|
total_active_sockets: schema.number(),
|
|
total_idle_sockets: schema.number(),
|
|
total_queued_requests: schema.number(),
|
|
}),
|
|
response_times: schema.object({
|
|
avg_ms: schema.maybe(schema.number()),
|
|
max_ms: schema.maybe(schema.number()),
|
|
}),
|
|
requests: schema.object({
|
|
total: schema.number(),
|
|
disconnects: schema.number(),
|
|
status_codes: schema.recordOf(schema.number(), schema.number()),
|
|
}),
|
|
concurrent_connections: schema.number(),
|
|
});
|
|
|
|
const legacyResponseSchema = baseResponseSchema.extends({
|
|
clusterUuid: schema.string(),
|
|
});
|
|
|
|
const statsResponseSchema = baseResponseSchema.extends({
|
|
cluster_uuid: schema.maybe(schema.string()),
|
|
});
|
|
|
|
const assertStatsAndMetrics = (body, legacy = false) => {
|
|
try {
|
|
if (legacy) {
|
|
legacyResponseSchema.validate(body);
|
|
} else {
|
|
statsResponseSchema.validate(body);
|
|
}
|
|
} catch (e) {
|
|
expect().fail(`Expected /api/stats response to match schema: ${e.message}`);
|
|
}
|
|
};
|
|
|
|
export default function ({ getService }) {
|
|
const supertest = getService('supertest');
|
|
const kibanaServer = getService('kibanaServer');
|
|
|
|
describe('kibana stats api', () => {
|
|
before(async () => {
|
|
await kibanaServer.importExport.load(
|
|
'test/api_integration/fixtures/kbn_archiver/saved_objects/basic.json'
|
|
);
|
|
});
|
|
after(async () => {
|
|
await kibanaServer.importExport.unload(
|
|
'test/api_integration/fixtures/kbn_archiver/saved_objects/basic.json'
|
|
);
|
|
});
|
|
|
|
describe('basic', () => {
|
|
it('should return the stats without cluster_uuid with no query string params', () => {
|
|
return supertest
|
|
.get('/api/stats')
|
|
.expect('Content-Type', /json/)
|
|
.expect(200)
|
|
.then(({ body }) => {
|
|
expect(body.cluster_uuid).to.be(undefined);
|
|
assertStatsAndMetrics(body);
|
|
});
|
|
});
|
|
it(`should return the stats without cluster_uuid with 'extended' query string param = false`, () => {
|
|
return supertest
|
|
.get('/api/stats?extended=false')
|
|
.expect('Content-Type', /json/)
|
|
.expect(200)
|
|
.then(({ body }) => {
|
|
expect(body.cluster_uuid).to.be(undefined);
|
|
assertStatsAndMetrics(body);
|
|
});
|
|
});
|
|
});
|
|
|
|
// TODO load an es archive and verify the counts in saved object usage info
|
|
describe('extended', () => {
|
|
it(`should return the stats, cluster_uuid, and usage with 'extended' query string param present`, () => {
|
|
return supertest
|
|
.get('/api/stats?extended')
|
|
.expect('Content-Type', /json/)
|
|
.expect(200)
|
|
.then(({ body }) => {
|
|
expect(body.cluster_uuid).to.be.a('string');
|
|
expect(body.usage).to.be.an('object'); // no usage collectors have been registered so usage is an empty object
|
|
expect(body.usage).to.eql({});
|
|
assertStatsAndMetrics(body);
|
|
});
|
|
});
|
|
|
|
it(`should return the stats, cluster_uuid, and usage with 'extended' query string param = true`, () => {
|
|
return supertest
|
|
.get('/api/stats?extended=true')
|
|
.expect('Content-Type', /json/)
|
|
.expect(200)
|
|
.then(({ body }) => {
|
|
expect(body.cluster_uuid).to.be.a('string');
|
|
expect(body.usage).to.be.an('object');
|
|
expect(body.usage).to.eql({});
|
|
assertStatsAndMetrics(body);
|
|
});
|
|
});
|
|
|
|
describe('legacy', () => {
|
|
it(`should return return the 'extended' data in the old format with 'legacy' query string param present`, () => {
|
|
return supertest
|
|
.get('/api/stats?extended&legacy')
|
|
.expect('Content-Type', /json/)
|
|
.expect(200)
|
|
.then(({ body }) => {
|
|
expect(body.clusterUuid).to.be.a('string');
|
|
expect(body.usage).to.be.an('object'); // no usage collectors have been registered so usage is an empty object
|
|
expect(body.usage).to.eql({});
|
|
assertStatsAndMetrics(body, true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('exclude usage', () => {
|
|
it('should include an empty usage object from the API response', () => {
|
|
return supertest
|
|
.get('/api/stats?extended&exclude_usage')
|
|
.expect('Content-Type', /json/)
|
|
.expect(200)
|
|
.then(({ body }) => {
|
|
expect(body).to.have.property('usage');
|
|
expect(body.usage).to.eql({});
|
|
});
|
|
});
|
|
|
|
it('should include an empty usage object from the API response if `legacy` is provided', () => {
|
|
return supertest
|
|
.get('/api/stats?extended&exclude_usage&legacy')
|
|
.expect('Content-Type', /json/)
|
|
.expect(200)
|
|
.then(({ body }) => {
|
|
expect(body).to.have.property('usage');
|
|
expect(body.usage).to.eql({});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|