Skip to content

Commit

Permalink
[7.x] [Telemetry] oss api tests (#64602) (#64815)
Browse files Browse the repository at this point in the history
* [Telemetry] oss api tests (#64602)

* Adds telemetry API tests for oss

* Modifies test expectations to match that within oss

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

* Update telemetry_local.js

debugs backport issue

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
TinaHeiligers and elasticmachine committed Apr 29, 2020
1 parent 3ed2f11 commit 3c940e2
Show file tree
Hide file tree
Showing 5 changed files with 342 additions and 0 deletions.
1 change: 1 addition & 0 deletions test/api_integration/apis/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ export default function({ loadTestFile }) {
loadTestFile(require.resolve('./status'));
loadTestFile(require.resolve('./stats'));
loadTestFile(require.resolve('./ui_metric'));
loadTestFile(require.resolve('./telemetry'));
});
}
26 changes: 26 additions & 0 deletions test/api_integration/apis/telemetry/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

export default function({ loadTestFile }) {
describe('Telemetry', () => {
loadTestFile(require.resolve('./telemetry_local'));
loadTestFile(require.resolve('./opt_in'));
loadTestFile(require.resolve('./telemetry_optin_notice_seen'));
});
}
123 changes: 123 additions & 0 deletions test/api_integration/apis/telemetry/opt_in.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import expect from '@kbn/expect';

import { TelemetrySavedObjectAttributes } from 'src/plugins/telemetry/server/telemetry_repository';
import { FtrProviderContext } from '../../ftr_provider_context';

export default function optInTest({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const kibanaServer = getService('kibanaServer');
describe('/api/telemetry/v2/optIn API', () => {
let defaultAttributes: TelemetrySavedObjectAttributes;
let kibanaVersion: any;
before(async () => {
const kibanaVersionAccessor = kibanaServer.version;
kibanaVersion = await kibanaVersionAccessor.get();
defaultAttributes =
(await getSavedObjectAttributes(supertest).catch(err => {
if (err.message === 'expected 200 "OK", got 404 "Not Found"') {
return null;
}
throw err;
})) || {};

expect(typeof kibanaVersion).to.eql('string');
expect(kibanaVersion.length).to.be.greaterThan(0);
});

afterEach(async () => {
await updateSavedObjectAttributes(supertest, defaultAttributes);
});

it('should support sending false with allowChangingOptInStatus true', async () => {
await updateSavedObjectAttributes(supertest, {
...defaultAttributes,
allowChangingOptInStatus: true,
});
await postTelemetryV2Optin(supertest, false, 200);
const { enabled, lastVersionChecked } = await getSavedObjectAttributes(supertest);
expect(enabled).to.be(false);
expect(lastVersionChecked).to.be(kibanaVersion);
});

it('should support sending true with allowChangingOptInStatus true', async () => {
await updateSavedObjectAttributes(supertest, {
...defaultAttributes,
allowChangingOptInStatus: true,
});
await postTelemetryV2Optin(supertest, true, 200);
const { enabled, lastVersionChecked } = await getSavedObjectAttributes(supertest);
expect(enabled).to.be(true);
expect(lastVersionChecked).to.be(kibanaVersion);
});

it('should not support sending false with allowChangingOptInStatus false', async () => {
await updateSavedObjectAttributes(supertest, {
...defaultAttributes,
allowChangingOptInStatus: false,
});
await postTelemetryV2Optin(supertest, false, 400);
});

it('should not support sending true with allowChangingOptInStatus false', async () => {
await updateSavedObjectAttributes(supertest, {
...defaultAttributes,
allowChangingOptInStatus: false,
});
await postTelemetryV2Optin(supertest, true, 400);
});

it('should not support sending null', async () => {
await postTelemetryV2Optin(supertest, null, 400);
});

it('should not support sending junk', async () => {
await postTelemetryV2Optin(supertest, 42, 400);
});
});
}

async function postTelemetryV2Optin(supertest: any, value: any, statusCode: number): Promise<any> {
const { body } = await supertest
.post('/api/telemetry/v2/optIn')
.set('kbn-xsrf', 'xxx')
.send({ enabled: value })
.expect(statusCode);

return body;
}

async function updateSavedObjectAttributes(
supertest: any,
attributes: TelemetrySavedObjectAttributes
): Promise<any> {
return await supertest
.post('/api/saved_objects/telemetry/telemetry')
.query({ overwrite: true })
.set('kbn-xsrf', 'xxx')
.send({ attributes })
.expect(200);
}

async function getSavedObjectAttributes(supertest: any): Promise<TelemetrySavedObjectAttributes> {
const { body } = await supertest.get('/api/saved_objects/telemetry/telemetry').expect(200);
return body.attributes;
}
133 changes: 133 additions & 0 deletions test/api_integration/apis/telemetry/telemetry_local.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import expect from '@kbn/expect';
import _ from 'lodash';

/*
* Create a single-level array with strings for all the paths to values in the
* source object, up to 3 deep. Going deeper than 3 causes a bit too much churn
* in the tests.
*/
function flatKeys(source) {
const recursivelyFlatKeys = (obj, path = [], depth = 0) => {
return depth < 3 && _.isObject(obj)
? _.map(obj, (v, k) => recursivelyFlatKeys(v, [...path, k], depth + 1))
: path.join('.');
};

return _.uniq(_.flattenDeep(recursivelyFlatKeys(source))).sort((a, b) => a.localeCompare(b));
}

export default function({ getService }) {
const supertest = getService('supertest');

describe('/api/telemetry/v2/clusters/_stats', () => {
it('should pull local stats and validate data types', async () => {
const timeRange = {
min: '2018-07-23T22:07:00Z',
max: '2018-07-23T22:13:00Z',
};

const { body } = await supertest
.post('/api/telemetry/v2/clusters/_stats')
.set('kbn-xsrf', 'xxx')
.send({ timeRange, unencrypted: true })
.expect(200);

expect(body.length).to.be(1);
const stats = body[0];
expect(stats.collection).to.be('local');
expect(stats.stack_stats.kibana.count).to.be.a('number');
expect(stats.stack_stats.kibana.indices).to.be.a('number');
expect(stats.stack_stats.kibana.os.platforms[0].platform).to.be.a('string');
expect(stats.stack_stats.kibana.os.platforms[0].count).to.be(1);
expect(stats.stack_stats.kibana.os.platformReleases[0].platformRelease).to.be.a('string');
expect(stats.stack_stats.kibana.os.platformReleases[0].count).to.be(1);
expect(stats.stack_stats.kibana.plugins.telemetry.opt_in_status).to.be(false);
expect(stats.stack_stats.kibana.plugins.telemetry.usage_fetcher).to.be.a('string');
expect(stats.stack_stats.kibana.plugins.stack_management).to.be.an('object');
expect(stats.stack_stats.kibana.plugins.ui_metric).to.be.an('object');
expect(stats.stack_stats.kibana.plugins.application_usage).to.be.an('object');
expect(stats.stack_stats.kibana.plugins.kql.defaultQueryLanguage).to.be.a('string');
expect(stats.stack_stats.kibana.plugins['tsvb-validation']).to.be.an('object');
expect(stats.stack_stats.kibana.plugins.localization).to.be.an('object');
expect(stats.stack_stats.kibana.plugins.csp.strict).to.be(false);
expect(stats.stack_stats.kibana.plugins.csp.warnLegacyBrowsers).to.be(true);
expect(stats.stack_stats.kibana.plugins.csp.rulesChangedFromDefault).to.be(false);
});

it('should pull local stats and validate fields', async () => {
const timeRange = {
min: '2018-07-23T22:07:00Z',
max: '2018-07-23T22:13:00Z',
};

const { body } = await supertest
.post('/api/telemetry/v2/clusters/_stats')
.set('kbn-xsrf', 'xxx')
.send({ timeRange, unencrypted: true })
.expect(200);

const stats = body[0];

const actual = flatKeys(stats);
expect(actual).to.be.an('array');
const expected = [
'cluster_name',
'cluster_stats.cluster_uuid',
'cluster_stats.indices.analysis',
'cluster_stats.indices.completion',
'cluster_stats.indices.count',
'cluster_stats.indices.docs',
'cluster_stats.indices.fielddata',
'cluster_stats.indices.mappings',
'cluster_stats.indices.query_cache',
'cluster_stats.indices.segments',
'cluster_stats.indices.shards',
'cluster_stats.indices.store',
'cluster_stats.nodes.count',
'cluster_stats.nodes.discovery_types',
'cluster_stats.nodes.fs',
'cluster_stats.nodes.ingest',
'cluster_stats.nodes.jvm',
'cluster_stats.nodes.network_types',
'cluster_stats.nodes.os',
'cluster_stats.nodes.packaging_types',
'cluster_stats.nodes.plugins',
'cluster_stats.nodes.process',
'cluster_stats.nodes.versions',
'cluster_stats.status',
'cluster_stats.timestamp',
'cluster_uuid',
'collection',
'collectionSource',
'stack_stats.kibana.count',
'stack_stats.kibana.indices',
'stack_stats.kibana.os',
'stack_stats.kibana.plugins',
'stack_stats.kibana.versions',
'timestamp',
'version',
];

expect(expected.every(m => actual.includes(m))).to.be.ok();
});
});
}
59 changes: 59 additions & 0 deletions test/api_integration/apis/telemetry/telemetry_optin_notice_seen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import expect from '@kbn/expect';
import { Client, DeleteDocumentParams, GetParams, GetResponse } from 'elasticsearch';
import { TelemetrySavedObjectAttributes } from 'src/plugins/telemetry/server/telemetry_repository';
import { FtrProviderContext } from '../../ftr_provider_context';

export default function optInTest({ getService }: FtrProviderContext) {
const client: Client = getService('legacyEs');
const supertest = getService('supertest');

describe('/api/telemetry/v2/userHasSeenNotice API Telemetry User has seen OptIn Notice', () => {
it('should update telemetry setting field via PUT', async () => {
try {
await client.delete({
index: '.kibana',
id: 'telemetry:telemetry',
} as DeleteDocumentParams);
} catch (err) {
if (err.statusCode !== 404) {
throw err;
}
}

await supertest
.put('/api/telemetry/v2/userHasSeenNotice')
.set('kbn-xsrf', 'xxx')
.expect(200);

const {
_source: { telemetry },
}: GetResponse<{
telemetry: TelemetrySavedObjectAttributes;
}> = await client.get({
index: '.kibana',
id: 'telemetry:telemetry',
} as GetParams);

expect(telemetry.userHasSeenNotice).to.be(true);
});
});
}

0 comments on commit 3c940e2

Please sign in to comment.