Add some more tests and switch to require

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
Gabriel Adrian Samfira 2022-07-06 19:21:36 +00:00
parent 280cad96e4
commit 8ccb152312
17 changed files with 3820 additions and 74 deletions

View file

@ -254,12 +254,12 @@ func (d *Database) GormParams() (dbType DBBackendType, uri string, err error) {
case MySQLBackend:
uri, err = d.MySQL.ConnectionString()
if err != nil {
return "", "", errors.Wrap(err, "validating mysql config")
return "", "", errors.Wrap(err, "fetching mysql connection string")
}
case SQLiteBackend:
uri, err = d.SQLite.ConnectionString()
if err != nil {
return "", "", errors.Wrap(err, "validating mysql config")
return "", "", errors.Wrap(err, "fetching sqlite3 connection string")
}
default:
return "", "", fmt.Errorf("invalid database backend: %s", dbType)
@ -272,9 +272,16 @@ func (d *Database) Validate() error {
if d.DbBackend == "" {
return fmt.Errorf("invalid databse configuration: backend is required")
}
if len(d.Passphrase) != 32 {
return fmt.Errorf("passphrase must be set and it must be a string of 32 characters (aes 256)")
}
passwordStenght := zxcvbn.PasswordStrength(d.Passphrase, nil)
if passwordStenght.Score < 4 {
return fmt.Errorf("database passphrase is too weak")
}
switch d.DbBackend {
case MySQLBackend:
if err := d.MySQL.Validate(); err != nil {

View file

@ -20,11 +20,12 @@ import (
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var (
EncryptionPassphrase = "bocyasicgatEtenOubwonIbsudNutDom"
EncryptionPassphrase = "bocyasicgatEtenOubwonIbsudNutDom"
WeakEncryptionPassphrase = "1234567890abcdefghijklmnopqrstuv"
)
func getDefaultSectionConfig(configDir string) Default {
@ -53,6 +54,15 @@ func getDefaultAPIServerConfig() APIServer {
}
}
func getMySQLDefaultConfig() MySQL {
return MySQL{
Username: "test",
Password: "test",
Hostname: "127.0.0.1",
DatabaseName: "garm",
}
}
func getDefaultDatabaseConfig(dir string) Database {
return Database{
Debug: false,
@ -114,7 +124,7 @@ func TestConfig(t *testing.T) {
cfg := getDefaultConfig(t)
err := cfg.Validate()
assert.Nil(t, err)
require.Nil(t, err)
}
func TestDefaultSectionConfig(t *testing.T) {
@ -165,10 +175,10 @@ func TestDefaultSectionConfig(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
err := tc.cfg.Validate()
if tc.errString == "" {
assert.Nil(t, err)
require.Nil(t, err)
} else {
assert.NotNil(t, err)
assert.Regexp(t, tc.errString, err.Error())
require.NotNil(t, err)
require.Regexp(t, tc.errString, err.Error())
}
})
}
@ -253,10 +263,10 @@ func TestValidateAPIServerConfig(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
err := tc.cfg.Validate()
if tc.errString == "" {
assert.Nil(t, err)
require.Nil(t, err)
} else {
assert.NotNil(t, err)
assert.Regexp(t, tc.errString, err.Error())
require.NotNil(t, err)
require.Regexp(t, tc.errString, err.Error())
}
})
}
@ -266,31 +276,31 @@ func TestAPIBindAddress(t *testing.T) {
cfg := getDefaultAPIServerConfig()
err := cfg.Validate()
assert.Nil(t, err)
assert.Equal(t, cfg.BindAddress(), "0.0.0.0:9998")
require.Nil(t, err)
require.Equal(t, cfg.BindAddress(), "0.0.0.0:9998")
}
func TestAPITLSconfig(t *testing.T) {
cfg := getDefaultAPIServerConfig()
err := cfg.Validate()
assert.Nil(t, err)
require.Nil(t, err)
tlsCfg, err := cfg.APITLSConfig()
assert.Nil(t, err)
assert.NotNil(t, tlsCfg)
require.Nil(t, err)
require.NotNil(t, tlsCfg)
// Any error in the TLSConfig should return an error here.
cfg.TLSConfig = TLSConfig{}
tlsCfg, err = cfg.APITLSConfig()
assert.NotNil(t, err)
assert.EqualError(t, err, "missing crt or key")
require.NotNil(t, err)
require.EqualError(t, err, "missing crt or key")
// If TLS is disabled, don't validate TLSconfig.
cfg.UseTLS = false
tlsCfg, err = cfg.APITLSConfig()
assert.Nil(t, err)
assert.Nil(t, tlsCfg)
require.Nil(t, err)
require.Nil(t, tlsCfg)
}
func TestTLSConfig(t *testing.T) {
@ -309,7 +319,7 @@ func TestTLSConfig(t *testing.T) {
cfg := getDefaultTLSConfig()
err = cfg.Validate()
assert.Nil(t, err)
require.Nil(t, err)
tests := []struct {
name string
@ -372,12 +382,119 @@ func TestTLSConfig(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
tlsCfg, err := tc.cfg.TLSConfig()
if tc.errString == "" {
assert.Nil(t, err)
assert.NotNil(t, tlsCfg)
require.Nil(t, err)
require.NotNil(t, tlsCfg)
} else {
assert.NotNil(t, err)
assert.Nil(t, tlsCfg)
assert.Regexp(t, tc.errString, err.Error())
require.NotNil(t, err)
require.Nil(t, tlsCfg)
require.Regexp(t, tc.errString, err.Error())
}
})
}
}
func TestDatabaseConfig(t *testing.T) {
dir, err := ioutil.TempDir("", "garm-config-test")
if err != nil {
t.Fatalf("failed to create temporary directory: %s", err)
}
t.Cleanup(func() { os.RemoveAll(dir) })
cfg := getDefaultDatabaseConfig(dir)
tests := []struct {
name string
cfg Database
errString string
}{
{
name: "Config is valid",
cfg: cfg,
errString: "",
},
{
name: "Missing backend",
cfg: Database{
DbBackend: "",
SQLite: cfg.SQLite,
Passphrase: cfg.Passphrase,
},
errString: "invalid databse configuration: backend is required",
},
{
name: "Invalid backend type",
cfg: Database{
DbBackend: DBBackendType("bogus"),
SQLite: cfg.SQLite,
Passphrase: cfg.Passphrase,
},
errString: "invalid database backend: bogus",
},
{
name: "Missing passphrase",
cfg: Database{
DbBackend: cfg.DbBackend,
SQLite: cfg.SQLite,
Passphrase: "",
},
errString: "passphrase must be set and it must be a string of 32 characters*",
},
{
name: "passphrase has invalid length",
cfg: Database{
DbBackend: cfg.DbBackend,
SQLite: cfg.SQLite,
Passphrase: "testing",
},
errString: "passphrase must be set and it must be a string of 32 characters*",
},
{
name: "passphrase is too weak",
cfg: Database{
DbBackend: cfg.DbBackend,
SQLite: cfg.SQLite,
Passphrase: WeakEncryptionPassphrase,
},
errString: "database passphrase is too weak",
},
{
name: "sqlite3 backend is missconfigured",
cfg: Database{
DbBackend: cfg.DbBackend,
SQLite: SQLite{
DBFile: "",
},
Passphrase: cfg.Passphrase,
},
errString: "validating sqlite3 config: no valid db_file was specified",
},
{
name: "mysql backend is missconfigured",
cfg: Database{
DbBackend: MySQLBackend,
MySQL: MySQL{},
Passphrase: cfg.Passphrase,
},
errString: "validating mysql config: database, username, password, hostname are mandatory parameters for the database section",
},
{
name: "mysql backend is configured and valid",
cfg: Database{
DbBackend: MySQLBackend,
MySQL: getMySQLDefaultConfig(),
Passphrase: cfg.Passphrase,
},
errString: "",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
err := tc.cfg.Validate()
if tc.errString == "" {
require.Nil(t, err)
} else {
require.NotNil(t, err)
require.Regexp(t, tc.errString, err.Error())
}
})
}

View file

@ -21,7 +21,7 @@ import (
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func getDefaultExternalConfig(t *testing.T) External {
@ -101,10 +101,10 @@ func TestExternal(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
err := tc.cfg.Validate()
if tc.errString == "" {
assert.Nil(t, err)
require.Nil(t, err)
} else {
assert.NotNil(t, err)
assert.EqualError(t, err, tc.errString)
require.NotNil(t, err)
require.EqualError(t, err, tc.errString)
}
})
}
@ -114,11 +114,11 @@ func TestProviderExecutableIsExecutable(t *testing.T) {
cfg := getDefaultExternalConfig(t)
execPath, err := cfg.ExecutablePath()
assert.Nil(t, err)
require.Nil(t, err)
err = os.Chmod(execPath, 0o644)
assert.Nil(t, err)
require.Nil(t, err)
err = cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, fmt.Sprintf("external provider binary %s is not executable", execPath))
require.NotNil(t, err)
require.EqualError(t, err, fmt.Sprintf("external provider binary %s is not executable", execPath))
}

View file

@ -17,7 +17,7 @@ package config
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func getDefaultLXDImageRemoteConfig() LXDImageRemote {
@ -49,7 +49,7 @@ func TestLXDRemote(t *testing.T) {
cfg := getDefaultLXDImageRemoteConfig()
err := cfg.Validate()
assert.Nil(t, err)
require.Nil(t, err)
}
func TestLXDRemoteEmptyAddress(t *testing.T) {
@ -58,8 +58,8 @@ func TestLXDRemoteEmptyAddress(t *testing.T) {
cfg.Address = ""
err := cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, "missing address")
require.NotNil(t, err)
require.EqualError(t, err, "missing address")
}
func TestLXDRemoteInvalidAddress(t *testing.T) {
@ -67,8 +67,8 @@ func TestLXDRemoteInvalidAddress(t *testing.T) {
cfg.Address = "bogus address"
err := cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, "validating address: parse \"bogus address\": invalid URI for request")
require.NotNil(t, err)
require.EqualError(t, err, "validating address: parse \"bogus address\": invalid URI for request")
}
func TestLXDRemoteIvalidAddressScheme(t *testing.T) {
@ -76,14 +76,14 @@ func TestLXDRemoteIvalidAddressScheme(t *testing.T) {
cfg.Address = "ftp://whatever"
err := cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, "address must be http or https")
require.NotNil(t, err)
require.EqualError(t, err, "address must be http or https")
}
func TestLXDConfig(t *testing.T) {
cfg := getDefaultLXDConfig()
err := cfg.Validate()
assert.Nil(t, err)
require.Nil(t, err)
}
func TestLXDWithInvalidUnixSocket(t *testing.T) {
@ -91,8 +91,8 @@ func TestLXDWithInvalidUnixSocket(t *testing.T) {
cfg.UnixSocket = "bogus unix socket"
err := cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, "could not access unix socket bogus unix socket: \"stat bogus unix socket: no such file or directory\"")
require.NotNil(t, err)
require.EqualError(t, err, "could not access unix socket bogus unix socket: \"stat bogus unix socket: no such file or directory\"")
}
func TestMissingUnixSocketAndMissingURL(t *testing.T) {
@ -102,8 +102,8 @@ func TestMissingUnixSocketAndMissingURL(t *testing.T) {
cfg.UnixSocket = ""
err := cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, "unix_socket or address must be specified")
require.NotNil(t, err)
require.EqualError(t, err, "unix_socket or address must be specified")
}
func TestInvalidLXDURL(t *testing.T) {
@ -111,8 +111,8 @@ func TestInvalidLXDURL(t *testing.T) {
cfg.URL = "bogus"
err := cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, "invalid LXD URL")
require.NotNil(t, err)
require.EqualError(t, err, "invalid LXD URL")
}
func TestLXDURLIsHTTPS(t *testing.T) {
@ -120,37 +120,37 @@ func TestLXDURLIsHTTPS(t *testing.T) {
cfg.URL = "http://example.com"
err := cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, "address must be https")
require.NotNil(t, err)
require.EqualError(t, err, "address must be https")
}
func TestMissingClientCertOrKey(t *testing.T) {
cfg := getDefaultLXDConfig()
cfg.ClientKey = ""
err := cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, "client_certificate and client_key are mandatory")
require.NotNil(t, err)
require.EqualError(t, err, "client_certificate and client_key are mandatory")
cfg = getDefaultLXDConfig()
cfg.ClientCertificate = ""
err = cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, "client_certificate and client_key are mandatory")
require.NotNil(t, err)
require.EqualError(t, err, "client_certificate and client_key are mandatory")
}
func TestLXDIvalidCertOrKeyPaths(t *testing.T) {
cfg := getDefaultLXDConfig()
cfg.ClientCertificate = "/i/am/not/here"
err := cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, "failed to access client certificate /i/am/not/here: \"stat /i/am/not/here: no such file or directory\"")
require.NotNil(t, err)
require.EqualError(t, err, "failed to access client certificate /i/am/not/here: \"stat /i/am/not/here: no such file or directory\"")
cfg.ClientCertificate = "../testdata/lxd/certs/client.crt"
cfg.ClientKey = "/me/neither"
err = cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, "failed to access client key /me/neither: \"stat /me/neither: no such file or directory\"")
require.NotNil(t, err)
require.EqualError(t, err, "failed to access client key /me/neither: \"stat /me/neither: no such file or directory\"")
}
func TestLXDInvalidServerCertPath(t *testing.T) {
@ -158,8 +158,8 @@ func TestLXDInvalidServerCertPath(t *testing.T) {
cfg.TLSServerCert = "/not/a/valid/server/cert/path"
err := cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, "failed to access tls_server_certificate /not/a/valid/server/cert/path: \"stat /not/a/valid/server/cert/path: no such file or directory\"")
require.NotNil(t, err)
require.EqualError(t, err, "failed to access tls_server_certificate /not/a/valid/server/cert/path: \"stat /not/a/valid/server/cert/path: no such file or directory\"")
}
func TestInvalidLXDImageRemotes(t *testing.T) {
@ -170,6 +170,6 @@ func TestInvalidLXDImageRemotes(t *testing.T) {
}
err := cfg.Validate()
assert.NotNil(t, err)
assert.EqualError(t, err, "remote default is invalid: invalid remote protocol bogus. Supported protocols: simplestreams")
require.NotNil(t, err)
require.EqualError(t, err, "remote default is invalid: invalid remote protocol bogus. Supported protocols: simplestreams")
}

2
go.mod
View file

@ -17,7 +17,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b
github.com/spf13/cobra v1.4.1-0.20220504202302-9e88759b19cd
github.com/stretchr/testify v1.7.5
github.com/stretchr/testify v1.8.0
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f

4
go.sum
View file

@ -231,8 +231,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

View file

@ -736,6 +736,16 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim
return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
}
// WithinRangef asserts that a time is within a time range (inclusive).
//
// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted")
func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
return WithinRange(t, actual, start, end, append([]interface{}{msg}, args...)...)
}
// YAMLEqf asserts that two YAML strings are equivalent.
func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {
if h, ok := t.(tHelper); ok {

View file

@ -1461,6 +1461,26 @@ func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta
return WithinDurationf(a.t, expected, actual, delta, msg, args...)
}
// WithinRange asserts that a time is within a time range (inclusive).
//
// a.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))
func (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {
h.Helper()
}
return WithinRange(a.t, actual, start, end, msgAndArgs...)
}
// WithinRangef asserts that a time is within a time range (inclusive).
//
// a.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted")
func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {
h.Helper()
}
return WithinRangef(a.t, actual, start, end, msg, args...)
}
// YAMLEq asserts that two YAML strings are equivalent.
func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {

View file

@ -8,6 +8,7 @@ import (
"fmt"
"math"
"os"
"path/filepath"
"reflect"
"regexp"
"runtime"
@ -144,7 +145,8 @@ func CallerInfo() []string {
if len(parts) > 1 {
dir := parts[len(parts)-2]
if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" {
callers = append(callers, fmt.Sprintf("%s:%d", file, line))
path, _ := filepath.Abs(file)
callers = append(callers, fmt.Sprintf("%s:%d", path, line))
}
}
@ -816,7 +818,6 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
return true // we consider nil to be equal to the nil set
}
subsetValue := reflect.ValueOf(subset)
defer func() {
if e := recover(); e != nil {
ok = false
@ -826,14 +827,32 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
listKind := reflect.TypeOf(list).Kind()
subsetKind := reflect.TypeOf(subset).Kind()
if listKind != reflect.Array && listKind != reflect.Slice {
if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map {
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...)
}
if subsetKind != reflect.Array && subsetKind != reflect.Slice {
if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
}
subsetValue := reflect.ValueOf(subset)
if subsetKind == reflect.Map && listKind == reflect.Map {
listValue := reflect.ValueOf(list)
subsetKeys := subsetValue.MapKeys()
for i := 0; i < len(subsetKeys); i++ {
subsetKey := subsetKeys[i]
subsetElement := subsetValue.MapIndex(subsetKey).Interface()
listElement := listValue.MapIndex(subsetKey).Interface()
if !ObjectsAreEqual(subsetElement, listElement) {
return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", list, subsetElement), msgAndArgs...)
}
}
return true
}
for i := 0; i < subsetValue.Len(); i++ {
element := subsetValue.Index(i).Interface()
ok, found := containsElement(list, element)
@ -860,7 +879,6 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
return Fail(t, "nil is the empty set which is a subset of every set", msgAndArgs...)
}
subsetValue := reflect.ValueOf(subset)
defer func() {
if e := recover(); e != nil {
ok = false
@ -870,14 +888,32 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
listKind := reflect.TypeOf(list).Kind()
subsetKind := reflect.TypeOf(subset).Kind()
if listKind != reflect.Array && listKind != reflect.Slice {
if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map {
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...)
}
if subsetKind != reflect.Array && subsetKind != reflect.Slice {
if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
}
subsetValue := reflect.ValueOf(subset)
if subsetKind == reflect.Map && listKind == reflect.Map {
listValue := reflect.ValueOf(list)
subsetKeys := subsetValue.MapKeys()
for i := 0; i < len(subsetKeys); i++ {
subsetKey := subsetKeys[i]
subsetElement := subsetValue.MapIndex(subsetKey).Interface()
listElement := listValue.MapIndex(subsetKey).Interface()
if !ObjectsAreEqual(subsetElement, listElement) {
return true
}
}
return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...)
}
for i := 0; i < subsetValue.Len(); i++ {
element := subsetValue.Index(i).Interface()
ok, found := containsElement(list, element)
@ -1110,6 +1146,27 @@ func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration,
return true
}
// WithinRange asserts that a time is within a time range (inclusive).
//
// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))
func WithinRange(t TestingT, actual, start, end time.Time, msgAndArgs ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
if end.Before(start) {
return Fail(t, "Start should be before end", msgAndArgs...)
}
if actual.Before(start) {
return Fail(t, fmt.Sprintf("Time %v expected to be in time range %v to %v, but is before the range", actual, start, end), msgAndArgs...)
} else if actual.After(end) {
return Fail(t, fmt.Sprintf("Time %v expected to be in time range %v to %v, but is after the range", actual, start, end), msgAndArgs...)
}
return true
}
func toFloat(x interface{}) (float64, bool) {
var xf float64
xok := true

28
vendor/github.com/stretchr/testify/require/doc.go generated vendored Normal file
View file

@ -0,0 +1,28 @@
// Package require implements the same assertions as the `assert` package but
// stops test execution when a test fails.
//
// Example Usage
//
// The following is a complete example using require in a standard test function:
// import (
// "testing"
// "github.com/stretchr/testify/require"
// )
//
// func TestSomething(t *testing.T) {
//
// var a string = "Hello"
// var b string = "Hello"
//
// require.Equal(t, a, b, "The two words should be the same.")
//
// }
//
// Assertions
//
// The `require` package have same global functions as in the `assert` package,
// but instead of returning a boolean result they call `t.FailNow()`.
//
// Every assertion function also takes an optional string message as the final argument,
// allowing custom error messages to be appended to the message the assertion method outputs.
package require

View file

@ -0,0 +1,16 @@
package require
// Assertions provides assertion methods around the
// TestingT interface.
type Assertions struct {
t TestingT
}
// New makes a new Assertions object for the specified TestingT.
func New(t TestingT) *Assertions {
return &Assertions{
t: t,
}
}
//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require_forward.go.tmpl -include-format-funcs"

1935
vendor/github.com/stretchr/testify/require/require.go generated vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,6 @@
{{.Comment}}
func {{.DocInfo.Name}}(t TestingT, {{.Params}}) {
if h, ok := t.(tHelper); ok { h.Helper() }
if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return }
t.FailNow()
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,5 @@
{{.CommentWithoutT "a"}}
func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) {
if h, ok := a.t.(tHelper); ok { h.Helper() }
{{.DocInfo.Name}}(a.t, {{.ForwardedParams}})
}

View file

@ -0,0 +1,29 @@
package require
// TestingT is an interface wrapper around *testing.T
type TestingT interface {
Errorf(format string, args ...interface{})
FailNow()
}
type tHelper interface {
Helper()
}
// ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful
// for table driven tests.
type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{})
// ValueAssertionFunc is a common function prototype when validating a single value. Can be useful
// for table driven tests.
type ValueAssertionFunc func(TestingT, interface{}, ...interface{})
// BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful
// for table driven tests.
type BoolAssertionFunc func(TestingT, bool, ...interface{})
// ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful
// for table driven tests.
type ErrorAssertionFunc func(TestingT, error, ...interface{})
//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require.go.tmpl -include-format-funcs"

3
vendor/modules.txt vendored
View file

@ -150,9 +150,10 @@ github.com/spf13/cobra
# github.com/spf13/pflag v1.0.5
## explicit; go 1.12
github.com/spf13/pflag
# github.com/stretchr/testify v1.7.5
# github.com/stretchr/testify v1.8.0
## explicit; go 1.13
github.com/stretchr/testify/assert
github.com/stretchr/testify/require
# golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064
## explicit; go 1.17
golang.org/x/crypto/bcrypt