A Go test framework for xtp / Extism plugins.
package main
import (
"encoding/json"
"fmt"
xtptest "github.com/dylibso/xtp-test-go"
)
// You _must_ export a single `test` function in order for the test runner to call something
//
//go:export test
func test() int32 {
// call the tested plugin's "count_vowels" function, passing it some data
output := xtptest.CallString("count_vowels", []byte("hello"))
// check that the output is as expected
xtptest.AssertNe("we got some output", output, "")
// create a named group of tests. NOTE: plugin state is reset before and after the group runs.
xtptest.Group("check how fast the function performs", func() {
// check the amount of time in seconds or nanoseconds spent in the plugin function.
sec := xtptest.TimeSeconds("count_vowels", []byte("hello"))
xtptest.AssertLt("it should be fast", sec, 0.1)
ns := xtptest.TimeNanos("count_vowels", []byte("hello"))
xtptest.AssertLt("it should be really fast", ns, 300000)
})
xtptest.Group("check that count_vowels maintains state", func() {
accumTotal := 0
for i := 0; i < 10; i++ {
c := fromJson(xtptest.CallBytes("count_vowels", []byte("this is a test")))
accumTotal += c.Count
xtptest.AssertEq(fmt.Sprintf("total should be incremented to: %d", accumTotal), c.Total, accumTotal)
}
})
// as this is an Extism plugin, return a status/error code
return 0
}
func fromJson(data []byte) CountVowels {
var res CountVowels
_ = json.Unmarshal(data, &res)
return res
}
type CountVowels struct {
Vowels string `json:"vowels"`
Total int `json:"total"`
Count int `json:"count"`
}
func main() {}
Please see the godoc
documentation page for full details.
1. Create a Go project using the XTP Test package
mkdir plugintest && cd plugintest
go mod init <your module>
go get github.com/dylibso/xtp-test-go
2. Write your test in Go
// test.go
package main
import (
"encoding/json"
"fmt"
xtptest "github.com/dylibso/xtp-test-go"
)
//go:export test
func test() int32 {
// call the tested plugin's "count_vowels" function, passing it some data
output := xtptest.CallString("count_vowels", []byte("hello"))
// check that the output is as expected
xtptest.AssertNe("we got some output", output, "")
// ...
3. Compile your test to .wasm:
Ensure you have
tinygo
installed. Eventually
you can use the go
compiler, but the test runner must find an exported
test
function from the test plugin, and go
cannot currently export any
function other than _start
.
tinygo build -o test.wasm -target wasi test.go
4. Run the test against your plugin: Once you have your test code as a
.wasm
module, you can run the test against your plugin using the xtp
CLI:
curl https://static.dylibso.com/cli/install.sh | sudo sh
xtp plugin test ./plugin-*.wasm --with test.wasm --mock-host host.wasm
# ^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^
# your plugin(s) test to run optional mock host functions
Note: The optional mock host functions must be implemented as Extism plugins, whose exported functions match the host function signature imported by the plugins being tested.
Please reach out via the
#xtp
channel on Discord.