Some checks failed
Docs Deploy / build_and_deploy (push) Has been cancelled
Generate Docs / cli (push) Has been cancelled
Generate Config Doc / cli (push) Has been cancelled
Go formatting / go-formatting (push) Has been cancelled
Check links / markdown-link-check (push) Has been cancelled
Integration / pre-test (push) Has been cancelled
Integration / test on (push) Has been cancelled
Integration / status (push) Has been cancelled
Lint / Lint Go code (push) Has been cancelled
Test / test (ubuntu-latest) (push) Has been cancelled
178 lines
4.4 KiB
Go
178 lines
4.4 KiB
Go
package envtest
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"strconv"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/cenkalti/backoff"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/cosmosfaucet"
|
|
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/env"
|
|
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/errors"
|
|
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/gocmd"
|
|
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/httpstatuschecker"
|
|
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/xurl"
|
|
)
|
|
|
|
const (
|
|
envDoNotTrack = "DO_NOT_TRACK"
|
|
)
|
|
|
|
var (
|
|
// IgniteApp hold the location of the ignite binary used in the integration
|
|
// tests. The binary is compiled the first time the env.New() function is
|
|
// invoked.
|
|
IgniteApp = path.Join(os.TempDir(), "ignite-tests", "ignite")
|
|
|
|
IsCI, _ = strconv.ParseBool(os.Getenv("CI"))
|
|
compileBinaryOnce sync.Once
|
|
)
|
|
|
|
// Env provides an isolated testing environment and what's needed to
|
|
// make it possible.
|
|
type Env struct {
|
|
t *testing.T
|
|
ctx context.Context
|
|
}
|
|
|
|
// New creates a new testing environment.
|
|
func New(t *testing.T) Env {
|
|
t.Helper()
|
|
ctx, cancel := context.WithCancel(t.Context())
|
|
e := Env{
|
|
t: t,
|
|
ctx: ctx,
|
|
}
|
|
// To avoid conflicts with the default config folder located in $HOME, we
|
|
// set an other one thanks to env var.
|
|
cfgDir := path.Join(t.TempDir(), ".ignite")
|
|
env.SetConfigDir(cfgDir)
|
|
enableDoNotTrackEnv(t)
|
|
|
|
t.Cleanup(cancel)
|
|
compileBinaryOnce.Do(func() {
|
|
compileBinary(ctx)
|
|
})
|
|
return e
|
|
}
|
|
|
|
func compileBinary(ctx context.Context) {
|
|
wd, err := os.Getwd()
|
|
if err != nil {
|
|
panic(fmt.Sprintf("unable to get working dir: %v", err))
|
|
}
|
|
pkgs, err := gocmd.List(ctx, wd, []string{"-m", "-f={{.Dir}}", "git.cw.tr/mukan-network/mukan-ignite"})
|
|
if err != nil {
|
|
panic(fmt.Sprintf("unable to list ignite cli package: %v", err))
|
|
}
|
|
if len(pkgs) != 1 {
|
|
panic(fmt.Sprintf("expected only one package, got %d", len(pkgs)))
|
|
}
|
|
appPath := pkgs[0]
|
|
var (
|
|
output, binary = filepath.Split(IgniteApp)
|
|
path = path.Join(appPath, "ignite", "cmd", "ignite")
|
|
)
|
|
err = gocmd.BuildPath(ctx, output, binary, path, nil)
|
|
if err != nil {
|
|
panic(fmt.Sprintf("error while building binary: %v", err))
|
|
}
|
|
}
|
|
|
|
func (e Env) T() *testing.T {
|
|
return e.t
|
|
}
|
|
|
|
// SetCleanup registers a function to be called when the test (or subtest) and all its
|
|
// subtests complete.
|
|
func (e Env) SetCleanup(f func()) {
|
|
e.t.Cleanup(f)
|
|
}
|
|
|
|
// Ctx returns parent context for the test suite to use for cancelations.
|
|
func (e Env) Ctx() context.Context {
|
|
return e.ctx
|
|
}
|
|
|
|
// IsAppServed checks that app is served properly and servers are started to listening before ctx canceled.
|
|
func (e Env) IsAppServed(ctx context.Context, apiAddr string) error {
|
|
checkAlive := func() error {
|
|
addr, err := xurl.HTTP(apiAddr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ok, err := httpstatuschecker.Check(ctx, fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/node_info", addr))
|
|
if err == nil && !ok {
|
|
err = errors.New("waiting for app")
|
|
}
|
|
if HasTestVerboseFlag() {
|
|
fmt.Printf("IsAppServed at %s: %v\n", addr, err)
|
|
}
|
|
return err
|
|
}
|
|
|
|
return backoff.Retry(checkAlive, backoff.WithContext(backoff.NewConstantBackOff(time.Second), ctx))
|
|
}
|
|
|
|
// IsFaucetServed checks that faucet of the app is served properly.
|
|
func (e Env) IsFaucetServed(ctx context.Context, faucetClient cosmosfaucet.HTTPClient) error {
|
|
checkAlive := func() error {
|
|
_, err := faucetClient.FaucetInfo(ctx)
|
|
return err
|
|
}
|
|
|
|
return backoff.Retry(checkAlive, backoff.WithContext(backoff.NewConstantBackOff(time.Second), ctx))
|
|
}
|
|
|
|
// TmpDir creates a new temporary directory.
|
|
func (e Env) TmpDir() (path string) {
|
|
return e.t.TempDir()
|
|
}
|
|
|
|
// Home returns user's home dir.
|
|
func (e Env) Home() string {
|
|
home, err := os.UserHomeDir()
|
|
require.NoError(e.t, err)
|
|
return home
|
|
}
|
|
|
|
// AppHome returns app's root home/data dir path.
|
|
func (e Env) AppHome(name string) string {
|
|
return filepath.Join(e.Home(), fmt.Sprintf(".%s", name))
|
|
}
|
|
|
|
// Must fails the immediately if not ok.
|
|
// t.Fail() needs to be called for the failing tests before running Must().
|
|
func (e Env) Must(ok bool) {
|
|
if !ok {
|
|
e.t.FailNow()
|
|
}
|
|
}
|
|
|
|
func (e Env) HasFailed() bool {
|
|
return e.t.Failed()
|
|
}
|
|
|
|
func (e Env) RequireExpectations() {
|
|
e.Must(e.HasFailed())
|
|
}
|
|
|
|
// enableDoNotTrackEnv set true the DO_NOT_TRACK env var.
|
|
func enableDoNotTrackEnv(t *testing.T) {
|
|
t.Helper()
|
|
t.Setenv(envDoNotTrack, "true")
|
|
}
|
|
|
|
func HasTestVerboseFlag() bool {
|
|
return flag.Lookup("test.v").Value.String() == "true"
|
|
}
|