info_tfgrid/collections/developers/internals/zos/development/testing.md
2024-05-13 19:10:10 -04:00

157 lines
3.9 KiB
Markdown

# Testing
Beside unit testing, you might want to test your change in an integrated environment, the following are two options to do it.
- [Testing](#testing)
- [Using grid/node client](#using-gridnode-client)
- [Using a test app](#using-a-test-app)
- [An example to talk to container and qsfs modules](#an-example-to-talk-to-container-and-qsfs-modules)
- [An example of directly using zinit package](#an-example-of-directly-using-zinit-package)
## Using grid/node client
You can simply use any grid client to deploy a workload of any type, you should specify your node's twin ID (and make sure you are on the correct network).
Inside the node, you can do `noded -id` and `noded -net` to get your current node ID and network. Also, [you can check your farm](https://dashboard.dev.grid.tf/explorer/farms) and get node information from there.
Another option is the golang [node client](../manual/manual.md#interaction).
While deploying on your local node, logs with `zinit log` would be helpful to see any possible errors and to debug your code.
## Using a test app
If you need to test a specific module or functionality, you can create a simple test app inside e.g. tools directory.
Inside this simple test app, you can import any module or talk to another one using [zbus](../internals/internals.md#ipc).
### An example to talk to container and qsfs modules
```go
// tools/del/main.go
package main
import (
"context"
"flag"
"strings"
"time"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/threefoldtech/zbus"
"github.com/threefoldtech/zos/pkg"
"github.com/threefoldtech/zos/pkg/stubs"
)
func main() {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
zbus, err := zbus.NewRedisClient("unix:///var/run/redis.sock")
if err != nil {
log.Err(err).Msg("cannot init zbus client")
return
}
var workloadType, workloadID string
flag.StringVar(&workloadType, "type", "", "workload type (qsfs or container)")
flag.StringVar(&workloadID, "id", "", "workload ID")
flag.Parse()
if workloadType == "" || workloadID == "" {
log.Error().Msg("you need to provide both type and id")
return
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if workloadType == "qsfs" {
qsfsd := stubs.NewQSFSDStub(zbus)
err := qsfsd.SignalDelete(ctx, workloadID)
if err != nil {
log.Err(err).Msg("cannot delete qsfs workload")
}
} else if workloadType == "container" {
args := strings.Split(workloadID, ":")
if len(args) != 2 {
log.Error().Msg("container id must contain namespace, e.g. qsfs:wl129")
}
containerd := stubs.NewContainerModuleStub(zbus)
err := containerd.SignalDelete(ctx, args[0], pkg.ContainerID(args[1]))
if err != nil {
log.Err(err).Msg("cannot delete container workload")
}
}
}
```
Then we can simply build, upload and execute this in our node:
```
cd tools/del
go build
scp del root@192.168.123.44:/root/del
```
Then ssh into `192.168.123.44` and simply execute your test app:
```
./del
```
### An example of directly using zinit package
```go
// tools/zinit_test
package main
import (
"encoding/json"
"fmt"
"regexp"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/threefoldtech/zos/pkg/zinit"
)
func main() {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
z := zinit.New("/var/run/zinit.sock")
regex := fmt.Sprintf(`^ip netns exec %s %s`, "ndmz", "/sbin/udhcpc")
_, err := regexp.Compile(regex)
if err != nil {
log.Err(err).Msgf("cannot compile %s", regex)
return
}
// try match
matched, err := z.Matches(zinit.WithExecRegex(regex))
if err != nil {
log.Err(err).Msg("cannot filter services")
}
matchedStr, err := json.Marshal(matched)
if err != nil {
log.Err(err).Msg("cannot convert matched map to json")
}
log.Debug().Str("matched", string(matchedStr)).Msg("matched services")
// // try destroy
// err = z.Destroy(10*time.Second, matched...)
// if err != nil {
// log.Err(err).Msg("cannot destroy matched services")
// }
}
```