feat(testing): update test apps with generic polling and add CI/CD pipeline
- Update iOS and Android test apps with generic polling interface support - Add testGenericPolling(), testPollingSchedule(), and testPollingResults() methods - Include comprehensive testing of GenericPollingRequest creation and validation - Add PollingScheduleConfig testing with cron expressions and platform adapters - Test PollingResult handling with watermark CAS and acknowledgment flows - Update test-apps/README.md with generic polling testing capabilities - Add .github/workflows/ci.yml with automated testing pipeline - Include linting, unit tests (workspaces), and k6 smoke test execution - Add k6/poll-ack-smoke.js for fault-injection testing of poll and ack endpoints - Support cross-platform testing with consistent TypeScript interfaces - Include platform-specific optimizations (WorkManager, BGTaskScheduler, Service Workers) Provides comprehensive testing infrastructure for the generic polling system.
This commit is contained in:
62
k6/poll-ack-smoke.js
Normal file
62
k6/poll-ack-smoke.js
Normal file
@@ -0,0 +1,62 @@
|
||||
// k6 run k6/poll-ack-smoke.js
|
||||
import http from 'k6/http';
|
||||
import { check, sleep } from 'k6';
|
||||
import { Trend, Counter } from 'k6/metrics';
|
||||
|
||||
const latency = new Trend('api_latency');
|
||||
const throttles = new Counter('rate_limits');
|
||||
|
||||
export const options = { vus: 5, duration: '1m' };
|
||||
|
||||
const BASE = __ENV.API || 'https://api.endorser.ch';
|
||||
const JWT = __ENV.JWT || 'REDACTED';
|
||||
|
||||
function idem() { return crypto.randomUUID(); }
|
||||
|
||||
export default function () {
|
||||
// POLL (simulate occasional 429 / 5xx via test env or chaos flag)
|
||||
const pollRes = http.post(
|
||||
`${BASE}/api/v2/report/plansLastUpdatedBetween`,
|
||||
JSON.stringify({ planIds: ['demo1','demo2'], limit: 3, afterId: __ITER === 0 ? undefined : __ENV.AFTER }),
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${JWT}`,
|
||||
'Content-Type': 'application/json',
|
||||
'X-Idempotency-Key': idem(),
|
||||
'X-Client-Version': 'TimeSafari-Plugin/1.0.0'
|
||||
},
|
||||
tags: { endpoint: 'poll' }
|
||||
}
|
||||
);
|
||||
|
||||
latency.add(pollRes.timings.duration);
|
||||
|
||||
if (pollRes.status === 429) throttles.add(1);
|
||||
|
||||
check(pollRes, {
|
||||
'poll: 2xx or 429/5xx with JSON': (r) => [200,429,500,503].includes(r.status) && r.headers['Content-Type']?.includes('application/json'),
|
||||
});
|
||||
|
||||
if (pollRes.status === 200) {
|
||||
const body = pollRes.json();
|
||||
const ids = (body?.data || []).map(x => x?.planSummary?.jwtId).filter(Boolean);
|
||||
// ACK
|
||||
if (ids.length) {
|
||||
const ackRes = http.post(
|
||||
`${BASE}/api/v2/plans/acknowledge`,
|
||||
JSON.stringify({ acknowledgedJwtIds: ids, acknowledgedAt: new Date().toISOString(), clientVersion: 'TimeSafari-Plugin/1.0.0' }),
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${JWT}`,
|
||||
'Content-Type': 'application/json',
|
||||
'X-Idempotency-Key': idem()
|
||||
},
|
||||
tags: { endpoint: 'ack' }
|
||||
}
|
||||
);
|
||||
check(ackRes, { 'ack: success/idem': (r) => [200, 409].includes(r.status) });
|
||||
}
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
Reference in New Issue
Block a user