forked from github/multus-cni
Bump libcni to fetch the bugfix
This change introduces https://github.com/containernetworking/cni/pull/904 to fix the issue.
This commit is contained in:
parent
3deb079546
commit
7f7bb354c5
9
.github/workflows/test.yml
vendored
9
.github/workflows/test.yml
vendored
@ -16,11 +16,10 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Run Revive
|
||||
run: |
|
||||
GO111MODULE=off go get github.com/mgechev/revive
|
||||
$(go env GOPATH)/bin/revive -exclude ./vendor/... ./... # this is ouput for user
|
||||
$(go env GOPATH)/bin/revive -exclude ./vendor/... ./...| xargs -0 -r false # this is for github actions
|
||||
- name: Run Revive Action by pulling pre-built image
|
||||
uses: docker://morphy/revive-action:v2
|
||||
with:
|
||||
exclude: "./vendor/..."
|
||||
|
||||
- name: Run go fmt
|
||||
run: go fmt ./...
|
||||
|
4
go.mod
4
go.mod
@ -4,14 +4,14 @@ go 1.17
|
||||
|
||||
require (
|
||||
github.com/blang/semver v3.5.1+incompatible
|
||||
github.com/containernetworking/cni v1.0.1
|
||||
github.com/containernetworking/cni v1.1.2
|
||||
github.com/containernetworking/plugins v1.1.0
|
||||
github.com/fsnotify/fsnotify v1.5.1
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.3.0
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/gomega v1.15.0
|
||||
github.com/onsi/gomega v1.17.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4
|
||||
|
7
go.sum
7
go.sum
@ -231,6 +231,8 @@ github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ
|
||||
github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/cni v1.0.1 h1:9OIL/sZmMYDBe+G8svzILAlulUpaDTUjeAbtH/JNLBo=
|
||||
github.com/containernetworking/cni v1.0.1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y=
|
||||
github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl31EQbXALQ=
|
||||
github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw=
|
||||
github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
|
||||
github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
|
||||
github.com/containernetworking/plugins v1.1.0 h1:kTIldaDo9SlbQsjhUKvDx0v9q7zyIFJH/Rm9F4xRBro=
|
||||
@ -419,6 +421,7 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@ -471,6 +474,7 @@ github.com/heketi/heketi v10.3.0+incompatible/go.mod h1:bB9ly3RchcQqsQ9CpyaQwvva
|
||||
github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7UkZt1i4FQeQy0R2T8GLUwQhOP5M1gBhy4=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
@ -595,6 +599,7 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
@ -603,6 +608,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
|
||||
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
||||
github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU=
|
||||
github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
|
||||
github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
|
6
vendor/github.com/containernetworking/cni/libcni/conf.go
generated
vendored
6
vendor/github.com/containernetworking/cni/libcni/conf.go
generated
vendored
@ -21,6 +21,8 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
)
|
||||
|
||||
type NotFoundError struct {
|
||||
@ -41,8 +43,8 @@ func (e NoConfigsFoundError) Error() string {
|
||||
}
|
||||
|
||||
func ConfFromBytes(bytes []byte) (*NetworkConfig, error) {
|
||||
conf := &NetworkConfig{Bytes: bytes}
|
||||
if err := json.Unmarshal(bytes, &conf.Network); err != nil {
|
||||
conf := &NetworkConfig{Bytes: bytes, Network: &types.NetConf{}}
|
||||
if err := json.Unmarshal(bytes, conf.Network); err != nil {
|
||||
return nil, fmt.Errorf("error parsing configuration: %w", err)
|
||||
}
|
||||
if conf.Network.Type == "" {
|
||||
|
51
vendor/github.com/containernetworking/cni/pkg/invoke/exec.go
generated
vendored
51
vendor/github.com/containernetworking/cni/pkg/invoke/exec.go
generated
vendored
@ -16,6 +16,7 @@ package invoke
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
@ -33,6 +34,49 @@ type Exec interface {
|
||||
Decode(jsonBytes []byte) (version.PluginInfo, error)
|
||||
}
|
||||
|
||||
// Plugin must return result in same version as specified in netconf; but
|
||||
// for backwards compatibility reasons if the result version is empty use
|
||||
// config version (rather than technically correct 0.1.0).
|
||||
// https://github.com/containernetworking/cni/issues/895
|
||||
func fixupResultVersion(netconf, result []byte) (string, []byte, error) {
|
||||
versionDecoder := &version.ConfigDecoder{}
|
||||
confVersion, err := versionDecoder.Decode(netconf)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
var rawResult map[string]interface{}
|
||||
if err := json.Unmarshal(result, &rawResult); err != nil {
|
||||
return "", nil, fmt.Errorf("failed to unmarshal raw result: %w", err)
|
||||
}
|
||||
|
||||
// plugin output of "null" is successfully unmarshalled, but results in a nil
|
||||
// map which causes a panic when the confVersion is assigned below.
|
||||
if rawResult == nil {
|
||||
rawResult = make(map[string]interface{})
|
||||
}
|
||||
|
||||
// Manually decode Result version; we need to know whether its cniVersion
|
||||
// is empty, while built-in decoders (correctly) substitute 0.1.0 for an
|
||||
// empty version per the CNI spec.
|
||||
if resultVerRaw, ok := rawResult["cniVersion"]; ok {
|
||||
resultVer, ok := resultVerRaw.(string)
|
||||
if ok && resultVer != "" {
|
||||
return resultVer, result, nil
|
||||
}
|
||||
}
|
||||
|
||||
// If the cniVersion is not present or empty, assume the result is
|
||||
// the same CNI spec version as the config
|
||||
rawResult["cniVersion"] = confVersion
|
||||
newBytes, err := json.Marshal(rawResult)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("failed to remarshal fixed result: %w", err)
|
||||
}
|
||||
|
||||
return confVersion, newBytes, nil
|
||||
}
|
||||
|
||||
// For example, a testcase could pass an instance of the following fakeExec
|
||||
// object to ExecPluginWithResult() to verify the incoming stdin and environment
|
||||
// and provide a tailored response:
|
||||
@ -84,7 +128,12 @@ func ExecPluginWithResult(ctx context.Context, pluginPath string, netconf []byte
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return create.CreateFromBytes(stdoutBytes)
|
||||
resultVersion, fixedBytes, err := fixupResultVersion(netconf, stdoutBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return create.Create(resultVersion, fixedBytes)
|
||||
}
|
||||
|
||||
func ExecPluginWithoutResult(ctx context.Context, pluginPath string, netconf []byte, args CNIArgs, exec Exec) error {
|
||||
|
6
vendor/github.com/containernetworking/cni/pkg/skel/skel.go
generated
vendored
6
vendor/github.com/containernetworking/cni/pkg/skel/skel.go
generated
vendored
@ -196,6 +196,7 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error,
|
||||
// Print the about string to stderr when no command is set
|
||||
if err.Code == types.ErrInvalidEnvironmentVariables && t.Getenv("CNI_COMMAND") == "" && about != "" {
|
||||
_, _ = fmt.Fprintln(t.Stderr, about)
|
||||
_, _ = fmt.Fprintf(t.Stderr, "CNI protocol versions supported: %s\n", strings.Join(versionInfo.SupportedVersions(), ", "))
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
@ -248,10 +249,7 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error,
|
||||
return types.NewError(types.ErrInvalidEnvironmentVariables, fmt.Sprintf("unknown CNI_COMMAND: %v", cmd), "")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// PluginMainWithError is the core "main" for a plugin. It accepts
|
||||
|
4
vendor/github.com/containernetworking/cni/pkg/version/plugin.go
generated
vendored
4
vendor/github.com/containernetworking/cni/pkg/version/plugin.go
generated
vendored
@ -86,8 +86,8 @@ func (*PluginDecoder) Decode(jsonBytes []byte) (PluginInfo, error) {
|
||||
// minor, and micro numbers or returns an error
|
||||
func ParseVersion(version string) (int, int, int, error) {
|
||||
var major, minor, micro int
|
||||
if version == "" {
|
||||
return -1, -1, -1, fmt.Errorf("invalid version %q: the version is empty", version)
|
||||
if version == "" { // special case: no version declared == v0.1.0
|
||||
return 0, 1, 0, nil
|
||||
}
|
||||
|
||||
parts := strings.Split(version, ".")
|
||||
|
20
vendor/github.com/onsi/gomega/CHANGELOG.md
generated
vendored
20
vendor/github.com/onsi/gomega/CHANGELOG.md
generated
vendored
@ -1,3 +1,23 @@
|
||||
## 1.17.0
|
||||
|
||||
### Features
|
||||
- Add HaveField matcher [3a26311]
|
||||
- add Error() assertions on the final error value of multi-return values (#480) [2f96943]
|
||||
- separate out offsets and timeouts (#478) [18a4723]
|
||||
- fix transformation error reporting (#479) [e001fab]
|
||||
- allow transform functions to report errors (#472) [bf93408]
|
||||
|
||||
### Fixes
|
||||
Stop using deprecated ioutil package (#467) [07f405d]
|
||||
|
||||
## 1.16.0
|
||||
|
||||
### Features
|
||||
- feat: HaveHTTPStatus multiple expected values (#465) [aa69f1b]
|
||||
- feat: HaveHTTPHeaderWithValue() matcher (#463) [dd83a96]
|
||||
- feat: HaveHTTPBody matcher (#462) [504e1f2]
|
||||
- feat: formatter for HTTP responses (#461) [e5b3157]
|
||||
|
||||
## 1.15.0
|
||||
|
||||
### Fixes
|
||||
|
17
vendor/github.com/onsi/gomega/gomega_dsl.go
generated
vendored
17
vendor/github.com/onsi/gomega/gomega_dsl.go
generated
vendored
@ -22,7 +22,7 @@ import (
|
||||
"github.com/onsi/gomega/types"
|
||||
)
|
||||
|
||||
const GOMEGA_VERSION = "1.15.0"
|
||||
const GOMEGA_VERSION = "1.17.0"
|
||||
|
||||
const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler.
|
||||
If you're using Ginkgo then you probably forgot to put your assertion in an It().
|
||||
@ -204,7 +204,8 @@ func Expect(actual interface{}, extra ...interface{}) Assertion {
|
||||
// ExpectWithOffset(1, "foo").To(Equal("foo"))
|
||||
//
|
||||
// Unlike `Expect` and `Ω`, `ExpectWithOffset` takes an additional integer argument
|
||||
// that is used to modify the call-stack offset when computing line numbers.
|
||||
// that is used to modify the call-stack offset when computing line numbers. It is
|
||||
// the same as `Expect(...).WithOffset`.
|
||||
//
|
||||
// This is most useful in helper functions that make assertions. If you want Gomega's
|
||||
// error message to refer to the calling line in the test (as opposed to the line in the helper function)
|
||||
@ -300,6 +301,9 @@ For example:
|
||||
}).Should(Succeed())
|
||||
|
||||
will rerun the function until all assertions pass.
|
||||
|
||||
`Eventually` specifying a timeout interval (and an optional polling interval) are
|
||||
the same as `Eventually(...).WithTimeout` or `Eventually(...).WithTimeout(...).WithPolling`.
|
||||
*/
|
||||
func Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion {
|
||||
ensureDefaultGomegaIsConfigured()
|
||||
@ -309,6 +313,12 @@ func Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion {
|
||||
// EventuallyWithOffset operates like Eventually but takes an additional
|
||||
// initial argument to indicate an offset in the call stack. This is useful when building helper
|
||||
// functions that contain matchers. To learn more, read about `ExpectWithOffset`.
|
||||
//
|
||||
// `EventuallyWithOffset` is the same as `Eventually(...).WithOffset`.
|
||||
//
|
||||
// `EventuallyWithOffset` specifying a timeout interval (and an optional polling interval) are
|
||||
// the same as `Eventually(...).WithOffset(...).WithTimeout` or
|
||||
// `Eventually(...).WithOffset(...).WithTimeout(...).WithPolling`.
|
||||
func EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion {
|
||||
ensureDefaultGomegaIsConfigured()
|
||||
return Default.EventuallyWithOffset(offset, actual, intervals...)
|
||||
@ -337,6 +347,9 @@ func Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion {
|
||||
// ConsistentlyWithOffset operates like Consistently but takes an additional
|
||||
// initial argument to indicate an offset in the call stack. This is useful when building helper
|
||||
// functions that contain matchers. To learn more, read about `ExpectWithOffset`.
|
||||
//
|
||||
// `ConsistentlyWithOffset` is the same as `Consistently(...).WithOffset` and
|
||||
// optional `WithTimeout` and `WithPolling`.
|
||||
func ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion {
|
||||
ensureDefaultGomegaIsConfigured()
|
||||
return Default.ConsistentlyWithOffset(offset, actual, intervals...)
|
||||
|
81
vendor/github.com/onsi/gomega/internal/assertion.go
generated
vendored
81
vendor/github.com/onsi/gomega/internal/assertion.go
generated
vendored
@ -8,44 +8,64 @@ import (
|
||||
)
|
||||
|
||||
type Assertion struct {
|
||||
actualInput interface{}
|
||||
actuals []interface{} // actual value plus all extra values
|
||||
actualIndex int // value to pass to the matcher
|
||||
vet vetinari // the vet to call before calling Gomega matcher
|
||||
offset int
|
||||
extra []interface{}
|
||||
g *Gomega
|
||||
}
|
||||
|
||||
// ...obligatory discworld reference, as "vetineer" doesn't sound ... quite right.
|
||||
type vetinari func(assertion *Assertion, optionalDescription ...interface{}) bool
|
||||
|
||||
func NewAssertion(actualInput interface{}, g *Gomega, offset int, extra ...interface{}) *Assertion {
|
||||
return &Assertion{
|
||||
actualInput: actualInput,
|
||||
actuals: append([]interface{}{actualInput}, extra...),
|
||||
actualIndex: 0,
|
||||
vet: (*Assertion).vetActuals,
|
||||
offset: offset,
|
||||
extra: extra,
|
||||
g: g,
|
||||
}
|
||||
}
|
||||
|
||||
func (assertion *Assertion) WithOffset(offset int) types.Assertion {
|
||||
assertion.offset = offset
|
||||
return assertion
|
||||
}
|
||||
|
||||
func (assertion *Assertion) Error() types.Assertion {
|
||||
return &Assertion{
|
||||
actuals: assertion.actuals,
|
||||
actualIndex: len(assertion.actuals) - 1,
|
||||
vet: (*Assertion).vetError,
|
||||
offset: assertion.offset,
|
||||
g: assertion.g,
|
||||
}
|
||||
}
|
||||
|
||||
func (assertion *Assertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
|
||||
assertion.g.THelper()
|
||||
return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, true, optionalDescription...)
|
||||
return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, true, optionalDescription...)
|
||||
}
|
||||
|
||||
func (assertion *Assertion) ShouldNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
|
||||
assertion.g.THelper()
|
||||
return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...)
|
||||
return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, false, optionalDescription...)
|
||||
}
|
||||
|
||||
func (assertion *Assertion) To(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
|
||||
assertion.g.THelper()
|
||||
return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, true, optionalDescription...)
|
||||
return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, true, optionalDescription...)
|
||||
}
|
||||
|
||||
func (assertion *Assertion) ToNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
|
||||
assertion.g.THelper()
|
||||
return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...)
|
||||
return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, false, optionalDescription...)
|
||||
}
|
||||
|
||||
func (assertion *Assertion) NotTo(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
|
||||
assertion.g.THelper()
|
||||
return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...)
|
||||
return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, false, optionalDescription...)
|
||||
}
|
||||
|
||||
func (assertion *Assertion) buildDescription(optionalDescription ...interface{}) string {
|
||||
@ -61,7 +81,8 @@ func (assertion *Assertion) buildDescription(optionalDescription ...interface{})
|
||||
}
|
||||
|
||||
func (assertion *Assertion) match(matcher types.GomegaMatcher, desiredMatch bool, optionalDescription ...interface{}) bool {
|
||||
matches, err := matcher.Match(assertion.actualInput)
|
||||
actualInput := assertion.actuals[assertion.actualIndex]
|
||||
matches, err := matcher.Match(actualInput)
|
||||
assertion.g.THelper()
|
||||
if err != nil {
|
||||
description := assertion.buildDescription(optionalDescription...)
|
||||
@ -71,9 +92,9 @@ func (assertion *Assertion) match(matcher types.GomegaMatcher, desiredMatch bool
|
||||
if matches != desiredMatch {
|
||||
var message string
|
||||
if desiredMatch {
|
||||
message = matcher.FailureMessage(assertion.actualInput)
|
||||
message = matcher.FailureMessage(actualInput)
|
||||
} else {
|
||||
message = matcher.NegatedFailureMessage(assertion.actualInput)
|
||||
message = matcher.NegatedFailureMessage(actualInput)
|
||||
}
|
||||
description := assertion.buildDescription(optionalDescription...)
|
||||
assertion.g.Fail(description+message, 2+assertion.offset)
|
||||
@ -83,8 +104,11 @@ func (assertion *Assertion) match(matcher types.GomegaMatcher, desiredMatch bool
|
||||
return true
|
||||
}
|
||||
|
||||
func (assertion *Assertion) vetExtras(optionalDescription ...interface{}) bool {
|
||||
success, message := vetExtras(assertion.extra)
|
||||
// vetActuals vets the actual values, with the (optional) exception of a
|
||||
// specific value, such as the first value in case non-error assertions, or the
|
||||
// last value in case of Error()-based assertions.
|
||||
func (assertion *Assertion) vetActuals(optionalDescription ...interface{}) bool {
|
||||
success, message := vetActuals(assertion.actuals, assertion.actualIndex)
|
||||
if success {
|
||||
return true
|
||||
}
|
||||
@ -95,12 +119,29 @@ func (assertion *Assertion) vetExtras(optionalDescription ...interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func vetExtras(extras []interface{}) (bool, string) {
|
||||
for i, extra := range extras {
|
||||
if extra != nil {
|
||||
zeroValue := reflect.Zero(reflect.TypeOf(extra)).Interface()
|
||||
if !reflect.DeepEqual(zeroValue, extra) {
|
||||
message := fmt.Sprintf("Unexpected non-nil/non-zero extra argument at index %d:\n\t<%T>: %#v", i+1, extra, extra)
|
||||
// vetError vets the actual values, except for the final error value, in case
|
||||
// the final error value is non-zero. Otherwise, it doesn't vet the actual
|
||||
// values, as these are allowed to take on any values unless there is a non-zero
|
||||
// error value.
|
||||
func (assertion *Assertion) vetError(optionalDescription ...interface{}) bool {
|
||||
if err := assertion.actuals[assertion.actualIndex]; err != nil {
|
||||
// Go error result idiom: all other actual values must be zero values.
|
||||
return assertion.vetActuals(optionalDescription...)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// vetActuals vets a slice of actual values, optionally skipping a particular
|
||||
// value slice element, such as the first or last value slice element.
|
||||
func vetActuals(actuals []interface{}, skipIndex int) (bool, string) {
|
||||
for i, actual := range actuals {
|
||||
if i == skipIndex {
|
||||
continue
|
||||
}
|
||||
if actual != nil {
|
||||
zeroValue := reflect.Zero(reflect.TypeOf(actual)).Interface()
|
||||
if !reflect.DeepEqual(zeroValue, actual) {
|
||||
message := fmt.Sprintf("Unexpected non-nil/non-zero argument at index %d:\n\t<%T>: %#v", i, actual, actual)
|
||||
return false, message
|
||||
}
|
||||
}
|
||||
|
19
vendor/github.com/onsi/gomega/internal/async_assertion.go
generated
vendored
19
vendor/github.com/onsi/gomega/internal/async_assertion.go
generated
vendored
@ -87,6 +87,21 @@ func NewAsyncAssertion(asyncType AsyncAssertionType, actualInput interface{}, g
|
||||
return out
|
||||
}
|
||||
|
||||
func (assertion *AsyncAssertion) WithOffset(offset int) types.AsyncAssertion {
|
||||
assertion.offset = offset
|
||||
return assertion
|
||||
}
|
||||
|
||||
func (assertion *AsyncAssertion) WithTimeout(interval time.Duration) types.AsyncAssertion {
|
||||
assertion.timeoutInterval = interval
|
||||
return assertion
|
||||
}
|
||||
|
||||
func (assertion *AsyncAssertion) WithPolling(interval time.Duration) types.AsyncAssertion {
|
||||
assertion.pollingInterval = interval
|
||||
return assertion
|
||||
}
|
||||
|
||||
func (assertion *AsyncAssertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
|
||||
assertion.g.THelper()
|
||||
return assertion.match(matcher, true, optionalDescription...)
|
||||
@ -118,11 +133,11 @@ func (assertion *AsyncAssertion) pollActual() (interface{}, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
extras := []interface{}{}
|
||||
extras := []interface{}{nil}
|
||||
for _, value := range values[1:] {
|
||||
extras = append(extras, value.Interface())
|
||||
}
|
||||
success, message := vetExtras(extras)
|
||||
success, message := vetActuals(extras, 0)
|
||||
if !success {
|
||||
return nil, errors.New(message)
|
||||
}
|
||||
|
8
vendor/github.com/onsi/gomega/internal/gomega.go
generated
vendored
8
vendor/github.com/onsi/gomega/internal/gomega.go
generated
vendored
@ -39,12 +39,12 @@ func (g *Gomega) ConfigureWithT(t types.GomegaTestingT) *Gomega {
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *Gomega) Ω(atual interface{}, extra ...interface{}) types.Assertion {
|
||||
return g.ExpectWithOffset(0, atual, extra...)
|
||||
func (g *Gomega) Ω(actual interface{}, extra ...interface{}) types.Assertion {
|
||||
return g.ExpectWithOffset(0, actual, extra...)
|
||||
}
|
||||
|
||||
func (g *Gomega) Expect(atual interface{}, extra ...interface{}) types.Assertion {
|
||||
return g.ExpectWithOffset(0, atual, extra...)
|
||||
func (g *Gomega) Expect(actual interface{}, extra ...interface{}) types.Assertion {
|
||||
return g.ExpectWithOffset(0, actual, extra...)
|
||||
}
|
||||
|
||||
func (g *Gomega) ExpectWithOffset(offset int, actual interface{}, extra ...interface{}) types.Assertion {
|
||||
|
56
vendor/github.com/onsi/gomega/matchers.go
generated
vendored
56
vendor/github.com/onsi/gomega/matchers.go
generated
vendored
@ -342,6 +342,34 @@ func HaveKeyWithValue(key interface{}, value interface{}) types.GomegaMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
//HaveField succeeds if actual is a struct and the value at the passed in field
|
||||
//matches the passed in matcher. By default HaveField used Equal() to perform the match,
|
||||
//however a matcher can be passed in in stead.
|
||||
//
|
||||
//The field must be a string that resolves to the name of a field in the struct. Structs can be traversed
|
||||
//using the '.' delimiter. If the field ends with '()' a method named field is assumed to exist on the struct and is invoked.
|
||||
//Such methods must take no arguments and return a single value:
|
||||
//
|
||||
// type Book struct {
|
||||
// Title string
|
||||
// Author Person
|
||||
// }
|
||||
// type Person struct {
|
||||
// FirstName string
|
||||
// LastName string
|
||||
// DOB time.Time
|
||||
// }
|
||||
// Expect(book).To(HaveField("Title", "Les Miserables"))
|
||||
// Expect(book).To(HaveField("Title", ContainSubstring("Les"))
|
||||
// Expect(book).To(HaveField("Person.FirstName", Equal("Victor"))
|
||||
// Expect(book).To(HaveField("Person.DOB.Year()", BeNumerically("<", 1900))
|
||||
func HaveField(field string, expected interface{}) types.GomegaMatcher {
|
||||
return &matchers.HaveFieldMatcher{
|
||||
Field: field,
|
||||
Expected: expected,
|
||||
}
|
||||
}
|
||||
|
||||
//BeNumerically performs numerical assertions in a type-agnostic way.
|
||||
//Actual and expected should be numbers, though the specific type of
|
||||
//number is irrelevant (float32, float64, uint8, etc...).
|
||||
@ -423,10 +451,29 @@ func BeADirectory() types.GomegaMatcher {
|
||||
//Expected must be either an int or a string.
|
||||
// Expect(resp).Should(HaveHTTPStatus(http.StatusOK)) // asserts that resp.StatusCode == 200
|
||||
// Expect(resp).Should(HaveHTTPStatus("404 Not Found")) // asserts that resp.Status == "404 Not Found"
|
||||
func HaveHTTPStatus(expected interface{}) types.GomegaMatcher {
|
||||
// Expect(resp).Should(HaveHTTPStatus(http.StatusOK, http.StatusNoContent)) // asserts that resp.StatusCode == 200 || resp.StatusCode == 204
|
||||
func HaveHTTPStatus(expected ...interface{}) types.GomegaMatcher {
|
||||
return &matchers.HaveHTTPStatusMatcher{Expected: expected}
|
||||
}
|
||||
|
||||
// HaveHTTPHeaderWithValue succeeds if the header is found and the value matches.
|
||||
// Actual must be either a *http.Response or *httptest.ResponseRecorder.
|
||||
// Expected must be a string header name, followed by a header value which
|
||||
// can be a string, or another matcher.
|
||||
func HaveHTTPHeaderWithValue(header string, value interface{}) types.GomegaMatcher {
|
||||
return &matchers.HaveHTTPHeaderWithValueMatcher{
|
||||
Header: header,
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
// HaveHTTPBody matches if the body matches.
|
||||
// Actual must be either a *http.Response or *httptest.ResponseRecorder.
|
||||
// Expected must be either a string, []byte, or other matcher
|
||||
func HaveHTTPBody(expected interface{}) types.GomegaMatcher {
|
||||
return &matchers.HaveHTTPBodyMatcher{Expected: expected}
|
||||
}
|
||||
|
||||
//And succeeds only if all of the given matchers succeed.
|
||||
//The matchers are tried in order, and will fail-fast if one doesn't succeed.
|
||||
// Expect("hi").To(And(HaveLen(2), Equal("hi"))
|
||||
@ -466,10 +513,15 @@ func Not(matcher types.GomegaMatcher) types.GomegaMatcher {
|
||||
}
|
||||
|
||||
//WithTransform applies the `transform` to the actual value and matches it against `matcher`.
|
||||
//The given transform must be a function of one parameter that returns one value.
|
||||
//The given transform must be either a function of one parameter that returns one value or a
|
||||
// function of one parameter that returns two values, where the second value must be of the
|
||||
// error type.
|
||||
// var plus1 = func(i int) int { return i + 1 }
|
||||
// Expect(1).To(WithTransform(plus1, Equal(2))
|
||||
//
|
||||
// var failingplus1 = func(i int) (int, error) { return 42, "this does not compute" }
|
||||
// Expect(1).To(WithTransform(failingplus1, Equal(2)))
|
||||
//
|
||||
//And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions.
|
||||
func WithTransform(transform interface{}, matcher types.GomegaMatcher) types.GomegaMatcher {
|
||||
return matchers.NewWithTransformMatcher(transform, matcher)
|
||||
|
80
vendor/github.com/onsi/gomega/matchers/have_field.go
generated
vendored
Normal file
80
vendor/github.com/onsi/gomega/matchers/have_field.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
package matchers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/onsi/gomega/format"
|
||||
)
|
||||
|
||||
func extractField(actual interface{}, field string) (interface{}, error) {
|
||||
fields := strings.SplitN(field, ".", 2)
|
||||
actualValue := reflect.ValueOf(actual)
|
||||
|
||||
if actualValue.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("HaveField encountered:\n%s\nWhich is not a struct.", format.Object(actual, 1))
|
||||
}
|
||||
|
||||
var extractedValue reflect.Value
|
||||
|
||||
if strings.HasSuffix(fields[0], "()") {
|
||||
extractedValue = actualValue.MethodByName(strings.TrimSuffix(fields[0], "()"))
|
||||
if extractedValue == (reflect.Value{}) {
|
||||
return nil, fmt.Errorf("HaveField could not find method named '%s' in struct of type %T.", fields[0], actual)
|
||||
}
|
||||
t := extractedValue.Type()
|
||||
if t.NumIn() != 0 || t.NumOut() != 1 {
|
||||
return nil, fmt.Errorf("HaveField found an invalid method named '%s' in struct of type %T.\nMethods must take no arguments and return exactly one value.", fields[0], actual)
|
||||
}
|
||||
extractedValue = extractedValue.Call([]reflect.Value{})[0]
|
||||
} else {
|
||||
extractedValue = actualValue.FieldByName(fields[0])
|
||||
if extractedValue == (reflect.Value{}) {
|
||||
return nil, fmt.Errorf("HaveField could not find field named '%s' in struct:\n%s", fields[0], format.Object(actual, 1))
|
||||
}
|
||||
}
|
||||
|
||||
if len(fields) == 1 {
|
||||
return extractedValue.Interface(), nil
|
||||
} else {
|
||||
return extractField(extractedValue.Interface(), fields[1])
|
||||
}
|
||||
}
|
||||
|
||||
type HaveFieldMatcher struct {
|
||||
Field string
|
||||
Expected interface{}
|
||||
|
||||
extractedField interface{}
|
||||
expectedMatcher omegaMatcher
|
||||
}
|
||||
|
||||
func (matcher *HaveFieldMatcher) Match(actual interface{}) (success bool, err error) {
|
||||
matcher.extractedField, err = extractField(actual, matcher.Field)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
var isMatcher bool
|
||||
matcher.expectedMatcher, isMatcher = matcher.Expected.(omegaMatcher)
|
||||
if !isMatcher {
|
||||
matcher.expectedMatcher = &EqualMatcher{Expected: matcher.Expected}
|
||||
}
|
||||
|
||||
return matcher.expectedMatcher.Match(matcher.extractedField)
|
||||
}
|
||||
|
||||
func (matcher *HaveFieldMatcher) FailureMessage(actual interface{}) (message string) {
|
||||
message = fmt.Sprintf("Value for field '%s' failed to satisfy matcher.\n", matcher.Field)
|
||||
message += matcher.expectedMatcher.FailureMessage(matcher.extractedField)
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
func (matcher *HaveFieldMatcher) NegatedFailureMessage(actual interface{}) (message string) {
|
||||
message = fmt.Sprintf("Value for field '%s' satisfied matcher, but should not have.\n", matcher.Field)
|
||||
message += matcher.expectedMatcher.NegatedFailureMessage(matcher.extractedField)
|
||||
|
||||
return message
|
||||
}
|
101
vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go
generated
vendored
Normal file
101
vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go
generated
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
package matchers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
||||
"github.com/onsi/gomega/format"
|
||||
"github.com/onsi/gomega/types"
|
||||
)
|
||||
|
||||
type HaveHTTPBodyMatcher struct {
|
||||
Expected interface{}
|
||||
cachedBody []byte
|
||||
}
|
||||
|
||||
func (matcher *HaveHTTPBodyMatcher) Match(actual interface{}) (bool, error) {
|
||||
body, err := matcher.body(actual)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
switch e := matcher.Expected.(type) {
|
||||
case string:
|
||||
return (&EqualMatcher{Expected: e}).Match(string(body))
|
||||
case []byte:
|
||||
return (&EqualMatcher{Expected: e}).Match(body)
|
||||
case types.GomegaMatcher:
|
||||
return e.Match(body)
|
||||
default:
|
||||
return false, fmt.Errorf("HaveHTTPBody matcher expects string, []byte, or GomegaMatcher. Got:\n%s", format.Object(matcher.Expected, 1))
|
||||
}
|
||||
}
|
||||
|
||||
func (matcher *HaveHTTPBodyMatcher) FailureMessage(actual interface{}) (message string) {
|
||||
body, err := matcher.body(actual)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("failed to read body: %s", err)
|
||||
}
|
||||
|
||||
switch e := matcher.Expected.(type) {
|
||||
case string:
|
||||
return (&EqualMatcher{Expected: e}).FailureMessage(string(body))
|
||||
case []byte:
|
||||
return (&EqualMatcher{Expected: e}).FailureMessage(body)
|
||||
case types.GomegaMatcher:
|
||||
return e.FailureMessage(body)
|
||||
default:
|
||||
return fmt.Sprintf("HaveHTTPBody matcher expects string, []byte, or GomegaMatcher. Got:\n%s", format.Object(matcher.Expected, 1))
|
||||
}
|
||||
}
|
||||
|
||||
func (matcher *HaveHTTPBodyMatcher) NegatedFailureMessage(actual interface{}) (message string) {
|
||||
body, err := matcher.body(actual)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("failed to read body: %s", err)
|
||||
}
|
||||
|
||||
switch e := matcher.Expected.(type) {
|
||||
case string:
|
||||
return (&EqualMatcher{Expected: e}).NegatedFailureMessage(string(body))
|
||||
case []byte:
|
||||
return (&EqualMatcher{Expected: e}).NegatedFailureMessage(body)
|
||||
case types.GomegaMatcher:
|
||||
return e.NegatedFailureMessage(body)
|
||||
default:
|
||||
return fmt.Sprintf("HaveHTTPBody matcher expects string, []byte, or GomegaMatcher. Got:\n%s", format.Object(matcher.Expected, 1))
|
||||
}
|
||||
}
|
||||
|
||||
// body returns the body. It is cached because once we read it in Match()
|
||||
// the Reader is closed and it is not readable again in FailureMessage()
|
||||
// or NegatedFailureMessage()
|
||||
func (matcher *HaveHTTPBodyMatcher) body(actual interface{}) ([]byte, error) {
|
||||
if matcher.cachedBody != nil {
|
||||
return matcher.cachedBody, nil
|
||||
}
|
||||
|
||||
body := func(a *http.Response) ([]byte, error) {
|
||||
if a.Body != nil {
|
||||
defer a.Body.Close()
|
||||
var err error
|
||||
matcher.cachedBody, err = io.ReadAll(a.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading response body: %w", err)
|
||||
}
|
||||
}
|
||||
return matcher.cachedBody, nil
|
||||
}
|
||||
|
||||
switch a := actual.(type) {
|
||||
case *http.Response:
|
||||
return body(a)
|
||||
case *httptest.ResponseRecorder:
|
||||
return body(a.Result())
|
||||
default:
|
||||
return nil, fmt.Errorf("HaveHTTPBody matcher expects *http.Response or *httptest.ResponseRecorder. Got:\n%s", format.Object(actual, 1))
|
||||
}
|
||||
|
||||
}
|
81
vendor/github.com/onsi/gomega/matchers/have_http_header_with_value_matcher.go
generated
vendored
Normal file
81
vendor/github.com/onsi/gomega/matchers/have_http_header_with_value_matcher.go
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
package matchers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
||||
"github.com/onsi/gomega/format"
|
||||
"github.com/onsi/gomega/types"
|
||||
)
|
||||
|
||||
type HaveHTTPHeaderWithValueMatcher struct {
|
||||
Header string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
func (matcher *HaveHTTPHeaderWithValueMatcher) Match(actual interface{}) (success bool, err error) {
|
||||
headerValue, err := matcher.extractHeader(actual)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
headerMatcher, err := matcher.getSubMatcher()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return headerMatcher.Match(headerValue)
|
||||
}
|
||||
|
||||
func (matcher *HaveHTTPHeaderWithValueMatcher) FailureMessage(actual interface{}) string {
|
||||
headerValue, err := matcher.extractHeader(actual)
|
||||
if err != nil {
|
||||
panic(err) // protected by Match()
|
||||
}
|
||||
|
||||
headerMatcher, err := matcher.getSubMatcher()
|
||||
if err != nil {
|
||||
panic(err) // protected by Match()
|
||||
}
|
||||
|
||||
diff := format.IndentString(headerMatcher.FailureMessage(headerValue), 1)
|
||||
return fmt.Sprintf("HTTP header %q:\n%s", matcher.Header, diff)
|
||||
}
|
||||
|
||||
func (matcher *HaveHTTPHeaderWithValueMatcher) NegatedFailureMessage(actual interface{}) (message string) {
|
||||
headerValue, err := matcher.extractHeader(actual)
|
||||
if err != nil {
|
||||
panic(err) // protected by Match()
|
||||
}
|
||||
|
||||
headerMatcher, err := matcher.getSubMatcher()
|
||||
if err != nil {
|
||||
panic(err) // protected by Match()
|
||||
}
|
||||
|
||||
diff := format.IndentString(headerMatcher.NegatedFailureMessage(headerValue), 1)
|
||||
return fmt.Sprintf("HTTP header %q:\n%s", matcher.Header, diff)
|
||||
}
|
||||
|
||||
func (matcher *HaveHTTPHeaderWithValueMatcher) getSubMatcher() (types.GomegaMatcher, error) {
|
||||
switch m := matcher.Value.(type) {
|
||||
case string:
|
||||
return &EqualMatcher{Expected: matcher.Value}, nil
|
||||
case types.GomegaMatcher:
|
||||
return m, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("HaveHTTPHeaderWithValue matcher must be passed a string or a GomegaMatcher. Got:\n%s", format.Object(matcher.Value, 1))
|
||||
}
|
||||
}
|
||||
|
||||
func (matcher *HaveHTTPHeaderWithValueMatcher) extractHeader(actual interface{}) (string, error) {
|
||||
switch r := actual.(type) {
|
||||
case *http.Response:
|
||||
return r.Header.Get(matcher.Header), nil
|
||||
case *httptest.ResponseRecorder:
|
||||
return r.Result().Header.Get(matcher.Header), nil
|
||||
default:
|
||||
return "", fmt.Errorf("HaveHTTPHeaderWithValue matcher expects *http.Response or *httptest.ResponseRecorder. Got:\n%s", format.Object(actual, 1))
|
||||
}
|
||||
}
|
72
vendor/github.com/onsi/gomega/matchers/have_http_status_matcher.go
generated
vendored
72
vendor/github.com/onsi/gomega/matchers/have_http_status_matcher.go
generated
vendored
@ -2,14 +2,17 @@ package matchers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/onsi/gomega/format"
|
||||
)
|
||||
|
||||
type HaveHTTPStatusMatcher struct {
|
||||
Expected interface{}
|
||||
Expected []interface{}
|
||||
}
|
||||
|
||||
func (matcher *HaveHTTPStatusMatcher) Match(actual interface{}) (success bool, err error) {
|
||||
@ -23,20 +26,71 @@ func (matcher *HaveHTTPStatusMatcher) Match(actual interface{}) (success bool, e
|
||||
return false, fmt.Errorf("HaveHTTPStatus matcher expects *http.Response or *httptest.ResponseRecorder. Got:\n%s", format.Object(actual, 1))
|
||||
}
|
||||
|
||||
switch e := matcher.Expected.(type) {
|
||||
case int:
|
||||
return resp.StatusCode == e, nil
|
||||
case string:
|
||||
return resp.Status == e, nil
|
||||
if len(matcher.Expected) == 0 {
|
||||
return false, fmt.Errorf("HaveHTTPStatus matcher must be passed an int or a string. Got nothing")
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("HaveHTTPStatus matcher must be passed an int or a string. Got:\n%s", format.Object(matcher.Expected, 1))
|
||||
for _, expected := range matcher.Expected {
|
||||
switch e := expected.(type) {
|
||||
case int:
|
||||
if resp.StatusCode == e {
|
||||
return true, nil
|
||||
}
|
||||
case string:
|
||||
if resp.Status == e {
|
||||
return true, nil
|
||||
}
|
||||
default:
|
||||
return false, fmt.Errorf("HaveHTTPStatus matcher must be passed int or string types. Got:\n%s", format.Object(expected, 1))
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (matcher *HaveHTTPStatusMatcher) FailureMessage(actual interface{}) (message string) {
|
||||
return format.Message(actual, "to have HTTP status", matcher.Expected)
|
||||
return fmt.Sprintf("Expected\n%s\n%s\n%s", formatHttpResponse(actual), "to have HTTP status", matcher.expectedString())
|
||||
}
|
||||
|
||||
func (matcher *HaveHTTPStatusMatcher) NegatedFailureMessage(actual interface{}) (message string) {
|
||||
return format.Message(actual, "not to have HTTP status", matcher.Expected)
|
||||
return fmt.Sprintf("Expected\n%s\n%s\n%s", formatHttpResponse(actual), "not to have HTTP status", matcher.expectedString())
|
||||
}
|
||||
|
||||
func (matcher *HaveHTTPStatusMatcher) expectedString() string {
|
||||
var lines []string
|
||||
for _, expected := range matcher.Expected {
|
||||
lines = append(lines, format.Object(expected, 1))
|
||||
}
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
func formatHttpResponse(input interface{}) string {
|
||||
var resp *http.Response
|
||||
switch r := input.(type) {
|
||||
case *http.Response:
|
||||
resp = r
|
||||
case *httptest.ResponseRecorder:
|
||||
resp = r.Result()
|
||||
default:
|
||||
return "cannot format invalid HTTP response"
|
||||
}
|
||||
|
||||
body := "<nil>"
|
||||
if resp.Body != nil {
|
||||
defer resp.Body.Close()
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
data = []byte("<error reading body>")
|
||||
}
|
||||
body = format.Object(string(data), 0)
|
||||
}
|
||||
|
||||
var s strings.Builder
|
||||
s.WriteString(fmt.Sprintf("%s<%s>: {\n", format.Indent, reflect.TypeOf(input)))
|
||||
s.WriteString(fmt.Sprintf("%s%sStatus: %s\n", format.Indent, format.Indent, format.Object(resp.Status, 0)))
|
||||
s.WriteString(fmt.Sprintf("%s%sStatusCode: %s\n", format.Indent, format.Indent, format.Object(resp.StatusCode, 0)))
|
||||
s.WriteString(fmt.Sprintf("%s%sBody: %s\n", format.Indent, format.Indent, body))
|
||||
s.WriteString(fmt.Sprintf("%s}", format.Indent))
|
||||
|
||||
return s.String()
|
||||
}
|
||||
|
16
vendor/github.com/onsi/gomega/matchers/with_transform.go
generated
vendored
16
vendor/github.com/onsi/gomega/matchers/with_transform.go
generated
vendored
@ -9,7 +9,7 @@ import (
|
||||
|
||||
type WithTransformMatcher struct {
|
||||
// input
|
||||
Transform interface{} // must be a function of one parameter that returns one value
|
||||
Transform interface{} // must be a function of one parameter that returns one value and an optional error
|
||||
Matcher types.GomegaMatcher
|
||||
|
||||
// cached value
|
||||
@ -19,6 +19,9 @@ type WithTransformMatcher struct {
|
||||
transformedValue interface{}
|
||||
}
|
||||
|
||||
// reflect.Type for error
|
||||
var errorT = reflect.TypeOf((*error)(nil)).Elem()
|
||||
|
||||
func NewWithTransformMatcher(transform interface{}, matcher types.GomegaMatcher) *WithTransformMatcher {
|
||||
if transform == nil {
|
||||
panic("transform function cannot be nil")
|
||||
@ -27,8 +30,10 @@ func NewWithTransformMatcher(transform interface{}, matcher types.GomegaMatcher)
|
||||
if txType.NumIn() != 1 {
|
||||
panic("transform function must have 1 argument")
|
||||
}
|
||||
if txType.NumOut() != 1 {
|
||||
panic("transform function must have 1 return value")
|
||||
if numout := txType.NumOut(); numout != 1 {
|
||||
if numout != 2 || !txType.Out(1).AssignableTo(errorT) {
|
||||
panic("transform function must either have 1 return value, or 1 return value plus 1 error value")
|
||||
}
|
||||
}
|
||||
|
||||
return &WithTransformMatcher{
|
||||
@ -57,6 +62,11 @@ func (m *WithTransformMatcher) Match(actual interface{}) (bool, error) {
|
||||
// call the Transform function with `actual`
|
||||
fn := reflect.ValueOf(m.Transform)
|
||||
result := fn.Call([]reflect.Value{param})
|
||||
if len(result) == 2 {
|
||||
if !result[1].IsNil() {
|
||||
return false, fmt.Errorf("Transform function failed: %s", result[1].Interface().(error).Error())
|
||||
}
|
||||
}
|
||||
m.transformedValue = result[0].Interface() // expect exactly one value
|
||||
|
||||
return m.Matcher.Match(m.transformedValue)
|
||||
|
8
vendor/github.com/onsi/gomega/types/types.go
generated
vendored
8
vendor/github.com/onsi/gomega/types/types.go
generated
vendored
@ -66,6 +66,10 @@ func MatchMayChangeInTheFuture(matcher GomegaMatcher, value interface{}) bool {
|
||||
type AsyncAssertion interface {
|
||||
Should(matcher GomegaMatcher, optionalDescription ...interface{}) bool
|
||||
ShouldNot(matcher GomegaMatcher, optionalDescription ...interface{}) bool
|
||||
|
||||
WithOffset(offset int) AsyncAssertion
|
||||
WithTimeout(interval time.Duration) AsyncAssertion
|
||||
WithPolling(interval time.Duration) AsyncAssertion
|
||||
}
|
||||
|
||||
// Assertions are returned by Ω and Expect and enable assertions against Gomega matchers
|
||||
@ -76,4 +80,8 @@ type Assertion interface {
|
||||
To(matcher GomegaMatcher, optionalDescription ...interface{}) bool
|
||||
ToNot(matcher GomegaMatcher, optionalDescription ...interface{}) bool
|
||||
NotTo(matcher GomegaMatcher, optionalDescription ...interface{}) bool
|
||||
|
||||
WithOffset(offset int) Assertion
|
||||
|
||||
Error() Assertion
|
||||
}
|
||||
|
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
@ -7,7 +7,7 @@ github.com/blang/semver
|
||||
# github.com/cespare/xxhash/v2 v2.1.2
|
||||
## explicit; go 1.11
|
||||
github.com/cespare/xxhash/v2
|
||||
# github.com/containernetworking/cni v1.0.1
|
||||
# github.com/containernetworking/cni v1.1.2
|
||||
## explicit; go 1.14
|
||||
github.com/containernetworking/cni/libcni
|
||||
github.com/containernetworking/cni/pkg/invoke
|
||||
@ -125,8 +125,8 @@ github.com/onsi/ginkgo/reporters/stenographer
|
||||
github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable
|
||||
github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty
|
||||
github.com/onsi/ginkgo/types
|
||||
# github.com/onsi/gomega v1.15.0
|
||||
## explicit; go 1.14
|
||||
# github.com/onsi/gomega v1.17.0
|
||||
## explicit; go 1.16
|
||||
github.com/onsi/gomega
|
||||
github.com/onsi/gomega/format
|
||||
github.com/onsi/gomega/internal
|
||||
|
Loading…
Reference in New Issue
Block a user