From 67c15f8662ee0cd1bc9aa9fa5854ba42e5006a80 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 4 May 2022 12:26:08 -0300 Subject: [PATCH 01/16] update type definitions --- package-lock.json | 14 +++++++------- package.json | 4 ++-- src/__tests__/testUtils/index.js | 2 +- ts-tests/index.ts | 3 +++ ts-tests/package.json | 2 +- types/splitio.d.ts | 20 +++++++++++++++++++- 6 files changed, 33 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8a390b5ba..d5070dfa5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.18.1", + "version": "10.18.2-rc.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -437,9 +437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.1.tgz", - "integrity": "sha512-otHrBCNJ2BP2tby31juRFfBETYzBVJZVecg1d27o9v5IKsv9uhzF9Q8B35GPpbndFht/596O2OlxKH5HdbjBwQ==", + "version": "1.3.2-rc.0", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.0.tgz", + "integrity": "sha512-ShSBphAAZHVyBtZA5A3rAuKKaUxmWfnli/tCs2qM16NSCVHWbMaxFomgL+4oLg7/UdPDAUeoHZLj5emJOWMPtA==", "requires": { "tslib": "^2.3.1" } @@ -6159,9 +6159,9 @@ } }, "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "tty-browserify": { "version": "0.0.1", diff --git a/package.json b/package.json index ee0e0149c..31b37326f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.18.1", + "version": "10.18.2-rc.0", "description": "Split SDK", "files": [ "README.md", @@ -32,7 +32,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.3.1", + "@splitsoftware/splitio-commons": "1.3.2-rc.0", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "ioredis": "^4.28.0", diff --git a/src/__tests__/testUtils/index.js b/src/__tests__/testUtils/index.js index 885bcd1c1..2d662ed56 100644 --- a/src/__tests__/testUtils/index.js +++ b/src/__tests__/testUtils/index.js @@ -1,7 +1,7 @@ const DEFAULT_ERROR_MARGIN = 50; // 0.05 secs /** - * Assert if an `actual` and `expected` numeric values are nearlyEqual. + * Assert if an `actual` and `expected` numeric values are nearly equal. * * @param {number} actual actual time lapse in millis * @param {number} expected expected time lapse in millis diff --git a/ts-tests/index.ts b/ts-tests/index.ts index 0f2d111d4..5c2e75377 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -478,6 +478,7 @@ let fullBrowserSettings: SplitIO.IBrowserSettings = { impressionsRefreshRate: 1, impressionsQueueSize: 1, metricsRefreshRate: 1, + telemetryRefreshRate: 1, segmentsRefreshRate: 1, offlineRefreshRate: 1, eventsPushRate: 1, @@ -527,6 +528,7 @@ let fullNodeSettings: SplitIO.INodeSettings = { impressionsRefreshRate: 1, impressionsQueueSize: 1, metricsRefreshRate: 1, + telemetryRefreshRate: 1, segmentsRefreshRate: 1, offlineRefreshRate: 1, eventsPushRate: 1, @@ -572,6 +574,7 @@ let fullAsyncSettings: SplitIO.INodeAsyncSettings = { impressionsRefreshRate: 1, impressionsQueueSize: 1, metricsRefreshRate: 1, + telemetryRefreshRate: 1, segmentsRefreshRate: 1, offlineRefreshRate: 1, eventsPushRate: 1, diff --git a/ts-tests/package.json b/ts-tests/package.json index 817b0252d..8d6336589 100644 --- a/ts-tests/package.json +++ b/ts-tests/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "repository": "splitio/javascript-client", "dependencies": { - "@types/node": "^14.18.12", + "@types/node": "^14.18.16", "typescript": "^3.7.4" } } diff --git a/types/splitio.d.ts b/types/splitio.d.ts index 53503861a..15ede60de 100644 --- a/types/splitio.d.ts +++ b/types/splitio.d.ts @@ -71,7 +71,11 @@ interface ISettings { featuresRefreshRate: number, impressionsRefreshRate: number, impressionsQueueSize: number, - metricsRefreshRate: number, + /** + * @deprecated + */ + metricsRefreshRate?: number, + telemetryRefreshRate: number, segmentsRefreshRate: number, offlineRefreshRate: number, eventsPushRate: number, @@ -297,8 +301,15 @@ interface INodeBasicSettings extends ISharedSettings { * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds. * @property {number} metricsRefreshRate * @default 120 + * @deprecated This parameter is ignored now. Use `telemetryRefreshRate` instead. */ metricsRefreshRate?: number, + /** + * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds. + * @property {number} telemetryRefreshRate + * @default 3600 + */ + telemetryRefreshRate?: number, /** * The SDK polls Split servers for changes to segment definitions. This parameter controls this polling period in seconds. * @property {number} segmentsRefreshRate @@ -947,8 +958,15 @@ declare namespace SplitIO { * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds. * @property {number} metricsRefreshRate * @default 120 + * @deprecated This parameter is ignored now. Use `telemetryRefreshRate` instead. */ metricsRefreshRate?: number, + /** + * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds. + * @property {number} telemetryRefreshRate + * @default 3600 + */ + telemetryRefreshRate?: number, /** * The SDK polls Split servers for changes to segment definitions. This parameter controls this polling period in seconds. * @property {number} segmentsRefreshRate From 7b264bff770e224109bdd91ac42bf5b9636d444b Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 4 May 2022 17:27:33 -0300 Subject: [PATCH 02/16] update platform object with now function --- package-lock.json | 6 +++--- package.json | 2 +- src/platform/browser.js | 4 +++- src/platform/node.js | 4 +++- src/settings/defaults/version.js | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index d5070dfa5..f84dc6f87 100644 --- a/package-lock.json +++ b/package-lock.json @@ -437,9 +437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.3.2-rc.0", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.0.tgz", - "integrity": "sha512-ShSBphAAZHVyBtZA5A3rAuKKaUxmWfnli/tCs2qM16NSCVHWbMaxFomgL+4oLg7/UdPDAUeoHZLj5emJOWMPtA==", + "version": "1.3.2-rc.1", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.1.tgz", + "integrity": "sha512-MVj3okk3WQhxtfFbT+xHGJHBYmcuYBc5Z24Sg/tIoV2rrfF9A/V8MtLFnJUdDM3Ue0tggb9dWpFKwUaGM7KSKw==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index 31b37326f..48238b4e7 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.3.2-rc.0", + "@splitsoftware/splitio-commons": "1.3.2-rc.1", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "ioredis": "^4.28.0", diff --git a/src/platform/browser.js b/src/platform/browser.js index feec1a7ad..9432f1d60 100644 --- a/src/platform/browser.js +++ b/src/platform/browser.js @@ -2,11 +2,13 @@ import { EventEmitter } from './EventEmitter'; import { getFetch } from '../platform/getFetch/browser'; import { getEventSource } from '../platform/getEventSource/browser'; import { BrowserSignalListener } from '@splitsoftware/splitio-commons/src/listeners/browser'; +import { now } from '@splitsoftware/splitio-commons/src/utils/timeTracker/now/browser'; export const platform = { getFetch, getEventSource, - EventEmitter + EventEmitter, + now }; export const SignalListener = BrowserSignalListener; diff --git a/src/platform/node.js b/src/platform/node.js index 5fb850afa..d3d2a93bb 100644 --- a/src/platform/node.js +++ b/src/platform/node.js @@ -3,12 +3,14 @@ import { getFetch } from '../platform/getFetch/node'; import { getEventSource } from '../platform/getEventSource/node'; import { getOptions } from '../platform/request/options/node'; import { NodeSignalListener } from '@splitsoftware/splitio-commons/src/listeners/node'; +import { now } from '@splitsoftware/splitio-commons/src/utils/timeTracker/now/node'; export const platform = { getOptions, getFetch, getEventSource, - EventEmitter + EventEmitter, + now }; export const SignalListener = NodeSignalListener; diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 457b9b5f8..88ff7331c 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.18.1'; +export const packageVersion = '10.18.2-rc.0'; From 2f6472419113d1e011ebf999aa34b7b2eac65b21 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 4 May 2022 18:41:21 -0300 Subject: [PATCH 03/16] telemetry endpoint --- src/__tests__/testUtils/index.js | 4 ++++ ts-tests/index.ts | 6 ++++-- types/splitio.d.ts | 11 +++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/__tests__/testUtils/index.js b/src/__tests__/testUtils/index.js index 2d662ed56..302e9449d 100644 --- a/src/__tests__/testUtils/index.js +++ b/src/__tests__/testUtils/index.js @@ -43,6 +43,7 @@ export function hasNoCacheHeader(fetchMockOpts) { return fetchMockOpts.headers['Cache-Control'] === 'no-cache'; } +const telemetryEndpointMatcher = /^\/v1\/metrics\/(config|usage)/; const eventsEndpointMatcher = /^\/(testImpressions|metrics|events)/; const authEndpointMatcher = /^\/v2\/auth/; const streamingEndpointMatcher = /^\/(sse|event-stream)/; @@ -56,6 +57,9 @@ const streamingEndpointMatcher = /^\/(sse|event-stream)/; * @return {String} completed url */ export function url(settings, target) { + if (telemetryEndpointMatcher.test(target)) { + return `${settings.urls.telemetry}${target}`; + } if (eventsEndpointMatcher.test(target)) { return `${settings.urls.events}${target}`; } diff --git a/ts-tests/index.ts b/ts-tests/index.ts index 5c2e75377..27926f4fc 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -495,7 +495,8 @@ let fullBrowserSettings: SplitIO.IBrowserSettings = { sdk: 'https://asd.com/sdk', events: 'https://asd.com/events', auth: 'https://asd.com/auth', - streaming: 'https://asd.com/streaming' + streaming: 'https://asd.com/streaming', + telemetry: 'https://asd.com/telemetry' }, features: mockedFeaturesMap, storage: { @@ -545,7 +546,8 @@ let fullNodeSettings: SplitIO.INodeSettings = { sdk: 'https://asd.com/sdk', events: 'https://asd.com/events', auth: 'https://asd.com/auth', - streaming: 'https://asd.com/streaming' + streaming: 'https://asd.com/streaming', + telemetry: 'https://asd.com/telemetry' }, features: mockedFeaturesPath, storage: { diff --git a/types/splitio.d.ts b/types/splitio.d.ts index 15ede60de..7a3a44398 100644 --- a/types/splitio.d.ts +++ b/types/splitio.d.ts @@ -97,7 +97,8 @@ interface ISettings { events: string, sdk: string, auth: string, - streaming: string + streaming: string, + telemetry: string }, readonly debug: boolean | LogLevel, readonly version: string, @@ -854,7 +855,13 @@ declare namespace SplitIO { * @property {string} streaming * @default 'https://streaming.split.io' */ - streaming?: string + streaming?: string, + /** + * String property to override the base URL where the SDK will post telemetry data. + * @property {string} telemetry + * @default 'https://telemetry.split.io/api' + */ + telemetry?: string }; /** From c6e67c684bc54ad6c0bf3440c65e72354f2a51a5 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Thu, 5 May 2022 15:40:29 -0300 Subject: [PATCH 04/16] updated impressionsRefreshRate --- package-lock.json | 6 +++--- package.json | 2 +- src/settings/defaults/node.js | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index f84dc6f87..3d5072a16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -437,9 +437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.3.2-rc.1", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.1.tgz", - "integrity": "sha512-MVj3okk3WQhxtfFbT+xHGJHBYmcuYBc5Z24Sg/tIoV2rrfF9A/V8MtLFnJUdDM3Ue0tggb9dWpFKwUaGM7KSKw==", + "version": "1.3.2-rc.3", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.3.tgz", + "integrity": "sha512-tv+j+TvlD0mMM3yLpVGEKhetY/sqMwjTyr8SeVCu/bJHQ9BRxUJ8rygJf54mTqoGbkn8X5/yIANRp4cb7cKc1Q==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index 48238b4e7..ebdda2816 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.3.2-rc.1", + "@splitsoftware/splitio-commons": "1.3.2-rc.3", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "ioredis": "^4.28.0", diff --git a/src/settings/defaults/node.js b/src/settings/defaults/node.js index 4087b5344..25b8e3894 100644 --- a/src/settings/defaults/node.js +++ b/src/settings/defaults/node.js @@ -16,8 +16,7 @@ export const defaults = { eventsFirstPushWindow: 0 }, scheduler: { - featuresRefreshRate: 5, - impressionsRefreshRate: 300 + featuresRefreshRate: 5 }, features: '.split', From 45ff05a74d74d2becac3fa5e3aaaaf2c12143fe6 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 6 May 2022 17:39:38 -0300 Subject: [PATCH 05/16] mock telemetry requests in NodeJS E2E tests --- src/__tests__/destroy/node.spec.js | 10 +++++ src/__tests__/errorCatching/node.spec.js | 3 +- src/__tests__/node.spec.js | 12 ++---- src/__tests__/nodeSuites/events.spec.js | 2 +- .../nodeSuites/impressions-listener.spec.js | 2 +- .../nodeSuites/impressions.debug.spec.js | 2 +- src/__tests__/nodeSuites/impressions.spec.js | 8 ++-- .../ip-addresses-setting.debug.spec.js | 23 ++++++------ .../nodeSuites/ip-addresses-setting.spec.js | 37 +++++++++---------- .../nodeSuites/push-fallbacking.spec.js | 2 +- .../push-initialization-nopush.spec.js | 2 +- .../push-initialization-retries.spec.js | 2 +- .../nodeSuites/push-refresh-token.spec.js | 2 + src/__tests__/push/node.spec.js | 3 ++ 14 files changed, 60 insertions(+), 50 deletions(-) diff --git a/src/__tests__/destroy/node.spec.js b/src/__tests__/destroy/node.spec.js index e24b3c8ef..0acb88e05 100644 --- a/src/__tests__/destroy/node.spec.js +++ b/src/__tests__/destroy/node.spec.js @@ -19,6 +19,7 @@ import impressionsMock from './impressions.json'; fetchMock.get(url(settings, '/splitChanges?since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.get(url(settings, '/splitChanges?since=-1500492097547'), { status: 200, body: splitChangesMock2 }); +fetchMock.postOnce(url(settings, '/v1/metrics/config'), 200); tape('SDK destroy for NodeJS', async function (assert) { const config = { @@ -74,6 +75,15 @@ tape('SDK destroy for NodeJS', async function (assert) { return 200; }); + // Assert we are sending telemetry stats while doing the destroy + fetchMock.postOnce(url(settings, '/v1/metrics/usage'), (url, opts) => { + const payload = JSON.parse(opts.body); + + assert.true(payload.sL > 0, 'Should flush telemetry stats with session length on destroy.'); + + return 200; + }); + await client.ready(); assert.equal(client.getTreatment('ut1', 'Single_Test'), 'on'); diff --git a/src/__tests__/errorCatching/node.spec.js b/src/__tests__/errorCatching/node.spec.js index 4e3de6657..df373acb2 100644 --- a/src/__tests__/errorCatching/node.spec.js +++ b/src/__tests__/errorCatching/node.spec.js @@ -24,7 +24,8 @@ const settings = settingsFactory({ fetchMock.get(url(settings, '/splitChanges?since=-1'), { status: 200, body: splitChangesMock1 }, responseDelay); fetchMock.get(url(settings, '/splitChanges?since=1500492097547'), { status: 200, body: splitChangesMock2 }, responseDelay); fetchMock.get(url(settings, '/splitChanges?since=1500492297547'), { status: 200, body: splitChangesMock3 }, responseDelay); - +fetchMock.postOnce(url(settings, '/v1/metrics/config'), 200); // SDK_READY +fetchMock.postOnce(url(settings, '/v1/metrics/usage'), 200); // SDK destroyed tape('Error catching on callbacks', assert => { const assertionsPlanned = 3; diff --git a/src/__tests__/node.spec.js b/src/__tests__/node.spec.js index f6ec2e308..903cd70be 100644 --- a/src/__tests__/node.spec.js +++ b/src/__tests__/node.spec.js @@ -19,13 +19,6 @@ import fetchSpecificSplits from './nodeSuites/fetch-specific-splits.spec'; import splitChangesMock1 from './mocks/splitchanges.since.-1.json'; import splitChangesMock2 from './mocks/splitchanges.since.1457552620999.json'; -const settings = settingsFactory({ - core: { - authorizationKey: '' - }, - streamingEnabled: false -}); - const config = { core: { authorizationKey: '' @@ -33,12 +26,13 @@ const config = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, // for now I don't want to publish metrics during E2E run. + telemetryRefreshRate: 3000, // for now I don't want to publish telemetry stats during E2E run. impressionsRefreshRate: 3000 // for now I don't want to publish impressions during E2E run. }, streamingEnabled: false }; +const settings = settingsFactory(config); const key = 'facundo@split.io'; fetchMock.get(url(settings, '/splitChanges?since=-1'), { status: 200, body: splitChangesMock1 }); @@ -54,6 +48,8 @@ fetchMock.get(new RegExp(`${url(settings, '/segmentChanges')}/*`), { }); fetchMock.post(url(settings, '/testImpressions/bulk'), 200); fetchMock.post(url(settings, '/testImpressions/count'), 200); +fetchMock.post(url(settings, '/v1/metrics/config'), 200); +fetchMock.post(url(settings, '/v1/metrics/usage'), 200); tape('## Node JS - E2E CI Tests ##', async function (assert) { /* Check client evaluations. */ diff --git a/src/__tests__/nodeSuites/events.spec.js b/src/__tests__/nodeSuites/events.spec.js index 0accdc63f..062e96560 100644 --- a/src/__tests__/nodeSuites/events.spec.js +++ b/src/__tests__/nodeSuites/events.spec.js @@ -17,7 +17,7 @@ const baseSettings = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, + telemetryRefreshRate: 3000, impressionsRefreshRate: 3000, eventsPushRate: 3000 }, diff --git a/src/__tests__/nodeSuites/impressions-listener.spec.js b/src/__tests__/nodeSuites/impressions-listener.spec.js index 3c6888724..eecc4b6c6 100644 --- a/src/__tests__/nodeSuites/impressions-listener.spec.js +++ b/src/__tests__/nodeSuites/impressions-listener.spec.js @@ -20,7 +20,7 @@ const config = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, + telemetryRefreshRate: 3000, impressionsRefreshRate: 3000 }, startup: { diff --git a/src/__tests__/nodeSuites/impressions.debug.spec.js b/src/__tests__/nodeSuites/impressions.debug.spec.js index e43fe62e6..fa38d4175 100644 --- a/src/__tests__/nodeSuites/impressions.debug.spec.js +++ b/src/__tests__/nodeSuites/impressions.debug.spec.js @@ -25,7 +25,7 @@ const config = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, + telemetryRefreshRate: 3000, impressionsRefreshRate: 3000, impressionsQueueSize: 3 // flush impressions when 3 are queued }, diff --git a/src/__tests__/nodeSuites/impressions.spec.js b/src/__tests__/nodeSuites/impressions.spec.js index 6b8121018..b269ebaa8 100644 --- a/src/__tests__/nodeSuites/impressions.spec.js +++ b/src/__tests__/nodeSuites/impressions.spec.js @@ -27,8 +27,8 @@ const config = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, - impressionsRefreshRate: 5 + telemetryRefreshRate: 3000, + impressionsRefreshRate: 5 // No effect, since min is 300 }, urls: baseUrls, startup: { @@ -45,7 +45,9 @@ export default async function(key, fetchMock, assert) { fetchMock.get(url(settings, '/splitChanges?since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: {since:10, till:10, name: 'segmentName', added: [], removed: []} }); - const splitio = SplitFactory(config); + const splitio = SplitFactory(config, ({settings}) => { + settings.scheduler.impressionsRefreshRate = 5000; // 5 secs + }); const client = splitio.client(); let evaluationsStart = 0, readyEvaluationsStart = 0, evaluationsEnd = 0; diff --git a/src/__tests__/nodeSuites/ip-addresses-setting.debug.spec.js b/src/__tests__/nodeSuites/ip-addresses-setting.debug.spec.js index e982d38e0..8db9bdbc6 100644 --- a/src/__tests__/nodeSuites/ip-addresses-setting.debug.spec.js +++ b/src/__tests__/nodeSuites/ip-addresses-setting.debug.spec.js @@ -3,7 +3,7 @@ import ipFunction from 'ip'; import { SplitFactory } from '../../'; import { settingsFactory } from '../../settings'; import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; -import { DEBUG, STANDALONE_MODE } from '@splitsoftware/splitio-commons/src/utils/constants'; +import { DEBUG } from '@splitsoftware/splitio-commons/src/utils/constants'; import { url } from '../testUtils'; // Header keys and expected values. Expected values are obtained with the runtime function evaluated with IPAddressesEnabled in true. @@ -14,12 +14,6 @@ const HOSTNAME_VALUE = osFunction.hostname(); // Refresh rates are set to 1 second to finish the test quickly. Otherwise, it would finish in 1 minute (60 seconds is the default value) const baseConfig = { - mode: STANDALONE_MODE, - scheduler: { - metricsRefreshRate: 1, - impressionsRefreshRate: 1, - eventsPushRate: 1 - }, streamingEnabled: false, sync: { impressionsMode: DEBUG, @@ -30,16 +24,16 @@ const baseConfig = { }, urls: { sdk: 'https://sdk.split-debug.io/api', - events: 'https://events.split-debug.io/api' + events: 'https://events.split-debug.io/api', + telemetry: 'https://telemetry.split-debug.io/api' } }; const postEndpoints = [ '/events/bulk', '/testImpressions/bulk', - // @TODO uncomment when telemetry is implemented - // '/metrics/times', - // '/metrics/counters' + '/v1/metrics/usage', + '/v1/metrics/config' ]; export default function ipAddressesSettingAssertions(fetchMock, assert) { @@ -63,7 +57,12 @@ export default function ipAddressesSettingAssertions(fetchMock, assert) { assertImpression(impression); } }; - const splitio = SplitFactory(config); + const splitio = SplitFactory(config, ({ settings }) => { + // Refresh rates are set to 1 second (below minimum values) to finish the test quickly. Otherwise, it would finish in 1 minute (60 seconds is the default value) + settings.scheduler.impressionsRefreshRate = 1000; + settings.scheduler.eventsPushRate = 1000; + settings.scheduler.telemetryRefreshRate = 1000; + }); const client = splitio.client(); const settings = settingsFactory(config); diff --git a/src/__tests__/nodeSuites/ip-addresses-setting.spec.js b/src/__tests__/nodeSuites/ip-addresses-setting.spec.js index 15f9fe907..383cb25d3 100644 --- a/src/__tests__/nodeSuites/ip-addresses-setting.spec.js +++ b/src/__tests__/nodeSuites/ip-addresses-setting.spec.js @@ -13,51 +13,44 @@ const IP_VALUE = ipFunction.address(); const HOSTNAME_VALUE = osFunction.hostname(); const NA = 'NA'; -// Refresh rates are set to 1 second to finish the test quickly. Otherwise, it would finish in 1 minute (60 seconds is the default value) -const baseConfig = { - scheduler: { - metricsRefreshRate: 1, - impressionsRefreshRate: 1, - eventsPushRate: 1 - }, - streamingEnabled: false -}; - // Config with IPAddressesEnabled set to false const configWithIPAddressesDisabled = { - ...baseConfig, + streamingEnabled: false, core: { authorizationKey: '', IPAddressesEnabled: false }, urls: { sdk: 'https://sdk.split-ipdisabled.io/api', - events: 'https://events.split-ipdisabled.io/api' + events: 'https://events.split-ipdisabled.io/api', + telemetry: 'https://telemetry.split-ipdisabled.io/api', } }; // Config with IPAddressesEnabled set to true const configWithIPAddressesEnabled = { - ...baseConfig, + streamingEnabled: false, core: { authorizationKey: '', IPAddressesEnabled: true }, urls: { sdk: 'https://sdk.split-ipenabled.io/api', - events: 'https://events.split-ipenabled.io/api' + events: 'https://events.split-ipenabled.io/api', + telemetry: 'https://telemetry.split-ipenabled.io/api' } }; // Config with default IPAddressesEnabled (true) const configWithIPAddressesDefault = { - ...baseConfig, + streamingEnabled: false, core: { authorizationKey: '' }, urls: { sdk: 'https://sdk.split-ipdefault.io/api', - events: 'https://events.split-ipdefault.io/api' + events: 'https://events.split-ipdefault.io/api', + telemetry: 'https://telemetry.split-ipdefault.io/api' } }; @@ -70,9 +63,8 @@ const configSamples = [ const postEndpoints = [ '/events/bulk', '/testImpressions/bulk', - // @TODO uncomment when telemetry is implemented - // '/metrics/times', - // '/metrics/counters' + '/v1/metrics/usage', + '/v1/metrics/config' ]; export default function ipAddressesSettingAssertions(fetchMock, assert) { @@ -109,7 +101,12 @@ export default function ipAddressesSettingAssertions(fetchMock, assert) { assertImpression(config.core.IPAddressesEnabled === undefined ? true : config.core.IPAddressesEnabled, config.mode === undefined ? STANDALONE_MODE : config.mode, impression); } }; - const splitio = SplitFactory(config); + const splitio = SplitFactory(config, ({ settings }) => { + // Refresh rates are set to 1 second (below minimum values) to finish the test quickly. Otherwise, it would finish in 1 minute (60 seconds is the default value) + settings.scheduler.impressionsRefreshRate = 1000; + settings.scheduler.eventsPushRate = 1000; + settings.scheduler.telemetryRefreshRate = 1000; + }); const client = splitio.client(); const settings = settingsFactory(config); diff --git a/src/__tests__/nodeSuites/push-fallbacking.spec.js b/src/__tests__/nodeSuites/push-fallbacking.spec.js index de33fe7a7..88b01cc48 100644 --- a/src/__tests__/nodeSuites/push-fallbacking.spec.js +++ b/src/__tests__/nodeSuites/push-fallbacking.spec.js @@ -46,7 +46,7 @@ const config = { scheduler: { featuresRefreshRate: 0.2, segmentsRefreshRate: 0.25, - metricsRefreshRate: 3000, + telemetryRefreshRate: 3000, impressionsRefreshRate: 3000 }, urls: baseUrls, diff --git a/src/__tests__/nodeSuites/push-initialization-nopush.spec.js b/src/__tests__/nodeSuites/push-initialization-nopush.spec.js index 80e6972a8..9968bec59 100644 --- a/src/__tests__/nodeSuites/push-initialization-nopush.spec.js +++ b/src/__tests__/nodeSuites/push-initialization-nopush.spec.js @@ -23,7 +23,7 @@ const config = { scheduler: { featuresRefreshRate: 0.1, segmentsRefreshRate: 0.1, - metricsRefreshRate: 3000, + telemetryRefreshRate: 3000, impressionsRefreshRate: 3000, pushRetryBackoffBase: 0.01 // small value to assert rapidly that push is not retried }, diff --git a/src/__tests__/nodeSuites/push-initialization-retries.spec.js b/src/__tests__/nodeSuites/push-initialization-retries.spec.js index 5f6dfb762..e88a34d97 100644 --- a/src/__tests__/nodeSuites/push-initialization-retries.spec.js +++ b/src/__tests__/nodeSuites/push-initialization-retries.spec.js @@ -24,7 +24,7 @@ const config = { scheduler: { featuresRefreshRate: 0.2, segmentsRefreshRate: 0.2, - metricsRefreshRate: 3000, + telemetryRefreshRate: 3000, impressionsRefreshRate: 3000, pushRetryBackoffBase: 0.1 }, diff --git a/src/__tests__/nodeSuites/push-refresh-token.spec.js b/src/__tests__/nodeSuites/push-refresh-token.spec.js index 546c7a992..644d2c07d 100644 --- a/src/__tests__/nodeSuites/push-refresh-token.spec.js +++ b/src/__tests__/nodeSuites/push-refresh-token.spec.js @@ -45,6 +45,8 @@ const MILLIS_REFRESH_TOKEN = 1000; */ export function testRefreshToken(fetchMock, assert) { fetchMock.reset(); + fetchMock.postOnce('https://telemetry.split.io/api/v1/metrics/config', 200); + fetchMock.postOnce('https://telemetry.split.io/api/v1/metrics/usage', 200); __setEventSource(EventSourceMock); let start, splitio, client; diff --git a/src/__tests__/push/node.spec.js b/src/__tests__/push/node.spec.js index a41673d49..14d6b59c7 100644 --- a/src/__tests__/push/node.spec.js +++ b/src/__tests__/push/node.spec.js @@ -9,6 +9,9 @@ import { testRefreshToken } from '../nodeSuites/push-refresh-token.spec'; fetchMock.config.overwriteRoutes = false; +fetchMock.post('https://telemetry.split.io/api/v1/metrics/config', 200); +fetchMock.post('https://telemetry.split.io/api/v1/metrics/usage', 200); + tape('## Node JS - E2E CI Tests for PUSH ##', async function (assert) { // Non-recoverable issues on inizialization From e6f90ff629e6c2a459b4d74771521be843b5a2ea Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Mon, 16 May 2022 16:38:45 -0300 Subject: [PATCH 06/16] extend E2E tests in consumer mode with redis --- package-lock.json | 6 +++--- package.json | 2 +- src/__tests__/node_redis.spec.js | 17 +++++++++++++++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index d6c01a3e0..9606a3fad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -437,9 +437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.3.2-rc.3", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.3.tgz", - "integrity": "sha512-tv+j+TvlD0mMM3yLpVGEKhetY/sqMwjTyr8SeVCu/bJHQ9BRxUJ8rygJf54mTqoGbkn8X5/yIANRp4cb7cKc1Q==", + "version": "1.3.2-rc.4", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.4.tgz", + "integrity": "sha512-734jQPgW3C4BPFXtmnfZGZDv8DPVlojmu0yBrHNgPlrACV9SiatXSBMXRFu1ym/N1chif3gMbBPN1y2WqEAdzw==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index 51f088433..58a7a1344 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.3.2-rc.3", + "@splitsoftware/splitio-commons": "1.3.2-rc.4", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "ioredis": "^4.28.0", diff --git a/src/__tests__/node_redis.spec.js b/src/__tests__/node_redis.spec.js index 18edf10fb..7766c314b 100644 --- a/src/__tests__/node_redis.spec.js +++ b/src/__tests__/node_redis.spec.js @@ -119,13 +119,26 @@ tape('NodeJS Redis', function (t) { await client.ready(); // promise already resolved await client.destroy(); + // Validate stored impressions and events exec(`echo "LLEN ${config.storage.prefix}.SPLITIO.impressions \n LLEN ${config.storage.prefix}.SPLITIO.events" | redis-cli -p ${redisPort}`, (error, stdout) => { if (error) assert.fail('Redis server should be reachable'); const trackedImpressionsAndEvents = stdout.split('\n').filter(line => line !== '').map(line => parseInt(line)); assert.deepEqual(trackedImpressionsAndEvents, [14, 2], 'Tracked impressions and events should be stored in Redis'); - // close server connection - server.close().then(assert.end); + + // Validate stored telemetry + exec(`echo "HLEN ${config.storage.prefix}.SPLITIO.telemetry.latencies \n HLEN ${config.storage.prefix}.SPLITIO.telemetry.exceptions \n HGET ${config.storage.prefix}.SPLITIO.telemetry.init ${'nodejs-10.18.3-rc.0'}/${HOSTNAME_VALUE}/${IP_VALUE}" | redis-cli -p ${redisPort}`, (error, stdout) => { + if (error) assert.fail('Redis server should be reachable'); + + const [latencies, exceptions, configValue] = stdout.split('\n').filter(line => line !== '').map(JSON.parse); + + assert.true(latencies > 0, 'There are stored latencies'); + assert.true(exceptions === 0, 'There aren\'t stored exceptions'); + assert.deepEqual(configValue, { oM: 1, st: 'redis', aF: 1, rF: 0 }, 'There is stored telemetry config'); + + // close server connection + server.close().then(assert.end); + }); }); }); }); From 0c979074ae3336e67fb426b4aeda0f119bde4413 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 17 May 2022 14:56:43 -0300 Subject: [PATCH 07/16] extend E2E tests in standalone mode for NodeJS --- src/__tests__/node.spec.js | 7 +- src/__tests__/nodeSuites/metrics.spec.js | 173 --------------------- src/__tests__/nodeSuites/telemetry.spec.js | 155 ++++++++++++++++++ 3 files changed, 158 insertions(+), 177 deletions(-) delete mode 100644 src/__tests__/nodeSuites/metrics.spec.js create mode 100644 src/__tests__/nodeSuites/telemetry.spec.js diff --git a/src/__tests__/node.spec.js b/src/__tests__/node.spec.js index 903cd70be..c5f0b6dc2 100644 --- a/src/__tests__/node.spec.js +++ b/src/__tests__/node.spec.js @@ -7,7 +7,7 @@ import evaluationsSuite from './nodeSuites/evaluations.spec'; import eventsSuite from './nodeSuites/events.spec'; import impressionsSuite from './nodeSuites/impressions.spec'; import impressionsSuiteDebug from './nodeSuites/impressions.debug.spec'; -// import metricsSuite from './nodeSuites/metrics.spec'; +import telemetrySuite from './nodeSuites/telemetry.spec'; import impressionsListenerSuite from './nodeSuites/impressions-listener.spec'; import expectedTreatmentsSuite from './nodeSuites/expected-treatments.spec'; import managerSuite from './nodeSuites/manager.spec'; @@ -60,9 +60,8 @@ tape('## Node JS - E2E CI Tests ##', async function (assert) { assert.test('E2E / Impressions Debug Mode', impressionsSuiteDebug.bind(null, key, fetchMock)); assert.test('E2E / Impressions listener', impressionsListenerSuite); - // /* Check metrics */ - // @TODO uncomment when telemetry is implemented - // assert.test('E2E / Metrics', metricsSuite.bind(null, key, fetchMock)); + /* Check telemetry */ + assert.test('E2E / Metrics', telemetrySuite.bind(null, key, fetchMock)); /* Check events in memory */ assert.test('E2E / Events', eventsSuite.bind(null, fetchMock)); diff --git a/src/__tests__/nodeSuites/metrics.spec.js b/src/__tests__/nodeSuites/metrics.spec.js deleted file mode 100644 index 9cfebcd9e..000000000 --- a/src/__tests__/nodeSuites/metrics.spec.js +++ /dev/null @@ -1,173 +0,0 @@ -import { SplitFactory } from '../../'; -import { settingsFactory } from '../../settings'; -import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; -import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; -import { OPTIMIZED } from '@splitsoftware/splitio-commons/src/utils/constants'; -import { url } from '../testUtils'; - -const baseUrls = { - sdk: 'https://sdk.baseurl/metricsSuite', - events: 'https://events.baseurl/metricsSuite' -}; - -const settings = settingsFactory({ - core: { - key: '' - }, - urls: baseUrls, - streamingEnabled: false -}); - -const config = { - core: { - authorizationKey: '' - }, - scheduler: { - featuresRefreshRate: 99999, - segmentsRefreshRate: 99999, - metricsRefreshRate: 3, - impressionsRefreshRate: 99999 - }, - urls: baseUrls, - startup: { - eventsFirstPushWindow: 3000 - }, - streamingEnabled: false -}; - -export default async function(key, fetchMock, assert) { - const segmentChangesUrlRegex = new RegExp(`${baseUrls.sdk}/segmentChanges/*`); - - fetchMock.getOnce(url(settings, '/splitChanges?since=-1'), 500); - fetchMock.getOnce(url(settings, '/splitChanges?since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(segmentChangesUrlRegex, { status: 200, body: { since:10, till:10, name: 'segmentName', added: [], removed: [] } }); - fetchMock.getOnce(segmentChangesUrlRegex, 401); - fetchMock.getOnce(segmentChangesUrlRegex, 500); - fetchMock.getOnce(segmentChangesUrlRegex, { status: 200, body: '{ INVALID JSON' }); - fetchMock.get(segmentChangesUrlRegex, { status: 200, body: {since:10, till:10, name: 'segmentName' + Date.now(), added: [], removed: []} }); - // Should not execute but adding just in case. - fetchMock.get(url(settings, '/splitChanges?since=1457552620999'), { status: 200, body: splitChangesMock2 }); - - fetchMock.postOnce(url(settings, '/testImpressions/bulk'), (url, opts) => { - assert.equal(opts.headers.SplitSDKImpressionsMode, OPTIMIZED); - return 200; - }); - fetchMock.postOnce(url(settings, '/testImpressions/count'), 200); - - const splitio = SplitFactory(config); - const client = splitio.client(); - - const finish = (function*() { - yield; - client.destroy(); - assert.end(); - })(); - - fetchMock.postOnce(url(settings, '/metrics/times'), (url, opts) => { - const data = JSON.parse(opts.body); - - assert.equal(data.length, 7, 'We performed 4 correct evaluation requests (one per method) plus ready, splits and segments, so we should have 7 latency metrics.'); - - const latencyMetricsRecorded = data.filter(metric => { - // At least one latency registed per metric - return metric.latencies.some(count => count > 0); - }); - - // If we have 7 items, it is because each one had at least ONE entry. - assert.equal(latencyMetricsRecorded.length, 7, 'Each metric has at least one enty, matching the calls.'); - - const getLatencyCount = metricName => { - const latencyMetric = data.find(metric => metric.name === metricName); - - if (!latencyMetric && !Array.isArray(latencyMetric.latencies)) return 0; - - return latencyMetric.latencies.reduce((accum, entry) => accum + entry, 0); - }; - - // Validate both names and values. - assert.equal(getLatencyCount('splitChangeFetcher.time'), 2, 'Two latency metrics for splitChanges'); - assert.equal(getLatencyCount('segmentChangeFetcher.time'), 1, 'One latency metric for segmentChangeFetcher'); - assert.equal(getLatencyCount('sdk.ready'), 1, 'One latency metric for ready'); - assert.equal(getLatencyCount('sdk.getTreatment'), 1, 'One latency metric for getTreatment'); - assert.equal(getLatencyCount('sdk.getTreatments'), 1, 'One latency metric for getTreatments'); - assert.equal(getLatencyCount('sdk.getTreatmentWithConfig'), 1, 'One latency metric for getTreatmentWithConfig'); - assert.equal(getLatencyCount('sdk.getTreatmentsWithConfig'), 1, 'One latency metric for getTreatmentsWithConfig'); - - finish.next(); - - return 200; - }); - - fetchMock.postOnce(url(settings, '/metrics/counters'), (url, opts) => { - const data = JSON.parse(opts.body); - - assert.equal(data.length, 4, 'Based on the mock setup, we should have four items.'); - - const countMetricsRecorded = data.reduce((accum, metric) => accum + metric.delta, 0); - - const getRecordsCount = metricName => { - const countMetric = data.find(metric => metric.name === metricName); - - if (!countMetric) return 0; - - return countMetric.delta; - }; - - // 5 items: - // For splitChanges, 1 exception and 1 200. - // For segmentChanges (3 segments) 1 with 200, two errors. - assert.equal(countMetricsRecorded, 5, 'Each metric has one entry, same as the amount of calls.'); - // break down - assert.equal(getRecordsCount('splitChangeFetcher.exception'), 1, 'The metric names and delta should correspond to the SDK behaviour.'); - assert.equal(getRecordsCount('segmentChangeFetcher.exception'), 2, 'The metric names and delta should correspond to the SDK behaviour.'); - assert.equal(getRecordsCount('splitChangeFetcher.status.200'), 1, 'The metric names and delta should correspond to the SDK behaviour.'); - assert.equal(getRecordsCount('segmentChangeFetcher.status.200'), 1, 'The metric names and delta should correspond to the SDK behaviour.'); - - finish.next(); - - return 200; - }); - - await client.ready(); - - // treatments and results are only validated so we know for sure when the function was actually running to compare the metrics. - assert.equal(client.getTreatment(key, 'always_on'), 'on', 'Evaluation was correct.'); - assert.equal(client.getTreatment(false, 'always_on'), 'control', 'We should return control with invalid input.'); - - assert.deepEqual(client.getTreatmentWithConfig(key, 'split_with_config'), { - treatment: 'o.n', - config: '{"color":"brown","dimensions":{"height":12,"width":14},"text":{"inner":"click me"}}' - }, 'Evaluation with config was correct.'); - assert.deepEqual(client.getTreatmentWithConfig(null, 'split_with_config'), { - treatment: 'control', - config: null - }, 'Evaluation with config returned control state for invalid input.'); - - assert.deepEqual(client.getTreatments(key, ['always_on', 'always_off']), { always_on:'on', always_off:'off' }, 'Evaluations were correct.'); - assert.deepEqual(client.getTreatments(false, ['always_on', 'always_off', null]), { always_on:'control', always_off:'control' }, 'We should return map of controls with invalid input.'); - - assert.deepEqual(client.getTreatmentsWithConfig(key, ['split_with_config', 'always_on', null]), - { - split_with_config: { - treatment: 'o.n', - config: '{"color":"brown","dimensions":{"height":12,"width":14},"text":{"inner":"click me"}}' - }, - always_on: { - treatment: 'on', - config: null - } - } - , 'Evaluations with config were correct.'); - assert.deepEqual(client.getTreatmentsWithConfig(null, ['split_with_config', 'always_on', null]), - { - split_with_config: { - treatment: 'control', - config: null - }, - always_on: { - treatment: 'control', - config: null - } - }, - 'Evaluations with config returned control states for invalid input.'); -} diff --git a/src/__tests__/nodeSuites/telemetry.spec.js b/src/__tests__/nodeSuites/telemetry.spec.js new file mode 100644 index 000000000..7b0c973b8 --- /dev/null +++ b/src/__tests__/nodeSuites/telemetry.spec.js @@ -0,0 +1,155 @@ +import { SplitFactory } from '../../'; +import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; +import { url, mockSegmentChanges } from '../testUtils'; + +const baseUrls = { + sdk: 'https://sdk.baseurl/telemetrySuite', + events: 'https://events.baseurl/telemetrySuite', + telemetry: 'https://events.baseurl/telemetrySuite', +}; + +const config = { + core: { + authorizationKey: '' + }, + scheduler: { + featuresRefreshRate: 99999 + }, + urls: baseUrls, + streamingEnabled: false +}; + +export default async function (key, fetchMock, assert) { + + fetchMock.getOnce(url(config, '/splitChanges?since=-1'), 500); // record http exception + fetchMock.getOnce(url(config, '/splitChanges?since=-1'), { status: 200, body: splitChangesMock1 }); + mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); + + fetchMock.postOnce(url(config, '/testImpressions/bulk'), 200); + fetchMock.postOnce(url(config, '/testImpressions/count'), 200); + fetchMock.postOnce(url(config, '/events/bulk'), 200); + + const splitio = SplitFactory(config, ({ settings }) => { + settings.scheduler.telemetryRefreshRate = 1000; // set below minimum + }); + const client = splitio.client(); + + const finish = (function* () { + yield; + client.destroy(); + assert.end(); + })(); + + let lastSync; + + // 1st metrics/usage call due to telemetryRefreshRate set in 1 second + fetchMock.postOnce(url(config, '/v1/metrics/usage'), (url, opts) => { + const data = JSON.parse(opts.body); + + // Validate last successful sync + assert.deepEqual(Object.keys(data.lS), ['sp', 'se', 'te'], 'Successful split changes, segment changes and telemetry config requests'); + lastSync = data.lS; delete data.lS; + + // Validate http and method latencies + const getLatencyCount = buckets => buckets ? buckets.reduce((accum, entry) => accum + entry, 0) : 0; + assert.equal(getLatencyCount(data.hL.sp), 2, 'Two latency metrics for splitChanges GET request'); + assert.equal(getLatencyCount(data.hL.se), 6, 'Six latency metrics for segmentChanges GET request'); + assert.equal(getLatencyCount(data.hL.te), 1, 'One latency metric for telemetry config POST request'); + assert.equal(getLatencyCount(data.mL.t), 2, 'Two latency metrics for getTreatment (one not ready usage'); + assert.equal(getLatencyCount(data.mL.ts), 1, 'One latency metric for getTreatments'); + assert.equal(getLatencyCount(data.mL.tc), 1, 'One latency metric for getTreatmentWithConfig'); + assert.equal(getLatencyCount(data.mL.tcs), 1, 'One latency metric for getTreatmentsWithConfig'); + assert.equal(getLatencyCount(data.mL.tr), 1, 'One latency metric for track'); + delete data.hL; delete data.mL; + + assert.deepEqual(data, { + mE: {}, hE: { sp: { 500: 1 } }, tR: 0, aR: 0, iQ: 4, iDe: 3, iDr: 0, spC: 31, seC: 3, skC: 3, eQ: 1, eD: 0, sE: [], t: [] + }, 'metrics/usage JSON payload should be the expected'); + + finish.next(); + return 200; + }); + + // 2nd metrics/usage call due to destroy + fetchMock.postOnce(url(config, '/v1/metrics/usage'), (url, opts) => { + const data = JSON.parse(opts.body); + + assert.deepEqual(data.lS, lastSync, 'last successful sync hasn\'t change'); + delete data.lS; + + assert.true(data.sL > 0, 'sessionLengthMs must be defined'); + delete data.sL; + + assert.deepEqual(data, { + mL: {}, mE: {}, hE: {}, hL: {}, tR: 0, aR: 0, iQ: 4, iDe: 3, iDr: 0, spC: 31, seC: 3, skC: 3, eQ: 1, eD: 0, sE: [], t: [] + }, '2nd metrics/usage JSON payload should be the expected'); + return 200; + }); + + fetchMock.postOnce(url(config, '/v1/metrics/config'), (url, opts) => { + const data = JSON.parse(opts.body); + + assert.true(data.tR > 0, 'timeUntilReady is larger than 0'); + delete data.tR; // delete to validate other properties + + assert.deepEqual(data, { + oM: 0, st: 'memory', aF: 1, rF: 0, sE: false, + rR: { sp: 99999, se: 60, im: 300, ev: 60, te: 1 } /* override featuresRefreshRate */, + uO: { s: true, e: true, a: false, st: false, t: true } /* override sdk, events and telemetry URLs */, + iQ: 30000, eQ: 500, iM: 0, iL: false, hP: false, nR: 1 /* 1 non ready usage */, t: [], uC: 0 /* NA */ + }, 'metrics/config JSON payload should be the expected'); + + finish.next(); + + return 200; + }); + + assert.equal(client.getTreatment(key, 'always_on'), 'control', 'Non ready usage.'); + + await client.ready(); + + // treatments and results are only validated so we know for sure when the function was actually running to compare the metrics. + assert.equal(client.getTreatment(key, 'always_on'), 'on', 'Evaluation was correct.'); + assert.equal(client.getTreatment(false, 'always_on'), 'control', 'We should return control with invalid input.'); + + assert.deepEqual(client.getTreatmentWithConfig(key, 'split_with_config'), { + treatment: 'o.n', + config: '{"color":"brown","dimensions":{"height":12,"width":14},"text":{"inner":"click me"}}' + }, 'Evaluation with config was correct.'); + assert.deepEqual(client.getTreatmentWithConfig(null, 'split_with_config'), { + treatment: 'control', + config: null + }, 'Evaluation with config returned control state for invalid input.'); + + assert.deepEqual(client.getTreatments(key, ['always_on', 'always_off']), { always_on: 'on', always_off: 'off' }, 'Evaluations were correct.'); + assert.deepEqual(client.getTreatments(false, ['always_on', 'always_off', null]), { always_on: 'control', always_off: 'control' }, 'We should return map of controls with invalid input.'); + + assert.deepEqual(client.getTreatmentsWithConfig(key, ['split_with_config', 'always_on', null]), + { + split_with_config: { + treatment: 'o.n', + config: '{"color":"brown","dimensions":{"height":12,"width":14},"text":{"inner":"click me"}}' + }, + always_on: { + treatment: 'on', + config: null + } + } + , 'Evaluations with config were correct.'); + assert.deepEqual(client.getTreatmentsWithConfig(null, ['split_with_config', 'always_on', null]), + { + split_with_config: { + treatment: 'control', + config: null + }, + always_on: { + treatment: 'control', + config: null + } + }, + 'Evaluations with config returned control states for invalid input.'); + + assert.equal(client.track(key, 'someTT', 'someEvent'), true, 'Event was queued'); + assert.equal(client.track(false, 'someTT', 'someEvent'), false, 'Invalid input.'); + +} From b9c697673de72ddcac103c961a902248bb39bafa Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 17 May 2022 16:40:04 -0300 Subject: [PATCH 08/16] E2E tests for telemetry in client-side/browser --- package-lock.json | 6 +- package.json | 2 +- src/__tests__/browser.spec.js | 7 +- src/__tests__/browserSuites/metrics.spec.js | 155 ----------------- src/__tests__/browserSuites/telemetry.spec.js | 161 ++++++++++++++++++ src/__tests__/node.spec.js | 2 +- src/__tests__/nodeSuites/telemetry.spec.js | 7 +- 7 files changed, 173 insertions(+), 167 deletions(-) delete mode 100644 src/__tests__/browserSuites/metrics.spec.js create mode 100644 src/__tests__/browserSuites/telemetry.spec.js diff --git a/package-lock.json b/package-lock.json index d5f54b00b..b50935d4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -437,9 +437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.3.2-rc.4", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.4.tgz", - "integrity": "sha512-734jQPgW3C4BPFXtmnfZGZDv8DPVlojmu0yBrHNgPlrACV9SiatXSBMXRFu1ym/N1chif3gMbBPN1y2WqEAdzw==", + "version": "1.3.2-rc.5", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.5.tgz", + "integrity": "sha512-43xcxlBv39fGle+fLTSV2/eZYVo6DC1LqXn7OUvEvuTbomihpauD+XjdlicG5U08Is/ncnj6eG1jCxjpKqal0g==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index aab12ddff..e462c48ba 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.3.2-rc.4", + "@splitsoftware/splitio-commons": "1.3.2-rc.5", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "ioredis": "^4.28.0", diff --git a/src/__tests__/browser.spec.js b/src/__tests__/browser.spec.js index c1993c405..f48f19b8e 100644 --- a/src/__tests__/browser.spec.js +++ b/src/__tests__/browser.spec.js @@ -4,7 +4,7 @@ import { url } from './testUtils'; import evaluationsSuite from './browserSuites/evaluations.spec'; import impressionsSuite from './browserSuites/impressions.spec'; import impressionsSuiteDebug from './browserSuites/impressions.debug.spec'; -// import metricsSuite from './browserSuites/metrics.spec'; +import telemetrySuite from './browserSuites/telemetry.spec'; import impressionsListenerSuite from './browserSuites/impressions-listener.spec'; import readinessSuite from './browserSuites/readiness.spec'; import readyFromCache from './browserSuites/ready-from-cache.spec'; @@ -108,9 +108,8 @@ tape('## E2E CI Tests ##', function(assert) { assert.test('E2E / Impressions Debug Mode', impressionsSuiteDebug.bind(null, fetchMock)); /* Check impression listener */ assert.test('E2E / Impression listener', impressionsListenerSuite); - /* Check metrics */ - // @TODO uncomment when telemetry is implemented - // assert.test('E2E / Metrics', metricsSuite.bind(null, fetchMock)); + /* Check telemetry */ + assert.test('E2E / Telemetry', telemetrySuite.bind(null, fetchMock)); /* Check events */ assert.test('E2E / Events', withoutBindingTT.bind(null, fetchMock)); assert.test('E2E / Events with TT binded', bindingTT.bind(null, fetchMock)); diff --git a/src/__tests__/browserSuites/metrics.spec.js b/src/__tests__/browserSuites/metrics.spec.js deleted file mode 100644 index 8841a9515..000000000 --- a/src/__tests__/browserSuites/metrics.spec.js +++ /dev/null @@ -1,155 +0,0 @@ -import { SplitFactory } from '../../'; -import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; -import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; - -const baseUrls = { - sdk: 'https://sdk.baseurl/metricsSuite', - events: 'https://events.baseurl/metricsSuite' -}; - -const config = { - core: { - authorizationKey: '', - key: 'metrics-browser-tests-key' - }, - scheduler: { - featuresRefreshRate: 99999, - segmentsRefreshRate: 99999, - metricsRefreshRate: 3, - impressionsRefreshRate: 99999 - }, - urls: baseUrls, - startup: { - eventsFirstPushWindow: 3000 - }, - streamingEnabled: false -}; - -export default async function metricsBrowserSuite(fetchMock, assert) { - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?since=-1', 500); - fetchMock.get(baseUrls.sdk + '/splitChanges?since=-1', { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(baseUrls.sdk + '/mySegments/metrics-browser-tests-key', 500); - fetchMock.get(baseUrls.sdk + '/mySegments/metrics-browser-tests-key', { status: 200, body: { 'mySegments': [] } }); - // Should not execute but adding just in case. - fetchMock.get(baseUrls.sdk + '/splitChanges?since=1457552620999', { status: 200, body: splitChangesMock2 }); - // We need to handle all requests properly - fetchMock.postOnce(baseUrls.events + '/testImpressions/bulk', 200); - fetchMock.postOnce(baseUrls.events + '/testImpressions/count', 200); - - const splitio = SplitFactory(config); - const client = splitio.client(); - - const finish = (function* () { - yield; - client.destroy(); - assert.end(); - })(); - - fetchMock.postOnce(baseUrls.events + '/metrics/times', (url, opts) => { - const data = JSON.parse(opts.body); - - assert.equal(data.length, 7, 'We performed 4 correct evaluation requests (one per method) plus ready, splits and segments, so we should have 7 latency metrics.'); - - const latencyMetricsRecorded = data.filter(metric => { - // At least one latency registed per metric - return metric.latencies.some(count => count > 0); - }); - - // If we have 7 items, it is because each one had at least ONE entry. - assert.equal(latencyMetricsRecorded.length, 7, 'Each metric has at least one enty, matching the calls.'); - - const getLatencyCount = metricName => { - const latencyMetric = data.find(metric => metric.name === metricName); - - if (!latencyMetric && !Array.isArray(latencyMetric.latencies)) return 0; - - return latencyMetric.latencies.reduce((accum, entry) => accum + entry, 0); - }; - - // Validate both names and values. - assert.equal(getLatencyCount('splitChangeFetcher.time'), 2, 'Two latency metrics for splitChanges'); // 1 err 1 ok - assert.equal(getLatencyCount('mySegmentsFetcher.time'), 2, 'One latency metric for mySegmentsFetcher'); // 1 err 1 ok - assert.equal(getLatencyCount('sdk.ready'), 1, 'One latency metric for ready'); - assert.equal(getLatencyCount('sdk.getTreatment'), 1, 'One latency metric for getTreatment'); - assert.equal(getLatencyCount('sdk.getTreatments'), 1, 'One latency metric for getTreatments'); - assert.equal(getLatencyCount('sdk.getTreatmentWithConfig'), 1, 'One latency metric for getTreatmentWithConfig'); - assert.equal(getLatencyCount('sdk.getTreatmentsWithConfig'), 1, 'One latency metric for getTreatmentsWithConfig'); - - finish.next(); - - return 200; - }); - - fetchMock.postOnce(baseUrls.events + '/metrics/counters', (url, opts) => { - const data = JSON.parse(opts.body); - - assert.equal(data.length, 4, 'Based on the mock setup, we should have four items.'); - - const countMetricsRecorded = data.reduce((accum, metric) => accum + metric.delta, 0); - - const getRecodsCount = metricName => { - const countMetric = data.find(metric => metric.name === metricName); - - if (!countMetric) return 0; - - return countMetric.delta; - }; - - // 4 items: - // For splitChanges, 1 exception and 1 200. - // For mySegments 1 exception and 1 200. - assert.equal(countMetricsRecorded, 4, 'Each metric has one entry, same as the amount of calls.'); - // break down - assert.equal(getRecodsCount('splitChangeFetcher.exception'), 1, 'The metric names and delta should correspond to the SDK behaviour.'); - assert.equal(getRecodsCount('mySegmentsFetcher.exception'), 1, 'The metric names and delta should correspond to the SDK behaviour.'); - assert.equal(getRecodsCount('splitChangeFetcher.status.200'), 1, 'The metric names and delta should correspond to the SDK behaviour.'); - assert.equal(getRecodsCount('mySegmentsFetcher.status.200'), 1, 'The metric names and delta should correspond to the SDK behaviour.'); - - finish.next(); - - return 200; - }); - - await client.ready(); - - // treatments and results are only validated so we know for sure when the function was actually running to compare the metrics. - assert.equal(client.getTreatment('always_on'), 'on', 'Evaluation was correct.'); - assert.equal(client.getTreatment('always_on', () => { }), 'control', 'We should return control with invalid input.'); - - assert.deepEqual(client.getTreatmentWithConfig('split_with_config'), { - treatment: 'o.n', - config: '{"color":"brown","dimensions":{"height":12,"width":14},"text":{"inner":"click me"}}' - }, 'Evaluation with config was correct.'); - assert.deepEqual(client.getTreatmentWithConfig('split_with_config', () => { }), { - treatment: 'control', - config: null - }, 'Evaluation with config returned control state for invalid input.'); - - assert.deepEqual(client.getTreatments(['always_on', 'always_off']), { always_on: 'on', always_off: 'off' }, 'Evaluations were correct.'); - assert.deepEqual(client.getTreatments(['always_on', 'always_off', null], () => { }), { always_on: 'control', always_off: 'control' }, 'We should return map of controls with invalid input.'); - - assert.deepEqual(client.getTreatmentsWithConfig(['split_with_config', 'always_on', null]), - { - split_with_config: { - treatment: 'o.n', - config: '{"color":"brown","dimensions":{"height":12,"width":14},"text":{"inner":"click me"}}' - }, - always_on: { - treatment: 'on', - config: null - } - } - , 'Evaluations with config were correct.'); - assert.deepEqual(client.getTreatmentsWithConfig(['split_with_config', 'always_on', null], () => { }), - { - split_with_config: { - treatment: 'control', - config: null - }, - always_on: { - treatment: 'control', - config: null - } - }, - 'Evaluations with config returned control states for invalid input.'); -} diff --git a/src/__tests__/browserSuites/telemetry.spec.js b/src/__tests__/browserSuites/telemetry.spec.js new file mode 100644 index 000000000..396179ee2 --- /dev/null +++ b/src/__tests__/browserSuites/telemetry.spec.js @@ -0,0 +1,161 @@ +import { SplitFactory } from '../../'; +import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; + +const baseUrls = { + sdk: 'https://sdk.baseurl/telemetrySuite', + events: 'https://events.baseurl/telemetrySuite', + telemetry: 'https://telemetry.baseurl/telemetrySuite', +}; + +const config = { + core: { + authorizationKey: '', + key: 'user-key' + }, + scheduler: { + featuresRefreshRate: 99999 + }, + urls: baseUrls, + streamingEnabled: false +}; + +export default async function telemetryBrowserSuite(fetchMock, assert) { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?since=-1', 500); + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?since=-1', { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(baseUrls.sdk + '/mySegments/user-key', 500); + fetchMock.getOnce(baseUrls.sdk + '/mySegments/user-key', { status: 200, body: { 'mySegments': [ 'one_segment'] } }); + + // We need to handle all requests properly + fetchMock.postOnce(baseUrls.events + '/testImpressions/bulk', 200); + fetchMock.postOnce(baseUrls.events + '/testImpressions/count', 200); + fetchMock.postOnce(baseUrls.events + '/events/bulk', 200); + + // Overwrite Math.random to instantiate factory with telemetry + const originalMathRandom = Math.random; Math.random = () => 0.001; + const splitio = SplitFactory(config, ({ settings }) => { + settings.scheduler.telemetryRefreshRate = 1000; // set below minimum + }); + Math.random = originalMathRandom; // restore + + const client = splitio.client(); + + const finish = (function* () { + yield; + client.destroy(); + assert.end(); + })(); + + let lastSync; + + // 1st metrics/usage call due to telemetryRefreshRate set in 1 second + fetchMock.postOnce(baseUrls.telemetry + '/v1/metrics/usage', (url, opts) => { + const data = JSON.parse(opts.body); + + // Validate last successful sync + assert.deepEqual(Object.keys(data.lS), ['sp', 'ms', 'te'], 'Successful splitChanges, mySegments and metrics/config requests'); + lastSync = data.lS; delete data.lS; + + // Validate http and method latencies + const getLatencyCount = buckets => buckets ? buckets.reduce((accum, entry) => accum + entry, 0) : 0; + assert.equal(getLatencyCount(data.hL.sp), 2, 'Two latency metrics for splitChanges GET request'); + assert.equal(getLatencyCount(data.hL.ms), 2, 'Two latency metrics for mySegments GET request'); + assert.equal(getLatencyCount(data.hL.te), 1, 'One latency metric for telemetry config POST request'); + assert.equal(getLatencyCount(data.mL.t), 2, 'Two latency metrics for getTreatment (one not ready usage'); + assert.equal(getLatencyCount(data.mL.ts), 1, 'One latency metric for getTreatments'); + assert.equal(getLatencyCount(data.mL.tc), 1, 'One latency metric for getTreatmentWithConfig'); + assert.equal(getLatencyCount(data.mL.tcs), 1, 'One latency metric for getTreatmentsWithConfig'); + assert.equal(getLatencyCount(data.mL.tr), 1, 'One latency metric for track'); + delete data.hL; delete data.mL; + + assert.deepEqual(data, { + mE: {}, hE: { sp: { 500: 1 }, ms: { 500: 1 } }, tR: 0, aR: 0, iQ: 4, iDe: 3, iDr: 0, spC: 31, seC: 1, skC: 1, eQ: 1, eD: 0, sE: [], t: [] + }, 'metrics/usage JSON payload should be the expected'); + + finish.next(); + return 200; + }); + + // 2nd metrics/usage call due to destroy + fetchMock.postOnce(baseUrls.telemetry + '/v1/metrics/usage', (url, opts) => { + const data = JSON.parse(opts.body); + + assert.deepEqual(data.lS, lastSync, 'last successful sync hasn\'t change'); + delete data.lS; + + assert.true(data.sL > 0, 'sessionLengthMs must be defined'); + delete data.sL; + + assert.deepEqual(data, { + mL: {}, mE: {}, hE: {}, hL: {}, // errors and latencies were popped + tR: 0, aR: 0, iQ: 4, iDe: 3, iDr: 0, spC: 31, seC: 1, skC: 1, eQ: 1, eD: 0, sE: [], t: [] + }, '2nd metrics/usage JSON payload should be the expected'); + return 200; + }); + + fetchMock.postOnce(baseUrls.telemetry + '/v1/metrics/config', (url, opts) => { + const data = JSON.parse(opts.body); + + assert.true(data.tR > 0, 'timeUntilReady is larger than 0'); + delete data.tR; // delete to validate other properties + + assert.deepEqual(data, { + oM: 0, st: 'memory', aF: 1, rF: 0, sE: false, + rR: { sp: 99999, se: 60, im: 300, ev: 60, te: 1 } /* override featuresRefreshRate */, + uO: { s: true, e: true, a: false, st: false, t: true } /* override sdk, events and telemetry URLs */, + iQ: 30000, eQ: 500, iM: 0, iL: false, hP: false, nR: 1 /* 1 non ready usage */, t: [], i: [], uC: 2 /* Default GRANTED */ + }, 'metrics/config JSON payload should be the expected'); + + finish.next(); + + return 200; + }); + + assert.equal(client.getTreatment('always_on'), 'control', 'Non ready usage.'); + + await client.ready(); + + // treatments and results are only validated so we know for sure when the function was actually running to compare the metrics. + assert.equal(client.getTreatment('always_on'), 'on', 'Evaluation was correct.'); + assert.equal(client.getTreatment('always_on', () => { }), 'control', 'We should return control with invalid input.'); + + assert.deepEqual(client.getTreatmentWithConfig('split_with_config'), { + treatment: 'o.n', + config: '{"color":"brown","dimensions":{"height":12,"width":14},"text":{"inner":"click me"}}' + }, 'Evaluation with config was correct.'); + assert.deepEqual(client.getTreatmentWithConfig('split_with_config', () => { }), { + treatment: 'control', + config: null + }, 'Evaluation with config returned control state for invalid input.'); + + assert.deepEqual(client.getTreatments(['always_on', 'always_off']), { always_on: 'on', always_off: 'off' }, 'Evaluations were correct.'); + assert.deepEqual(client.getTreatments(['always_on', 'always_off', null], () => { }), { always_on: 'control', always_off: 'control' }, 'We should return map of controls with invalid input.'); + + assert.deepEqual(client.getTreatmentsWithConfig(['split_with_config', 'always_on', null]), + { + split_with_config: { + treatment: 'o.n', + config: '{"color":"brown","dimensions":{"height":12,"width":14},"text":{"inner":"click me"}}' + }, + always_on: { + treatment: 'on', + config: null + } + } + , 'Evaluations with config were correct.'); + assert.deepEqual(client.getTreatmentsWithConfig(['split_with_config', 'always_on', null], () => { }), + { + split_with_config: { + treatment: 'control', + config: null + }, + always_on: { + treatment: 'control', + config: null + } + }, + 'Evaluations with config returned control states for invalid input.'); + + assert.equal(client.track('someTT', 'someEvent'), true, 'Event was queued'); + assert.equal(client.track('someTT', null), false, 'Invalid input.'); + +} diff --git a/src/__tests__/node.spec.js b/src/__tests__/node.spec.js index c5f0b6dc2..6c3d0c729 100644 --- a/src/__tests__/node.spec.js +++ b/src/__tests__/node.spec.js @@ -61,7 +61,7 @@ tape('## Node JS - E2E CI Tests ##', async function (assert) { assert.test('E2E / Impressions listener', impressionsListenerSuite); /* Check telemetry */ - assert.test('E2E / Metrics', telemetrySuite.bind(null, key, fetchMock)); + assert.test('E2E / Telemetry', telemetrySuite.bind(null, key, fetchMock)); /* Check events in memory */ assert.test('E2E / Events', eventsSuite.bind(null, fetchMock)); diff --git a/src/__tests__/nodeSuites/telemetry.spec.js b/src/__tests__/nodeSuites/telemetry.spec.js index 7b0c973b8..c5cdc3b56 100644 --- a/src/__tests__/nodeSuites/telemetry.spec.js +++ b/src/__tests__/nodeSuites/telemetry.spec.js @@ -5,7 +5,7 @@ import { url, mockSegmentChanges } from '../testUtils'; const baseUrls = { sdk: 'https://sdk.baseurl/telemetrySuite', events: 'https://events.baseurl/telemetrySuite', - telemetry: 'https://events.baseurl/telemetrySuite', + telemetry: 'https://telemetry.baseurl/telemetrySuite', }; const config = { @@ -19,7 +19,7 @@ const config = { streamingEnabled: false }; -export default async function (key, fetchMock, assert) { +export default async function telemetryNodejsSuite(key, fetchMock, assert) { fetchMock.getOnce(url(config, '/splitChanges?since=-1'), 500); // record http exception fetchMock.getOnce(url(config, '/splitChanges?since=-1'), { status: 200, body: splitChangesMock1 }); @@ -81,7 +81,8 @@ export default async function (key, fetchMock, assert) { delete data.sL; assert.deepEqual(data, { - mL: {}, mE: {}, hE: {}, hL: {}, tR: 0, aR: 0, iQ: 4, iDe: 3, iDr: 0, spC: 31, seC: 3, skC: 3, eQ: 1, eD: 0, sE: [], t: [] + mL: {}, mE: {}, hE: {}, hL: {}, // errors and latencies were popped + tR: 0, aR: 0, iQ: 4, iDe: 3, iDr: 0, spC: 31, seC: 3, skC: 3, eQ: 1, eD: 0, sE: [], t: [] }, '2nd metrics/usage JSON payload should be the expected'); return 200; }); From e2b5aa01a9b1daad4ff0aae1f717248fd004353b Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 17 May 2022 16:41:39 -0300 Subject: [PATCH 09/16] prepare rc --- .github/workflows/ci-cd.yml | 4 ++-- package-lock.json | 2 +- package.json | 2 +- src/settings/defaults/version.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 7164bcf99..a5a3cbf13 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -51,14 +51,14 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") BUILD_COMMIT=${{ github.sha }} npm run build - name: Configure AWS credentials (development) - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/telemetry_v2' }} uses: aws-actions/configure-aws-credentials@v1 with: role-to-assume: arn:aws:iam::079419646996:role/public-assets aws-region: us-east-1 - name: Upload to S3 (development) - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/telemetry_v2' }} run: aws s3 sync $SOURCE_DIR s3://$BUCKET/$DEST_DIR $ARGS env: BUCKET: split-public-stage diff --git a/package-lock.json b/package-lock.json index b50935d4d..f376b9e93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.18.2", + "version": "10.18.3-rc.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e462c48ba..b6f9f6f86 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.18.2", + "version": "10.18.3-rc.0", "description": "Split SDK", "files": [ "README.md", diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 3187bdd08..9c4d41505 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.18.2'; +export const packageVersion = '10.18.3-rc.0'; From eb64dfd6ecd1785fdb7665d70d575cd704997e2f Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 17 May 2022 16:56:55 -0300 Subject: [PATCH 10/16] removed old metricsRefreshRate config from tests --- src/__tests__/browser.spec.js | 3 --- src/__tests__/browserSuites/events.spec.js | 1 - .../browserSuites/ignore-ip-addresses-setting.spec.js | 1 - .../browserSuites/impressions-listener.spec.js | 1 - src/__tests__/browserSuites/impressions.debug.spec.js | 1 - src/__tests__/browserSuites/impressions.spec.js | 1 - src/__tests__/browserSuites/push-fallbacking.spec.js | 1 - .../browserSuites/push-initialization-nopush.spec.js | 1 - .../browserSuites/push-initialization-retries.spec.js | 1 - src/__tests__/browserSuites/readiness.spec.js | 10 ---------- src/__tests__/browserSuites/ready-from-cache.spec.js | 1 - src/__tests__/errorCatching/browser.spec.js | 2 +- src/__tests__/errorCatching/node.spec.js | 2 +- src/__tests__/offline/browser.spec.js | 1 - src/__tests__/offline/node.spec.js | 1 - 15 files changed, 2 insertions(+), 26 deletions(-) diff --git a/src/__tests__/browser.spec.js b/src/__tests__/browser.spec.js index c1993c405..204f8dc03 100644 --- a/src/__tests__/browser.spec.js +++ b/src/__tests__/browser.spec.js @@ -45,7 +45,6 @@ const configInMemory = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, // for now I don't want to publish metrics during E2E run. impressionsRefreshRate: 3000 // for now I don't want to publish impressions during E2E run. }, streamingEnabled: false @@ -62,7 +61,6 @@ const configInMemoryWithBucketingKey = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, // for now I don't want to publish metrics during E2E run. impressionsRefreshRate: 3000 // for now I don't want to publish impressions during E2E run. }, streamingEnabled: false @@ -76,7 +74,6 @@ const configInLocalStorage = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, // for now I don't want to publish metrics during E2E run. impressionsRefreshRate: 3000 // for now I don't want to publish impressions during E2E run. }, storage: { diff --git a/src/__tests__/browserSuites/events.spec.js b/src/__tests__/browserSuites/events.spec.js index 1d18a6e66..396f01d35 100644 --- a/src/__tests__/browserSuites/events.spec.js +++ b/src/__tests__/browserSuites/events.spec.js @@ -17,7 +17,6 @@ const baseSettings = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000, eventsPushRate: 3000 }, diff --git a/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js b/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js index 80e1f27cc..3a76bc465 100644 --- a/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js +++ b/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js @@ -11,7 +11,6 @@ const HEADER_SPLITSDKMACHINENAME = 'SplitSDKMachineName'; // Refresh rates are set to 1 second to finish the test quickly. Otherwise, it would finish in 1 minute (60 seconds is the default value) const baseConfig = { scheduler: { - metricsRefreshRate: 1, impressionsRefreshRate: 1, eventsPushRate: 1 }, diff --git a/src/__tests__/browserSuites/impressions-listener.spec.js b/src/__tests__/browserSuites/impressions-listener.spec.js index 79339b54c..5ca928804 100644 --- a/src/__tests__/browserSuites/impressions-listener.spec.js +++ b/src/__tests__/browserSuites/impressions-listener.spec.js @@ -21,7 +21,6 @@ const config = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000 }, startup: { diff --git a/src/__tests__/browserSuites/impressions.debug.spec.js b/src/__tests__/browserSuites/impressions.debug.spec.js index f8ceb5e2f..a4b182dce 100644 --- a/src/__tests__/browserSuites/impressions.debug.spec.js +++ b/src/__tests__/browserSuites/impressions.debug.spec.js @@ -33,7 +33,6 @@ export default function (fetchMock, assert) { scheduler: { featuresRefreshRate: 0.5, segmentsRefreshRate: 0.5, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000, impressionsQueueSize: 3 // flush impressions when 3 are queued }, diff --git a/src/__tests__/browserSuites/impressions.spec.js b/src/__tests__/browserSuites/impressions.spec.js index c20506d30..e5ebb5092 100644 --- a/src/__tests__/browserSuites/impressions.spec.js +++ b/src/__tests__/browserSuites/impressions.spec.js @@ -36,7 +36,6 @@ export default function (fetchMock, assert) { scheduler: { featuresRefreshRate: 0.5, segmentsRefreshRate: 0.5, - metricsRefreshRate: 3000, impressionsRefreshRate: 0.5 }, startup: { diff --git a/src/__tests__/browserSuites/push-fallbacking.spec.js b/src/__tests__/browserSuites/push-fallbacking.spec.js index fafb3725e..878a3f5ea 100644 --- a/src/__tests__/browserSuites/push-fallbacking.spec.js +++ b/src/__tests__/browserSuites/push-fallbacking.spec.js @@ -51,7 +51,6 @@ const config = { scheduler: { featuresRefreshRate: 0.2, segmentsRefreshRate: 0.25, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000 }, urls: baseUrls, diff --git a/src/__tests__/browserSuites/push-initialization-nopush.spec.js b/src/__tests__/browserSuites/push-initialization-nopush.spec.js index d337501f8..6e0e0a4f7 100644 --- a/src/__tests__/browserSuites/push-initialization-nopush.spec.js +++ b/src/__tests__/browserSuites/push-initialization-nopush.spec.js @@ -24,7 +24,6 @@ const config = { scheduler: { featuresRefreshRate: 0.1, segmentsRefreshRate: 0.1, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000, pushRetryBackoffBase: 0.01 // small value to assert rapidly that push is not retried }, diff --git a/src/__tests__/browserSuites/push-initialization-retries.spec.js b/src/__tests__/browserSuites/push-initialization-retries.spec.js index 7fd440c2d..6585076d8 100644 --- a/src/__tests__/browserSuites/push-initialization-retries.spec.js +++ b/src/__tests__/browserSuites/push-initialization-retries.spec.js @@ -26,7 +26,6 @@ const config = { scheduler: { featuresRefreshRate: 0.2, segmentsRefreshRate: 0.2, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000, pushRetryBackoffBase: 0.1 }, diff --git a/src/__tests__/browserSuites/readiness.spec.js b/src/__tests__/browserSuites/readiness.spec.js index 5956af465..c6897fafd 100644 --- a/src/__tests__/browserSuites/readiness.spec.js +++ b/src/__tests__/browserSuites/readiness.spec.js @@ -22,7 +22,6 @@ const baseConfig = { scheduler: { featuresRefreshRate: 3000, segmentsRefreshRate: 3000, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000 }, startup: { @@ -164,7 +163,6 @@ export default function (fetchMock, assert) { scheduler: { featuresRefreshRate: 3.1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000 }, urls: testUrls @@ -245,7 +243,6 @@ export default function (fetchMock, assert) { scheduler: { featuresRefreshRate: 3.1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000 }, storage: { @@ -330,7 +327,6 @@ export default function (fetchMock, assert) { scheduler: { featuresRefreshRate: 3.1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000 }, urls: testUrls @@ -411,7 +407,6 @@ export default function (fetchMock, assert) { scheduler: { featuresRefreshRate: 3.1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000 }, storage: { @@ -481,7 +476,6 @@ export default function (fetchMock, assert) { scheduler: { featuresRefreshRate: 3.1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000 }, storage: { @@ -529,7 +523,6 @@ export default function (fetchMock, assert) { scheduler: { featuresRefreshRate: 3.1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000 }, storage: { @@ -581,7 +574,6 @@ export default function (fetchMock, assert) { scheduler: { featuresRefreshRate: 3.1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000 }, storage: { @@ -629,7 +621,6 @@ export default function (fetchMock, assert) { scheduler: { featuresRefreshRate: 3.1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000 }, storage: { @@ -680,7 +671,6 @@ export default function (fetchMock, assert) { scheduler: { featuresRefreshRate: 3.1, segmentsRefreshRate: 1, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000 }, storage: { diff --git a/src/__tests__/browserSuites/ready-from-cache.spec.js b/src/__tests__/browserSuites/ready-from-cache.spec.js index fe52597a8..45a56012e 100644 --- a/src/__tests__/browserSuites/ready-from-cache.spec.js +++ b/src/__tests__/browserSuites/ready-from-cache.spec.js @@ -72,7 +72,6 @@ const baseConfig = { scheduler: { featuresRefreshRate: 3000, segmentsRefreshRate: 3000, - metricsRefreshRate: 3000, impressionsRefreshRate: 3000 }, startup: { diff --git a/src/__tests__/errorCatching/browser.spec.js b/src/__tests__/errorCatching/browser.spec.js index f5e3e2e7c..af5a0cabe 100644 --- a/src/__tests__/errorCatching/browser.spec.js +++ b/src/__tests__/errorCatching/browser.spec.js @@ -48,7 +48,7 @@ tape('Error catching on callbacks - Browsers', assert => { scheduler: { featuresRefreshRate: 1.5, segmentsRefreshRate: 100000, - metricsRefreshRate: 100000, + telemetryRefreshRate: 100000, impressionsRefreshRate: 100000, eventsPushRate: 100000 }, diff --git a/src/__tests__/errorCatching/node.spec.js b/src/__tests__/errorCatching/node.spec.js index df373acb2..c270d68e4 100644 --- a/src/__tests__/errorCatching/node.spec.js +++ b/src/__tests__/errorCatching/node.spec.js @@ -41,7 +41,7 @@ tape('Error catching on callbacks', assert => { scheduler: { featuresRefreshRate: 2, segmentsRefreshRate: 10000, - metricsRefreshRate: 10000, + telemetryRefreshRate: 10000, impressionsRefreshRate: 10000, eventsPushRate: 10000 }, diff --git a/src/__tests__/offline/browser.spec.js b/src/__tests__/offline/browser.spec.js index e3f8552aa..b97496a50 100644 --- a/src/__tests__/offline/browser.spec.js +++ b/src/__tests__/offline/browser.spec.js @@ -56,7 +56,6 @@ tape('Browser offline mode', function (assert) { scheduler: { impressionsRefreshRate: 0.01, eventsPushRate: 0.01, - metricsRefreshRate: 0.01, offlineRefreshRate: 0.19 }, startup: { diff --git a/src/__tests__/offline/node.spec.js b/src/__tests__/offline/node.spec.js index cd4bb3630..5e384bb04 100644 --- a/src/__tests__/offline/node.spec.js +++ b/src/__tests__/offline/node.spec.js @@ -46,7 +46,6 @@ const settingsGenerator = mockFileName => { scheduler: { impressionsRefreshRate: 0.01, eventsPushRate: 0.01, - metricsRefreshRate: 0.01, offlineRefreshRate: 0.3 }, startup: { From bb78ea7f6bfbfd751a766f0b454258ca08507557 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 17 May 2022 17:15:11 -0300 Subject: [PATCH 11/16] polishing on test configs --- .../browserSuites/ignore-ip-addresses-setting.spec.js | 3 --- src/__tests__/node.spec.js | 1 - src/__tests__/nodeSuites/impressions-listener.spec.js | 5 ----- src/__tests__/nodeSuites/impressions.debug.spec.js | 1 - src/__tests__/nodeSuites/impressions.spec.js | 4 ---- src/__tests__/nodeSuites/push-fallbacking.spec.js | 2 -- src/__tests__/nodeSuites/push-initialization-nopush.spec.js | 5 ----- src/__tests__/nodeSuites/push-initialization-retries.spec.js | 5 ----- src/__tests__/offline/node.spec.js | 1 - 9 files changed, 27 deletions(-) diff --git a/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js b/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js index 3a76bc465..05383e38b 100644 --- a/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js +++ b/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js @@ -70,9 +70,6 @@ const configSamples = [ const postEndpoints = [ '/events/bulk', '/testImpressions/bulk', - // @TODO uncomment when telemetry is implemented - // '/metrics/times', - // '/metrics/counters' ]; export default function (fetchMock, assert) { diff --git a/src/__tests__/node.spec.js b/src/__tests__/node.spec.js index 903cd70be..e9f80e753 100644 --- a/src/__tests__/node.spec.js +++ b/src/__tests__/node.spec.js @@ -26,7 +26,6 @@ const config = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - telemetryRefreshRate: 3000, // for now I don't want to publish telemetry stats during E2E run. impressionsRefreshRate: 3000 // for now I don't want to publish impressions during E2E run. }, streamingEnabled: false diff --git a/src/__tests__/nodeSuites/impressions-listener.spec.js b/src/__tests__/nodeSuites/impressions-listener.spec.js index eecc4b6c6..fe26fb364 100644 --- a/src/__tests__/nodeSuites/impressions-listener.spec.js +++ b/src/__tests__/nodeSuites/impressions-listener.spec.js @@ -20,11 +20,6 @@ const config = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - telemetryRefreshRate: 3000, - impressionsRefreshRate: 3000 - }, - startup: { - eventsFirstPushWindow: 3000 }, impressionListener: listener, streamingEnabled: false diff --git a/src/__tests__/nodeSuites/impressions.debug.spec.js b/src/__tests__/nodeSuites/impressions.debug.spec.js index fa38d4175..2005d96c4 100644 --- a/src/__tests__/nodeSuites/impressions.debug.spec.js +++ b/src/__tests__/nodeSuites/impressions.debug.spec.js @@ -25,7 +25,6 @@ const config = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - telemetryRefreshRate: 3000, impressionsRefreshRate: 3000, impressionsQueueSize: 3 // flush impressions when 3 are queued }, diff --git a/src/__tests__/nodeSuites/impressions.spec.js b/src/__tests__/nodeSuites/impressions.spec.js index b269ebaa8..a3bacb4be 100644 --- a/src/__tests__/nodeSuites/impressions.spec.js +++ b/src/__tests__/nodeSuites/impressions.spec.js @@ -27,13 +27,9 @@ const config = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - telemetryRefreshRate: 3000, impressionsRefreshRate: 5 // No effect, since min is 300 }, urls: baseUrls, - startup: { - eventsFirstPushWindow: 3000 - }, streamingEnabled: false }; diff --git a/src/__tests__/nodeSuites/push-fallbacking.spec.js b/src/__tests__/nodeSuites/push-fallbacking.spec.js index 88b01cc48..8285028ad 100644 --- a/src/__tests__/nodeSuites/push-fallbacking.spec.js +++ b/src/__tests__/nodeSuites/push-fallbacking.spec.js @@ -46,8 +46,6 @@ const config = { scheduler: { featuresRefreshRate: 0.2, segmentsRefreshRate: 0.25, - telemetryRefreshRate: 3000, - impressionsRefreshRate: 3000 }, urls: baseUrls, streamingEnabled: true, diff --git a/src/__tests__/nodeSuites/push-initialization-nopush.spec.js b/src/__tests__/nodeSuites/push-initialization-nopush.spec.js index 9968bec59..f17b41412 100644 --- a/src/__tests__/nodeSuites/push-initialization-nopush.spec.js +++ b/src/__tests__/nodeSuites/push-initialization-nopush.spec.js @@ -23,14 +23,9 @@ const config = { scheduler: { featuresRefreshRate: 0.1, segmentsRefreshRate: 0.1, - telemetryRefreshRate: 3000, - impressionsRefreshRate: 3000, pushRetryBackoffBase: 0.01 // small value to assert rapidly that push is not retried }, urls: baseUrls, - startup: { - eventsFirstPushWindow: 3000 - }, streamingEnabled: true, // debug: true, }; diff --git a/src/__tests__/nodeSuites/push-initialization-retries.spec.js b/src/__tests__/nodeSuites/push-initialization-retries.spec.js index e88a34d97..51b7b0ece 100644 --- a/src/__tests__/nodeSuites/push-initialization-retries.spec.js +++ b/src/__tests__/nodeSuites/push-initialization-retries.spec.js @@ -24,14 +24,9 @@ const config = { scheduler: { featuresRefreshRate: 0.2, segmentsRefreshRate: 0.2, - telemetryRefreshRate: 3000, - impressionsRefreshRate: 3000, pushRetryBackoffBase: 0.1 }, urls: baseUrls, - startup: { - eventsFirstPushWindow: 3000 - }, streamingEnabled: true, // debug: true, }; diff --git a/src/__tests__/offline/node.spec.js b/src/__tests__/offline/node.spec.js index 5e384bb04..777c7649d 100644 --- a/src/__tests__/offline/node.spec.js +++ b/src/__tests__/offline/node.spec.js @@ -49,7 +49,6 @@ const settingsGenerator = mockFileName => { offlineRefreshRate: 0.3 }, startup: { - eventsFirstPushWindow: 0, readyTimeout: 3, retriesOnFailureBeforeReady: 0 }, From 6a6f4e870fdf98c02ff5cdab93a794cdd465fff4 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 17 May 2022 17:40:16 -0300 Subject: [PATCH 12/16] update telemetry test --- src/__tests__/browserSuites/telemetry.spec.js | 1 + src/__tests__/nodeSuites/telemetry.spec.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/__tests__/browserSuites/telemetry.spec.js b/src/__tests__/browserSuites/telemetry.spec.js index 36520ac5d..67db4c5df 100644 --- a/src/__tests__/browserSuites/telemetry.spec.js +++ b/src/__tests__/browserSuites/telemetry.spec.js @@ -13,6 +13,7 @@ const config = { key: 'user-key' }, scheduler: { + featuresRefreshRate: 99999, telemetryRefreshRate: 60 }, urls: baseUrls, diff --git a/src/__tests__/nodeSuites/telemetry.spec.js b/src/__tests__/nodeSuites/telemetry.spec.js index bef2b23da..81679fc81 100644 --- a/src/__tests__/nodeSuites/telemetry.spec.js +++ b/src/__tests__/nodeSuites/telemetry.spec.js @@ -13,6 +13,7 @@ const config = { authorizationKey: '' }, scheduler: { + featuresRefreshRate: 99999, telemetryRefreshRate: 60 }, urls: baseUrls, From 8b9cb07267ca7cc5beeb6d03795b2bd8a0f97dac Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 20 May 2022 15:11:05 -0300 Subject: [PATCH 13/16] rc --- .github/workflows/ci-cd.yml | 4 ++-- package-lock.json | 8 ++++---- package.json | 4 ++-- src/__tests__/browserSuites/telemetry.spec.js | 2 +- src/__tests__/node_redis.spec.js | 3 ++- src/settings/defaults/version.js | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index a5a3cbf13..db66db99d 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -51,14 +51,14 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") BUILD_COMMIT=${{ github.sha }} npm run build - name: Configure AWS credentials (development) - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/telemetry_v2' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/telemetry_v2_type_definitions' }} uses: aws-actions/configure-aws-credentials@v1 with: role-to-assume: arn:aws:iam::079419646996:role/public-assets aws-region: us-east-1 - name: Upload to S3 (development) - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/telemetry_v2' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/telemetry_v2_type_definitions' }} run: aws s3 sync $SOURCE_DIR s3://$BUCKET/$DEST_DIR $ARGS env: BUCKET: split-public-stage diff --git a/package-lock.json b/package-lock.json index f376b9e93..b5b83ac3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.18.3-rc.0", + "version": "10.18.3-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -437,9 +437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.3.2-rc.5", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.5.tgz", - "integrity": "sha512-43xcxlBv39fGle+fLTSV2/eZYVo6DC1LqXn7OUvEvuTbomihpauD+XjdlicG5U08Is/ncnj6eG1jCxjpKqal0g==", + "version": "1.3.2-rc.6", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.6.tgz", + "integrity": "sha512-iBaz0NlixndiY63tHDtv835NyPzZMTEqgx30EtYBBuGdBffJBQbLvTeTRLD+VIHIWoQNZ323PipftLtuTXaAuQ==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index b6f9f6f86..d04e887fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.18.3-rc.0", + "version": "10.18.3-rc.1", "description": "Split SDK", "files": [ "README.md", @@ -32,7 +32,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.3.2-rc.5", + "@splitsoftware/splitio-commons": "1.3.2-rc.6", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "ioredis": "^4.28.0", diff --git a/src/__tests__/browserSuites/telemetry.spec.js b/src/__tests__/browserSuites/telemetry.spec.js index 67db4c5df..e6ebbad22 100644 --- a/src/__tests__/browserSuites/telemetry.spec.js +++ b/src/__tests__/browserSuites/telemetry.spec.js @@ -102,7 +102,7 @@ export default async function telemetryBrowserSuite(fetchMock, assert) { assert.deepEqual(data, { oM: 0, st: 'memory', aF: 1, rF: 0, sE: false, - rR: { sp: 99999, se: 60, im: 300, ev: 60, te: 1 } /* override featuresRefreshRate */, + rR: { sp: 99999, ms: 60, im: 300, ev: 60, te: 1 } /* override featuresRefreshRate */, uO: { s: true, e: true, a: false, st: false, t: true } /* override sdk, events and telemetry URLs */, iQ: 30000, eQ: 500, iM: 0, iL: false, hP: false, nR: 1 /* 1 non ready usage */, t: [], i: [], uC: 2 /* Default GRANTED */ }, 'metrics/config JSON payload should be the expected'); diff --git a/src/__tests__/node_redis.spec.js b/src/__tests__/node_redis.spec.js index 7766c314b..2ee60f4b8 100644 --- a/src/__tests__/node_redis.spec.js +++ b/src/__tests__/node_redis.spec.js @@ -13,6 +13,7 @@ import { KeyBuilderSS } from '@splitsoftware/splitio-commons/src/storages/KeyBui import { validatePrefix } from '@splitsoftware/splitio-commons/src/storages/KeyBuilder'; import { settingsFactory } from '../settings'; import { nearlyEqual } from './testUtils'; +import { version } from '../../package.json'; const IP_VALUE = ipFunction.address(); const HOSTNAME_VALUE = osFunction.hostname(); @@ -127,7 +128,7 @@ tape('NodeJS Redis', function (t) { assert.deepEqual(trackedImpressionsAndEvents, [14, 2], 'Tracked impressions and events should be stored in Redis'); // Validate stored telemetry - exec(`echo "HLEN ${config.storage.prefix}.SPLITIO.telemetry.latencies \n HLEN ${config.storage.prefix}.SPLITIO.telemetry.exceptions \n HGET ${config.storage.prefix}.SPLITIO.telemetry.init ${'nodejs-10.18.3-rc.0'}/${HOSTNAME_VALUE}/${IP_VALUE}" | redis-cli -p ${redisPort}`, (error, stdout) => { + exec(`echo "HLEN ${config.storage.prefix}.SPLITIO.telemetry.latencies \n HLEN ${config.storage.prefix}.SPLITIO.telemetry.exceptions \n HGET ${config.storage.prefix}.SPLITIO.telemetry.init nodejs-${version}/${HOSTNAME_VALUE}/${IP_VALUE}" | redis-cli -p ${redisPort}`, (error, stdout) => { if (error) assert.fail('Redis server should be reachable'); const [latencies, exceptions, configValue] = stdout.split('\n').filter(line => line !== '').map(JSON.parse); diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 9c4d41505..1cbe8cc0c 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.18.3-rc.0'; +export const packageVersion = '10.18.3-rc.1'; From 713c4b99ec425b9fb0ecb85b1f8d4f601f79c69f Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Mon, 23 May 2022 17:49:17 -0300 Subject: [PATCH 14/16] rc --- .github/workflows/ci-cd.yml | 4 ++-- CHANGES.txt | 5 +++++ package-lock.json | 20 ++++++++++---------- package.json | 4 ++-- src/__tests__/nodeSuites/impressions.spec.js | 6 ++---- src/settings/defaults/version.js | 2 +- 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index db66db99d..d93ddbc62 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -51,14 +51,14 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") BUILD_COMMIT=${{ github.sha }} npm run build - name: Configure AWS credentials (development) - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/telemetry_v2_type_definitions' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/release_v10.19.0' }} uses: aws-actions/configure-aws-credentials@v1 with: role-to-assume: arn:aws:iam::079419646996:role/public-assets aws-region: us-east-1 - name: Upload to S3 (development) - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/telemetry_v2_type_definitions' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/release_v10.19.0' }} run: aws s3 sync $SOURCE_DIR s3://$BUCKET/$DEST_DIR $ARGS env: BUCKET: split-public-stage diff --git a/CHANGES.txt b/CHANGES.txt index 1dcf3090b..5973c4fbf 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,8 @@ +10.19.0 (May 24, 2022) + - Added `scheduler.telemetryRefreshRate` property to SDK configuration, and deprecated `scheduler.metricsRefreshRate` property. + - Updated SDK telemetry storage, metrics and updater to be more effective and send less often. + - Bugfixing - Updated default values for `scheduler.impressionsRefreshRate` config parameter: 300s for OPTIMIZED impression mode and 60s for DEBUG impression mode. + 10.18.2 (May 6, 2022) - Bugfixing - Removed "ip" dependency to use an inline copy of it that fixes an error when using it in Node v18 (https://github.com/indutny/node-ip/issues/113). diff --git a/package-lock.json b/package-lock.json index b5b83ac3e..b3471240d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.18.3-rc.1", + "version": "10.18.3-rc.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -437,9 +437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.3.2-rc.6", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.6.tgz", - "integrity": "sha512-iBaz0NlixndiY63tHDtv835NyPzZMTEqgx30EtYBBuGdBffJBQbLvTeTRLD+VIHIWoQNZ323PipftLtuTXaAuQ==", + "version": "1.3.2-rc.7", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.7.tgz", + "integrity": "sha512-XXlzwycEFkO6hAducV7f+78n8qp5o/Kq94VyZVRi1VI8DbKD+stvilHOiZ+J595rWDFBtmx7XKxJKkLtITahdA==", "requires": { "tslib": "^2.3.1" } @@ -2818,9 +2818,9 @@ "dev": true }, "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.1.tgz", + "integrity": "sha512-qV5ZC0h7jYIAOhArFJgSfdyz6rALJyb270714o7ZtNnw2WSJ+eexhKtE0O8LYPRsHZHf2osHKZBxGPvm3kPkCA==", "optional": true, "requires": { "original": "^1.0.0" @@ -4936,9 +4936,9 @@ "dev": true }, "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "optional": true }, "randombytes": { diff --git a/package.json b/package.json index d04e887fd..3327ddbec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.18.3-rc.1", + "version": "10.18.3-rc.2", "description": "Split SDK", "files": [ "README.md", @@ -32,7 +32,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.3.2-rc.6", + "@splitsoftware/splitio-commons": "1.3.2-rc.7", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "ioredis": "^4.28.0", diff --git a/src/__tests__/nodeSuites/impressions.spec.js b/src/__tests__/nodeSuites/impressions.spec.js index a3bacb4be..21324b560 100644 --- a/src/__tests__/nodeSuites/impressions.spec.js +++ b/src/__tests__/nodeSuites/impressions.spec.js @@ -27,7 +27,7 @@ const config = { scheduler: { featuresRefreshRate: 1, segmentsRefreshRate: 1, - impressionsRefreshRate: 5 // No effect, since min is 300 + impressionsRefreshRate: 5 }, urls: baseUrls, streamingEnabled: false @@ -41,9 +41,7 @@ export default async function(key, fetchMock, assert) { fetchMock.get(url(settings, '/splitChanges?since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: {since:10, till:10, name: 'segmentName', added: [], removed: []} }); - const splitio = SplitFactory(config, ({settings}) => { - settings.scheduler.impressionsRefreshRate = 5000; // 5 secs - }); + const splitio = SplitFactory(config); const client = splitio.client(); let evaluationsStart = 0, readyEvaluationsStart = 0, evaluationsEnd = 0; diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 1cbe8cc0c..70d4ca918 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.18.3-rc.1'; +export const packageVersion = '10.18.3-rc.2'; From fbf089b0aff79919f2042d284a4bf3fbc2c0103b Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 24 May 2022 12:34:04 -0300 Subject: [PATCH 15/16] rc --- CHANGES.txt | 3 ++- package-lock.json | 2 +- package.json | 2 +- src/settings/defaults/version.js | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 5973c4fbf..79303ed5b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,7 +1,8 @@ 10.19.0 (May 24, 2022) - Added `scheduler.telemetryRefreshRate` property to SDK configuration, and deprecated `scheduler.metricsRefreshRate` property. - Updated SDK telemetry storage, metrics and updater to be more effective and send less often. - - Bugfixing - Updated default values for `scheduler.impressionsRefreshRate` config parameter: 300s for OPTIMIZED impression mode and 60s for DEBUG impression mode. + - Bugfixing - Updated default values for `scheduler.impressionsRefreshRate` config parameter: 300s for OPTIMIZED impression mode and 60s for DEBUG impression mode, + in both Browser and NodeJS (previously it was 60s and 300s in Browser and NodeJS respectively, equal for DEBUG and OPTIMIZED impression modes). 10.18.2 (May 6, 2022) - Bugfixing - Removed "ip" dependency to use an inline copy of it that fixes an error when using it in Node v18 (https://github.com/indutny/node-ip/issues/113). diff --git a/package-lock.json b/package-lock.json index b3471240d..cc0aad319 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.18.3-rc.2", + "version": "10.18.3-rc.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3327ddbec..42e247ef5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.18.3-rc.2", + "version": "10.18.3-rc.3", "description": "Split SDK", "files": [ "README.md", diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 70d4ca918..6ba620ef4 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.18.3-rc.2'; +export const packageVersion = '10.18.3-rc.3'; From a2c26ab326cd1cdcea472c7139a1ae4849979a23 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 24 May 2022 15:16:36 -0300 Subject: [PATCH 16/16] stable version --- .github/workflows/ci-cd.yml | 4 ++-- package-lock.json | 8 ++++---- package.json | 4 ++-- src/settings/defaults/version.js | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index d93ddbc62..7164bcf99 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -51,14 +51,14 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") BUILD_COMMIT=${{ github.sha }} npm run build - name: Configure AWS credentials (development) - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/release_v10.19.0' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} uses: aws-actions/configure-aws-credentials@v1 with: role-to-assume: arn:aws:iam::079419646996:role/public-assets aws-region: us-east-1 - name: Upload to S3 (development) - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/release_v10.19.0' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} run: aws s3 sync $SOURCE_DIR s3://$BUCKET/$DEST_DIR $ARGS env: BUCKET: split-public-stage diff --git a/package-lock.json b/package-lock.json index cc0aad319..7891466df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.18.3-rc.3", + "version": "10.19.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -437,9 +437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.3.2-rc.7", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.3.2-rc.7.tgz", - "integrity": "sha512-XXlzwycEFkO6hAducV7f+78n8qp5o/Kq94VyZVRi1VI8DbKD+stvilHOiZ+J595rWDFBtmx7XKxJKkLtITahdA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.4.0.tgz", + "integrity": "sha512-i/gXbtzUMKotva66mkPpa8g49v+gR4AbA/ZTKBGFi4CN+blwFO/10YQQWro8Gm9YJIB1mTXdplem6XkeBUzISA==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index 42e247ef5..8e16d9430 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.18.3-rc.3", + "version": "10.19.0", "description": "Split SDK", "files": [ "README.md", @@ -32,7 +32,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.3.2-rc.7", + "@splitsoftware/splitio-commons": "1.4.0", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "ioredis": "^4.28.0", diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 6ba620ef4..87675e575 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.18.3-rc.3'; +export const packageVersion = '10.19.0';