Skip to content

Commit a73bd4b

Browse files
author
Guy Bedford
committed
SimpleCache StarlingMonkey port (#767)
1 parent 841f1f2 commit a73bd4b

File tree

17 files changed

+1111
-73
lines changed

17 files changed

+1111
-73
lines changed

.github/workflows/starlingmonkey.yml

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ jobs:
3636
sdktest:
3737
if: github.ref != 'refs/heads/main'
3838
runs-on: ubuntu-latest
39+
strategy:
40+
matrix:
41+
platform: [viceroy, compute]
3942
needs: [build]
4043
steps:
4144
- name: Checkout fastly/js-compute-runtime
@@ -52,7 +55,9 @@ jobs:
5255
cli_version: ${{ env.fastly-cli_version }}
5356

5457
- name: Restore Viceroy from cache
58+
if: ${{ matrix.platform == 'viceroy' }}
5559
uses: actions/cache@v3
60+
id: viceroy
5661
with:
5762
path: "/home/runner/.cargo/bin/viceroy"
5863
key: crate-cache-viceroy-${{ env.viceroy_version }}
@@ -64,12 +69,9 @@ jobs:
6469
path: "/home/runner/.cargo/bin/wasm-tools"
6570
key: crate-cache-wasm-tools-${{ env.wasm-tools_version }}
6671

67-
- name: "Check wasm-tools has been restored"
68-
if: steps.wasm-tools.outputs.cache-hit != 'true'
69-
run: |
70-
echo "wasm-tools was not restored from the cache"
71-
echo "bailing out from the build early"
72-
exit 1
72+
- name: "Check caches have been restored"
73+
if: steps.wasm-tools.outputs.cache-hit != 'true' || matrix.platform == 'viceory' && steps.viceroy.outputs.cache-hit != 'true'
74+
run: echo "Unable to restore from the cache, bailing." && exit 1
7375

7476
- name: Download Engine
7577
uses: actions/download-artifact@v3
@@ -78,11 +80,8 @@ jobs:
7880
- run: yarn install --frozen-lockfile
7981

8082
- name: Yarn install
81-
run: |
82-
yarn
83-
cd ./integration-tests/js-compute
84-
yarn
83+
run: yarn && cd ./integration-tests/js-compute && yarn
8584

86-
- run: |
87-
cd ./integration-tests/js-compute
88-
FASTLY_API_TOKEN=${{ secrets.FASTLY_API_TOKEN }} ./test.js --starlingmonkey --local
85+
- run: node integration-tests/js-compute/test.js --starlingmonkey ${{ matrix.platform == 'viceroy' && '--local' || '' }}
86+
env:
87+
FASTLY_API_TOKEN: ${{ secrets.FASTLY_API_TOKEN }}

integration-tests/js-compute/fixtures/app/setup.js

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
#!/usr/bin/env node
22

33
import { $ as zx } from 'zx'
4+
import { argv } from 'node:process'
5+
6+
const serviceName = argv[2]
7+
const starlingmonkey = argv.slice(2).includes('--starlingmonkey');
48

59
const startTime = Date.now();
610

7-
zx.verbose = false;
811
if (process.env.FASTLY_API_TOKEN === undefined) {
12+
zx.verbose = false;
913
try {
1014
process.env.FASTLY_API_TOKEN = String(await zx`fastly profile token --quiet`).trim()
1115
} catch {
1216
console.error('No environment variable named FASTLY_API_TOKEN has been set and no default fastly profile exists.');
1317
console.error('In order to run the tests, either create a fastly profile using `fastly profile create` or export a fastly token under the name FASTLY_API_TOKEN');
1418
process.exit(1)
1519
}
20+
zx.verbose = true;
1621
}
1722

1823
async function setupConfigStores() {
@@ -31,7 +36,12 @@ async function setupConfigStores() {
3136
process.env.STORE_ID = STORE_ID;
3237
}
3338
await zx`echo -n 'https://twitter.com/fastly' | fastly config-store-entry update --upsert --key twitter --store-id=$STORE_ID --stdin --token $FASTLY_API_TOKEN`
34-
await zx`fastly resource-link create --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
39+
try {
40+
await zx`fastly resource-link create --service-name ${serviceName} --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
41+
} catch (e) {
42+
if (!e.message.includes('Duplicate record'))
43+
throw e;
44+
}
3545

3646
STORE_ID = stores.find(({ name }) => name === 'testconfig')?.id
3747
if (!STORE_ID) {
@@ -40,7 +50,12 @@ async function setupConfigStores() {
4050
process.env.STORE_ID = STORE_ID;
4151
}
4252
await zx`echo -n 'https://twitter.com/fastly' | fastly config-store-entry update --upsert --key twitter --store-id=$STORE_ID --stdin --token $FASTLY_API_TOKEN`
43-
await zx`fastly resource-link create --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
53+
try {
54+
await zx`fastly resource-link create --service-name ${serviceName} --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
55+
} catch (e) {
56+
if (!e.message.includes('Duplicate record'))
57+
throw e;
58+
}
4459
}
4560

4661
async function setupKVStore() {
@@ -52,13 +67,20 @@ async function setupKVStore() {
5267
}
5368
}())
5469

55-
const STORE_ID = stores.Data.find(({ Name }) => Name === 'example-test-kv-store')?.StoreID
70+
const existing = stores.Data.find(({ Name }) => Name === `example-test-kv-store${starlingmonkey ? '-sm' : ''}`);
71+
// For somereason the StarlingMonkey version of this contains "ID" instead of "StoreID"
72+
const STORE_ID = existing?.StoreID || existing?.ID;
5673
if (!STORE_ID) {
57-
process.env.STORE_ID = JSON.parse(await zx`fastly kv-store create --quiet --name='example-test-kv-store' --json --token $FASTLY_API_TOKEN`).id
74+
process.env.STORE_ID = JSON.parse(await zx`fastly kv-store create --quiet --name='example-test-kv-store${starlingmonkey ? '-sm' : ''}' --json --token $FASTLY_API_TOKEN`).id
5875
} else {
5976
process.env.STORE_ID = STORE_ID;
6077
}
61-
await zx`fastly resource-link create --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
78+
try {
79+
await zx`fastly resource-link create --service-name ${serviceName} --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
80+
} catch (e) {
81+
if (!e.message.includes('Duplicate record'))
82+
throw e;
83+
}
6284
}
6385

6486
async function setupSecretStore() {
@@ -78,13 +100,18 @@ async function setupSecretStore() {
78100
await zx`echo -n 'This is also some secret data' | fastly secret-store-entry create --recreate-allow --name first --store-id=$STORE_ID --stdin --token $FASTLY_API_TOKEN`
79101
let key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
80102
await zx`echo -n 'This is some secret data' | fastly secret-store-entry create --recreate-allow --name ${key} --store-id=$STORE_ID --stdin --token $FASTLY_API_TOKEN`
81-
await zx`fastly resource-link create --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
103+
try {
104+
await zx`fastly resource-link create --service-name ${serviceName} --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
105+
} catch (e) {
106+
if (!e.message.includes('Duplicate record'))
107+
throw e;
108+
}
82109
}
83110

84111
await setupConfigStores()
85112
await setupKVStore()
86113
await setupSecretStore()
87114

88-
await zx`fastly service-version activate --version latest --token $FASTLY_API_TOKEN`
115+
await zx`fastly service-version activate --service-name ${serviceName} --version latest --token $FASTLY_API_TOKEN`
89116

90117
console.log(`Set up has finished! Took ${(Date.now() - startTime) / 1000} seconds to complete`);

integration-tests/js-compute/fixtures/app/src/cache-simple.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@
22
/* eslint-env serviceworker */
33

44
import { pass, assert, assertDoesNotThrow, assertThrows, assertRejects, iteratableToStream, streamToString, assertResolves } from "./assertions.js";
5-
import { SimpleCache } from 'fastly:cache';
6-
import * as fastlyCache from 'fastly:cache';
5+
import { SimpleCache, SimpleCacheEntry } from 'fastly:cache';
76
import { routes, isRunningLocally } from "./routes.js";
87

9-
const { SimpleCacheEntry } = fastlyCache;
10-
118
let error;
129
routes.set("/simple-cache/interface", () => {
1310
let actual = Reflect.ownKeys(SimpleCache)
@@ -255,7 +252,7 @@ routes.set("/simple-cache/interface", () => {
255252
if (!isRunningLocally()) {
256253
error = assertThrows(() => {
257254
new SimpleCache.purge('1', { scope: "global" })
258-
}, TypeError, `SimpleCache.purge is not a constructor`)
255+
}, TypeError)
259256
if (error) { return error }
260257
}
261258
return pass()
@@ -373,7 +370,7 @@ routes.set("/simple-cache/interface", () => {
373370
if (!isRunningLocally()) {
374371
error = assertThrows(() => {
375372
new SimpleCache.set('1', 'meow', 1)
376-
}, TypeError, `SimpleCache.set is not a constructor`)
373+
}, TypeError)
377374
if (error) { return error }
378375
}
379376
return pass()
@@ -818,7 +815,7 @@ routes.set("/simple-cache/interface", () => {
818815
if (!isRunningLocally()) {
819816
let error = assertThrows(() => {
820817
new SimpleCache.get('1')
821-
}, TypeError, `SimpleCache.get is not a constructor`)
818+
}, TypeError)
822819
if (error) { return error }
823820
}
824821
return pass()
@@ -1188,7 +1185,7 @@ async function simpleCacheEntryInterfaceTests() {
11881185
ttl: 10
11891186
}
11901187
});
1191-
}, TypeError, `SimpleCache.getOrSet is not a constructor`)
1188+
}, TypeError)
11921189
if (error) { return error }
11931190
}
11941191
return pass()

integration-tests/js-compute/fixtures/app/src/kv-store.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
/* globals KVStoreEntry */
22
import { pass, assert, assertThrows, assertRejects, assertResolves } from "./assertions.js";
33
import { KVStore } from "fastly:kv-store";
4+
import { sdkVersion } from "fastly:experimental";
45
import { routes, isRunningLocally } from "./routes.js";
56

7+
const starlingmonkey = sdkVersion.includes('starlingmonkey');
8+
69
// KVStore
710
{
811
routes.set("/kv-store/exposed-as-global", async () => {
@@ -1286,7 +1289,7 @@ async function kvStoreInterfaceTests() {
12861289
}
12871290

12881291
function createValidStore() {
1289-
return new KVStore('example-test-kv-store')
1292+
return new KVStore(`example-test-kv-store${starlingmonkey ? '-sm' : ''}`)
12901293
}
12911294

12921295
function iteratableToStream(iterable) {

integration-tests/js-compute/fixtures/app/tests-starlingmonkey.json

Lines changed: 84 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,90 @@
88
"GET /cache-override/constructor/invalid-mode",
99
"GET /cache-override/constructor/valid-mode",
1010
"GET /cache-override/fetch/mode-none",
11-
"GET /cache-override/fetch/mode-pass",
12-
"GET /client/tlsJA3MD5",
13-
"GET /client/tlsClientHello",
14-
"GET /client/tlsClientCertificate",
15-
"GET /client/tlsCipherOpensslName",
16-
"GET /client/tlsProtocol",
11+
"GET /simple-cache/interface",
12+
"GET /simple-store/constructor/called-as-regular-function",
13+
"GET /simple-cache/constructor/throws",
14+
"GET /simple-cache/purge/called-as-constructor",
15+
"GET /simple-cache/purge/key-parameter-calls-7.1.17-ToString",
16+
"GET /simple-cache/purge/key-parameter-not-supplied",
17+
"GET /simple-cache/purge/key-parameter-empty-string",
18+
"GET /simple-cache/purge/key-parameter-8135-character-string",
19+
"GET /simple-cache/purge/key-parameter-8136-character-string",
20+
"GET /simple-cache/purge/options-parameter",
21+
"GET /simple-cache/purge/returns-undefined",
22+
"GET /simple-cache/set/called-as-constructor",
23+
"GET /simple-cache/set/key-parameter-calls-7.1.17-ToString",
24+
"GET /simple-cache/set/tll-parameter-7.1.4-ToNumber",
25+
"GET /simple-cache/set/no-parameters-supplied",
26+
"GET /simple-cache/set/key-parameter-empty-string",
27+
"GET /simple-cache/set/key-parameter-8135-character-string",
28+
"GET /simple-cache/set/key-parameter-8136-character-string",
29+
"GET /simple-cache/set/ttl-parameter-negative-number",
30+
"GET /simple-cache/set/ttl-parameter-NaN",
31+
"GET /simple-cache/set/ttl-parameter-Infinity",
32+
"GET /simple-cache/set/value-parameter-as-undefined",
33+
"GET /simple-cache/set/value-parameter-readablestream-missing-length-parameter",
34+
"GET /simple-cache/set/value-parameter-readablestream-negative-length-parameter",
35+
"GET /simple-cache/set/value-parameter-readablestream-nan-length-parameter",
36+
"GET /simple-cache/set/value-parameter-readablestream-negative-infinity-length-parameter",
37+
"GET /simple-cache/set/value-parameter-readablestream-positive-infinity-length-parameter",
38+
"GET /simple-cache/set/length-parameter-7.1.4-ToNumber",
39+
"GET /simple-cache/set/value-parameter-readablestream-empty",
40+
"GET /simple-cache/set/value-parameter-readablestream-locked",
41+
"GET /simple-cache/set/value-parameter-readablestream",
42+
"GET /simple-cache/set/value-parameter-URLSearchParams",
43+
"GET /simple-cache/set/value-parameter-strings",
44+
"GET /simple-cache/set/value-parameter-calls-7.1.17-ToString",
45+
"GET /simple-cache/set/value-parameter-buffer",
46+
"GET /simple-cache/set/value-parameter-arraybuffer",
47+
"GET /simple-cache/set/value-parameter-typed-arrays",
48+
"GET /simple-cache/set/value-parameter-dataview",
49+
"GET /simple-cache/set/returns-undefined",
50+
"GET /simple-cache/get/called-as-constructor",
51+
"GET /simple-cache/get/key-parameter-calls-7.1.17-ToString",
52+
"GET /simple-cache/get/key-parameter-not-supplied",
53+
"GET /simple-cache/get/key-parameter-empty-string",
54+
"GET /simple-cache/get/key-parameter-8135-character-string",
55+
"GET /simple-cache/get/key-parameter-8136-character-string",
56+
"GET /simple-cache/get/key-does-not-exist-returns-null",
57+
"GET /simple-cache/get/key-exists",
58+
"GET /simple-cache-entry/interface",
59+
"GET /simple-cache-entry/text/valid",
60+
"GET /simple-cache-entry/json/valid",
61+
"GET /simple-cache-entry/json/invalid",
62+
"GET /simple-cache-entry/arrayBuffer/valid",
63+
"GET /simple-cache-entry/bodyUsed",
64+
"GET /simple-cache-entry/readablestream",
65+
"GET /simple-cache/getOrSet/called-as-constructor",
66+
"GET /simple-cache/getOrSet/no-parameters-supplied",
67+
"GET /simple-cache/getOrSet/key-parameter-calls-7.1.17-ToString",
68+
"GET /simple-cache/getOrSet/key-parameter-empty-string",
69+
"GET /simple-cache/getOrSet/key-parameter-8135-character-string",
70+
"GET /simple-cache/getOrSet/key-parameter-8136-character-string",
71+
"GET /simple-cache/getOrSet/ttl-field-7.1.4-ToNumber",
72+
"GET /simple-cache/getOrSet/ttl-field-negative-number",
73+
"GET /simple-cache/getOrSet/ttl-field-NaN",
74+
"GET /simple-cache/getOrSet/ttl-field-Infinity",
75+
"GET /simple-cache/getOrSet/value-field-as-undefined",
76+
"GET /simple-cache/getOrSet/value-field-readablestream-missing-length-field",
77+
"GET /simple-cache/getOrSet/value-field-readablestream-negative-length-field",
78+
"GET /simple-cache/getOrSet/value-field-readablestream-nan-length-field",
79+
"GET /simple-cache/getOrSet/value-field-readablestream-negative-infinity-length-field",
80+
"GET /simple-cache/getOrSet/value-field-readablestream-positive-infinity-length-field",
81+
"GET /simple-cache/getOrSet/length-field-7.1.4-ToNumber",
82+
"GET /simple-cache/getOrSet/value-field-readablestream-empty",
83+
"GET /simple-cache/getOrSet/value-field-readablestream-locked",
84+
"GET /simple-cache/getOrSet/value-field-readablestream",
85+
"GET /simple-cache/getOrSet/value-field-URLSearchParams",
86+
"GET /simple-cache/getOrSet/value-field-strings",
87+
"GET /simple-cache/getOrSet/value-field-calls-7.1.17-ToString",
88+
"GET /simple-cache/getOrSet/value-field-buffer",
89+
"GET /simple-cache/getOrSet/value-field-typed-arrays",
90+
"GET /simple-cache/getOrSet/value-field-dataview",
91+
"GET /simple-cache/getOrSet/returns-SimpleCacheEntry",
92+
"GET /simple-cache/getOrSet/executes-the-set-method-when-key-not-in-cache",
93+
"GET /simple-cache/getOrSet/does-not-execute-the-set-method-when-key-is-in-cache",
94+
"GET /simple-cache/getOrSet/does-not-freeze-when-called-after-a-get",
1795
"GET /console",
1896
"GET /crypto",
1997
"GET /crypto.subtle",
@@ -235,8 +313,6 @@
235313
"GET /error",
236314
"GET /override-content-length/request/init/object-literal/true",
237315
"GET /override-content-length/request/init/object-literal/false",
238-
"GET /override-content-length/request/clone/true",
239-
"GET /override-content-length/request/clone/false",
240316
"GET /override-content-length/fetch/init/object-literal/true",
241317
"GET /override-content-length/fetch/init/object-literal/false",
242318
"GET /override-content-length/response/init/object-literal/true",

integration-tests/js-compute/fixtures/app/tests.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@
588588
}
589589
},
590590
"GET /simple-cache-entry/interface": {
591-
"environments": ["compute"],
591+
"environments": ["compute", "viceroy"],
592592
"downstream_request": {
593593
"method": "GET",
594594
"pathname": "/simple-cache-entry/interface"

integration-tests/js-compute/test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ zx.verbose = true;
5858
const branchName = (await zx`git branch --show-current`).stdout.trim().replace(/[^a-zA-Z0-9_-]/g, '_')
5959

6060
const fixture = 'app';
61-
const serviceName = `${fixture}--${branchName}`
61+
const serviceName = `${fixture}--${branchName}${starlingmonkey ? '--sm' : ''}`
6262
let domain;
6363
const fixturePath = join(__dirname, 'fixtures', fixture)
6464
let localServer;
@@ -91,7 +91,7 @@ if (!local) {
9191
const setupPath = join(fixturePath, 'setup.js')
9292
if (existsSync(setupPath)) {
9393
core.startGroup('Extra set-up steps for the service')
94-
await zx`${setupPath}${starlingmonkey ? ' --starlingmonkey' : ''}`
94+
await zx`node ${setupPath} ${serviceName} ${starlingmonkey ? '--starlingmonkey' : ''}`
9595
await sleep(60)
9696
core.endGroup()
9797
}

runtime/fastly/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ cmake_minimum_required(VERSION 3.27)
33
include("../StarlingMonkey/cmake/add_as_subproject.cmake")
44

55
add_builtin(fastly::runtime SRC handler.cpp host-api/component/fastly_world_adapter.cpp)
6+
add_builtin(fastly::cache_simple SRC builtins/cache-simple.cpp DEPENDENCIES OpenSSL)
67
add_builtin(fastly::fastly SRC builtins/fastly.cpp)
78
add_builtin(fastly::backend SRC builtins/backend.cpp)
89
add_builtin(fastly::fetch SRC builtins/fetch/fetch.cpp builtins/fetch/request-response.cpp builtins/fetch/headers.cpp)
910
add_builtin(fastly::cache_override SRC builtins/cache-override.cpp)
1011
add_builtin(fastly::fetch_event SRC builtins/fetch-event.cpp)
11-
add_builtin(fastly::cache_simple SRC builtins/cache-simple.cpp DEPENDENCIES OpenSSL)
1212

1313
project(FastlyJS)

runtime/fastly/builtins/cache-override.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifndef JS_COMPUTE_RUNTIME_CACHE_OVERRIDE_H
2-
#define JS_COMPUTE_RUNTIME_CACHE_OVERRIDE_H
1+
#ifndef FASTLY_CACHE_OVERRIDE_H
2+
#define FASTLY_CACHE_OVERRIDE_H
33

44
#include "../host-api/host_api_fastly.h"
55
#include "builtin.h"

0 commit comments

Comments
 (0)