From 0f6200f81dfd1a2817a6cb6e97def292e2b0db2c Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 9 Jul 2021 13:42:48 +0100 Subject: [PATCH] Add initial Wasm test harness --- .github/workflows/wasm.yml | 40 +++++++++++++++++++++++ .gitignore | 7 ++++ build-dendritejs.sh | 2 +- build.sh | 2 +- cmd/dendritejs-pinecone/main.go | 10 ++++-- cmd/dendritejs-pinecone/main_test.go | 25 +++++++++++++++ docs/p2p.md | 15 +++++++-- test-dendritejs.sh | 3 ++ test/wasm/index.js | 48 ++++++++++++++++++++++++++++ test/wasm/package-lock.json | 25 +++++++++++++++ test/wasm/package.json | 5 +++ 11 files changed, 174 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/wasm.yml create mode 100644 cmd/dendritejs-pinecone/main_test.go create mode 100755 test-dendritejs.sh create mode 100755 test/wasm/index.js create mode 100644 test/wasm/package-lock.json create mode 100644 test/wasm/package.json diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml new file mode 100644 index 000000000..cf10cf176 --- /dev/null +++ b/.github/workflows/wasm.yml @@ -0,0 +1,40 @@ +name: WebAssembly + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: 1.16.5 + + - uses: actions/cache@v2 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Install Node + uses: actions/setup-node@v2 + with: + node-version: 14 + cache: npm + + - name: Install test dependencies + working-directory: ./test/wasm + run: npm install + + - name: Test + run: ./test-dendritejs.sh diff --git a/.gitignore b/.gitignore index c5bf92ccb..6a13ed376 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ # Hidden files .* +# Allow GitHub config +!.github + # Downloads /.downloads @@ -36,6 +39,7 @@ _testmain.go *.exe *.test *.prof +*.wasm # Generated keys *.pem @@ -53,3 +57,6 @@ dendrite.yaml # Generated code cmd/dendrite-demo-yggdrasil/embed/fs*.go + +# Test dependencies +test/wasm/node_modules diff --git a/build-dendritejs.sh b/build-dendritejs.sh index 83ec3699c..2ffe41a8b 100755 --- a/build-dendritejs.sh +++ b/build-dendritejs.sh @@ -1,4 +1,4 @@ #!/bin/sh -eu export GIT_COMMIT=$(git rev-list -1 HEAD) && \ -GOOS=js GOARCH=wasm go build -ldflags "-X main.GitCommit=$GIT_COMMIT" -o main.wasm ./cmd/dendritejs +GOOS=js GOARCH=wasm go build -ldflags "-X main.GitCommit=$GIT_COMMIT" -o ./bin/main.wasm ./cmd/dendritejs-pinecone diff --git a/build.sh b/build.sh index a49814084..8196fc653 100755 --- a/build.sh +++ b/build.sh @@ -21,4 +21,4 @@ mkdir -p bin CGO_ENABLED=1 go build -trimpath -ldflags "$FLAGS" -v -o "bin/" ./cmd/... -CGO_ENABLED=0 GOOS=js GOARCH=wasm go build -trimpath -ldflags "$FLAGS" -o bin/main.wasm ./cmd/dendritejs +CGO_ENABLED=0 GOOS=js GOARCH=wasm go build -trimpath -ldflags "$FLAGS" -o bin/main.wasm ./cmd/dendritejs-pinecone diff --git a/cmd/dendritejs-pinecone/main.go b/cmd/dendritejs-pinecone/main.go index 433e9bf82..00de481c8 100644 --- a/cmd/dendritejs-pinecone/main.go +++ b/cmd/dendritejs-pinecone/main.go @@ -144,6 +144,13 @@ func generateKey() ed25519.PrivateKey { } func main() { + startup() + + // We want to block forever to let the fetch and libp2p handler serve the APIs + select {} +} + +func startup() { sk := generateKey() pk := sk.Public().(ed25519.PublicKey) @@ -250,7 +257,4 @@ func main() { } } }() - - // We want to block forever to let the fetch and libp2p handler serve the APIs - select {} } diff --git a/cmd/dendritejs-pinecone/main_test.go b/cmd/dendritejs-pinecone/main_test.go new file mode 100644 index 000000000..751700cb2 --- /dev/null +++ b/cmd/dendritejs-pinecone/main_test.go @@ -0,0 +1,25 @@ +// Copyright 2021 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build wasm + +package main + +import ( + "testing" +) + +func TestStartup(t *testing.T) { + startup() +} diff --git a/docs/p2p.md b/docs/p2p.md index d69b47bea..e858ba114 100644 --- a/docs/p2p.md +++ b/docs/p2p.md @@ -2,14 +2,23 @@ These are the instructions for setting up P2P Dendrite, current as of May 2020. There's both Go stuff and JS stuff to do to set this up. - ### Dendrite +#### Build + - The `master` branch has a WASM-only binary for dendrite: `./cmd/dendritejs`. - Build it and copy assets to riot-web. ``` -$ GOOS=js GOARCH=wasm go build -o main.wasm ./cmd/dendritejs -$ cp main.wasm ../riot-web/src/vector/dendrite.wasm +$ ./build-dendritejs.sh +$ cp bin/main.wasm ../riot-web/src/vector/dendrite.wasm +``` + +#### Test + +To check that the Dendrite side is working well as Wasm, you can run the +Wasm-specific tests: +``` +$ ./test-dendritejs.sh ``` ### Rendezvous diff --git a/test-dendritejs.sh b/test-dendritejs.sh new file mode 100755 index 000000000..73e3d7354 --- /dev/null +++ b/test-dendritejs.sh @@ -0,0 +1,3 @@ +#!/bin/sh -eu + +GOOS=js GOARCH=wasm go test -v -exec "$(pwd)/test/wasm/index.js" ./cmd/dendritejs-pinecone diff --git a/test/wasm/index.js b/test/wasm/index.js new file mode 100755 index 000000000..29d86839d --- /dev/null +++ b/test/wasm/index.js @@ -0,0 +1,48 @@ +#!/usr/bin/env node + +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +const fs = require('fs'); +const path = require('path'); +const childProcess = require('child_process'); + +(async function() { + // sql.js + const initSqlJs = require('sql.js'); + await initSqlJs().then(SQL => { + global._go_sqlite = SQL; + console.log("Loaded sqlite") + }); + // dendritejs expects to write to `/idb` so we create that here + // Since this is testing only, we use the default in-memory FS + global._go_sqlite.FS.mkdir("/idb"); + + // Load the generic Go Wasm exec helper inline to trigger built-in run call + // This approach avoids copying `wasm_exec.js` into the repo, which is nice + // to aim for since it can differ between Go versions. + const goRoot = await new Promise((resolve, reject) => { + childProcess.execFile('go', ['env', 'GOROOT'], (err, out) => { + if (err) { + reject("Can't find go"); + } + resolve(out.trim()); + }); + }); + const execPath = path.join(goRoot, 'misc/wasm/wasm_exec.js'); + const execCode = fs.readFileSync(execPath, 'utf8'); + eval(execCode); +})(); diff --git a/test/wasm/package-lock.json b/test/wasm/package-lock.json new file mode 100644 index 000000000..e7711deda --- /dev/null +++ b/test/wasm/package-lock.json @@ -0,0 +1,25 @@ +{ + "name": "wasm", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "sql.js": "github:neilalexander/sql.js#252a72bf57b0538cbd49bbd6f70af71e516966ae" + } + }, + "node_modules/sql.js": { + "version": "1.5.0", + "resolved": "git+ssh://git@github.com/neilalexander/sql.js.git#252a72bf57b0538cbd49bbd6f70af71e516966ae", + "integrity": "sha512-EFYI/yMoQ1U08nZxQOZ7+4S0nOpKF45EVoWGef8L1kvSCMP3B3xSzwZeOmoF2tBVpbMssAgHEz43cf0ZulRDSQ==", + "license": "MIT" + } + }, + "dependencies": { + "sql.js": { + "version": "git+ssh://git@github.com/neilalexander/sql.js.git#252a72bf57b0538cbd49bbd6f70af71e516966ae", + "integrity": "sha512-EFYI/yMoQ1U08nZxQOZ7+4S0nOpKF45EVoWGef8L1kvSCMP3B3xSzwZeOmoF2tBVpbMssAgHEz43cf0ZulRDSQ==", + "from": "sql.js@github:neilalexander/sql.js#252a72bf57b0538cbd49bbd6f70af71e516966ae" + } + } +} diff --git a/test/wasm/package.json b/test/wasm/package.json new file mode 100644 index 000000000..fa0e9730b --- /dev/null +++ b/test/wasm/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "sql.js": "github:neilalexander/sql.js#252a72bf57b0538cbd49bbd6f70af71e516966ae" + } +}