Skip to content

Commit 8089ac9

Browse files
authored
Merge pull request #99 from fastly/trevor/integrate-74
Move the JS SDK into this JS Compute Runtime Repo (SDK and Integration Tests)
2 parents 90642b0 + edfbba7 commit 8089ac9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+43476
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: "Compute SDK Test"
2+
description: "Test fixture Wasm modules with Fastly C@E (From a JS Github Action)"
3+
inputs:
4+
config:
5+
description: 'Configuration JSON of the wasm module, and their expectations'
6+
required: true
7+
8+
runs:
9+
using: "node12"
10+
main: dist/main.js

.github/actions/compute-sdk-test/dist/main.js

Lines changed: 32069 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
// Node & 3P Modules
2+
const fs = require('fs');
3+
const path = require('path');
4+
const childProcess = require('child_process');
5+
const fetch = require('node-fetch');
6+
const chalk = require('chalk');
7+
require('better-logging')(console, {
8+
format: ctx => {
9+
10+
const tag = chalk.bold(`[compute-sdk-test]`);
11+
12+
if (ctx.type.includes("debug")) {
13+
return chalk.blue(`${tag} ${chalk.bold(ctx.type)} ${ctx.msg}`);
14+
} else if (ctx.type.includes("info")) {
15+
return chalk.green(`${tag} ${chalk.bold(ctx.type)} ${ctx.msg}`);
16+
} else if (ctx.type.includes("warn")) {
17+
return chalk.yellow(`${tag} ${chalk.bold(ctx.type)} ${ctx.msg}`);
18+
} else if (ctx.type.includes("error")) {
19+
return chalk.red(`${tag} ${chalk.bold(ctx.type)} ${ctx.msg}`);
20+
}
21+
22+
return `${tag} ${chalk.white.bold(ctx.type)} ${ctx.msg}`;
23+
}
24+
});
25+
const core = require('@actions/core');
26+
const github = require('@actions/github');
27+
28+
// Utility modules
29+
const Viceroy = require('./src/viceroy.js');
30+
const UpstreamServer = require('./src/upstream-server.js');
31+
const compareUpstreamRequest = require('./src/compare-upstream-request.js');
32+
const compareDownstreamResponse = require('./src/compare-downstream-response.js');
33+
34+
35+
// Get our config from the Github Action
36+
const configRelativePath = `${core.getInput("config")}`;
37+
console.info(`Parsing SDK Test config: ${configRelativePath}`);
38+
const configAbsolutePath = path.resolve(configRelativePath);
39+
const config = JSON.parse(fs.readFileSync(configAbsolutePath));
40+
console.info('Running the SDK Config:');
41+
console.log(`${JSON.stringify(config, null, 2)}`);
42+
43+
// Our main task, in which we compile and run tests
44+
const mainAsyncTask = async () => {
45+
// Iterate through our config and compile our wasm modules
46+
const modules = config.modules;
47+
const moduleKeys = Object.keys(modules);
48+
49+
moduleKeys.forEach(key => {
50+
const module = modules[key];
51+
console.info(`Compiling the fixture for: ${key} ...`);
52+
const moduleBuildStdout = childProcess.execSync(
53+
module.build,
54+
{
55+
stdio: 'inherit'
56+
}
57+
);
58+
});
59+
60+
console.info(`Running the Viceroy environment tests ...`);
61+
62+
// Define our viceroy here so we can kill it on errors
63+
let viceroy;
64+
65+
// Check if we are validating any local upstream requests (For example, like telemetry being sent)
66+
// If so, we will need an upstream server to compare the request that was sent
67+
let isDownstreamResponseHandled = false;
68+
let upstreamServer = new UpstreamServer();
69+
let upstreamServerTest;
70+
upstreamServer.listen(8081, async (localUpstreamRequestNumber, req, res) => {
71+
// Let's do the verifications on the request
72+
const configRequest = upstreamServerTest.local_upstream_requests[localUpstreamRequestNumber];
73+
74+
try {
75+
await compareUpstreamRequest(configRequest, req, isDownstreamResponseHandled);
76+
} catch (err) {
77+
await viceroy.kill();
78+
console.error(`[LocalUpstreamRequest (${localUpstreamRequestNumber})] ${err.message}`);
79+
process.exit(1);
80+
}
81+
});
82+
83+
// Iterate through the module tests, and run the Viceroy tests
84+
for (const moduleKey of moduleKeys) {
85+
const module = modules[moduleKey];
86+
const moduleTestKeys = Object.keys(module.tests);
87+
console.info(`Running tests for the module: ${moduleKey} ...`);
88+
89+
// Spawn a new viceroy instance for the module
90+
viceroy = new Viceroy();
91+
const viceroyAddr = '127.0.0.1:8080';
92+
await viceroy.spawn(module.wasm_path, {
93+
config: module.fastly_toml_path,
94+
addr: viceroyAddr
95+
})
96+
97+
98+
for (const testKey of moduleTestKeys) {
99+
const test = module.tests[testKey];
100+
101+
// Check if this module should be tested in viceroy
102+
if (!test.environments.includes("viceroy")) {
103+
continue;
104+
}
105+
106+
console.log(`Running the test ${testKey} ...`);
107+
108+
// Prepare our upstream server for this specific test
109+
isDownstreamResponseHandled = false;
110+
if (test.local_upstream_requests) {
111+
upstreamServerTest = test;
112+
upstreamServer.setExpectedNumberOfRequests(test.local_upstream_requests.length);
113+
} else {
114+
upstreamServerTest = null;
115+
upstreamServer.setExpectedNumberOfRequests(0);
116+
}
117+
118+
// Make the downstream request to the server (Viceroy)
119+
const downstreamRequest = test.downstream_request;
120+
let downstreamResponse;
121+
try {
122+
downstreamResponse = await fetch(`http://${viceroyAddr}${downstreamRequest.pathname || ''}`, {
123+
method: downstreamRequest.method || 'GET',
124+
headers: downstreamRequest.headers || undefined,
125+
body: downstreamRequest.body || undefined
126+
});
127+
} catch(error) {
128+
await upstreamServer.close();
129+
await viceroy.kill();
130+
console.error(error);
131+
process.exit(1);
132+
}
133+
134+
// Now that we have gotten our downstream response, we can flip our boolean
135+
// that our local_upstream_request will check
136+
isDownstreamResponseHandled = true;
137+
138+
// Check the Logs to see if they match expected logs in the config
139+
if (test.logs) {
140+
for (let i = 0; i < test.logs.length; i++) {
141+
let log = test.logs[i];
142+
143+
if (!viceroy.logs.includes(log)) {
144+
console.error(`[Logs: log not found] Expected: ${log}`);
145+
await upstreamServer.close();
146+
await viceroy.kill();
147+
process.exit(1);
148+
}
149+
}
150+
}
151+
152+
// Do our confirmations about the downstream response
153+
const configResponse = test.downstream_response;
154+
try {
155+
await compareDownstreamResponse(configResponse, downstreamResponse);
156+
} catch (err) {
157+
console.error(err.message);
158+
await upstreamServer.close();
159+
await viceroy.kill();
160+
process.exit(1);
161+
}
162+
163+
console.log(`The test ${testKey} Passed!`);
164+
165+
// Done! Kill the process, and go to the next test
166+
try {
167+
await upstreamServer.waitForExpectedNumberOfRequests();
168+
upstreamServerTest = null;
169+
upstreamServer.setExpectedNumberOfRequests(0);
170+
} catch(e) {
171+
console.error('Could not cleanup the upstream server. Error Below:');
172+
console.error(e);
173+
process.exit(1);
174+
}
175+
}
176+
177+
// Kill Viceroy and continue onto the next module
178+
try {
179+
await viceroy.kill();
180+
} catch(e) {
181+
console.error('Could not kill Viceory. Error Below:');
182+
console.error(e);
183+
process.exit(1);
184+
}
185+
};
186+
187+
// Viceroy is done! Close our upstream server and things
188+
await upstreamServer.close();
189+
190+
// Check if we have C@E Environement tests
191+
let shouldRunComputeTests = moduleKeys.some(moduleKey => {
192+
const module = modules[moduleKey];
193+
const moduleTestKeys = Object.keys(module.tests);
194+
195+
return moduleTestKeys.some(testKey => {
196+
197+
const test = module.tests[testKey];
198+
// Check if this module should be tested in viceroy
199+
if (test.environments.includes("c@e")) {
200+
return true;
201+
}
202+
return false;
203+
});
204+
});
205+
206+
if (!shouldRunComputeTests) {
207+
console.info('Viceroy environment tests are done, and no C@E environment tests!');
208+
console.info('We are finished, all tests passed! :)');
209+
return;
210+
}
211+
212+
console.warn('C@E tests are currently unsupported');
213+
};
214+
mainAsyncTask().then(() => {
215+
process.exit(0);
216+
}).catch((error) => {
217+
core.setFailed(error.message)
218+
process.exit(1);
219+
});
220+
221+

0 commit comments

Comments
 (0)