diff options
Diffstat (limited to 'test/utils')
-rw-r--r-- | test/utils/matchers.go | 153 | ||||
-rw-r--r-- | test/utils/podmantest_test.go | 2 | ||||
-rw-r--r-- | test/utils/utils.go | 28 |
3 files changed, 142 insertions, 41 deletions
diff --git a/test/utils/matchers.go b/test/utils/matchers.go index 07c1232e7..17ff3ea75 100644 --- a/test/utils/matchers.go +++ b/test/utils/matchers.go @@ -2,57 +2,164 @@ package utils import ( "fmt" + "net/url" + "github.com/containers/common/pkg/config" + . "github.com/onsi/gomega" "github.com/onsi/gomega/format" "github.com/onsi/gomega/gexec" + "github.com/onsi/gomega/matchers" + "github.com/onsi/gomega/types" ) +// HaveActiveService verifies the given service is the active service +func HaveActiveService(name interface{}) OmegaMatcher { + return WithTransform( + func(cfg *config.Config) string { + return cfg.Engine.ActiveService + }, + Equal(name)) +} + +type ServiceMatcher struct { + types.GomegaMatcher + Name interface{} + URI interface{} + Identity interface{} + failureMessage string + negatedFailureMessage string +} + +func VerifyService(name, uri, identity interface{}) OmegaMatcher { + return &ServiceMatcher{ + Name: name, + URI: uri, + Identity: identity, + } +} + +func (matcher *ServiceMatcher) Match(actual interface{}) (success bool, err error) { + cfg, ok := actual.(*config.Config) + if !ok { + return false, fmt.Errorf("ServiceMatcher matcher expects a config.Config") + } + + if _, err = url.Parse(matcher.URI.(string)); err != nil { + return false, err + } + + success, err = HaveKey(matcher.Name).Match(cfg.Engine.ServiceDestinations) + if !success || err != nil { + matcher.failureMessage = HaveKey(matcher.Name).FailureMessage(cfg.Engine.ServiceDestinations) + matcher.negatedFailureMessage = HaveKey(matcher.Name).NegatedFailureMessage(cfg.Engine.ServiceDestinations) + return + } + + sd := cfg.Engine.ServiceDestinations[matcher.Name.(string)] + success, err = Equal(matcher.URI).Match(sd.URI) + if !success || err != nil { + matcher.failureMessage = Equal(matcher.URI).FailureMessage(sd.URI) + matcher.negatedFailureMessage = Equal(matcher.URI).NegatedFailureMessage(sd.URI) + return + } + + success, err = Equal(matcher.Identity).Match(sd.Identity) + if !success || err != nil { + matcher.failureMessage = Equal(matcher.Identity).FailureMessage(sd.Identity) + matcher.negatedFailureMessage = Equal(matcher.Identity).NegatedFailureMessage(sd.Identity) + return + } + + return true, nil +} + +func (matcher *ServiceMatcher) FailureMessage(_ interface{}) string { + return matcher.failureMessage +} + +func (matcher *ServiceMatcher) NegatedFailureMessage(_ interface{}) string { + return matcher.negatedFailureMessage +} + +type URLMatcher struct { + matchers.EqualMatcher +} + +// VerifyURL matches when actual is a valid URL and matches expected +func VerifyURL(uri interface{}) OmegaMatcher { + return &URLMatcher{matchers.EqualMatcher{Expected: uri}} +} + +func (matcher *URLMatcher) Match(actual interface{}) (bool, error) { + e, ok := matcher.Expected.(string) + if !ok { + return false, fmt.Errorf("VerifyURL requires string inputs %T is not supported", matcher.Expected) + } + e_uri, err := url.Parse(e) + if err != nil { + return false, err + } + + a, ok := actual.(string) + if !ok { + return false, fmt.Errorf("VerifyURL requires string inputs %T is not supported", actual) + } + a_uri, err := url.Parse(a) + if err != nil { + return false, err + } + + return (&matchers.EqualMatcher{Expected: e_uri}).Match(a_uri) +} + +type ExitMatcher struct { + types.GomegaMatcher + Expected int + Actual int +} + // ExitWithError matches when assertion is > argument. Default 0 -// Modeled after the gomega Exit() matcher -func ExitWithError(optionalExitCode ...int) *exitMatcher { +// Modeled after the gomega Exit() matcher and also operates on sessions. +func ExitWithError(optionalExitCode ...int) *ExitMatcher { exitCode := 0 if len(optionalExitCode) > 0 { exitCode = optionalExitCode[0] } - return &exitMatcher{exitCode: exitCode} + return &ExitMatcher{Expected: exitCode} } -type exitMatcher struct { - exitCode int - actualExitCode int -} - -func (m *exitMatcher) Match(actual interface{}) (success bool, err error) { +// Match follows gexec.Matcher interface +func (matcher *ExitMatcher) Match(actual interface{}) (success bool, err error) { exiter, ok := actual.(gexec.Exiter) if !ok { return false, fmt.Errorf("ExitWithError must be passed a gexec.Exiter (Missing method ExitCode() int) Got:\n#{format.Object(actual, 1)}") } - m.actualExitCode = exiter.ExitCode() - if m.actualExitCode == -1 { + matcher.Actual = exiter.ExitCode() + if matcher.Actual == -1 { return false, nil } - return m.actualExitCode > m.exitCode, nil + return matcher.Actual > matcher.Expected, nil } -func (m *exitMatcher) FailureMessage(actual interface{}) (message string) { - if m.actualExitCode == -1 { +func (matcher *ExitMatcher) FailureMessage(_ interface{}) (message string) { + if matcher.Actual == -1 { return "Expected process to exit. It did not." } - return format.Message(m.actualExitCode, "to be greater than exit code:", m.exitCode) + return format.Message(matcher.Actual, "to be greater than exit code: ", matcher.Expected) } -func (m *exitMatcher) NegatedFailureMessage(actual interface{}) (message string) { - if m.actualExitCode == -1 { +func (matcher *ExitMatcher) NegatedFailureMessage(_ interface{}) (message string) { + switch { + case matcher.Actual == -1: return "you really shouldn't be able to see this!" - } else { - if m.exitCode == -1 { - return "Expected process not to exit. It did." - } - return format.Message(m.actualExitCode, "is less than or equal to exit code:", m.exitCode) + case matcher.Expected == -1: + return "Expected process not to exit. It did." } + return format.Message(matcher.Actual, "is less than or equal to exit code: ", matcher.Expected) } -func (m *exitMatcher) MatchMayChangeInTheFuture(actual interface{}) bool { + +func (matcher *ExitMatcher) MatchMayChangeInTheFuture(actual interface{}) bool { session, ok := actual.(*gexec.Session) if ok { return session.ExitCode() == -1 diff --git a/test/utils/podmantest_test.go b/test/utils/podmantest_test.go index 9bd1c4a66..1bb9ecb6b 100644 --- a/test/utils/podmantest_test.go +++ b/test/utils/podmantest_test.go @@ -23,7 +23,7 @@ var _ = Describe("PodmanTest test", func() { FakeOutputs["check"] = []string{"check"} os.Setenv("HOOK_OPTION", "hook_option") env := os.Environ() - session := podmanTest.PodmanAsUserBase([]string{"check"}, 1000, 1000, "", env, true, false, nil) + session := podmanTest.PodmanAsUserBase([]string{"check"}, 1000, 1000, "", env, true, false, nil, nil) os.Unsetenv("HOOK_OPTION") session.WaitWithDefaultTimeout() Expect(session.Command.Process).ShouldNot(BeNil()) diff --git a/test/utils/utils.go b/test/utils/utils.go index bfefc58ec..8d1edb23a 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -66,27 +66,31 @@ func (p *PodmanTest) MakeOptions(args []string, noEvents, noCache bool) []string // PodmanAsUserBase exec podman as user. uid and gid is set for credentials usage. env is used // to record the env for debugging -func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string, env []string, noEvents, noCache bool, extraFiles []*os.File) *PodmanSession { +func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string, env []string, noEvents, noCache bool, wrapper []string, extraFiles []*os.File) *PodmanSession { var command *exec.Cmd podmanOptions := p.MakeOptions(args, noEvents, noCache) podmanBinary := p.PodmanBinary if p.RemoteTest { podmanBinary = p.RemotePodmanBinary } + + runCmd := append(wrapper, podmanBinary) if p.RemoteTest { podmanOptions = append([]string{"--remote", "--url", p.RemoteSocket}, podmanOptions...) } if env == nil { - fmt.Printf("Running: %s %s\n", podmanBinary, strings.Join(podmanOptions, " ")) + fmt.Printf("Running: %s %s\n", strings.Join(runCmd, " "), strings.Join(podmanOptions, " ")) } else { - fmt.Printf("Running: (env: %v) %s %s\n", env, podmanBinary, strings.Join(podmanOptions, " ")) + fmt.Printf("Running: (env: %v) %s %s\n", env, strings.Join(runCmd, " "), strings.Join(podmanOptions, " ")) } if uid != 0 || gid != 0 { pythonCmd := fmt.Sprintf("import os; import sys; uid = %d; gid = %d; cwd = '%s'; os.setgid(gid); os.setuid(uid); os.chdir(cwd) if len(cwd)>0 else True; os.execv(sys.argv[1], sys.argv[1:])", gid, uid, cwd) - nsEnterOpts := append([]string{"-c", pythonCmd, podmanBinary}, podmanOptions...) + runCmd = append(runCmd, podmanOptions...) + nsEnterOpts := append([]string{"-c", pythonCmd}, runCmd...) command = exec.Command("python", nsEnterOpts...) } else { - command = exec.Command(podmanBinary, podmanOptions...) + runCmd = append(runCmd, podmanOptions...) + command = exec.Command(runCmd[0], runCmd[1:]...) } if env != nil { command.Env = env @@ -106,7 +110,7 @@ func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string // PodmanBase exec podman with default env. func (p *PodmanTest) PodmanBase(args []string, noEvents, noCache bool) *PodmanSession { - return p.PodmanAsUserBase(args, 0, 0, "", nil, noEvents, noCache, nil) + return p.PodmanAsUserBase(args, 0, 0, "", nil, noEvents, noCache, nil, nil) } // WaitForContainer waits on a started container @@ -393,7 +397,7 @@ func tagOutputToMap(imagesOutput []string) map[string]map[string]bool { return m } -// GetHostDistributionInfo returns a struct with its distribution name and version +// GetHostDistributionInfo returns a struct with its distribution Name and version func GetHostDistributionInfo() HostOS { f, err := os.Open(OSReleasePath) defer f.Close() @@ -487,13 +491,3 @@ func RandomString(n int) string { } return string(b) } - -//SkipIfInContainer skips a test if the test is run inside a container -func SkipIfInContainer(reason string) { - if len(reason) < 5 { - panic("SkipIfInContainer must specify a reason to skip") - } - if os.Getenv("TEST_ENVIRON") == "container" { - Skip("[container]: " + reason) - } -} |