mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 10:51:29 +00:00
Merge pull request #113106 from pohly/dep-ginkgo-gomega
dependencies: update to gomega v1.22.1 and ginkgo v2.3.1
This commit is contained in:
commit
4216ad3542
8
go.mod
8
go.mod
@ -51,8 +51,8 @@ require (
|
|||||||
github.com/moby/ipvs v1.0.1
|
github.com/moby/ipvs v1.0.1
|
||||||
github.com/mrunalp/fileutils v0.5.0
|
github.com/mrunalp/fileutils v0.5.0
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0
|
github.com/onsi/ginkgo/v2 v2.3.1
|
||||||
github.com/onsi/gomega v1.20.1
|
github.com/onsi/gomega v1.22.1
|
||||||
github.com/opencontainers/runc v1.1.3
|
github.com/opencontainers/runc v1.1.3
|
||||||
github.com/opencontainers/selinux v1.10.0
|
github.com/opencontainers/selinux v1.10.0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
@ -424,8 +424,8 @@ replace (
|
|||||||
github.com/mxk/go-flowrate => github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
|
github.com/mxk/go-flowrate => github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
|
||||||
github.com/niemeyer/pretty => github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e
|
github.com/niemeyer/pretty => github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e
|
||||||
github.com/olekukonko/tablewriter => github.com/olekukonko/tablewriter v0.0.4
|
github.com/olekukonko/tablewriter => github.com/olekukonko/tablewriter v0.0.4
|
||||||
github.com/onsi/ginkgo/v2 => github.com/onsi/ginkgo/v2 v2.2.0
|
github.com/onsi/ginkgo/v2 => github.com/onsi/ginkgo/v2 v2.3.1
|
||||||
github.com/onsi/gomega => github.com/onsi/gomega v1.20.1
|
github.com/onsi/gomega => github.com/onsi/gomega v1.22.1
|
||||||
github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.0
|
github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.0
|
||||||
github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.0.2
|
github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.0.2
|
||||||
github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.3
|
github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.3
|
||||||
|
8
go.sum
8
go.sum
@ -306,10 +306,10 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J
|
|||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
github.com/onsi/ginkgo/v2 v2.3.1/go.mod h1:Sv4yQXwG5VmF7tm3Q5Z+RWUpPo24LF1mpnz2crUb8Ys=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
|
github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
|
||||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||||
|
@ -342,8 +342,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
|
|||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
@ -36,8 +36,8 @@ require (
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 // indirect
|
github.com/onsi/ginkgo/v2 v2.3.1 // indirect
|
||||||
github.com/onsi/gomega v1.20.1 // indirect
|
github.com/onsi/gomega v1.22.1 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect
|
||||||
|
8
staging/src/k8s.io/apimachinery/go.sum
generated
8
staging/src/k8s.io/apimachinery/go.sum
generated
@ -68,10 +68,10 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J
|
|||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
github.com/onsi/ginkgo/v2 v2.3.1/go.mod h1:Sv4yQXwG5VmF7tm3Q5Z+RWUpPo24LF1mpnz2crUb8Ys=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
|
github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
4
staging/src/k8s.io/apiserver/go.sum
generated
4
staging/src/k8s.io/apiserver/go.sum
generated
@ -369,8 +369,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
|
|||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
4
staging/src/k8s.io/client-go/go.sum
generated
4
staging/src/k8s.io/client-go/go.sum
generated
@ -169,8 +169,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
|||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
4
staging/src/k8s.io/cloud-provider/go.sum
generated
4
staging/src/k8s.io/cloud-provider/go.sum
generated
@ -263,8 +263,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
|
|||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
11
staging/src/k8s.io/code-generator/examples/go.sum
generated
11
staging/src/k8s.io/code-generator/examples/go.sum
generated
@ -192,14 +192,19 @@ github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
|||||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||||
github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
|
github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.3.1/go.mod h1:Sv4yQXwG5VmF7tm3Q5Z+RWUpPo24LF1mpnz2crUb8Ys=
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
|
||||||
github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
|
github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
|
||||||
|
github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
|
||||||
|
github.com/onsi/gomega v1.22.0/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
|
||||||
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
|
github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
@ -28,8 +28,8 @@ require (
|
|||||||
github.com/mailru/easyjson v0.7.6 // indirect
|
github.com/mailru/easyjson v0.7.6 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 // indirect
|
github.com/onsi/ginkgo/v2 v2.3.1 // indirect
|
||||||
github.com/onsi/gomega v1.20.1 // indirect
|
github.com/onsi/gomega v1.22.1 // indirect
|
||||||
github.com/stretchr/testify v1.8.0 // indirect
|
github.com/stretchr/testify v1.8.0 // indirect
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect
|
||||||
|
8
staging/src/k8s.io/code-generator/go.sum
generated
8
staging/src/k8s.io/code-generator/go.sum
generated
@ -73,10 +73,10 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
|
|||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
github.com/onsi/ginkgo/v2 v2.3.1/go.mod h1:Sv4yQXwG5VmF7tm3Q5Z+RWUpPo24LF1mpnz2crUb8Ys=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
|
github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
4
staging/src/k8s.io/component-base/go.sum
generated
4
staging/src/k8s.io/component-base/go.sum
generated
@ -238,8 +238,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
|
|||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
4
staging/src/k8s.io/component-helpers/go.sum
generated
4
staging/src/k8s.io/component-helpers/go.sum
generated
@ -155,8 +155,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
|||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
4
staging/src/k8s.io/controller-manager/go.sum
generated
4
staging/src/k8s.io/controller-manager/go.sum
generated
@ -256,8 +256,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
|
|||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
4
staging/src/k8s.io/kube-aggregator/go.sum
generated
4
staging/src/k8s.io/kube-aggregator/go.sum
generated
@ -260,8 +260,8 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J
|
|||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
@ -20,8 +20,8 @@ require (
|
|||||||
github.com/lithammer/dedent v1.1.0
|
github.com/lithammer/dedent v1.1.0
|
||||||
github.com/mitchellh/go-wordwrap v1.0.0
|
github.com/mitchellh/go-wordwrap v1.0.0
|
||||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6
|
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0
|
github.com/onsi/ginkgo/v2 v2.3.1
|
||||||
github.com/onsi/gomega v1.20.1
|
github.com/onsi/gomega v1.22.1
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/russross/blackfriday/v2 v2.1.0
|
github.com/russross/blackfriday/v2 v2.1.0
|
||||||
github.com/spf13/cobra v1.6.0
|
github.com/spf13/cobra v1.6.0
|
||||||
|
8
staging/src/k8s.io/kubectl/go.sum
generated
8
staging/src/k8s.io/kubectl/go.sum
generated
@ -211,10 +211,10 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J
|
|||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
github.com/onsi/ginkgo/v2 v2.3.1/go.mod h1:Sv4yQXwG5VmF7tm3Q5Z+RWUpPo24LF1mpnz2crUb8Ys=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
|
github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
|
||||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||||
|
4
staging/src/k8s.io/legacy-cloud-providers/go.sum
generated
4
staging/src/k8s.io/legacy-cloud-providers/go.sum
generated
@ -289,8 +289,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
|
|||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
4
staging/src/k8s.io/metrics/go.sum
generated
4
staging/src/k8s.io/metrics/go.sum
generated
@ -155,8 +155,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
|||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
4
staging/src/k8s.io/pod-security-admission/go.sum
generated
4
staging/src/k8s.io/pod-security-admission/go.sum
generated
@ -259,8 +259,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
|
|||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
4
staging/src/k8s.io/sample-apiserver/go.sum
generated
4
staging/src/k8s.io/sample-apiserver/go.sum
generated
@ -258,8 +258,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
|
|||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
4
staging/src/k8s.io/sample-controller/go.sum
generated
4
staging/src/k8s.io/sample-controller/go.sum
generated
@ -160,8 +160,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
|||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
|
||||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
@ -128,15 +128,15 @@ INFO: after #1
|
|||||||
[AfterEach] e2e
|
[AfterEach] e2e
|
||||||
cleanup_test.go:76
|
cleanup_test.go:76
|
||||||
INFO: after #2
|
INFO: after #2
|
||||||
[DeferCleanup] e2e
|
[DeferCleanup (Each)] e2e
|
||||||
cleanup_test.go:85
|
cleanup_test.go:85
|
||||||
INFO: cleanup first
|
INFO: cleanup first
|
||||||
[DeferCleanup] e2e
|
[DeferCleanup (Each)] e2e
|
||||||
cleanup_test.go:82
|
cleanup_test.go:82
|
||||||
INFO: cleanup last
|
INFO: cleanup last
|
||||||
[DeferCleanup] e2e
|
[DeferCleanup (Each)] e2e
|
||||||
dump namespaces | framework.go:xxx
|
dump namespaces | framework.go:xxx
|
||||||
[DeferCleanup] e2e
|
[DeferCleanup (Each)] e2e
|
||||||
tear down framework | framework.go:xxx
|
tear down framework | framework.go:xxx
|
||||||
STEP: Destroying namespace "test-namespace-zzz" for this suite.
|
STEP: Destroying namespace "test-namespace-zzz" for this suite.
|
||||||
`
|
`
|
||||||
|
49
vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
generated
vendored
49
vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
generated
vendored
@ -1,3 +1,52 @@
|
|||||||
|
## 2.3.1
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
Several users were invoking `ginkgo` by installing the latest version of the cli via `go install github.com/onsi/ginkgo/v2/ginkgo@latest`. When 2.3.0 was released this resulted in an influx of issues as CI systems failed due to a change in the internal contract between the Ginkgo CLI and the Ginkgo library. Ginkgo only supports running the same version of the library as the cli (which is why both are packaged in the same repository).
|
||||||
|
|
||||||
|
With this patch release, the ginkgo CLI can now identify a version mismatch and emit a helpful error message.
|
||||||
|
|
||||||
|
- Ginkgo cli can identify version mismatches and emit a helpful error message [bc4ae2f]
|
||||||
|
- further emphasize that a version match is required when running Ginkgo on CI and/or locally [2691dd8]
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
- bump gomega to v1.22.0 [822a937]
|
||||||
|
|
||||||
|
## 2.3.0
|
||||||
|
|
||||||
|
### Interruptible Nodes and Timeouts
|
||||||
|
|
||||||
|
Ginkgo now supports per-node and per-spec timeouts on interruptible nodes. Check out the [documentation for all the details](https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes) but the gist is you can now write specs like this:
|
||||||
|
|
||||||
|
```go
|
||||||
|
It("is interruptible", func(ctx SpecContext) { // or context.Context instead of SpecContext, both are valid.
|
||||||
|
// do things until `ctx.Done()` is closed, for example:
|
||||||
|
req, err := http.NewRequestWithContext(ctx, "POST", "/build-widgets", nil)
|
||||||
|
Expect(err).NotTo(HaveOccured())
|
||||||
|
_, err := http.DefaultClient.Do(req)
|
||||||
|
Expect(err).NotTo(HaveOccured())
|
||||||
|
|
||||||
|
Eventually(client.WidgetCount).WithContext(ctx).Should(Equal(17))
|
||||||
|
}, NodeTimeout(time.Second*20), GracePeriod(5*time.Second))
|
||||||
|
```
|
||||||
|
|
||||||
|
and have Ginkgo ensure that the node completes before the timeout elapses. If it does elapse, or if an external interrupt is received (e.g. `^C`) then Ginkgo will cancel the context and wait for the Grace Period for the node to exit before proceeding with any cleanup nodes associated with the spec. The `ctx` provided by Ginkgo can also be passed down to Gomega's `Eventually` to have all assertions within the node governed by a single deadline.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- Ginkgo now records any additional failures that occur during the cleanup of a failed spec. In prior versions this information was quietly discarded, but the introduction of a more rigorous approach to timeouts and interruptions allows Ginkgo to better track subsequent failures.
|
||||||
|
- `SpecContext` also provides a mechanism for third-party libraries to provide additional information when a Progress Report is generated. Gomega uses this to provide the current state of an `Eventually().WithContext()` assertion when a Progress Report is requested.
|
||||||
|
- DescribeTable now exits with an error if it is not passed any Entries [a4c9865]
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
- fixes crashes on newer Ruby 3 installations by upgrading github-pages gem dependency [92c88d5]
|
||||||
|
- Make the outline command able to use the DSL import [1be2427]
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
- chore(docs): delete no meaning d [57c373c]
|
||||||
|
- chore(docs): Fix hyperlinks [30526d5]
|
||||||
|
- chore(docs): fix code blocks without language settings [cf611c4]
|
||||||
|
- fix intra-doc link [b541bcb]
|
||||||
|
|
||||||
## 2.2.0
|
## 2.2.0
|
||||||
|
|
||||||
### Generate real-time Progress Reports [f91377c]
|
### Generate real-time Progress Reports [f91377c]
|
||||||
|
8
vendor/github.com/onsi/ginkgo/v2/RELEASING.md
generated
vendored
8
vendor/github.com/onsi/ginkgo/v2/RELEASING.md
generated
vendored
@ -1,7 +1,13 @@
|
|||||||
A Ginkgo release is a tagged git sha and a GitHub release. To cut a release:
|
A Ginkgo release is a tagged git sha and a GitHub release. To cut a release:
|
||||||
|
|
||||||
1. Ensure CHANGELOG.md is up to date.
|
1. Ensure CHANGELOG.md is up to date.
|
||||||
- Use `git log --pretty=format:'- %s [%h]' HEAD...vX.X.X` to list all the commits since the last release
|
- Use
|
||||||
|
```bash
|
||||||
|
LAST_VERSION=$(git tag --sort=version:refname | tail -n1)
|
||||||
|
CHANGES=$(git log --pretty=format:'- %s [%h]' HEAD...$LAST_VERSION)
|
||||||
|
echo -e "## NEXT\n\n$CHANGES\n\n### Features\n\n## Fixes\n\n## Maintenance\n\n$(cat CHANGELOG.md)" > CHANGELOG.md
|
||||||
|
```
|
||||||
|
to update the changelog
|
||||||
- Categorize the changes into
|
- Categorize the changes into
|
||||||
- Breaking Changes (requires a major version)
|
- Breaking Changes (requires a major version)
|
||||||
- New Features (minor version)
|
- New Features (minor version)
|
||||||
|
77
vendor/github.com/onsi/ginkgo/v2/core_dsl.go
generated
vendored
77
vendor/github.com/onsi/ginkgo/v2/core_dsl.go
generated
vendored
@ -89,6 +89,15 @@ type GinkgoWriterInterface interface {
|
|||||||
ClearTeeWriters()
|
ClearTeeWriters()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
SpecContext is the context object passed into nodes that are subject to a timeout or need to be notified of an interrupt. It implements the standard context.Context interface but also contains additional helpers to provide an extensibility point for Ginkgo. (As an example, Gomega's Eventually can use the methods defined on SpecContext to provide deeper integratoin with Ginkgo).
|
||||||
|
|
||||||
|
You can do anything with SpecContext that you do with a typical context.Context including wrapping it with any of the context.With* methods.
|
||||||
|
|
||||||
|
Ginkgo will cancel the SpecContext when a node is interrupted (e.g. by the user sending an interupt signal) or when a node has exceeded it's allowed run-time. Note, however, that even in cases where a node has a deadline, SpecContext will not return a deadline via .Deadline(). This is because Ginkgo does not use a WithDeadline() context to model node deadlines as Ginkgo needs control over the precise timing of the context cancellation to ensure it can provide an accurate progress report at the moment of cancellation.
|
||||||
|
*/
|
||||||
|
type SpecContext = internal.SpecContext
|
||||||
|
|
||||||
/*
|
/*
|
||||||
GinkgoWriter implements a GinkgoWriterInterface and io.Writer
|
GinkgoWriter implements a GinkgoWriterInterface and io.Writer
|
||||||
|
|
||||||
@ -277,7 +286,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...interface{}) bool {
|
|||||||
suitePath, err = filepath.Abs(suitePath)
|
suitePath, err = filepath.Abs(suitePath)
|
||||||
exitIfErr(err)
|
exitIfErr(err)
|
||||||
|
|
||||||
passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(suiteConfig.Timeout, client), client, internal.RegisterForProgressSignal, suiteConfig)
|
passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
|
||||||
outputInterceptor.Shutdown()
|
outputInterceptor.Shutdown()
|
||||||
|
|
||||||
flagSet.ValidateDeprecations(deprecationTracker)
|
flagSet.ValidateDeprecations(deprecationTracker)
|
||||||
@ -444,6 +453,8 @@ It nodes are Subject nodes that contain your spec code and assertions.
|
|||||||
|
|
||||||
Each It node corresponds to an individual Ginkgo spec. You cannot nest any other Ginkgo nodes within an It node's closure.
|
Each It node corresponds to an individual Ginkgo spec. You cannot nest any other Ginkgo nodes within an It node's closure.
|
||||||
|
|
||||||
|
You can pass It nodes bare functions (func() {}) or functions that receive a SpecContext or context.Context: func(ctx SpecContext) {} and func (ctx context.Context) {}. If the function takes a context then the It is deemed interruptible and Ginkgo will cancel the context in the event of a timeout (configured via the SpecTimeout() or NodeTimeout() decorators) or of an interrupt signal.
|
||||||
|
|
||||||
You can learn more at https://onsi.github.io/ginkgo/#spec-subjects-it
|
You can learn more at https://onsi.github.io/ginkgo/#spec-subjects-it
|
||||||
In addition, subject nodes can be decorated with a variety of decorators. You can learn more here: https://onsi.github.io/ginkgo/#decorator-reference
|
In addition, subject nodes can be decorated with a variety of decorators. You can learn more here: https://onsi.github.io/ginkgo/#decorator-reference
|
||||||
*/
|
*/
|
||||||
@ -527,10 +538,12 @@ When running in parallel, each parallel process will call BeforeSuite.
|
|||||||
|
|
||||||
You may only register *one* BeforeSuite handler per test suite. You typically do so in your bootstrap file at the top level.
|
You may only register *one* BeforeSuite handler per test suite. You typically do so in your bootstrap file at the top level.
|
||||||
|
|
||||||
|
BeforeSuite can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body.
|
||||||
|
|
||||||
You cannot nest any other Ginkgo nodes within a BeforeSuite node's closure.
|
You cannot nest any other Ginkgo nodes within a BeforeSuite node's closure.
|
||||||
You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite
|
You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite
|
||||||
*/
|
*/
|
||||||
func BeforeSuite(body func(), args ...interface{}) bool {
|
func BeforeSuite(body interface{}, args ...interface{}) bool {
|
||||||
combinedArgs := []interface{}{body}
|
combinedArgs := []interface{}{body}
|
||||||
combinedArgs = append(combinedArgs, args...)
|
combinedArgs = append(combinedArgs, args...)
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeSuite, "", combinedArgs...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeSuite, "", combinedArgs...))
|
||||||
@ -544,10 +557,12 @@ When running in parallel, each parallel process will call AfterSuite.
|
|||||||
|
|
||||||
You may only register *one* AfterSuite handler per test suite. You typically do so in your bootstrap file at the top level.
|
You may only register *one* AfterSuite handler per test suite. You typically do so in your bootstrap file at the top level.
|
||||||
|
|
||||||
|
AfterSuite can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body.
|
||||||
|
|
||||||
You cannot nest any other Ginkgo nodes within an AfterSuite node's closure.
|
You cannot nest any other Ginkgo nodes within an AfterSuite node's closure.
|
||||||
You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite
|
You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite
|
||||||
*/
|
*/
|
||||||
func AfterSuite(body func(), args ...interface{}) bool {
|
func AfterSuite(body interface{}, args ...interface{}) bool {
|
||||||
combinedArgs := []interface{}{body}
|
combinedArgs := []interface{}{body}
|
||||||
combinedArgs = append(combinedArgs, args...)
|
combinedArgs = append(combinedArgs, args...)
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterSuite, "", combinedArgs...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterSuite, "", combinedArgs...))
|
||||||
@ -561,18 +576,30 @@ information from that setup to all parallel processes.
|
|||||||
SynchronizedBeforeSuite accomplishes this by taking *two* function arguments and passing data between them.
|
SynchronizedBeforeSuite accomplishes this by taking *two* function arguments and passing data between them.
|
||||||
The first function is only run on parallel process #1. The second is run on all processes, but *only* after the first function completes successfully. The functions have the following signatures:
|
The first function is only run on parallel process #1. The second is run on all processes, but *only* after the first function completes successfully. The functions have the following signatures:
|
||||||
|
|
||||||
The first function (which only runs on process #1) has the signature:
|
The first function (which only runs on process #1) can have any of the following the signatures:
|
||||||
|
|
||||||
|
func()
|
||||||
|
func(ctx context.Context)
|
||||||
|
func(ctx SpecContext)
|
||||||
func() []byte
|
func() []byte
|
||||||
|
func(ctx context.Context) []byte
|
||||||
|
func(ctx SpecContext) []byte
|
||||||
|
|
||||||
The byte array returned by the first function is then passed to the second function, which has the signature:
|
The byte array returned by the first function (if present) is then passed to the second function, which can have any of the following signature:
|
||||||
|
|
||||||
|
func()
|
||||||
|
func(ctx context.Context)
|
||||||
|
func(ctx SpecContext)
|
||||||
func(data []byte)
|
func(data []byte)
|
||||||
|
func(ctx context.Context, data []byte)
|
||||||
|
func(ctx SpecContext, data []byte)
|
||||||
|
|
||||||
|
If either function receives a context.Context/SpecContext it is considered interruptible.
|
||||||
|
|
||||||
You cannot nest any other Ginkgo nodes within an SynchronizedBeforeSuite node's closure.
|
You cannot nest any other Ginkgo nodes within an SynchronizedBeforeSuite node's closure.
|
||||||
You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite
|
You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite
|
||||||
*/
|
*/
|
||||||
func SynchronizedBeforeSuite(process1Body func() []byte, allProcessBody func([]byte), args ...interface{}) bool {
|
func SynchronizedBeforeSuite(process1Body interface{}, allProcessBody interface{}, args ...interface{}) bool {
|
||||||
combinedArgs := []interface{}{process1Body, allProcessBody}
|
combinedArgs := []interface{}{process1Body, allProcessBody}
|
||||||
combinedArgs = append(combinedArgs, args...)
|
combinedArgs = append(combinedArgs, args...)
|
||||||
|
|
||||||
@ -585,14 +612,14 @@ and a piece that must only run once - on process #1.
|
|||||||
|
|
||||||
SynchronizedAfterSuite accomplishes this by taking *two* function arguments. The first runs on all processes. The second runs only on parallel process #1
|
SynchronizedAfterSuite accomplishes this by taking *two* function arguments. The first runs on all processes. The second runs only on parallel process #1
|
||||||
and *only* after all other processes have finished and exited. This ensures that process #1, and any resources it is managing, remain alive until
|
and *only* after all other processes have finished and exited. This ensures that process #1, and any resources it is managing, remain alive until
|
||||||
all other processes are finished.
|
all other processes are finished. These two functions can be bare functions (func()) or interruptible (func(context.Context)/func(SpecContext))
|
||||||
|
|
||||||
Note that you can also use DeferCleanup() in SynchronizedBeforeSuite to accomplish similar results.
|
Note that you can also use DeferCleanup() in SynchronizedBeforeSuite to accomplish similar results.
|
||||||
|
|
||||||
You cannot nest any other Ginkgo nodes within an SynchronizedAfterSuite node's closure.
|
You cannot nest any other Ginkgo nodes within an SynchronizedAfterSuite node's closure.
|
||||||
You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite
|
You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite
|
||||||
*/
|
*/
|
||||||
func SynchronizedAfterSuite(allProcessBody func(), process1Body func(), args ...interface{}) bool {
|
func SynchronizedAfterSuite(allProcessBody interface{}, process1Body interface{}, args ...interface{}) bool {
|
||||||
combinedArgs := []interface{}{allProcessBody, process1Body}
|
combinedArgs := []interface{}{allProcessBody, process1Body}
|
||||||
combinedArgs = append(combinedArgs, args...)
|
combinedArgs = append(combinedArgs, args...)
|
||||||
|
|
||||||
@ -603,6 +630,8 @@ func SynchronizedAfterSuite(allProcessBody func(), process1Body func(), args ...
|
|||||||
BeforeEach nodes are Setup nodes whose closures run before It node closures. When multiple BeforeEach nodes
|
BeforeEach nodes are Setup nodes whose closures run before It node closures. When multiple BeforeEach nodes
|
||||||
are defined in nested Container nodes the outermost BeforeEach node closures are run first.
|
are defined in nested Container nodes the outermost BeforeEach node closures are run first.
|
||||||
|
|
||||||
|
BeforeEach can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body.
|
||||||
|
|
||||||
You cannot nest any other Ginkgo nodes within a BeforeEach node's closure.
|
You cannot nest any other Ginkgo nodes within a BeforeEach node's closure.
|
||||||
You can learn more here: https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach
|
You can learn more here: https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach
|
||||||
*/
|
*/
|
||||||
@ -614,6 +643,8 @@ func BeforeEach(args ...interface{}) bool {
|
|||||||
JustBeforeEach nodes are similar to BeforeEach nodes, however they are guaranteed to run *after* all BeforeEach node closures - just before the It node closure.
|
JustBeforeEach nodes are similar to BeforeEach nodes, however they are guaranteed to run *after* all BeforeEach node closures - just before the It node closure.
|
||||||
This can allow you to separate configuration from creation of resources for a spec.
|
This can allow you to separate configuration from creation of resources for a spec.
|
||||||
|
|
||||||
|
JustBeforeEach can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body.
|
||||||
|
|
||||||
You cannot nest any other Ginkgo nodes within a JustBeforeEach node's closure.
|
You cannot nest any other Ginkgo nodes within a JustBeforeEach node's closure.
|
||||||
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-creation-and-configuration-justbeforeeach
|
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-creation-and-configuration-justbeforeeach
|
||||||
*/
|
*/
|
||||||
@ -627,6 +658,8 @@ are defined in nested Container nodes the innermost AfterEach node closures are
|
|||||||
|
|
||||||
Note that you can also use DeferCleanup() in other Setup or Subject nodes to accomplish similar results.
|
Note that you can also use DeferCleanup() in other Setup or Subject nodes to accomplish similar results.
|
||||||
|
|
||||||
|
AfterEach can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body.
|
||||||
|
|
||||||
You cannot nest any other Ginkgo nodes within an AfterEach node's closure.
|
You cannot nest any other Ginkgo nodes within an AfterEach node's closure.
|
||||||
You can learn more here: https://onsi.github.io/ginkgo/#spec-cleanup-aftereach-and-defercleanup
|
You can learn more here: https://onsi.github.io/ginkgo/#spec-cleanup-aftereach-and-defercleanup
|
||||||
*/
|
*/
|
||||||
@ -637,6 +670,8 @@ func AfterEach(args ...interface{}) bool {
|
|||||||
/*
|
/*
|
||||||
JustAfterEach nodes are similar to AfterEach nodes, however they are guaranteed to run *before* all AfterEach node closures - just after the It node closure. This can allow you to separate diagnostics collection from teardown for a spec.
|
JustAfterEach nodes are similar to AfterEach nodes, however they are guaranteed to run *before* all AfterEach node closures - just after the It node closure. This can allow you to separate diagnostics collection from teardown for a spec.
|
||||||
|
|
||||||
|
JustAfterEach can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body.
|
||||||
|
|
||||||
You cannot nest any other Ginkgo nodes within a JustAfterEach node's closure.
|
You cannot nest any other Ginkgo nodes within a JustAfterEach node's closure.
|
||||||
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-diagnostics-collection-and-teardown-justaftereach
|
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-diagnostics-collection-and-teardown-justaftereach
|
||||||
*/
|
*/
|
||||||
@ -649,6 +684,9 @@ BeforeAll nodes are Setup nodes that can occur inside Ordered containers. They
|
|||||||
|
|
||||||
Multiple BeforeAll nodes can be defined in a given Ordered container however they cannot be nested inside any other container.
|
Multiple BeforeAll nodes can be defined in a given Ordered container however they cannot be nested inside any other container.
|
||||||
|
|
||||||
|
BeforeAll can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body.
|
||||||
|
|
||||||
|
|
||||||
You cannot nest any other Ginkgo nodes within a BeforeAll node's closure.
|
You cannot nest any other Ginkgo nodes within a BeforeAll node's closure.
|
||||||
You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers
|
You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers
|
||||||
And you can learn more about BeforeAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
|
And you can learn more about BeforeAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
|
||||||
@ -664,6 +702,8 @@ Multiple AfterAll nodes can be defined in a given Ordered container however they
|
|||||||
|
|
||||||
Note that you can also use DeferCleanup() in a BeforeAll node to accomplish similar behavior.
|
Note that you can also use DeferCleanup() in a BeforeAll node to accomplish similar behavior.
|
||||||
|
|
||||||
|
AfterAll can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body.
|
||||||
|
|
||||||
You cannot nest any other Ginkgo nodes within an AfterAll node's closure.
|
You cannot nest any other Ginkgo nodes within an AfterAll node's closure.
|
||||||
You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers
|
You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers
|
||||||
And you can learn more about AfterAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
|
And you can learn more about AfterAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
|
||||||
@ -678,7 +718,11 @@ DeferCleanup can be called within any Setup or Subject node to register a cleanu
|
|||||||
DeferCleanup can be passed:
|
DeferCleanup can be passed:
|
||||||
1. A function that takes no arguments and returns no values.
|
1. A function that takes no arguments and returns no values.
|
||||||
2. A function that returns an error (in which case it will assert that the returned error was nil, or it will fail the spec).
|
2. A function that returns an error (in which case it will assert that the returned error was nil, or it will fail the spec).
|
||||||
3. A function that takes arguments (and optionally returns an error) followed by a list of arguments to passe to the function. For example:
|
3. A function that takes a context.Context or SpecContext (and optionally returns an error). The resulting cleanup node is deemed interruptible and the passed-in context will be cancelled in the event of a timeout or interrupt.
|
||||||
|
4. A function that takes arguments (and optionally returns an error) followed by a list of arguments to pass to the function.
|
||||||
|
5. A function that takes SpecContext and a list of arguments (and optionally returns an error) followed by a list of arguments to pass to the function.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
DeferCleanup(os.SetEnv, "FOO", os.GetEnv("FOO"))
|
DeferCleanup(os.SetEnv, "FOO", os.GetEnv("FOO"))
|
||||||
@ -687,6 +731,19 @@ DeferCleanup can be passed:
|
|||||||
|
|
||||||
will register a cleanup handler that will set the environment variable "FOO" to it's current value (obtained by os.GetEnv("FOO")) after the spec runs and then sets the environment variable "FOO" to "BAR" for the current spec.
|
will register a cleanup handler that will set the environment variable "FOO" to it's current value (obtained by os.GetEnv("FOO")) after the spec runs and then sets the environment variable "FOO" to "BAR" for the current spec.
|
||||||
|
|
||||||
|
Similarly:
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
DeferCleanup(func(ctx SpecContext, path) {
|
||||||
|
req, err := http.NewRequestWithContext(ctx, "POST", path, nil)
|
||||||
|
Expect(err).NotTo(HaveOccured())
|
||||||
|
_, err := http.DefaultClient.Do(req)
|
||||||
|
Expect(err).NotTo(HaveOccured())
|
||||||
|
}, "example.com/cleanup", NodeTimeout(time.Second*3))
|
||||||
|
})
|
||||||
|
|
||||||
|
will register a cleanup handler that will have three seconds to successfully complete a request to the specified path. Note that we do not specify a context in the list of arguments passed to DeferCleanup - only in the signature of the function we pass in. Ginkgo will detect the requested context and supply a SpecContext when it invokes the cleanup node. If you want to pass in your own context in addition to the Ginkgo-provided SpecContext you must specify the SpecContext as the first argument (e.g. func(ctx SpecContext, otherCtx context.Context)).
|
||||||
|
|
||||||
When DeferCleanup is called in BeforeEach, JustBeforeEach, It, AfterEach, or JustAfterEach the registered callback will be invoked when the spec completes (i.e. it will behave like an AfterEach node)
|
When DeferCleanup is called in BeforeEach, JustBeforeEach, It, AfterEach, or JustAfterEach the registered callback will be invoked when the spec completes (i.e. it will behave like an AfterEach node)
|
||||||
When DeferCleanup is called in BeforeAll or AfterAll the registered callback will be invoked when the ordered container completes (i.e. it will behave like an AfterAll node)
|
When DeferCleanup is called in BeforeAll or AfterAll the registered callback will be invoked when the ordered container completes (i.e. it will behave like an AfterAll node)
|
||||||
When DeferCleanup is called in BeforeSuite, SynchronizedBeforeSuite, AfterSuite, or SynchronizedAfterSuite the registered callback will be invoked when the suite completes (i.e. it will behave like an AfterSuite node)
|
When DeferCleanup is called in BeforeSuite, SynchronizedBeforeSuite, AfterSuite, or SynchronizedAfterSuite the registered callback will be invoked when the suite completes (i.e. it will behave like an AfterSuite node)
|
||||||
@ -698,5 +755,5 @@ func DeferCleanup(args ...interface{}) {
|
|||||||
fail := func(message string, cl types.CodeLocation) {
|
fail := func(message string, cl types.CodeLocation) {
|
||||||
global.Failer.Fail(message, cl)
|
global.Failer.Fail(message, cl)
|
||||||
}
|
}
|
||||||
pushNode(internal.NewCleanupNode(fail, args...))
|
pushNode(internal.NewCleanupNode(deprecationTracker, fail, args...))
|
||||||
}
|
}
|
||||||
|
23
vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go
generated
vendored
23
vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go
generated
vendored
@ -95,6 +95,29 @@ Once a node has been running for longer than PollProgressAfter Ginkgo will emit
|
|||||||
*/
|
*/
|
||||||
type PollProgressInterval = internal.PollProgressInterval
|
type PollProgressInterval = internal.PollProgressInterval
|
||||||
|
|
||||||
|
/*
|
||||||
|
NodeTimeout allows you to specify a timeout for an indivdiual node. The node cannot be a container and must be interruptible (i.e. it must be passed a function that accepts a SpecContext or context.Context).
|
||||||
|
|
||||||
|
If the node does not exit within the specified NodeTimeout its context will be cancelled. The node wil then have a period of time controlled by the GracePeriod decorator (or global --grace-period command-line argument) to exit. If the node does not exit within GracePeriod Ginkgo will leak the node and proceed to any clean-up nodes associated with the current spec.
|
||||||
|
*/
|
||||||
|
type NodeTimeout = internal.NodeTimeout
|
||||||
|
|
||||||
|
/*
|
||||||
|
SpecTimeout allows you to specify a timeout for an indivdiual spec. SpecTimeout can only decorate interruptible It nodes.
|
||||||
|
|
||||||
|
All nodes associated with the It node will need to complete before the SpecTimeout has elapsed. Individual nodes (e.g. BeforeEach) may be decorated with different NodeTimeouts - but these can only serve to provide a more stringent deadline for the node in question; they cannot extend the deadline past the SpecTimeout.
|
||||||
|
|
||||||
|
If the spec does not complete within the specified SpecTimeout the currently running node will have its context cancelled. The node wil then have a period of time controlled by that node's GracePeriod decorator (or global --grace-period command-line argument) to exit. If the node does not exit within GracePeriod Ginkgo will leak the node and proceed to any clean-up nodes associated with the current spec.
|
||||||
|
*/
|
||||||
|
type SpecTimeout = internal.SpecTimeout
|
||||||
|
|
||||||
|
/*
|
||||||
|
GracePeriod denotes the period of time Ginkgo will wait for an interruptible node to exit once an interruption (whether due to a timeout or a user-invoked signal) has occurred. If both the global --grace-period cli flag and a GracePeriod decorator are specified the value in the decorator will take precedence.
|
||||||
|
|
||||||
|
Nodes that do not finish within a GracePeriod will be leaked and Ginkgo will proceed to run subsequent nodes. In the event of a timeout, such leaks will be reported to the user.
|
||||||
|
*/
|
||||||
|
type GracePeriod = internal.GracePeriod
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SuppressProgressReporting is a decorator that allows you to disable progress reporting of a particular node. This is useful if `ginkgo -v -progress` is generating too much noise; particularly
|
SuppressProgressReporting is a decorator that allows you to disable progress reporting of a particular node. This is useful if `ginkgo -v -progress` is generating too much noise; particularly
|
||||||
if you have a `ReportAfterEach` node that is running for every skipped spec and is generating lots of progress reports.
|
if you have a `ReportAfterEach` node that is running for every skipped spec and is generating lots of progress reports.
|
||||||
|
2
vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go
generated
vendored
2
vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go
generated
vendored
@ -39,6 +39,8 @@ func buildSpecs(args []string, cliConfig types.CLIConfig, goFlagsConfig types.Go
|
|||||||
command.AbortWith("Found no test suites")
|
command.AbortWith("Found no test suites")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal.VerifyCLIAndFrameworkVersion(suites)
|
||||||
|
|
||||||
opc := internal.NewOrderedParallelCompiler(cliConfig.ComputedNumCompilers())
|
opc := internal.NewOrderedParallelCompiler(cliConfig.ComputedNumCompilers())
|
||||||
opc.StartCompiling(suites, goFlagsConfig)
|
opc.StartCompiling(suites, goFlagsConfig)
|
||||||
|
|
||||||
|
54
vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/verify_version.go
generated
vendored
Normal file
54
vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/verify_version.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/onsi/ginkgo/v2/formatter"
|
||||||
|
"github.com/onsi/ginkgo/v2/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var versiorRe = regexp.MustCompile(`v(\d+\.\d+\.\d+)`)
|
||||||
|
|
||||||
|
func VerifyCLIAndFrameworkVersion(suites TestSuites) {
|
||||||
|
cliVersion := types.VERSION
|
||||||
|
mismatches := map[string][]string{}
|
||||||
|
|
||||||
|
for _, suite := range suites {
|
||||||
|
cmd := exec.Command("go", "list", "-m", "github.com/onsi/ginkgo/v2")
|
||||||
|
cmd.Dir = suite.Path
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
components := strings.Split(string(output), " ")
|
||||||
|
if len(components) != 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
matches := versiorRe.FindStringSubmatch(components[1])
|
||||||
|
if matches == nil || len(matches) != 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
libraryVersion := matches[1]
|
||||||
|
if cliVersion != libraryVersion {
|
||||||
|
mismatches[libraryVersion] = append(mismatches[libraryVersion], suite.PackageName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(mismatches) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(formatter.F("{{red}}{{bold}}Ginkgo detected a version mismatch between the Ginkgo CLI and the version of Ginkgo imported by your packages:{{/}}"))
|
||||||
|
|
||||||
|
fmt.Println(formatter.Fi(1, "Ginkgo CLI Version:"))
|
||||||
|
fmt.Println(formatter.Fi(2, "{{bold}}%s{{/}}", cliVersion))
|
||||||
|
fmt.Println(formatter.Fi(1, "Mismatched package versions found:"))
|
||||||
|
for version, packages := range mismatches {
|
||||||
|
fmt.Println(formatter.Fi(2, "{{bold}}%s{{/}} used by %s", version, strings.Join(packages, ", ")))
|
||||||
|
}
|
||||||
|
fmt.Println("")
|
||||||
|
fmt.Println(formatter.Fiw(1, formatter.COLS, "{{gray}}Ginkgo will continue to attempt to run but you may see errors (including flag parsing errors) and should either update your go.mod or your version of the Ginkgo CLI to match.\n\nTo install the matching version of the CLI run\n {{bold}}go install github.com/onsi/ginkgo/v2/ginkgo{{/}}{{gray}}\nfrom a path that contains a go.mod file. Alternatively you can use\n {{bold}}go run github.com/onsi/ginkgo/v2/ginkgo{{/}}{{gray}}\nfrom a path that contains a go.mod file to invoke the matching version of the Ginkgo CLI.\n\nIf you are attempting to test multiple packages that each have a different version of the Ginkgo library with a single Ginkgo CLI that is currently unsupported.\n{{/}}"))
|
||||||
|
}
|
2
vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/import.go
generated
vendored
2
vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/import.go
generated
vendored
@ -47,7 +47,7 @@ func packageNameForImport(f *ast.File, path string) *string {
|
|||||||
// or nil otherwise.
|
// or nil otherwise.
|
||||||
func importSpec(f *ast.File, path string) *ast.ImportSpec {
|
func importSpec(f *ast.File, path string) *ast.ImportSpec {
|
||||||
for _, s := range f.Imports {
|
for _, s := range f.Imports {
|
||||||
if importPath(s) == path {
|
if strings.HasPrefix(importPath(s), path) {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go
generated
vendored
6
vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go
generated
vendored
@ -24,7 +24,7 @@ func BuildRunCommand() command.Command {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
interruptHandler := interrupt_handler.NewInterruptHandler(0, nil)
|
interruptHandler := interrupt_handler.NewInterruptHandler(nil)
|
||||||
interrupt_handler.SwallowSigQuit()
|
interrupt_handler.SwallowSigQuit()
|
||||||
|
|
||||||
return command.Command{
|
return command.Command{
|
||||||
@ -69,6 +69,8 @@ func (r *SpecRunner) RunSpecs(args []string, additionalArgs []string) {
|
|||||||
skippedSuites := suites.WithState(internal.TestSuiteStateSkippedByFilter)
|
skippedSuites := suites.WithState(internal.TestSuiteStateSkippedByFilter)
|
||||||
suites = suites.WithoutState(internal.TestSuiteStateSkippedByFilter)
|
suites = suites.WithoutState(internal.TestSuiteStateSkippedByFilter)
|
||||||
|
|
||||||
|
internal.VerifyCLIAndFrameworkVersion(suites)
|
||||||
|
|
||||||
if len(skippedSuites) > 0 {
|
if len(skippedSuites) > 0 {
|
||||||
fmt.Println("Will skip:")
|
fmt.Println("Will skip:")
|
||||||
for _, skippedSuite := range skippedSuites {
|
for _, skippedSuite := range skippedSuites {
|
||||||
@ -115,7 +117,7 @@ OUTER_LOOP:
|
|||||||
}
|
}
|
||||||
suites[suiteIdx] = suite
|
suites[suiteIdx] = suite
|
||||||
|
|
||||||
if r.interruptHandler.Status().Interrupted {
|
if r.interruptHandler.Status().Interrupted() {
|
||||||
opc.StopAndDrain()
|
opc.StopAndDrain()
|
||||||
break OUTER_LOOP
|
break OUTER_LOOP
|
||||||
}
|
}
|
||||||
|
8
vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go
generated
vendored
8
vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go
generated
vendored
@ -22,7 +22,7 @@ func BuildWatchCommand() command.Command {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
interruptHandler := interrupt_handler.NewInterruptHandler(0, nil)
|
interruptHandler := interrupt_handler.NewInterruptHandler(nil)
|
||||||
interrupt_handler.SwallowSigQuit()
|
interrupt_handler.SwallowSigQuit()
|
||||||
|
|
||||||
return command.Command{
|
return command.Command{
|
||||||
@ -65,6 +65,8 @@ type SpecWatcher struct {
|
|||||||
func (w *SpecWatcher) WatchSpecs(args []string, additionalArgs []string) {
|
func (w *SpecWatcher) WatchSpecs(args []string, additionalArgs []string) {
|
||||||
suites := internal.FindSuites(args, w.cliConfig, false).WithoutState(internal.TestSuiteStateSkippedByFilter)
|
suites := internal.FindSuites(args, w.cliConfig, false).WithoutState(internal.TestSuiteStateSkippedByFilter)
|
||||||
|
|
||||||
|
internal.VerifyCLIAndFrameworkVersion(suites)
|
||||||
|
|
||||||
if len(suites) == 0 {
|
if len(suites) == 0 {
|
||||||
command.AbortWith("Found no test suites")
|
command.AbortWith("Found no test suites")
|
||||||
}
|
}
|
||||||
@ -127,7 +129,7 @@ func (w *SpecWatcher) WatchSpecs(args []string, additionalArgs []string) {
|
|||||||
w.updateSeed()
|
w.updateSeed()
|
||||||
w.computeSuccinctMode(len(suites))
|
w.computeSuccinctMode(len(suites))
|
||||||
for idx := range suites {
|
for idx := range suites {
|
||||||
if w.interruptHandler.Status().Interrupted {
|
if w.interruptHandler.Status().Interrupted() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
deltaTracker.WillRun(suites[idx])
|
deltaTracker.WillRun(suites[idx])
|
||||||
@ -156,7 +158,7 @@ func (w *SpecWatcher) compileAndRun(suite internal.TestSuite, additionalArgs []s
|
|||||||
fmt.Println(suite.CompilationError.Error())
|
fmt.Println(suite.CompilationError.Error())
|
||||||
return suite
|
return suite
|
||||||
}
|
}
|
||||||
if w.interruptHandler.Status().Interrupted {
|
if w.interruptHandler.Status().Interrupted() {
|
||||||
return suite
|
return suite
|
||||||
}
|
}
|
||||||
suite = internal.RunCompiledSuite(suite, w.suiteConfig, w.reporterConfig, w.cliConfig, w.goFlagsConfig, additionalArgs)
|
suite = internal.RunCompiledSuite(suite, w.suiteConfig, w.reporterConfig, w.cliConfig, w.goFlagsConfig, additionalArgs)
|
||||||
|
239
vendor/github.com/onsi/ginkgo/v2/internal/group.go
generated
vendored
239
vendor/github.com/onsi/ginkgo/v2/internal/group.go
generated
vendored
@ -128,7 +128,10 @@ func (g *group) evaluateSkipStatus(spec Spec) (types.SpecState, types.Failure) {
|
|||||||
if spec.Skip {
|
if spec.Skip {
|
||||||
return types.SpecStateSkipped, types.Failure{}
|
return types.SpecStateSkipped, types.Failure{}
|
||||||
}
|
}
|
||||||
if g.suite.interruptHandler.Status().Interrupted || g.suite.skipAll {
|
if g.suite.interruptHandler.Status().Interrupted() || g.suite.skipAll {
|
||||||
|
return types.SpecStateSkipped, types.Failure{}
|
||||||
|
}
|
||||||
|
if !g.suite.deadline.IsZero() && g.suite.deadline.Before(time.Now()) {
|
||||||
return types.SpecStateSkipped, types.Failure{}
|
return types.SpecStateSkipped, types.Failure{}
|
||||||
}
|
}
|
||||||
if !g.succeeded {
|
if !g.succeeded {
|
||||||
@ -163,8 +166,6 @@ func (g *group) isLastSpecWithPair(specID uint, pair runOncePair) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *group) attemptSpec(isFinalAttempt bool, spec Spec) {
|
func (g *group) attemptSpec(isFinalAttempt bool, spec Spec) {
|
||||||
interruptStatus := g.suite.interruptHandler.Status()
|
|
||||||
|
|
||||||
pairs := g.runOncePairs[spec.SubjectID()]
|
pairs := g.runOncePairs[spec.SubjectID()]
|
||||||
|
|
||||||
nodes := spec.Nodes.WithType(types.NodeTypeBeforeAll)
|
nodes := spec.Nodes.WithType(types.NodeTypeBeforeAll)
|
||||||
@ -173,12 +174,17 @@ func (g *group) attemptSpec(isFinalAttempt bool, spec Spec) {
|
|||||||
nodes = append(nodes, spec.Nodes.FirstNodeWithType(types.NodeTypeIt))
|
nodes = append(nodes, spec.Nodes.FirstNodeWithType(types.NodeTypeIt))
|
||||||
terminatingNode, terminatingPair := Node{}, runOncePair{}
|
terminatingNode, terminatingPair := Node{}, runOncePair{}
|
||||||
|
|
||||||
|
deadline := time.Time{}
|
||||||
|
if spec.SpecTimeout() > 0 {
|
||||||
|
deadline = time.Now().Add(spec.SpecTimeout())
|
||||||
|
}
|
||||||
|
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
oncePair := pairs.runOncePairFor(node.ID)
|
oncePair := pairs.runOncePairFor(node.ID)
|
||||||
if !oncePair.isZero() && g.runOnceTracker[oncePair].Is(types.SpecStatePassed) {
|
if !oncePair.isZero() && g.runOnceTracker[oncePair].Is(types.SpecStatePassed) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
g.suite.currentSpecReport.State, g.suite.currentSpecReport.Failure = g.suite.runNode(node, interruptStatus.Channel, spec.Nodes.BestTextFor(node))
|
g.suite.currentSpecReport.State, g.suite.currentSpecReport.Failure = g.suite.runNode(node, deadline, spec.Nodes.BestTextFor(node))
|
||||||
g.suite.currentSpecReport.RunTime = time.Since(g.suite.currentSpecReport.StartTime)
|
g.suite.currentSpecReport.RunTime = time.Since(g.suite.currentSpecReport.StartTime)
|
||||||
if !oncePair.isZero() {
|
if !oncePair.isZero() {
|
||||||
g.runOnceTracker[oncePair] = g.suite.currentSpecReport.State
|
g.runOnceTracker[oncePair] = g.suite.currentSpecReport.State
|
||||||
@ -260,11 +266,13 @@ func (g *group) attemptSpec(isFinalAttempt bool, spec Spec) {
|
|||||||
|
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
afterNodeWasRun[node.ID] = true
|
afterNodeWasRun[node.ID] = true
|
||||||
state, failure := g.suite.runNode(node, g.suite.interruptHandler.Status().Channel, spec.Nodes.BestTextFor(node))
|
state, failure := g.suite.runNode(node, deadline, spec.Nodes.BestTextFor(node))
|
||||||
g.suite.currentSpecReport.RunTime = time.Since(g.suite.currentSpecReport.StartTime)
|
g.suite.currentSpecReport.RunTime = time.Since(g.suite.currentSpecReport.StartTime)
|
||||||
if g.suite.currentSpecReport.State == types.SpecStatePassed || state == types.SpecStateAborted {
|
if g.suite.currentSpecReport.State == types.SpecStatePassed || state == types.SpecStateAborted {
|
||||||
g.suite.currentSpecReport.State = state
|
g.suite.currentSpecReport.State = state
|
||||||
g.suite.currentSpecReport.Failure = failure
|
g.suite.currentSpecReport.Failure = failure
|
||||||
|
} else if state.Is(types.SpecStateFailureStates) {
|
||||||
|
g.suite.currentSpecReport.AdditionalFailures = append(g.suite.currentSpecReport.AdditionalFailures, types.AdditionalFailure{State: state, Failure: failure})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
includeDeferCleanups = true
|
includeDeferCleanups = true
|
||||||
@ -326,224 +334,3 @@ func (g *group) run(specs Specs) {
|
|||||||
g.suite.selectiveLock.Unlock()
|
g.suite.selectiveLock.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *group) oldRun(specs Specs) {
|
|
||||||
var suite = g.suite
|
|
||||||
nodeState := map[uint]types.SpecState{}
|
|
||||||
groupSucceeded := true
|
|
||||||
|
|
||||||
indexOfLastSpecContainingNodeID := func(id uint) int {
|
|
||||||
lastIdx := -1
|
|
||||||
for idx := range specs {
|
|
||||||
if specs[idx].Nodes.ContainsNodeID(id) && !specs[idx].Skip {
|
|
||||||
lastIdx = idx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lastIdx
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, spec := range specs {
|
|
||||||
suite.currentSpecReport = types.SpecReport{
|
|
||||||
ContainerHierarchyTexts: spec.Nodes.WithType(types.NodeTypeContainer).Texts(),
|
|
||||||
ContainerHierarchyLocations: spec.Nodes.WithType(types.NodeTypeContainer).CodeLocations(),
|
|
||||||
ContainerHierarchyLabels: spec.Nodes.WithType(types.NodeTypeContainer).Labels(),
|
|
||||||
LeafNodeLocation: spec.FirstNodeWithType(types.NodeTypeIt).CodeLocation,
|
|
||||||
LeafNodeType: types.NodeTypeIt,
|
|
||||||
LeafNodeText: spec.FirstNodeWithType(types.NodeTypeIt).Text,
|
|
||||||
LeafNodeLabels: []string(spec.FirstNodeWithType(types.NodeTypeIt).Labels),
|
|
||||||
ParallelProcess: suite.config.ParallelProcess,
|
|
||||||
IsSerial: spec.Nodes.HasNodeMarkedSerial(),
|
|
||||||
IsInOrderedContainer: !spec.Nodes.FirstNodeMarkedOrdered().IsZero(),
|
|
||||||
}
|
|
||||||
|
|
||||||
skip := spec.Skip
|
|
||||||
if spec.Nodes.HasNodeMarkedPending() {
|
|
||||||
skip = true
|
|
||||||
suite.currentSpecReport.State = types.SpecStatePending
|
|
||||||
} else {
|
|
||||||
if suite.interruptHandler.Status().Interrupted || suite.skipAll {
|
|
||||||
skip = true
|
|
||||||
}
|
|
||||||
if !groupSucceeded {
|
|
||||||
skip = true
|
|
||||||
suite.currentSpecReport.Failure = suite.failureForLeafNodeWithMessage(spec.FirstNodeWithType(types.NodeTypeIt),
|
|
||||||
"Spec skipped because an earlier spec in an ordered container failed")
|
|
||||||
}
|
|
||||||
for _, node := range spec.Nodes.WithType(types.NodeTypeBeforeAll) {
|
|
||||||
if nodeState[node.ID] == types.SpecStateSkipped {
|
|
||||||
skip = true
|
|
||||||
suite.currentSpecReport.Failure = suite.failureForLeafNodeWithMessage(spec.FirstNodeWithType(types.NodeTypeIt),
|
|
||||||
"Spec skipped because Skip() was called in BeforeAll")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if skip {
|
|
||||||
suite.currentSpecReport.State = types.SpecStateSkipped
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if suite.config.DryRun && !skip {
|
|
||||||
skip = true
|
|
||||||
suite.currentSpecReport.State = types.SpecStatePassed
|
|
||||||
}
|
|
||||||
|
|
||||||
suite.reporter.WillRun(suite.currentSpecReport)
|
|
||||||
//send the spec report to any attached ReportBeforeEach blocks - this will update suite.currentSpecReport if failures occur in these blocks
|
|
||||||
suite.reportEach(spec, types.NodeTypeReportBeforeEach)
|
|
||||||
if suite.currentSpecReport.State.Is(types.SpecStateFailureStates) {
|
|
||||||
//the reportEach failed, skip this spec
|
|
||||||
skip = true
|
|
||||||
}
|
|
||||||
|
|
||||||
suite.currentSpecReport.StartTime = time.Now()
|
|
||||||
maxAttempts := max(1, spec.FlakeAttempts())
|
|
||||||
if suite.config.FlakeAttempts > 0 {
|
|
||||||
maxAttempts = suite.config.FlakeAttempts
|
|
||||||
}
|
|
||||||
|
|
||||||
for attempt := 0; !skip && (attempt < maxAttempts); attempt++ {
|
|
||||||
suite.currentSpecReport.NumAttempts = attempt + 1
|
|
||||||
suite.writer.Truncate()
|
|
||||||
suite.outputInterceptor.StartInterceptingOutput()
|
|
||||||
if attempt > 0 {
|
|
||||||
fmt.Fprintf(suite.writer, "\nGinkgo: Attempt #%d Failed. Retrying...\n", attempt)
|
|
||||||
}
|
|
||||||
isFinalAttempt := (attempt == maxAttempts-1)
|
|
||||||
|
|
||||||
interruptStatus := suite.interruptHandler.Status()
|
|
||||||
deepestNestingLevelAttained := -1
|
|
||||||
var nodes = spec.Nodes.WithType(types.NodeTypeBeforeAll).Filter(func(n Node) bool {
|
|
||||||
return nodeState[n.ID] != types.SpecStatePassed
|
|
||||||
})
|
|
||||||
nodes = nodes.CopyAppend(spec.Nodes.WithType(types.NodeTypeBeforeEach)...).SortedByAscendingNestingLevel()
|
|
||||||
nodes = nodes.CopyAppend(spec.Nodes.WithType(types.NodeTypeJustBeforeEach).SortedByAscendingNestingLevel()...)
|
|
||||||
nodes = nodes.CopyAppend(spec.Nodes.WithType(types.NodeTypeIt)...)
|
|
||||||
|
|
||||||
var terminatingNode Node
|
|
||||||
for j := range nodes {
|
|
||||||
deepestNestingLevelAttained = max(deepestNestingLevelAttained, nodes[j].NestingLevel)
|
|
||||||
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(nodes[j], interruptStatus.Channel, spec.Nodes.BestTextFor(nodes[j]))
|
|
||||||
suite.currentSpecReport.RunTime = time.Since(suite.currentSpecReport.StartTime)
|
|
||||||
nodeState[nodes[j].ID] = suite.currentSpecReport.State
|
|
||||||
if suite.currentSpecReport.State != types.SpecStatePassed {
|
|
||||||
terminatingNode = nodes[j]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
afterAllNodesThatRan := map[uint]bool{}
|
|
||||||
// pull out some shared code so we aren't repeating ourselves down below. this just runs after and cleanup nodes
|
|
||||||
runAfterAndCleanupNodes := func(nodes Nodes) {
|
|
||||||
for j := range nodes {
|
|
||||||
state, failure := suite.runNode(nodes[j], suite.interruptHandler.Status().Channel, spec.Nodes.BestTextFor(nodes[j]))
|
|
||||||
suite.currentSpecReport.RunTime = time.Since(suite.currentSpecReport.StartTime)
|
|
||||||
nodeState[nodes[j].ID] = state
|
|
||||||
if suite.currentSpecReport.State == types.SpecStatePassed || state == types.SpecStateAborted {
|
|
||||||
suite.currentSpecReport.State = state
|
|
||||||
suite.currentSpecReport.Failure = failure
|
|
||||||
if state != types.SpecStatePassed {
|
|
||||||
terminatingNode = nodes[j]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if nodes[j].NodeType.Is(types.NodeTypeAfterAll) {
|
|
||||||
afterAllNodesThatRan[nodes[j].ID] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// pull out a helper that captures the logic of whether or not we should run a given After node.
|
|
||||||
// there is complexity here stemming from the fact that we allow nested ordered contexts and flakey retries
|
|
||||||
shouldRunAfterNode := func(n Node) bool {
|
|
||||||
if n.NodeType.Is(types.NodeTypeAfterEach | types.NodeTypeJustAfterEach) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
var id uint
|
|
||||||
if n.NodeType.Is(types.NodeTypeAfterAll) {
|
|
||||||
id = n.ID
|
|
||||||
if afterAllNodesThatRan[id] { //we've already run on this attempt. don't run again.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if n.NodeType.Is(types.NodeTypeCleanupAfterAll) {
|
|
||||||
id = n.NodeIDWhereCleanupWasGenerated
|
|
||||||
}
|
|
||||||
isLastSpecWithNode := indexOfLastSpecContainingNodeID(id) == i
|
|
||||||
|
|
||||||
switch suite.currentSpecReport.State {
|
|
||||||
case types.SpecStatePassed: //we've passed so far...
|
|
||||||
return isLastSpecWithNode //... and we're the last spec with this AfterNode, so we should run it
|
|
||||||
case types.SpecStateSkipped: //the spec was skipped by the user...
|
|
||||||
if isLastSpecWithNode {
|
|
||||||
return true //...we're the last spec, so we should run the AfterNode
|
|
||||||
}
|
|
||||||
if terminatingNode.NodeType.Is(types.NodeTypeBeforeAll) && terminatingNode.NestingLevel == n.NestingLevel {
|
|
||||||
return true //...or, a BeforeAll was skipped and it's at our nesting level, so our subgroup is going to skip
|
|
||||||
}
|
|
||||||
case types.SpecStateFailed, types.SpecStatePanicked: // the spec has failed...
|
|
||||||
if isFinalAttempt {
|
|
||||||
return true //...if this was the last attempt then we're the last spec to run and so the AfterNode should run
|
|
||||||
}
|
|
||||||
if terminatingNode.NodeType.Is(types.NodeTypeBeforeAll) {
|
|
||||||
//...we'll be rerunning a BeforeAll so we should cleanup after it if...
|
|
||||||
if n.NodeType.Is(types.NodeTypeAfterAll) && terminatingNode.NestingLevel == n.NestingLevel {
|
|
||||||
return true //we're at the same nesting level
|
|
||||||
}
|
|
||||||
if n.NodeType.Is(types.NodeTypeCleanupAfterAll) && terminatingNode.ID == n.NodeIDWhereCleanupWasGenerated {
|
|
||||||
return true //we're a DeferCleanup generated by it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if terminatingNode.NodeType.Is(types.NodeTypeAfterAll) {
|
|
||||||
//...we'll be rerunning an AfterAll so we should cleanup after it if...
|
|
||||||
if n.NodeType.Is(types.NodeTypeCleanupAfterAll) && terminatingNode.ID == n.NodeIDWhereCleanupWasGenerated {
|
|
||||||
return true //we're a DeferCleanup generated by it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case types.SpecStateInterrupted, types.SpecStateAborted: // ...we've been interrupted and/or aborted
|
|
||||||
return true //...that means the test run is over and we should clean up the stack. Run the AfterNode
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// first pass - run all the JustAfterEach, Aftereach, and AfterAlls. Our shoudlRunAfterNode filter function will clean up the AfterAlls for us.
|
|
||||||
afterNodes := spec.Nodes.WithType(types.NodeTypeJustAfterEach).SortedByDescendingNestingLevel()
|
|
||||||
afterNodes = afterNodes.CopyAppend(spec.Nodes.WithType(types.NodeTypeAfterEach).CopyAppend(spec.Nodes.WithType(types.NodeTypeAfterAll)...).SortedByDescendingNestingLevel()...)
|
|
||||||
afterNodes = afterNodes.WithinNestingLevel(deepestNestingLevelAttained)
|
|
||||||
afterNodes = afterNodes.Filter(shouldRunAfterNode)
|
|
||||||
runAfterAndCleanupNodes(afterNodes)
|
|
||||||
|
|
||||||
// second-pass perhaps we didn't run the AfterAlls but a state change due to an AfterEach now requires us to run the AfterAlls:
|
|
||||||
afterNodes = spec.Nodes.WithType(types.NodeTypeAfterAll).WithinNestingLevel(deepestNestingLevelAttained).Filter(shouldRunAfterNode)
|
|
||||||
runAfterAndCleanupNodes(afterNodes)
|
|
||||||
|
|
||||||
// now we run any DeferCleanups
|
|
||||||
afterNodes = suite.cleanupNodes.WithType(types.NodeTypeCleanupAfterEach).Reverse()
|
|
||||||
afterNodes = append(afterNodes, suite.cleanupNodes.WithType(types.NodeTypeCleanupAfterAll).Filter(shouldRunAfterNode).Reverse()...)
|
|
||||||
runAfterAndCleanupNodes(afterNodes)
|
|
||||||
|
|
||||||
// third-pass, perhaps a DeferCleanup failed and now we need to run the AfterAlls.
|
|
||||||
afterNodes = spec.Nodes.WithType(types.NodeTypeAfterAll).WithinNestingLevel(deepestNestingLevelAttained).Filter(shouldRunAfterNode)
|
|
||||||
runAfterAndCleanupNodes(afterNodes)
|
|
||||||
|
|
||||||
// and finally - running AfterAlls may have generated some new DeferCleanup nodes, let's run them to finish up
|
|
||||||
afterNodes = suite.cleanupNodes.WithType(types.NodeTypeCleanupAfterAll).Reverse().Filter(shouldRunAfterNode)
|
|
||||||
runAfterAndCleanupNodes(afterNodes)
|
|
||||||
|
|
||||||
suite.currentSpecReport.EndTime = time.Now()
|
|
||||||
suite.currentSpecReport.RunTime = suite.currentSpecReport.EndTime.Sub(suite.currentSpecReport.StartTime)
|
|
||||||
suite.currentSpecReport.CapturedGinkgoWriterOutput += string(suite.writer.Bytes())
|
|
||||||
suite.currentSpecReport.CapturedStdOutErr += suite.outputInterceptor.StopInterceptingAndReturnOutput()
|
|
||||||
|
|
||||||
if suite.currentSpecReport.State.Is(types.SpecStatePassed | types.SpecStateSkipped | types.SpecStateAborted | types.SpecStateInterrupted) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//send the spec report to any attached ReportAfterEach blocks - this will update suite.currentSpecReport if failures occur in these blocks
|
|
||||||
suite.reportEach(spec, types.NodeTypeReportAfterEach)
|
|
||||||
suite.processCurrentSpecReport()
|
|
||||||
if suite.currentSpecReport.State.Is(types.SpecStateFailureStates) {
|
|
||||||
groupSucceeded = false
|
|
||||||
}
|
|
||||||
suite.currentSpecReport = types.SpecReport{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
138
vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go
generated
vendored
138
vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go
generated
vendored
@ -1,7 +1,6 @@
|
|||||||
package interrupt_handler
|
package interrupt_handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"sync"
|
"sync"
|
||||||
@ -11,27 +10,29 @@ import (
|
|||||||
"github.com/onsi/ginkgo/v2/internal/parallel_support"
|
"github.com/onsi/ginkgo/v2/internal/parallel_support"
|
||||||
)
|
)
|
||||||
|
|
||||||
const TIMEOUT_REPEAT_INTERRUPT_MAXIMUM_DURATION = 30 * time.Second
|
|
||||||
const TIMEOUT_REPEAT_INTERRUPT_FRACTION_OF_TIMEOUT = 10
|
|
||||||
const ABORT_POLLING_INTERVAL = 500 * time.Millisecond
|
const ABORT_POLLING_INTERVAL = 500 * time.Millisecond
|
||||||
const ABORT_REPEAT_INTERRUPT_DURATION = 30 * time.Second
|
|
||||||
|
|
||||||
type InterruptCause uint
|
type InterruptCause uint
|
||||||
|
|
||||||
const (
|
const (
|
||||||
InterruptCauseInvalid InterruptCause = iota
|
InterruptCauseInvalid InterruptCause = iota
|
||||||
|
|
||||||
InterruptCauseSignal
|
InterruptCauseSignal
|
||||||
InterruptCauseTimeout
|
|
||||||
InterruptCauseAbortByOtherProcess
|
InterruptCauseAbortByOtherProcess
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type InterruptLevel uint
|
||||||
|
|
||||||
|
const (
|
||||||
|
InterruptLevelUninterrupted InterruptLevel = iota
|
||||||
|
InterruptLevelCleanupAndReport
|
||||||
|
InterruptLevelReportOnly
|
||||||
|
InterruptLevelBailOut
|
||||||
|
)
|
||||||
|
|
||||||
func (ic InterruptCause) String() string {
|
func (ic InterruptCause) String() string {
|
||||||
switch ic {
|
switch ic {
|
||||||
case InterruptCauseSignal:
|
case InterruptCauseSignal:
|
||||||
return "Interrupted by User"
|
return "Interrupted by User"
|
||||||
case InterruptCauseTimeout:
|
|
||||||
return "Interrupted by Timeout"
|
|
||||||
case InterruptCauseAbortByOtherProcess:
|
case InterruptCauseAbortByOtherProcess:
|
||||||
return "Interrupted by Other Ginkgo Process"
|
return "Interrupted by Other Ginkgo Process"
|
||||||
}
|
}
|
||||||
@ -39,37 +40,49 @@ func (ic InterruptCause) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type InterruptStatus struct {
|
type InterruptStatus struct {
|
||||||
Interrupted bool
|
|
||||||
Channel chan interface{}
|
Channel chan interface{}
|
||||||
|
Level InterruptLevel
|
||||||
Cause InterruptCause
|
Cause InterruptCause
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s InterruptStatus) Interrupted() bool {
|
||||||
|
return s.Level != InterruptLevelUninterrupted
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s InterruptStatus) Message() string {
|
||||||
|
return s.Cause.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s InterruptStatus) ShouldIncludeProgressReport() bool {
|
||||||
|
return s.Cause != InterruptCauseAbortByOtherProcess
|
||||||
|
}
|
||||||
|
|
||||||
type InterruptHandlerInterface interface {
|
type InterruptHandlerInterface interface {
|
||||||
Status() InterruptStatus
|
Status() InterruptStatus
|
||||||
SetInterruptPlaceholderMessage(string)
|
|
||||||
ClearInterruptPlaceholderMessage()
|
|
||||||
InterruptMessage() (string, bool)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type InterruptHandler struct {
|
type InterruptHandler struct {
|
||||||
c chan interface{}
|
c chan interface{}
|
||||||
lock *sync.Mutex
|
lock *sync.Mutex
|
||||||
interrupted bool
|
level InterruptLevel
|
||||||
interruptPlaceholderMessage string
|
cause InterruptCause
|
||||||
interruptCause InterruptCause
|
|
||||||
client parallel_support.Client
|
client parallel_support.Client
|
||||||
stop chan interface{}
|
stop chan interface{}
|
||||||
|
signals []os.Signal
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInterruptHandler(timeout time.Duration, client parallel_support.Client) *InterruptHandler {
|
func NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *InterruptHandler {
|
||||||
|
if len(signals) == 0 {
|
||||||
|
signals = []os.Signal{os.Interrupt, syscall.SIGTERM}
|
||||||
|
}
|
||||||
handler := &InterruptHandler{
|
handler := &InterruptHandler{
|
||||||
c: make(chan interface{}),
|
c: make(chan interface{}),
|
||||||
lock: &sync.Mutex{},
|
lock: &sync.Mutex{},
|
||||||
interrupted: false,
|
|
||||||
stop: make(chan interface{}),
|
stop: make(chan interface{}),
|
||||||
client: client,
|
client: client,
|
||||||
|
signals: signals,
|
||||||
}
|
}
|
||||||
handler.registerForInterrupts(timeout)
|
handler.registerForInterrupts()
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,30 +90,22 @@ func (handler *InterruptHandler) Stop() {
|
|||||||
close(handler.stop)
|
close(handler.stop)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *InterruptHandler) registerForInterrupts(timeout time.Duration) {
|
func (handler *InterruptHandler) registerForInterrupts() {
|
||||||
// os signal handling
|
// os signal handling
|
||||||
signalChannel := make(chan os.Signal, 1)
|
signalChannel := make(chan os.Signal, 1)
|
||||||
signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(signalChannel, handler.signals...)
|
||||||
|
|
||||||
// timeout handling
|
|
||||||
var timeoutChannel <-chan time.Time
|
|
||||||
var timeoutTimer *time.Timer
|
|
||||||
if timeout > 0 {
|
|
||||||
timeoutTimer = time.NewTimer(timeout)
|
|
||||||
timeoutChannel = timeoutTimer.C
|
|
||||||
}
|
|
||||||
|
|
||||||
// cross-process abort handling
|
// cross-process abort handling
|
||||||
var abortChannel chan bool
|
var abortChannel chan interface{}
|
||||||
if handler.client != nil {
|
if handler.client != nil {
|
||||||
abortChannel = make(chan bool)
|
abortChannel = make(chan interface{})
|
||||||
go func() {
|
go func() {
|
||||||
pollTicker := time.NewTicker(ABORT_POLLING_INTERVAL)
|
pollTicker := time.NewTicker(ABORT_POLLING_INTERVAL)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-pollTicker.C:
|
case <-pollTicker.C:
|
||||||
if handler.client.ShouldAbort() {
|
if handler.client.ShouldAbort() {
|
||||||
abortChannel <- true
|
close(abortChannel)
|
||||||
pollTicker.Stop()
|
pollTicker.Stop()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -112,55 +117,37 @@ func (handler *InterruptHandler) registerForInterrupts(timeout time.Duration) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// listen for any interrupt signals
|
go func(abortChannel chan interface{}) {
|
||||||
// note that some (timeouts, cross-process aborts) will only trigger once
|
|
||||||
// for these we set up a ticker to keep interrupting the suite until it ends
|
|
||||||
// this ensures any `AfterEach` or `AfterSuite`s that get stuck cleaning up
|
|
||||||
// get interrupted eventually
|
|
||||||
go func() {
|
|
||||||
var interruptCause InterruptCause
|
var interruptCause InterruptCause
|
||||||
var repeatChannel <-chan time.Time
|
|
||||||
var repeatTicker *time.Ticker
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-signalChannel:
|
case <-signalChannel:
|
||||||
interruptCause = InterruptCauseSignal
|
interruptCause = InterruptCauseSignal
|
||||||
case <-timeoutChannel:
|
|
||||||
interruptCause = InterruptCauseTimeout
|
|
||||||
repeatInterruptTimeout := timeout / time.Duration(TIMEOUT_REPEAT_INTERRUPT_FRACTION_OF_TIMEOUT)
|
|
||||||
if repeatInterruptTimeout > TIMEOUT_REPEAT_INTERRUPT_MAXIMUM_DURATION {
|
|
||||||
repeatInterruptTimeout = TIMEOUT_REPEAT_INTERRUPT_MAXIMUM_DURATION
|
|
||||||
}
|
|
||||||
timeoutTimer.Stop()
|
|
||||||
repeatTicker = time.NewTicker(repeatInterruptTimeout)
|
|
||||||
repeatChannel = repeatTicker.C
|
|
||||||
case <-abortChannel:
|
case <-abortChannel:
|
||||||
interruptCause = InterruptCauseAbortByOtherProcess
|
interruptCause = InterruptCauseAbortByOtherProcess
|
||||||
repeatTicker = time.NewTicker(ABORT_REPEAT_INTERRUPT_DURATION)
|
|
||||||
repeatChannel = repeatTicker.C
|
|
||||||
case <-repeatChannel:
|
|
||||||
//do nothing, just interrupt again using the same interruptCause
|
|
||||||
case <-handler.stop:
|
case <-handler.stop:
|
||||||
if timeoutTimer != nil {
|
|
||||||
timeoutTimer.Stop()
|
|
||||||
}
|
|
||||||
if repeatTicker != nil {
|
|
||||||
repeatTicker.Stop()
|
|
||||||
}
|
|
||||||
signal.Stop(signalChannel)
|
signal.Stop(signalChannel)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
abortChannel = nil
|
||||||
|
|
||||||
handler.lock.Lock()
|
handler.lock.Lock()
|
||||||
handler.interruptCause = interruptCause
|
oldLevel := handler.level
|
||||||
if handler.interruptPlaceholderMessage != "" {
|
handler.cause = interruptCause
|
||||||
fmt.Println(handler.interruptPlaceholderMessage)
|
if handler.level == InterruptLevelUninterrupted {
|
||||||
|
handler.level = InterruptLevelCleanupAndReport
|
||||||
|
} else if handler.level == InterruptLevelCleanupAndReport {
|
||||||
|
handler.level = InterruptLevelReportOnly
|
||||||
|
} else if handler.level == InterruptLevelReportOnly {
|
||||||
|
handler.level = InterruptLevelBailOut
|
||||||
}
|
}
|
||||||
handler.interrupted = true
|
if handler.level != oldLevel {
|
||||||
close(handler.c)
|
close(handler.c)
|
||||||
handler.c = make(chan interface{})
|
handler.c = make(chan interface{})
|
||||||
|
}
|
||||||
handler.lock.Unlock()
|
handler.lock.Unlock()
|
||||||
}
|
}
|
||||||
}()
|
}(abortChannel)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *InterruptHandler) Status() InterruptStatus {
|
func (handler *InterruptHandler) Status() InterruptStatus {
|
||||||
@ -168,29 +155,8 @@ func (handler *InterruptHandler) Status() InterruptStatus {
|
|||||||
defer handler.lock.Unlock()
|
defer handler.lock.Unlock()
|
||||||
|
|
||||||
return InterruptStatus{
|
return InterruptStatus{
|
||||||
Interrupted: handler.interrupted,
|
Level: handler.level,
|
||||||
Channel: handler.c,
|
Channel: handler.c,
|
||||||
Cause: handler.interruptCause,
|
Cause: handler.cause,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *InterruptHandler) SetInterruptPlaceholderMessage(message string) {
|
|
||||||
handler.lock.Lock()
|
|
||||||
defer handler.lock.Unlock()
|
|
||||||
|
|
||||||
handler.interruptPlaceholderMessage = message
|
|
||||||
}
|
|
||||||
|
|
||||||
func (handler *InterruptHandler) ClearInterruptPlaceholderMessage() {
|
|
||||||
handler.lock.Lock()
|
|
||||||
defer handler.lock.Unlock()
|
|
||||||
|
|
||||||
handler.interruptPlaceholderMessage = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (handler *InterruptHandler) InterruptMessage() (string, bool) {
|
|
||||||
handler.lock.Lock()
|
|
||||||
out := fmt.Sprintf("%s", handler.interruptCause.String())
|
|
||||||
defer handler.lock.Unlock()
|
|
||||||
return out, handler.interruptCause != InterruptCauseAbortByOtherProcess
|
|
||||||
}
|
|
||||||
|
305
vendor/github.com/onsi/ginkgo/v2/internal/node.go
generated
vendored
305
vendor/github.com/onsi/ginkgo/v2/internal/node.go
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
@ -28,15 +29,20 @@ type Node struct {
|
|||||||
NodeType types.NodeType
|
NodeType types.NodeType
|
||||||
|
|
||||||
Text string
|
Text string
|
||||||
Body func()
|
Body func(SpecContext)
|
||||||
CodeLocation types.CodeLocation
|
CodeLocation types.CodeLocation
|
||||||
NestingLevel int
|
NestingLevel int
|
||||||
|
HasContext bool
|
||||||
|
|
||||||
SynchronizedBeforeSuiteProc1Body func() []byte
|
SynchronizedBeforeSuiteProc1Body func(SpecContext) []byte
|
||||||
SynchronizedBeforeSuiteAllProcsBody func([]byte)
|
SynchronizedBeforeSuiteProc1BodyHasContext bool
|
||||||
|
SynchronizedBeforeSuiteAllProcsBody func(SpecContext, []byte)
|
||||||
|
SynchronizedBeforeSuiteAllProcsBodyHasContext bool
|
||||||
|
|
||||||
SynchronizedAfterSuiteAllProcsBody func()
|
SynchronizedAfterSuiteAllProcsBody func(SpecContext)
|
||||||
SynchronizedAfterSuiteProc1Body func()
|
SynchronizedAfterSuiteAllProcsBodyHasContext bool
|
||||||
|
SynchronizedAfterSuiteProc1Body func(SpecContext)
|
||||||
|
SynchronizedAfterSuiteProc1BodyHasContext bool
|
||||||
|
|
||||||
ReportEachBody func(types.SpecReport)
|
ReportEachBody func(types.SpecReport)
|
||||||
ReportAfterSuiteBody func(types.Report)
|
ReportAfterSuiteBody func(types.Report)
|
||||||
@ -51,6 +57,9 @@ type Node struct {
|
|||||||
Labels Labels
|
Labels Labels
|
||||||
PollProgressAfter time.Duration
|
PollProgressAfter time.Duration
|
||||||
PollProgressInterval time.Duration
|
PollProgressInterval time.Duration
|
||||||
|
NodeTimeout time.Duration
|
||||||
|
SpecTimeout time.Duration
|
||||||
|
GracePeriod time.Duration
|
||||||
|
|
||||||
NodeIDWhereCleanupWasGenerated uint
|
NodeIDWhereCleanupWasGenerated uint
|
||||||
}
|
}
|
||||||
@ -76,6 +85,9 @@ type Done chan<- interface{} // Deprecated Done Channel for asynchronous testing
|
|||||||
type Labels []string
|
type Labels []string
|
||||||
type PollProgressInterval time.Duration
|
type PollProgressInterval time.Duration
|
||||||
type PollProgressAfter time.Duration
|
type PollProgressAfter time.Duration
|
||||||
|
type NodeTimeout time.Duration
|
||||||
|
type SpecTimeout time.Duration
|
||||||
|
type GracePeriod time.Duration
|
||||||
|
|
||||||
func UnionOfLabels(labels ...Labels) Labels {
|
func UnionOfLabels(labels ...Labels) Labels {
|
||||||
out := Labels{}
|
out := Labels{}
|
||||||
@ -132,6 +144,12 @@ func isDecoration(arg interface{}) bool {
|
|||||||
return true
|
return true
|
||||||
case t == reflect.TypeOf(PollProgressAfter(0)):
|
case t == reflect.TypeOf(PollProgressAfter(0)):
|
||||||
return true
|
return true
|
||||||
|
case t == reflect.TypeOf(NodeTimeout(0)):
|
||||||
|
return true
|
||||||
|
case t == reflect.TypeOf(SpecTimeout(0)):
|
||||||
|
return true
|
||||||
|
case t == reflect.TypeOf(GracePeriod(0)):
|
||||||
|
return true
|
||||||
case t.Kind() == reflect.Slice && isSliceOfDecorations(arg):
|
case t.Kind() == reflect.Slice && isSliceOfDecorations(arg):
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
@ -152,6 +170,9 @@ func isSliceOfDecorations(slice interface{}) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var contextType = reflect.TypeOf(new(context.Context)).Elem()
|
||||||
|
var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
|
||||||
|
|
||||||
func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...interface{}) (Node, []error) {
|
func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...interface{}) (Node, []error) {
|
||||||
baseOffset := 2
|
baseOffset := 2
|
||||||
node := Node{
|
node := Node{
|
||||||
@ -163,6 +184,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
|
|||||||
NestingLevel: -1,
|
NestingLevel: -1,
|
||||||
PollProgressAfter: -1,
|
PollProgressAfter: -1,
|
||||||
PollProgressInterval: -1,
|
PollProgressInterval: -1,
|
||||||
|
GracePeriod: -1,
|
||||||
}
|
}
|
||||||
|
|
||||||
errors := []error{}
|
errors := []error{}
|
||||||
@ -241,6 +263,21 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
|
|||||||
if nodeType.Is(types.NodeTypeContainer) {
|
if nodeType.Is(types.NodeTypeContainer) {
|
||||||
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "PollProgressInterval"))
|
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "PollProgressInterval"))
|
||||||
}
|
}
|
||||||
|
case t == reflect.TypeOf(NodeTimeout(0)):
|
||||||
|
node.NodeTimeout = time.Duration(arg.(NodeTimeout))
|
||||||
|
if nodeType.Is(types.NodeTypeContainer) {
|
||||||
|
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "NodeTimeout"))
|
||||||
|
}
|
||||||
|
case t == reflect.TypeOf(SpecTimeout(0)):
|
||||||
|
node.SpecTimeout = time.Duration(arg.(SpecTimeout))
|
||||||
|
if !nodeType.Is(types.NodeTypeIt) {
|
||||||
|
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "SpecTimeout"))
|
||||||
|
}
|
||||||
|
case t == reflect.TypeOf(GracePeriod(0)):
|
||||||
|
node.GracePeriod = time.Duration(arg.(GracePeriod))
|
||||||
|
if nodeType.Is(types.NodeTypeContainer) {
|
||||||
|
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "GracePeriod"))
|
||||||
|
}
|
||||||
case t == reflect.TypeOf(Labels{}):
|
case t == reflect.TypeOf(Labels{}):
|
||||||
if !nodeType.Is(types.NodeTypesForContainerAndIt) {
|
if !nodeType.Is(types.NodeTypesForContainerAndIt) {
|
||||||
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "Label"))
|
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "Label"))
|
||||||
@ -254,7 +291,20 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case t.Kind() == reflect.Func:
|
case t.Kind() == reflect.Func:
|
||||||
if nodeType.Is(types.NodeTypeReportBeforeEach | types.NodeTypeReportAfterEach) {
|
if nodeType.Is(types.NodeTypeContainer) {
|
||||||
|
if node.Body != nil {
|
||||||
|
appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType))
|
||||||
|
trackedFunctionError = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if t.NumOut() > 0 || t.NumIn() > 0 {
|
||||||
|
appendError(types.GinkgoErrors.InvalidBodyTypeForContainer(t, node.CodeLocation, nodeType))
|
||||||
|
trackedFunctionError = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
body := arg.(func())
|
||||||
|
node.Body = func(SpecContext) { body() }
|
||||||
|
} else if nodeType.Is(types.NodeTypeReportBeforeEach | types.NodeTypeReportAfterEach) {
|
||||||
if node.ReportEachBody == nil {
|
if node.ReportEachBody == nil {
|
||||||
node.ReportEachBody = arg.(func(types.SpecReport))
|
node.ReportEachBody = arg.(func(types.SpecReport))
|
||||||
} else {
|
} else {
|
||||||
@ -262,26 +312,6 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
|
|||||||
trackedFunctionError = true
|
trackedFunctionError = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else if nodeType.Is(types.NodeTypeSynchronizedBeforeSuite) {
|
|
||||||
if node.SynchronizedBeforeSuiteProc1Body == nil {
|
|
||||||
node.SynchronizedBeforeSuiteProc1Body = arg.(func() []byte)
|
|
||||||
} else if node.SynchronizedBeforeSuiteAllProcsBody == nil {
|
|
||||||
node.SynchronizedBeforeSuiteAllProcsBody = arg.(func([]byte))
|
|
||||||
} else {
|
|
||||||
appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType))
|
|
||||||
trackedFunctionError = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if nodeType.Is(types.NodeTypeSynchronizedAfterSuite) {
|
|
||||||
if node.SynchronizedAfterSuiteAllProcsBody == nil {
|
|
||||||
node.SynchronizedAfterSuiteAllProcsBody = arg.(func())
|
|
||||||
} else if node.SynchronizedAfterSuiteProc1Body == nil {
|
|
||||||
node.SynchronizedAfterSuiteProc1Body = arg.(func())
|
|
||||||
} else {
|
|
||||||
appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType))
|
|
||||||
trackedFunctionError = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if nodeType.Is(types.NodeTypeReportAfterSuite) {
|
} else if nodeType.Is(types.NodeTypeReportAfterSuite) {
|
||||||
if node.ReportAfterSuiteBody == nil {
|
if node.ReportAfterSuiteBody == nil {
|
||||||
node.ReportAfterSuiteBody = arg.(func(types.Report))
|
node.ReportAfterSuiteBody = arg.(func(types.Report))
|
||||||
@ -290,25 +320,56 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
|
|||||||
trackedFunctionError = true
|
trackedFunctionError = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
} else if nodeType.Is(types.NodeTypeSynchronizedBeforeSuite) {
|
||||||
|
if node.SynchronizedBeforeSuiteProc1Body != nil && node.SynchronizedBeforeSuiteAllProcsBody != nil {
|
||||||
|
appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType))
|
||||||
|
trackedFunctionError = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if node.SynchronizedBeforeSuiteProc1Body == nil {
|
||||||
|
body, hasContext := extractSynchronizedBeforeSuiteProc1Body(arg)
|
||||||
|
if body == nil {
|
||||||
|
appendError(types.GinkgoErrors.InvalidBodyTypeForSynchronizedBeforeSuiteProc1(t, node.CodeLocation))
|
||||||
|
trackedFunctionError = true
|
||||||
|
}
|
||||||
|
node.SynchronizedBeforeSuiteProc1Body, node.SynchronizedBeforeSuiteProc1BodyHasContext = body, hasContext
|
||||||
|
} else if node.SynchronizedBeforeSuiteAllProcsBody == nil {
|
||||||
|
body, hasContext := extractSynchronizedBeforeSuiteAllProcsBody(arg)
|
||||||
|
if body == nil {
|
||||||
|
appendError(types.GinkgoErrors.InvalidBodyTypeForSynchronizedBeforeSuiteAllProcs(t, node.CodeLocation))
|
||||||
|
trackedFunctionError = true
|
||||||
|
}
|
||||||
|
node.SynchronizedBeforeSuiteAllProcsBody, node.SynchronizedBeforeSuiteAllProcsBodyHasContext = body, hasContext
|
||||||
|
}
|
||||||
|
} else if nodeType.Is(types.NodeTypeSynchronizedAfterSuite) {
|
||||||
|
if node.SynchronizedAfterSuiteAllProcsBody != nil && node.SynchronizedAfterSuiteProc1Body != nil {
|
||||||
|
appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType))
|
||||||
|
trackedFunctionError = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
body, hasContext := extractBodyFunction(deprecationTracker, node.CodeLocation, arg)
|
||||||
|
if body == nil {
|
||||||
|
appendError(types.GinkgoErrors.InvalidBodyType(t, node.CodeLocation, nodeType))
|
||||||
|
trackedFunctionError = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if node.SynchronizedAfterSuiteAllProcsBody == nil {
|
||||||
|
node.SynchronizedAfterSuiteAllProcsBody, node.SynchronizedAfterSuiteAllProcsBodyHasContext = body, hasContext
|
||||||
|
} else if node.SynchronizedAfterSuiteProc1Body == nil {
|
||||||
|
node.SynchronizedAfterSuiteProc1Body, node.SynchronizedAfterSuiteProc1BodyHasContext = body, hasContext
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if node.Body != nil {
|
if node.Body != nil {
|
||||||
appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType))
|
appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType))
|
||||||
trackedFunctionError = true
|
trackedFunctionError = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
isValid := (t.NumOut() == 0) && (t.NumIn() <= 1) && (t.NumIn() == 0 || t.In(0) == reflect.TypeOf(make(Done)))
|
node.Body, node.HasContext = extractBodyFunction(deprecationTracker, node.CodeLocation, arg)
|
||||||
if !isValid {
|
if node.Body == nil {
|
||||||
appendError(types.GinkgoErrors.InvalidBodyType(t, node.CodeLocation, nodeType))
|
appendError(types.GinkgoErrors.InvalidBodyType(t, node.CodeLocation, nodeType))
|
||||||
trackedFunctionError = true
|
trackedFunctionError = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if t.NumIn() == 0 {
|
|
||||||
node.Body = arg.(func())
|
|
||||||
} else {
|
|
||||||
deprecationTracker.TrackDeprecation(types.Deprecations.Async(), node.CodeLocation)
|
|
||||||
deprecatedAsyncBody := arg.(func(Done))
|
|
||||||
node.Body = func() { deprecatedAsyncBody(make(Done)) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
remainingArgs = append(remainingArgs, arg)
|
remainingArgs = append(remainingArgs, arg)
|
||||||
@ -320,9 +381,24 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
|
|||||||
appendError(types.GinkgoErrors.InvalidDeclarationOfFocusedAndPending(node.CodeLocation, nodeType))
|
appendError(types.GinkgoErrors.InvalidDeclarationOfFocusedAndPending(node.CodeLocation, nodeType))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasContext := node.HasContext || node.SynchronizedAfterSuiteProc1BodyHasContext || node.SynchronizedAfterSuiteAllProcsBodyHasContext || node.SynchronizedBeforeSuiteProc1BodyHasContext || node.SynchronizedBeforeSuiteAllProcsBodyHasContext
|
||||||
|
|
||||||
|
if !hasContext && (node.NodeTimeout > 0 || node.SpecTimeout > 0 || node.GracePeriod > 0) && len(errors) == 0 {
|
||||||
|
appendError(types.GinkgoErrors.InvalidTimeoutOrGracePeriodForNonContextNode(node.CodeLocation, nodeType))
|
||||||
|
}
|
||||||
|
|
||||||
if !node.NodeType.Is(types.NodeTypeReportBeforeEach|types.NodeTypeReportAfterEach|types.NodeTypeSynchronizedBeforeSuite|types.NodeTypeSynchronizedAfterSuite|types.NodeTypeReportAfterSuite) && node.Body == nil && !node.MarkedPending && !trackedFunctionError {
|
if !node.NodeType.Is(types.NodeTypeReportBeforeEach|types.NodeTypeReportAfterEach|types.NodeTypeSynchronizedBeforeSuite|types.NodeTypeSynchronizedAfterSuite|types.NodeTypeReportAfterSuite) && node.Body == nil && !node.MarkedPending && !trackedFunctionError {
|
||||||
appendError(types.GinkgoErrors.MissingBodyFunction(node.CodeLocation, nodeType))
|
appendError(types.GinkgoErrors.MissingBodyFunction(node.CodeLocation, nodeType))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if node.NodeType.Is(types.NodeTypeSynchronizedBeforeSuite) && !trackedFunctionError && (node.SynchronizedBeforeSuiteProc1Body == nil || node.SynchronizedBeforeSuiteAllProcsBody == nil) {
|
||||||
|
appendError(types.GinkgoErrors.MissingBodyFunction(node.CodeLocation, nodeType))
|
||||||
|
}
|
||||||
|
|
||||||
|
if node.NodeType.Is(types.NodeTypeSynchronizedAfterSuite) && !trackedFunctionError && (node.SynchronizedAfterSuiteProc1Body == nil || node.SynchronizedAfterSuiteAllProcsBody == nil) {
|
||||||
|
appendError(types.GinkgoErrors.MissingBodyFunction(node.CodeLocation, nodeType))
|
||||||
|
}
|
||||||
|
|
||||||
for _, arg := range remainingArgs {
|
for _, arg := range remainingArgs {
|
||||||
appendError(types.GinkgoErrors.UnknownDecorator(node.CodeLocation, nodeType, arg))
|
appendError(types.GinkgoErrors.UnknownDecorator(node.CodeLocation, nodeType, arg))
|
||||||
}
|
}
|
||||||
@ -334,52 +410,151 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
|
|||||||
return node, errors
|
return node, errors
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCleanupNode(fail func(string, types.CodeLocation), args ...interface{}) (Node, []error) {
|
var doneType = reflect.TypeOf(make(Done))
|
||||||
baseOffset := 2
|
|
||||||
node := Node{
|
func extractBodyFunction(deprecationTracker *types.DeprecationTracker, cl types.CodeLocation, arg interface{}) (func(SpecContext), bool) {
|
||||||
ID: UniqueNodeID(),
|
t := reflect.TypeOf(arg)
|
||||||
NodeType: types.NodeTypeCleanupInvalid,
|
if t.NumOut() > 0 || t.NumIn() > 1 {
|
||||||
CodeLocation: types.NewCodeLocation(baseOffset),
|
return nil, false
|
||||||
NestingLevel: -1,
|
|
||||||
PollProgressAfter: -1,
|
|
||||||
PollProgressInterval: -1,
|
|
||||||
}
|
|
||||||
remainingArgs := []interface{}{}
|
|
||||||
for _, arg := range args {
|
|
||||||
switch t := reflect.TypeOf(arg); {
|
|
||||||
case t == reflect.TypeOf(Offset(0)):
|
|
||||||
node.CodeLocation = types.NewCodeLocation(baseOffset + int(arg.(Offset)))
|
|
||||||
case t == reflect.TypeOf(types.CodeLocation{}):
|
|
||||||
node.CodeLocation = arg.(types.CodeLocation)
|
|
||||||
case t == reflect.TypeOf(PollProgressAfter(0)):
|
|
||||||
node.PollProgressAfter = time.Duration(arg.(PollProgressAfter))
|
|
||||||
case t == reflect.TypeOf(PollProgressInterval(0)):
|
|
||||||
node.PollProgressInterval = time.Duration(arg.(PollProgressInterval))
|
|
||||||
default:
|
|
||||||
remainingArgs = append(remainingArgs, arg)
|
|
||||||
}
|
}
|
||||||
|
if t.NumIn() == 1 {
|
||||||
|
if t.In(0) == doneType {
|
||||||
|
deprecationTracker.TrackDeprecation(types.Deprecations.Async(), cl)
|
||||||
|
deprecatedAsyncBody := arg.(func(Done))
|
||||||
|
return func(SpecContext) { deprecatedAsyncBody(make(Done)) }, false
|
||||||
|
} else if t.In(0).Implements(specContextType) {
|
||||||
|
return arg.(func(SpecContext)), true
|
||||||
|
} else if t.In(0).Implements(contextType) {
|
||||||
|
body := arg.(func(context.Context))
|
||||||
|
return func(c SpecContext) { body(c) }, true
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(remainingArgs) == 0 {
|
return nil, false
|
||||||
return Node{}, []error{types.GinkgoErrors.DeferCleanupInvalidFunction(node.CodeLocation)}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body := arg.(func())
|
||||||
|
return func(SpecContext) { body() }, false
|
||||||
|
}
|
||||||
|
|
||||||
|
var byteType = reflect.TypeOf([]byte{})
|
||||||
|
|
||||||
|
func extractSynchronizedBeforeSuiteProc1Body(arg interface{}) (func(SpecContext) []byte, bool) {
|
||||||
|
t := reflect.TypeOf(arg)
|
||||||
|
v := reflect.ValueOf(arg)
|
||||||
|
|
||||||
|
if t.NumOut() > 1 || t.NumIn() > 1 {
|
||||||
|
return nil, false
|
||||||
|
} else if t.NumOut() == 1 && t.Out(0) != byteType {
|
||||||
|
return nil, false
|
||||||
|
} else if t.NumIn() == 1 && !t.In(0).Implements(contextType) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
hasContext := t.NumIn() == 1
|
||||||
|
|
||||||
|
return func(c SpecContext) []byte {
|
||||||
|
var out []reflect.Value
|
||||||
|
if hasContext {
|
||||||
|
out = v.Call([]reflect.Value{reflect.ValueOf(c)})
|
||||||
|
} else {
|
||||||
|
out = v.Call([]reflect.Value{})
|
||||||
|
}
|
||||||
|
if len(out) == 1 {
|
||||||
|
return (out[0].Interface()).([]byte)
|
||||||
|
} else {
|
||||||
|
return []byte{}
|
||||||
|
}
|
||||||
|
}, hasContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractSynchronizedBeforeSuiteAllProcsBody(arg interface{}) (func(SpecContext, []byte), bool) {
|
||||||
|
t := reflect.TypeOf(arg)
|
||||||
|
v := reflect.ValueOf(arg)
|
||||||
|
hasContext, hasByte := false, false
|
||||||
|
|
||||||
|
if t.NumOut() > 0 || t.NumIn() > 2 {
|
||||||
|
return nil, false
|
||||||
|
} else if t.NumIn() == 2 && t.In(0).Implements(contextType) && t.In(1) == byteType {
|
||||||
|
hasContext, hasByte = true, true
|
||||||
|
} else if t.NumIn() == 1 && t.In(0).Implements(contextType) {
|
||||||
|
hasContext = true
|
||||||
|
} else if t.NumIn() == 1 && t.In(0) == byteType {
|
||||||
|
hasByte = true
|
||||||
|
} else if t.NumIn() != 0 {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return func(c SpecContext, b []byte) {
|
||||||
|
in := []reflect.Value{}
|
||||||
|
if hasContext {
|
||||||
|
in = append(in, reflect.ValueOf(c))
|
||||||
|
}
|
||||||
|
if hasByte {
|
||||||
|
in = append(in, reflect.ValueOf(b))
|
||||||
|
}
|
||||||
|
v.Call(in)
|
||||||
|
}, hasContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCleanupNode(deprecationTracker *types.DeprecationTracker, fail func(string, types.CodeLocation), args ...interface{}) (Node, []error) {
|
||||||
|
decorations, remainingArgs := PartitionDecorations(args...)
|
||||||
|
baseOffset := 2
|
||||||
|
cl := types.NewCodeLocation(baseOffset)
|
||||||
|
finalArgs := []interface{}{}
|
||||||
|
for _, arg := range decorations {
|
||||||
|
switch t := reflect.TypeOf(arg); {
|
||||||
|
case t == reflect.TypeOf(Offset(0)):
|
||||||
|
cl = types.NewCodeLocation(baseOffset + int(arg.(Offset)))
|
||||||
|
case t == reflect.TypeOf(types.CodeLocation{}):
|
||||||
|
cl = arg.(types.CodeLocation)
|
||||||
|
default:
|
||||||
|
finalArgs = append(finalArgs, arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finalArgs = append(finalArgs, cl)
|
||||||
|
|
||||||
|
if len(remainingArgs) == 0 {
|
||||||
|
return Node{}, []error{types.GinkgoErrors.DeferCleanupInvalidFunction(cl)}
|
||||||
|
}
|
||||||
|
|
||||||
callback := reflect.ValueOf(remainingArgs[0])
|
callback := reflect.ValueOf(remainingArgs[0])
|
||||||
if !(callback.Kind() == reflect.Func && callback.Type().NumOut() <= 1) {
|
if !(callback.Kind() == reflect.Func && callback.Type().NumOut() <= 1) {
|
||||||
return Node{}, []error{types.GinkgoErrors.DeferCleanupInvalidFunction(node.CodeLocation)}
|
return Node{}, []error{types.GinkgoErrors.DeferCleanupInvalidFunction(cl)}
|
||||||
}
|
}
|
||||||
|
|
||||||
callArgs := []reflect.Value{}
|
callArgs := []reflect.Value{}
|
||||||
for _, arg := range remainingArgs[1:] {
|
for _, arg := range remainingArgs[1:] {
|
||||||
callArgs = append(callArgs, reflect.ValueOf(arg))
|
callArgs = append(callArgs, reflect.ValueOf(arg))
|
||||||
}
|
}
|
||||||
cl := node.CodeLocation
|
|
||||||
node.Body = func() {
|
hasContext := false
|
||||||
out := callback.Call(callArgs)
|
t := callback.Type()
|
||||||
|
if t.NumIn() > 0 {
|
||||||
|
if t.In(0).Implements(specContextType) {
|
||||||
|
hasContext = true
|
||||||
|
} else if t.In(0).Implements(contextType) && (len(callArgs) == 0 || !callArgs[0].Type().Implements(contextType)) {
|
||||||
|
hasContext = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleFailure := func(out []reflect.Value) {
|
||||||
if len(out) == 1 && !out[0].IsNil() {
|
if len(out) == 1 && !out[0].IsNil() {
|
||||||
fail(fmt.Sprintf("DeferCleanup callback returned error: %v", out[0]), cl)
|
fail(fmt.Sprintf("DeferCleanup callback returned error: %v", out[0]), cl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return node, nil
|
if hasContext {
|
||||||
|
finalArgs = append(finalArgs, func(c SpecContext) {
|
||||||
|
out := callback.Call(append([]reflect.Value{reflect.ValueOf(c)}, callArgs...))
|
||||||
|
handleFailure(out)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
finalArgs = append(finalArgs, func() {
|
||||||
|
out := callback.Call(callArgs)
|
||||||
|
handleFailure(out)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewNode(deprecationTracker, types.NodeTypeCleanupInvalid, "", finalArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n Node) IsZero() bool {
|
func (n Node) IsZero() bool {
|
||||||
|
4
vendor/github.com/onsi/ginkgo/v2/internal/progress_report.go
generated
vendored
4
vendor/github.com/onsi/ginkgo/v2/internal/progress_report.go
generated
vendored
@ -48,7 +48,7 @@ type ProgressStepCursor struct {
|
|||||||
StartTime time.Time
|
StartTime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProgressReport(isRunningInParallel bool, report types.SpecReport, currentNode Node, currentNodeStartTime time.Time, currentStep ProgressStepCursor, gwOutput string, sourceRoots []string, includeAll bool) (types.ProgressReport, error) {
|
func NewProgressReport(isRunningInParallel bool, report types.SpecReport, currentNode Node, currentNodeStartTime time.Time, currentStep ProgressStepCursor, gwOutput string, additionalReports []string, sourceRoots []string, includeAll bool) (types.ProgressReport, error) {
|
||||||
pr := types.ProgressReport{
|
pr := types.ProgressReport{
|
||||||
ParallelProcess: report.ParallelProcess,
|
ParallelProcess: report.ParallelProcess,
|
||||||
RunningInParallel: isRunningInParallel,
|
RunningInParallel: isRunningInParallel,
|
||||||
@ -69,6 +69,8 @@ func NewProgressReport(isRunningInParallel bool, report types.SpecReport, curren
|
|||||||
CurrentStepLocation: currentStep.CodeLocation,
|
CurrentStepLocation: currentStep.CodeLocation,
|
||||||
CurrentStepStartTime: currentStep.StartTime,
|
CurrentStepStartTime: currentStep.StartTime,
|
||||||
|
|
||||||
|
AdditionalReports: additionalReports,
|
||||||
|
|
||||||
CapturedGinkgoWriterOutput: gwOutput,
|
CapturedGinkgoWriterOutput: gwOutput,
|
||||||
GinkgoWriterOffset: len(gwOutput),
|
GinkgoWriterOffset: len(gwOutput),
|
||||||
}
|
}
|
||||||
|
5
vendor/github.com/onsi/ginkgo/v2/internal/spec.go
generated
vendored
5
vendor/github.com/onsi/ginkgo/v2/internal/spec.go
generated
vendored
@ -2,6 +2,7 @@ package internal
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/onsi/ginkgo/v2/types"
|
"github.com/onsi/ginkgo/v2/types"
|
||||||
)
|
)
|
||||||
@ -40,6 +41,10 @@ func (s Spec) FlakeAttempts() int {
|
|||||||
return flakeAttempts
|
return flakeAttempts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s Spec) SpecTimeout() time.Duration {
|
||||||
|
return s.FirstNodeWithType(types.NodeTypeIt).SpecTimeout
|
||||||
|
}
|
||||||
|
|
||||||
type Specs []Spec
|
type Specs []Spec
|
||||||
|
|
||||||
func (s Specs) HasAnySpecsMarkedPending() bool {
|
func (s Specs) HasAnySpecsMarkedPending() bool {
|
||||||
|
90
vendor/github.com/onsi/ginkgo/v2/internal/spec_context.go
generated
vendored
Normal file
90
vendor/github.com/onsi/ginkgo/v2/internal/spec_context.go
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"sort"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/onsi/ginkgo/v2/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SpecContext interface {
|
||||||
|
context.Context
|
||||||
|
|
||||||
|
SpecReport() types.SpecReport
|
||||||
|
AttachProgressReporter(func() string) func()
|
||||||
|
}
|
||||||
|
|
||||||
|
type specContext struct {
|
||||||
|
context.Context
|
||||||
|
|
||||||
|
cancel context.CancelFunc
|
||||||
|
lock *sync.Mutex
|
||||||
|
progressReporters map[int]func() string
|
||||||
|
prCounter int
|
||||||
|
|
||||||
|
suite *Suite
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
SpecContext includes a reference to `suite` and embeds itself in itself as a "GINKGO_SPEC_CONTEXT" value. This allows users to create child Contexts without having down-stream consumers (e.g. Gomega) lose access to the SpecContext and its methods. This allows us to build extensions on top of Ginkgo that simply take an all-encompassing context.
|
||||||
|
|
||||||
|
Note that while SpecContext is used to enforce deadlines by Ginkgo it is not configured as a context.WithDeadline. Instead, Ginkgo owns responsibility for cancelling the context when the deadline elapses.
|
||||||
|
|
||||||
|
This is because Ginkgo needs finer control over when the context is canceled. Specifically, Ginkgo needs to generate a ProgressReport before it cancels the context to ensure progress is captured where the spec is currently running. The only way to avoid a race here is to manually control the cancellation.
|
||||||
|
*/
|
||||||
|
func NewSpecContext(suite *Suite) *specContext {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
sc := &specContext{
|
||||||
|
cancel: cancel,
|
||||||
|
suite: suite,
|
||||||
|
lock: &sync.Mutex{},
|
||||||
|
prCounter: 0,
|
||||||
|
progressReporters: map[int]func() string{},
|
||||||
|
}
|
||||||
|
ctx = context.WithValue(ctx, "GINKGO_SPEC_CONTEXT", sc) //yes, yes, the go docs say don't use a string for a key... but we'd rather avoid a circular dependency between Gomega and Ginkgo
|
||||||
|
sc.Context = ctx //thank goodness for garbage collectors that can handle circular dependencies
|
||||||
|
|
||||||
|
return sc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *specContext) SpecReport() types.SpecReport {
|
||||||
|
return sc.suite.CurrentSpecReport()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *specContext) AttachProgressReporter(reporter func() string) func() {
|
||||||
|
sc.lock.Lock()
|
||||||
|
defer sc.lock.Unlock()
|
||||||
|
sc.prCounter += 1
|
||||||
|
prCounter := sc.prCounter
|
||||||
|
sc.progressReporters[prCounter] = reporter
|
||||||
|
|
||||||
|
return func() {
|
||||||
|
sc.lock.Lock()
|
||||||
|
defer sc.lock.Unlock()
|
||||||
|
delete(sc.progressReporters, prCounter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *specContext) QueryProgressReporters() []string {
|
||||||
|
sc.lock.Lock()
|
||||||
|
keys := []int{}
|
||||||
|
for key := range sc.progressReporters {
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
sort.Ints(keys)
|
||||||
|
reporters := []func() string{}
|
||||||
|
for _, key := range keys {
|
||||||
|
reporters = append(reporters, sc.progressReporters[key])
|
||||||
|
}
|
||||||
|
sc.lock.Unlock()
|
||||||
|
|
||||||
|
if len(reporters) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := []string{}
|
||||||
|
for _, reporter := range reporters {
|
||||||
|
out = append(out, reporter())
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
239
vendor/github.com/onsi/ginkgo/v2/internal/suite.go
generated
vendored
239
vendor/github.com/onsi/ginkgo/v2/internal/suite.go
generated
vendored
@ -5,7 +5,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/onsi/ginkgo/v2/formatter"
|
|
||||||
"github.com/onsi/ginkgo/v2/internal/interrupt_handler"
|
"github.com/onsi/ginkgo/v2/internal/interrupt_handler"
|
||||||
"github.com/onsi/ginkgo/v2/internal/parallel_support"
|
"github.com/onsi/ginkgo/v2/internal/parallel_support"
|
||||||
"github.com/onsi/ginkgo/v2/reporters"
|
"github.com/onsi/ginkgo/v2/reporters"
|
||||||
@ -35,6 +34,7 @@ type Suite struct {
|
|||||||
outputInterceptor OutputInterceptor
|
outputInterceptor OutputInterceptor
|
||||||
interruptHandler interrupt_handler.InterruptHandlerInterface
|
interruptHandler interrupt_handler.InterruptHandlerInterface
|
||||||
config types.SuiteConfig
|
config types.SuiteConfig
|
||||||
|
deadline time.Time
|
||||||
|
|
||||||
skipAll bool
|
skipAll bool
|
||||||
report types.Report
|
report types.Report
|
||||||
@ -42,6 +42,8 @@ type Suite struct {
|
|||||||
currentNode Node
|
currentNode Node
|
||||||
currentNodeStartTime time.Time
|
currentNodeStartTime time.Time
|
||||||
|
|
||||||
|
currentSpecContext *specContext
|
||||||
|
|
||||||
progressStepCursor ProgressStepCursor
|
progressStepCursor ProgressStepCursor
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -98,6 +100,10 @@ func (suite *Suite) Run(description string, suiteLabels Labels, suitePath string
|
|||||||
suite.interruptHandler = interruptHandler
|
suite.interruptHandler = interruptHandler
|
||||||
suite.config = suiteConfig
|
suite.config = suiteConfig
|
||||||
|
|
||||||
|
if suite.config.Timeout > 0 {
|
||||||
|
suite.deadline = time.Now().Add(suite.config.Timeout)
|
||||||
|
}
|
||||||
|
|
||||||
cancelProgressHandler := progressSignalRegistrar(suite.handleProgressSignal)
|
cancelProgressHandler := progressSignalRegistrar(suite.handleProgressSignal)
|
||||||
|
|
||||||
success := suite.runSpecs(description, suiteLabels, suitePath, hasProgrammaticFocus, specs)
|
success := suite.runSpecs(description, suiteLabels, suitePath, hasProgrammaticFocus, specs)
|
||||||
@ -165,7 +171,7 @@ func (suite *Suite) PushNode(node Node) error {
|
|||||||
err = types.GinkgoErrors.CaughtPanicDuringABuildPhase(e, node.CodeLocation)
|
err = types.GinkgoErrors.CaughtPanicDuringABuildPhase(e, node.CodeLocation)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
node.Body()
|
node.Body(nil)
|
||||||
return err
|
return err
|
||||||
}()
|
}()
|
||||||
suite.tree = parentTree
|
suite.tree = parentTree
|
||||||
@ -270,10 +276,14 @@ func (suite *Suite) generateProgressReport(fullReport bool) types.ProgressReport
|
|||||||
suite.selectiveLock.Lock()
|
suite.selectiveLock.Lock()
|
||||||
defer suite.selectiveLock.Unlock()
|
defer suite.selectiveLock.Unlock()
|
||||||
|
|
||||||
|
var additionalReports []string
|
||||||
|
if suite.currentSpecContext != nil {
|
||||||
|
additionalReports = suite.currentSpecContext.QueryProgressReporters()
|
||||||
|
}
|
||||||
stepCursor := suite.progressStepCursor
|
stepCursor := suite.progressStepCursor
|
||||||
|
|
||||||
gwOutput := suite.currentSpecReport.CapturedGinkgoWriterOutput + string(suite.writer.Bytes())
|
gwOutput := suite.currentSpecReport.CapturedGinkgoWriterOutput + string(suite.writer.Bytes())
|
||||||
pr, err := NewProgressReport(suite.isRunningInParallel(), suite.currentSpecReport, suite.currentNode, suite.currentNodeStartTime, stepCursor, gwOutput, suite.config.SourceRoots, fullReport)
|
pr, err := NewProgressReport(suite.isRunningInParallel(), suite.currentSpecReport, suite.currentNode, suite.currentNodeStartTime, stepCursor, gwOutput, additionalReports, suite.config.SourceRoots, fullReport)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("{{red}}Failed to generate progress report:{{/}}\n%s\n", err.Error())
|
fmt.Printf("{{red}}Failed to generate progress report:{{/}}\n%s\n", err.Error())
|
||||||
@ -283,7 +293,11 @@ func (suite *Suite) generateProgressReport(fullReport bool) types.ProgressReport
|
|||||||
|
|
||||||
func (suite *Suite) handleProgressSignal() {
|
func (suite *Suite) handleProgressSignal() {
|
||||||
report := suite.generateProgressReport(false)
|
report := suite.generateProgressReport(false)
|
||||||
|
report.Message = "{{bold}}You've requested a progress report:{{/}}"
|
||||||
|
suite.emitProgressReport(report)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *Suite) emitProgressReport(report types.ProgressReport) {
|
||||||
suite.selectiveLock.Lock()
|
suite.selectiveLock.Lock()
|
||||||
suite.currentSpecReport.ProgressReports = append(suite.currentSpecReport.ProgressReports, report.WithoutCapturedGinkgoWriterOutput())
|
suite.currentSpecReport.ProgressReports = append(suite.currentSpecReport.ProgressReports, report.WithoutCapturedGinkgoWriterOutput())
|
||||||
suite.selectiveLock.Unlock()
|
suite.selectiveLock.Unlock()
|
||||||
@ -383,12 +397,16 @@ func (suite *Suite) runSpecs(description string, suiteLabels Labels, suitePath s
|
|||||||
suite.runAfterSuiteCleanup(numSpecsThatWillBeRun)
|
suite.runAfterSuiteCleanup(numSpecsThatWillBeRun)
|
||||||
|
|
||||||
interruptStatus := suite.interruptHandler.Status()
|
interruptStatus := suite.interruptHandler.Status()
|
||||||
if interruptStatus.Interrupted {
|
if interruptStatus.Interrupted() {
|
||||||
suite.report.SpecialSuiteFailureReasons = append(suite.report.SpecialSuiteFailureReasons, interruptStatus.Cause.String())
|
suite.report.SpecialSuiteFailureReasons = append(suite.report.SpecialSuiteFailureReasons, interruptStatus.Cause.String())
|
||||||
suite.report.SuiteSucceeded = false
|
suite.report.SuiteSucceeded = false
|
||||||
}
|
}
|
||||||
suite.report.EndTime = time.Now()
|
suite.report.EndTime = time.Now()
|
||||||
suite.report.RunTime = suite.report.EndTime.Sub(suite.report.StartTime)
|
suite.report.RunTime = suite.report.EndTime.Sub(suite.report.StartTime)
|
||||||
|
if !suite.deadline.IsZero() && suite.report.EndTime.After(suite.deadline) {
|
||||||
|
suite.report.SpecialSuiteFailureReasons = append(suite.report.SpecialSuiteFailureReasons, "Suite Timeout Elapsed")
|
||||||
|
suite.report.SuiteSucceeded = false
|
||||||
|
}
|
||||||
|
|
||||||
if suite.config.ParallelProcess == 1 {
|
if suite.config.ParallelProcess == 1 {
|
||||||
suite.runReportAfterSuite()
|
suite.runReportAfterSuite()
|
||||||
@ -402,9 +420,8 @@ func (suite *Suite) runSpecs(description string, suiteLabels Labels, suitePath s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *Suite) runBeforeSuite(numSpecsThatWillBeRun int) {
|
func (suite *Suite) runBeforeSuite(numSpecsThatWillBeRun int) {
|
||||||
interruptStatus := suite.interruptHandler.Status()
|
|
||||||
beforeSuiteNode := suite.suiteNodes.FirstNodeWithType(types.NodeTypeBeforeSuite | types.NodeTypeSynchronizedBeforeSuite)
|
beforeSuiteNode := suite.suiteNodes.FirstNodeWithType(types.NodeTypeBeforeSuite | types.NodeTypeSynchronizedBeforeSuite)
|
||||||
if !beforeSuiteNode.IsZero() && !interruptStatus.Interrupted && numSpecsThatWillBeRun > 0 {
|
if !beforeSuiteNode.IsZero() && numSpecsThatWillBeRun > 0 {
|
||||||
suite.selectiveLock.Lock()
|
suite.selectiveLock.Lock()
|
||||||
suite.currentSpecReport = types.SpecReport{
|
suite.currentSpecReport = types.SpecReport{
|
||||||
LeafNodeType: beforeSuiteNode.NodeType,
|
LeafNodeType: beforeSuiteNode.NodeType,
|
||||||
@ -414,7 +431,7 @@ func (suite *Suite) runBeforeSuite(numSpecsThatWillBeRun int) {
|
|||||||
suite.selectiveLock.Unlock()
|
suite.selectiveLock.Unlock()
|
||||||
|
|
||||||
suite.reporter.WillRun(suite.currentSpecReport)
|
suite.reporter.WillRun(suite.currentSpecReport)
|
||||||
suite.runSuiteNode(beforeSuiteNode, interruptStatus.Channel)
|
suite.runSuiteNode(beforeSuiteNode)
|
||||||
if suite.currentSpecReport.State.Is(types.SpecStateSkipped) {
|
if suite.currentSpecReport.State.Is(types.SpecStateSkipped) {
|
||||||
suite.report.SpecialSuiteFailureReasons = append(suite.report.SpecialSuiteFailureReasons, "Suite skipped in BeforeSuite")
|
suite.report.SpecialSuiteFailureReasons = append(suite.report.SpecialSuiteFailureReasons, "Suite skipped in BeforeSuite")
|
||||||
suite.skipAll = true
|
suite.skipAll = true
|
||||||
@ -435,7 +452,7 @@ func (suite *Suite) runAfterSuiteCleanup(numSpecsThatWillBeRun int) {
|
|||||||
suite.selectiveLock.Unlock()
|
suite.selectiveLock.Unlock()
|
||||||
|
|
||||||
suite.reporter.WillRun(suite.currentSpecReport)
|
suite.reporter.WillRun(suite.currentSpecReport)
|
||||||
suite.runSuiteNode(afterSuiteNode, suite.interruptHandler.Status().Channel)
|
suite.runSuiteNode(afterSuiteNode)
|
||||||
suite.processCurrentSpecReport()
|
suite.processCurrentSpecReport()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,7 +468,7 @@ func (suite *Suite) runAfterSuiteCleanup(numSpecsThatWillBeRun int) {
|
|||||||
suite.selectiveLock.Unlock()
|
suite.selectiveLock.Unlock()
|
||||||
|
|
||||||
suite.reporter.WillRun(suite.currentSpecReport)
|
suite.reporter.WillRun(suite.currentSpecReport)
|
||||||
suite.runSuiteNode(cleanupNode, suite.interruptHandler.Status().Channel)
|
suite.runSuiteNode(cleanupNode)
|
||||||
suite.processCurrentSpecReport()
|
suite.processCurrentSpecReport()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -490,16 +507,11 @@ func (suite *Suite) reportEach(spec Spec, nodeType types.NodeType) {
|
|||||||
suite.writer.Truncate()
|
suite.writer.Truncate()
|
||||||
suite.outputInterceptor.StartInterceptingOutput()
|
suite.outputInterceptor.StartInterceptingOutput()
|
||||||
report := suite.currentSpecReport
|
report := suite.currentSpecReport
|
||||||
nodes[i].Body = func() {
|
nodes[i].Body = func(SpecContext) {
|
||||||
nodes[i].ReportEachBody(report)
|
nodes[i].ReportEachBody(report)
|
||||||
}
|
}
|
||||||
suite.interruptHandler.SetInterruptPlaceholderMessage(formatter.Fiw(0, formatter.COLS,
|
state, failure := suite.runNode(nodes[i], time.Time{}, spec.Nodes.BestTextFor(nodes[i]))
|
||||||
"{{yellow}}Ginkgo received an interrupt signal but is currently running a %s node. To avoid an invalid report the %s node will not be interrupted however subsequent tests will be skipped.{{/}}\n\n{{bold}}The running %s node is at:\n%s.{{/}}",
|
|
||||||
nodeType, nodeType, nodeType,
|
|
||||||
nodes[i].CodeLocation,
|
|
||||||
))
|
|
||||||
state, failure := suite.runNode(nodes[i], nil, spec.Nodes.BestTextFor(nodes[i]))
|
|
||||||
suite.interruptHandler.ClearInterruptPlaceholderMessage()
|
|
||||||
// If the spec is not in a failure state (i.e. it's Passed/Skipped/Pending) and the reporter has failed, override the state.
|
// If the spec is not in a failure state (i.e. it's Passed/Skipped/Pending) and the reporter has failed, override the state.
|
||||||
// Also, if the reporter is every aborted - always override the state to propagate the abort
|
// Also, if the reporter is every aborted - always override the state to propagate the abort
|
||||||
if (!suite.currentSpecReport.State.Is(types.SpecStateFailureStates) && state.Is(types.SpecStateFailureStates)) || state.Is(types.SpecStateAborted) {
|
if (!suite.currentSpecReport.State.Is(types.SpecStateFailureStates) && state.Is(types.SpecStateFailureStates)) || state.Is(types.SpecStateAborted) {
|
||||||
@ -511,7 +523,7 @@ func (suite *Suite) reportEach(spec Spec, nodeType types.NodeType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *Suite) runSuiteNode(node Node, interruptChannel chan interface{}) {
|
func (suite *Suite) runSuiteNode(node Node) {
|
||||||
if suite.config.DryRun {
|
if suite.config.DryRun {
|
||||||
suite.currentSpecReport.State = types.SpecStatePassed
|
suite.currentSpecReport.State = types.SpecStatePassed
|
||||||
return
|
return
|
||||||
@ -524,13 +536,13 @@ func (suite *Suite) runSuiteNode(node Node, interruptChannel chan interface{}) {
|
|||||||
var err error
|
var err error
|
||||||
switch node.NodeType {
|
switch node.NodeType {
|
||||||
case types.NodeTypeBeforeSuite, types.NodeTypeAfterSuite:
|
case types.NodeTypeBeforeSuite, types.NodeTypeAfterSuite:
|
||||||
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, interruptChannel, "")
|
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "")
|
||||||
case types.NodeTypeCleanupAfterSuite:
|
case types.NodeTypeCleanupAfterSuite:
|
||||||
if suite.config.ParallelTotal > 1 && suite.config.ParallelProcess == 1 {
|
if suite.config.ParallelTotal > 1 && suite.config.ParallelProcess == 1 {
|
||||||
err = suite.client.BlockUntilNonprimaryProcsHaveFinished()
|
err = suite.client.BlockUntilNonprimaryProcsHaveFinished()
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, interruptChannel, "")
|
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "")
|
||||||
}
|
}
|
||||||
case types.NodeTypeSynchronizedBeforeSuite:
|
case types.NodeTypeSynchronizedBeforeSuite:
|
||||||
var data []byte
|
var data []byte
|
||||||
@ -540,8 +552,9 @@ func (suite *Suite) runSuiteNode(node Node, interruptChannel chan interface{}) {
|
|||||||
suite.outputInterceptor.StopInterceptingAndReturnOutput()
|
suite.outputInterceptor.StopInterceptingAndReturnOutput()
|
||||||
suite.outputInterceptor.StartInterceptingOutputAndForwardTo(suite.client)
|
suite.outputInterceptor.StartInterceptingOutputAndForwardTo(suite.client)
|
||||||
}
|
}
|
||||||
node.Body = func() { data = node.SynchronizedBeforeSuiteProc1Body() }
|
node.Body = func(c SpecContext) { data = node.SynchronizedBeforeSuiteProc1Body(c) }
|
||||||
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, interruptChannel, "")
|
node.HasContext = node.SynchronizedBeforeSuiteProc1BodyHasContext
|
||||||
|
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "")
|
||||||
if suite.config.ParallelTotal > 1 {
|
if suite.config.ParallelTotal > 1 {
|
||||||
suite.currentSpecReport.CapturedStdOutErr += suite.outputInterceptor.StopInterceptingAndReturnOutput()
|
suite.currentSpecReport.CapturedStdOutErr += suite.outputInterceptor.StopInterceptingAndReturnOutput()
|
||||||
suite.outputInterceptor.StartInterceptingOutput()
|
suite.outputInterceptor.StartInterceptingOutput()
|
||||||
@ -558,19 +571,21 @@ func (suite *Suite) runSuiteNode(node Node, interruptChannel chan interface{}) {
|
|||||||
switch proc1State {
|
switch proc1State {
|
||||||
case types.SpecStatePassed:
|
case types.SpecStatePassed:
|
||||||
runAllProcs = true
|
runAllProcs = true
|
||||||
case types.SpecStateFailed, types.SpecStatePanicked:
|
case types.SpecStateFailed, types.SpecStatePanicked, types.SpecStateTimedout:
|
||||||
err = types.GinkgoErrors.SynchronizedBeforeSuiteFailedOnProc1()
|
err = types.GinkgoErrors.SynchronizedBeforeSuiteFailedOnProc1()
|
||||||
case types.SpecStateInterrupted, types.SpecStateAborted, types.SpecStateSkipped:
|
case types.SpecStateInterrupted, types.SpecStateAborted, types.SpecStateSkipped:
|
||||||
suite.currentSpecReport.State = proc1State
|
suite.currentSpecReport.State = proc1State
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if runAllProcs {
|
if runAllProcs {
|
||||||
node.Body = func() { node.SynchronizedBeforeSuiteAllProcsBody(data) }
|
node.Body = func(c SpecContext) { node.SynchronizedBeforeSuiteAllProcsBody(c, data) }
|
||||||
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, interruptChannel, "")
|
node.HasContext = node.SynchronizedBeforeSuiteAllProcsBodyHasContext
|
||||||
|
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "")
|
||||||
}
|
}
|
||||||
case types.NodeTypeSynchronizedAfterSuite:
|
case types.NodeTypeSynchronizedAfterSuite:
|
||||||
node.Body = node.SynchronizedAfterSuiteAllProcsBody
|
node.Body = node.SynchronizedAfterSuiteAllProcsBody
|
||||||
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, interruptChannel, "")
|
node.HasContext = node.SynchronizedAfterSuiteAllProcsBodyHasContext
|
||||||
|
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "")
|
||||||
if suite.config.ParallelProcess == 1 {
|
if suite.config.ParallelProcess == 1 {
|
||||||
if suite.config.ParallelTotal > 1 {
|
if suite.config.ParallelTotal > 1 {
|
||||||
err = suite.client.BlockUntilNonprimaryProcsHaveFinished()
|
err = suite.client.BlockUntilNonprimaryProcsHaveFinished()
|
||||||
@ -582,7 +597,8 @@ func (suite *Suite) runSuiteNode(node Node, interruptChannel chan interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
node.Body = node.SynchronizedAfterSuiteProc1Body
|
node.Body = node.SynchronizedAfterSuiteProc1Body
|
||||||
state, failure := suite.runNode(node, interruptChannel, "")
|
node.HasContext = node.SynchronizedAfterSuiteProc1BodyHasContext
|
||||||
|
state, failure := suite.runNode(node, time.Time{}, "")
|
||||||
if suite.currentSpecReport.State.Is(types.SpecStatePassed) {
|
if suite.currentSpecReport.State.Is(types.SpecStatePassed) {
|
||||||
suite.currentSpecReport.State, suite.currentSpecReport.Failure = state, failure
|
suite.currentSpecReport.State, suite.currentSpecReport.Failure = state, failure
|
||||||
}
|
}
|
||||||
@ -616,13 +632,8 @@ func (suite *Suite) runReportAfterSuiteNode(node Node, report types.Report) {
|
|||||||
report = report.Add(aggregatedReport)
|
report = report.Add(aggregatedReport)
|
||||||
}
|
}
|
||||||
|
|
||||||
node.Body = func() { node.ReportAfterSuiteBody(report) }
|
node.Body = func(SpecContext) { node.ReportAfterSuiteBody(report) }
|
||||||
suite.interruptHandler.SetInterruptPlaceholderMessage(formatter.Fiw(0, formatter.COLS,
|
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "")
|
||||||
"{{yellow}}Ginkgo received an interrupt signal but is currently running a ReportAfterSuite node. To avoid an invalid report the ReportAfterSuite node will not be interrupted.{{/}}\n\n{{bold}}The running ReportAfterSuite node is at:\n%s.{{/}}",
|
|
||||||
node.CodeLocation,
|
|
||||||
))
|
|
||||||
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, nil, "")
|
|
||||||
suite.interruptHandler.ClearInterruptPlaceholderMessage()
|
|
||||||
|
|
||||||
suite.currentSpecReport.EndTime = time.Now()
|
suite.currentSpecReport.EndTime = time.Now()
|
||||||
suite.currentSpecReport.RunTime = suite.currentSpecReport.EndTime.Sub(suite.currentSpecReport.StartTime)
|
suite.currentSpecReport.RunTime = suite.currentSpecReport.EndTime.Sub(suite.currentSpecReport.StartTime)
|
||||||
@ -632,11 +643,22 @@ func (suite *Suite) runReportAfterSuiteNode(node Node, report types.Report) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *Suite) runNode(node Node, interruptChannel chan interface{}, text string) (types.SpecState, types.Failure) {
|
func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (types.SpecState, types.Failure) {
|
||||||
if node.NodeType.Is(types.NodeTypeCleanupAfterEach | types.NodeTypeCleanupAfterAll | types.NodeTypeCleanupAfterSuite) {
|
if node.NodeType.Is(types.NodeTypeCleanupAfterEach | types.NodeTypeCleanupAfterAll | types.NodeTypeCleanupAfterSuite) {
|
||||||
suite.cleanupNodes = suite.cleanupNodes.WithoutNode(node)
|
suite.cleanupNodes = suite.cleanupNodes.WithoutNode(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interruptStatus := suite.interruptHandler.Status()
|
||||||
|
if interruptStatus.Level == interrupt_handler.InterruptLevelBailOut {
|
||||||
|
return types.SpecStateSkipped, types.Failure{}
|
||||||
|
}
|
||||||
|
if interruptStatus.Level == interrupt_handler.InterruptLevelReportOnly && !node.NodeType.Is(types.NodeTypesAllowedDuringReportInterrupt) {
|
||||||
|
return types.SpecStateSkipped, types.Failure{}
|
||||||
|
}
|
||||||
|
if interruptStatus.Level == interrupt_handler.InterruptLevelCleanupAndReport && !node.NodeType.Is(types.NodeTypesAllowedDuringReportInterrupt|types.NodeTypesAllowedDuringCleanupInterrupt) {
|
||||||
|
return types.SpecStateSkipped, types.Failure{}
|
||||||
|
}
|
||||||
|
|
||||||
suite.selectiveLock.Lock()
|
suite.selectiveLock.Lock()
|
||||||
suite.currentNode = node
|
suite.currentNode = node
|
||||||
suite.currentNodeStartTime = time.Now()
|
suite.currentNodeStartTime = time.Now()
|
||||||
@ -666,6 +688,49 @@ func (suite *Suite) runNode(node Node, interruptChannel chan interface{}, text s
|
|||||||
} else {
|
} else {
|
||||||
failure.FailureNodeContext, failure.FailureNodeContainerIndex = types.FailureNodeInContainer, node.NestingLevel-1
|
failure.FailureNodeContext, failure.FailureNodeContainerIndex = types.FailureNodeInContainer, node.NestingLevel-1
|
||||||
}
|
}
|
||||||
|
var outcome types.SpecState
|
||||||
|
|
||||||
|
gracePeriod := suite.config.GracePeriod
|
||||||
|
if node.GracePeriod >= 0 {
|
||||||
|
gracePeriod = node.GracePeriod
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
deadline := suite.deadline
|
||||||
|
if deadline.IsZero() || (!specDeadline.IsZero() && specDeadline.Before(deadline)) {
|
||||||
|
deadline = specDeadline
|
||||||
|
}
|
||||||
|
if node.NodeTimeout > 0 && (deadline.IsZero() || deadline.Sub(now) > node.NodeTimeout) {
|
||||||
|
deadline = now.Add(node.NodeTimeout)
|
||||||
|
}
|
||||||
|
if (!deadline.IsZero() && deadline.Before(now)) || interruptStatus.Interrupted() {
|
||||||
|
//we're out of time already. let's wait for a NodeTimeout if we have it, or GracePeriod if we don't
|
||||||
|
if node.NodeTimeout > 0 {
|
||||||
|
deadline = now.Add(node.NodeTimeout)
|
||||||
|
} else {
|
||||||
|
deadline = now.Add(gracePeriod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !node.HasContext {
|
||||||
|
// this maps onto the pre-context behavior:
|
||||||
|
// - an interrupted node exits immediately. with this, context-less nodes that are in a spec with a SpecTimeout and/or are interrupted by other means will simply exit immediately after the timeout/interrupt
|
||||||
|
// - clean up nodes have up to GracePeriod (formerly hard-coded at 30s) to complete before they are interrupted
|
||||||
|
gracePeriod = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
sc := NewSpecContext(suite)
|
||||||
|
defer sc.cancel()
|
||||||
|
|
||||||
|
suite.selectiveLock.Lock()
|
||||||
|
suite.currentSpecContext = sc
|
||||||
|
suite.selectiveLock.Unlock()
|
||||||
|
|
||||||
|
var deadlineChannel <-chan time.Time
|
||||||
|
if !deadline.IsZero() {
|
||||||
|
deadlineChannel = time.After(deadline.Sub(now))
|
||||||
|
}
|
||||||
|
var gracePeriodChannel <-chan time.Time
|
||||||
|
|
||||||
outcomeC := make(chan types.SpecState)
|
outcomeC := make(chan types.SpecState)
|
||||||
failureC := make(chan types.Failure)
|
failureC := make(chan types.Failure)
|
||||||
@ -677,15 +742,16 @@ func (suite *Suite) runNode(node Node, interruptChannel chan interface{}, text s
|
|||||||
suite.failer.Panic(types.NewCodeLocationWithStackTrace(2), e)
|
suite.failer.Panic(types.NewCodeLocationWithStackTrace(2), e)
|
||||||
}
|
}
|
||||||
|
|
||||||
outcome, failureFromRun := suite.failer.Drain()
|
outcomeFromRun, failureFromRun := suite.failer.Drain()
|
||||||
outcomeC <- outcome
|
outcomeC <- outcomeFromRun
|
||||||
failureC <- failureFromRun
|
failureC <- failureFromRun
|
||||||
}()
|
}()
|
||||||
|
|
||||||
node.Body()
|
node.Body(sc)
|
||||||
finished = true
|
finished = true
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// progress polling timer and channel
|
||||||
var emitProgressNow <-chan time.Time
|
var emitProgressNow <-chan time.Time
|
||||||
var progressPoller *time.Timer
|
var progressPoller *time.Timer
|
||||||
var pollProgressAfter, pollProgressInterval = suite.config.PollProgressAfter, suite.config.PollProgressInterval
|
var pollProgressAfter, pollProgressInterval = suite.config.PollProgressAfter, suite.config.PollProgressInterval
|
||||||
@ -695,31 +761,102 @@ func (suite *Suite) runNode(node Node, interruptChannel chan interface{}, text s
|
|||||||
if node.PollProgressInterval >= 0 {
|
if node.PollProgressInterval >= 0 {
|
||||||
pollProgressInterval = node.PollProgressInterval
|
pollProgressInterval = node.PollProgressInterval
|
||||||
}
|
}
|
||||||
|
|
||||||
if pollProgressAfter > 0 {
|
if pollProgressAfter > 0 {
|
||||||
progressPoller = time.NewTimer(pollProgressAfter)
|
progressPoller = time.NewTimer(pollProgressAfter)
|
||||||
emitProgressNow = progressPoller.C
|
emitProgressNow = progressPoller.C
|
||||||
defer progressPoller.Stop()
|
defer progressPoller.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// now we wait for an outcome, an interrupt, a timeout, or a progress poll
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case outcome := <-outcomeC:
|
case outcomeFromRun := <-outcomeC:
|
||||||
failureFromRun := <-failureC
|
failureFromRun := <-failureC
|
||||||
if outcome == types.SpecStatePassed {
|
if outcome == types.SpecStateInterrupted {
|
||||||
return outcome, types.Failure{}
|
// we've already been interrupted. we just managed to actually exit
|
||||||
}
|
// before the grace period elapsed
|
||||||
failure.Message, failure.Location, failure.ForwardedPanic = failureFromRun.Message, failureFromRun.Location, failureFromRun.ForwardedPanic
|
return outcome, failure
|
||||||
|
} else if outcome == types.SpecStateTimedout {
|
||||||
|
// we've already timed out. we just managed to actually exit
|
||||||
|
// before the grace period elapsed. if we have a failure message we should include it
|
||||||
|
if outcomeFromRun != types.SpecStatePassed {
|
||||||
|
failure.Location, failure.ForwardedPanic = failureFromRun.Location, failureFromRun.ForwardedPanic
|
||||||
|
failure.Message = "This spec timed out and reported the following failure after the timeout:\n\n" + failureFromRun.Message
|
||||||
|
}
|
||||||
|
return outcome, failure
|
||||||
|
}
|
||||||
|
if outcomeFromRun.Is(types.SpecStatePassed) {
|
||||||
|
return outcomeFromRun, types.Failure{}
|
||||||
|
} else {
|
||||||
|
failure.Message, failure.Location, failure.ForwardedPanic = failureFromRun.Message, failureFromRun.Location, failureFromRun.ForwardedPanic
|
||||||
|
return outcomeFromRun, failure
|
||||||
|
}
|
||||||
|
case <-gracePeriodChannel:
|
||||||
|
if node.HasContext && outcome.Is(types.SpecStateTimedout) {
|
||||||
|
report := suite.generateProgressReport(false)
|
||||||
|
report.Message = "{{bold}}{{orange}}A running node failed to exit in time{{/}}\nGinkgo is moving on but a node has timed out and failed to exit before its grace period elapsed. The node has now leaked and is running in the background.\nHere's a current progress report:"
|
||||||
|
suite.emitProgressReport(report)
|
||||||
|
}
|
||||||
|
return outcome, failure
|
||||||
|
case <-deadlineChannel:
|
||||||
|
// we're out of time - the outcome is a timeout and we capture the failure and progress report
|
||||||
|
outcome = types.SpecStateTimedout
|
||||||
|
failure.Message, failure.Location = "Timedout", node.CodeLocation
|
||||||
|
failure.ProgressReport = suite.generateProgressReport(false).WithoutCapturedGinkgoWriterOutput()
|
||||||
|
failure.ProgressReport.Message = "{{bold}}This is the Progress Report generated when the timeout occurred:{{/}}"
|
||||||
|
deadlineChannel = nil
|
||||||
|
// tell the spec to stop. it's important we generate the progress report first to make sure we capture where
|
||||||
|
// the spec is actually stuck
|
||||||
|
sc.cancel()
|
||||||
|
//and now we wait for the grace period
|
||||||
|
gracePeriodChannel = time.After(gracePeriod)
|
||||||
|
case <-interruptStatus.Channel:
|
||||||
|
interruptStatus = suite.interruptHandler.Status()
|
||||||
|
deadlineChannel = nil // don't worry about deadlines, time's up now
|
||||||
|
|
||||||
|
if outcome == types.SpecStateInvalid {
|
||||||
|
outcome = types.SpecStateInterrupted
|
||||||
|
failure.Message, failure.Location = interruptStatus.Message(), node.CodeLocation
|
||||||
|
if interruptStatus.ShouldIncludeProgressReport() {
|
||||||
|
failure.ProgressReport = suite.generateProgressReport(true).WithoutCapturedGinkgoWriterOutput()
|
||||||
|
failure.ProgressReport.Message = "{{bold}}This is the Progress Report generated when the interrupt was received:{{/}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var report types.ProgressReport
|
||||||
|
if interruptStatus.ShouldIncludeProgressReport() {
|
||||||
|
report = suite.generateProgressReport(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
sc.cancel()
|
||||||
|
|
||||||
|
if interruptStatus.Level == interrupt_handler.InterruptLevelBailOut {
|
||||||
|
if interruptStatus.ShouldIncludeProgressReport() {
|
||||||
|
report.Message = fmt.Sprintf("{{bold}}{{orange}}%s{{/}}\n{{bold}}{{red}}Final interrupt received{{/}}; Ginkgo will not run any cleanup or reporting nodes and will terminate as soon as possible.\nHere's a current progress report:", interruptStatus.Message())
|
||||||
|
suite.emitProgressReport(report)
|
||||||
|
}
|
||||||
|
return outcome, failure
|
||||||
|
}
|
||||||
|
if interruptStatus.ShouldIncludeProgressReport() {
|
||||||
|
if interruptStatus.Level == interrupt_handler.InterruptLevelCleanupAndReport {
|
||||||
|
report.Message = fmt.Sprintf("{{bold}}{{orange}}%s{{/}}\nFirst interrupt received; Ginkgo will run any cleanup and reporting nodes but will skip all remaining specs. {{bold}}Interrupt again to skip cleanup{{/}}.\nHere's a current progress report:", interruptStatus.Message())
|
||||||
|
} else if interruptStatus.Level == interrupt_handler.InterruptLevelReportOnly {
|
||||||
|
report.Message = fmt.Sprintf("{{bold}}{{orange}}%s{{/}}\nSecond interrupt received; Ginkgo will run any reporting nodes but will skip all remaining specs and cleanup nodes. {{bold}}Interrupt again to bail immediately{{/}}.\nHere's a current progress report:", interruptStatus.Message())
|
||||||
|
}
|
||||||
|
suite.emitProgressReport(report)
|
||||||
|
}
|
||||||
|
|
||||||
|
if gracePeriodChannel == nil {
|
||||||
|
// we haven't given grace yet... so let's
|
||||||
|
gracePeriodChannel = time.After(gracePeriod)
|
||||||
|
} else {
|
||||||
|
// we've already given grace. time's up. now.
|
||||||
return outcome, failure
|
return outcome, failure
|
||||||
case <-interruptChannel:
|
|
||||||
reason, includeProgressReport := suite.interruptHandler.InterruptMessage()
|
|
||||||
failure.Message, failure.Location = reason, node.CodeLocation
|
|
||||||
if includeProgressReport {
|
|
||||||
failure.ProgressReport = suite.generateProgressReport(true).WithoutCapturedGinkgoWriterOutput()
|
|
||||||
}
|
}
|
||||||
return types.SpecStateInterrupted, failure
|
|
||||||
case <-emitProgressNow:
|
case <-emitProgressNow:
|
||||||
suite.handleProgressSignal()
|
report := suite.generateProgressReport(false)
|
||||||
|
report.Message = "{{bold}}Automatically polling progress:{{/}}"
|
||||||
|
suite.emitProgressReport(report)
|
||||||
if pollProgressInterval > 0 {
|
if pollProgressInterval > 0 {
|
||||||
progressPoller.Reset(pollProgressInterval)
|
progressPoller.Reset(pollProgressInterval)
|
||||||
}
|
}
|
||||||
|
119
vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
generated
vendored
119
vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
generated
vendored
@ -135,9 +135,11 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) {
|
|||||||
denoter = fmt.Sprintf("[%s]", report.LeafNodeType)
|
denoter = fmt.Sprintf("[%s]", report.LeafNodeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
highlightColor = r.highlightColorForState(report.State)
|
||||||
|
|
||||||
switch report.State {
|
switch report.State {
|
||||||
case types.SpecStatePassed:
|
case types.SpecStatePassed:
|
||||||
highlightColor, succinctLocationBlock = "{{green}}", v.LT(types.VerbosityLevelVerbose)
|
succinctLocationBlock = v.LT(types.VerbosityLevelVerbose)
|
||||||
emitGinkgoWriterOutput = (r.conf.AlwaysEmitGinkgoWriter || v.GTE(types.VerbosityLevelVerbose)) && hasGW
|
emitGinkgoWriterOutput = (r.conf.AlwaysEmitGinkgoWriter || v.GTE(types.VerbosityLevelVerbose)) && hasGW
|
||||||
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
|
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
|
||||||
if v.GTE(types.VerbosityLevelVerbose) || hasStd || hasEmittableReports {
|
if v.GTE(types.VerbosityLevelVerbose) || hasStd || hasEmittableReports {
|
||||||
@ -158,7 +160,6 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) {
|
|||||||
stream = false
|
stream = false
|
||||||
}
|
}
|
||||||
case types.SpecStatePending:
|
case types.SpecStatePending:
|
||||||
highlightColor = "{{yellow}}"
|
|
||||||
includeRuntime, emitGinkgoWriterOutput = false, false
|
includeRuntime, emitGinkgoWriterOutput = false, false
|
||||||
if v.Is(types.VerbosityLevelSuccinct) {
|
if v.Is(types.VerbosityLevelSuccinct) {
|
||||||
header, stream = "P", true
|
header, stream = "P", true
|
||||||
@ -166,20 +167,21 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) {
|
|||||||
header, succinctLocationBlock = "P [PENDING]", v.LT(types.VerbosityLevelVeryVerbose)
|
header, succinctLocationBlock = "P [PENDING]", v.LT(types.VerbosityLevelVeryVerbose)
|
||||||
}
|
}
|
||||||
case types.SpecStateSkipped:
|
case types.SpecStateSkipped:
|
||||||
highlightColor = "{{cyan}}"
|
|
||||||
if report.Failure.Message != "" || v.Is(types.VerbosityLevelVeryVerbose) {
|
if report.Failure.Message != "" || v.Is(types.VerbosityLevelVeryVerbose) {
|
||||||
header = "S [SKIPPED]"
|
header = "S [SKIPPED]"
|
||||||
} else {
|
} else {
|
||||||
header, stream = "S", true
|
header, stream = "S", true
|
||||||
}
|
}
|
||||||
case types.SpecStateFailed:
|
case types.SpecStateFailed:
|
||||||
highlightColor, header = "{{red}}", fmt.Sprintf("%s [FAILED]", denoter)
|
header = fmt.Sprintf("%s [FAILED]", denoter)
|
||||||
|
case types.SpecStateTimedout:
|
||||||
|
header = fmt.Sprintf("%s [TIMEDOUT]", denoter)
|
||||||
case types.SpecStatePanicked:
|
case types.SpecStatePanicked:
|
||||||
highlightColor, header = "{{magenta}}", fmt.Sprintf("%s! [PANICKED]", denoter)
|
header = fmt.Sprintf("%s! [PANICKED]", denoter)
|
||||||
case types.SpecStateInterrupted:
|
case types.SpecStateInterrupted:
|
||||||
highlightColor, header = "{{orange}}", fmt.Sprintf("%s! [INTERRUPTED]", denoter)
|
header = fmt.Sprintf("%s! [INTERRUPTED]", denoter)
|
||||||
case types.SpecStateAborted:
|
case types.SpecStateAborted:
|
||||||
highlightColor, header = "{{coral}}", fmt.Sprintf("%s! [ABORTED]", denoter)
|
header = fmt.Sprintf("%s! [ABORTED]", denoter)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit stream and return
|
// Emit stream and return
|
||||||
@ -231,28 +233,87 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) {
|
|||||||
// Emit Failure Message
|
// Emit Failure Message
|
||||||
if !report.Failure.IsZero() {
|
if !report.Failure.IsZero() {
|
||||||
r.emitBlock("\n")
|
r.emitBlock("\n")
|
||||||
r.emitBlock(r.fi(1, highlightColor+"%s{{/}}", report.Failure.Message))
|
r.EmitFailure(1, report.State, report.Failure, false)
|
||||||
r.emitBlock(r.fi(1, highlightColor+"In {{bold}}[%s]{{/}}"+highlightColor+" at: {{bold}}%s{{/}}\n", report.Failure.FailureNodeType, report.Failure.Location))
|
|
||||||
if report.Failure.ForwardedPanic != "" {
|
|
||||||
r.emitBlock("\n")
|
|
||||||
r.emitBlock(r.fi(1, highlightColor+"%s{{/}}", report.Failure.ForwardedPanic))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.conf.FullTrace || report.Failure.ForwardedPanic != "" {
|
if len(report.AdditionalFailures) > 0 {
|
||||||
|
if v.GTE(types.VerbosityLevelVerbose) {
|
||||||
r.emitBlock("\n")
|
r.emitBlock("\n")
|
||||||
r.emitBlock(r.fi(1, highlightColor+"Full Stack Trace{{/}}"))
|
r.emitBlock(r.fi(1, "{{bold}}There were additional failures detected after the initial failure:{{/}}"))
|
||||||
r.emitBlock(r.fi(2, "%s", report.Failure.Location.FullStackTrace))
|
for i, additionalFailure := range report.AdditionalFailures {
|
||||||
|
r.EmitFailure(2, additionalFailure.State, additionalFailure.Failure, true)
|
||||||
|
if i < len(report.AdditionalFailures)-1 {
|
||||||
|
r.emitBlock(r.fi(2, "{{gray}}%s{{/}}", strings.Repeat("-", 10)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r.emitBlock("\n")
|
||||||
|
r.emitBlock(r.fi(1, "{{bold}}There were additional failures detected after the initial failure. Here's a summary - for full details run Ginkgo in verbose mode:{{/}}"))
|
||||||
|
for _, additionalFailure := range report.AdditionalFailures {
|
||||||
|
r.emitBlock(r.fi(2, r.highlightColorForState(additionalFailure.State)+"[%s]{{/}} in [%s] at %s",
|
||||||
|
r.humanReadableState(additionalFailure.State),
|
||||||
|
additionalFailure.Failure.FailureNodeType,
|
||||||
|
additionalFailure.Failure.Location,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
if !report.Failure.ProgressReport.IsZero() {
|
|
||||||
r.emitBlock("\n")
|
|
||||||
r.emitProgressReport(1, false, report.Failure.ProgressReport)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.emitDelimiter()
|
r.emitDelimiter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *DefaultReporter) highlightColorForState(state types.SpecState) string {
|
||||||
|
switch state {
|
||||||
|
case types.SpecStatePassed:
|
||||||
|
return "{{green}}"
|
||||||
|
case types.SpecStatePending:
|
||||||
|
return "{{yellow}}"
|
||||||
|
case types.SpecStateSkipped:
|
||||||
|
return "{{cyan}}"
|
||||||
|
case types.SpecStateFailed:
|
||||||
|
return "{{red}}"
|
||||||
|
case types.SpecStateTimedout:
|
||||||
|
return "{{orange}}"
|
||||||
|
case types.SpecStatePanicked:
|
||||||
|
return "{{magenta}}"
|
||||||
|
case types.SpecStateInterrupted:
|
||||||
|
return "{{orange}}"
|
||||||
|
case types.SpecStateAborted:
|
||||||
|
return "{{coral}}"
|
||||||
|
default:
|
||||||
|
return "{{gray}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *DefaultReporter) humanReadableState(state types.SpecState) string {
|
||||||
|
return strings.ToUpper(state.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *DefaultReporter) EmitFailure(indent uint, state types.SpecState, failure types.Failure, includeState bool) {
|
||||||
|
highlightColor := r.highlightColorForState(state)
|
||||||
|
if includeState {
|
||||||
|
r.emitBlock(r.fi(indent, highlightColor+"[%s]{{/}}", r.humanReadableState(state)))
|
||||||
|
}
|
||||||
|
r.emitBlock(r.fi(indent, highlightColor+"%s{{/}}", failure.Message))
|
||||||
|
r.emitBlock(r.fi(indent, highlightColor+"In {{bold}}[%s]{{/}}"+highlightColor+" at: {{bold}}%s{{/}}\n", failure.FailureNodeType, failure.Location))
|
||||||
|
if failure.ForwardedPanic != "" {
|
||||||
|
r.emitBlock("\n")
|
||||||
|
r.emitBlock(r.fi(indent, highlightColor+"%s{{/}}", failure.ForwardedPanic))
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.conf.FullTrace || failure.ForwardedPanic != "" {
|
||||||
|
r.emitBlock("\n")
|
||||||
|
r.emitBlock(r.fi(indent, highlightColor+"Full Stack Trace{{/}}"))
|
||||||
|
r.emitBlock(r.fi(indent+1, "%s", failure.Location.FullStackTrace))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !failure.ProgressReport.IsZero() {
|
||||||
|
r.emitBlock("\n")
|
||||||
|
r.emitProgressReport(indent, false, failure.ProgressReport)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *DefaultReporter) SuiteDidEnd(report types.Report) {
|
func (r *DefaultReporter) SuiteDidEnd(report types.Report) {
|
||||||
failures := report.SpecReports.WithState(types.SpecStateFailureStates)
|
failures := report.SpecReports.WithState(types.SpecStateFailureStates)
|
||||||
if len(failures) > 0 {
|
if len(failures) > 0 {
|
||||||
@ -269,6 +330,8 @@ func (r *DefaultReporter) SuiteDidEnd(report types.Report) {
|
|||||||
highlightColor, heading = "{{magenta}}", "[PANICKED!]"
|
highlightColor, heading = "{{magenta}}", "[PANICKED!]"
|
||||||
case types.SpecStateAborted:
|
case types.SpecStateAborted:
|
||||||
highlightColor, heading = "{{coral}}", "[ABORTED]"
|
highlightColor, heading = "{{coral}}", "[ABORTED]"
|
||||||
|
case types.SpecStateTimedout:
|
||||||
|
highlightColor, heading = "{{orange}}", "[TIMEDOUT]"
|
||||||
case types.SpecStateInterrupted:
|
case types.SpecStateInterrupted:
|
||||||
highlightColor, heading = "{{orange}}", "[INTERRUPTED]"
|
highlightColor, heading = "{{orange}}", "[INTERRUPTED]"
|
||||||
}
|
}
|
||||||
@ -329,12 +392,18 @@ func (r *DefaultReporter) EmitProgressReport(report types.ProgressReport) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput bool, report types.ProgressReport) {
|
func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput bool, report types.ProgressReport) {
|
||||||
|
if report.Message != "" {
|
||||||
|
r.emitBlock(r.fi(indent, report.Message+"\n"))
|
||||||
|
indent += 1
|
||||||
|
}
|
||||||
if report.LeafNodeText != "" {
|
if report.LeafNodeText != "" {
|
||||||
|
subjectIndent := indent
|
||||||
if len(report.ContainerHierarchyTexts) > 0 {
|
if len(report.ContainerHierarchyTexts) > 0 {
|
||||||
r.emit(r.fi(indent, r.cycleJoin(report.ContainerHierarchyTexts, " ")))
|
r.emit(r.fi(indent, r.cycleJoin(report.ContainerHierarchyTexts, " ")))
|
||||||
r.emit(" ")
|
r.emit(" ")
|
||||||
|
subjectIndent = 0
|
||||||
}
|
}
|
||||||
r.emit(r.f("{{bold}}{{orange}}%s{{/}} (Spec Runtime: %s)\n", report.LeafNodeText, report.Time.Sub(report.SpecStartTime).Round(time.Millisecond)))
|
r.emit(r.fi(subjectIndent, "{{bold}}{{orange}}%s{{/}} (Spec Runtime: %s)\n", report.LeafNodeText, report.Time.Sub(report.SpecStartTime).Round(time.Millisecond)))
|
||||||
r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.LeafNodeLocation))
|
r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.LeafNodeLocation))
|
||||||
indent += 1
|
indent += 1
|
||||||
}
|
}
|
||||||
@ -369,6 +438,18 @@ func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput
|
|||||||
r.emitGoroutines(indent, report.SpecGoroutine())
|
r.emitGoroutines(indent, report.SpecGoroutine())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(report.AdditionalReports) > 0 {
|
||||||
|
r.emit("\n")
|
||||||
|
r.emitBlock(r.fi(indent, "{{gray}}Begin Additional Progress Reports >>{{/}}"))
|
||||||
|
for i, additionalReport := range report.AdditionalReports {
|
||||||
|
r.emit(r.fi(indent+1, additionalReport))
|
||||||
|
if i < len(report.AdditionalReports)-1 {
|
||||||
|
r.emitBlock(r.fi(indent+1, "{{gray}}%s{{/}}", strings.Repeat("-", 10)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.emitBlock(r.fi(indent, "{{gray}}<< End Additional Progress Reports{{/}}"))
|
||||||
|
}
|
||||||
|
|
||||||
highlightedGoroutines := report.HighlightedGoroutines()
|
highlightedGoroutines := report.HighlightedGoroutines()
|
||||||
if len(highlightedGoroutines) > 0 {
|
if len(highlightedGoroutines) > 0 {
|
||||||
r.emit("\n")
|
r.emit("\n")
|
||||||
|
36
vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go
generated
vendored
36
vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go
generated
vendored
@ -191,28 +191,35 @@ func GenerateJUnitReport(report types.Report, dst string) error {
|
|||||||
test.Failure = &JUnitFailure{
|
test.Failure = &JUnitFailure{
|
||||||
Message: spec.Failure.Message,
|
Message: spec.Failure.Message,
|
||||||
Type: "failed",
|
Type: "failed",
|
||||||
Description: fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace),
|
Description: failureDescriptionForUnstructuredReporters(spec),
|
||||||
|
}
|
||||||
|
suite.Failures += 1
|
||||||
|
case types.SpecStateTimedout:
|
||||||
|
test.Failure = &JUnitFailure{
|
||||||
|
Message: spec.Failure.Message,
|
||||||
|
Type: "timedout",
|
||||||
|
Description: failureDescriptionForUnstructuredReporters(spec),
|
||||||
}
|
}
|
||||||
suite.Failures += 1
|
suite.Failures += 1
|
||||||
case types.SpecStateInterrupted:
|
case types.SpecStateInterrupted:
|
||||||
test.Error = &JUnitError{
|
test.Error = &JUnitError{
|
||||||
Message: "interrupted",
|
Message: spec.Failure.Message,
|
||||||
Type: "interrupted",
|
Type: "interrupted",
|
||||||
Description: interruptDescriptionForUnstructuredReporters(spec.Failure),
|
Description: failureDescriptionForUnstructuredReporters(spec),
|
||||||
}
|
}
|
||||||
suite.Errors += 1
|
suite.Errors += 1
|
||||||
case types.SpecStateAborted:
|
case types.SpecStateAborted:
|
||||||
test.Failure = &JUnitFailure{
|
test.Failure = &JUnitFailure{
|
||||||
Message: spec.Failure.Message,
|
Message: spec.Failure.Message,
|
||||||
Type: "aborted",
|
Type: "aborted",
|
||||||
Description: fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace),
|
Description: failureDescriptionForUnstructuredReporters(spec),
|
||||||
}
|
}
|
||||||
suite.Errors += 1
|
suite.Errors += 1
|
||||||
case types.SpecStatePanicked:
|
case types.SpecStatePanicked:
|
||||||
test.Error = &JUnitError{
|
test.Error = &JUnitError{
|
||||||
Message: spec.Failure.ForwardedPanic,
|
Message: spec.Failure.ForwardedPanic,
|
||||||
Type: "panicked",
|
Type: "panicked",
|
||||||
Description: fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace),
|
Description: failureDescriptionForUnstructuredReporters(spec),
|
||||||
}
|
}
|
||||||
suite.Errors += 1
|
suite.Errors += 1
|
||||||
}
|
}
|
||||||
@ -278,10 +285,23 @@ func MergeAndCleanupJUnitReports(sources []string, dst string) ([]string, error)
|
|||||||
return messages, f.Close()
|
return messages, f.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func interruptDescriptionForUnstructuredReporters(failure types.Failure) string {
|
func failureDescriptionForUnstructuredReporters(spec types.SpecReport) string {
|
||||||
out := &strings.Builder{}
|
out := &strings.Builder{}
|
||||||
out.WriteString(failure.Message + "\n")
|
out.WriteString(spec.Failure.Location.String() + "\n")
|
||||||
NewDefaultReporter(types.ReporterConfig{NoColor: true}, out).EmitProgressReport(failure.ProgressReport)
|
out.WriteString(spec.Failure.Location.FullStackTrace)
|
||||||
|
if !spec.Failure.ProgressReport.IsZero() {
|
||||||
|
out.WriteString("\n")
|
||||||
|
NewDefaultReporter(types.ReporterConfig{NoColor: true}, out).EmitProgressReport(spec.Failure.ProgressReport)
|
||||||
|
}
|
||||||
|
if len(spec.AdditionalFailures) > 0 {
|
||||||
|
out.WriteString("\nThere were additional failures detected after the initial failure:\n")
|
||||||
|
for i, additionalFailure := range spec.AdditionalFailures {
|
||||||
|
NewDefaultReporter(types.ReporterConfig{NoColor: true}, out).EmitFailure(0, additionalFailure.State, additionalFailure.Failure, true)
|
||||||
|
if i < len(spec.AdditionalFailures)-1 {
|
||||||
|
out.WriteString("----------\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return out.String()
|
return out.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go
generated
vendored
12
vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go
generated
vendored
@ -60,15 +60,19 @@ func GenerateTeamcityReport(report types.Report, dst string) error {
|
|||||||
}
|
}
|
||||||
fmt.Fprintf(f, "##teamcity[testIgnored name='%s' message='%s']\n", name, tcEscape(message))
|
fmt.Fprintf(f, "##teamcity[testIgnored name='%s' message='%s']\n", name, tcEscape(message))
|
||||||
case types.SpecStateFailed:
|
case types.SpecStateFailed:
|
||||||
details := fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace)
|
details := failureDescriptionForUnstructuredReporters(spec)
|
||||||
fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='failed - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details))
|
fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='failed - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details))
|
||||||
case types.SpecStatePanicked:
|
case types.SpecStatePanicked:
|
||||||
details := fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace)
|
details := failureDescriptionForUnstructuredReporters(spec)
|
||||||
fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='panicked - %s' details='%s']\n", name, tcEscape(spec.Failure.ForwardedPanic), tcEscape(details))
|
fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='panicked - %s' details='%s']\n", name, tcEscape(spec.Failure.ForwardedPanic), tcEscape(details))
|
||||||
|
case types.SpecStateTimedout:
|
||||||
|
details := failureDescriptionForUnstructuredReporters(spec)
|
||||||
|
fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='timedout - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details))
|
||||||
case types.SpecStateInterrupted:
|
case types.SpecStateInterrupted:
|
||||||
fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='interrupted' details='%s']\n", name, tcEscape(interruptDescriptionForUnstructuredReporters(spec.Failure)))
|
details := failureDescriptionForUnstructuredReporters(spec)
|
||||||
|
fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='interrupted - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details))
|
||||||
case types.SpecStateAborted:
|
case types.SpecStateAborted:
|
||||||
details := fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace)
|
details := failureDescriptionForUnstructuredReporters(spec)
|
||||||
fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='aborted - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details))
|
fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='aborted - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
53
vendor/github.com/onsi/ginkgo/v2/table_dsl.go
generated
vendored
53
vendor/github.com/onsi/ginkgo/v2/table_dsl.go
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
package ginkgo
|
package ginkgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
@ -89,6 +90,8 @@ Subsequent arguments accept any Ginkgo decorators. These are filtered out and t
|
|||||||
|
|
||||||
Each Entry ends up generating an individual Ginkgo It. The body of the it is the Table Body function with the Entry parameters passed in.
|
Each Entry ends up generating an individual Ginkgo It. The body of the it is the Table Body function with the Entry parameters passed in.
|
||||||
|
|
||||||
|
If you want to generate interruptible specs simply write a Table function that accepts a SpecContext as its first argument. You can then decorate individual Entrys with the NodeTimeout and SpecTimeout decorators.
|
||||||
|
|
||||||
You can learn more about Entry here: https://onsi.github.io/ginkgo/#table-specs
|
You can learn more about Entry here: https://onsi.github.io/ginkgo/#table-specs
|
||||||
*/
|
*/
|
||||||
func Entry(description interface{}, args ...interface{}) TableEntry {
|
func Entry(description interface{}, args ...interface{}) TableEntry {
|
||||||
@ -119,12 +122,16 @@ You can mark a particular entry as pending with XEntry. This is equivalent to X
|
|||||||
*/
|
*/
|
||||||
var XEntry = PEntry
|
var XEntry = PEntry
|
||||||
|
|
||||||
|
var contextType = reflect.TypeOf(new(context.Context)).Elem()
|
||||||
|
var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
|
||||||
|
|
||||||
func generateTable(description string, args ...interface{}) {
|
func generateTable(description string, args ...interface{}) {
|
||||||
cl := types.NewCodeLocation(2)
|
cl := types.NewCodeLocation(2)
|
||||||
containerNodeArgs := []interface{}{cl}
|
containerNodeArgs := []interface{}{cl}
|
||||||
|
|
||||||
entries := []TableEntry{}
|
entries := []TableEntry{}
|
||||||
var itBody interface{}
|
var itBody interface{}
|
||||||
|
var itBodyType reflect.Type
|
||||||
|
|
||||||
var tableLevelEntryDescription interface{}
|
var tableLevelEntryDescription interface{}
|
||||||
tableLevelEntryDescription = func(args ...interface{}) string {
|
tableLevelEntryDescription = func(args ...interface{}) string {
|
||||||
@ -135,6 +142,10 @@ func generateTable(description string, args ...interface{}) {
|
|||||||
return "Entry: " + strings.Join(out, ", ")
|
return "Entry: " + strings.Join(out, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(args) == 1 {
|
||||||
|
exitIfErr(types.GinkgoErrors.MissingParametersForTableFunction(cl))
|
||||||
|
}
|
||||||
|
|
||||||
for i, arg := range args {
|
for i, arg := range args {
|
||||||
switch t := reflect.TypeOf(arg); {
|
switch t := reflect.TypeOf(arg); {
|
||||||
case t == nil:
|
case t == nil:
|
||||||
@ -152,6 +163,7 @@ func generateTable(description string, args ...interface{}) {
|
|||||||
exitIfErr(types.GinkgoErrors.MultipleEntryBodyFunctionsForTable(cl))
|
exitIfErr(types.GinkgoErrors.MultipleEntryBodyFunctionsForTable(cl))
|
||||||
}
|
}
|
||||||
itBody = arg
|
itBody = arg
|
||||||
|
itBodyType = reflect.TypeOf(itBody)
|
||||||
default:
|
default:
|
||||||
containerNodeArgs = append(containerNodeArgs, arg)
|
containerNodeArgs = append(containerNodeArgs, arg)
|
||||||
}
|
}
|
||||||
@ -164,7 +176,7 @@ func generateTable(description string, args ...interface{}) {
|
|||||||
var description string
|
var description string
|
||||||
switch t := reflect.TypeOf(entry.description); {
|
switch t := reflect.TypeOf(entry.description); {
|
||||||
case t == nil:
|
case t == nil:
|
||||||
err = validateParameters(tableLevelEntryDescription, entry.parameters, "Entry Description function", entry.codeLocation)
|
err = validateParameters(tableLevelEntryDescription, entry.parameters, "Entry Description function", entry.codeLocation, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
description = invokeFunction(tableLevelEntryDescription, entry.parameters)[0].String()
|
description = invokeFunction(tableLevelEntryDescription, entry.parameters)[0].String()
|
||||||
}
|
}
|
||||||
@ -173,7 +185,7 @@ func generateTable(description string, args ...interface{}) {
|
|||||||
case t == reflect.TypeOf(""):
|
case t == reflect.TypeOf(""):
|
||||||
description = entry.description.(string)
|
description = entry.description.(string)
|
||||||
case t.Kind() == reflect.Func && t.NumOut() == 1 && t.Out(0) == reflect.TypeOf(""):
|
case t.Kind() == reflect.Func && t.NumOut() == 1 && t.Out(0) == reflect.TypeOf(""):
|
||||||
err = validateParameters(entry.description, entry.parameters, "Entry Description function", entry.codeLocation)
|
err = validateParameters(entry.description, entry.parameters, "Entry Description function", entry.codeLocation, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
description = invokeFunction(entry.description, entry.parameters)[0].String()
|
description = invokeFunction(entry.description, entry.parameters)[0].String()
|
||||||
}
|
}
|
||||||
@ -181,17 +193,37 @@ func generateTable(description string, args ...interface{}) {
|
|||||||
err = types.GinkgoErrors.InvalidEntryDescription(entry.codeLocation)
|
err = types.GinkgoErrors.InvalidEntryDescription(entry.codeLocation)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
err = validateParameters(itBody, entry.parameters, "Table Body function", entry.codeLocation)
|
|
||||||
}
|
|
||||||
itNodeArgs := []interface{}{entry.codeLocation}
|
itNodeArgs := []interface{}{entry.codeLocation}
|
||||||
itNodeArgs = append(itNodeArgs, entry.decorations...)
|
itNodeArgs = append(itNodeArgs, entry.decorations...)
|
||||||
|
|
||||||
|
hasContext := false
|
||||||
|
if itBodyType.NumIn() > 0. {
|
||||||
|
if itBodyType.In(0).Implements(specContextType) {
|
||||||
|
hasContext = true
|
||||||
|
} else if itBodyType.In(0).Implements(contextType) && (len(entry.parameters) == 0 || !reflect.TypeOf(entry.parameters[0]).Implements(contextType)) {
|
||||||
|
hasContext = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
err = validateParameters(itBody, entry.parameters, "Table Body function", entry.codeLocation, hasContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasContext {
|
||||||
|
itNodeArgs = append(itNodeArgs, func(c SpecContext) {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
invokeFunction(itBody, append([]interface{}{c}, entry.parameters...))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
itNodeArgs = append(itNodeArgs, func() {
|
itNodeArgs = append(itNodeArgs, func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
invokeFunction(itBody, entry.parameters)
|
invokeFunction(itBody, entry.parameters)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, description, itNodeArgs...))
|
pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, description, itNodeArgs...))
|
||||||
}
|
}
|
||||||
@ -223,9 +255,14 @@ func invokeFunction(function interface{}, parameters []interface{}) []reflect.Va
|
|||||||
return reflect.ValueOf(function).Call(inValues)
|
return reflect.ValueOf(function).Call(inValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateParameters(function interface{}, parameters []interface{}, kind string, cl types.CodeLocation) error {
|
func validateParameters(function interface{}, parameters []interface{}, kind string, cl types.CodeLocation, hasContext bool) error {
|
||||||
funcType := reflect.TypeOf(function)
|
funcType := reflect.TypeOf(function)
|
||||||
limit := funcType.NumIn()
|
limit := funcType.NumIn()
|
||||||
|
offset := 0
|
||||||
|
if hasContext {
|
||||||
|
limit = limit - 1
|
||||||
|
offset = 1
|
||||||
|
}
|
||||||
if funcType.IsVariadic() {
|
if funcType.IsVariadic() {
|
||||||
limit = limit - 1
|
limit = limit - 1
|
||||||
}
|
}
|
||||||
@ -238,13 +275,13 @@ func validateParameters(function interface{}, parameters []interface{}, kind str
|
|||||||
var i = 0
|
var i = 0
|
||||||
for ; i < limit; i++ {
|
for ; i < limit; i++ {
|
||||||
actual := reflect.TypeOf(parameters[i])
|
actual := reflect.TypeOf(parameters[i])
|
||||||
expected := funcType.In(i)
|
expected := funcType.In(i + offset)
|
||||||
if !(actual == nil) && !actual.AssignableTo(expected) {
|
if !(actual == nil) && !actual.AssignableTo(expected) {
|
||||||
return types.GinkgoErrors.IncorrectParameterTypeToTableFunction(i+1, expected, actual, kind, cl)
|
return types.GinkgoErrors.IncorrectParameterTypeToTableFunction(i+1, expected, actual, kind, cl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if funcType.IsVariadic() {
|
if funcType.IsVariadic() {
|
||||||
expected := funcType.In(limit).Elem()
|
expected := funcType.In(limit + offset).Elem()
|
||||||
for ; i < len(parameters); i++ {
|
for ; i < len(parameters); i++ {
|
||||||
actual := reflect.TypeOf(parameters[i])
|
actual := reflect.TypeOf(parameters[i])
|
||||||
if !(actual == nil) && !actual.AssignableTo(expected) {
|
if !(actual == nil) && !actual.AssignableTo(expected) {
|
||||||
|
1
vendor/github.com/onsi/ginkgo/v2/types/code_location.go
generated
vendored
1
vendor/github.com/onsi/ginkgo/v2/types/code_location.go
generated
vendored
@ -1,5 +1,4 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
8
vendor/github.com/onsi/ginkgo/v2/types/config.go
generated
vendored
8
vendor/github.com/onsi/ginkgo/v2/types/config.go
generated
vendored
@ -33,6 +33,7 @@ type SuiteConfig struct {
|
|||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
OutputInterceptorMode string
|
OutputInterceptorMode string
|
||||||
SourceRoots []string
|
SourceRoots []string
|
||||||
|
GracePeriod time.Duration
|
||||||
|
|
||||||
ParallelProcess int
|
ParallelProcess int
|
||||||
ParallelTotal int
|
ParallelTotal int
|
||||||
@ -45,6 +46,7 @@ func NewDefaultSuiteConfig() SuiteConfig {
|
|||||||
Timeout: time.Hour,
|
Timeout: time.Hour,
|
||||||
ParallelProcess: 1,
|
ParallelProcess: 1,
|
||||||
ParallelTotal: 1,
|
ParallelTotal: 1,
|
||||||
|
GracePeriod: 30 * time.Second,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,6 +285,8 @@ var SuiteConfigFlags = GinkgoFlags{
|
|||||||
Usage: "The location to look for source code when generating progress reports. You can pass multiple --source-root flags."},
|
Usage: "The location to look for source code when generating progress reports. You can pass multiple --source-root flags."},
|
||||||
{KeyPath: "S.Timeout", Name: "timeout", SectionKey: "debug", UsageDefaultValue: "1h",
|
{KeyPath: "S.Timeout", Name: "timeout", SectionKey: "debug", UsageDefaultValue: "1h",
|
||||||
Usage: "Test suite fails if it does not complete within the specified timeout."},
|
Usage: "Test suite fails if it does not complete within the specified timeout."},
|
||||||
|
{KeyPath: "S.GracePeriod", Name: "grace-period", SectionKey: "debug", UsageDefaultValue: "30s",
|
||||||
|
Usage: "When interrupted, Ginkgo will wait for GracePeriod for the current running node to exit before moving on to the next one."},
|
||||||
{KeyPath: "S.OutputInterceptorMode", Name: "output-interceptor-mode", SectionKey: "debug", UsageArgument: "dup, swap, or none",
|
{KeyPath: "S.OutputInterceptorMode", Name: "output-interceptor-mode", SectionKey: "debug", UsageArgument: "dup, swap, or none",
|
||||||
Usage: "If set, ginkgo will use the specified output interception strategy when running in parallel. Defaults to dup on unix and swap on windows."},
|
Usage: "If set, ginkgo will use the specified output interception strategy when running in parallel. Defaults to dup on unix and swap on windows."},
|
||||||
|
|
||||||
@ -390,6 +394,10 @@ func VetConfig(flagSet GinkgoFlagSet, suiteConfig SuiteConfig, reporterConfig Re
|
|||||||
errors = append(errors, GinkgoErrors.DryRunInParallelConfiguration())
|
errors = append(errors, GinkgoErrors.DryRunInParallelConfiguration())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if suiteConfig.GracePeriod <= 0 {
|
||||||
|
errors = append(errors, GinkgoErrors.GracePeriodCannotBeZero())
|
||||||
|
}
|
||||||
|
|
||||||
if len(suiteConfig.FocusFiles) > 0 {
|
if len(suiteConfig.FocusFiles) > 0 {
|
||||||
_, err := ParseFileFilters(suiteConfig.FocusFiles)
|
_, err := ParseFileFilters(suiteConfig.FocusFiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
77
vendor/github.com/onsi/ginkgo/v2/types/errors.go
generated
vendored
77
vendor/github.com/onsi/ginkgo/v2/types/errors.go
generated
vendored
@ -189,20 +189,55 @@ func (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g ginkgoErrors) InvalidBodyType(t reflect.Type, cl CodeLocation, nodeType NodeType) error {
|
func (g ginkgoErrors) InvalidBodyTypeForContainer(t reflect.Type, cl CodeLocation, nodeType NodeType) error {
|
||||||
return GinkgoError{
|
return GinkgoError{
|
||||||
Heading: "Invalid Function",
|
Heading: "Invalid Function",
|
||||||
Message: formatter.F(`[%s] node must be passed {{bold}}func(){{/}} - i.e. functions that take nothing and return nothing.
|
Message: formatter.F(`[%s] node must be passed {{bold}}func(){{/}} - i.e. functions that take nothing and return nothing. You passed {{bold}}%s{{/}} instead.`, nodeType, t),
|
||||||
|
CodeLocation: cl,
|
||||||
|
DocLink: "node-decorators-overview",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g ginkgoErrors) InvalidBodyType(t reflect.Type, cl CodeLocation, nodeType NodeType) error {
|
||||||
|
mustGet := "{{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}"
|
||||||
|
if nodeType.Is(NodeTypeContainer) {
|
||||||
|
mustGet = "{{bold}}func(){{/}}"
|
||||||
|
}
|
||||||
|
return GinkgoError{
|
||||||
|
Heading: "Invalid Function",
|
||||||
|
Message: formatter.F(`[%s] node must be passed `+mustGet+`.
|
||||||
You passed {{bold}}%s{{/}} instead.`, nodeType, t),
|
You passed {{bold}}%s{{/}} instead.`, nodeType, t),
|
||||||
CodeLocation: cl,
|
CodeLocation: cl,
|
||||||
DocLink: "node-decorators-overview",
|
DocLink: "node-decorators-overview",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g ginkgoErrors) InvalidBodyTypeForSynchronizedBeforeSuiteProc1(t reflect.Type, cl CodeLocation) error {
|
||||||
|
mustGet := "{{bold}}func() []byte{{/}}, {{bold}}func(ctx SpecContext) []byte{{/}}, or {{bold}}func(ctx context.Context) []byte{{/}}, {{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}"
|
||||||
|
return GinkgoError{
|
||||||
|
Heading: "Invalid Function",
|
||||||
|
Message: formatter.F(`[SynchronizedBeforeSuite] node must be passed `+mustGet+` for its first function.
|
||||||
|
You passed {{bold}}%s{{/}} instead.`, t),
|
||||||
|
CodeLocation: cl,
|
||||||
|
DocLink: "node-decorators-overview",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g ginkgoErrors) InvalidBodyTypeForSynchronizedBeforeSuiteAllProcs(t reflect.Type, cl CodeLocation) error {
|
||||||
|
mustGet := "{{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}, {{bold}}func([]byte){{/}}, {{bold}}func(ctx SpecContext, []byte){{/}}, or {{bold}}func(ctx context.Context, []byte){{/}}"
|
||||||
|
return GinkgoError{
|
||||||
|
Heading: "Invalid Function",
|
||||||
|
Message: formatter.F(`[SynchronizedBeforeSuite] node must be passed `+mustGet+` for its second function.
|
||||||
|
You passed {{bold}}%s{{/}} instead.`, t),
|
||||||
|
CodeLocation: cl,
|
||||||
|
DocLink: "node-decorators-overview",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (g ginkgoErrors) MultipleBodyFunctions(cl CodeLocation, nodeType NodeType) error {
|
func (g ginkgoErrors) MultipleBodyFunctions(cl CodeLocation, nodeType NodeType) error {
|
||||||
return GinkgoError{
|
return GinkgoError{
|
||||||
Heading: "Multiple Functions",
|
Heading: "Multiple Functions",
|
||||||
Message: formatter.F(`[%s] node must be passed a single {{bold}}func(){{/}} - but more than one was passed in.`, nodeType),
|
Message: formatter.F(`[%s] node must be passed a single function - but more than one was passed in.`, nodeType),
|
||||||
CodeLocation: cl,
|
CodeLocation: cl,
|
||||||
DocLink: "node-decorators-overview",
|
DocLink: "node-decorators-overview",
|
||||||
}
|
}
|
||||||
@ -211,12 +246,30 @@ func (g ginkgoErrors) MultipleBodyFunctions(cl CodeLocation, nodeType NodeType)
|
|||||||
func (g ginkgoErrors) MissingBodyFunction(cl CodeLocation, nodeType NodeType) error {
|
func (g ginkgoErrors) MissingBodyFunction(cl CodeLocation, nodeType NodeType) error {
|
||||||
return GinkgoError{
|
return GinkgoError{
|
||||||
Heading: "Missing Functions",
|
Heading: "Missing Functions",
|
||||||
Message: formatter.F(`[%s] node must be passed a single {{bold}}func(){{/}} - but none was passed in.`, nodeType),
|
Message: formatter.F(`[%s] node must be passed a single function - but none was passed in.`, nodeType),
|
||||||
CodeLocation: cl,
|
CodeLocation: cl,
|
||||||
DocLink: "node-decorators-overview",
|
DocLink: "node-decorators-overview",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g ginkgoErrors) InvalidTimeoutOrGracePeriodForNonContextNode(cl CodeLocation, nodeType NodeType) error {
|
||||||
|
return GinkgoError{
|
||||||
|
Heading: "Invalid NodeTimeout SpecTimeout, or GracePeriod",
|
||||||
|
Message: formatter.F(`[%s] was passed NodeTimeout, SpecTimeout, or GracePeriod but does not have a callback that accepts a {{bold}}SpecContext{{/}} or {{bold}}context.Context{{/}}. You must accept a context to enable timeouts and grace periods`, nodeType),
|
||||||
|
CodeLocation: cl,
|
||||||
|
DocLink: "spec-timeouts-and-interruptible-nodes",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g ginkgoErrors) InvalidTimeoutOrGracePeriodForNonContextCleanupNode(cl CodeLocation) error {
|
||||||
|
return GinkgoError{
|
||||||
|
Heading: "Invalid NodeTimeout SpecTimeout, or GracePeriod",
|
||||||
|
Message: formatter.F(`[DeferCleanup] was passed NodeTimeout or GracePeriod but does not have a callback that accepts a {{bold}}SpecContext{{/}} or {{bold}}context.Context{{/}}. You must accept a context to enable timeouts and grace periods`),
|
||||||
|
CodeLocation: cl,
|
||||||
|
DocLink: "spec-timeouts-and-interruptible-nodes",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Ordered Container errors */
|
/* Ordered Container errors */
|
||||||
func (g ginkgoErrors) InvalidSerialNodeInNonSerialOrderedContainer(cl CodeLocation, nodeType NodeType) error {
|
func (g ginkgoErrors) InvalidSerialNodeInNonSerialOrderedContainer(cl CodeLocation, nodeType NodeType) error {
|
||||||
return GinkgoError{
|
return GinkgoError{
|
||||||
@ -380,6 +433,15 @@ func (g ginkgoErrors) InvalidEntryDescription(cl CodeLocation) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g ginkgoErrors) MissingParametersForTableFunction(cl CodeLocation) error {
|
||||||
|
return GinkgoError{
|
||||||
|
Heading: fmt.Sprintf("No parameters have been passed to the Table Function"),
|
||||||
|
Message: fmt.Sprintf("The Table Function expected at least 1 parameter"),
|
||||||
|
CodeLocation: cl,
|
||||||
|
DocLink: "table-specs",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (g ginkgoErrors) IncorrectParameterTypeForTable(i int, name string, cl CodeLocation) error {
|
func (g ginkgoErrors) IncorrectParameterTypeForTable(i int, name string, cl CodeLocation) error {
|
||||||
return GinkgoError{
|
return GinkgoError{
|
||||||
Heading: "DescribeTable passed incorrect parameter type",
|
Heading: "DescribeTable passed incorrect parameter type",
|
||||||
@ -498,6 +560,13 @@ func (g ginkgoErrors) DryRunInParallelConfiguration() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g ginkgoErrors) GracePeriodCannotBeZero() error {
|
||||||
|
return GinkgoError{
|
||||||
|
Heading: "Ginkgo requires a positive --grace-period.",
|
||||||
|
Message: "Please set --grace-period to a positive duration. The default is 30s.",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (g ginkgoErrors) ConflictingVerbosityConfiguration() error {
|
func (g ginkgoErrors) ConflictingVerbosityConfiguration() error {
|
||||||
return GinkgoError{
|
return GinkgoError{
|
||||||
Heading: "Conflicting reporter verbosity settings.",
|
Heading: "Conflicting reporter verbosity settings.",
|
||||||
|
28
vendor/github.com/onsi/ginkgo/v2/types/types.go
generated
vendored
28
vendor/github.com/onsi/ginkgo/v2/types/types.go
generated
vendored
@ -168,6 +168,9 @@ type SpecReport struct {
|
|||||||
|
|
||||||
// ProgressReports contains any progress reports generated during this spec. These can either be manually triggered, or automatically generated by Ginkgo via the PollProgressAfter() decorator
|
// ProgressReports contains any progress reports generated during this spec. These can either be manually triggered, or automatically generated by Ginkgo via the PollProgressAfter() decorator
|
||||||
ProgressReports []ProgressReport
|
ProgressReports []ProgressReport
|
||||||
|
|
||||||
|
// AdditionalFailures contains any failures that occurred after the initial spec failure. These typically occur in cleanup nodes after the initial failure and are only emitted when running in verbose mode.
|
||||||
|
AdditionalFailures []AdditionalFailure
|
||||||
}
|
}
|
||||||
|
|
||||||
func (report SpecReport) MarshalJSON() ([]byte, error) {
|
func (report SpecReport) MarshalJSON() ([]byte, error) {
|
||||||
@ -191,6 +194,7 @@ func (report SpecReport) MarshalJSON() ([]byte, error) {
|
|||||||
CapturedStdOutErr string `json:",omitempty"`
|
CapturedStdOutErr string `json:",omitempty"`
|
||||||
ReportEntries ReportEntries `json:",omitempty"`
|
ReportEntries ReportEntries `json:",omitempty"`
|
||||||
ProgressReports []ProgressReport `json:",omitempty"`
|
ProgressReports []ProgressReport `json:",omitempty"`
|
||||||
|
AdditionalFailures []AdditionalFailure `json:",omitempty"`
|
||||||
}{
|
}{
|
||||||
ContainerHierarchyTexts: report.ContainerHierarchyTexts,
|
ContainerHierarchyTexts: report.ContainerHierarchyTexts,
|
||||||
ContainerHierarchyLocations: report.ContainerHierarchyLocations,
|
ContainerHierarchyLocations: report.ContainerHierarchyLocations,
|
||||||
@ -220,6 +224,9 @@ func (report SpecReport) MarshalJSON() ([]byte, error) {
|
|||||||
if len(report.ProgressReports) > 0 {
|
if len(report.ProgressReports) > 0 {
|
||||||
out.ProgressReports = report.ProgressReports
|
out.ProgressReports = report.ProgressReports
|
||||||
}
|
}
|
||||||
|
if len(report.AdditionalFailures) > 0 {
|
||||||
|
out.AdditionalFailures = report.AdditionalFailures
|
||||||
|
}
|
||||||
|
|
||||||
return json.Marshal(out)
|
return json.Marshal(out)
|
||||||
}
|
}
|
||||||
@ -434,6 +441,14 @@ func (fnc FailureNodeContext) MarshalJSON() ([]byte, error) {
|
|||||||
return fncEnumSupport.MarshJSON(uint(fnc))
|
return fncEnumSupport.MarshJSON(uint(fnc))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AdditionalFailure capturs any additional failures that occur after the initial failure of a psec
|
||||||
|
// these typically occur in clean up nodes after the spec has failed.
|
||||||
|
// We can't simply use Failure as we want to track the SpecState to know what kind of failure this is
|
||||||
|
type AdditionalFailure struct {
|
||||||
|
State SpecState
|
||||||
|
Failure Failure
|
||||||
|
}
|
||||||
|
|
||||||
// SpecState captures the state of a spec
|
// SpecState captures the state of a spec
|
||||||
// To determine if a given `state` represents a failure state, use `state.Is(SpecStateFailureStates)`
|
// To determine if a given `state` represents a failure state, use `state.Is(SpecStateFailureStates)`
|
||||||
type SpecState uint
|
type SpecState uint
|
||||||
@ -448,6 +463,7 @@ const (
|
|||||||
SpecStateAborted
|
SpecStateAborted
|
||||||
SpecStatePanicked
|
SpecStatePanicked
|
||||||
SpecStateInterrupted
|
SpecStateInterrupted
|
||||||
|
SpecStateTimedout
|
||||||
)
|
)
|
||||||
|
|
||||||
var ssEnumSupport = NewEnumSupport(map[uint]string{
|
var ssEnumSupport = NewEnumSupport(map[uint]string{
|
||||||
@ -459,6 +475,7 @@ var ssEnumSupport = NewEnumSupport(map[uint]string{
|
|||||||
uint(SpecStateAborted): "aborted",
|
uint(SpecStateAborted): "aborted",
|
||||||
uint(SpecStatePanicked): "panicked",
|
uint(SpecStatePanicked): "panicked",
|
||||||
uint(SpecStateInterrupted): "interrupted",
|
uint(SpecStateInterrupted): "interrupted",
|
||||||
|
uint(SpecStateTimedout): "timedout",
|
||||||
})
|
})
|
||||||
|
|
||||||
func (ss SpecState) String() string {
|
func (ss SpecState) String() string {
|
||||||
@ -473,7 +490,7 @@ func (ss SpecState) MarshalJSON() ([]byte, error) {
|
|||||||
return ssEnumSupport.MarshJSON(uint(ss))
|
return ssEnumSupport.MarshJSON(uint(ss))
|
||||||
}
|
}
|
||||||
|
|
||||||
var SpecStateFailureStates = SpecStateFailed | SpecStateAborted | SpecStatePanicked | SpecStateInterrupted
|
var SpecStateFailureStates = SpecStateFailed | SpecStateTimedout | SpecStateAborted | SpecStatePanicked | SpecStateInterrupted
|
||||||
|
|
||||||
func (ss SpecState) Is(states SpecState) bool {
|
func (ss SpecState) Is(states SpecState) bool {
|
||||||
return ss&states != 0
|
return ss&states != 0
|
||||||
@ -481,6 +498,7 @@ func (ss SpecState) Is(states SpecState) bool {
|
|||||||
|
|
||||||
// ProgressReport captures the progress of the current spec. It is, effectively, a structured Ginkgo-aware stack trace
|
// ProgressReport captures the progress of the current spec. It is, effectively, a structured Ginkgo-aware stack trace
|
||||||
type ProgressReport struct {
|
type ProgressReport struct {
|
||||||
|
Message string
|
||||||
ParallelProcess int
|
ParallelProcess int
|
||||||
RunningInParallel bool
|
RunningInParallel bool
|
||||||
|
|
||||||
@ -500,6 +518,8 @@ type ProgressReport struct {
|
|||||||
CurrentStepLocation CodeLocation
|
CurrentStepLocation CodeLocation
|
||||||
CurrentStepStartTime time.Time
|
CurrentStepStartTime time.Time
|
||||||
|
|
||||||
|
AdditionalReports []string
|
||||||
|
|
||||||
CapturedGinkgoWriterOutput string `json:",omitempty"`
|
CapturedGinkgoWriterOutput string `json:",omitempty"`
|
||||||
GinkgoWriterOffset int
|
GinkgoWriterOffset int
|
||||||
|
|
||||||
@ -611,6 +631,8 @@ const (
|
|||||||
|
|
||||||
var NodeTypesForContainerAndIt = NodeTypeContainer | NodeTypeIt
|
var NodeTypesForContainerAndIt = NodeTypeContainer | NodeTypeIt
|
||||||
var NodeTypesForSuiteLevelNodes = NodeTypeBeforeSuite | NodeTypeSynchronizedBeforeSuite | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeReportAfterSuite | NodeTypeCleanupAfterSuite
|
var NodeTypesForSuiteLevelNodes = NodeTypeBeforeSuite | NodeTypeSynchronizedBeforeSuite | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeReportAfterSuite | NodeTypeCleanupAfterSuite
|
||||||
|
var NodeTypesAllowedDuringCleanupInterrupt = NodeTypeAfterEach | NodeTypeJustAfterEach | NodeTypeAfterAll | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeCleanupAfterEach | NodeTypeCleanupAfterAll | NodeTypeCleanupAfterSuite
|
||||||
|
var NodeTypesAllowedDuringReportInterrupt = NodeTypeReportBeforeEach | NodeTypeReportAfterEach | NodeTypeReportAfterSuite
|
||||||
|
|
||||||
var ntEnumSupport = NewEnumSupport(map[uint]string{
|
var ntEnumSupport = NewEnumSupport(map[uint]string{
|
||||||
uint(NodeTypeInvalid): "INVALID NODE TYPE",
|
uint(NodeTypeInvalid): "INVALID NODE TYPE",
|
||||||
@ -629,8 +651,8 @@ var ntEnumSupport = NewEnumSupport(map[uint]string{
|
|||||||
uint(NodeTypeReportBeforeEach): "ReportBeforeEach",
|
uint(NodeTypeReportBeforeEach): "ReportBeforeEach",
|
||||||
uint(NodeTypeReportAfterEach): "ReportAfterEach",
|
uint(NodeTypeReportAfterEach): "ReportAfterEach",
|
||||||
uint(NodeTypeReportAfterSuite): "ReportAfterSuite",
|
uint(NodeTypeReportAfterSuite): "ReportAfterSuite",
|
||||||
uint(NodeTypeCleanupInvalid): "INVALID CLEANUP NODE",
|
uint(NodeTypeCleanupInvalid): "DeferCleanup",
|
||||||
uint(NodeTypeCleanupAfterEach): "DeferCleanup",
|
uint(NodeTypeCleanupAfterEach): "DeferCleanup (Each)",
|
||||||
uint(NodeTypeCleanupAfterAll): "DeferCleanup (All)",
|
uint(NodeTypeCleanupAfterAll): "DeferCleanup (All)",
|
||||||
uint(NodeTypeCleanupAfterSuite): "DeferCleanup (Suite)",
|
uint(NodeTypeCleanupAfterSuite): "DeferCleanup (Suite)",
|
||||||
})
|
})
|
||||||
|
2
vendor/github.com/onsi/ginkgo/v2/types/version.go
generated
vendored
2
vendor/github.com/onsi/ginkgo/v2/types/version.go
generated
vendored
@ -1,3 +1,3 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
const VERSION = "2.2.0"
|
const VERSION = "2.3.1"
|
||||||
|
62
vendor/github.com/onsi/gomega/CHANGELOG.md
generated
vendored
62
vendor/github.com/onsi/gomega/CHANGELOG.md
generated
vendored
@ -1,3 +1,65 @@
|
|||||||
|
## 1.22.1
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
- When passed a context and no explicit timeout, Eventually will only timeout when the context is cancelled [e5105cf]
|
||||||
|
- Allow StopTrying() to be wrapped [bf3cba9]
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
- bump to ginkgo v2.3.0 [c5d5c39]
|
||||||
|
|
||||||
|
## 1.22.0
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
Several improvements have been made to `Eventually` and `Consistently` in this and the most recent releases:
|
||||||
|
|
||||||
|
- Eventually and Consistently can take a context.Context [65c01bc]
|
||||||
|
This enables integration with Ginkgo 2.3.0's interruptible nodes and node timeouts.
|
||||||
|
- Eventually and Consistently that are passed a SpecContext can provide reports when an interrupt occurs [0d063c9]
|
||||||
|
- Eventually/Consistently will forward an attached context to functions that ask for one [e2091c5]
|
||||||
|
- Eventually/Consistently supports passing arguments to functions via WithArguments() [a2dc7c3]
|
||||||
|
- Eventually and Consistently can now be stopped early with StopTrying(message) and StopTrying(message).Now() [52976bb]
|
||||||
|
|
||||||
|
These improvements are all documented in [Gomega's docs](https://onsi.github.io/gomega/#making-asynchronous-assertions)
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
|
||||||
|
## 1.21.1
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- Eventually and Consistently that are passed a SpecContext can provide reports when an interrupt occurs [0d063c9]
|
||||||
|
|
||||||
|
## 1.21.0
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- Eventually and Consistently can take a context.Context [65c01bc]
|
||||||
|
This enables integration with Ginkgo 2.3.0's interruptible nodes and node timeouts.
|
||||||
|
- Introduces Eventually.Within.ProbeEvery with tests and documentation (#591) [f633800]
|
||||||
|
- New BeKeyOf matcher with documentation and unit tests (#590) [fb586b3]
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
- Cover the entire gmeasure suite with leak detection [8c54344]
|
||||||
|
- Fix gmeasure leak [119d4ce]
|
||||||
|
- Ignore new Ginkgo ProgressSignal goroutine in gleak [ba548e2]
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
|
||||||
|
- Fixes crashes on newer Ruby 3 installations by upgrading github-pages gem dependency (#596) [12469a0]
|
||||||
|
|
||||||
|
|
||||||
|
## 1.20.2
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
- label specs that rely on remote access; bump timeout on short-circuit test to make it less flaky [35eeadf]
|
||||||
|
- gexec: allow more headroom for SIGABRT-related unit tests (#581) [5b78f40]
|
||||||
|
- Enable reading from a closed gbytes.Buffer (#575) [061fd26]
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
- Bump github.com/onsi/ginkgo/v2 from 2.1.5 to 2.1.6 (#583) [55d895b]
|
||||||
|
- Bump github.com/onsi/ginkgo/v2 from 2.1.4 to 2.1.5 (#582) [346de7c]
|
||||||
|
|
||||||
## 1.20.1
|
## 1.20.1
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
8
vendor/github.com/onsi/gomega/RELEASING.md
generated
vendored
8
vendor/github.com/onsi/gomega/RELEASING.md
generated
vendored
@ -1,7 +1,13 @@
|
|||||||
A Gomega release is a tagged sha and a GitHub release. To cut a release:
|
A Gomega release is a tagged sha and a GitHub release. To cut a release:
|
||||||
|
|
||||||
1. Ensure CHANGELOG.md is up to date.
|
1. Ensure CHANGELOG.md is up to date.
|
||||||
- Use `git log --pretty=format:'- %s [%h]' HEAD...vX.X.X` to list all the commits since the last release
|
- Use
|
||||||
|
```bash
|
||||||
|
LAST_VERSION=$(git tag --sort=version:refname | tail -n1)
|
||||||
|
CHANGES=$(git log --pretty=format:'- %s [%h]' HEAD...$LAST_VERSION)
|
||||||
|
echo -e "## NEXT\n\n$CHANGES\n\n### Features\n\n## Fixes\n\n## Maintenance\n\n$(cat CHANGELOG.md)" > CHANGELOG.md
|
||||||
|
```
|
||||||
|
to update the changelog
|
||||||
- Categorize the changes into
|
- Categorize the changes into
|
||||||
- Breaking Changes (requires a major version)
|
- Breaking Changes (requires a major version)
|
||||||
- New Features (minor version)
|
- New Features (minor version)
|
||||||
|
1
vendor/github.com/onsi/gomega/gmeasure/experiment.go
generated
vendored
1
vendor/github.com/onsi/gomega/gmeasure/experiment.go
generated
vendored
@ -463,6 +463,7 @@ func (e *Experiment) Sample(callback func(idx int), samplingConfig SamplingConfi
|
|||||||
minSamplingInterval := samplingConfig.MinSamplingInterval
|
minSamplingInterval := samplingConfig.MinSamplingInterval
|
||||||
|
|
||||||
work := make(chan int)
|
work := make(chan int)
|
||||||
|
defer close(work)
|
||||||
if numParallel > 1 {
|
if numParallel > 1 {
|
||||||
for worker := 0; worker < numParallel; worker++ {
|
for worker := 0; worker < numParallel; worker++ {
|
||||||
go func() {
|
go func() {
|
||||||
|
99
vendor/github.com/onsi/gomega/gomega_dsl.go
generated
vendored
99
vendor/github.com/onsi/gomega/gomega_dsl.go
generated
vendored
@ -22,7 +22,7 @@ import (
|
|||||||
"github.com/onsi/gomega/types"
|
"github.com/onsi/gomega/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
const GOMEGA_VERSION = "1.20.1"
|
const GOMEGA_VERSION = "1.22.1"
|
||||||
|
|
||||||
const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler.
|
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().
|
If you're using Ginkgo then you probably forgot to put your assertion in an It().
|
||||||
@ -233,7 +233,7 @@ func ExpectWithOffset(offset int, actual interface{}, extra ...interface{}) Asse
|
|||||||
Eventually enables making assertions on asynchronous behavior.
|
Eventually enables making assertions on asynchronous behavior.
|
||||||
|
|
||||||
Eventually checks that an assertion *eventually* passes. Eventually blocks when called and attempts an assertion periodically until it passes or a timeout occurs. Both the timeout and polling interval are configurable as optional arguments.
|
Eventually checks that an assertion *eventually* passes. Eventually blocks when called and attempts an assertion periodically until it passes or a timeout occurs. Both the timeout and polling interval are configurable as optional arguments.
|
||||||
The first optional argument is the timeout (which defaults to 1s), the second is the polling interval (which defaults to 10ms). Both intervals can be specified as time.Duration, parsable duration strings or floats/integers (in which case they are interpreted as seconds).
|
The first optional argument is the timeout (which defaults to 1s), the second is the polling interval (which defaults to 10ms). Both intervals can be specified as time.Duration, parsable duration strings or floats/integers (in which case they are interpreted as seconds). In addition an optional context.Context can be passed in - Eventually will keep trying until either the timeout epxires or the context is cancelled, whichever comes first.
|
||||||
|
|
||||||
Eventually works with any Gomega compatible matcher and supports making assertions against three categories of actual value:
|
Eventually works with any Gomega compatible matcher and supports making assertions against three categories of actual value:
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ this will trigger Go's race detector as the goroutine polling via Eventually wil
|
|||||||
|
|
||||||
**Category 2: Make Eventually assertions on functions**
|
**Category 2: Make Eventually assertions on functions**
|
||||||
|
|
||||||
Eventually can be passed functions that **take no arguments** and **return at least one value**. When configured this way, Eventually will poll the function repeatedly and pass the first returned value to the matcher.
|
Eventually can be passed functions that **return at least one value**. When configured this way, Eventually will poll the function repeatedly and pass the first returned value to the matcher.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
@ -286,7 +286,27 @@ Then
|
|||||||
|
|
||||||
will pass only if and when the returned error is nil *and* the returned string satisfies the matcher.
|
will pass only if and when the returned error is nil *and* the returned string satisfies the matcher.
|
||||||
|
|
||||||
It is important to note that the function passed into Eventually is invoked *synchronously* when polled. Eventually does not (in fact, it cannot) kill the function if it takes longer to return than Eventually's configured timeout. You should design your functions with this in mind.
|
Eventually can also accept functions that take arguments, however you must provide those arguments using .WithArguments(). For example, consider a function that takes a user-id and makes a network request to fetch a full name:
|
||||||
|
func FetchFullName(userId int) (string, error)
|
||||||
|
|
||||||
|
You can poll this function like so:
|
||||||
|
Eventually(FetchFullName).WithArguments(1138).Should(Equal("Wookie"))
|
||||||
|
|
||||||
|
It is important to note that the function passed into Eventually is invoked *synchronously* when polled. Eventually does not (in fact, it cannot) kill the function if it takes longer to return than Eventually's configured timeout. A common practice here is to use a context. Here's an example that combines Ginkgo's spec timeout support with Eventually:
|
||||||
|
|
||||||
|
It("fetches the correct count", func(ctx SpecContext) {
|
||||||
|
Eventually(func() int {
|
||||||
|
return client.FetchCount(ctx, "/users")
|
||||||
|
}, ctx).Should(BeNumerically(">=", 17))
|
||||||
|
}, SpecTimeout(time.Second))
|
||||||
|
|
||||||
|
you an also use Eventually().WithContext(ctx) to pass in the context. Passed-in contexts play nicely with paseed-in arguments as long as the context appears first. You can rewrite the above example as:
|
||||||
|
|
||||||
|
It("fetches the correct count", func(ctx SpecContext) {
|
||||||
|
Eventually(client.FetchCount).WithContext(ctx).WithArguments("/users").Should(BeNumerically(">=", 17))
|
||||||
|
}, SpecTimeout(time.Second))
|
||||||
|
|
||||||
|
Either way the context passd to Eventually is also passed to the underlying funciton. Now, when Ginkgo cancels the context both the FetchCount client and Gomega will be informed and can exit.
|
||||||
|
|
||||||
**Category 3: Making assertions _in_ the function passed into Eventually**
|
**Category 3: Making assertions _in_ the function passed into Eventually**
|
||||||
|
|
||||||
@ -316,12 +336,28 @@ For example:
|
|||||||
|
|
||||||
will rerun the function until all assertions pass.
|
will rerun the function until all assertions pass.
|
||||||
|
|
||||||
`Eventually` specifying a timeout interval (and an optional polling interval) are
|
You can also pass additional arugments to functions that take a Gomega. The only rule is that the Gomega argument must be first. If you also want to pass the context attached to Eventually you must ensure that is the second argument. For example:
|
||||||
the same as `Eventually(...).WithTimeout` or `Eventually(...).WithTimeout(...).WithPolling`.
|
|
||||||
|
Eventually(func(g Gomega, ctx context.Context, path string, expected ...string){
|
||||||
|
tok, err := client.GetToken(ctx)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
elements, err := client.Fetch(ctx, tok, path)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
g.Expect(elements).To(ConsistOf(expected))
|
||||||
|
}).WithContext(ctx).WithArguments("/names", "Joe", "Jane", "Sam").Should(Succeed())
|
||||||
|
|
||||||
|
Finally, in addition to passing timeouts and a context to Eventually you can be more explicit with Eventually's chaining configuration methods:
|
||||||
|
|
||||||
|
Eventually(..., "1s", "2s", ctx).Should(...)
|
||||||
|
|
||||||
|
is equivalent to
|
||||||
|
|
||||||
|
Eventually(...).WithTimeout(time.Second).WithPolling(2*time.Second).WithContext(ctx).Should(...)
|
||||||
*/
|
*/
|
||||||
func Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion {
|
func Eventually(actual interface{}, args ...interface{}) AsyncAssertion {
|
||||||
ensureDefaultGomegaIsConfigured()
|
ensureDefaultGomegaIsConfigured()
|
||||||
return Default.Eventually(actual, intervals...)
|
return Default.Eventually(actual, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventuallyWithOffset operates like Eventually but takes an additional
|
// EventuallyWithOffset operates like Eventually but takes an additional
|
||||||
@ -333,9 +369,9 @@ func Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion {
|
|||||||
// `EventuallyWithOffset` specifying a timeout interval (and an optional polling interval) are
|
// `EventuallyWithOffset` specifying a timeout interval (and an optional polling interval) are
|
||||||
// the same as `Eventually(...).WithOffset(...).WithTimeout` or
|
// the same as `Eventually(...).WithOffset(...).WithTimeout` or
|
||||||
// `Eventually(...).WithOffset(...).WithTimeout(...).WithPolling`.
|
// `Eventually(...).WithOffset(...).WithTimeout(...).WithPolling`.
|
||||||
func EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion {
|
func EventuallyWithOffset(offset int, actual interface{}, args ...interface{}) AsyncAssertion {
|
||||||
ensureDefaultGomegaIsConfigured()
|
ensureDefaultGomegaIsConfigured()
|
||||||
return Default.EventuallyWithOffset(offset, actual, intervals...)
|
return Default.EventuallyWithOffset(offset, actual, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -343,7 +379,7 @@ Consistently, like Eventually, enables making assertions on asynchronous behavio
|
|||||||
|
|
||||||
Consistently blocks when called for a specified duration. During that duration Consistently repeatedly polls its matcher and ensures that it is satisfied. If the matcher is consistently satisfied, then Consistently will pass. Otherwise Consistently will fail.
|
Consistently blocks when called for a specified duration. During that duration Consistently repeatedly polls its matcher and ensures that it is satisfied. If the matcher is consistently satisfied, then Consistently will pass. Otherwise Consistently will fail.
|
||||||
|
|
||||||
Both the total waiting duration and the polling interval are configurable as optional arguments. The first optional argument is the duration that Consistently will run for (defaults to 100ms), and the second argument is the polling interval (defaults to 10ms). As with Eventually, these intervals can be passed in as time.Duration, parsable duration strings or an integer or float number of seconds.
|
Both the total waiting duration and the polling interval are configurable as optional arguments. The first optional argument is the duration that Consistently will run for (defaults to 100ms), and the second argument is the polling interval (defaults to 10ms). As with Eventually, these intervals can be passed in as time.Duration, parsable duration strings or an integer or float number of seconds. You can also pass in an optional context.Context - Consistently will exit early (with a failure) if the context is cancelled before the waiting duration expires.
|
||||||
|
|
||||||
Consistently accepts the same three categories of actual as Eventually, check the Eventually docs to learn more.
|
Consistently accepts the same three categories of actual as Eventually, check the Eventually docs to learn more.
|
||||||
|
|
||||||
@ -353,9 +389,9 @@ Consistently is useful in cases where you want to assert that something *does no
|
|||||||
|
|
||||||
This will block for 200 milliseconds and repeatedly check the channel and ensure nothing has been received.
|
This will block for 200 milliseconds and repeatedly check the channel and ensure nothing has been received.
|
||||||
*/
|
*/
|
||||||
func Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion {
|
func Consistently(actual interface{}, args ...interface{}) AsyncAssertion {
|
||||||
ensureDefaultGomegaIsConfigured()
|
ensureDefaultGomegaIsConfigured()
|
||||||
return Default.Consistently(actual, intervals...)
|
return Default.Consistently(actual, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConsistentlyWithOffset operates like Consistently but takes an additional
|
// ConsistentlyWithOffset operates like Consistently but takes an additional
|
||||||
@ -364,11 +400,44 @@ func Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion {
|
|||||||
//
|
//
|
||||||
// `ConsistentlyWithOffset` is the same as `Consistently(...).WithOffset` and
|
// `ConsistentlyWithOffset` is the same as `Consistently(...).WithOffset` and
|
||||||
// optional `WithTimeout` and `WithPolling`.
|
// optional `WithTimeout` and `WithPolling`.
|
||||||
func ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion {
|
func ConsistentlyWithOffset(offset int, actual interface{}, args ...interface{}) AsyncAssertion {
|
||||||
ensureDefaultGomegaIsConfigured()
|
ensureDefaultGomegaIsConfigured()
|
||||||
return Default.ConsistentlyWithOffset(offset, actual, intervals...)
|
return Default.ConsistentlyWithOffset(offset, actual, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
StopTrying can be used to signal to Eventually and Consistently that the polled function will not change
|
||||||
|
and that they should stop trying. In the case of Eventually, if a match does not occur in this, final, iteration then a failure will result. In the case of Consistently, as long as this last iteration satisfies the match, the assertion will be considered successful.
|
||||||
|
|
||||||
|
You can send the StopTrying signal by either returning a StopTrying("message") messages as an error from your passed-in function _or_ by calling StopTrying("message").Now() to trigger a panic and end execution.
|
||||||
|
|
||||||
|
Here are a couple of examples. This is how you might use StopTrying() as an error to signal that Eventually should stop:
|
||||||
|
|
||||||
|
playerIndex, numPlayers := 0, 11
|
||||||
|
Eventually(func() (string, error) {
|
||||||
|
name := client.FetchPlayer(playerIndex)
|
||||||
|
playerIndex += 1
|
||||||
|
if playerIndex == numPlayers {
|
||||||
|
return name, StopTrying("No more players left")
|
||||||
|
} else {
|
||||||
|
return name, nil
|
||||||
|
}
|
||||||
|
}).Should(Equal("Patrick Mahomes"))
|
||||||
|
|
||||||
|
note that the final `name` returned alongside `StopTrying()` will be processed.
|
||||||
|
|
||||||
|
And here's an example where `StopTrying().Now()` is called to halt execution immediately:
|
||||||
|
|
||||||
|
Eventually(func() []string {
|
||||||
|
names, err := client.FetchAllPlayers()
|
||||||
|
if err == client.IRRECOVERABLE_ERROR {
|
||||||
|
StopTrying("Irrecoverable error occurred").Now()
|
||||||
|
}
|
||||||
|
return names
|
||||||
|
}).Should(ContainElement("Patrick Mahomes"))
|
||||||
|
*/
|
||||||
|
var StopTrying = internal.StopTrying
|
||||||
|
|
||||||
// SetDefaultEventuallyTimeout sets the default timeout duration for Eventually. Eventually will repeatedly poll your condition until it succeeds, or until this timeout elapses.
|
// SetDefaultEventuallyTimeout sets the default timeout duration for Eventually. Eventually will repeatedly poll your condition until it succeeds, or until this timeout elapses.
|
||||||
func SetDefaultEventuallyTimeout(t time.Duration) {
|
func SetDefaultEventuallyTimeout(t time.Duration) {
|
||||||
Default.SetDefaultEventuallyTimeout(t)
|
Default.SetDefaultEventuallyTimeout(t)
|
||||||
|
426
vendor/github.com/onsi/gomega/internal/async_assertion.go
generated
vendored
426
vendor/github.com/onsi/gomega/internal/async_assertion.go
generated
vendored
@ -1,15 +1,61 @@
|
|||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/onsi/gomega/types"
|
"github.com/onsi/gomega/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type StopTryingError interface {
|
||||||
|
error
|
||||||
|
Now()
|
||||||
|
wasViaPanic() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func asStopTryingError(actual interface{}) (StopTryingError, bool) {
|
||||||
|
if actual == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
if actualErr, ok := actual.(error); ok {
|
||||||
|
var target *stopTryingError
|
||||||
|
if errors.As(actualErr, &target) {
|
||||||
|
return target, true
|
||||||
|
} else {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
type stopTryingError struct {
|
||||||
|
message string
|
||||||
|
viaPanic bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stopTryingError) Error() string {
|
||||||
|
return s.message
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stopTryingError) Now() {
|
||||||
|
s.viaPanic = true
|
||||||
|
panic(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stopTryingError) wasViaPanic() bool {
|
||||||
|
return s.viaPanic
|
||||||
|
}
|
||||||
|
|
||||||
|
var StopTrying = func(message string) StopTryingError {
|
||||||
|
return &stopTryingError{message: message}
|
||||||
|
}
|
||||||
|
|
||||||
type AsyncAssertionType uint
|
type AsyncAssertionType uint
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -17,71 +63,43 @@ const (
|
|||||||
AsyncAssertionTypeConsistently
|
AsyncAssertionTypeConsistently
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (at AsyncAssertionType) String() string {
|
||||||
|
switch at {
|
||||||
|
case AsyncAssertionTypeEventually:
|
||||||
|
return "Eventually"
|
||||||
|
case AsyncAssertionTypeConsistently:
|
||||||
|
return "Consistently"
|
||||||
|
}
|
||||||
|
return "INVALID ASYNC ASSERTION TYPE"
|
||||||
|
}
|
||||||
|
|
||||||
type AsyncAssertion struct {
|
type AsyncAssertion struct {
|
||||||
asyncType AsyncAssertionType
|
asyncType AsyncAssertionType
|
||||||
|
|
||||||
actualIsFunc bool
|
actualIsFunc bool
|
||||||
actualValue interface{}
|
actual interface{}
|
||||||
actualFunc func() ([]reflect.Value, error)
|
argsToForward []interface{}
|
||||||
|
|
||||||
timeoutInterval time.Duration
|
timeoutInterval time.Duration
|
||||||
pollingInterval time.Duration
|
pollingInterval time.Duration
|
||||||
|
ctx context.Context
|
||||||
offset int
|
offset int
|
||||||
g *Gomega
|
g *Gomega
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAsyncAssertion(asyncType AsyncAssertionType, actualInput interface{}, g *Gomega, timeoutInterval time.Duration, pollingInterval time.Duration, offset int) *AsyncAssertion {
|
func NewAsyncAssertion(asyncType AsyncAssertionType, actualInput interface{}, g *Gomega, timeoutInterval time.Duration, pollingInterval time.Duration, ctx context.Context, offset int) *AsyncAssertion {
|
||||||
out := &AsyncAssertion{
|
out := &AsyncAssertion{
|
||||||
asyncType: asyncType,
|
asyncType: asyncType,
|
||||||
timeoutInterval: timeoutInterval,
|
timeoutInterval: timeoutInterval,
|
||||||
pollingInterval: pollingInterval,
|
pollingInterval: pollingInterval,
|
||||||
offset: offset,
|
offset: offset,
|
||||||
|
ctx: ctx,
|
||||||
g: g,
|
g: g,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch actualType := reflect.TypeOf(actualInput); {
|
out.actual = actualInput
|
||||||
case actualInput == nil || actualType.Kind() != reflect.Func:
|
if actualInput != nil && reflect.TypeOf(actualInput).Kind() == reflect.Func {
|
||||||
out.actualValue = actualInput
|
|
||||||
case actualType.NumIn() == 0 && actualType.NumOut() > 0:
|
|
||||||
out.actualIsFunc = true
|
out.actualIsFunc = true
|
||||||
out.actualFunc = func() ([]reflect.Value, error) {
|
|
||||||
return reflect.ValueOf(actualInput).Call([]reflect.Value{}), nil
|
|
||||||
}
|
|
||||||
case actualType.NumIn() == 1 && actualType.In(0).Implements(reflect.TypeOf((*types.Gomega)(nil)).Elem()):
|
|
||||||
out.actualIsFunc = true
|
|
||||||
out.actualFunc = func() (values []reflect.Value, err error) {
|
|
||||||
var assertionFailure error
|
|
||||||
assertionCapturingGomega := NewGomega(g.DurationBundle).ConfigureWithFailHandler(func(message string, callerSkip ...int) {
|
|
||||||
skip := 0
|
|
||||||
if len(callerSkip) > 0 {
|
|
||||||
skip = callerSkip[0]
|
|
||||||
}
|
|
||||||
_, file, line, _ := runtime.Caller(skip + 1)
|
|
||||||
assertionFailure = fmt.Errorf("Assertion in callback at %s:%d failed:\n%s", file, line, message)
|
|
||||||
panic("stop execution")
|
|
||||||
})
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if actualType.NumOut() == 0 {
|
|
||||||
if assertionFailure == nil {
|
|
||||||
values = []reflect.Value{reflect.Zero(reflect.TypeOf((*error)(nil)).Elem())}
|
|
||||||
} else {
|
|
||||||
values = []reflect.Value{reflect.ValueOf(assertionFailure)}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = assertionFailure
|
|
||||||
}
|
|
||||||
if e := recover(); e != nil && assertionFailure == nil {
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
values = reflect.ValueOf(actualInput).Call([]reflect.Value{reflect.ValueOf(assertionCapturingGomega)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
msg := fmt.Sprintf("The function passed to Gomega's async assertions should either take no arguments and return values, or take a single Gomega interface that it can use to make assertions within the body of the function. When taking a Gomega interface the function can optionally return values or return nothing. The function you passed takes %d arguments and returns %d values.", actualType.NumIn(), actualType.NumOut())
|
|
||||||
g.Fail(msg, offset+4)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return out
|
return out
|
||||||
@ -102,6 +120,26 @@ func (assertion *AsyncAssertion) WithPolling(interval time.Duration) types.Async
|
|||||||
return assertion
|
return assertion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (assertion *AsyncAssertion) Within(timeout time.Duration) types.AsyncAssertion {
|
||||||
|
assertion.timeoutInterval = timeout
|
||||||
|
return assertion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (assertion *AsyncAssertion) ProbeEvery(interval time.Duration) types.AsyncAssertion {
|
||||||
|
assertion.pollingInterval = interval
|
||||||
|
return assertion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (assertion *AsyncAssertion) WithContext(ctx context.Context) types.AsyncAssertion {
|
||||||
|
assertion.ctx = ctx
|
||||||
|
return assertion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (assertion *AsyncAssertion) WithArguments(argsToForward ...interface{}) types.AsyncAssertion {
|
||||||
|
assertion.argsToForward = argsToForward
|
||||||
|
return assertion
|
||||||
|
}
|
||||||
|
|
||||||
func (assertion *AsyncAssertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
|
func (assertion *AsyncAssertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
|
||||||
assertion.g.THelper()
|
assertion.g.THelper()
|
||||||
vetOptionalDescription("Asynchronous assertion", optionalDescription...)
|
vetOptionalDescription("Asynchronous assertion", optionalDescription...)
|
||||||
@ -126,50 +164,225 @@ func (assertion *AsyncAssertion) buildDescription(optionalDescription ...interfa
|
|||||||
return fmt.Sprintf(optionalDescription[0].(string), optionalDescription[1:]...) + "\n"
|
return fmt.Sprintf(optionalDescription[0].(string), optionalDescription[1:]...) + "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (assertion *AsyncAssertion) pollActual() (interface{}, error) {
|
func (assertion *AsyncAssertion) processReturnValues(values []reflect.Value) (interface{}, error, StopTryingError) {
|
||||||
|
var err error
|
||||||
|
var stopTrying StopTryingError
|
||||||
|
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil, fmt.Errorf("No values were returned by the function passed to Gomega"), stopTrying
|
||||||
|
}
|
||||||
|
actual := values[0].Interface()
|
||||||
|
if stopTryingErr, ok := asStopTryingError(actual); ok {
|
||||||
|
stopTrying = stopTryingErr
|
||||||
|
}
|
||||||
|
for i, extraValue := range values[1:] {
|
||||||
|
extra := extraValue.Interface()
|
||||||
|
if extra == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if stopTryingErr, ok := asStopTryingError(extra); ok {
|
||||||
|
stopTrying = stopTryingErr
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
zero := reflect.Zero(reflect.TypeOf(extra)).Interface()
|
||||||
|
if reflect.DeepEqual(extra, zero) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
err = fmt.Errorf("Unexpected non-nil/non-zero argument at index %d:\n\t<%T>: %#v", i+1, extra, extra)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actual, err, stopTrying
|
||||||
|
}
|
||||||
|
|
||||||
|
var gomegaType = reflect.TypeOf((*types.Gomega)(nil)).Elem()
|
||||||
|
var contextType = reflect.TypeOf(new(context.Context)).Elem()
|
||||||
|
|
||||||
|
func (assertion *AsyncAssertion) invalidFunctionError(t reflect.Type) error {
|
||||||
|
return fmt.Errorf(`The function passed to %s had an invalid signature of %s. Functions passed to %s must either:
|
||||||
|
|
||||||
|
(a) have return values or
|
||||||
|
(b) take a Gomega interface as their first argument and use that Gomega instance to make assertions.
|
||||||
|
|
||||||
|
You can learn more at https://onsi.github.io/gomega/#eventually
|
||||||
|
`, assertion.asyncType, t, assertion.asyncType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (assertion *AsyncAssertion) noConfiguredContextForFunctionError() error {
|
||||||
|
return fmt.Errorf(`The function passed to %s requested a context.Context, but no context has been provided. Please pass one in using %s().WithContext().
|
||||||
|
|
||||||
|
You can learn more at https://onsi.github.io/gomega/#eventually
|
||||||
|
`, assertion.asyncType, assertion.asyncType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (assertion *AsyncAssertion) argumentMismatchError(t reflect.Type, numProvided int) error {
|
||||||
|
have := "have"
|
||||||
|
if numProvided == 1 {
|
||||||
|
have = "has"
|
||||||
|
}
|
||||||
|
return fmt.Errorf(`The function passed to %s has signature %s takes %d arguments but %d %s been provided. Please use %s().WithArguments() to pass the corect set of arguments.
|
||||||
|
|
||||||
|
You can learn more at https://onsi.github.io/gomega/#eventually
|
||||||
|
`, assertion.asyncType, t, t.NumIn(), numProvided, have, assertion.asyncType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (assertion *AsyncAssertion) buildActualPoller() (func() (interface{}, error, StopTryingError), error) {
|
||||||
if !assertion.actualIsFunc {
|
if !assertion.actualIsFunc {
|
||||||
return assertion.actualValue, nil
|
return func() (interface{}, error, StopTryingError) { return assertion.actual, nil, nil }, nil
|
||||||
|
}
|
||||||
|
actualValue := reflect.ValueOf(assertion.actual)
|
||||||
|
actualType := reflect.TypeOf(assertion.actual)
|
||||||
|
numIn, numOut, isVariadic := actualType.NumIn(), actualType.NumOut(), actualType.IsVariadic()
|
||||||
|
|
||||||
|
if numIn == 0 && numOut == 0 {
|
||||||
|
return nil, assertion.invalidFunctionError(actualType)
|
||||||
|
} else if numIn == 0 {
|
||||||
|
return func() (actual interface{}, err error, stopTrying StopTryingError) {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
if stopTryingErr, ok := asStopTryingError(e); ok {
|
||||||
|
stopTrying = stopTryingErr
|
||||||
|
} else {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
actual, err, stopTrying = assertion.processReturnValues(actualValue.Call([]reflect.Value{}))
|
||||||
|
return
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
takesGomega, takesContext := actualType.In(0).Implements(gomegaType), actualType.In(0).Implements(contextType)
|
||||||
|
if takesGomega && numIn > 1 && actualType.In(1).Implements(contextType) {
|
||||||
|
takesContext = true
|
||||||
|
}
|
||||||
|
if takesContext && len(assertion.argsToForward) > 0 && reflect.TypeOf(assertion.argsToForward[0]).Implements(contextType) {
|
||||||
|
takesContext = false
|
||||||
|
}
|
||||||
|
if !takesGomega && numOut == 0 {
|
||||||
|
return nil, assertion.invalidFunctionError(actualType)
|
||||||
|
}
|
||||||
|
if takesContext && assertion.ctx == nil {
|
||||||
|
return nil, assertion.noConfiguredContextForFunctionError()
|
||||||
}
|
}
|
||||||
|
|
||||||
values, err := assertion.actualFunc()
|
var assertionFailure error
|
||||||
if err != nil {
|
inValues := []reflect.Value{}
|
||||||
return nil, err
|
if takesGomega {
|
||||||
|
inValues = append(inValues, reflect.ValueOf(NewGomega(assertion.g.DurationBundle).ConfigureWithFailHandler(func(message string, callerSkip ...int) {
|
||||||
|
skip := 0
|
||||||
|
if len(callerSkip) > 0 {
|
||||||
|
skip = callerSkip[0]
|
||||||
}
|
}
|
||||||
extras := []interface{}{nil}
|
_, file, line, _ := runtime.Caller(skip + 1)
|
||||||
for _, value := range values[1:] {
|
assertionFailure = fmt.Errorf("Assertion in callback at %s:%d failed:\n%s", file, line, message)
|
||||||
extras = append(extras, value.Interface())
|
panic("stop execution")
|
||||||
|
})))
|
||||||
}
|
}
|
||||||
success, message := vetActuals(extras, 0)
|
if takesContext {
|
||||||
if !success {
|
inValues = append(inValues, reflect.ValueOf(assertion.ctx))
|
||||||
return nil, errors.New(message)
|
}
|
||||||
|
for _, arg := range assertion.argsToForward {
|
||||||
|
inValues = append(inValues, reflect.ValueOf(arg))
|
||||||
}
|
}
|
||||||
|
|
||||||
return values[0].Interface(), nil
|
if !isVariadic && numIn != len(inValues) {
|
||||||
|
return nil, assertion.argumentMismatchError(actualType, len(inValues))
|
||||||
|
} else if isVariadic && len(inValues) < numIn-1 {
|
||||||
|
return nil, assertion.argumentMismatchError(actualType, len(inValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (assertion *AsyncAssertion) matcherMayChange(matcher types.GomegaMatcher, value interface{}) bool {
|
return func() (actual interface{}, err error, stopTrying StopTryingError) {
|
||||||
if assertion.actualIsFunc {
|
var values []reflect.Value
|
||||||
return true
|
assertionFailure = nil
|
||||||
|
defer func() {
|
||||||
|
if numOut == 0 {
|
||||||
|
actual = assertionFailure
|
||||||
|
} else {
|
||||||
|
actual, err, stopTrying = assertion.processReturnValues(values)
|
||||||
|
if assertionFailure != nil {
|
||||||
|
err = assertionFailure
|
||||||
}
|
}
|
||||||
return types.MatchMayChangeInTheFuture(matcher, value)
|
}
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
if stopTryingErr, ok := asStopTryingError(e); ok {
|
||||||
|
stopTrying = stopTryingErr
|
||||||
|
} else if assertionFailure == nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
values = actualValue.Call(inValues)
|
||||||
|
return
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (assertion *AsyncAssertion) matcherSaysStopTrying(matcher types.GomegaMatcher, value interface{}) StopTryingError {
|
||||||
|
if assertion.actualIsFunc || types.MatchMayChangeInTheFuture(matcher, value) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return StopTrying("No future change is possible. Bailing out early")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (assertion *AsyncAssertion) afterTimeout() <-chan time.Time {
|
||||||
|
if assertion.timeoutInterval >= 0 {
|
||||||
|
return time.After(assertion.timeoutInterval)
|
||||||
|
}
|
||||||
|
|
||||||
|
if assertion.asyncType == AsyncAssertionTypeConsistently {
|
||||||
|
return time.After(assertion.g.DurationBundle.ConsistentlyDuration)
|
||||||
|
} else {
|
||||||
|
if assertion.ctx == nil {
|
||||||
|
return time.After(assertion.g.DurationBundle.EventuallyTimeout)
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (assertion *AsyncAssertion) afterPolling() <-chan time.Time {
|
||||||
|
if assertion.pollingInterval >= 0 {
|
||||||
|
return time.After(assertion.pollingInterval)
|
||||||
|
}
|
||||||
|
if assertion.asyncType == AsyncAssertionTypeConsistently {
|
||||||
|
return time.After(assertion.g.DurationBundle.ConsistentlyPollingInterval)
|
||||||
|
} else {
|
||||||
|
return time.After(assertion.g.DurationBundle.EventuallyPollingInterval)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type contextWithAttachProgressReporter interface {
|
||||||
|
AttachProgressReporter(func() string) func()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch bool, optionalDescription ...interface{}) bool {
|
func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch bool, optionalDescription ...interface{}) bool {
|
||||||
timer := time.Now()
|
timer := time.Now()
|
||||||
timeout := time.After(assertion.timeoutInterval)
|
timeout := assertion.afterTimeout()
|
||||||
|
lock := sync.Mutex{}
|
||||||
|
|
||||||
var matches bool
|
var matches bool
|
||||||
var err error
|
var err error
|
||||||
mayChange := true
|
|
||||||
value, err := assertion.pollActual()
|
|
||||||
if err == nil {
|
|
||||||
mayChange = assertion.matcherMayChange(matcher, value)
|
|
||||||
matches, err = matcher.Match(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
assertion.g.THelper()
|
assertion.g.THelper()
|
||||||
|
|
||||||
fail := func(preamble string) {
|
pollActual, err := assertion.buildActualPoller()
|
||||||
|
if err != nil {
|
||||||
|
assertion.g.Fail(err.Error(), 2+assertion.offset)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err, stopTrying := pollActual()
|
||||||
|
if err == nil {
|
||||||
|
if stopTrying == nil {
|
||||||
|
stopTrying = assertion.matcherSaysStopTrying(matcher, value)
|
||||||
|
}
|
||||||
|
matches, err = matcher.Match(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
messageGenerator := func() string {
|
||||||
|
// can be called out of band by Ginkgo if the user requests a progress report
|
||||||
|
lock.Lock()
|
||||||
|
defer lock.Unlock()
|
||||||
errMsg := ""
|
errMsg := ""
|
||||||
message := ""
|
message := ""
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -181,9 +394,22 @@ func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch
|
|||||||
message = matcher.NegatedFailureMessage(value)
|
message = matcher.NegatedFailureMessage(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertion.g.THelper()
|
|
||||||
description := assertion.buildDescription(optionalDescription...)
|
description := assertion.buildDescription(optionalDescription...)
|
||||||
assertion.g.Fail(fmt.Sprintf("%s after %.3fs.\n%s%s%s", preamble, time.Since(timer).Seconds(), description, message, errMsg), 3+assertion.offset)
|
return fmt.Sprintf("%s%s%s", description, message, errMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
fail := func(preamble string) {
|
||||||
|
assertion.g.THelper()
|
||||||
|
assertion.g.Fail(fmt.Sprintf("%s after %.3fs.\n%s", preamble, time.Since(timer).Seconds(), messageGenerator()), 3+assertion.offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
var contextDone <-chan struct{}
|
||||||
|
if assertion.ctx != nil {
|
||||||
|
contextDone = assertion.ctx.Done()
|
||||||
|
if v, ok := assertion.ctx.Value("GINKGO_SPEC_CONTEXT").(contextWithAttachProgressReporter); ok {
|
||||||
|
detach := v.AttachProgressReporter(messageGenerator)
|
||||||
|
defer detach()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if assertion.asyncType == AsyncAssertionTypeEventually {
|
if assertion.asyncType == AsyncAssertionTypeEventually {
|
||||||
@ -192,18 +418,35 @@ func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !mayChange {
|
if stopTrying != nil {
|
||||||
fail("No future change is possible. Bailing out early")
|
fail(stopTrying.Error() + " -")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-time.After(assertion.pollingInterval):
|
case <-assertion.afterPolling():
|
||||||
value, err = assertion.pollActual()
|
v, e, st := pollActual()
|
||||||
if err == nil {
|
if st != nil && st.wasViaPanic() {
|
||||||
mayChange = assertion.matcherMayChange(matcher, value)
|
// we were told to stop trying via panic - which means we dont' have reasonable new values
|
||||||
matches, err = matcher.Match(value)
|
// we should simply use the old values and exit now
|
||||||
|
fail(st.Error() + " -")
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
lock.Lock()
|
||||||
|
value, err, stopTrying = v, e, st
|
||||||
|
lock.Unlock()
|
||||||
|
if err == nil {
|
||||||
|
if stopTrying == nil {
|
||||||
|
stopTrying = assertion.matcherSaysStopTrying(matcher, value)
|
||||||
|
}
|
||||||
|
matches, e = matcher.Match(value)
|
||||||
|
lock.Lock()
|
||||||
|
err = e
|
||||||
|
lock.Unlock()
|
||||||
|
}
|
||||||
|
case <-contextDone:
|
||||||
|
fail("Context was cancelled")
|
||||||
|
return false
|
||||||
case <-timeout:
|
case <-timeout:
|
||||||
fail("Timed out")
|
fail("Timed out")
|
||||||
return false
|
return false
|
||||||
@ -216,17 +459,32 @@ func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if !mayChange {
|
if stopTrying != nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-time.After(assertion.pollingInterval):
|
case <-assertion.afterPolling():
|
||||||
value, err = assertion.pollActual()
|
v, e, st := pollActual()
|
||||||
if err == nil {
|
if st != nil && st.wasViaPanic() {
|
||||||
mayChange = assertion.matcherMayChange(matcher, value)
|
// we were told to stop trying via panic - which means we made it this far and should return successfully
|
||||||
matches, err = matcher.Match(value)
|
return true
|
||||||
}
|
}
|
||||||
|
lock.Lock()
|
||||||
|
value, err, stopTrying = v, e, st
|
||||||
|
lock.Unlock()
|
||||||
|
if err == nil {
|
||||||
|
if stopTrying == nil {
|
||||||
|
stopTrying = assertion.matcherSaysStopTrying(matcher, value)
|
||||||
|
}
|
||||||
|
matches, e = matcher.Match(value)
|
||||||
|
lock.Lock()
|
||||||
|
err = e
|
||||||
|
lock.Unlock()
|
||||||
|
}
|
||||||
|
case <-contextDone:
|
||||||
|
fail("Context was cancelled")
|
||||||
|
return false
|
||||||
case <-timeout:
|
case <-timeout:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
37
vendor/github.com/onsi/gomega/internal/gomega.go
generated
vendored
37
vendor/github.com/onsi/gomega/internal/gomega.go
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/onsi/gomega/types"
|
"github.com/onsi/gomega/types"
|
||||||
@ -55,9 +56,19 @@ func (g *Gomega) Eventually(actual interface{}, intervals ...interface{}) types.
|
|||||||
return g.EventuallyWithOffset(0, actual, intervals...)
|
return g.EventuallyWithOffset(0, actual, intervals...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Gomega) EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) types.AsyncAssertion {
|
func (g *Gomega) EventuallyWithOffset(offset int, actual interface{}, args ...interface{}) types.AsyncAssertion {
|
||||||
timeoutInterval := g.DurationBundle.EventuallyTimeout
|
timeoutInterval := -time.Duration(1)
|
||||||
pollingInterval := g.DurationBundle.EventuallyPollingInterval
|
pollingInterval := -time.Duration(1)
|
||||||
|
intervals := []interface{}{}
|
||||||
|
var ctx context.Context
|
||||||
|
for _, arg := range args {
|
||||||
|
switch v := arg.(type) {
|
||||||
|
case context.Context:
|
||||||
|
ctx = v
|
||||||
|
default:
|
||||||
|
intervals = append(intervals, arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
if len(intervals) > 0 {
|
if len(intervals) > 0 {
|
||||||
timeoutInterval = toDuration(intervals[0])
|
timeoutInterval = toDuration(intervals[0])
|
||||||
}
|
}
|
||||||
@ -65,16 +76,26 @@ func (g *Gomega) EventuallyWithOffset(offset int, actual interface{}, intervals
|
|||||||
pollingInterval = toDuration(intervals[1])
|
pollingInterval = toDuration(intervals[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewAsyncAssertion(AsyncAssertionTypeEventually, actual, g, timeoutInterval, pollingInterval, offset)
|
return NewAsyncAssertion(AsyncAssertionTypeEventually, actual, g, timeoutInterval, pollingInterval, ctx, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Gomega) Consistently(actual interface{}, intervals ...interface{}) types.AsyncAssertion {
|
func (g *Gomega) Consistently(actual interface{}, intervals ...interface{}) types.AsyncAssertion {
|
||||||
return g.ConsistentlyWithOffset(0, actual, intervals...)
|
return g.ConsistentlyWithOffset(0, actual, intervals...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Gomega) ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) types.AsyncAssertion {
|
func (g *Gomega) ConsistentlyWithOffset(offset int, actual interface{}, args ...interface{}) types.AsyncAssertion {
|
||||||
timeoutInterval := g.DurationBundle.ConsistentlyDuration
|
timeoutInterval := -time.Duration(1)
|
||||||
pollingInterval := g.DurationBundle.ConsistentlyPollingInterval
|
pollingInterval := -time.Duration(1)
|
||||||
|
intervals := []interface{}{}
|
||||||
|
var ctx context.Context
|
||||||
|
for _, arg := range args {
|
||||||
|
switch v := arg.(type) {
|
||||||
|
case context.Context:
|
||||||
|
ctx = v
|
||||||
|
default:
|
||||||
|
intervals = append(intervals, arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
if len(intervals) > 0 {
|
if len(intervals) > 0 {
|
||||||
timeoutInterval = toDuration(intervals[0])
|
timeoutInterval = toDuration(intervals[0])
|
||||||
}
|
}
|
||||||
@ -82,7 +103,7 @@ func (g *Gomega) ConsistentlyWithOffset(offset int, actual interface{}, interval
|
|||||||
pollingInterval = toDuration(intervals[1])
|
pollingInterval = toDuration(intervals[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewAsyncAssertion(AsyncAssertionTypeConsistently, actual, g, timeoutInterval, pollingInterval, offset)
|
return NewAsyncAssertion(AsyncAssertionTypeConsistently, actual, g, timeoutInterval, pollingInterval, ctx, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Gomega) SetDefaultEventuallyTimeout(t time.Duration) {
|
func (g *Gomega) SetDefaultEventuallyTimeout(t time.Duration) {
|
||||||
|
37
vendor/github.com/onsi/gomega/matchers.go
generated
vendored
37
vendor/github.com/onsi/gomega/matchers.go
generated
vendored
@ -62,6 +62,7 @@ func BeFalse() types.GomegaMatcher {
|
|||||||
|
|
||||||
// HaveOccurred succeeds if actual is a non-nil error
|
// HaveOccurred succeeds if actual is a non-nil error
|
||||||
// The typical Go error checking pattern looks like:
|
// The typical Go error checking pattern looks like:
|
||||||
|
//
|
||||||
// err := SomethingThatMightFail()
|
// err := SomethingThatMightFail()
|
||||||
// Expect(err).ShouldNot(HaveOccurred())
|
// Expect(err).ShouldNot(HaveOccurred())
|
||||||
func HaveOccurred() types.GomegaMatcher {
|
func HaveOccurred() types.GomegaMatcher {
|
||||||
@ -70,10 +71,12 @@ func HaveOccurred() types.GomegaMatcher {
|
|||||||
|
|
||||||
// Succeed passes if actual is a nil error
|
// Succeed passes if actual is a nil error
|
||||||
// Succeed is intended to be used with functions that return a single error value. Instead of
|
// Succeed is intended to be used with functions that return a single error value. Instead of
|
||||||
|
//
|
||||||
// err := SomethingThatMightFail()
|
// err := SomethingThatMightFail()
|
||||||
// Expect(err).ShouldNot(HaveOccurred())
|
// Expect(err).ShouldNot(HaveOccurred())
|
||||||
//
|
//
|
||||||
// You can write:
|
// You can write:
|
||||||
|
//
|
||||||
// Expect(SomethingThatMightFail()).Should(Succeed())
|
// Expect(SomethingThatMightFail()).Should(Succeed())
|
||||||
//
|
//
|
||||||
// It is a mistake to use Succeed with a function that has multiple return values. Gomega's Ω and Expect
|
// It is a mistake to use Succeed with a function that has multiple return values. Gomega's Ω and Expect
|
||||||
@ -86,6 +89,7 @@ func Succeed() types.GomegaMatcher {
|
|||||||
// MatchError succeeds if actual is a non-nil error that matches the passed in string/error.
|
// MatchError succeeds if actual is a non-nil error that matches the passed in string/error.
|
||||||
//
|
//
|
||||||
// These are valid use-cases:
|
// These are valid use-cases:
|
||||||
|
//
|
||||||
// Expect(err).Should(MatchError("an error")) //asserts that err.Error() == "an error"
|
// Expect(err).Should(MatchError("an error")) //asserts that err.Error() == "an error"
|
||||||
// Expect(err).Should(MatchError(SomeError)) //asserts that err == SomeError (via reflect.DeepEqual)
|
// Expect(err).Should(MatchError(SomeError)) //asserts that err == SomeError (via reflect.DeepEqual)
|
||||||
//
|
//
|
||||||
@ -123,14 +127,17 @@ func BeClosed() types.GomegaMatcher {
|
|||||||
// - If there is something on the channel `c` ready to be read, then Expect(c).Should(Receive()) will pass and Ω(c).ShouldNot(Receive()) will fail.
|
// - If there is something on the channel `c` ready to be read, then Expect(c).Should(Receive()) will pass and Ω(c).ShouldNot(Receive()) will fail.
|
||||||
//
|
//
|
||||||
// If you have a go-routine running in the background that will write to channel `c` you can:
|
// If you have a go-routine running in the background that will write to channel `c` you can:
|
||||||
|
//
|
||||||
// Eventually(c).Should(Receive())
|
// Eventually(c).Should(Receive())
|
||||||
//
|
//
|
||||||
// This will timeout if nothing gets sent to `c` (you can modify the timeout interval as you normally do with `Eventually`)
|
// This will timeout if nothing gets sent to `c` (you can modify the timeout interval as you normally do with `Eventually`)
|
||||||
//
|
//
|
||||||
// A similar use-case is to assert that no go-routine writes to a channel (for a period of time). You can do this with `Consistently`:
|
// A similar use-case is to assert that no go-routine writes to a channel (for a period of time). You can do this with `Consistently`:
|
||||||
|
//
|
||||||
// Consistently(c).ShouldNot(Receive())
|
// Consistently(c).ShouldNot(Receive())
|
||||||
//
|
//
|
||||||
// You can pass `Receive` a matcher. If you do so, it will match the received object against the matcher. For example:
|
// You can pass `Receive` a matcher. If you do so, it will match the received object against the matcher. For example:
|
||||||
|
//
|
||||||
// Expect(c).Should(Receive(Equal("foo")))
|
// Expect(c).Should(Receive(Equal("foo")))
|
||||||
//
|
//
|
||||||
// When given a matcher, `Receive` will always fail if there is nothing to be received on the channel.
|
// When given a matcher, `Receive` will always fail if there is nothing to be received on the channel.
|
||||||
@ -142,6 +149,7 @@ func BeClosed() types.GomegaMatcher {
|
|||||||
// will repeatedly attempt to pull values out of `c` until a value matching "bar" is received.
|
// will repeatedly attempt to pull values out of `c` until a value matching "bar" is received.
|
||||||
//
|
//
|
||||||
// Finally, if you want to have a reference to the value *sent* to the channel you can pass the `Receive` matcher a pointer to a variable of the appropriate type:
|
// Finally, if you want to have a reference to the value *sent* to the channel you can pass the `Receive` matcher a pointer to a variable of the appropriate type:
|
||||||
|
//
|
||||||
// var myThing thing
|
// var myThing thing
|
||||||
// Eventually(thingChan).Should(Receive(&myThing))
|
// Eventually(thingChan).Should(Receive(&myThing))
|
||||||
// Expect(myThing.Sprocket).Should(Equal("foo"))
|
// Expect(myThing.Sprocket).Should(Equal("foo"))
|
||||||
@ -269,6 +277,7 @@ func BeZero() types.GomegaMatcher {
|
|||||||
// ContainElement succeeds if actual contains the passed in element. By default
|
// ContainElement succeeds if actual contains the passed in element. By default
|
||||||
// ContainElement() uses Equal() to perform the match, however a matcher can be
|
// ContainElement() uses Equal() to perform the match, however a matcher can be
|
||||||
// passed in instead:
|
// passed in instead:
|
||||||
|
//
|
||||||
// Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubstring("Bar")))
|
// Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubstring("Bar")))
|
||||||
//
|
//
|
||||||
// Actual must be an array, slice or map. For maps, ContainElement searches
|
// Actual must be an array, slice or map. For maps, ContainElement searches
|
||||||
@ -293,9 +302,12 @@ func ContainElement(element interface{}, result ...interface{}) types.GomegaMatc
|
|||||||
// BeElementOf() always uses Equal() to perform the match.
|
// BeElementOf() always uses Equal() to perform the match.
|
||||||
// When the passed in elements are comprised of a single element that is either an Array or Slice, BeElementOf() behaves
|
// When the passed in elements are comprised of a single element that is either an Array or Slice, BeElementOf() behaves
|
||||||
// as the reverse of ContainElement() that operates with Equal() to perform the match.
|
// as the reverse of ContainElement() that operates with Equal() to perform the match.
|
||||||
|
//
|
||||||
// Expect(2).Should(BeElementOf([]int{1, 2}))
|
// Expect(2).Should(BeElementOf([]int{1, 2}))
|
||||||
// Expect(2).Should(BeElementOf([2]int{1, 2}))
|
// Expect(2).Should(BeElementOf([2]int{1, 2}))
|
||||||
|
//
|
||||||
// Otherwise, BeElementOf() provides a syntactic sugar for Or(Equal(_), Equal(_), ...):
|
// Otherwise, BeElementOf() provides a syntactic sugar for Or(Equal(_), Equal(_), ...):
|
||||||
|
//
|
||||||
// Expect(2).Should(BeElementOf(1, 2))
|
// Expect(2).Should(BeElementOf(1, 2))
|
||||||
//
|
//
|
||||||
// Actual must be typed.
|
// Actual must be typed.
|
||||||
@ -305,6 +317,16 @@ func BeElementOf(elements ...interface{}) types.GomegaMatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BeKeyOf succeeds if actual is contained in the keys of the passed in map.
|
||||||
|
// BeKeyOf() always uses Equal() to perform the match between actual and the map keys.
|
||||||
|
//
|
||||||
|
// Expect("foo").Should(BeKeyOf(map[string]bool{"foo": true, "bar": false}))
|
||||||
|
func BeKeyOf(element interface{}) types.GomegaMatcher {
|
||||||
|
return &matchers.BeKeyOfMatcher{
|
||||||
|
Map: element,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ConsistOf succeeds if actual contains precisely the elements passed into the matcher. The ordering of the elements does not matter.
|
// ConsistOf succeeds if actual contains precisely the elements passed into the matcher. The ordering of the elements does not matter.
|
||||||
// By default ConsistOf() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples:
|
// By default ConsistOf() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples:
|
||||||
//
|
//
|
||||||
@ -344,6 +366,7 @@ func ContainElements(elements ...interface{}) types.GomegaMatcher {
|
|||||||
// Please note that if actual is empty, HaveEach always will succeed.
|
// Please note that if actual is empty, HaveEach always will succeed.
|
||||||
// By default HaveEach() uses Equal() to perform the match, however a
|
// By default HaveEach() uses Equal() to perform the match, however a
|
||||||
// matcher can be passed in instead:
|
// matcher can be passed in instead:
|
||||||
|
//
|
||||||
// Expect([]string{"Foo", "FooBar"}).Should(HaveEach(ContainSubstring("Foo")))
|
// Expect([]string{"Foo", "FooBar"}).Should(HaveEach(ContainSubstring("Foo")))
|
||||||
//
|
//
|
||||||
// Actual must be an array, slice or map.
|
// Actual must be an array, slice or map.
|
||||||
@ -357,6 +380,7 @@ func HaveEach(element interface{}) types.GomegaMatcher {
|
|||||||
// HaveKey succeeds if actual is a map with the passed in key.
|
// HaveKey succeeds if actual is a map with the passed in key.
|
||||||
// By default HaveKey uses Equal() to perform the match, however a
|
// By default HaveKey uses Equal() to perform the match, however a
|
||||||
// matcher can be passed in instead:
|
// matcher can be passed in instead:
|
||||||
|
//
|
||||||
// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKey(MatchRegexp(`.+Foo$`)))
|
// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKey(MatchRegexp(`.+Foo$`)))
|
||||||
func HaveKey(key interface{}) types.GomegaMatcher {
|
func HaveKey(key interface{}) types.GomegaMatcher {
|
||||||
return &matchers.HaveKeyMatcher{
|
return &matchers.HaveKeyMatcher{
|
||||||
@ -367,6 +391,7 @@ func HaveKey(key interface{}) types.GomegaMatcher {
|
|||||||
// HaveKeyWithValue succeeds if actual is a map with the passed in key and value.
|
// HaveKeyWithValue succeeds if actual is a map with the passed in key and value.
|
||||||
// By default HaveKeyWithValue uses Equal() to perform the match, however a
|
// By default HaveKeyWithValue uses Equal() to perform the match, however a
|
||||||
// matcher can be passed in instead:
|
// matcher can be passed in instead:
|
||||||
|
//
|
||||||
// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue("Foo", "Bar"))
|
// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue("Foo", "Bar"))
|
||||||
// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue(MatchRegexp(`.+Foo$`), "Bar"))
|
// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue(MatchRegexp(`.+Foo$`), "Bar"))
|
||||||
func HaveKeyWithValue(key interface{}, value interface{}) types.GomegaMatcher {
|
func HaveKeyWithValue(key interface{}, value interface{}) types.GomegaMatcher {
|
||||||
@ -442,6 +467,7 @@ func HaveValue(matcher types.GomegaMatcher) types.GomegaMatcher {
|
|||||||
// number is irrelevant (float32, float64, uint8, etc...).
|
// number is irrelevant (float32, float64, uint8, etc...).
|
||||||
//
|
//
|
||||||
// There are six, self-explanatory, supported comparators:
|
// There are six, self-explanatory, supported comparators:
|
||||||
|
//
|
||||||
// Expect(1.0).Should(BeNumerically("==", 1))
|
// Expect(1.0).Should(BeNumerically("==", 1))
|
||||||
// Expect(1.0).Should(BeNumerically("~", 0.999, 0.01))
|
// Expect(1.0).Should(BeNumerically("~", 0.999, 0.01))
|
||||||
// Expect(1.0).Should(BeNumerically(">", 0.9))
|
// Expect(1.0).Should(BeNumerically(">", 0.9))
|
||||||
@ -457,6 +483,7 @@ func BeNumerically(comparator string, compareTo ...interface{}) types.GomegaMatc
|
|||||||
|
|
||||||
// BeTemporally compares time.Time's like BeNumerically
|
// BeTemporally compares time.Time's like BeNumerically
|
||||||
// Actual and expected must be time.Time. The comparators are the same as for BeNumerically
|
// Actual and expected must be time.Time. The comparators are the same as for BeNumerically
|
||||||
|
//
|
||||||
// Expect(time.Now()).Should(BeTemporally(">", time.Time{}))
|
// Expect(time.Now()).Should(BeTemporally(">", time.Time{}))
|
||||||
// Expect(time.Now()).Should(BeTemporally("~", time.Now(), time.Second))
|
// Expect(time.Now()).Should(BeTemporally("~", time.Now(), time.Second))
|
||||||
func BeTemporally(comparator string, compareTo time.Time, threshold ...time.Duration) types.GomegaMatcher {
|
func BeTemporally(comparator string, compareTo time.Time, threshold ...time.Duration) types.GomegaMatcher {
|
||||||
@ -469,6 +496,7 @@ func BeTemporally(comparator string, compareTo time.Time, threshold ...time.Dura
|
|||||||
|
|
||||||
// BeAssignableToTypeOf succeeds if actual is assignable to the type of expected.
|
// BeAssignableToTypeOf succeeds if actual is assignable to the type of expected.
|
||||||
// It will return an error when one of the values is nil.
|
// It will return an error when one of the values is nil.
|
||||||
|
//
|
||||||
// Expect(0).Should(BeAssignableToTypeOf(0)) // Same values
|
// Expect(0).Should(BeAssignableToTypeOf(0)) // Same values
|
||||||
// Expect(5).Should(BeAssignableToTypeOf(-1)) // different values same type
|
// Expect(5).Should(BeAssignableToTypeOf(-1)) // different values same type
|
||||||
// Expect("foo").Should(BeAssignableToTypeOf("bar")) // different values same type
|
// Expect("foo").Should(BeAssignableToTypeOf("bar")) // different values same type
|
||||||
@ -490,6 +518,7 @@ func Panic() types.GomegaMatcher {
|
|||||||
//
|
//
|
||||||
// By default PanicWith uses Equal() to perform the match, however a
|
// By default PanicWith uses Equal() to perform the match, however a
|
||||||
// matcher can be passed in instead:
|
// matcher can be passed in instead:
|
||||||
|
//
|
||||||
// Expect(fn).Should(PanicWith(MatchRegexp(`.+Foo$`)))
|
// Expect(fn).Should(PanicWith(MatchRegexp(`.+Foo$`)))
|
||||||
func PanicWith(expected interface{}) types.GomegaMatcher {
|
func PanicWith(expected interface{}) types.GomegaMatcher {
|
||||||
return &matchers.PanicMatcher{Expected: expected}
|
return &matchers.PanicMatcher{Expected: expected}
|
||||||
@ -516,6 +545,7 @@ func BeADirectory() types.GomegaMatcher {
|
|||||||
// HaveHTTPStatus succeeds if the Status or StatusCode field of an HTTP response matches.
|
// HaveHTTPStatus succeeds if the Status or StatusCode field of an HTTP response matches.
|
||||||
// Actual must be either a *http.Response or *httptest.ResponseRecorder.
|
// Actual must be either a *http.Response or *httptest.ResponseRecorder.
|
||||||
// Expected must be either an int or a string.
|
// Expected must be either an int or a string.
|
||||||
|
//
|
||||||
// Expect(resp).Should(HaveHTTPStatus(http.StatusOK)) // asserts that resp.StatusCode == 200
|
// 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"
|
// Expect(resp).Should(HaveHTTPStatus("404 Not Found")) // asserts that resp.Status == "404 Not Found"
|
||||||
// Expect(resp).Should(HaveHTTPStatus(http.StatusOK, http.StatusNoContent)) // asserts that resp.StatusCode == 200 || resp.StatusCode == 204
|
// Expect(resp).Should(HaveHTTPStatus(http.StatusOK, http.StatusNoContent)) // asserts that resp.StatusCode == 200 || resp.StatusCode == 204
|
||||||
@ -543,6 +573,7 @@ func HaveHTTPBody(expected interface{}) types.GomegaMatcher {
|
|||||||
|
|
||||||
// And succeeds only if all of the given matchers succeed.
|
// 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.
|
// The matchers are tried in order, and will fail-fast if one doesn't succeed.
|
||||||
|
//
|
||||||
// Expect("hi").To(And(HaveLen(2), Equal("hi"))
|
// Expect("hi").To(And(HaveLen(2), Equal("hi"))
|
||||||
//
|
//
|
||||||
// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions.
|
// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions.
|
||||||
@ -551,6 +582,7 @@ func And(ms ...types.GomegaMatcher) types.GomegaMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SatisfyAll is an alias for And().
|
// SatisfyAll is an alias for And().
|
||||||
|
//
|
||||||
// Expect("hi").Should(SatisfyAll(HaveLen(2), Equal("hi")))
|
// Expect("hi").Should(SatisfyAll(HaveLen(2), Equal("hi")))
|
||||||
func SatisfyAll(matchers ...types.GomegaMatcher) types.GomegaMatcher {
|
func SatisfyAll(matchers ...types.GomegaMatcher) types.GomegaMatcher {
|
||||||
return And(matchers...)
|
return And(matchers...)
|
||||||
@ -558,6 +590,7 @@ func SatisfyAll(matchers ...types.GomegaMatcher) types.GomegaMatcher {
|
|||||||
|
|
||||||
// Or succeeds if any of the given matchers succeed.
|
// Or succeeds if any of the given matchers succeed.
|
||||||
// The matchers are tried in order and will return immediately upon the first successful match.
|
// The matchers are tried in order and will return immediately upon the first successful match.
|
||||||
|
//
|
||||||
// Expect("hi").To(Or(HaveLen(3), HaveLen(2))
|
// Expect("hi").To(Or(HaveLen(3), HaveLen(2))
|
||||||
//
|
//
|
||||||
// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions.
|
// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions.
|
||||||
@ -566,12 +599,14 @@ func Or(ms ...types.GomegaMatcher) types.GomegaMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SatisfyAny is an alias for Or().
|
// SatisfyAny is an alias for Or().
|
||||||
|
//
|
||||||
// Expect("hi").SatisfyAny(Or(HaveLen(3), HaveLen(2))
|
// Expect("hi").SatisfyAny(Or(HaveLen(3), HaveLen(2))
|
||||||
func SatisfyAny(matchers ...types.GomegaMatcher) types.GomegaMatcher {
|
func SatisfyAny(matchers ...types.GomegaMatcher) types.GomegaMatcher {
|
||||||
return Or(matchers...)
|
return Or(matchers...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not negates the given matcher; it succeeds if the given matcher fails.
|
// Not negates the given matcher; it succeeds if the given matcher fails.
|
||||||
|
//
|
||||||
// Expect(1).To(Not(Equal(2))
|
// Expect(1).To(Not(Equal(2))
|
||||||
//
|
//
|
||||||
// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions.
|
// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions.
|
||||||
@ -583,6 +618,7 @@ func Not(matcher types.GomegaMatcher) types.GomegaMatcher {
|
|||||||
// The given transform must be either a function of one parameter that returns one value or a
|
// 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
|
// function of one parameter that returns two values, where the second value must be of the
|
||||||
// error type.
|
// error type.
|
||||||
|
//
|
||||||
// var plus1 = func(i int) int { return i + 1 }
|
// var plus1 = func(i int) int { return i + 1 }
|
||||||
// Expect(1).To(WithTransform(plus1, Equal(2))
|
// Expect(1).To(WithTransform(plus1, Equal(2))
|
||||||
//
|
//
|
||||||
@ -596,6 +632,7 @@ func WithTransform(transform interface{}, matcher types.GomegaMatcher) types.Gom
|
|||||||
|
|
||||||
// Satisfy matches the actual value against the `predicate` function.
|
// Satisfy matches the actual value against the `predicate` function.
|
||||||
// The given predicate must be a function of one paramter that returns bool.
|
// The given predicate must be a function of one paramter that returns bool.
|
||||||
|
//
|
||||||
// var isEven = func(i int) bool { return i%2 == 0 }
|
// var isEven = func(i int) bool { return i%2 == 0 }
|
||||||
// Expect(2).To(Satisfy(isEven))
|
// Expect(2).To(Satisfy(isEven))
|
||||||
func Satisfy(predicate interface{}) types.GomegaMatcher {
|
func Satisfy(predicate interface{}) types.GomegaMatcher {
|
||||||
|
45
vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go
generated
vendored
Normal file
45
vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package matchers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/onsi/gomega/format"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BeKeyOfMatcher struct {
|
||||||
|
Map interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (matcher *BeKeyOfMatcher) Match(actual interface{}) (success bool, err error) {
|
||||||
|
if !isMap(matcher.Map) {
|
||||||
|
return false, fmt.Errorf("BeKeyOf matcher needs expected to be a map type")
|
||||||
|
}
|
||||||
|
|
||||||
|
if reflect.TypeOf(actual) == nil {
|
||||||
|
return false, fmt.Errorf("BeKeyOf matcher expects actual to be typed")
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastError error
|
||||||
|
for _, key := range reflect.ValueOf(matcher.Map).MapKeys() {
|
||||||
|
matcher := &EqualMatcher{Expected: key.Interface()}
|
||||||
|
success, err := matcher.Match(actual)
|
||||||
|
if err != nil {
|
||||||
|
lastError = err
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if success {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, lastError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (matcher *BeKeyOfMatcher) FailureMessage(actual interface{}) (message string) {
|
||||||
|
return format.Message(actual, "to be a key of", presentable(valuesOf(matcher.Map)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (matcher *BeKeyOfMatcher) NegatedFailureMessage(actual interface{}) (message string) {
|
||||||
|
return format.Message(actual, "not to be a key of", presentable(valuesOf(matcher.Map)))
|
||||||
|
}
|
5
vendor/github.com/onsi/gomega/types/types.go
generated
vendored
5
vendor/github.com/onsi/gomega/types/types.go
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -70,6 +71,10 @@ type AsyncAssertion interface {
|
|||||||
WithOffset(offset int) AsyncAssertion
|
WithOffset(offset int) AsyncAssertion
|
||||||
WithTimeout(interval time.Duration) AsyncAssertion
|
WithTimeout(interval time.Duration) AsyncAssertion
|
||||||
WithPolling(interval time.Duration) AsyncAssertion
|
WithPolling(interval time.Duration) AsyncAssertion
|
||||||
|
Within(timeout time.Duration) AsyncAssertion
|
||||||
|
ProbeEvery(interval time.Duration) AsyncAssertion
|
||||||
|
WithContext(ctx context.Context) AsyncAssertion
|
||||||
|
WithArguments(argsToForward ...interface{}) AsyncAssertion
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assertions are returned by Ω and Expect and enable assertions against Gomega matchers
|
// Assertions are returned by Ω and Expect and enable assertions against Gomega matchers
|
||||||
|
8
vendor/modules.txt
vendored
8
vendor/modules.txt
vendored
@ -573,7 +573,7 @@ github.com/munnerz/goautoneg
|
|||||||
# github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f => github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
|
# github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f => github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
|
||||||
## explicit
|
## explicit
|
||||||
github.com/mxk/go-flowrate/flowrate
|
github.com/mxk/go-flowrate/flowrate
|
||||||
# github.com/onsi/ginkgo/v2 v2.2.0 => github.com/onsi/ginkgo/v2 v2.2.0
|
# github.com/onsi/ginkgo/v2 v2.3.1 => github.com/onsi/ginkgo/v2 v2.3.1
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
github.com/onsi/ginkgo/v2
|
github.com/onsi/ginkgo/v2
|
||||||
github.com/onsi/ginkgo/v2/config
|
github.com/onsi/ginkgo/v2/config
|
||||||
@ -595,7 +595,7 @@ github.com/onsi/ginkgo/v2/internal/parallel_support
|
|||||||
github.com/onsi/ginkgo/v2/internal/testingtproxy
|
github.com/onsi/ginkgo/v2/internal/testingtproxy
|
||||||
github.com/onsi/ginkgo/v2/reporters
|
github.com/onsi/ginkgo/v2/reporters
|
||||||
github.com/onsi/ginkgo/v2/types
|
github.com/onsi/ginkgo/v2/types
|
||||||
# github.com/onsi/gomega v1.20.1 => github.com/onsi/gomega v1.20.1
|
# github.com/onsi/gomega v1.22.1 => github.com/onsi/gomega v1.22.1
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
github.com/onsi/gomega
|
github.com/onsi/gomega
|
||||||
github.com/onsi/gomega/format
|
github.com/onsi/gomega/format
|
||||||
@ -2651,8 +2651,8 @@ sigs.k8s.io/yaml
|
|||||||
# github.com/mxk/go-flowrate => github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
|
# github.com/mxk/go-flowrate => github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
|
||||||
# github.com/niemeyer/pretty => github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e
|
# github.com/niemeyer/pretty => github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e
|
||||||
# github.com/olekukonko/tablewriter => github.com/olekukonko/tablewriter v0.0.4
|
# github.com/olekukonko/tablewriter => github.com/olekukonko/tablewriter v0.0.4
|
||||||
# github.com/onsi/ginkgo/v2 => github.com/onsi/ginkgo/v2 v2.2.0
|
# github.com/onsi/ginkgo/v2 => github.com/onsi/ginkgo/v2 v2.3.1
|
||||||
# github.com/onsi/gomega => github.com/onsi/gomega v1.20.1
|
# github.com/onsi/gomega => github.com/onsi/gomega v1.22.1
|
||||||
# github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.0
|
# github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.0
|
||||||
# github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.0.2
|
# github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.0.2
|
||||||
# github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.3
|
# github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.3
|
||||||
|
Loading…
Reference in New Issue
Block a user