Skip to content

Commit 9b356db

Browse files
Add proxy fallback test
1 parent 8ea167a commit 9b356db

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import { SplitFactory } from '../../';
2+
import splitChangesMockReal from '../mocks/splitchanges.real.json';
3+
import authPushDisabled from '../mocks/auth.pushDisabled.json';
4+
import { nearlyEqual, url } from '../testUtils';
5+
6+
const config = {
7+
core: {
8+
authorizationKey: '<fake-token-1>'
9+
},
10+
scheduler: {
11+
featuresRefreshRate: 0.5,
12+
},
13+
urls: {
14+
sdk: 'https://outdated-proxy/api',
15+
auth: 'https://outdated-proxy/api',
16+
}
17+
};
18+
19+
// Response mocks
20+
const outdatedProxyFailResponse = {
21+
status: 400
22+
};
23+
const outdatedProxyInitialResponse = {
24+
status: 200, body: {
25+
splits: splitChangesMockReal.ff.d,
26+
since: splitChangesMockReal.ff.s,
27+
till: splitChangesMockReal.ff.t
28+
}
29+
};
30+
const outdatedProxyNextResponse = {
31+
status: 200, body: {
32+
splits: [],
33+
since: 1457552620999,
34+
till: 1457552620999
35+
}
36+
};
37+
const fixedProxyInitialResponse = {
38+
status: 200, body: splitChangesMockReal
39+
};
40+
const fixedProxyNextResponse = {
41+
status: 200, body: {
42+
ff: {
43+
d: [],
44+
s: 1457552620999,
45+
t: 1457552620999
46+
}
47+
}
48+
};
49+
50+
export async function proxyFallbackSuite(fetchMock, assert) {
51+
const originalDateNow = Date.now;
52+
const start = originalDateNow();
53+
54+
fetchMock.getOnce(url(config, '/v2/auth?s=1.2'), { status: 200, body: authPushDisabled });
55+
56+
// Outdated Proxy responds with 400 when spec 1.3 is provided
57+
fetchMock.getOnce(url(config, '/splitChanges?s=1.3&since=-1&rbSince=-1'), outdatedProxyFailResponse);
58+
59+
// Fallback to spec 1.2
60+
fetchMock.getOnce(url(config, '/splitChanges?s=1.2&since=-1'), () => {
61+
assert.true(nearlyEqual(originalDateNow(), start), 'Initial fallback to spec 1.2');
62+
return outdatedProxyInitialResponse;
63+
});
64+
fetchMock.getOnce(url(config, '/splitChanges?s=1.2&since=1457552620999'), () => {
65+
assert.true(nearlyEqual(originalDateNow(), start), 'Initial fallback to spec 1.2');
66+
return outdatedProxyNextResponse;
67+
});
68+
69+
// Polling with fallback to spec 1.2
70+
fetchMock.getOnce(url(config, '/splitChanges?s=1.2&since=1457552620999'), () => {
71+
assert.true(nearlyEqual(originalDateNow() - start, config.scheduler.featuresRefreshRate * 1000), 'First polling with fallback to spec 1.2');
72+
73+
// Mock Date.now() to return a +24h timestamp to force a proxy recheck
74+
let lastTimestamp = originalDateNow();
75+
Date.now = () => lastTimestamp += 25 * 60 * 60 * 1000;
76+
77+
return outdatedProxyNextResponse;
78+
});
79+
80+
// Polling with proxy recheck using spec 1.3, but fail again
81+
fetchMock.getOnce(url(config, '/splitChanges?s=1.3&since=1457552620999&rbSince=-1'), () => {
82+
assert.true(nearlyEqual(originalDateNow() - start, config.scheduler.featuresRefreshRate * 2000), 'Second polling with recheck');
83+
84+
return outdatedProxyFailResponse;
85+
});
86+
// Fallback to spec 1.2
87+
fetchMock.getOnce(url(config, '/splitChanges?s=1.2&since=1457552620999'), () => {
88+
assert.true(nearlyEqual(originalDateNow() - start, config.scheduler.featuresRefreshRate * 2000), 'Second polling with fallback to spec 1.2');
89+
90+
return outdatedProxyNextResponse;
91+
});
92+
93+
// Polling with proxy recheck using spec 1.3. This time succeeds
94+
fetchMock.getOnce(url(config, '/splitChanges?s=1.3&since=1457552620999&rbSince=-1'), () => {
95+
assert.true(nearlyEqual(originalDateNow() - start, config.scheduler.featuresRefreshRate * 3000), 'Third polling with recheck');
96+
97+
return fixedProxyNextResponse;
98+
});
99+
// Proxy recovery: refetch with clear cache
100+
fetchMock.getOnce(url(config, '/splitChanges?s=1.3&since=-1&rbSince=-1'), () => {
101+
assert.true(nearlyEqual(originalDateNow() - start, config.scheduler.featuresRefreshRate * 3000), 'Proxy recovery: refetch with clear cache');
102+
103+
return fixedProxyInitialResponse;
104+
});
105+
106+
// Polling with spec 1.3
107+
fetchMock.getOnce(url(config, '/splitChanges?s=1.3&since=1457552620999&rbSince=-1'), () => {
108+
assert.true(nearlyEqual(originalDateNow() - start, config.scheduler.featuresRefreshRate * 4000), 'Fourth polling with spec 1.3');
109+
110+
return fixedProxyNextResponse;
111+
});
112+
113+
const splitio = SplitFactory(config);
114+
const client = splitio.client();
115+
const manager = splitio.manager();
116+
117+
client.once(client.Event.SDK_READY, () => {
118+
assert.equal(manager.splits().length, splitChangesMockReal.ff.d.length, 'SDK IS READY as it should. The manager.splits() method should return all feature flags.');
119+
});
120+
121+
client.once(client.Event.SDK_READY_TIMED_OUT, () => {
122+
assert.fail('SDK TIMED OUT - It should not in this scenario');
123+
assert.end();
124+
});
125+
126+
client.once(client.Event.SDK_UPDATE, () => {
127+
assert.true(nearlyEqual(originalDateNow() - start, config.scheduler.featuresRefreshRate * 3000), 'Proxy recovery: refetch with clear cache and spec 1.3 trigger an SDK_UPDATE event');
128+
assert.equal(manager.splits().length, splitChangesMockReal.ff.d.length, 'Validate that the SDK is operational after proxy recovery');
129+
});
130+
131+
// Wait for 4 feature refreshes
132+
await new Promise(resolve => setTimeout(resolve, config.scheduler.featuresRefreshRate * 1000 * 4 + 200));
133+
await client.destroy();
134+
assert.end();
135+
}

src/__tests__/online/node.spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import readyPromiseSuite from '../nodeSuites/ready-promise.spec';
2323
import { fetchSpecificSplits, fetchSpecificSplitsForFlagSets } from '../nodeSuites/fetch-specific-splits.spec';
2424
import flagSets from '../nodeSuites/flag-sets.spec';
2525
import lazyInitSuite from '../nodeSuites/lazy-init.spec';
26+
import { proxyFallbackSuite } from '../nodeSuites/proxy-fallback.spec';
2627

2728
const config = {
2829
core: {
@@ -96,5 +97,8 @@ tape('## Node.js - E2E CI Tests ##', async function (assert) {
9697

9798
assert.test('E2E / SplitFactory with lazy init', lazyInitSuite.bind(null, settings, fetchMock));
9899

100+
// @TODO remove when dropping support for Split Proxy v5.10.0 or below
101+
assert.test('E2E / Proxy fallback', proxyFallbackSuite.bind(null, fetchMock, assert));
102+
99103
assert.end();
100104
});

0 commit comments

Comments
 (0)