Skip to content

Simple cache StarlingMonkey port #772

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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/StarlingMonkey
1 change: 1 addition & 0 deletions runtime/fastly/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ 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)
Expand Down
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
Loading