Skip to content

Commit

Permalink
SimpleCache StarlingMonkey port (#767)
Browse files Browse the repository at this point in the history
  • Loading branch information
guybedford committed May 10, 2024
1 parent 841f1f2 commit a73bd4b
Show file tree
Hide file tree
Showing 17 changed files with 1,111 additions and 73 deletions.
25 changes: 12 additions & 13 deletions .github/workflows/starlingmonkey.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ jobs:
sdktest:
if: github.ref != 'refs/heads/main'
runs-on: ubuntu-latest
strategy:
matrix:
platform: [viceroy, compute]
needs: [build]
steps:
- name: Checkout fastly/js-compute-runtime
Expand All @@ -52,7 +55,9 @@ jobs:
cli_version: ${{ env.fastly-cli_version }}

- name: Restore Viceroy from cache
if: ${{ matrix.platform == 'viceroy' }}
uses: actions/cache@v3
id: viceroy
with:
path: "/home/runner/.cargo/bin/viceroy"
key: crate-cache-viceroy-${{ env.viceroy_version }}
Expand All @@ -64,12 +69,9 @@ jobs:
path: "/home/runner/.cargo/bin/wasm-tools"
key: crate-cache-wasm-tools-${{ env.wasm-tools_version }}

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

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

- name: Yarn install
run: |
yarn
cd ./integration-tests/js-compute
yarn
run: yarn && cd ./integration-tests/js-compute && yarn

- run: |
cd ./integration-tests/js-compute
FASTLY_API_TOKEN=${{ secrets.FASTLY_API_TOKEN }} ./test.js --starlingmonkey --local
- run: node integration-tests/js-compute/test.js --starlingmonkey ${{ matrix.platform == 'viceroy' && '--local' || '' }}
env:
FASTLY_API_TOKEN: ${{ secrets.FASTLY_API_TOKEN }}
43 changes: 35 additions & 8 deletions integration-tests/js-compute/fixtures/app/setup.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
#!/usr/bin/env node

import { $ as zx } from 'zx'
import { argv } from 'node:process'

const serviceName = argv[2]
const starlingmonkey = argv.slice(2).includes('--starlingmonkey');

const startTime = Date.now();

zx.verbose = false;
if (process.env.FASTLY_API_TOKEN === undefined) {
zx.verbose = false;
try {
process.env.FASTLY_API_TOKEN = String(await zx`fastly profile token --quiet`).trim()
} catch {
console.error('No environment variable named FASTLY_API_TOKEN has been set and no default fastly profile exists.');
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');
process.exit(1)
}
zx.verbose = true;
}

async function setupConfigStores() {
Expand All @@ -31,7 +36,12 @@ async function setupConfigStores() {
process.env.STORE_ID = STORE_ID;
}
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`
await zx`fastly resource-link create --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
try {
await zx`fastly resource-link create --service-name ${serviceName} --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
} catch (e) {
if (!e.message.includes('Duplicate record'))
throw e;
}

STORE_ID = stores.find(({ name }) => name === 'testconfig')?.id
if (!STORE_ID) {
Expand All @@ -40,7 +50,12 @@ async function setupConfigStores() {
process.env.STORE_ID = STORE_ID;
}
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`
await zx`fastly resource-link create --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
try {
await zx`fastly resource-link create --service-name ${serviceName} --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
} catch (e) {
if (!e.message.includes('Duplicate record'))
throw e;
}
}

async function setupKVStore() {
Expand All @@ -52,13 +67,20 @@ async function setupKVStore() {
}
}())

const STORE_ID = stores.Data.find(({ Name }) => Name === 'example-test-kv-store')?.StoreID
const existing = stores.Data.find(({ Name }) => Name === `example-test-kv-store${starlingmonkey ? '-sm' : ''}`);
// For somereason the StarlingMonkey version of this contains "ID" instead of "StoreID"
const STORE_ID = existing?.StoreID || existing?.ID;
if (!STORE_ID) {
process.env.STORE_ID = JSON.parse(await zx`fastly kv-store create --quiet --name='example-test-kv-store' --json --token $FASTLY_API_TOKEN`).id
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
} else {
process.env.STORE_ID = STORE_ID;
}
await zx`fastly resource-link create --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
try {
await zx`fastly resource-link create --service-name ${serviceName} --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
} catch (e) {
if (!e.message.includes('Duplicate record'))
throw e;
}
}

async function setupSecretStore() {
Expand All @@ -78,13 +100,18 @@ async function setupSecretStore() {
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`
let key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
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`
await zx`fastly resource-link create --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
try {
await zx`fastly resource-link create --service-name ${serviceName} --version latest --resource-id $STORE_ID --token $FASTLY_API_TOKEN --autoclone`
} catch (e) {
if (!e.message.includes('Duplicate record'))
throw e;
}
}

await setupConfigStores()
await setupKVStore()
await setupSecretStore()

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

console.log(`Set up has finished! Took ${(Date.now() - startTime) / 1000} seconds to complete`);
13 changes: 5 additions & 8 deletions integration-tests/js-compute/fixtures/app/src/cache-simple.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@
/* eslint-env serviceworker */

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

const { SimpleCacheEntry } = fastlyCache;

let error;
routes.set("/simple-cache/interface", () => {
let actual = Reflect.ownKeys(SimpleCache)
Expand Down Expand Up @@ -255,7 +252,7 @@ routes.set("/simple-cache/interface", () => {
if (!isRunningLocally()) {
error = assertThrows(() => {
new SimpleCache.purge('1', { scope: "global" })
}, TypeError, `SimpleCache.purge is not a constructor`)
}, TypeError)
if (error) { return error }
}
return pass()
Expand Down Expand Up @@ -373,7 +370,7 @@ routes.set("/simple-cache/interface", () => {
if (!isRunningLocally()) {
error = assertThrows(() => {
new SimpleCache.set('1', 'meow', 1)
}, TypeError, `SimpleCache.set is not a constructor`)
}, TypeError)
if (error) { return error }
}
return pass()
Expand Down Expand Up @@ -818,7 +815,7 @@ routes.set("/simple-cache/interface", () => {
if (!isRunningLocally()) {
let error = assertThrows(() => {
new SimpleCache.get('1')
}, TypeError, `SimpleCache.get is not a constructor`)
}, TypeError)
if (error) { return error }
}
return pass()
Expand Down Expand Up @@ -1188,7 +1185,7 @@ async function simpleCacheEntryInterfaceTests() {
ttl: 10
}
});
}, TypeError, `SimpleCache.getOrSet is not a constructor`)
}, TypeError)
if (error) { return error }
}
return pass()
Expand Down
5 changes: 4 additions & 1 deletion integration-tests/js-compute/fixtures/app/src/kv-store.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
/* globals KVStoreEntry */
import { pass, assert, assertThrows, assertRejects, assertResolves } from "./assertions.js";
import { KVStore } from "fastly:kv-store";
import { sdkVersion } from "fastly:experimental";
import { routes, isRunningLocally } from "./routes.js";

const starlingmonkey = sdkVersion.includes('starlingmonkey');

// KVStore
{
routes.set("/kv-store/exposed-as-global", async () => {
Expand Down Expand Up @@ -1286,7 +1289,7 @@ async function kvStoreInterfaceTests() {
}

function createValidStore() {
return new KVStore('example-test-kv-store')
return new KVStore(`example-test-kv-store${starlingmonkey ? '-sm' : ''}`)
}

function iteratableToStream(iterable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,90 @@
"GET /cache-override/constructor/invalid-mode",
"GET /cache-override/constructor/valid-mode",
"GET /cache-override/fetch/mode-none",
"GET /cache-override/fetch/mode-pass",
"GET /client/tlsJA3MD5",
"GET /client/tlsClientHello",
"GET /client/tlsClientCertificate",
"GET /client/tlsCipherOpensslName",
"GET /client/tlsProtocol",
"GET /simple-cache/interface",
"GET /simple-store/constructor/called-as-regular-function",
"GET /simple-cache/constructor/throws",
"GET /simple-cache/purge/called-as-constructor",
"GET /simple-cache/purge/key-parameter-calls-7.1.17-ToString",
"GET /simple-cache/purge/key-parameter-not-supplied",
"GET /simple-cache/purge/key-parameter-empty-string",
"GET /simple-cache/purge/key-parameter-8135-character-string",
"GET /simple-cache/purge/key-parameter-8136-character-string",
"GET /simple-cache/purge/options-parameter",
"GET /simple-cache/purge/returns-undefined",
"GET /simple-cache/set/called-as-constructor",
"GET /simple-cache/set/key-parameter-calls-7.1.17-ToString",
"GET /simple-cache/set/tll-parameter-7.1.4-ToNumber",
"GET /simple-cache/set/no-parameters-supplied",
"GET /simple-cache/set/key-parameter-empty-string",
"GET /simple-cache/set/key-parameter-8135-character-string",
"GET /simple-cache/set/key-parameter-8136-character-string",
"GET /simple-cache/set/ttl-parameter-negative-number",
"GET /simple-cache/set/ttl-parameter-NaN",
"GET /simple-cache/set/ttl-parameter-Infinity",
"GET /simple-cache/set/value-parameter-as-undefined",
"GET /simple-cache/set/value-parameter-readablestream-missing-length-parameter",
"GET /simple-cache/set/value-parameter-readablestream-negative-length-parameter",
"GET /simple-cache/set/value-parameter-readablestream-nan-length-parameter",
"GET /simple-cache/set/value-parameter-readablestream-negative-infinity-length-parameter",
"GET /simple-cache/set/value-parameter-readablestream-positive-infinity-length-parameter",
"GET /simple-cache/set/length-parameter-7.1.4-ToNumber",
"GET /simple-cache/set/value-parameter-readablestream-empty",
"GET /simple-cache/set/value-parameter-readablestream-locked",
"GET /simple-cache/set/value-parameter-readablestream",
"GET /simple-cache/set/value-parameter-URLSearchParams",
"GET /simple-cache/set/value-parameter-strings",
"GET /simple-cache/set/value-parameter-calls-7.1.17-ToString",
"GET /simple-cache/set/value-parameter-buffer",
"GET /simple-cache/set/value-parameter-arraybuffer",
"GET /simple-cache/set/value-parameter-typed-arrays",
"GET /simple-cache/set/value-parameter-dataview",
"GET /simple-cache/set/returns-undefined",
"GET /simple-cache/get/called-as-constructor",
"GET /simple-cache/get/key-parameter-calls-7.1.17-ToString",
"GET /simple-cache/get/key-parameter-not-supplied",
"GET /simple-cache/get/key-parameter-empty-string",
"GET /simple-cache/get/key-parameter-8135-character-string",
"GET /simple-cache/get/key-parameter-8136-character-string",
"GET /simple-cache/get/key-does-not-exist-returns-null",
"GET /simple-cache/get/key-exists",
"GET /simple-cache-entry/interface",
"GET /simple-cache-entry/text/valid",
"GET /simple-cache-entry/json/valid",
"GET /simple-cache-entry/json/invalid",
"GET /simple-cache-entry/arrayBuffer/valid",
"GET /simple-cache-entry/bodyUsed",
"GET /simple-cache-entry/readablestream",
"GET /simple-cache/getOrSet/called-as-constructor",
"GET /simple-cache/getOrSet/no-parameters-supplied",
"GET /simple-cache/getOrSet/key-parameter-calls-7.1.17-ToString",
"GET /simple-cache/getOrSet/key-parameter-empty-string",
"GET /simple-cache/getOrSet/key-parameter-8135-character-string",
"GET /simple-cache/getOrSet/key-parameter-8136-character-string",
"GET /simple-cache/getOrSet/ttl-field-7.1.4-ToNumber",
"GET /simple-cache/getOrSet/ttl-field-negative-number",
"GET /simple-cache/getOrSet/ttl-field-NaN",
"GET /simple-cache/getOrSet/ttl-field-Infinity",
"GET /simple-cache/getOrSet/value-field-as-undefined",
"GET /simple-cache/getOrSet/value-field-readablestream-missing-length-field",
"GET /simple-cache/getOrSet/value-field-readablestream-negative-length-field",
"GET /simple-cache/getOrSet/value-field-readablestream-nan-length-field",
"GET /simple-cache/getOrSet/value-field-readablestream-negative-infinity-length-field",
"GET /simple-cache/getOrSet/value-field-readablestream-positive-infinity-length-field",
"GET /simple-cache/getOrSet/length-field-7.1.4-ToNumber",
"GET /simple-cache/getOrSet/value-field-readablestream-empty",
"GET /simple-cache/getOrSet/value-field-readablestream-locked",
"GET /simple-cache/getOrSet/value-field-readablestream",
"GET /simple-cache/getOrSet/value-field-URLSearchParams",
"GET /simple-cache/getOrSet/value-field-strings",
"GET /simple-cache/getOrSet/value-field-calls-7.1.17-ToString",
"GET /simple-cache/getOrSet/value-field-buffer",
"GET /simple-cache/getOrSet/value-field-typed-arrays",
"GET /simple-cache/getOrSet/value-field-dataview",
"GET /simple-cache/getOrSet/returns-SimpleCacheEntry",
"GET /simple-cache/getOrSet/executes-the-set-method-when-key-not-in-cache",
"GET /simple-cache/getOrSet/does-not-execute-the-set-method-when-key-is-in-cache",
"GET /simple-cache/getOrSet/does-not-freeze-when-called-after-a-get",
"GET /console",
"GET /crypto",
"GET /crypto.subtle",
Expand Down Expand Up @@ -235,8 +313,6 @@
"GET /error",
"GET /override-content-length/request/init/object-literal/true",
"GET /override-content-length/request/init/object-literal/false",
"GET /override-content-length/request/clone/true",
"GET /override-content-length/request/clone/false",
"GET /override-content-length/fetch/init/object-literal/true",
"GET /override-content-length/fetch/init/object-literal/false",
"GET /override-content-length/response/init/object-literal/true",
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/js-compute/fixtures/app/tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@
}
},
"GET /simple-cache-entry/interface": {
"environments": ["compute"],
"environments": ["compute", "viceroy"],
"downstream_request": {
"method": "GET",
"pathname": "/simple-cache-entry/interface"
Expand Down
4 changes: 2 additions & 2 deletions integration-tests/js-compute/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ zx.verbose = true;
const branchName = (await zx`git branch --show-current`).stdout.trim().replace(/[^a-zA-Z0-9_-]/g, '_')

const fixture = 'app';
const serviceName = `${fixture}--${branchName}`
const serviceName = `${fixture}--${branchName}${starlingmonkey ? '--sm' : ''}`
let domain;
const fixturePath = join(__dirname, 'fixtures', fixture)
let localServer;
Expand Down Expand Up @@ -91,7 +91,7 @@ if (!local) {
const setupPath = join(fixturePath, 'setup.js')
if (existsSync(setupPath)) {
core.startGroup('Extra set-up steps for the service')
await zx`${setupPath}${starlingmonkey ? ' --starlingmonkey' : ''}`
await zx`node ${setupPath} ${serviceName} ${starlingmonkey ? '--starlingmonkey' : ''}`
await sleep(60)
core.endGroup()
}
Expand Down
2 changes: 1 addition & 1 deletion runtime/fastly/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ cmake_minimum_required(VERSION 3.27)
include("../StarlingMonkey/cmake/add_as_subproject.cmake")

add_builtin(fastly::runtime SRC handler.cpp host-api/component/fastly_world_adapter.cpp)
add_builtin(fastly::cache_simple SRC builtins/cache-simple.cpp DEPENDENCIES OpenSSL)
add_builtin(fastly::fastly SRC builtins/fastly.cpp)
add_builtin(fastly::backend SRC builtins/backend.cpp)
add_builtin(fastly::fetch SRC builtins/fetch/fetch.cpp builtins/fetch/request-response.cpp builtins/fetch/headers.cpp)
add_builtin(fastly::cache_override SRC builtins/cache-override.cpp)
add_builtin(fastly::fetch_event SRC builtins/fetch-event.cpp)
add_builtin(fastly::cache_simple SRC builtins/cache-simple.cpp DEPENDENCIES OpenSSL)

project(FastlyJS)
4 changes: 2 additions & 2 deletions runtime/fastly/builtins/cache-override.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef JS_COMPUTE_RUNTIME_CACHE_OVERRIDE_H
#define JS_COMPUTE_RUNTIME_CACHE_OVERRIDE_H
#ifndef FASTLY_CACHE_OVERRIDE_H
#define FASTLY_CACHE_OVERRIDE_H

#include "../host-api/host_api_fastly.h"
#include "builtin.h"
Expand Down
Loading

0 comments on commit a73bd4b

Please sign in to comment.