From 6e3cf6591ea89e36a7ff2d2198ae72879838f19d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 10:13:16 +0100 Subject: [PATCH 001/102] Bump golang.org/x/net in /integration/_fixtures/version_mismatch_fixture (#1286) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.7.0 to 0.17.0. - [Commits](https://github.com/golang/net/compare/v0.7.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../_fixtures/version_mismatch_fixture/go.mod | 6 +++--- .../_fixtures/version_mismatch_fixture/go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/integration/_fixtures/version_mismatch_fixture/go.mod b/integration/_fixtures/version_mismatch_fixture/go.mod index 6ed445cd9..0216b502c 100644 --- a/integration/_fixtures/version_mismatch_fixture/go.mod +++ b/integration/_fixtures/version_mismatch_fixture/go.mod @@ -9,8 +9,8 @@ require ( require ( github.com/google/go-cmp v0.5.8 // indirect - golang.org/x/net v0.7.0 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/integration/_fixtures/version_mismatch_fixture/go.sum b/integration/_fixtures/version_mismatch_fixture/go.sum index 3ba4ba14d..5bfc394f6 100644 --- a/integration/_fixtures/version_mismatch_fixture/go.sum +++ b/integration/_fixtures/version_mismatch_fixture/go.sum @@ -5,12 +5,12 @@ github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI= github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 937363309301ba5848fe675bd62efe45931c5631 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 08:24:31 +0100 Subject: [PATCH 002/102] Bump github.com/onsi/gomega from 1.27.10 to 1.29.0 (#1290) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.27.10 to 1.29.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.27.10...v1.29.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 91d34f481..fcab70dac 100644 --- a/go.mod +++ b/go.mod @@ -6,16 +6,16 @@ require ( github.com/go-logr/logr v1.2.4 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 - github.com/onsi/gomega v1.27.10 - golang.org/x/net v0.14.0 - golang.org/x/sys v0.12.0 + github.com/onsi/gomega v1.29.0 + golang.org/x/net v0.17.0 + golang.org/x/sys v0.13.0 golang.org/x/tools v0.12.0 ) require ( github.com/golang/protobuf v1.5.3 // indirect - github.com/google/go-cmp v0.5.9 // indirect - golang.org/x/text v0.12.0 // indirect + github.com/google/go-cmp v0.6.0 // indirect + golang.org/x/text v0.13.0 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 048928de8..f446629ac 100644 --- a/go.sum +++ b/go.sum @@ -12,26 +12,26 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= 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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 74bbd6552ca29d47cf6c828aac38d42fbd912bd9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 09:29:53 +0100 Subject: [PATCH 003/102] Bump golang.org/x/tools from 0.12.0 to 0.14.0 (#1282) Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.12.0 to 0.14.0. - [Release notes](https://github.com/golang/tools/releases) - [Commits](https://github.com/golang/tools/compare/v0.12.0...v0.14.0) --- updated-dependencies: - dependency-name: golang.org/x/tools dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index fcab70dac..d730ce0f6 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/onsi/gomega v1.29.0 golang.org/x/net v0.17.0 golang.org/x/sys v0.13.0 - golang.org/x/tools v0.12.0 + golang.org/x/tools v0.14.0 ) require ( diff --git a/go.sum b/go.sum index f446629ac..9de7c7b50 100644 --- a/go.sum +++ b/go.sum @@ -24,7 +24,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -32,8 +32,8 @@ golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= From 7fc7b101ae7ec8266083090895ce68a9c4a43546 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 15:59:31 +0000 Subject: [PATCH 004/102] Bump golang.org/x/sys from 0.13.0 to 0.14.0 (#1295) Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.13.0 to 0.14.0. - [Commits](https://github.com/golang/sys/compare/v0.13.0...v0.14.0) --- updated-dependencies: - dependency-name: golang.org/x/sys dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d730ce0f6..9075e7ba5 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 github.com/onsi/gomega v1.29.0 golang.org/x/net v0.17.0 - golang.org/x/sys v0.13.0 + golang.org/x/sys v0.14.0 golang.org/x/tools v0.14.0 ) diff --git a/go.sum b/go.sum index 9de7c7b50..e0ff07c3e 100644 --- a/go.sum +++ b/go.sum @@ -28,8 +28,8 @@ golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= From 7161a9d90a24fd70df1e687b71d4ae186ec85dd7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 16:02:08 +0000 Subject: [PATCH 005/102] Bump github.com/go-logr/logr from 1.2.4 to 1.3.0 (#1291) Bumps [github.com/go-logr/logr](https://github.com/go-logr/logr) from 1.2.4 to 1.3.0. - [Release notes](https://github.com/go-logr/logr/releases) - [Changelog](https://github.com/go-logr/logr/blob/master/CHANGELOG.md) - [Commits](https://github.com/go-logr/logr/compare/v1.2.4...v1.3.0) --- updated-dependencies: - dependency-name: github.com/go-logr/logr dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9075e7ba5..d541ee830 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/onsi/ginkgo/v2 go 1.18 require ( - github.com/go-logr/logr v1.2.4 + github.com/go-logr/logr v1.3.0 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 github.com/onsi/gomega v1.29.0 diff --git a/go.sum b/go.sum index e0ff07c3e..b029f6d7d 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= From 26eea013cbafdec66e1385cde033c3c105a3d020 Mon Sep 17 00:00:00 2001 From: Jacob Date: Fri, 10 Nov 2023 14:29:22 +0100 Subject: [PATCH 006/102] # 1296 fix(precompiled test guite): exec bit check omitted on Windows (#1301) Co-authored-by: Jacob Grieger --- ginkgo/internal/test_suite.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ginkgo/internal/test_suite.go b/ginkgo/internal/test_suite.go index 64dcb1b78..f3ae13bb1 100644 --- a/ginkgo/internal/test_suite.go +++ b/ginkgo/internal/test_suite.go @@ -7,6 +7,7 @@ import ( "path" "path/filepath" "regexp" + "runtime" "strings" "github.com/onsi/ginkgo/v2/types" @@ -192,7 +193,7 @@ func precompiledTestSuite(path string) (TestSuite, error) { return TestSuite{}, errors.New("this is not a .test binary") } - if filepath.Ext(path) == ".test" && info.Mode()&0111 == 0 { + if filepath.Ext(path) == ".test" && runtime.GOOS != "windows" && info.Mode()&0111 == 0 { return TestSuite{}, errors.New("this is not executable") } From 64b855226151a4fe9df057839750d1bf4772b009 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Fri, 10 Nov 2023 08:55:53 -0700 Subject: [PATCH 007/102] v2.13.1 --- CHANGELOG.md | 12 ++++++++++++ types/version.go | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fea67526e..102bb529f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## 2.13.1 + +### Fixes +- # 1296 fix(precompiled test guite): exec bit check omitted on Windows (#1301) [26eea01] + +### Maintenance +- Bump github.com/go-logr/logr from 1.2.4 to 1.3.0 (#1291) [7161a9d] +- Bump golang.org/x/sys from 0.13.0 to 0.14.0 (#1295) [7fc7b10] +- Bump golang.org/x/tools from 0.12.0 to 0.14.0 (#1282) [74bbd65] +- Bump github.com/onsi/gomega from 1.27.10 to 1.29.0 (#1290) [9373633] +- Bump golang.org/x/net in /integration/_fixtures/version_mismatch_fixture (#1286) [6e3cf65] + ## 2.13.0 ### Features diff --git a/types/version.go b/types/version.go index a37f30828..7a794d87a 100644 --- a/types/version.go +++ b/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.13.0" +const VERSION = "2.13.1" From 3b2a2a7e74069d66b0f64922afd3426a6167dd3c Mon Sep 17 00:00:00 2001 From: Eng Zer Jun Date: Sun, 12 Nov 2023 01:56:58 +0800 Subject: [PATCH 008/102] Avoid allocations with `(*regexp.Regexp).MatchString` (#1302) We should use `(*regexp.Regexp).MatchString` instead of `(*regexp.Regexp).Match([]byte(...))` when matching string to avoid unnecessary `[]byte` conversions and reduce allocations. Example benchmark: var goTestRegExp = regexp.MustCompile(`_test\.go$`) func BenchmarkMatch(b *testing.B) { for i := 0; i < b.N; i++ { if match := goTestRegExp.Match([]byte("file_test.go")); !match { b.Fail() } } } func BenchmarkMatchString(b *testing.B) { for i := 0; i < b.N; i++ { if match := goTestRegExp.MatchString("file_test.go"); !match { b.Fail() } } } goos: linux goarch: amd64 pkg: github.com/onsi/ginkgo/v2/ginkgo/watch cpu: AMD Ryzen 7 PRO 4750U with Radeon Graphics BenchmarkMatch-16 5665784 314.4 ns/op 16 B/op 1 allocs/op BenchmarkMatchString-16 8481872 140.5 ns/op 0 B/op 0 allocs/op PASS ok github.com/onsi/ginkgo/v2/ginkgo/watch 4.321s Signed-off-by: Eng Zer Jun --- ginkgo/internal/test_suite.go | 6 +++--- ginkgo/watch/dependencies.go | 2 +- ginkgo/watch/package_hash.go | 4 ++-- types/code_location.go | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ginkgo/internal/test_suite.go b/ginkgo/internal/test_suite.go index f3ae13bb1..df99875be 100644 --- a/ginkgo/internal/test_suite.go +++ b/ginkgo/internal/test_suite.go @@ -226,7 +226,7 @@ func suitesInDir(dir string, recurse bool) TestSuites { files, _ := os.ReadDir(dir) re := regexp.MustCompile(`^[^._].*_test\.go$`) for _, file := range files { - if !file.IsDir() && re.Match([]byte(file.Name())) { + if !file.IsDir() && re.MatchString(file.Name()) { suite := TestSuite{ Path: relPath(dir), PackageName: packageNameForSuite(dir), @@ -241,7 +241,7 @@ func suitesInDir(dir string, recurse bool) TestSuites { if recurse { re = regexp.MustCompile(`^[._]`) for _, file := range files { - if file.IsDir() && !re.Match([]byte(file.Name())) { + if file.IsDir() && !re.MatchString(file.Name()) { suites = append(suites, suitesInDir(dir+"/"+file.Name(), recurse)...) } } @@ -272,7 +272,7 @@ func filesHaveGinkgoSuite(dir string, files []os.DirEntry) bool { reGinkgo := regexp.MustCompile(`package ginkgo|\/ginkgo"|\/ginkgo\/v2"|\/ginkgo\/v2/dsl/`) for _, file := range files { - if !file.IsDir() && reTestFile.Match([]byte(file.Name())) { + if !file.IsDir() && reTestFile.MatchString(file.Name()) { contents, _ := os.ReadFile(dir + "/" + file.Name()) if reGinkgo.Match(contents) { return true diff --git a/ginkgo/watch/dependencies.go b/ginkgo/watch/dependencies.go index f5ddff30f..a34d94354 100644 --- a/ginkgo/watch/dependencies.go +++ b/ginkgo/watch/dependencies.go @@ -78,7 +78,7 @@ func (d Dependencies) resolveAndAdd(deps []string, depth int) { if err != nil { continue } - if !pkg.Goroot && (!ginkgoAndGomegaFilter.Match([]byte(pkg.Dir)) || ginkgoIntegrationTestFilter.Match([]byte(pkg.Dir))) { + if !pkg.Goroot && (!ginkgoAndGomegaFilter.MatchString(pkg.Dir) || ginkgoIntegrationTestFilter.MatchString(pkg.Dir)) { d.addDepIfNotPresent(pkg.Dir, depth) } } diff --git a/ginkgo/watch/package_hash.go b/ginkgo/watch/package_hash.go index e9f7ec0cb..17d052bdc 100644 --- a/ginkgo/watch/package_hash.go +++ b/ginkgo/watch/package_hash.go @@ -79,7 +79,7 @@ func (p *PackageHash) computeHashes() (codeHash string, codeModifiedTime time.Ti continue } - if goTestRegExp.Match([]byte(info.Name())) { + if goTestRegExp.MatchString(info.Name()) { testHash += p.hashForFileInfo(info) if info.ModTime().After(testModifiedTime) { testModifiedTime = info.ModTime() @@ -87,7 +87,7 @@ func (p *PackageHash) computeHashes() (codeHash string, codeModifiedTime time.Ti continue } - if p.watchRegExp.Match([]byte(info.Name())) { + if p.watchRegExp.MatchString(info.Name()) { codeHash += p.hashForFileInfo(info) if info.ModTime().After(codeModifiedTime) { codeModifiedTime = info.ModTime() diff --git a/types/code_location.go b/types/code_location.go index 9cd576817..57e87517e 100644 --- a/types/code_location.go +++ b/types/code_location.go @@ -149,7 +149,7 @@ func PruneStack(fullStackTrace string, skip int) string { re := regexp.MustCompile(`\/ginkgo\/|\/pkg\/testing\/|\/pkg\/runtime\/`) for i := 0; i < len(stack)/2; i++ { // We filter out based on the source code file name. - if !re.Match([]byte(stack[i*2+1])) { + if !re.MatchString(stack[i*2+1]) { prunedStack = append(prunedStack, stack[i*2]) prunedStack = append(prunedStack, stack[i*2+1]) } From e2e81c8c1d965d0e1274dcac71740dcc6d75dfcf Mon Sep 17 00:00:00 2001 From: Stanislav Osipov <57736012+stasos24@users.noreply.github.com> Date: Wed, 29 Nov 2023 05:33:31 +0300 Subject: [PATCH 009/102] Fix file handler leak (#1309) Co-authored-by: sosipov --- reporters/json_report.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/reporters/json_report.go b/reporters/json_report.go index be506f9b4..5d3e8db99 100644 --- a/reporters/json_report.go +++ b/reporters/json_report.go @@ -18,6 +18,7 @@ func GenerateJSONReport(report types.Report, destination string) error { if err != nil { return err } + defer f.Close() enc := json.NewEncoder(f) enc.SetIndent("", " ") err = enc.Encode([]types.Report{ @@ -26,7 +27,7 @@ func GenerateJSONReport(report types.Report, destination string) error { if err != nil { return err } - return f.Close() + return nil } // MergeJSONReports produces a single JSON-formatted report at the passed in destination by merging the JSON-formatted reports provided in sources @@ -57,11 +58,12 @@ func MergeAndCleanupJSONReports(sources []string, destination string) ([]string, if err != nil { return messages, err } + defer f.Close() enc := json.NewEncoder(f) enc.SetIndent("", " ") err = enc.Encode(allReports) if err != nil { return messages, err } - return messages, f.Close() + return messages, nil } From 931dc0b144749710bd085d4eb7cd4192a22972d7 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Tue, 28 Nov 2023 20:52:01 -0700 Subject: [PATCH 010/102] v2.13.2 --- CHANGELOG.md | 6 ++++++ types/version.go | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 102bb529f..ec91408f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.13.2 + +### Fixes +- Fix file handler leak (#1309) [e2e81c8] +- Avoid allocations with `(*regexp.Regexp).MatchString` (#1302) [3b2a2a7] + ## 2.13.1 ### Fixes diff --git a/types/version.go b/types/version.go index 7a794d87a..a4a1524b4 100644 --- a/types/version.go +++ b/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.13.1" +const VERSION = "2.13.2" From 84ff7f382a92d1699e4963e660012515fcf0af38 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:03:07 +0000 Subject: [PATCH 011/102] Bump golang.org/x/net from 0.17.0 to 0.19.0 (#1307) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.17.0 to 0.19.0. - [Commits](https://github.com/golang/net/compare/v0.17.0...v0.19.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index d541ee830..5620ba018 100644 --- a/go.mod +++ b/go.mod @@ -7,15 +7,15 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 github.com/onsi/gomega v1.29.0 - golang.org/x/net v0.17.0 - golang.org/x/sys v0.14.0 + golang.org/x/net v0.19.0 + golang.org/x/sys v0.15.0 golang.org/x/tools v0.14.0 ) require ( github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.6.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/text v0.14.0 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index b029f6d7d..4ba947da8 100644 --- a/go.sum +++ b/go.sum @@ -25,13 +25,13 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 558f6e08cfd54e2034722bfbd8cfe99f3a954a92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:08:22 +0000 Subject: [PATCH 012/102] Bump github.com/onsi/gomega from 1.29.0 to 1.30.0 (#1297) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.29.0 to 1.30.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.29.0...v1.30.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5620ba018..1d0ecea2d 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/go-logr/logr v1.3.0 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 - github.com/onsi/gomega v1.29.0 + github.com/onsi/gomega v1.30.0 golang.org/x/net v0.19.0 golang.org/x/sys v0.15.0 golang.org/x/tools v0.14.0 diff --git a/go.sum b/go.sum index 4ba947da8..21cd61da1 100644 --- a/go.sum +++ b/go.sum @@ -17,8 +17,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= -github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= +github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= 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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= From 123e1d50419b58a36ecd04157f7859ac604174b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:19:00 +0000 Subject: [PATCH 013/102] Bump golang.org/x/tools from 0.14.0 to 0.16.0 (#1306) Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.14.0 to 0.16.0. - [Release notes](https://github.com/golang/tools/releases) - [Commits](https://github.com/golang/tools/compare/v0.14.0...v0.16.0) --- updated-dependencies: - dependency-name: golang.org/x/tools dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 1d0ecea2d..c518de74a 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/onsi/gomega v1.30.0 golang.org/x/net v0.19.0 golang.org/x/sys v0.15.0 - golang.org/x/tools v0.14.0 + golang.org/x/tools v0.16.0 ) require ( diff --git a/go.sum b/go.sum index 21cd61da1..c2bd89f61 100644 --- a/go.sum +++ b/go.sum @@ -24,7 +24,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -32,8 +32,8 @@ golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= From b2e5bc5003d98387c02c8f01af6edf4b5c3000f9 Mon Sep 17 00:00:00 2001 From: James Date: Thu, 30 Nov 2023 12:49:25 -0500 Subject: [PATCH 014/102] allow wasm to compile with ginkgo present (#1311) --- internal/output_interceptor_wasm.go | 7 +++++++ internal/progress_report_wasm.go | 10 ++++++++++ 2 files changed, 17 insertions(+) create mode 100644 internal/output_interceptor_wasm.go create mode 100644 internal/progress_report_wasm.go diff --git a/internal/output_interceptor_wasm.go b/internal/output_interceptor_wasm.go new file mode 100644 index 000000000..4c374935b --- /dev/null +++ b/internal/output_interceptor_wasm.go @@ -0,0 +1,7 @@ +//go:build wasm + +package internal + +func NewOutputInterceptor() OutputInterceptor { + return &NoopOutputInterceptor{} +} diff --git a/internal/progress_report_wasm.go b/internal/progress_report_wasm.go new file mode 100644 index 000000000..8c53fe0ad --- /dev/null +++ b/internal/progress_report_wasm.go @@ -0,0 +1,10 @@ +//go:build wasm + +package internal + +import ( + "os" + "syscall" +) + +var PROGRESS_SIGNALS = []os.Signal{syscall.SIGUSR1} From 3ee80ee27f78973801684cd6da1a9c8d443bcf9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 23:13:19 +0000 Subject: [PATCH 015/102] Bump golang.org/x/crypto (#1318) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.1.0 to 0.17.0. - [Commits](https://github.com/golang/crypto/compare/v0.1.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../_fixtures/performance_fixture/go.mod | 2 +- .../_fixtures/performance_fixture/go.sum | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ginkgo/performance/_fixtures/performance_fixture/go.mod b/ginkgo/performance/_fixtures/performance_fixture/go.mod index 5543d0a46..386a19107 100644 --- a/ginkgo/performance/_fixtures/performance_fixture/go.mod +++ b/ginkgo/performance/_fixtures/performance_fixture/go.mod @@ -11,7 +11,7 @@ require gopkg.in/yaml.v2 v2.4.0 require ( github.com/onsi/ginkgo v1.16.4 // indirect github.com/tdewolff/minify/v2 v2.9.17 - golang.org/x/crypto v0.1.0 + golang.org/x/crypto v0.17.0 ) replace github.com/onsi/ginkgo => ../../ginkgo diff --git a/ginkgo/performance/_fixtures/performance_fixture/go.sum b/ginkgo/performance/_fixtures/performance_fixture/go.sum index 43bec9080..134c52491 100644 --- a/ginkgo/performance/_fixtures/performance_fixture/go.sum +++ b/ginkgo/performance/_fixtures/performance_fixture/go.sum @@ -52,9 +52,12 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -63,10 +66,13 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG0 golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -80,21 +86,31 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From fbf9724382128d09643cb1339b838d9991745819 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 23:13:28 +0000 Subject: [PATCH 016/102] Bump github/codeql-action from 2 to 3 (#1317) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v2...v3) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 17aeb9727..972590e27 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -46,7 +46,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -57,7 +57,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -71,4 +71,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 From eab0e40d801360cf7a3665b47ebe80c08c8259e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 23:13:37 +0000 Subject: [PATCH 017/102] Bump actions/setup-go from 4 to 5 (#1313) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0a4325e4b..b5d2ca53e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest name: Check modules steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: '1.20' - uses: actions/checkout@v4 @@ -22,7 +22,7 @@ jobs: version: [ '1.20', '1.21' ] name: Go ${{ matrix.version }} steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: ${{ matrix.version }} - uses: actions/checkout@v4 From 465a8ec1bb583f2f30af269e09b69d7142d11d0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 23:13:48 +0000 Subject: [PATCH 018/102] Bump golang.org/x/tools from 0.16.0 to 0.16.1 (#1316) Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.16.0 to 0.16.1. - [Release notes](https://github.com/golang/tools/releases) - [Commits](https://github.com/golang/tools/compare/v0.16.0...v0.16.1) --- updated-dependencies: - dependency-name: golang.org/x/tools dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index c518de74a..190cc624e 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/onsi/gomega v1.30.0 golang.org/x/net v0.19.0 golang.org/x/sys v0.15.0 - golang.org/x/tools v0.16.0 + golang.org/x/tools v0.16.1 ) require ( diff --git a/go.sum b/go.sum index c2bd89f61..f389152e6 100644 --- a/go.sum +++ b/go.sum @@ -24,7 +24,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -32,8 +31,8 @@ golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= -golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= From 4ac3a130a33f4839442f45331e3386b1d3d94a23 Mon Sep 17 00:00:00 2001 From: byehn <154425387+byehn@users.noreply.github.com> Date: Wed, 20 Dec 2023 21:03:51 +0900 Subject: [PATCH 019/102] Fix typo in docs/index.md (#1319) --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index dd9983a37..8764b16e6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1345,7 +1345,7 @@ The string passed to `By` is attached to the spec and can be displayed by Ginkgo ### Mental Model: Spec Timelines Several events can occur during the lifecycle of a Ginkgo spec. You've seen a few of these already: various setup and subject nodes start and end; data is written to the `GinkgoWriter`; `By` annotations are generated; failures occur. And there are several more that you'll see introduced later in these docs (e.g. [`ReportEntries`](#attaching-data-to-reports) and [Progess Reports](#getting-visibility-into-long-running-specs) are attached to specs; [flaky specs](#repeating-spec-runs-and-managing-flaky-specs) might be retried). -By default, when a spec passes Ginkgo does not emit any of this information. When a failure occurs, however, Ginkgo emits a **timeline** view of the spec. This includes all the events and `GinkgoWriter` output associated with a spec in ther order they were generated and provides the context needed to debug the spec and understand the nature and context of the failure. +By default, when a spec passes Ginkgo does not emit any of this information. When a failure occurs, however, Ginkgo emits a **timeline** view of the spec. This includes all the events and `GinkgoWriter` output associated with a spec in the order they were generated and provides the context needed to debug the spec and understand the nature and context of the failure. You can view the timeline for all specs (whether passed or failed) by running `ginkgo -v` or `ginkgo -vv`. From 65ec56d254aaa3e221933e911aa1540f1e93bd00 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Tue, 26 Dec 2023 14:31:31 -0700 Subject: [PATCH 020/102] Introduce DescribeTableSubtree --- docs/index.md | 105 +++++++++++++++++- dsl/table/table_dsl.go | 9 +- internal/internal_integration/table_test.go | 47 ++++++++ table_dsl.go | 113 ++++++++++++++++---- types/errors.go | 9 ++ 5 files changed, 260 insertions(+), 23 deletions(-) diff --git a/docs/index.md b/docs/index.md index 8764b16e6..9f09075fa 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1378,7 +1378,7 @@ DescribeTable("Extracting the author's first and last name", You'll be notified with a clear message at runtime if the parameter types don't match the spec closure signature. #### Mental Model: Table Specs are just Syntactic Sugar -`DescribeTable` is simply providing syntactic sugar to convert its Ls into a set of standard Ginkgo nodes. During the [Tree Construction Phase](#mental-model-how-ginkgo-traverses-the-spec-hierarchy) `DescribeTable` is generating a single container node that contains one subject node per table entry. The description for the container node will be the description passed to `DescribeTable` and the descriptions for the subject nodes will be the descriptions passed to the `Entry`s. During the Run Phase, when specs run, each subject node will simply invoke the spec closure passed to `DescribeTable`, passing in the parameters associated with the `Entry`. +`DescribeTable` is simply providing syntactic sugar to convert its entries into a set of standard Ginkgo nodes. During the [Tree Construction Phase](#mental-model-how-ginkgo-traverses-the-spec-hierarchy) `DescribeTable` is generating a single container node that contains one subject node per table entry. The description for the container node will be the description passed to `DescribeTable` and the descriptions for the subject nodes will be the descriptions passed to the `Entry`s. During the Run Phase, when specs run, each subject node will simply invoke the spec closure passed to `DescribeTable`, passing in the parameters associated with the `Entry`. To put it another way, the table test above is equivalent to: @@ -1629,6 +1629,86 @@ var _ = Describe("Math", func() { Will generate entries named: `1 + 2 = 3`, `-1 + 2 = 1`, `zeros`, `110 = 10 + 100`, and `7 = 7`. +#### Generating Subtree Tables + +As we've seen `DescribeTable` takes a function and interprets it as the body of a single `It` function. Sometimes, however, you may want to run a collection of specs for a given table entry. You can do this with `DescribeTableSubtree`: + +```go +DescribeTableSubtree("handling requests", + func(url string, code int, message string) { + var resp *http.Response + BeforeEach(func() { + var err error + resp, err = http.Get(url) + Expect(err).NotTo(HaveOccurred()) + DeferCleanup(resp.Body.Close) + }) + + It("should return the expected status code", func() { + Expect(resp.StatusCode).To(Equal(code)) + }) + + It("should return the expected message", func() { + body, err := ioutil.ReadAll(resp.Body) + Expect(err).NotTo(HaveOccurred()) + Expect(string(body)).To(Equal(message)) + }) + }, + Entry("default response", "example.com/response", http.StatusOK, "hello world"), + Entry("missing response", "example.com/missing", http.StatusNotFound, "wat?"), + ... +) +``` + +now the body function passed to the table is invoked during the Tree Construction Phase to generate a set of specs for each entry. Each body function is invoked within the context of a new container so that setup nodes will only run for the specs defined in the body function. As with `DescribeTable` this is simply synctactic sugar around Ginkgo's existing DSL. The above example is identical to: + +```go + +Describe("handling requests", func() { + Describe("default response", func() { + var resp *http.Response + BeforeEach(func() { + var err error + resp, err = http.Get("example.com/response") + Expect(err).NotTo(HaveOccurred()) + DeferCleanup(resp.Body.Close) + }) + + It("should return the expected status code", func() { + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + }) + + It("should return the expected message", func() { + body, err := ioutil.ReadAll(resp.Body) + Expect(err).NotTo(HaveOccurred()) + Expect(string(body)).To(Equal("hello world")) + }) + }) + + Describe("missing response", func() { + var resp *http.Response + BeforeEach(func() { + var err error + resp, err = http.Get("example.com/missing") + Expect(err).NotTo(HaveOccurred()) + DeferCleanup(resp.Body.Close) + }) + + It("should return the expected status code", func() { + Expect(resp.StatusCode).To(Equal(http.StatusNotFound)) + }) + + It("should return the expected message", func() { + body, err := ioutil.ReadAll(resp.Body) + Expect(err).NotTo(HaveOccurred()) + Expect(string(body)).To(Equal("wat?")) + }) + }) +}) +``` + +all the infrastructure around generating table entry descriptions applies here as well - though the description will be the title of the generatd container. Note that you **must** add subject nodes in the body function if you want `DescribeHandleSubtree` to add specs. + ### Alternatives to Dot-Importing Ginkgo As shown throughout this documentation, Ginkgo users are encouraged to dot-import the Ginkgo DSL into their test suites to effectively extend the Go language with Ginkgo's expressive building blocks: @@ -4127,6 +4207,29 @@ DescribeTable("Reading invalid books always errors", func(book *books.Book) { ``` +alternatively you can use `DescribeTableSubtree` to associate multiple specs with a given entry: + +```go +DescribeTableSubtree("Handling invalid books", func(book *books.Book) { + Describe("Storing invalid books", func() { + It("always errors", func() { + Expect(library.Store(book)).To(MatchError(books.ErrInvalidBook)) + }) + }) + + Describe("Reading invalid books", func() { + It("always errors", func() { + Expect(user.Read(book)).To(MatchError(books.ErrInvalidBook)) + }) + }) + }, + Entry("Empty book", &books.Book{}), + Entry("Only title", &books.Book{Title: "Les Miserables"}), + Entry("Only author", &books.Book{Author: "Victor Hugo"}), + Entry("Missing pages", &books.Book{Title: "Les Miserables", Author: "Victor Hugo"}) +) +``` + ### Patterns for Asynchronous Testing It is common, especially in integration suites, to be testing behaviors that occur asynchronously (either within the same process or, in the case of distributed systems, outside the current test process in some combination of external systems). Ginkgo and Gomega provide the building blocks you need to write effective asynchronous specs efficiently. diff --git a/dsl/table/table_dsl.go b/dsl/table/table_dsl.go index cf7c8bd3e..9bbfb8284 100644 --- a/dsl/table/table_dsl.go +++ b/dsl/table/table_dsl.go @@ -1,7 +1,7 @@ /* -Ginkgo isusually dot-imported via: +Ginkgo is usually dot-imported via: - import . "github.com/onsi/ginkgo/v2" + import . "github.com/onsi/ginkgo/v2" however some parts of the DSL may conflict with existing symbols in the user's code. @@ -23,6 +23,11 @@ var FDescribeTable = ginkgo.FDescribeTable var PDescribeTable = ginkgo.PDescribeTable var XDescribeTable = ginkgo.XDescribeTable +var DescribeTableSubtree = ginkgo.DescribeTableSubtree +var FDescribeTableSubtree = ginkgo.FDescribeTableSubtree +var PDescribeTableSubtree = ginkgo.PDescribeTableSubtree +var XDescribeTableSubtree = ginkgo.XDescribeTableSubtree + type TableEntry = ginkgo.TableEntry var Entry = ginkgo.Entry diff --git a/internal/internal_integration/table_test.go b/internal/internal_integration/table_test.go index a695ec3c4..bf954bb63 100644 --- a/internal/internal_integration/table_test.go +++ b/internal/internal_integration/table_test.go @@ -44,6 +44,53 @@ var _ = Describe("Table driven tests", func() { }) }) + Describe("constructing subtree tables", func() { + BeforeEach(func() { + success, _ := RunFixture("table subtree happy-path", func() { + DescribeTableSubtree("hello", func(a, b, sum, difference int) { + var actualSum, actualDifference int + BeforeEach(func() { + rt.Run(CurrentSpecReport().ContainerHierarchyTexts[1] + " bef") + actualSum = a + b + actualDifference = a - b + }) + It(fmt.Sprintf("%d + %d sums correctly", a, b), func() { + rt.Run(CurrentSpecReport().ContainerHierarchyTexts[1] + " sum") + if actualSum != sum { + F("fail") + } + }) + It(fmt.Sprintf("%d - %d subtracts correctly", a, b), func() { + rt.Run(CurrentSpecReport().ContainerHierarchyTexts[1] + " difference") + if actualDifference != difference { + F("fail") + } + }) + }, func(a, b, sum, differenct int) string { return fmt.Sprintf("%d,%d", a, b) }, + Entry(nil, 1, 1, 2, 0), + Entry(nil, 1, 2, 3, -1), + Entry(nil, 2, 1, 0, 0), + ) + }) + Ω(success).Should(BeFalse()) + }) + + It("runs all the entries", func() { + Ω(rt).Should(HaveTracked("1,1 bef", "1,1 sum", "1,1 bef", "1,1 difference", "1,2 bef", "1,2 sum", "1,2 bef", "1,2 difference", "2,1 bef", "2,1 sum", "2,1 bef", "2,1 difference")) + }) + + It("reports on the tests correctly", func() { + Ω(reporter.Did.Names()).Should(Equal([]string{"1 + 1 sums correctly", "1 - 1 subtracts correctly", "1 + 2 sums correctly", "1 - 2 subtracts correctly", "2 + 1 sums correctly", "2 - 1 subtracts correctly"})) + Ω(reporter.Did.Find("1 + 1 sums correctly")).Should(HavePassed()) + Ω(reporter.Did.Find("1 - 1 subtracts correctly")).Should(HavePassed()) + Ω(reporter.Did.Find("1 + 2 sums correctly")).Should(HavePassed()) + Ω(reporter.Did.Find("1 - 2 subtracts correctly")).Should(HavePassed()) + Ω(reporter.Did.Find("2 + 1 sums correctly")).Should(HaveFailed("fail", types.NodeTypeIt)) + Ω(reporter.Did.Find("2 - 1 subtracts correctly")).Should(HaveFailed("fail", types.NodeTypeIt)) + Ω(reporter.End).Should(BeASuiteSummary(false, NSpecs(6), NPassed(4), NFailed(2))) + }) + }) + Describe("Entry Descriptions", func() { Describe("tables with no table-level entry description functions or strings", func() { BeforeEach(func() { diff --git a/table_dsl.go b/table_dsl.go index ac9b7abb5..a3aef821b 100644 --- a/table_dsl.go +++ b/table_dsl.go @@ -46,7 +46,7 @@ And can explore some Table patterns here: https://onsi.github.io/ginkgo/#table-s */ func DescribeTable(description string, args ...interface{}) bool { GinkgoHelper() - generateTable(description, args...) + generateTable(description, false, args...) return true } @@ -56,7 +56,7 @@ You can focus a table with `FDescribeTable`. This is equivalent to `FDescribe`. func FDescribeTable(description string, args ...interface{}) bool { GinkgoHelper() args = append(args, internal.Focus) - generateTable(description, args...) + generateTable(description, false, args...) return true } @@ -66,7 +66,7 @@ You can mark a table as pending with `PDescribeTable`. This is equivalent to `P func PDescribeTable(description string, args ...interface{}) bool { GinkgoHelper() args = append(args, internal.Pending) - generateTable(description, args...) + generateTable(description, false, args...) return true } @@ -75,6 +75,71 @@ You can mark a table as pending with `XDescribeTable`. This is equivalent to `X */ var XDescribeTable = PDescribeTable +/* +DescribeTableSubtree describes a table-driven spec that generates a set of tests for each entry. + +For example: + + DescribeTableSubtree("a subtree table", + func(url string, code int, message string) { + var resp *http.Response + BeforeEach(func() { + var err error + resp, err = http.Get(url) + Expect(err).NotTo(HaveOccurred()) + DeferCleanup(resp.Body.Close) + }) + + It("should return the expected status code", func() { + Expect(resp.StatusCode).To(Equal(code)) + }) + + It("should return the expected message", func() { + body, err := ioutil.ReadAll(resp.Body) + Expect(err).NotTo(HaveOccurred()) + Expect(string(body)).To(Equal(message)) + }) + }, + Entry("default response", "example.com/response", http.StatusOK, "hello world"), + Entry("missing response", "example.com/missing", http.StatusNotFound, "wat?"), + ) + +Note that you **must** place define an It inside the body function. + +You can learn more about DescribeTableSubtree here: https://onsi.github.io/ginkgo/#table-specs +And can explore some Table patterns here: https://onsi.github.io/ginkgo/#table-specs-patterns +*/ +func DescribeTableSubtree(description string, args ...interface{}) bool { + GinkgoHelper() + generateTable(description, true, args...) + return true +} + +/* +You can focus a table with `FDescribeTableSubtree`. This is equivalent to `FDescribe`. +*/ +func FDescribeTableSubtree(description string, args ...interface{}) bool { + GinkgoHelper() + args = append(args, internal.Focus) + generateTable(description, true, args...) + return true +} + +/* +You can mark a table as pending with `PDescribeTableSubtree`. This is equivalent to `PDescribe`. +*/ +func PDescribeTableSubtree(description string, args ...interface{}) bool { + GinkgoHelper() + args = append(args, internal.Pending) + generateTable(description, true, args...) + return true +} + +/* +You can mark a table as pending with `XDescribeTableSubtree`. This is equivalent to `XDescribe`. +*/ +var XDescribeTableSubtree = PDescribeTableSubtree + /* TableEntry represents an entry in a table test. You generally use the `Entry` constructor. */ @@ -131,14 +196,14 @@ 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, isSubtree bool, args ...interface{}) { GinkgoHelper() cl := types.NewCodeLocation(0) containerNodeArgs := []interface{}{cl} entries := []TableEntry{} - var itBody interface{} - var itBodyType reflect.Type + var internalBody interface{} + var internalBodyType reflect.Type var tableLevelEntryDescription interface{} tableLevelEntryDescription = func(args ...interface{}) string { @@ -166,11 +231,11 @@ func generateTable(description string, args ...interface{}) { case t.Kind() == reflect.Func && t.NumOut() == 1 && t.Out(0) == reflect.TypeOf(""): tableLevelEntryDescription = arg case t.Kind() == reflect.Func: - if itBody != nil { + if internalBody != nil { exitIfErr(types.GinkgoErrors.MultipleEntryBodyFunctionsForTable(cl)) } - itBody = arg - itBodyType = reflect.TypeOf(itBody) + internalBody = arg + internalBodyType = reflect.TypeOf(internalBody) default: containerNodeArgs = append(containerNodeArgs, arg) } @@ -200,39 +265,47 @@ func generateTable(description string, args ...interface{}) { err = types.GinkgoErrors.InvalidEntryDescription(entry.codeLocation) } - itNodeArgs := []interface{}{entry.codeLocation} - itNodeArgs = append(itNodeArgs, entry.decorations...) + internalNodeArgs := []interface{}{entry.codeLocation} + internalNodeArgs = append(internalNodeArgs, entry.decorations...) hasContext := false - if itBodyType.NumIn() > 0. { - if itBodyType.In(0).Implements(specContextType) { + if internalBodyType.NumIn() > 0. { + if internalBodyType.In(0).Implements(specContextType) { hasContext = true - } else if itBodyType.In(0).Implements(contextType) && (len(entry.parameters) == 0 || !reflect.TypeOf(entry.parameters[0]).Implements(contextType)) { + } else if internalBodyType.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) + err = validateParameters(internalBody, entry.parameters, "Table Body function", entry.codeLocation, hasContext) } if hasContext { - itNodeArgs = append(itNodeArgs, func(c SpecContext) { + internalNodeArgs = append(internalNodeArgs, func(c SpecContext) { if err != nil { panic(err) } - invokeFunction(itBody, append([]interface{}{c}, entry.parameters...)) + invokeFunction(internalBody, append([]interface{}{c}, entry.parameters...)) }) + if isSubtree { + exitIfErr(types.GinkgoErrors.ContextsCannotBeUsedInSubtreeTables(cl)) + } } else { - itNodeArgs = append(itNodeArgs, func() { + internalNodeArgs = append(internalNodeArgs, func() { if err != nil { panic(err) } - invokeFunction(itBody, entry.parameters) + invokeFunction(internalBody, entry.parameters) }) } - pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, description, itNodeArgs...)) + internalNodeType := types.NodeTypeIt + if isSubtree { + internalNodeType = types.NodeTypeContainer + } + + pushNode(internal.NewNode(deprecationTracker, internalNodeType, description, internalNodeArgs...)) } }) diff --git a/types/errors.go b/types/errors.go index 4fbdc3e9b..6bb72d00c 100644 --- a/types/errors.go +++ b/types/errors.go @@ -505,6 +505,15 @@ func (g ginkgoErrors) IncorrectVariadicParameterTypeToTableFunction(expected, ac } } +func (g ginkgoErrors) ContextsCannotBeUsedInSubtreeTables(cl CodeLocation) error { + return GinkgoError{ + Heading: "Contexts cannot be used in subtree tables", + Message: "You''ve defined a subtree body function that accepts a context but did not provide one in the table entry. Ginkgo SpecContexts can only be passed in to subject and setup nodes - so if you are trying to implement a spec timeout you should request a context in the It function within your subtree body function, not in the subtree body function itself.", + CodeLocation: cl, + DocLink: "table-specs", + } +} + /* Parallel Synchronization errors */ func (g ginkgoErrors) AggregatedReportUnavailableDueToNodeDisappearing() error { From beb95072b84ada2addccf9dca167a35f56d2af39 Mon Sep 17 00:00:00 2001 From: Shubham Bajpai Date: Fri, 5 Jan 2024 21:35:18 +0530 Subject: [PATCH 021/102] Fix typo in internal/suite.go (#1332) * Fix typo in internal/suite.go * update the test case --- internal/suite.go | 2 +- internal/suite_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/suite.go b/internal/suite.go index fe6e8288a..6746152ec 100644 --- a/internal/suite.go +++ b/internal/suite.go @@ -79,7 +79,7 @@ func NewSuite() *Suite { func (suite *Suite) Clone() (*Suite, error) { if suite.phase != PhaseBuildTopLevel { - return nil, fmt.Errorf("cnanot clone suite after tree has been built") + return nil, fmt.Errorf("cannot clone suite after tree has been built") } return &Suite{ tree: &TreeNode{}, diff --git a/internal/suite_test.go b/internal/suite_test.go index 1e7194034..f54965cd4 100644 --- a/internal/suite_test.go +++ b/internal/suite_test.go @@ -88,7 +88,7 @@ var _ = Describe("Suite", func() { It("fails if the tree has already been built", func() { Ω(suite.BuildTree()).Should(Succeed()) _, err := suite.Clone() - Ω(err).Should(MatchError("cnanot clone suite after tree has been built")) + Ω(err).Should(MatchError("cannot clone suite after tree has been built")) }) It("generates the same tree as the original", func() { From 92b6744a3a0c4e7a196009a0620b6c211e1d8b8e Mon Sep 17 00:00:00 2001 From: Ergin Babani Date: Mon, 8 Jan 2024 19:51:31 -0500 Subject: [PATCH 022/102] Add GinkgoTB() function (#1333) This function returns a wrapper around GinkgoT() which satisfies the `testing.TB` interface. - Update fail tests with tests for GinkgoT() and GinkgoTB(). - Fix a bug where GinkgoT().Fail() was not reporting the correct line on error. --- docs/index.md | 2 + dsl/core/core_dsl.go | 2 + dsl/dsl_suite_test.go | 4 +- ginkgo_t_dsl.go | 106 ++++++++++++++++-- .../fail_fixture_ginkgo_t_test.go | 35 ++++++ .../fail_fixture_ginkgo_tb_test.go | 36 ++++++ .../more_ginkgo_tests_test.go | 10 ++ integration/fail_test.go | 26 ++++- integration/flags_test.go | 4 +- integration/run_test.go | 6 +- integration/verbose_and_succinct_test.go | 2 +- internal/testingtproxy/testingtproxy_test.go | 1 + 12 files changed, 214 insertions(+), 20 deletions(-) create mode 100644 integration/_fixtures/fail_fixture/fail_fixture_ginkgo_t_test.go create mode 100644 integration/_fixtures/fail_fixture/fail_fixture_ginkgo_tb_test.go diff --git a/docs/index.md b/docs/index.md index 9f09075fa..6aee23662 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5478,6 +5478,8 @@ When using Gomock you may want to run `ginkgo` with the `-trace` flag to print o `GinkgoT()` also provides additional methods that are Ginkgo-specific. This allows rich third-party integrations to be built on top of Ginkgo - with GinkgoT() serving as a single connection point. +Similarly for third party libraries which accept a `testing.TB` interface, use the `GinkgoTB()` function. This function returns a struct wrapper around `GinkgoT()` which satisfies the `testing.TB`interface. If you need to use any Ginkgo-specific methods you can access the wrapped `GinkgoT()` instance using `GinkgoTBWrapper.GinkgoT`. + ### IDE Support Ginkgo works best from the command-line, and [`ginkgo watch`](#watching-for-changes) makes it easy to rerun tests on the command line whenever changes are detected. diff --git a/dsl/core/core_dsl.go b/dsl/core/core_dsl.go index 0796cee68..b2dad1bef 100644 --- a/dsl/core/core_dsl.go +++ b/dsl/core/core_dsl.go @@ -23,6 +23,7 @@ type GinkgoTestingT = ginkgo.GinkgoTestingT type GinkgoTInterface = ginkgo.GinkgoTInterface type FullGinkgoTInterface = ginkgo.FullGinkgoTInterface type SpecContext = ginkgo.SpecContext +type GinkgoTBWrapper = ginkgo.GinkgoTBWrapper var GinkgoWriter = ginkgo.GinkgoWriter var GinkgoLogr = ginkgo.GinkgoLogr @@ -63,4 +64,5 @@ var BeforeAll = ginkgo.BeforeAll var AfterAll = ginkgo.AfterAll var DeferCleanup = ginkgo.DeferCleanup var GinkgoT = ginkgo.GinkgoT +var GinkgoTB = ginkgo.GinkgoTB var AttachProgressReporter = ginkgo.AttachProgressReporter diff --git a/dsl/dsl_suite_test.go b/dsl/dsl_suite_test.go index 01d3c5e83..ce3ffeb10 100644 --- a/dsl/dsl_suite_test.go +++ b/dsl/dsl_suite_test.go @@ -21,7 +21,9 @@ func ExtractSymbols(f *ast.File) []string { names := []string{} switch v := decl.(type) { case *ast.FuncDecl: - names = append(names, v.Name.Name) + if v.Recv == nil { + names = append(names, v.Name.Name) + } case *ast.GenDecl: switch v.Tok { case token.TYPE: diff --git a/ginkgo_t_dsl.go b/ginkgo_t_dsl.go index 28447ffdd..e908cbfbf 100644 --- a/ginkgo_t_dsl.go +++ b/ginkgo_t_dsl.go @@ -1,7 +1,10 @@ package ginkgo import ( + "testing" + "github.com/onsi/ginkgo/v2/internal/testingtproxy" + "github.com/onsi/ginkgo/v2/types" ) /* @@ -15,7 +18,7 @@ correct line number associated with the failure - though you do not need to use You can learn more here: https://onsi.github.io/ginkgo/#using-third-party-libraries */ func GinkgoT(optionalOffset ...int) FullGinkgoTInterface { - offset := 3 + offset := 1 if len(optionalOffset) > 0 { offset = optionalOffset[0] } @@ -41,21 +44,21 @@ The portion of the interface returned by GinkgoT() that maps onto methods in the type GinkgoTInterface interface { Cleanup(func()) Setenv(kev, value string) - Error(args ...interface{}) - Errorf(format string, args ...interface{}) + Error(args ...any) + Errorf(format string, args ...any) Fail() FailNow() Failed() bool - Fatal(args ...interface{}) - Fatalf(format string, args ...interface{}) + Fatal(args ...any) + Fatalf(format string, args ...any) Helper() - Log(args ...interface{}) - Logf(format string, args ...interface{}) + Log(args ...any) + Logf(format string, args ...any) Name() string Parallel() - Skip(args ...interface{}) + Skip(args ...any) SkipNow() - Skipf(format string, args ...interface{}) + Skipf(format string, args ...any) Skipped() bool TempDir() string } @@ -71,9 +74,9 @@ type FullGinkgoTInterface interface { AddReportEntryVisibilityNever(name string, args ...any) //Prints to the GinkgoWriter - Print(a ...interface{}) - Printf(format string, a ...interface{}) - Println(a ...interface{}) + Print(a ...any) + Printf(format string, a ...any) + Println(a ...any) //Provides access to Ginkgo's color formatting, correctly configured to match the color settings specified in the invocation of ginkgo F(format string, args ...any) string @@ -92,3 +95,82 @@ type FullGinkgoTInterface interface { AttachProgressReporter(func() string) func() } + +/* +GinkgoTB() implements a wrapper that exactly matches the testing.TB interface. + +In go 1.18 a new private() function was added to the testing.TB interface. Any function which accepts testing.TB as input needs to be passed in something that directly implements testing.TB. + +This wrapper satisfies the testing.TB interface and intended to be used as a drop-in replacement with third party libraries that accept testing.TB. + +Similar to GinkgoT(), GinkgoTB() takes an optional offset argument that can be used to get the +correct line number associated with the failure - though you do not need to use this if you call GinkgoHelper() or GinkgoT().Helper() appropriately +*/ + +func GinkgoTB(optionalOffset ...int) *GinkgoTBWrapper { + offset := 2 + if len(optionalOffset) > 0 { + offset = optionalOffset[0] + } + return &GinkgoTBWrapper{GinkgoT: GinkgoT(offset)} +} + +type GinkgoTBWrapper struct { + testing.TB + GinkgoT FullGinkgoTInterface +} + +func (g *GinkgoTBWrapper) Cleanup(f func()) { + g.GinkgoT.Cleanup(f) +} +func (g *GinkgoTBWrapper) Error(args ...any) { + g.GinkgoT.Error(args...) +} +func (g *GinkgoTBWrapper) Errorf(format string, args ...any) { + g.GinkgoT.Errorf(format, args...) +} +func (g *GinkgoTBWrapper) Fail() { + g.GinkgoT.Fail() +} +func (g *GinkgoTBWrapper) FailNow() { + g.GinkgoT.FailNow() +} +func (g *GinkgoTBWrapper) Failed() bool { + return g.GinkgoT.Failed() +} +func (g *GinkgoTBWrapper) Fatal(args ...any) { + g.GinkgoT.Fatal(args...) +} +func (g *GinkgoTBWrapper) Fatalf(format string, args ...any) { + g.GinkgoT.Fatalf(format, args...) +} +func (g *GinkgoTBWrapper) Helper() { + types.MarkAsHelper(1) +} +func (g *GinkgoTBWrapper) Log(args ...any) { + g.GinkgoT.Log(args...) +} +func (g *GinkgoTBWrapper) Logf(format string, args ...any) { + g.GinkgoT.Logf(format, args...) +} +func (g *GinkgoTBWrapper) Name() string { + return g.GinkgoT.Name() +} +func (g *GinkgoTBWrapper) Setenv(key, value string) { + g.GinkgoT.Setenv(key, value) +} +func (g *GinkgoTBWrapper) Skip(args ...any) { + g.GinkgoT.Skip(args...) +} +func (g *GinkgoTBWrapper) SkipNow() { + g.GinkgoT.SkipNow() +} +func (g *GinkgoTBWrapper) Skipf(format string, args ...any) { + g.GinkgoT.Skipf(format, args...) +} +func (g *GinkgoTBWrapper) Skipped() bool { + return g.GinkgoT.Skipped() +} +func (g *GinkgoTBWrapper) TempDir() string { + return g.GinkgoT.TempDir() +} diff --git a/integration/_fixtures/fail_fixture/fail_fixture_ginkgo_t_test.go b/integration/_fixtures/fail_fixture/fail_fixture_ginkgo_t_test.go new file mode 100644 index 000000000..5e161bbac --- /dev/null +++ b/integration/_fixtures/fail_fixture/fail_fixture_ginkgo_t_test.go @@ -0,0 +1,35 @@ +package fail_fixture_test + +import ( + . "github.com/onsi/ginkgo/v2" +) + +var _ = Describe("GinkgoT", func() { + It("synchronous failures with GinkgoT().Fail", func() { + GinkgoT().Fail() + println("NEVER SEE THIS") + }) + + DescribeTable("DescribeTable", + func() { + GinkgoT().Fail() + }, + Entry("a TableEntry constructed by Entry"), + ) + + It("tracks line numbers correctly when GinkgoT().Helper() is called", func() { + ginkgoTHelper() + }) + + It("tracks the actual line number when no helper is used", func() { + ginkgoTNoHelper() + }) +}) + +var ginkgoTNoHelper = func() { + GinkgoT().Fail() +} +var ginkgoTHelper = func() { + GinkgoT().Helper() + GinkgoT().Fail() +} diff --git a/integration/_fixtures/fail_fixture/fail_fixture_ginkgo_tb_test.go b/integration/_fixtures/fail_fixture/fail_fixture_ginkgo_tb_test.go new file mode 100644 index 000000000..c024adbc3 --- /dev/null +++ b/integration/_fixtures/fail_fixture/fail_fixture_ginkgo_tb_test.go @@ -0,0 +1,36 @@ +package fail_fixture_test + +import ( + . "github.com/onsi/ginkgo/v2" +) + +var _ = Describe("GinkgoTB", func() { + It("synchronous failures with GinkgoTB().Fail", func() { + GinkgoTB().Fail() + println("NEVER SEE THIS") + }) + + DescribeTable("DescribeTable", + func() { + GinkgoTB().Fail() + }, + Entry("a TableEntry constructed by Entry"), + ) + + It("tracks line numbers correctly when GinkgoTB().Helper() is called", func() { + ginkgoTBHelper() + }) + + It("tracks the actual line number when no GinkgoTB helper is used", func() { + ginkgoTBNoHelper() + }) +}) + +var ginkgoTBNoHelper = func() { + GinkgoTB().Fail() +} +var ginkgoTBHelper = func() { + t := GinkgoTB() + t.Helper() + t.Fail() +} diff --git a/integration/_fixtures/more_ginkgo_tests_fixture/more_ginkgo_tests_test.go b/integration/_fixtures/more_ginkgo_tests_fixture/more_ginkgo_tests_test.go index c5da1d496..2c13271a3 100644 --- a/integration/_fixtures/more_ginkgo_tests_fixture/more_ginkgo_tests_test.go +++ b/integration/_fixtures/more_ginkgo_tests_fixture/more_ginkgo_tests_test.go @@ -1,6 +1,8 @@ package more_ginkgo_tests_test import ( + "testing" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/ginkgo/v2/integration/_fixtures/more_ginkgo_tests_fixture" . "github.com/onsi/gomega" @@ -14,4 +16,12 @@ var _ = Describe("MoreGinkgoTests", func() { It("should always pass", func() { Ω(AlwaysTrue()).Should(BeTrue()) }) + + It("should match testing.TB", func() { + var tbFunc = func(_ testing.TB) { + Ω(AlwaysTrue()).Should(BeTrue()) + } + + tbFunc(GinkgoTB()) + }) }) diff --git a/integration/fail_test.go b/integration/fail_test.go index 4bea55a6d..ca4b2b0d9 100644 --- a/integration/fail_test.go +++ b/integration/fail_test.go @@ -41,7 +41,31 @@ var _ = Describe("Failing Specs", func() { Ω(output).Should(ContainSubstring(`a helper failed`)) Ω(output).Should(ContainSubstring(`fail_fixture_test.go:54`), "the code location reported for the helper failure - we're testing the call to GinkgoHelper() works as expected") - Ω(output).Should(ContainSubstring("0 Passed | 8 Failed")) + Ω(output).Should(ContainSubstring("synchronous failures with GinkgoT().Fail")) + Ω(output).Should(ContainSubstring("fail_fixture_ginkgo_t_test.go:9")) + + Ω(output).Should(ContainSubstring("GinkgoT DescribeTable")) + Ω(output).Should(ContainSubstring("fail_fixture_ginkgo_t_test.go:15")) + + Ω(output).Should(ContainSubstring(`tracks line numbers correctly when GinkgoT().Helper() is called`)) + Ω(output).Should(ContainSubstring(`fail_fixture_ginkgo_t_test.go:21`), "the code location reported for the ginkgoT helper failure") + + Ω(output).Should(ContainSubstring(`tracks the actual line number when no helper is used`)) + Ω(output).Should(ContainSubstring(`fail_fixture_ginkgo_t_test.go:30`), "the code location reported for the ginkgoT no helper failure") + + Ω(output).Should(ContainSubstring("synchronous failures with GinkgoTB().Fail")) + Ω(output).Should(ContainSubstring("fail_fixture_ginkgo_tb_test.go:9")) + + Ω(output).Should(ContainSubstring("GinkgoTB DescribeTable")) + Ω(output).Should(ContainSubstring("fail_fixture_ginkgo_tb_test.go:15")) + + Ω(output).Should(ContainSubstring(`tracks line numbers correctly when GinkgoTB().Helper() is called`)) + Ω(output).Should(ContainSubstring(`fail_fixture_ginkgo_tb_test.go:21`), "the code location reported for the ginkgoTB helper failure") + + Ω(output).Should(ContainSubstring(`tracks the actual line number when no GinkgoTB helper is used`)) + Ω(output).Should(ContainSubstring(`fail_fixture_ginkgo_tb_test.go:30`), "the code location reported for the ginkgoT no helper failure") + + Ω(output).Should(ContainSubstring("0 Passed | 16 Failed")) }) }) diff --git a/integration/flags_test.go b/integration/flags_test.go index 72d48c099..18fcdea9b 100644 --- a/integration/flags_test.go +++ b/integration/flags_test.go @@ -129,8 +129,8 @@ var _ = Describe("Flags Specs", func() { output := string(session.Out.Contents()) Ω(output).Should(ContainSubstring("synchronous failures")) - Ω(output).Should(ContainSubstring("8 Specs")) - Ω(output).Should(ContainSubstring("8 Passed")) + Ω(output).Should(ContainSubstring("16 Specs")) + Ω(output).Should(ContainSubstring("16 Passed")) Ω(output).Should(ContainSubstring("0 Failed")) }) diff --git a/integration/run_test.go b/integration/run_test.go index 6297ce5fd..e59c2384f 100644 --- a/integration/run_test.go +++ b/integration/run_test.go @@ -339,7 +339,7 @@ var _ = Describe("Running Specs", func() { output := string(session.Out.Contents()) outputLines := strings.Split(output, "\n") - Ω(outputLines[0]).Should(MatchRegexp(`\[\d+\] More_ginkgo_tests Suite - 2/2 specs [%s]{2} SUCCESS! \d+(\.\d+)?[muµ]s PASS`, regexp.QuoteMeta(denoter))) + Ω(outputLines[0]).Should(MatchRegexp(`\[\d+\] More_ginkgo_tests Suite - 3/3 specs [%s]{3} SUCCESS! \d+(\.\d+)?[muµ]s PASS`, regexp.QuoteMeta(denoter))) Ω(outputLines[1]).Should(ContainSubstring("Skipping ./no_tagged_tests (no test files)")) Ω(outputLines[2]).Should(MatchRegexp(`\[\d+\] Passing_ginkgo_tests Suite - 5/5 specs [%s]{5} SUCCESS! \d+(\.\d+)?[muµ]s PASS`, regexp.QuoteMeta(denoter))) Ω(output).Should(ContainSubstring("Test Suite Passed")) @@ -352,7 +352,7 @@ var _ = Describe("Running Specs", func() { output := string(session.Out.Contents()) outputLines := strings.Split(output, "\n") - Ω(outputLines[0]).Should(MatchRegexp(`\[\d+\] More_ginkgo_tests Suite - 2/2 specs [%s]{2} SUCCESS! \d+(\.\d+)?[muµ]s PASS`, regexp.QuoteMeta(denoter))) + Ω(outputLines[0]).Should(MatchRegexp(`\[\d+\] More_ginkgo_tests Suite - 3/3 specs [%s]{3} SUCCESS! \d+(\.\d+)?[muµ]s PASS`, regexp.QuoteMeta(denoter))) Ω(outputLines[1]).Should(ContainSubstring("Skipping ./no_tagged_tests (no test files)")) Ω(outputLines[2]).Should(MatchRegexp(`\[\d+\] Passing_ginkgo_tests Suite - 5/5 specs [%s]{5} SUCCESS! \d+(\.\d+)?[muµ]s PASS`, regexp.QuoteMeta(denoter))) Ω(output).Should(ContainSubstring("Test Suite Passed")) @@ -416,7 +416,7 @@ var _ = Describe("Running Specs", func() { Ω(outputLines[2]).Should(ContainSubstring("Failed to compile does_not_compile:")) Ω(output).Should(MatchRegexp(`\[\d+\] Failing_ginkgo_tests Suite - 2/2 specs`)) Ω(output).Should(ContainSubstring(fmt.Sprintf("%s [FAILED]", denoter))) - Ω(output).Should(MatchRegexp(`\[\d+\] More_ginkgo_tests Suite - 2/2 specs [%s]{2} SUCCESS! \d+(\.\d+)?[muµ]s PASS`, regexp.QuoteMeta(denoter))) + Ω(output).Should(MatchRegexp(`\[\d+\] More_ginkgo_tests Suite - 3/3 specs [%s]{3} SUCCESS! \d+(\.\d+)?[muµ]s PASS`, regexp.QuoteMeta(denoter))) Ω(output).Should(ContainSubstring("Test Suite Failed")) }) }) diff --git a/integration/verbose_and_succinct_test.go b/integration/verbose_and_succinct_test.go index eb1087622..8720f245a 100644 --- a/integration/verbose_and_succinct_test.go +++ b/integration/verbose_and_succinct_test.go @@ -43,7 +43,7 @@ var _ = Describe("Verbose And Succinct Mode", func() { output := session.Out.Contents() Ω(output).Should(MatchRegexp(`\] Passing_ginkgo_tests Suite - 5/5 specs [%s]{5} SUCCESS!`, regexp.QuoteMeta(denoter))) - Ω(output).Should(MatchRegexp(`\] More_ginkgo_tests Suite - 2/2 specs [%s]{2} SUCCESS!`, regexp.QuoteMeta(denoter))) + Ω(output).Should(MatchRegexp(`\] More_ginkgo_tests Suite - 3/3 specs [%s]{3} SUCCESS!`, regexp.QuoteMeta(denoter))) }) }) diff --git a/internal/testingtproxy/testingtproxy_test.go b/internal/testingtproxy/testingtproxy_test.go index 22a3e9242..518e3a8eb 100644 --- a/internal/testingtproxy/testingtproxy_test.go +++ b/internal/testingtproxy/testingtproxy_test.go @@ -223,6 +223,7 @@ var _ = Describe("Testingtproxy", func() { reportToReturn.LeafNodeText = "Lewis" Ω(t.Name()).Should(Equal("C.S. Lewis")) Ω(GinkgoT().Name()).Should(ContainSubstring("supports Name")) + Ω(GinkgoTB().Name()).Should(ContainSubstring("supports Name")) }) It("ignores Parallel", func() { From 4a2c8326e1a618a6dba9339e14755b30118e4260 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Thu, 11 Jan 2024 13:09:14 -0700 Subject: [PATCH 023/102] add GinkgoTB() to docs --- docs/index.md | 2 +- ginkgo_t_dsl.go | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 6aee23662..ca9e95549 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5420,7 +5420,7 @@ ginkgo version ### Using Third-party Libraries -Most third-party Go `testing` integrations (e.g. matcher libraries, mocking libraries) take and wrap a `*testing.T` to provide functionality. Unfortunately there is no formal interface for `*testing.T` however Ginkgo provides a function, `GinkgoT()` that returns a struct that implements all the methods that `*testing.T` implements. Most libraries accept the `*testing.T` object via an interface and you can usually simply pass in `GinkgoT()` and expect the library to work. +Most third-party Go `testing` integrations (e.g. matcher libraries, mocking libraries) take and wrap a `*testing.T` to provide functionality. Unfortunately there is no formal interface for `*testing.T` however Ginkgo provides a function, `GinkgoT()` that returns a struct that implements all the methods that `*testing.T` implements. Most libraries accept the `*testing.T` object via an interface and you can usually simply pass in `GinkgoT()` and expect the library to work. Some libraries require passing in a `testing.TB` - you can use `GinkgoTB()` for these. For example, you can choose to use [testify](https://github.com/stretchr/testify) instead of Gomega like so: diff --git a/ginkgo_t_dsl.go b/ginkgo_t_dsl.go index e908cbfbf..639541a16 100644 --- a/ginkgo_t_dsl.go +++ b/ginkgo_t_dsl.go @@ -106,7 +106,6 @@ This wrapper satisfies the testing.TB interface and intended to be used as a dro Similar to GinkgoT(), GinkgoTB() takes an optional offset argument that can be used to get the correct line number associated with the failure - though you do not need to use this if you call GinkgoHelper() or GinkgoT().Helper() appropriately */ - func GinkgoTB(optionalOffset ...int) *GinkgoTBWrapper { offset := 2 if len(optionalOffset) > 0 { From beaf16d17f98f30365a11ff236583d611c094078 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Thu, 11 Jan 2024 14:24:28 -0700 Subject: [PATCH 024/102] v2.14.0 --- CHANGELOG.md | 25 +++++++++++++++++++++++++ types/version.go | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec91408f9..fbe515639 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,28 @@ +## 2.14.0 + +### Features +You can now use `GinkgoTB()` when you need an instance of `testing.TB` to pass to a library. + +Prior to this release table testing only supported generating individual `It`s for each test entry. `DescribeTableSubtree` extends table testing support to entire testing subtrees - under the hood `DescrieTableSubtree` generates a new container for each entry and invokes your function to fill our the container. See the [docs](https://onsi.github.io/ginkgo/#generating-subtree-tables) to learn more. + +- Introduce DescribeTableSubtree [65ec56d] +- add GinkgoTB() to docs [4a2c832] +- Add GinkgoTB() function (#1333) [92b6744] + +### Fixes +- Fix typo in internal/suite.go (#1332) [beb9507] +- Fix typo in docs/index.md (#1319) [4ac3a13] +- allow wasm to compile with ginkgo present (#1311) [b2e5bc5] + +### Maintenance +- Bump golang.org/x/tools from 0.16.0 to 0.16.1 (#1316) [465a8ec] +- Bump actions/setup-go from 4 to 5 (#1313) [eab0e40] +- Bump github/codeql-action from 2 to 3 (#1317) [fbf9724] +- Bump golang.org/x/crypto (#1318) [3ee80ee] +- Bump golang.org/x/tools from 0.14.0 to 0.16.0 (#1306) [123e1d5] +- Bump github.com/onsi/gomega from 1.29.0 to 1.30.0 (#1297) [558f6e0] +- Bump golang.org/x/net from 0.17.0 to 0.19.0 (#1307) [84ff7f3] + ## 2.13.2 ### Fixes diff --git a/types/version.go b/types/version.go index a4a1524b4..7015be128 100644 --- a/types/version.go +++ b/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.13.2" +const VERSION = "2.14.0" From 6f67a147b39873678462615d412cfb0177463bf1 Mon Sep 17 00:00:00 2001 From: wangxiang Date: Wed, 17 Jan 2024 22:54:18 +0800 Subject: [PATCH 025/102] bugfix(docs): use Unsetenv instead of Clearenv (#1337) --- docs/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/index.md b/docs/index.md index ca9e95549..7f30a36e8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -875,7 +875,7 @@ Describe("Reporting book weight", func() { Context("with no WEIGHT_UNITS environment set", func() { BeforeEach(func() { - err := os.Clearenv("WEIGHT_UNITS") + err := os.Unsetenv("WEIGHT_UNITS") Expect(err).NotTo(HaveOccurred()) }) @@ -928,13 +928,13 @@ Describe("Reporting book weight", func() { }) AfterEach(func() { - err := os.Clearenv("WEIGHT_UNITS") + err := os.Unsetenv("WEIGHT_UNITS") Expect(err).NotTo(HaveOccurred()) }) Context("with no WEIGHT_UNITS environment set", func() { BeforeEach(func() { - err := os.Clearenv("WEIGHT_UNITS") + err := os.Unsetenv("WEIGHT_UNITS") Expect(err).NotTo(HaveOccurred()) }) From dbaf18fd0af2b798961b08ee9c0a3266d3abadd6 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Wed, 17 Jan 2024 13:03:06 -0700 Subject: [PATCH 026/102] Document areas where GinkgoT() behaves differently from testing.T adresses #1331 --- docs/index.md | 5 +++++ ginkgo_t_dsl.go | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/docs/index.md b/docs/index.md index 7f30a36e8..15ef9187d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5480,6 +5480,11 @@ When using Gomock you may want to run `ginkgo` with the `-trace` flag to print o Similarly for third party libraries which accept a `testing.TB` interface, use the `GinkgoTB()` function. This function returns a struct wrapper around `GinkgoT()` which satisfies the `testing.TB`interface. If you need to use any Ginkgo-specific methods you can access the wrapped `GinkgoT()` instance using `GinkgoTBWrapper.GinkgoT`. +In general, `GinkgoT()` attempts to mimic the behavior of `testing.T` with the exception of the following: + +- `Error`/`Errorf`: failures in Ginkgo always immediately stop execution and there is no mechanism to log a failure without aborting the test. As such `Error`/`Errorf` are equivalent to `Fatal`/`Fatalf`. +- `Parallel()` is a no-op as Ginkgo's multi-process parallelism model is substantially different from go test's in-process model. + ### IDE Support Ginkgo works best from the command-line, and [`ginkgo watch`](#watching-for-changes) makes it easy to rerun tests on the command line whenever changes are detected. diff --git a/ginkgo_t_dsl.go b/ginkgo_t_dsl.go index 639541a16..02c6739e5 100644 --- a/ginkgo_t_dsl.go +++ b/ginkgo_t_dsl.go @@ -15,6 +15,11 @@ GinkgoT() is analogous to *testing.T and implements the majority of *testing.T's GinkgoT() takes an optional offset argument that can be used to get the correct line number associated with the failure - though you do not need to use this if you call GinkgoHelper() or GinkgoT().Helper() appropriately +GinkgoT() attempts to mimic the behavior of `testing.T` with the exception of the following: + +- Error/Errorf: failures in Ginkgo always immediately stop execution and there is no mechanism to log a failure without aborting the test. As such Error/Errorf are equivalent to Fatal/Fatalf. +- Parallel() is a no-op as Ginkgo's multi-process parallelism model is substantially different from go test's in-process model. + You can learn more here: https://onsi.github.io/ginkgo/#using-third-party-libraries */ func GinkgoT(optionalOffset ...int) FullGinkgoTInterface { From 8f3bd70cc78b00986aaf7fc8e9fbd77df05e6b26 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Wed, 17 Jan 2024 13:17:54 -0700 Subject: [PATCH 027/102] JUnit reports now interpret Label(owner:X) and set owner to X. --- docs/index.md | 2 +- reporters/junit_report.go | 12 ++++++++++++ reporters/junit_report_test.go | 16 ++++++++++------ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/docs/index.md b/docs/index.md index 15ef9187d..c68cc6e17 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3389,7 +3389,7 @@ Ginkgo also supports generating JUnit reports with ginkgo --junit-report=report.xml ``` -The JUnit report is compatible with the JUnit specification, however Ginkgo specs carry much more metadata than can be easily mapped onto the JUnit spec so some information is lost and/or a bit harder to decode than using Ginkgo's native JSON format. +The JUnit report is compatible with the JUnit specification, however Ginkgo specs carry much more metadata than can be easily mapped onto the JUnit spec so some information is lost and/or a bit harder to decode than using Ginkgo's native JSON format. Nonetheless, Ginkgo does its best to populate as much of the JUnit report as possible. This includes adding additional metadata using [labels](#spec-labels) - in particular if you provide a label of the form `Label("owner:XYZ")`, the generating JUnit spec will set the `Owner` attribute to `XYZ`. Ginkgo also supports Teamcity reports with `ginkgo --teamcity-report=report.teamcity` though, again, the Teamcity spec makes it difficult to capture all the spec metadata. diff --git a/reporters/junit_report.go b/reporters/junit_report.go index 816042208..314aeaba0 100644 --- a/reporters/junit_report.go +++ b/reporters/junit_report.go @@ -15,6 +15,7 @@ import ( "fmt" "os" "path" + "regexp" "strings" "github.com/onsi/ginkgo/v2/config" @@ -104,6 +105,8 @@ type JUnitProperty struct { Value string `xml:"value,attr"` } +var ownerRE = regexp.MustCompile(`(?i)^owner:(.*)$`) + type JUnitTestCase struct { // Name maps onto the full text of the spec - equivalent to "[SpecReport.LeafNodeType] SpecReport.FullText()" Name string `xml:"name,attr"` @@ -113,6 +116,8 @@ type JUnitTestCase struct { Status string `xml:"status,attr"` // Time is the time in seconds to execute the spec - maps onto SpecReport.RunTime Time float64 `xml:"time,attr"` + // Owner is the owner the spec - is set if a label matching Label("owner:X") is provided + Owner string `xml:"owner,attr,omitempty"` //Skipped is populated with a message if the test was skipped or pending Skipped *JUnitSkipped `xml:"skipped,omitempty"` //Error is populated if the test panicked or was interrupted @@ -195,6 +200,12 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit if len(labels) > 0 && !config.OmitSpecLabels { name = name + " [" + strings.Join(labels, ", ") + "]" } + owner := "" + for _, label := range labels { + if matches := ownerRE.FindStringSubmatch(label); len(matches) == 2 { + owner = matches[1] + } + } name = strings.TrimSpace(name) test := JUnitTestCase{ @@ -202,6 +213,7 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit Classname: report.SuiteDescription, Status: spec.State.String(), Time: spec.RunTime.Seconds(), + Owner: owner, } if !spec.State.Is(config.OmitTimelinesForSpecState) { test.SystemErr = systemErrForUnstructuredReporters(spec) diff --git a/reporters/junit_report_test.go b/reporters/junit_report_test.go index 78c92edc0..9c71df483 100644 --- a/reporters/junit_report_test.go +++ b/reporters/junit_report_test.go @@ -33,7 +33,7 @@ var _ = Describe("JunitReport", func() { RE("a hidden report entry", cl1, TL("ginkgowriter\noutput\n"), types.ReportEntryVisibilityNever), AF(types.SpecStateFailed, "a subsequent failure", types.FailureNodeInContainer, FailureNodeLocation(cl3), types.NodeTypeAfterEach, 0, TL("ginkgowriter\noutput\ncleanup!")), ), - S(types.NodeTypeIt, "A", cl0, STD("some captured stdout\n"), GW("some GinkgoWriter\noutput is interspersed\nhere and there\n"), + S(types.NodeTypeIt, "A", cl0, STD("some captured stdout\n"), GW("some GinkgoWriter\noutput is interspersed\nhere and there\n"), Label("cat", "owner:frank", "OWNer:bob"), SE(types.SpecEventNodeStart, types.NodeTypeIt, "A", cl0), PR("my progress report", LeafNodeText("A"), TL("some GinkgoWriter\n")), SE(types.SpecEventByStart, "My Step", cl1, TL("some GinkgoWriter\n")), @@ -42,8 +42,8 @@ var _ = Describe("JunitReport", func() { SE(types.SpecEventByEnd, "My Step", cl1, time.Millisecond*200, TL("some GinkgoWriter\noutput is interspersed\n")), SE(types.SpecEventNodeEnd, types.NodeTypeIt, "A", cl0, time.Millisecond*300, TL("some GinkgoWriter\noutput is interspersed\nhere and there\n")), ), - S(types.NodeTypeIt, "A", cl0, types.SpecStatePending), - S(types.NodeTypeIt, "A", cl0, types.SpecStatePanicked, STD("some captured stdout\n"), + S(types.NodeTypeIt, "A", cl0, types.SpecStatePending, CLabels(Label("owner:org")), Label("owner:team")), + S(types.NodeTypeIt, "A", cl0, types.SpecStatePanicked, CLabels(Label("owner:org")), STD("some captured stdout\n"), SE(types.SpecEventNodeStart, types.NodeTypeIt, "A", cl0), F("failure\nmessage", cl1, types.FailureNodeIsLeafNode, FailureNodeLocation(cl0), types.NodeTypeIt, ForwardedPanic("the panic")), SE(types.SpecEventNodeEnd, types.NodeTypeIt, "A", cl0, time.Millisecond*300, TL("some GinkgoWriter\noutput is interspersed\nhere and there\n")), @@ -95,6 +95,7 @@ var _ = Describe("JunitReport", func() { Ω(failingSpec.Status).Should(Equal("timedout")) Ω(failingSpec.Skipped).Should(BeNil()) Ω(failingSpec.Error).Should(BeNil()) + Ω(failingSpec.Owner).Should(Equal("")) Ω(failingSpec.Failure.Message).Should(Equal("failure\nmessage")) Ω(failingSpec.Failure.Type).Should(Equal("timedout")) Ω(failingSpec.Failure.Description).Should(MatchLines( @@ -141,12 +142,13 @@ var _ = Describe("JunitReport", func() { )) passingSpec := suite.TestCases[1] - Ω(passingSpec.Name).Should(Equal("[It] A")) + Ω(passingSpec.Name).Should(Equal("[It] A [cat, owner:frank, OWNer:bob]")) Ω(passingSpec.Classname).Should(Equal("My Suite")) Ω(passingSpec.Status).Should(Equal("passed")) Ω(passingSpec.Skipped).Should(BeNil()) Ω(passingSpec.Error).Should(BeNil()) Ω(passingSpec.Failure).Should(BeNil()) + Ω(passingSpec.Owner).Should(Equal("bob")) Ω(passingSpec.SystemOut).Should(Equal("some captured stdout\n")) Ω(passingSpec.SystemErr).Should(MatchLines( spr("> Enter [It] A - cl0.go:12 @ %s", FORMATTED_TIME), @@ -165,20 +167,22 @@ var _ = Describe("JunitReport", func() { )) pendingSpec := suite.TestCases[2] - Ω(pendingSpec.Name).Should(Equal("[It] A")) + Ω(pendingSpec.Name).Should(Equal("[It] A [owner:org, owner:team]")) Ω(pendingSpec.Classname).Should(Equal("My Suite")) Ω(pendingSpec.Status).Should(Equal("pending")) Ω(pendingSpec.Skipped.Message).Should(Equal("pending")) Ω(pendingSpec.Error).Should(BeNil()) + Ω(pendingSpec.Owner).Should(Equal("team")) Ω(pendingSpec.Failure).Should(BeNil()) Ω(pendingSpec.SystemOut).Should(BeEmpty()) Ω(pendingSpec.SystemErr).Should(BeEmpty()) panickedSpec := suite.TestCases[3] - Ω(panickedSpec.Name).Should(Equal("[It] A")) + Ω(panickedSpec.Name).Should(Equal("[It] A [owner:org]")) Ω(panickedSpec.Classname).Should(Equal("My Suite")) Ω(panickedSpec.Status).Should(Equal("panicked")) Ω(panickedSpec.Skipped).Should(BeNil()) + Ω(panickedSpec.Owner).Should(Equal("org")) Ω(panickedSpec.Error.Message).Should(Equal("the panic")) Ω(panickedSpec.Error.Type).Should(Equal("panicked")) Ω(panickedSpec.Error.Description).Should(MatchLines( From 732abbc3e709c4913e7f0644c1aee1faf076f0ea Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Wed, 17 Jan 2024 13:19:36 -0700 Subject: [PATCH 028/102] clarify that last owner label wins --- reporters/junit_report.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reporters/junit_report.go b/reporters/junit_report.go index 314aeaba0..43244a9bd 100644 --- a/reporters/junit_report.go +++ b/reporters/junit_report.go @@ -116,7 +116,7 @@ type JUnitTestCase struct { Status string `xml:"status,attr"` // Time is the time in seconds to execute the spec - maps onto SpecReport.RunTime Time float64 `xml:"time,attr"` - // Owner is the owner the spec - is set if a label matching Label("owner:X") is provided + // Owner is the owner the spec - is set if a label matching Label("owner:X") is provided. The last matching label is used as the owner, thereby allowing specs to override owners specified in container nodes. Owner string `xml:"owner,attr,omitempty"` //Skipped is populated with a message if the test was skipped or pending Skipped *JUnitSkipped `xml:"skipped,omitempty"` From 4fcd0b3559d887317826a9d604b947d6b2b52b1c Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Wed, 17 Jan 2024 15:05:00 -0700 Subject: [PATCH 029/102] Bump to go 1.20 --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 190cc624e..9a36d3c88 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/onsi/ginkgo/v2 -go 1.18 +go 1.20 require ( github.com/go-logr/logr v1.3.0 From 96e915c326d0265f3bb0f662672573f124fcd38d Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Wed, 17 Jan 2024 15:17:03 -0700 Subject: [PATCH 030/102] include cancellation reason when cancelling spec context --- .../interrupt_and_timeout_test.go | 27 +++++++++++++++++++ internal/spec_context.go | 4 +-- internal/suite.go | 6 ++--- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/internal/internal_integration/interrupt_and_timeout_test.go b/internal/internal_integration/interrupt_and_timeout_test.go index fde47b99a..566866b24 100644 --- a/internal/internal_integration/interrupt_and_timeout_test.go +++ b/internal/internal_integration/interrupt_and_timeout_test.go @@ -195,6 +195,7 @@ var _ = Describe("Interrupts and Timeouts", func() { interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) select { case <-c.Done(): + Ω(context.Cause(c)).Should(MatchError(interrupt_handler.InterruptCauseSignal.String())) F("bam") case <-time.After(time.Hour): } @@ -236,6 +237,7 @@ var _ = Describe("Interrupts and Timeouts", func() { interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) select { case <-c.Done(): + Ω(context.Cause(c)).Should(MatchError(interrupt_handler.InterruptCauseSignal.String())) time.Sleep(time.Hour) case <-time.After(time.Hour): } @@ -275,6 +277,7 @@ var _ = Describe("Interrupts and Timeouts", func() { interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) select { case <-c.Done(): + Ω(context.Cause(c)).Should(MatchError(interrupt_handler.InterruptCauseSignal.String())) time.Sleep(time.Millisecond * 100) interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) time.Sleep(time.Hour) @@ -325,12 +328,14 @@ var _ = Describe("Interrupts and Timeouts", func() { It("A", rt.TSC("A", func(c SpecContext) { interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) <-c.Done() + Ω(context.Cause(c)).Should(MatchError(interrupt_handler.InterruptCauseSignal.String())) })) It("B", rt.T("B")) AfterEach(rt.TSC("aft-inner", func(c SpecContext) { t := time.Now() select { case <-c.Done(): + Ω(context.Cause(c)).Should(MatchError("grace period timeout occurred")) times.Set("aft-inner", time.Since(t)) time.Sleep(time.Second) case <-time.After(time.Second): @@ -380,11 +385,13 @@ var _ = Describe("Interrupts and Timeouts", func() { It("A", rt.TSC("A", func(c SpecContext) { interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) <-c.Done() + Ω(context.Cause(c)).Should(MatchError(interrupt_handler.InterruptCauseSignal.String())) })) It("B", rt.T("B")) AfterEach(rt.TSC("aft-inner", func(c SpecContext) { select { case <-c.Done(): + Ω(context.Cause(c)).Should(MatchError("node timeout occurred")) times.Set("aft-inner", time.Since(t)) time.Sleep(time.Second) case <-time.After(time.Second): @@ -432,11 +439,13 @@ var _ = Describe("Interrupts and Timeouts", func() { It("A", rt.TSC("A", func(c SpecContext) { interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) <-c.Done() + Ω(context.Cause(c)).Should(MatchError(interrupt_handler.InterruptCauseSignal.String())) })) It("B", rt.T("B")) AfterEach(rt.TSC("aft-inner", func(c SpecContext) { interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) <-c.Done() + Ω(context.Cause(c)).Should(MatchError(interrupt_handler.InterruptCauseSignal.String())) })) }) AfterEach(rt.T("aft-outer")) @@ -479,11 +488,13 @@ var _ = Describe("Interrupts and Timeouts", func() { It("A", rt.TSC("A", func(c SpecContext) { interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) <-c.Done() + Ω(context.Cause(c)).Should(MatchError(interrupt_handler.InterruptCauseSignal.String())) })) It("B", rt.T("B")) AfterEach(rt.TSC("aft-inner", func(c SpecContext) { interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) <-c.Done() + Ω(context.Cause(c)).Should(MatchError(interrupt_handler.InterruptCauseSignal.String())) })) }) AfterEach(rt.T("aft-outer")) @@ -536,6 +547,7 @@ var _ = Describe("Interrupts and Timeouts", func() { BeforeEach(rt.TSC("bef-inner", func(c SpecContext) { interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) <-c.Done() + Ω(context.Cause(c)).Should(MatchError(interrupt_handler.InterruptCauseSignal.String())) })) Context("even more nested", func() { @@ -629,6 +641,7 @@ var _ = Describe("Interrupts and Timeouts", func() { Describe("when it exits in time", func() { It("A", rt.TSC("A", func(c SpecContext) { <-c.Done() + Ω(context.Cause(c)).Should(MatchError("node timeout occurred")) rt.Run("A-cancelled") Fail("subsequent failure message") }), NodeTimeout(time.Millisecond*100)) @@ -637,6 +650,7 @@ var _ = Describe("Interrupts and Timeouts", func() { Describe("with no configured grace period", func() { It("B", rt.TSC("B", func(c SpecContext) { <-c.Done() + Ω(context.Cause(c)).Should(MatchError("node timeout occurred")) time.Sleep(time.Hour) }), NodeTimeout(time.Millisecond*100)) }) @@ -644,6 +658,7 @@ var _ = Describe("Interrupts and Timeouts", func() { Describe("with a configured grace period", func() { It("C", rt.TSC("C", func(c SpecContext) { <-c.Done() + Ω(context.Cause(c)).Should(MatchError("node timeout occurred")) time.Sleep(time.Hour) }), NodeTimeout(time.Millisecond*100), GracePeriod(time.Millisecond*50)) }) @@ -714,6 +729,7 @@ var _ = Describe("Interrupts and Timeouts", func() { }, func(c SpecContext, b []byte) { rt.Run(string(b)) <-c.Done() + Ω(context.Cause(c)).Should(MatchError("node timeout occurred")) times.Set(string(b), time.Since(t)) }, NodeTimeout(time.Millisecond*100)) @@ -724,6 +740,7 @@ var _ = Describe("Interrupts and Timeouts", func() { }, func(c SpecContext) { rt.Run("afts-proc-1") <-c.Done() + Ω(context.Cause(c)).Should(MatchError("node timeout occurred")) times.Set("afts-proc-1", time.Since(t)) }, NodeTimeout(time.Millisecond*200)) }) @@ -763,6 +780,7 @@ var _ = Describe("Interrupts and Timeouts", func() { AfterEach(rt.TSC("aft-1", func(c SpecContext) { times.Set("A", time.Since(t)) <-c.Done() + Ω(context.Cause(c)).Should(MatchError("grace period timeout occurred")) times.Set("aft-1-cancel", time.Since(t)) writer.Println("aft-1") time.Sleep(time.Hour) @@ -771,6 +789,7 @@ var _ = Describe("Interrupts and Timeouts", func() { AfterEach(rt.TSC("aft-2", func(c SpecContext) { times.Set("aft-1-out", time.Since(t)) <-c.Done() + Ω(context.Cause(c)).Should(MatchError("grace period timeout occurred")) times.Set("aft-2-cancel", time.Since(t)) writer.Println("aft-2") time.Sleep(time.Hour) @@ -779,6 +798,7 @@ var _ = Describe("Interrupts and Timeouts", func() { AfterEach(rt.TSC("aft-3", func(c SpecContext) { times.Set("aft-2-out", time.Since(t)) <-c.Done() + Ω(context.Cause(c)).Should(MatchError("node timeout occurred")) times.Set("aft-3-cancel", time.Since(t)) writer.Println("aft-3") time.Sleep(time.Hour) @@ -839,6 +859,7 @@ var _ = Describe("Interrupts and Timeouts", func() { BeforeEach(rt.TSC("bef-A", func(c SpecContext) { t := time.Now() <-c.Done() + Ω(context.Cause(c)).Should(MatchError("node timeout occurred")) times.Set("bef-A", time.Since(t)) }), NodeTimeout(time.Millisecond*100)) @@ -849,6 +870,7 @@ var _ = Describe("Interrupts and Timeouts", func() { BeforeEach(rt.TSC("bef-B", func(c SpecContext) { t := time.Now() <-c.Done() + Ω(context.Cause(c)).Should(MatchError("spec timeout occurred")) times.Set("bef-B", time.Since(t)) }), NodeTimeout(time.Millisecond*250)) @@ -859,6 +881,7 @@ var _ = Describe("Interrupts and Timeouts", func() { BeforeEach(rt.TSC("bef-C", func(c SpecContext) { t := time.Now() <-c.Done() + Ω(context.Cause(c)).Should(MatchError("suite timeout occurred")) times.Set("bef-C", time.Since(t)) }), NodeTimeout(time.Millisecond*300)) @@ -914,6 +937,7 @@ var _ = Describe("Interrupts and Timeouts", func() { Context("container", func() { It("A", rt.TSC("A", func(c SpecContext) { <-c.Done() + Ω(context.Cause(c)).Should(MatchError("suite timeout occurred")) })) It("B", rt.T("B")) @@ -947,6 +971,7 @@ var _ = Describe("Interrupts and Timeouts", func() { rt.Run(key) t := time.Now() <-c.Done() + Ω(context.Cause(c)).Should(MatchError("node timeout occurred")) times.Set(key, time.Since(t)) }, NodeTimeout(time.Millisecond*100), "dc-1") @@ -954,6 +979,7 @@ var _ = Describe("Interrupts and Timeouts", func() { rt.Run(key) t := time.Now() <-c.Done() + Ω(context.Cause(c)).Should(MatchError("node timeout occurred")) times.Set(key, time.Since(t)) }, NodeTimeout(time.Millisecond*100), "dc-2") @@ -962,6 +988,7 @@ var _ = Describe("Interrupts and Timeouts", func() { rt.Run(key) t := time.Now() <-c.Done() + Ω(context.Cause(c)).Should(MatchError("node timeout occurred")) times.Set(key, time.Since(t)) }, NodeTimeout(time.Millisecond*100), context.WithValue(context.Background(), "key", "dc"), "-3") diff --git a/internal/spec_context.go b/internal/spec_context.go index 2515b84a1..2d2ea2fc3 100644 --- a/internal/spec_context.go +++ b/internal/spec_context.go @@ -17,7 +17,7 @@ type specContext struct { context.Context *ProgressReporterManager - cancel context.CancelFunc + cancel context.CancelCauseFunc suite *Suite } @@ -30,7 +30,7 @@ Note that while SpecContext is used to enforce deadlines by Ginkgo it is not con 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()) + ctx, cancel := context.WithCancelCause(context.Background()) sc := &specContext{ cancel: cancel, suite: suite, diff --git a/internal/suite.go b/internal/suite.go index 6746152ec..2b4db48af 100644 --- a/internal/suite.go +++ b/internal/suite.go @@ -858,7 +858,7 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ } sc := NewSpecContext(suite) - defer sc.cancel() + defer sc.cancel(fmt.Errorf("spec has finished")) suite.selectiveLock.Lock() suite.currentSpecContext = sc @@ -958,7 +958,7 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ // 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() + sc.cancel(fmt.Errorf("%s timeout occurred", timeoutInPlay)) //and now we wait for the grace period gracePeriodChannel = time.After(gracePeriod) case <-interruptStatus.Channel: @@ -985,7 +985,7 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ } progressReport = progressReport.WithoutOtherGoroutines() - sc.cancel() + sc.cancel(fmt.Errorf(interruptStatus.Message())) if interruptStatus.Level == interrupt_handler.InterruptLevelBailOut { if interruptStatus.ShouldIncludeProgressReport() { From dca77c807c02fbc18dcc957c8e605424dbb5a891 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Wed, 17 Jan 2024 15:37:29 -0700 Subject: [PATCH 031/102] fix outline when using nodot inginkgo v2 --- ginkgo/outline/_testdata/nodot_test.go.csv | 15 +++++++++++++++ ginkgo/outline/_testdata/nodot_test.go.json | 2 +- ginkgo/outline/ginkgo.go | 3 ++- ginkgo/outline/import.go | 9 +-------- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/ginkgo/outline/_testdata/nodot_test.go.csv b/ginkgo/outline/_testdata/nodot_test.go.csv index fe810ce3c..9795d38f3 100644 --- a/ginkgo/outline/_testdata/nodot_test.go.csv +++ b/ginkgo/outline/_testdata/nodot_test.go.csv @@ -1 +1,16 @@ Name,Text,Start,End,Spec,Focused,Pending,Labels +Describe,NodotFixture,71,614,false,false,false,"" +Describe,normal,113,233,false,false,false,"" +It,normal,150,229,true,false,false,"" +By,normal,182,201,false,false,false,"" +By,normal,205,224,false,false,false,"" +Context,normal,236,310,false,false,false,"" +It,normal,272,306,true,false,false,"" +When,normal,313,384,false,false,false,"" +It,normal,346,380,true,false,false,"" +It,normal,387,420,true,false,false,"" +Specify,normal,423,461,true,false,false,"" +DescribeTable,normal,464,536,false,false,false,"" +Entry,normal,510,532,true,false,false,"" +DescribeTable,normal,539,611,false,false,false,"" +Entry,normal,585,607,true,false,false,"" diff --git a/ginkgo/outline/_testdata/nodot_test.go.json b/ginkgo/outline/_testdata/nodot_test.go.json index fe51488c7..3920cb150 100644 --- a/ginkgo/outline/_testdata/nodot_test.go.json +++ b/ginkgo/outline/_testdata/nodot_test.go.json @@ -1 +1 @@ -[] +[{"name":"Describe","text":"NodotFixture","start":71,"end":614,"spec":false,"focused":false,"pending":false,"labels":[],"nodes":[{"name":"Describe","text":"normal","start":113,"end":233,"spec":false,"focused":false,"pending":false,"labels":[],"nodes":[{"name":"It","text":"normal","start":150,"end":229,"spec":true,"focused":false,"pending":false,"labels":[],"nodes":[{"name":"By","text":"normal","start":182,"end":201,"spec":false,"focused":false,"pending":false,"labels":null,"nodes":[]},{"name":"By","text":"normal","start":205,"end":224,"spec":false,"focused":false,"pending":false,"labels":null,"nodes":[]}]}]},{"name":"Context","text":"normal","start":236,"end":310,"spec":false,"focused":false,"pending":false,"labels":[],"nodes":[{"name":"It","text":"normal","start":272,"end":306,"spec":true,"focused":false,"pending":false,"labels":[],"nodes":[]}]},{"name":"When","text":"normal","start":313,"end":384,"spec":false,"focused":false,"pending":false,"labels":[],"nodes":[{"name":"It","text":"normal","start":346,"end":380,"spec":true,"focused":false,"pending":false,"labels":[],"nodes":[]}]},{"name":"It","text":"normal","start":387,"end":420,"spec":true,"focused":false,"pending":false,"labels":[],"nodes":[]},{"name":"Specify","text":"normal","start":423,"end":461,"spec":true,"focused":false,"pending":false,"labels":[],"nodes":[]},{"name":"DescribeTable","text":"normal","start":464,"end":536,"spec":false,"focused":false,"pending":false,"labels":[],"nodes":[{"name":"Entry","text":"normal","start":510,"end":532,"spec":true,"focused":false,"pending":false,"labels":[],"nodes":[]}]},{"name":"DescribeTable","text":"normal","start":539,"end":611,"spec":false,"focused":false,"pending":false,"labels":[],"nodes":[{"name":"Entry","text":"normal","start":585,"end":607,"spec":true,"focused":false,"pending":false,"labels":[],"nodes":[]}]}]}] diff --git a/ginkgo/outline/ginkgo.go b/ginkgo/outline/ginkgo.go index 958daccbf..5d8d00bb1 100644 --- a/ginkgo/outline/ginkgo.go +++ b/ginkgo/outline/ginkgo.go @@ -1,10 +1,11 @@ package outline import ( - "github.com/onsi/ginkgo/v2/types" "go/ast" "go/token" "strconv" + + "github.com/onsi/ginkgo/v2/types" ) const ( diff --git a/ginkgo/outline/import.go b/ginkgo/outline/import.go index 67ec5ab75..f0a6b5d26 100644 --- a/ginkgo/outline/import.go +++ b/ginkgo/outline/import.go @@ -28,14 +28,7 @@ func packageNameForImport(f *ast.File, path string) *string { } name := spec.Name.String() if name == "" { - // If the package name is not explicitly specified, - // make an educated guess. This is not guaranteed to be correct. - lastSlash := strings.LastIndex(path, "/") - if lastSlash == -1 { - name = path - } else { - name = path[lastSlash+1:] - } + name = "ginkgo" } if name == "." { name = "" From c245d09a1a083f643ad2b91878cf060146cc94e3 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Wed, 17 Jan 2024 15:49:32 -0700 Subject: [PATCH 032/102] emit output of failed go tool cover invocation so users can try to debug things for themselves --- ginkgo/internal/profiles_and_reports.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ginkgo/internal/profiles_and_reports.go b/ginkgo/internal/profiles_and_reports.go index bd3c6d028..26de28b57 100644 --- a/ginkgo/internal/profiles_and_reports.go +++ b/ginkgo/internal/profiles_and_reports.go @@ -144,7 +144,7 @@ func FinalizeProfilesAndReportsForSuites(suites TestSuites, cliConfig types.CLIC return messages, nil } -//loads each profile, combines them, deletes them, stores them in destination +// loads each profile, combines them, deletes them, stores them in destination func MergeAndCleanupCoverProfiles(profiles []string, destination string) error { combined := &bytes.Buffer{} modeRegex := regexp.MustCompile(`^mode: .*\n`) @@ -184,7 +184,7 @@ func GetCoverageFromCoverProfile(profile string) (float64, error) { cmd := exec.Command("go", "tool", "cover", "-func", profile) output, err := cmd.CombinedOutput() if err != nil { - return 0, fmt.Errorf("Could not process Coverprofile %s: %s", profile, err.Error()) + return 0, fmt.Errorf("Could not process Coverprofile %s: %s - %s", profile, err.Error(), string(output)) } re := regexp.MustCompile(`total:\s*\(statements\)\s*(\d*\.\d*)\%`) matches := re.FindStringSubmatch(string(output)) From 7fa019079a7b6cfe92acac92df4a84f2748e45a4 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Wed, 17 Jan 2024 15:54:58 -0700 Subject: [PATCH 033/102] v2.15.0 --- CHANGELOG.md | 18 ++++++++++++++++++ types/version.go | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbe515639..9a65dd10c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +## 2.15.0 + +### Features + +- JUnit reports now interpret Label(owner:X) and set owner to X. [8f3bd70] +- include cancellation reason when cancelling spec context [96e915c] + +### Fixes + +- emit output of failed go tool cover invocation so users can try to debug things for themselves [c245d09] +- fix outline when using nodot in ginkgo v2 [dca77c8] +- Document areas where GinkgoT() behaves differently from testing.T [dbaf18f] +- bugfix(docs): use Unsetenv instead of Clearenv (#1337) [6f67a14] + +### Maintenance + +- Bump to go 1.20 [4fcd0b3] + ## 2.14.0 ### Features diff --git a/types/version.go b/types/version.go index 7015be128..ed9346474 100644 --- a/types/version.go +++ b/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.14.0" +const VERSION = "2.15.0" From 4471b2e6fb4c10b17fa12a8cd9ebec7eaade24b5 Mon Sep 17 00:00:00 2001 From: Austin Cawley-Edwards Date: Wed, 17 Jan 2024 21:05:25 -0500 Subject: [PATCH 034/102] Fix docs for handling failures in goroutines (#1339) * Fix goroutine failure handling docs See: https://github.com/onsi/ginkgo/issues/1114#issuecomment-1372466155 Signed-off-by: austin ce * Correct CSS rules for desktop --------- Signed-off-by: austin ce --- docs/css/layout.css | 4 ++-- docs/index.md | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/css/layout.css b/docs/css/layout.css index bfa7c5e32..6f742a20b 100644 --- a/docs/css/layout.css +++ b/docs/css/layout.css @@ -191,11 +191,11 @@ a:last-of-type .logo { } #left-background { - grid-area; left-background; + grid-area: left-background; } #right-background { - grid-area; right-background; + grid-area: right-background; } #header { diff --git a/docs/index.md b/docs/index.md index c68cc6e17..204c64765 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1202,7 +1202,10 @@ When a failure occurs in a `BeforeEach`, `JustBeforeEach`, or `It` closure Ginkg Ginkgo orchestrates this behavior by rescuing the panic thrown by `Fail` and unwinding the spec. However, if your spec launches a **goroutine** that calls `Fail` (or, equivalently, invokes a failing Gomega assertion), there's no way for Ginkgo to rescue the panic that `Fail` throws. This will cause the suite to panic and no subsequent specs will run. To get around this you must rescue the panic using `defer GinkgoRecover()`. Here's an example: +However, if you block in a test case, Ginkgo will not be able to catch the failure and the case will time out instead. + ```go +/* === INVALID === */ It("panics in a goroutine", func() { var c chan interface{} go func() { @@ -1210,7 +1213,21 @@ It("panics in a goroutine", func() { Fail("boom") close(c) }() - <-c + <-c // Do not block! +}) +``` + +[Asynchronous assertions](https://onsi.github.io/gomega/#making-asynchronous-assertions) can be used to wait for the condition while allowing Ginkgo to abort the case when an async failure occurs. + +```go +It("panics in a goroutine", func() { + done := make(chan struct{}) + go func() { + defer GinkgoRecover() + Fail("boom") + close(c) + }() + Eventually(done).Should(BeClosed()) }) ``` From 23f0cc596f3b58e34169ab4d95e269b3b2ea481c Mon Sep 17 00:00:00 2001 From: myzhan Date: Wed, 24 Jan 2024 11:29:45 +0800 Subject: [PATCH 035/102] merge coverages instead of combining them (#1329) (#1340) * merge coverages instead of combining them (#1329) * add license of gocovmerge --- ginkgo/internal/gocovmerge.go | 129 ++++++++++++++++++++++++ ginkgo/internal/profiles_and_reports.go | 42 +++----- 2 files changed, 144 insertions(+), 27 deletions(-) create mode 100644 ginkgo/internal/gocovmerge.go diff --git a/ginkgo/internal/gocovmerge.go b/ginkgo/internal/gocovmerge.go new file mode 100644 index 000000000..3c5079ff4 --- /dev/null +++ b/ginkgo/internal/gocovmerge.go @@ -0,0 +1,129 @@ +// Copyright (c) 2015, Wade Simmons +// All rights reserved. + +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: + +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. + +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Package gocovmerge takes the results from multiple `go test -coverprofile` +// runs and merges them into one profile + +// this file was originally taken from the gocovmerge project +// see also: https://go.shabbyrobe.org/gocovmerge +package internal + +import ( + "fmt" + "io" + "sort" + + "golang.org/x/tools/cover" +) + +func AddCoverProfile(profiles []*cover.Profile, p *cover.Profile) []*cover.Profile { + i := sort.Search(len(profiles), func(i int) bool { return profiles[i].FileName >= p.FileName }) + if i < len(profiles) && profiles[i].FileName == p.FileName { + MergeCoverProfiles(profiles[i], p) + } else { + profiles = append(profiles, nil) + copy(profiles[i+1:], profiles[i:]) + profiles[i] = p + } + return profiles +} + +func DumpCoverProfiles(profiles []*cover.Profile, out io.Writer) error { + if len(profiles) == 0 { + return nil + } + if _, err := fmt.Fprintf(out, "mode: %s\n", profiles[0].Mode); err != nil { + return err + } + for _, p := range profiles { + for _, b := range p.Blocks { + if _, err := fmt.Fprintf(out, "%s:%d.%d,%d.%d %d %d\n", p.FileName, b.StartLine, b.StartCol, b.EndLine, b.EndCol, b.NumStmt, b.Count); err != nil { + return err + } + } + } + return nil +} + +func MergeCoverProfiles(into *cover.Profile, merge *cover.Profile) error { + if into.Mode != merge.Mode { + return fmt.Errorf("cannot merge profiles with different modes") + } + // Since the blocks are sorted, we can keep track of where the last block + // was inserted and only look at the blocks after that as targets for merge + startIndex := 0 + for _, b := range merge.Blocks { + var err error + startIndex, err = mergeProfileBlock(into, b, startIndex) + if err != nil { + return err + } + } + return nil +} + +func mergeProfileBlock(p *cover.Profile, pb cover.ProfileBlock, startIndex int) (int, error) { + sortFunc := func(i int) bool { + pi := p.Blocks[i+startIndex] + return pi.StartLine >= pb.StartLine && (pi.StartLine != pb.StartLine || pi.StartCol >= pb.StartCol) + } + + i := 0 + if sortFunc(i) != true { + i = sort.Search(len(p.Blocks)-startIndex, sortFunc) + } + + i += startIndex + if i < len(p.Blocks) && p.Blocks[i].StartLine == pb.StartLine && p.Blocks[i].StartCol == pb.StartCol { + if p.Blocks[i].EndLine != pb.EndLine || p.Blocks[i].EndCol != pb.EndCol { + return i, fmt.Errorf("gocovmerge: overlapping merge %v %v %v", p.FileName, p.Blocks[i], pb) + } + switch p.Mode { + case "set": + p.Blocks[i].Count |= pb.Count + case "count", "atomic": + p.Blocks[i].Count += pb.Count + default: + return i, fmt.Errorf("gocovmerge: unsupported covermode '%s'", p.Mode) + } + + } else { + if i > 0 { + pa := p.Blocks[i-1] + if pa.EndLine >= pb.EndLine && (pa.EndLine != pb.EndLine || pa.EndCol > pb.EndCol) { + return i, fmt.Errorf("gocovmerge: overlap before %v %v %v", p.FileName, pa, pb) + } + } + if i < len(p.Blocks)-1 { + pa := p.Blocks[i+1] + if pa.StartLine <= pb.StartLine && (pa.StartLine != pb.StartLine || pa.StartCol < pb.StartCol) { + return i, fmt.Errorf("gocovmerge: overlap after %v %v %v", p.FileName, pa, pb) + } + } + p.Blocks = append(p.Blocks, cover.ProfileBlock{}) + copy(p.Blocks[i+1:], p.Blocks[i:]) + p.Blocks[i] = pb + } + + return i + 1, nil +} diff --git a/ginkgo/internal/profiles_and_reports.go b/ginkgo/internal/profiles_and_reports.go index 26de28b57..5f35864dd 100644 --- a/ginkgo/internal/profiles_and_reports.go +++ b/ginkgo/internal/profiles_and_reports.go @@ -1,7 +1,6 @@ package internal import ( - "bytes" "fmt" "os" "os/exec" @@ -12,6 +11,7 @@ import ( "github.com/google/pprof/profile" "github.com/onsi/ginkgo/v2/reporters" "github.com/onsi/ginkgo/v2/types" + "golang.org/x/tools/cover" ) func AbsPathForGeneratedAsset(assetName string, suite TestSuite, cliConfig types.CLIConfig, process int) string { @@ -144,38 +144,26 @@ func FinalizeProfilesAndReportsForSuites(suites TestSuites, cliConfig types.CLIC return messages, nil } -// loads each profile, combines them, deletes them, stores them in destination +// loads each profile, merges them, deletes them, stores them in destination func MergeAndCleanupCoverProfiles(profiles []string, destination string) error { - combined := &bytes.Buffer{} - modeRegex := regexp.MustCompile(`^mode: .*\n`) - for i, profile := range profiles { - contents, err := os.ReadFile(profile) + var merged []*cover.Profile + for _, file := range profiles { + parsedProfiles, err := cover.ParseProfiles(file) if err != nil { - return fmt.Errorf("Unable to read coverage file %s:\n%s", profile, err.Error()) + return err } - os.Remove(profile) - - // remove the cover mode line from every file - // except the first one - if i > 0 { - contents = modeRegex.ReplaceAll(contents, []byte{}) - } - - _, err = combined.Write(contents) - - // Add a newline to the end of every file if missing. - if err == nil && len(contents) > 0 && contents[len(contents)-1] != '\n' { - _, err = combined.Write([]byte("\n")) - } - - if err != nil { - return fmt.Errorf("Unable to append to coverprofile:\n%s", err.Error()) + os.Remove(file) + for _, p := range parsedProfiles { + merged = AddCoverProfile(merged, p) } } - - err := os.WriteFile(destination, combined.Bytes(), 0666) + dst, err := os.OpenFile(destination, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + return err + } + err = DumpCoverProfiles(merged, dst) if err != nil { - return fmt.Errorf("Unable to create combined cover profile:\n%s", err.Error()) + return err } return nil } From d52951d4a77c7ca901ba606c737b8296f0b3e80e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 10:50:02 +0000 Subject: [PATCH 036/102] Bump github-pages and jekyll-feed in /docs (#1351) Bumps [github-pages](https://github.com/github/pages-gem) and [jekyll-feed](https://github.com/jekyll/jekyll-feed). These dependencies needed to be updated together. Updates `github-pages` from 228 to 229 - [Release notes](https://github.com/github/pages-gem/releases) - [Commits](https://github.com/github/pages-gem/compare/v228...v229) Updates `jekyll-feed` from 0.15.1 to 0.17.0 - [Release notes](https://github.com/jekyll/jekyll-feed/releases) - [Changelog](https://github.com/jekyll/jekyll-feed/blob/master/History.markdown) - [Commits](https://github.com/jekyll/jekyll-feed/compare/v0.15.1...v0.17.0) --- updated-dependencies: - dependency-name: github-pages dependency-type: direct:development update-type: version-update:semver-major - dependency-name: jekyll-feed dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Gemfile | 4 +- docs/Gemfile.lock | 108 +++++++++++++++++++++++----------------------- 2 files changed, 57 insertions(+), 55 deletions(-) diff --git a/docs/Gemfile b/docs/Gemfile index 862d7535f..88f454a6a 100644 --- a/docs/Gemfile +++ b/docs/Gemfile @@ -12,10 +12,10 @@ source "https://rubygems.org" gem "minima", "~> 2.5" # If you want to use GitHub Pages, remove the "gem "jekyll"" above and # uncomment the line below. To upgrade, run `bundle update github-pages`. -gem "github-pages", "~> 228", group: :jekyll_plugins +gem "github-pages", "~> 229", group: :jekyll_plugins # If you have any plugins, put them here! group :jekyll_plugins do - gem "jekyll-feed", "~> 0.12" + gem "jekyll-feed", "~> 0.17" end gem "webrick" diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 93754b08f..09cf58cd2 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -7,48 +7,48 @@ GEM minitest (~> 5.1) tzinfo (~> 1.1) zeitwerk (~> 2.2, >= 2.2.2) - addressable (2.8.1) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) coffee-script (2.4.1) coffee-script-source execjs - coffee-script-source (1.11.1) + coffee-script-source (1.12.2) colorator (1.1.0) commonmarker (0.23.10) - concurrent-ruby (1.2.0) - dnsruby (1.61.9) - simpleidn (~> 0.1) + concurrent-ruby (1.2.3) + dnsruby (1.70.0) + simpleidn (~> 0.2.1) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) ethon (0.16.0) ffi (>= 1.15.0) eventmachine (1.2.7) - execjs (2.8.1) - faraday (2.7.4) - faraday-net_http (>= 2.0, < 3.1) - ruby2_keywords (>= 0.0.4) - faraday-net_http (3.0.2) - ffi (1.15.5) + execjs (2.9.1) + faraday (2.9.0) + faraday-net_http (>= 2.0, < 3.2) + faraday-net_http (3.1.0) + net-http + ffi (1.16.3) forwardable-extended (2.6.0) - gemoji (3.0.1) - github-pages (228) - github-pages-health-check (= 1.17.9) - jekyll (= 3.9.3) - jekyll-avatar (= 0.7.0) - jekyll-coffeescript (= 1.1.1) + gemoji (4.1.0) + github-pages (229) + github-pages-health-check (= 1.18.2) + jekyll (= 3.9.4) + jekyll-avatar (= 0.8.0) + jekyll-coffeescript (= 1.2.2) jekyll-commonmark-ghpages (= 0.4.0) - jekyll-default-layout (= 0.1.4) - jekyll-feed (= 0.15.1) + jekyll-default-layout (= 0.1.5) + jekyll-feed (= 0.17.0) jekyll-gist (= 1.5.0) - jekyll-github-metadata (= 2.13.0) + jekyll-github-metadata (= 2.16.1) jekyll-include-cache (= 0.2.1) jekyll-mentions (= 1.6.0) jekyll-optional-front-matter (= 0.3.2) jekyll-paginate (= 1.1.0) jekyll-readme-index (= 0.3.0) jekyll-redirect-from (= 0.16.0) - jekyll-relative-links (= 0.6.1) + jekyll-relative-links (= 0.7.0) jekyll-remote-theme (= 0.4.3) jekyll-sass-converter (= 1.5.2) jekyll-seo-tag (= 2.8.0) @@ -68,28 +68,28 @@ GEM jekyll-theme-tactile (= 0.2.0) jekyll-theme-time-machine (= 0.2.0) jekyll-titles-from-headings (= 0.5.3) - jemoji (= 0.12.0) - kramdown (= 2.3.2) + jemoji (= 0.13.0) + kramdown (= 2.4.0) kramdown-parser-gfm (= 1.1.0) liquid (= 4.0.4) mercenary (~> 0.3) minima (= 2.5.1) nokogiri (>= 1.13.6, < 2.0) - rouge (= 3.26.0) + rouge (= 3.30.0) terminal-table (~> 1.4) - github-pages-health-check (1.17.9) + github-pages-health-check (1.18.2) addressable (~> 2.3) dnsruby (~> 1.60) - octokit (~> 4.0) - public_suffix (>= 3.0, < 5.0) + octokit (>= 4, < 8) + public_suffix (>= 3.0, < 6.0) typhoeus (~> 1.3) html-pipeline (2.14.3) activesupport (>= 2) nokogiri (>= 1.4) http_parser.rb (0.8.0) - i18n (1.12.0) + i18n (1.14.1) concurrent-ruby (~> 1.0) - jekyll (3.9.3) + jekyll (3.9.4) addressable (~> 2.4) colorator (~> 1.0) em-websocket (~> 0.5) @@ -102,11 +102,11 @@ GEM pathutil (~> 0.9) rouge (>= 1.7, < 4) safe_yaml (~> 1.0) - jekyll-avatar (0.7.0) + jekyll-avatar (0.8.0) jekyll (>= 3.0, < 5.0) - jekyll-coffeescript (1.1.1) + jekyll-coffeescript (1.2.2) coffee-script (~> 2.2) - coffee-script-source (~> 1.11.1) + coffee-script-source (~> 1.12) jekyll-commonmark (1.4.0) commonmarker (~> 0.22) jekyll-commonmark-ghpages (0.4.0) @@ -114,15 +114,15 @@ GEM jekyll (~> 3.9.0) jekyll-commonmark (~> 1.4.0) rouge (>= 2.0, < 5.0) - jekyll-default-layout (0.1.4) - jekyll (~> 3.0) - jekyll-feed (0.15.1) + jekyll-default-layout (0.1.5) + jekyll (>= 3.0, < 5.0) + jekyll-feed (0.17.0) jekyll (>= 3.7, < 5.0) jekyll-gist (1.5.0) octokit (~> 4.2) - jekyll-github-metadata (2.13.0) + jekyll-github-metadata (2.16.1) jekyll (>= 3.4, < 5.0) - octokit (~> 4.0, != 4.4.0) + octokit (>= 4, < 7, != 4.4.0) jekyll-include-cache (0.2.1) jekyll (>= 3.7, < 5.0) jekyll-mentions (1.6.0) @@ -135,7 +135,7 @@ GEM jekyll (>= 3.0, < 5.0) jekyll-redirect-from (0.16.0) jekyll (>= 3.3, < 5.0) - jekyll-relative-links (0.6.1) + jekyll-relative-links (0.7.0) jekyll (>= 3.3, < 5.0) jekyll-remote-theme (0.4.3) addressable (~> 2.0) @@ -193,11 +193,11 @@ GEM jekyll (>= 3.3, < 5.0) jekyll-watch (2.2.1) listen (~> 3.0) - jemoji (0.12.0) - gemoji (~> 3.0) + jemoji (0.13.0) + gemoji (>= 3, < 5) html-pipeline (~> 2.2) jekyll (>= 3.0, < 5.0) - kramdown (2.3.2) + kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) @@ -210,22 +210,23 @@ GEM jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) - minitest (5.17.0) - nokogiri (1.14.3-x86_64-linux) + minitest (5.22.0) + net-http (0.4.1) + uri + nokogiri (1.16.2-x86_64-linux) racc (~> 1.4) octokit (4.25.1) faraday (>= 1, < 3) sawyer (~> 0.9) pathutil (0.16.2) forwardable-extended (~> 2.6) - public_suffix (4.0.7) - racc (1.6.2) + public_suffix (5.0.4) + racc (1.7.3) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - rexml (3.2.5) - rouge (3.26.0) - ruby2_keywords (0.0.5) + rexml (3.2.6) + rouge (3.30.0) rubyzip (2.3.2) safe_yaml (1.0.5) sass (3.7.4) @@ -241,23 +242,24 @@ GEM terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) thread_safe (0.3.6) - typhoeus (1.4.0) + typhoeus (1.4.1) ethon (>= 0.9.0) tzinfo (1.2.10) thread_safe (~> 0.1) unf (0.1.4) unf_ext - unf_ext (0.0.8.2) + unf_ext (0.0.9.1) unicode-display_width (1.8.0) + uri (0.13.0) webrick (1.8.1) - zeitwerk (2.6.6) + zeitwerk (2.6.13) PLATFORMS x86_64-linux DEPENDENCIES - github-pages (~> 228) - jekyll-feed (~> 0.12) + github-pages (~> 229) + jekyll-feed (~> 0.17) minima (~> 2.5) tzinfo (~> 1.2) tzinfo-data From a1e6b69a1cf4057a93fcc54403024eea61e8d00f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 10:51:05 +0000 Subject: [PATCH 037/102] Bump github.com/go-logr/logr from 1.3.0 to 1.4.1 (#1321) Bumps [github.com/go-logr/logr](https://github.com/go-logr/logr) from 1.3.0 to 1.4.1. - [Release notes](https://github.com/go-logr/logr/releases) - [Changelog](https://github.com/go-logr/logr/blob/master/CHANGELOG.md) - [Commits](https://github.com/go-logr/logr/compare/v1.3.0...v1.4.1) --- updated-dependencies: - dependency-name: github.com/go-logr/logr dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9a36d3c88..3acb659d2 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/onsi/ginkgo/v2 go 1.20 require ( - github.com/go-logr/logr v1.3.0 + github.com/go-logr/logr v1.4.1 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 github.com/onsi/gomega v1.30.0 diff --git a/go.sum b/go.sum index f389152e6..11e61aeba 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= From 5a179ed4a43085c76cdf136fbec00b803507336c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 10:52:22 +0000 Subject: [PATCH 038/102] Bump golang.org/x/sys from 0.15.0 to 0.16.0 (#1327) Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.15.0 to 0.16.0. - [Commits](https://github.com/golang/sys/compare/v0.15.0...v0.16.0) --- updated-dependencies: - dependency-name: golang.org/x/sys dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3acb659d2..874ddba80 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 github.com/onsi/gomega v1.30.0 golang.org/x/net v0.19.0 - golang.org/x/sys v0.15.0 + golang.org/x/sys v0.16.0 golang.org/x/tools v0.16.1 ) diff --git a/go.sum b/go.sum index 11e61aeba..154eab248 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= From 17ae120fed9df18efade8149f065bc9d9f2e3a34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 14:15:16 +0000 Subject: [PATCH 039/102] Bump golang.org/x/tools from 0.16.1 to 0.17.0 (#1336) Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.16.1 to 0.17.0. - [Release notes](https://github.com/golang/tools/releases) - [Commits](https://github.com/golang/tools/compare/v0.16.1...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/tools dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 874ddba80..a4adb6692 100644 --- a/go.mod +++ b/go.mod @@ -7,9 +7,9 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 github.com/onsi/gomega v1.30.0 - golang.org/x/net v0.19.0 + golang.org/x/net v0.20.0 golang.org/x/sys v0.16.0 - golang.org/x/tools v0.16.1 + golang.org/x/tools v0.17.0 ) require ( diff --git a/go.sum b/go.sum index 154eab248..58f1a1d5a 100644 --- a/go.sum +++ b/go.sum @@ -24,15 +24,15 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= From 898cba913da007c801c54335eda08caa0f294bce Mon Sep 17 00:00:00 2001 From: George Blue Date: Wed, 7 Feb 2024 16:54:28 +0000 Subject: [PATCH 040/102] chore: test with Go 1.22 (#1352) - Rather than hard-coding the Go version in the workflow, we will use the `stable` and `oldstable` tags which today resolve to 1.22.0 and 1.21.7, but will float as Go versions change. - Some anonymous function names seem to have changed in Go 1.22 and a test had to be modified as a result --- .github/workflows/test.yml | 4 ++-- integration/profiling_go1.21_test.go | 6 ++++++ integration/profiling_go1.22_test.go | 6 ++++++ integration/profiling_test.go | 9 +++++---- 4 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 integration/profiling_go1.21_test.go create mode 100644 integration/profiling_go1.22_test.go diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b5d2ca53e..91e5402dd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,14 +12,14 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: '1.20' + go-version: 'oldstable' - uses: actions/checkout@v4 - run: go mod tidy && git diff --exit-code go.mod go.sum build: runs-on: ubuntu-latest strategy: matrix: - version: [ '1.20', '1.21' ] + version: [ 'oldstable', 'stable' ] name: Go ${{ matrix.version }} steps: - uses: actions/setup-go@v5 diff --git a/integration/profiling_go1.21_test.go b/integration/profiling_go1.21_test.go new file mode 100644 index 000000000..09ec29b51 --- /dev/null +++ b/integration/profiling_go1.21_test.go @@ -0,0 +1,6 @@ +//go:build !go1.22 + +package integration_test + +// lockContestPrefix is the function name prefix with Go 1.21 and earlier +const lockContestPrefix = "lock_contest_test.glob.." diff --git a/integration/profiling_go1.22_test.go b/integration/profiling_go1.22_test.go new file mode 100644 index 000000000..ca8bf191d --- /dev/null +++ b/integration/profiling_go1.22_test.go @@ -0,0 +1,6 @@ +//go:build go1.22 + +package integration_test + +// lockContestPrefix is the function name prefix with Go 1.22 and later +const lockContestPrefix = "lock_contest_test.init." diff --git a/integration/profiling_test.go b/integration/profiling_test.go index ff02b2289..96a9e57c3 100644 --- a/integration/profiling_test.go +++ b/integration/profiling_test.go @@ -252,13 +252,14 @@ var _ = Describe("Profiling Specs", func() { // The MutexProfile for the lock_contest test should list two functions that wait on a lock. // Unfortunately go doesn't seem to capture the names of the functions - so they're listed here as // lock_contest_test.glob..func1.1 is called 10 times and takes ~5ms per call - // lock_contest_test.glob..func2.1 is called once and teakes ~500ms per call + // lock_contest_test.glob..func2.1 is called once and takes ~500ms per call + // Note that in Go 1.22 and later, the functions are called lock_contest_test.init.func1.1 and lock_contest_test.init.func2.1 // Asserting that both times are within a range should be stable across tests. The function names should be as well // but that might become a source of failure in the future // Note: these numbers are adjusted slightly to tolerate variance during test runs - Ω(mutexProfile.FindCaller("lock_contest_test.glob..func1.1").CumStat).Should(BeNumerically(">=", 45)) - Ω(mutexProfile.FindCaller("lock_contest_test.glob..func1.1").CumStat).Should(BeNumerically("<", 500)) - Ω(mutexProfile.FindCaller("lock_contest_test.glob..func2.1").CumStat).Should(BeNumerically(">=", 450)) + Ω(mutexProfile.FindCaller(fmt.Sprintf("%sfunc1.1", lockContestPrefix)).CumStat).Should(BeNumerically(">=", 45)) + Ω(mutexProfile.FindCaller(fmt.Sprintf("%sfunc1.1", lockContestPrefix)).CumStat).Should(BeNumerically("<", 500)) + Ω(mutexProfile.FindCaller(fmt.Sprintf("%sfunc2.1", lockContestPrefix)).CumStat).Should(BeNumerically(">=", 450)) }, Entry("when running in series", From cd418b74c1e8502b305aab84e882516a6335a0e7 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Mon, 12 Feb 2024 09:54:01 -0800 Subject: [PATCH 041/102] core_dsl: disable Getwd() with environment variable (#1357) os.Getwd() calls os.Getenv("PWD"), which can change from run to run if you are using a test suite runner like e.g. Buildkite. Because test caching relies on environment variables being the same from run to run, this facile change breaks test caching. Fixes #1355. --- core_dsl.go | 13 +++- docs/index.md | 195 ++++++++++++++++++++++++++------------------------ 2 files changed, 114 insertions(+), 94 deletions(-) diff --git a/core_dsl.go b/core_dsl.go index 2d7a70ecc..0e633f309 100644 --- a/core_dsl.go +++ b/core_dsl.go @@ -292,7 +292,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...interface{}) bool { err = global.Suite.BuildTree() exitIfErr(err) - suitePath, err := os.Getwd() + suitePath, err := getwd() exitIfErr(err) suitePath, err = filepath.Abs(suitePath) exitIfErr(err) @@ -345,6 +345,15 @@ func extractSuiteConfiguration(args []interface{}) Labels { return suiteLabels } +func getwd() (string, error) { + if !strings.EqualFold(os.Getenv("GINKGO_PRESERVE_CACHE"), "true") { + // Getwd calls os.Getenv("PWD"), which breaks test caching if the cache + // is shared between two different directories with the same test code. + return os.Getwd() + } + return "", nil +} + /* PreviewSpecs walks the testing tree and produces a report without actually invoking the specs. See http://onsi.github.io/ginkgo/#previewing-specs for more information. @@ -369,7 +378,7 @@ func PreviewSpecs(description string, args ...any) Report { err = global.Suite.BuildTree() exitIfErr(err) - suitePath, err := os.Getwd() + suitePath, err := getwd() exitIfErr(err) suitePath, err = filepath.Abs(suitePath) exitIfErr(err) diff --git a/docs/index.md b/docs/index.md index 204c64765..0a64b4211 100644 --- a/docs/index.md +++ b/docs/index.md @@ -57,7 +57,7 @@ go get github.com/onsi/ginkgo/v2 go install github.com/onsi/ginkgo/v2/ginkgo ``` -To pick a particular version: +To pick a particular version: ```bash go get github.com/onsi/ginkgo/v2@v2.m.p @@ -72,7 +72,7 @@ The current version of Ginkgo is guaranteed to be compatible with the currently ### Your First Ginkgo Suite -Ginkgo hooks into Go's existing `testing` infrastructure. That means that Ginkgo specs live in `*_test.go` files, just like standard go tests. However, instead of using `func TestX(t *testing.T) {}` to write your tests you use the Ginkgo and Gomega DSLs. +Ginkgo hooks into Go's existing `testing` infrastructure. That means that Ginkgo specs live in `*_test.go` files, just like standard go tests. However, instead of using `func TestX(t *testing.T) {}` to write your tests you use the Ginkgo and Gomega DSLs. We call a collection of Ginkgo specs in a given package a **Ginkgo suite**; and we use the word **spec** to talk about individual Ginkgo tests contained in the suite. Though they're functionally interchangeable, we'll use the word "spec" instead of "test" to make a distinction between Ginkgo tests and traditional `testing` tests. @@ -375,19 +375,19 @@ var _ = Describe("Books", func() { Describe("Extracting the author's first and last name", func() { Context("When the author has both names", func() { - It("can extract the author's last name", func() { + It("can extract the author's last name", func() { Expect(book.AuthorLastName()).To(Equal("Hugo")) }) It("can extract the author's first name", func() { Expect(book.AuthorFirstName()).To(Equal("Victor")) - }) + }) }) Context("When the author only has one name", func() { BeforeEach(func() { book.Author = "Hugo" - }) + }) It("interprets the single author name as a last name", func() { Expect(book.AuthorLastName()).To(Equal("Hugo")) @@ -423,19 +423,19 @@ var _ = Describe("Books", func() { Describe("Extracting the author's first and last name", func() { Context("When the author has both names", func() { - It("can extract the author's last name", func() { + It("can extract the author's last name", func() { Expect(book.AuthorLastName()).To(Equal("Hugo")) }) It("can extract the author's first name", func() { Expect(book.AuthorFirstName()).To(Equal("Victor")) - }) + }) }) Context("When the author only has one name", func() { BeforeEach(func() { book.Author = "Hugo" - }) + }) It("interprets the single author name as a last name", func() { Expect(book.AuthorLastName()).To(Equal("Hugo")) @@ -449,15 +449,15 @@ var _ = Describe("Books", func() { Context("When the author has a middle name", func() { BeforeEach(func() { book.Author = "Victor Marie Hugo" - }) + }) - It("can extract the author's last name", func() { + It("can extract the author's last name", func() { Expect(book.AuthorLastName()).To(Equal("Hugo")) }) It("can extract the author's first name", func() { Expect(book.AuthorFirstName()).To(Equal("Victor")) - }) + }) }) Context("When the author has no name", func() { @@ -539,7 +539,7 @@ var _ = Describe("Books", func() { It("errors", func() { Expect(err).To(MatchError(books.ErrIncompleteJSON)) }) - }) + }) }) }) }) @@ -547,7 +547,7 @@ var _ = Describe("Books", func() { In this way we can continue to grow our suite while clearly delineating the structure of our specs using a spec tree hierarchy. Note that we use the `When` container variant in this example as it reads cleanly. Remember that `Describe`, `Context`, and `When` are functionally equivalent aliases. -### Mental Model: How Ginkgo Traverses the Spec Hierarchy +### Mental Model: How Ginkgo Traverses the Spec Hierarchy We've delved into the three basic Ginkgo node types: container nodes, setup nodes, and subject nodes. Before we move on let's build a mental model for how Ginkgo traverses and runs specs in a little more detail. @@ -573,7 +573,7 @@ var _ = Describe("Books", func() { Describe("Extracting names", func() { When("author has both names", func() { - It("extracts the last name", func() { + It("extracts the last name", func() { //Closure B Expect(book.AuthorLastName()).To(Equal("Hugo")) }) @@ -581,14 +581,14 @@ var _ = Describe("Books", func() { It("extracts the first name", func() { //Closure C Expect(book.AuthorFirstName()).To(Equal("Victor")) - }) + }) }) When("author has one name", func() { BeforeEach(func() { //Closure D book.Author = "Hugo" - }) + }) It("extracts the last name", func() { //Closure E @@ -682,7 +682,7 @@ Ginkgo will emit a warning if it detects this. #### Avoid Spec Pollution: Don't Initialize Variables in Container Nodes -We've covered this already but it bears repeating: **"Declare in container nodes, initialize in setup nodes"**. Since container nodes are only invoked once during the tree construction phase you should declare closure variables in container nodes but always initialize them in setup nodes. The following is +We've covered this already but it bears repeating: **"Declare in container nodes, initialize in setup nodes"**. Since container nodes are only invoked once during the tree construction phase you should declare closure variables in container nodes but always initialize them in setup nodes. The following is invalid can potentially infuriating to debug: ```go @@ -716,7 +716,7 @@ var _ = Describe("book", func() { Title: "Les Miserables", Author: "Victor Hugo", Pages: 2783, - } + } }) It("is invalid with no author", func() { @@ -777,7 +777,7 @@ Describe("some JSON decoding edge cases", func() { It("errors", func() { Expect(err).To(MatchError(books.ErrIncompleteJSON)) }) - }) + }) }) ``` @@ -803,7 +803,7 @@ Describe("some JSON decoding edge cases", func() { It("errors", func() { Expect(err).To(MatchError(books.ErrIncompleteJSON)) }) - }) + }) }) ``` @@ -840,11 +840,11 @@ Describe("some JSON decoding edge cases", func() { "author":"Victor Hugo", }` }) - + It("errors", func() { Expect(err).To(MatchError(books.ErrIncompleteJSON)) }) - }) + }) }) ``` @@ -886,7 +886,7 @@ Describe("Reporting book weight", func() { Context("when WEIGHT_UNITS is set to oz", func() { BeforeEach(func() { - err := os.Setenv("WEIGHT_UNITS", "oz") + err := os.Setenv("WEIGHT_UNITS", "oz") Expect(err).NotTo(HaveOccurred()) }) @@ -945,7 +945,7 @@ Describe("Reporting book weight", func() { Context("when WEIGHT_UNITS is set to oz", func() { BeforeEach(func() { - err := os.Setenv("WEIGHT_UNITS", "oz") + err := os.Setenv("WEIGHT_UNITS", "oz") Expect(err).NotTo(HaveOccurred()) }) @@ -969,7 +969,7 @@ Describe("Reporting book weight", func() { }) ``` -Now we're guaranteed to clear out `WEIGHT_UNITS` after each spec as Ginkgo will run the `AfterEach` node's closure after the subject node for each spec... +Now we're guaranteed to clear out `WEIGHT_UNITS` after each spec as Ginkgo will run the `AfterEach` node's closure after the subject node for each spec... ...but we've still got a subtle issue. By clearing it out in our `AfterEach` we're assuming that `WEIGHT_UNITS` is not set when the specs run. But perhaps it is? What we really want to do is restore `WEIGHT_UNITS` to its original value. We can solve this by recording the original value first: @@ -1019,7 +1019,7 @@ Describe("Reporting book weight", func() { BeforeEach(func() { ... originalWeightUnits := os.Getenv("WEIGHT_UNITS") - DeferCleanup(func() { + DeferCleanup(func() { err := os.Setenv("WEIGHT_UNITS", originalWeightUnits) Expect(err).NotTo(HaveOccurred()) }) @@ -1043,7 +1043,7 @@ Describe("Reporting book weight", func() { BeforeEach(func() { ... originalWeightUnits := os.Getenv("WEIGHT_UNITS") - DeferCleanup(func() error { + DeferCleanup(func() error { return os.Setenv("WEIGHT_UNITS", originalWeightUnits) }) }) @@ -1198,7 +1198,7 @@ whether in a setup or subject node, whenever `Fail` is called Ginkgo will mark t But there's more. The `Fail` function **panics** when it is called. This allows Ginkgo to stop the current closure in its tracks - no subsequent assertions or code in the closure will run. Ginkgo is quite opinionated about this behavior - if an assertion has failed then the current spec is not in an expected state and subsequent assertions will likely fail. This fast-fail approach is especially useful when running slow complex integration tests. It cannot be disabled. -When a failure occurs in a `BeforeEach`, `JustBeforeEach`, or `It` closure Ginkgo halts execution of the current spec and cleans up by invoking any registered `AfterEach` or `JustAfterEach` closures (and any registered `DeferCleanup` closures if applicable). This is important to ensure the spec state is cleaned up. +When a failure occurs in a `BeforeEach`, `JustBeforeEach`, or `It` closure Ginkgo halts execution of the current spec and cleans up by invoking any registered `AfterEach` or `JustAfterEach` closures (and any registered `DeferCleanup` closures if applicable). This is important to ensure the spec state is cleaned up. Ginkgo orchestrates this behavior by rescuing the panic thrown by `Fail` and unwinding the spec. However, if your spec launches a **goroutine** that calls `Fail` (or, equivalently, invokes a failing Gomega assertion), there's no way for Ginkgo to rescue the panic that `Fail` throws. This will cause the suite to panic and no subsequent specs will run. To get around this you must rescue the panic using `defer GinkgoRecover()`. Here's an example: @@ -1355,7 +1355,7 @@ var _ = Describe("Browsing the library", func() { The string passed to `By` is attached to the spec and can be displayed by Ginkgo when needed. If a test succeeds you won't see any output beyond Ginkgo's green dot. If a test fails, however, you will see each step printed out up to the step immediately preceding the failure. Running with `ginkgo -v` always emits all steps. -`By` takes an optional function of type `func()`. When passed such a function `By` will immediately call the function. This allows you to organize your `It`s into groups of steps. +`By` takes an optional function of type `func()`. When passed such a function `By` will immediately call the function. This allows you to organize your `It`s into groups of steps. `By` doesn't affect the structure of your specs - it's primarily syntactic sugar to help you document long and complex specs. Ginkgo has additional mechanisms to break specs up into more granular subunits with guaranteed ordering - we'll discuss [Ordered containers](#ordered-containers) in detail later. @@ -1432,7 +1432,7 @@ Describe("Extracting the author's first and last name", func() { Expect(book.IsValid()).To(Equal(true)) Expect(book.AuthorFirstName()).To(Equal("Victor")) Expect(book.AuthorLastName()).To(Equal("Hugo")) - }) + }) It("When author has no name", func() { book := &books.Book{ @@ -1443,7 +1443,7 @@ Describe("Extracting the author's first and last name", func() { Expect(book.IsValid()).To(Equal(false)) Expect(book.AuthorFirstName()).To(Equal("")) Expect(book.AuthorLastName()).To(Equal("")) - }) + }) }) ``` @@ -1588,7 +1588,7 @@ var _ = Describe("Math", func() { }, func(a, b, c int) string { return fmt.Sprintf("%d + %d = %d", a, b, c) - } + } Entry(nil, 1, 2, 3), Entry(nil, -1, 2, 1), Entry(nil, 0, 0, 0), @@ -1756,8 +1756,8 @@ Alternatively, you can choose to dot-import only _portions_ of Ginkgo's DSL into ```go import ( - . "github.com/onsi/ginkgo/v2/dsl/core" - "github.com/onsi/ginkgo/v2/dsl/decorators" + . "github.com/onsi/ginkgo/v2/dsl/core" + "github.com/onsi/ginkgo/v2/dsl/decorators" ) var _ = It("gives you the core DSL", decorators.Label("and namespaced decorators"), func() { @@ -1769,7 +1769,7 @@ The available DSL packages are: | Package | Contents | |-------|--------| -| `github.com/onsi/ginkgo/v2/dsl/core` | The core DSL including all container, setup, and subject nodes (`Describe`, `Context`, `BeforeEach`, `BeforeSuite`, `It`, etc...) as well as the most commonly used functions (`RunSpecs`, `Skip`, `Fail`, `By`, `GinkgoT`) | +| `github.com/onsi/ginkgo/v2/dsl/core` | The core DSL including all container, setup, and subject nodes (`Describe`, `Context`, `BeforeEach`, `BeforeSuite`, `It`, etc...) as well as the most commonly used functions (`RunSpecs`, `Skip`, `Fail`, `By`, `GinkgoT`) | | `github.com/onsi/ginkgo/v2/decorators` | The decorator DSL includes all Ginkgo's decorators (e.g. `Label`, `Ordered`, `Serial`, etc...) | | `github.com/onsi/ginkgo/v2/reporting` | The reporting DSL includes all reporting-related nodes and types (e.g. `Report`, `CurrentSpecReport`, `ReportAfterEach`, `AddReportEntry`) | | `github.com/onsi/ginkgo/v2/table` | The table DSL includes all table-related types and functions (e.g. `DescribeTable`, `Entry`, `EntryDescription`) | @@ -1849,7 +1849,7 @@ Describe("Bookmark", func() { Title: "Les Miserables", Author: "Victor Hugo", Pages: 2783, - } + } }) It("has no bookmarks by default", func() { @@ -1948,7 +1948,7 @@ Describe("Bookmark", func() { Title: "Les Miserables", Author: "Victor Hugo", Pages: 2783, - } + } }) It("has no bookmarks by default", func() { @@ -2017,7 +2017,7 @@ Describe("Storing books in an external database", func() { It("can delete the book", func() { Expect(dbClient.Delete(book)).To(Succeed()) - Expect(dbClient.Books()).To(BeEmpty()) + Expect(dbClient.Books()).To(BeEmpty()) }) }) }) @@ -2107,7 +2107,7 @@ var _ = SynchronizedBeforeSuite(func() []byte { var _ = SynchronizedAfterSuite(func() { //runs on *all* processes - Expect(dbClient.Cleanup()).To(Succeed()) + Expect(dbClient.Cleanup()).To(Succeed()) }, func() { //runs *only* on process #1 Expect(dbRunner.Stop()).To(Succeed()) @@ -2179,11 +2179,11 @@ So, if `Serial` is applied to a container like so: ```go Describe("Never in parallel please", Serial, func() { It("tests one behavior", func() { - + }) It("tests another behavior", func() { - + }) }) ``` @@ -2193,11 +2193,11 @@ Then both specs generated by the subject nodes in this container will be marked ```go Describe("Never in parallel please", func() { It("tests one behavior", func() { - + }) It("tests another behavior", Serial, func() { - + }) }) ``` @@ -2357,7 +2357,7 @@ As always, you can also use `DeferCleanup`. Since `DeferCleanup` is context awa ```go BeforeAll(func() { libraryClient = library.NewClient() - Expect(libraryClient.Connect()).To(Succeed()) + Expect(libraryClient.Connect()).To(Succeed()) DeferCleanup(libraryClient.Disconnect) }) ``` @@ -2542,7 +2542,7 @@ now only the second spec will run because of Ginkgo's focus rules. We refer to the focus filtering mechanism as "Programmatic Focus" as the focus declarations are "programmed in" at compile time. Programmatic focus can be super helpful when developing or debugging a test suite, however it can be a real pain to accidentally commit a focused spec. So... -When Ginkgo detects that a passing test suite has programmatically focused tests it causes the suite to exit with a non-zero status code. The logs will show that the suite succeeded, but will also include a message that says that programmatic specs were detected. The non-zero exit code will be caught by most CI systems and flagged, allowing developers to go back and unfocus the specs they committed. +When Ginkgo detects that a passing test suite has programmatically focused tests it causes the suite to exit with a non-zero status code. The logs will show that the suite succeeded, but will also include a message that says that programmatic specs were detected. The non-zero exit code will be caught by most CI systems and flagged, allowing developers to go back and unfocus the specs they committed. You can unfocus _all_ specs in a suite by running `ginkgo unfocus`. This simply strips off any `F`s off of `FDescribe`, `FContext`, `FIt`, etc... and removes `Focus` decorators. @@ -2565,19 +2565,19 @@ Describe("Storing books", Label("integration", "storage"), func() { }) It("cannot delete books from the central library", Label("network", "library storage"), func() { - // has labels [integration, storage, network, library storage] + // has labels [integration, storage, network, library storage] }) It("can check if a book is stored in the central library", Label("network", "slow", "library query"), func() { - // has labels [integration, storage, network, slow, library query] + // has labels [integration, storage, network, slow, library query] }) It("can save books locally", Label("local"), func() { - // has labels [integration, storage, local] + // has labels [integration, storage, local] }) It("can delete books locally", Label("local"), func() { - // has labels [integration, storage, local] + // has labels [integration, storage, local] }) }) ``` @@ -2656,7 +2656,7 @@ When these flags are provided Ginkgo matches the passed-in regular expression ag Describe("Studying books", func() { Context("when the book is long", func() { It("can be read over multiple sessions", func() { - + }) }) }) @@ -2770,7 +2770,7 @@ Ginkgo can provide a **Progress Report** of what is currently running in respons These Progress Reports can also show you a preview of the running source code, but only if Ginkgo can find your source files. If need be you can tell Ginkgo where to look for source files by specifying `--source-root`. -Finally - you can instruct Ginkgo to provide Progress Reports automatically whenever a node takes too long to complete. You do this by passing the `--poll-progress-after=INTERVAL` flag to specify how long Ginkgo should wait before emitting a progress report. Once this interval is passed Ginkgo can periodically emit Progress Reports - the interval between these reports is controlled via the `--poll-progress-interval=INTERVAL` flag. By default `--poll-progress-after` is set to `0` and so Ginkgo does not emit Progress Reports. +Finally - you can instruct Ginkgo to provide Progress Reports automatically whenever a node takes too long to complete. You do this by passing the `--poll-progress-after=INTERVAL` flag to specify how long Ginkgo should wait before emitting a progress report. Once this interval is passed Ginkgo can periodically emit Progress Reports - the interval between these reports is controlled via the `--poll-progress-interval=INTERVAL` flag. By default `--poll-progress-after` is set to `0` and so Ginkgo does not emit Progress Reports. You can override the global setting of `poll-progess-after` and `poll-progress-interval` on a per-node basis by using the `PollProgressAfter(INTERVAL)` and `PollProgressInterval(INTERVAL)` decorators. A value of `0` will explicitly turn off Progress Reports for a given node regardless of the global setting. @@ -2796,7 +2796,7 @@ AttachProgressReporter(func() string { ```go BeforeEach(func() { library = libraryClient.ConnectAs("Jean ValJean") - + //we attach a progress reporter and can trust that it will be cleaned up after the spec runs DeferCleanup(AttachProgressReporter(func() string { libraryState := library.GetStatusReport() @@ -2958,7 +2958,7 @@ now, if any of the node contexts are cancelled (either due to a timeout or an in Eventually(func() ([]*books.Book, error) { return libraryClient.ListBooksByAuthor(ctx, "Victor Hugo") }).WithContext(ctx).Should(ContainElement(book)) -``` +``` This is important as the cancellation of the context needs to cause `ListBooksByAuthor` to exit _and_ `Eventually` to stop retrying. This is a common-enough pattern that Gomega provides some short hand. If you pass `Eventually` a function that takes a `context.Context` as its first parameter, Gomega will pass in the context attached via `.WithContext()` automatically. This allows us to turn statements like this: @@ -2979,12 +2979,12 @@ This also works well with Gomega's `.WithArguments(...)` method which allows us Eventually(func() ([]*books.Book, error) { return libraryClient.ListBooksByAuthor(ctx, "Victor Hugo") }).WithContext(ctx).Should(ContainElement(book)) -``` +``` into: ```go Eventually(libraryClient.ListBooksByAuthor).WithContext(ctx).WithArguments("Victor Hugo").Should(ContainElement(book)) -``` +``` all told this allows us to rewrite our example as: @@ -3192,7 +3192,7 @@ The heuristic here is simple: if the function passed to `DeferCleanup` takes a ` `DescribeTable` behaves similarly. You can make the `It`s generated by your table interruptible by passing a `SpecContext` or `context.Context` as the first argument to the table function: ```go -DescribeTable("shelf counts", +DescribeTable("shelf counts", func(ctx SpecContext, shelf string, count int) { // or context.Context instead Expect(libraryClient.Count(ctx, shelf)).To(Equal(count)) }, @@ -3208,7 +3208,7 @@ If you also want to specify a [custom entry description generator](#generating-e ```go -DescribeTable("shelf counts", +DescribeTable("shelf counts", func(ctx SpecContext, shelf string, count int) { // or context.Context instead Expect(libraryClient.Count(ctx, shelf)).To(Equal(count)) }, @@ -3224,7 +3224,7 @@ DescribeTable("shelf counts", As with `DeferCleanup`, Ginkgo will detect if the entry parameter list provides a context. Doing so will avoid treating the function as interruptible and use the provided context instead. For example: ```go -DescribeTable("contrived context-value example", +DescribeTable("contrived context-value example", func(ctx context.Context, result string) { //but **NOT** SpecContext Expect(libraryClient.Encabulate(ctx)).To(Equal(result)) }, @@ -3242,7 +3242,7 @@ While users of Ginkgo can provide their own custom progress reporters the intent ### Interrupting, Aborting, and Timing Out Suites -We've seen how nodes can be marked as interruptible and focused on how Ginkgo can apply deadlines to individual nodes and interrupt them when a timeout expires. Ginkgo also provides a few, related, mechanisms for interrupting a _suite_ before all specs have naturally completed. +We've seen how nodes can be marked as interruptible and focused on how Ginkgo can apply deadlines to individual nodes and interrupt them when a timeout expires. Ginkgo also provides a few, related, mechanisms for interrupting a _suite_ before all specs have naturally completed. First, you can signal to a suite that it must stop running by sending a `SIGINT` or `SIGTERM` signal to the running ginkgo process (or just hit `^C`). @@ -3400,7 +3400,7 @@ The resulting JSON file encodes an array of `types.Report`. Each entry in that When possible, we recommend building tooling on top of Ginkgo's JSON format and using Ginkgo's `types` package directly to access the suite and spec reports. The structs in the package include several helper functions to interpret the report. -Ginkgo also supports generating JUnit reports with +Ginkgo also supports generating JUnit reports with ```bash ginkgo --junit-report=report.xml @@ -3450,7 +3450,7 @@ Describe("Manipulating books at the central library", func() { It("can fetch a specific book", func() { book, err := libraryClient.FetchBook("Les Miserables") Expect(err).NotTo(HaveOccurred()) - Expect(book.AuthorLastName()).To(Equal("Hugo")) + Expect(book.AuthorLastName()).To(Equal("Hugo")) }) It("can update a book", func() { @@ -3587,7 +3587,7 @@ If you pass multiple arguments of the same type (e.g. two `Offset`s), the last a `type Timestamp time.Time` #### Controlling Output -By default, Ginkgo's console reporter will emit any `ReportEntry` attached to a spec. It will emit the `ReportEntry` name, location, and time. If the `ReportEntry` value is non-nil it will also emit a representation of the value. If the value implements `fmt.Stringer` or `types.ColorableStringer` then `value.String()` or `value.ColorableString()` (which takes precedence) is used to generate the representation, otherwise Ginkgo uses `fmt.Sprintf("%#v", value)`. +By default, Ginkgo's console reporter will emit any `ReportEntry` attached to a spec. It will emit the `ReportEntry` name, location, and time. If the `ReportEntry` value is non-nil it will also emit a representation of the value. If the value implements `fmt.Stringer` or `types.ColorableStringer` then `value.String()` or `value.ColorableString()` (which takes precedence) is used to generate the representation, otherwise Ginkgo uses `fmt.Sprintf("%#v", value)`. You can modify this default behavior by passing in one of the `ReportEntryVisibility` enum to `AddReportEntry`: @@ -3714,7 +3714,7 @@ var _ = BeforeSuite(func() { Expect(os.Getenv("SMOKETEST_SERVER_ADDR")).NotTo(BeZero(), "Please make sure SMOKETEST_SERVER_ADDR is set correctly.") Expect(os.Getenv("SMOKETEST_ENV")).To(Or(Equal("PRODUCTION"), Equal("STAGING")), "SMOKETEST_ENV must be set to PRODUCTION or STAGING.") - //set up a client + //set up a client client = client.NewClient(os.Getenv("SMOKETEST_SERVER_ADDR")) }) @@ -3789,7 +3789,7 @@ var _ = BeforeSuite(func() { Expect(serverAddr).NotTo(BeZero(), "Please make sure --server-addr is set correctly.") Expect(smokeEnv).To(Or(Equal("PRODUCTION"), Equal("STAGING")), "--environment must be set to PRODUCTION or STAGING.") - //set up a client + //set up a client client = client.NewClient(serverAddr) }) @@ -3942,7 +3942,7 @@ func TestSmokeTest(t *testing.T) { suiteConfig.LabelFilter = smokeEnv } else { // if the user has specified a label-filter we extend it: - suiteConfig.LabelFilter = "(" + suiteConfig.LabelFilter + ") && " + smokeEnv + suiteConfig.LabelFilter = "(" + suiteConfig.LabelFilter + ") && " + smokeEnv } // finally, we pass the modified configuration in to RunSpecs @@ -3999,7 +3999,7 @@ Describe("Storing and retrieving books by category", func() { } Expect(library.Store(book)).To(Succeed()) DeferCleanup(library.Delete, book) - Expect(library.FindByCategory(category)).To(ContainElement(book)) + Expect(library.FindByCategory(category)).To(ContainElement(book)) }) } }) @@ -4028,7 +4028,7 @@ Describe("Storing and retrieving the book fixtures", func() { It(fmt.Sprintf("can store and retrieve %s", book.Title), func() { Expect(library.Store(book)).To(Succeed()) DeferCleanup(library.Delete, book) - Expect(library.FindByTitle(book.Title)).To(Equal(book)) + Expect(library.FindByTitle(book.Title)).To(Equal(book)) }) } }) @@ -4058,14 +4058,14 @@ Describe("Storing and retrieving the book fixtures", func() { It(fmt.Sprintf("can store and retrieve %s", book.Title), func() { Expect(library.Store(book)).To(Succeed()) DeferCleanup(library.Delete, book) - Expect(library.FindByTitle(book.Title)).To(Equal(book)) + Expect(library.FindByTitle(book.Title)).To(Equal(book)) }) } }) ``` ### Shared Behaviors -It's common to want to extract subsets of spec behavior for reuse - these are typically called "Shared Behaviors". +It's common to want to extract subsets of spec behavior for reuse - these are typically called "Shared Behaviors". It is often the case that within a particular suite there will be a number of different `Context`s that assert the exact same behavior, in that they have identical `It`s within them. The only difference between these `Context`s is the set up done in their respective `BeforeEach`s. Rather than repeat the `It`s for these `Context`s, you can extract the code into a shared-scope closure and avoid repeating yourself. For example: @@ -4130,12 +4130,12 @@ Describe("Storing books in the library", func() { }) AssertFailedBehavior() - }) + }) }) }) ``` -Since `AssertFailedBehavior` is defined in the same stack of closures as the other nodes, it has access to the shared `book` variable. Note that the `AssertFailedBehavior` function is called within the body of the `Context` container block. This will happen during The Tree Construction phase and result in a spec tree that includes the `It`s defined in the `AssertFailedBehavior` function for each context. +Since `AssertFailedBehavior` is defined in the same stack of closures as the other nodes, it has access to the shared `book` variable. Note that the `AssertFailedBehavior` function is called within the body of the `Context` container block. This will happen during The Tree Construction phase and result in a spec tree that includes the `It`s defined in the `AssertFailedBehavior` function for each context. ### Table Specs Patterns @@ -4188,8 +4188,8 @@ DescribeTable("Repaginating Books", Expect(book.RecomputePages()).To(BeNumerically("~", expectedPages, 30)) }, func(formatting BookFormatting, expectedPages int) string { - return fmt.Sprintf("FontSize: %d, LineHeight: %.2f, Page:%.2fx%.2f => %d", - formatting.fontSize, formatting.lineHeight, + return fmt.Sprintf("FontSize: %d, LineHeight: %.2f, Page:%.2fx%.2f => %d", + formatting.fontSize, formatting.lineHeight, formatting.pageWidth, formatting.pageHeight, expectedPages) } @@ -4257,7 +4257,7 @@ Both `Eventually` and `Consistently` perform asynchronous assertions by polling In the case of `Consistently`, Gomega polls the input repeatedly and asserts the matcher is satisfied every time. `Consistently` only exits early if a failure occurs - otherwise it continues polling until the specified interval elapses. This is often the only way to assert that something "does not happen" in an asynchronous system. -`Eventually` and `Consistently` can accept three types of input. You can pass in bare values and assert that some aspect of the value changes eventually. This is most commonly done with Go channels or Gomega's +`Eventually` and `Consistently` can accept three types of input. You can pass in bare values and assert that some aspect of the value changes eventually. This is most commonly done with Go channels or Gomega's [`gbytes`](https://onsi.github.io/gomega/#gbytes-testing-streaming-buffers) and [`gexec`](https://onsi.github.io/gomega/#gexec-testing-external-processes) packages. You can also pass in functions and assert that their return values `Eventually` or `Consistently` satisfy a matcher - we'll cover those later. Lastly, you can pass in functions that take a `Gomega` argument - these allow you to make assertions within the function and are a way to assert that a series of assertions _eventually_ succeeds. We'll cover _that_ later as well. Let's look at these various input types through the lens of some concrete use-cases. #### Testing an in-process Asynchronous Service. @@ -4273,7 +4273,7 @@ Describe("Publishing books", func() { It("can publish a book, emitting information as it goes", func(ctx SpecContext) { buffer := gbytes.NewBuffer() //gbytes provides a thread-safe buffer that works with the `gbytes.Say` matcher - + // we begin publishing the book. This kicks off a goroutine and returns a channel // Publish takes a `context.Context` and so we pass in our `ctx` to clean up correctly in case the spec timeout elapses c := publisher.Publish(ctx, book, buffer) @@ -4317,7 +4317,7 @@ BeforeSuite(func() { var err error publisherPath, err = gexec.Build("path/to/publisher") Expect(err).NotTo(HaveOccurred()) - DeferCleanup(gexec.CleanupBuildArtifacts) + DeferCleanup(gexec.CleanupBuildArtifacts) }) Describe("Publishing books", func() { @@ -4325,7 +4325,7 @@ Describe("Publishing books", func() { //First, we create a command to invoke the publisher and pass appropriate args cmd := exec.CommandContext(ctx, publisherPath, "-o=les-miserables.epub", "les-miserables.fixture") - //Now we launch the command with `gexec`. This returns a session that wraps the running command. + //Now we launch the command with `gexec`. This returns a session that wraps the running command. //We also tell `gexec` to tee any stdout/stderr output from the process to `GinkgoWriter` - this will //ensure we get all the process output if the spec fails. session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) @@ -4339,7 +4339,7 @@ Describe("Publishing books", func() { Eventually(ctx, session).Should(gbytes.Say(`Published page 2782/2783`)) Eventually(ctx, session).Should(gbytes.Say(`Publish complete!`)) - //We can also assert the session has exited + //We can also assert the session has exited Eventually(ctx, session).WithTimeout(time.Second).Should(gexec.Exit(0)) //with exit code 0 //At this point we should have the `les-miserables.epub` artifact @@ -4366,7 +4366,7 @@ Describe("Change book font-size", func() { book = loadBookWithContent("les_miserables.fixture") Expect(book).NotTo(BeNil()) }) - + It("can repaginate books without losing any content", func() { done := make(chan interface{}) go func() { @@ -4388,7 +4388,7 @@ Describe("Change book font-size", func() { // now we wait for the `done` channel to close. Note that we neither pass in a context nor set an explicit timeout // in this case `Eventually` `will use Gomega's default global timeout (1 second, unless overriden by the user) Eventually(done).Should(BeClosed()) - }) + }) }) ``` @@ -4402,7 +4402,7 @@ Describe("Change book font-size", func() { book = loadBookWithContent("les_miserables.fixture") Expect(book).NotTo(BeNil()) }) - + It("can repaginate books without losing any content", func(ctx SpecContext) { content := book.RawContent() Expect(book.Pages).To(Equal(2783)) @@ -4413,7 +4413,7 @@ Describe("Change book font-size", func() { Expect(book.Pages).To(BeNumerically(">", 2783)) Expect(book.RawContent()).To(Equal(content)) - }, SpecTimeout(time.Second)) + }, SpecTimeout(time.Second)) }) ``` @@ -4444,14 +4444,14 @@ var _ = Describe("Getting notifications about holds", func() { } Expect(library.Store(ctx, book)).To(Succeed()) - // we'll want to delete the book after the spec ends. `library` has a `Delete` function with signature `Delete(context.Context, *book.Book)`. + // we'll want to delete the book after the spec ends. `library` has a `Delete` function with signature `Delete(context.Context, *book.Book)`. // DeferCleanup will detect this signature and automatically pass a `SpecContext` (configured with a one second timeout thanks to the `NodeTimeout` decorator) // in as the first parameter. `book` will be passed in as the second parameter. DeferCleanup(library.Delete, book, NodeTimeout(time.Second)) sarah = user.NewUser(ctx, "Sarah", "integration-test-account+sarah@gmail.com") jane = user.NewUser(ctx, "Jane", "integration-test-account+jane@gmail.com") - + By("Sarah checks the book out") Expect(sarah.CheckOut(ctx, library, book)).To(Succeed()) }, NodeTimeout(time.Second*10)) @@ -4582,11 +4582,11 @@ BeforeSuite(func() { var err error publisherPath, err = gexec.Build("path/to/publisher") Expect(err).NotTo(HaveOccurred()) - DeferCleanup(gexec.CleanupBuildArtifacts) + DeferCleanup(gexec.CleanupBuildArtifacts) }) ``` -This code will work fine in parallel as well (under the hood `gexec.Build` places build artifacts in a randomly-generated temporary directory - this is why you need to call `gexec.CleanupBuildArtifacts` to clean +This code will work fine in parallel as well (under the hood `gexec.Build` places build artifacts in a randomly-generated temporary directory - this is why you need to call `gexec.CleanupBuildArtifacts` to clean up); but it's inefficient and all your parallel processes will spend time up front compiling multiple copies of the same binary. Instead, we can use `SynchronizedBeforeSuite` to perform the compilation step just once: ```go @@ -4622,7 +4622,7 @@ Describe("Publishing books", func() { Expect(result.EpubPages).To(Equal(2783)) }, SpecTimeout(time.Second*30)) - It("can publish a preview that contains just the first chapter", func(ctx SpecContext) { + It("can publish a preview that contains just the first chapter", func(ctx SpecContext) { cmd := exec.CommandContext(ctx, publisherPath, "-o=out.epub", "--preview", "les-miserables.fixture") session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) @@ -4648,7 +4648,7 @@ Describe("Publishing books", func() { ... }) - It("can publish a preview that contains just the first chapter", func(ctx SpecContext) { + It("can publish a preview that contains just the first chapter", func(ctx SpecContext) { cmd := exec.CommandContext(ctx, publisherPath, "-o=preview.epub", "--preview", "les-miserables.fixture") ... }) @@ -5036,7 +5036,7 @@ Expect(book).To(BeAValidBook(Author("Victor Hugo"))) Expect(book).To(BeAValidBook(Title("Les Miserables"), Pages(2783))) ``` -The failure messages generated by composed matchers are generally good enough to capture the reason for the failure. However if you want more fine-control over the message, or if you want more complex logic in your matcher you can use [`gcustom`](https://onsi.github.io/gomega/#gcustom-a-convenient-mechanism-for-buildling-custom-matchers) to build custom matchers using a simple function and templates - to learn more check out the [`gucstom` docs](https://onsi.github.io/gomega/#gcustom-a-convenient-mechanism-for-buildling-custom-matchers) and [godoc](https://pkg.go.dev/github.com/onsi/gomega/gcustom). +The failure messages generated by composed matchers are generally good enough to capture the reason for the failure. However if you want more fine-control over the message, or if you want more complex logic in your matcher you can use [`gcustom`](https://onsi.github.io/gomega/#gcustom-a-convenient-mechanism-for-buildling-custom-matchers) to build custom matchers using a simple function and templates - to learn more check out the [`gucstom` docs](https://onsi.github.io/gomega/#gcustom-a-convenient-mechanism-for-buildling-custom-matchers) and [godoc](https://pkg.go.dev/github.com/onsi/gomega/gcustom). ## Decorator Reference We've seen a number of Decorators detailed throughout this documentation. This reference collects them all in one place. @@ -5050,7 +5050,7 @@ func It(text string, args ...interface{}) func BeforeEach(args ...interface{}) ``` -Ginkgo will vet the passed in decorators and exit with a clear error message if it detects any invalid configurations. +Ginkgo will vet the passed in decorators and exit with a clear error message if it detects any invalid configurations. Moreover, Ginkgo also supports passing in arbitrarily nested slices of decorators. Ginkgo will unroll these slices and process the flattened list. This makes it easier to pass around groups of decorators. For example, this is valid: @@ -5326,7 +5326,7 @@ Since the `ginkgo` CLI is a [necessary component when running specs in parallel] ginkgo -p ./path/to/suite.test ``` -As with the rest of the go tool chain, you can cross-compile and target different platforms using the standard `GOOS` and `GOARCH` environment variables. For example: +As with the rest of the go tool chain, you can cross-compile and target different platforms using the standard `GOOS` and `GOARCH` environment variables. For example: ```bash GOOS=linux GOARCH=amd64 ginkgo build path/to/package @@ -5365,7 +5365,7 @@ will generate a file named `PACKAGE_suite_test.go` and ginkgo generate ``` -will generate a file named `SUBJECT_test.go` (or `PACKAGE_test.go` if `` is not provided). Both generators support custom templates using `--template` +will generate a file named `SUBJECT_test.go` (or `PACKAGE_test.go` if `` is not provided). Both generators support custom templates using `--template` and the option to provide extra custom data to be rendered into the template, besides the default values, using `--template-data`. The custom data should be a well structured JSON file. When loaded into the template the custom data will be available to access from the global key `.CustomData`. For example, with a JSON file ```json @@ -5509,6 +5509,17 @@ There are a set of [completions](https://github.com/onsi/ginkgo-sublime-completi IDE authors can set the `GINKGO_EDITOR_INTEGRATION` environment variable to any non-empty value to enable coverage to be displayed for focused specs. By default, Ginkgo will fail with a non-zero exit code if specs are focused to ensure they do not pass in CI. +#### Working directory + +Ginkgo calls os.Getwd() to get the current directory for display in several +reporters. os.Getwd() calls os.Getenv("PWD"), which can change from run to run +if you are using a test suite runner like e.g. Buildkite. Because test caching +relies on environment variables being the same from run to run, this facile +change can break test caching. + +Set the `GINKGO_PRESERVE_CACHE` environment variable to `true` in order to +skip the `os.Getwd()` call. This may affect the reporter output. + ### The ginkgolinter The [ginkgolinter](https://github.com/nunnatsa/ginkgolinter) enforces several patterns of using ginkgo and gomega. It can run as an independent executable or as part of the [golangci-lint](https://golangci-lint.run/) linter. See the ginkgolinter [READMY](https://github.com/nunnatsa/ginkgolinter#readme) for more details. From 9c771cd687800da7a9a6c65c0e447127e6a90548 Mon Sep 17 00:00:00 2001 From: Eugene Nosenko Date: Wed, 24 Jan 2024 14:19:56 +0100 Subject: [PATCH 042/102] Add SpecContext to ReportAfterSuite callback body. --- internal/node.go | 8 ++++++-- internal/node_test.go | 4 ++-- internal/suite.go | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/internal/node.go b/internal/node.go index 16f0dc227..6699b030a 100644 --- a/internal/node.go +++ b/internal/node.go @@ -45,7 +45,7 @@ type Node struct { SynchronizedAfterSuiteProc1BodyHasContext bool ReportEachBody func(types.SpecReport) - ReportSuiteBody func(types.Report) + ReportSuiteBody func(SpecContext, types.Report) MarkedFocus bool MarkedPending bool @@ -333,7 +333,11 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy } } else if nodeType.Is(types.NodeTypeReportBeforeSuite | types.NodeTypeReportAfterSuite) { if node.ReportSuiteBody == nil { - node.ReportSuiteBody = arg.(func(types.Report)) + if fn, ok := arg.(func(types.Report)); ok { + node.ReportSuiteBody = func(_ SpecContext, r types.Report) { fn(r) } + } else { + node.ReportSuiteBody = arg.(func(SpecContext, types.Report)) + } } else { appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType)) trackedFunctionError = true diff --git a/internal/node_test.go b/internal/node_test.go index a26d16919..05641a65c 100644 --- a/internal/node_test.go +++ b/internal/node_test.go @@ -861,7 +861,7 @@ var _ = Describe("Node", func() { Ω(node.ID).Should(BeNumerically(">", 0)) Ω(node.NodeType).Should(Equal(types.NodeTypeReportAfterSuite)) - node.ReportSuiteBody(types.Report{}) + node.ReportSuiteBody(internal.NewSpecContext(nil), types.Report{}) Ω(didRun).Should(BeTrue()) Ω(node.CodeLocation).Should(Equal(cl)) @@ -885,7 +885,7 @@ var _ = Describe("Node", func() { Ω(node.ID).Should(BeNumerically(">", 0)) Ω(node.NodeType).Should(Equal(types.NodeTypeReportBeforeSuite)) - node.ReportSuiteBody(types.Report{}) + node.ReportSuiteBody(internal.NewSpecContext(nil), types.Report{}) Ω(didRun).Should(BeTrue()) Ω(node.CodeLocation).Should(Equal(cl)) diff --git a/internal/suite.go b/internal/suite.go index 2b4db48af..44b531ffd 100644 --- a/internal/suite.go +++ b/internal/suite.go @@ -762,7 +762,7 @@ func (suite *Suite) runReportSuiteNode(node Node, report types.Report) { report = report.Add(aggregatedReport) } - node.Body = func(SpecContext) { node.ReportSuiteBody(report) } + node.Body = func(ctx SpecContext) { node.ReportSuiteBody(ctx, report) } suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "") suite.currentSpecReport.EndTime = time.Now() From 5ff9d7fafb94f34fa83fbbc29132d1ef60890e19 Mon Sep 17 00:00:00 2001 From: Eugene Nosenko Date: Sun, 25 Feb 2024 06:46:15 +0100 Subject: [PATCH 043/102] Add SpecContext to ReportAfterSuite callback body. --- .../internal_integration/report_suite_test.go | 46 ++++++++++++++++--- internal/node.go | 4 +- reporting_dsl.go | 20 ++++++-- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/internal/internal_integration/report_suite_test.go b/internal/internal_integration/report_suite_test.go index 0c09da03a..4702e7936 100644 --- a/internal/internal_integration/report_suite_test.go +++ b/internal/internal_integration/report_suite_test.go @@ -11,12 +11,13 @@ import ( ) var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite nodes", func() { - var failInReportBeforeSuiteA, failInReportAfterSuiteA, interruptSuiteB bool + var failInReportBeforeSuiteA, failInReportAfterSuiteA, timeoutInReportAfterSuiteC, interruptSuiteB bool var fixture func() BeforeEach(func() { failInReportBeforeSuiteA = false failInReportAfterSuiteA = false + timeoutInReportAfterSuiteC = false interruptSuiteB = false conf.RandomSeed = 17 fixture = func() { @@ -61,6 +62,19 @@ var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite node writer.Print("gw-report-after-suite-B") outputInterceptor.AppendInterceptedOutput("out-report-after-suite-B") }) + ReportAfterSuite("Report C", func(ctx SpecContext, report Report) { + timeout := 200 * time.Millisecond + if timeoutInReportAfterSuiteC { + timeout = timeout + 1*time.Second + } + rt.RunWithData("report-after-suite-C", "report", report) + writer.Print("gw-report-after-suite-C") + outputInterceptor.AppendInterceptedOutput("out-report-after-suite-C") + select { + case <-ctx.Done(): + case <-time.After(timeout): + } + }, NodeTimeout(500*time.Millisecond)) AfterSuite(rt.T("after-suite", func() { writer.Print("gw-after-suite") F("fail in after-suite") @@ -87,7 +101,7 @@ var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite node "before-suite", "A", "B", "C", "after-suite", - "report-after-suite-A", "report-after-suite-B", + "report-after-suite-A", "report-after-suite-B", "report-after-suite-C", )) }) @@ -159,7 +173,7 @@ var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite node It("doesn't run any specs - just reporting functions", func() { Ω(rt).Should(HaveTracked( "report-before-suite-A", "report-before-suite-B", - "report-after-suite-A", "report-after-suite-B", + "report-after-suite-A", "report-after-suite-B", "report-after-suite-C", )) }) @@ -176,6 +190,23 @@ var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite node }) }) + Context("when a ReportAfterSuiteContext times out", func() { + BeforeEach(func() { + timeoutInReportAfterSuiteC = true + success, _ := RunFixture("report-after-suite-C-timed-out", fixture) + Ω(success).Should(BeFalse()) + }) + + It("reports on the failure, to Ginkgo's reporter and any subsequent reporters", func() { + Ω(reporter.Did.Find("Report C")).Should(HaveTimedOut( + types.NodeTypeReportAfterSuite, + "A node timeout occurred", + CapturedGinkgoWriterOutput("gw-report-after-suite-C"), + CapturedStdOutput("out-report-after-suite-C"), + )) + }) + }) + Context("when a ReportAfterSuite node fails", func() { BeforeEach(func() { failInReportAfterSuiteA = true @@ -189,7 +220,7 @@ var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite node "before-suite", "A", "B", "C", "after-suite", - "report-after-suite-A", "report-after-suite-B", + "report-after-suite-A", "report-after-suite-B", "report-after-suite-C", )) }) @@ -220,6 +251,7 @@ var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite node "A", "B", "C", "after-suite", "report-after-suite-A", + "report-after-suite-C", )) }) }) @@ -259,7 +291,7 @@ var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite node "before-suite", "A", "B", "C", "after-suite", - "report-after-suite-A", "report-after-suite-B", + "report-after-suite-A", "report-after-suite-B", "report-after-suite-C", )) }) @@ -309,7 +341,7 @@ var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite node Context("when a non-primary proc disappears before it reports", func() { BeforeEach(func() { - close(exitChannels[2]) //proc 2 disappears before reporting + close(exitChannels[2]) // proc 2 disappears before reporting success, _ := RunFixture("disappearing-proc-2", fixture) Ω(success).Should(BeFalse()) }) @@ -342,7 +374,7 @@ var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite node It("only runs the reporting nodes", func() { Ω(rt).Should(HaveTracked( "report-before-suite-A", "report-before-suite-B", - "report-after-suite-A", "report-after-suite-B", + "report-after-suite-A", "report-after-suite-B", "report-after-suite-C", )) }) diff --git a/internal/node.go b/internal/node.go index 6699b030a..5fe3b024f 100644 --- a/internal/node.go +++ b/internal/node.go @@ -5,9 +5,8 @@ import ( "fmt" "reflect" "sort" - "time" - "sync" + "time" "github.com/onsi/ginkgo/v2/types" ) @@ -337,6 +336,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy node.ReportSuiteBody = func(_ SpecContext, r types.Report) { fn(r) } } else { node.ReportSuiteBody = arg.(func(SpecContext, types.Report)) + node.HasContext = true } } else { appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType)) diff --git a/reporting_dsl.go b/reporting_dsl.go index f33786a2d..3447c2ecf 100644 --- a/reporting_dsl.go +++ b/reporting_dsl.go @@ -120,10 +120,22 @@ func ReportBeforeSuite(body func(Report), args ...interface{}) bool { } /* -ReportAfterSuite nodes are run at the end of the suite. ReportAfterSuite nodes take a function that receives a suite Report. +ReportAfterSuite nodes are run at the end of the suite. ReportAfterSuite nodes execute at the suite's conclusion, +accepting a function that can either receives Report or both SpecContext and Report for interruptible behavior. + +Example Usage: + + ReportAfterSuite("Non-interruptible ReportAfterSuite", func(r Report) { }) + ReportAfterSuite("Interruptible ReportAfterSuite", func(ctx SpecContext, r Report) { }) + +These nodes must be placed at the top-level of your test suite, ensuring they're not nested within Context, Describe, or When nodes, to maintain clear, hierarchical test structures. + +In parallel test execution, Ginkgo ensures a singular ReportAfterSuite node runs, aggregating reports across all nodes for consistency. + +ReportAfterSuite supports generating detailed suite reports programmatically and via CLI flags (--json-report, --junit-report, and --teamcity-report) for various report formats. However, nesting other Ginkgo nodes within ReportAfterSuite's closure is not permitted. They are called at the end of the suite, after all specs have run and any AfterSuite or SynchronizedAfterSuite nodes, and are passed in the final report for the suite. -ReportAftersuite nodes must be created at the top-level (i.e. not nested in a Context/Describe/When node) +ReportAfterSuite nodes must be created at the top-level (i.e. not nested in a Context/Describe/When node) When running in parallel, Ginkgo ensures that only one of the parallel nodes runs the ReportAfterSuite and that it is passed a report that is aggregated across all parallel nodes @@ -134,8 +146,10 @@ You cannot nest any other Ginkgo nodes within a ReportAfterSuite node's closure. You can learn more about ReportAfterSuite here: https://onsi.github.io/ginkgo/#generating-reports-programmatically You can learn more about Ginkgo's reporting infrastructure, including generating reports with the CLI here: https://onsi.github.io/ginkgo/#generating-machine-readable-reports + +You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes */ -func ReportAfterSuite(text string, body func(Report), args ...interface{}) bool { +func ReportAfterSuite(text string, body any, args ...interface{}) bool { combinedArgs := []interface{}{body} combinedArgs = append(combinedArgs, args...) return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterSuite, text, combinedArgs...)) From fed9402d63e0871b76dc390a18e3fa23d8428e92 Mon Sep 17 00:00:00 2001 From: Eugene Nosenko Date: Sun, 25 Feb 2024 06:46:47 +0100 Subject: [PATCH 044/102] update documentation. --- docs/index.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 0a64b4211..7552bf23b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3098,7 +3098,9 @@ SynchronizedBeforeSuite(func(ctx SpecContext) []byte { ``` are all valid interruptible signatures. Of course you can specify `context.Context` instead and can mix-and-match interruptibility between the two functions. -Currently the **Reporting** nodes (`ReportAfterEach`, `ReportAfterSuite`, and `ReportBeforeEach`) cannot be made interruptible and do not accept callbacks that receive a `SpecContext`. This may change in a future release of Ginkgo (in a backward compatible way). +Currently only `ReportAfterSuite` node can be made interruptible, to do this you need to provide it a node function which accepts both `SpecContext` and `Report`. +The remaining **Reporting** nodes (`ReportAfterEach`, and `ReportBeforeEach`) are not interruptible and do not accept callbacks that receive a `SpecContext`. +This may change in a future release of Ginkgo (in a backward compatible way). As for **Container** nodes, since these run during the Tree Construction Phase they cannot be made interruptible and so do not accept functions that expect a context. And since the `By` annotation is simply syntactic sugar enabling more detailed spec documentation, any callbacks passed to `By` cannot be independently marked as interruptible (you should, instead, use the `context` passed into the node that you're calling `By` from). @@ -3532,7 +3534,9 @@ ReportAfterEach(func(report SpecReport) { you'll end up with multiple processes writing to the same file and the output will be a mess. There is a better approach for this usecase... #### Reporting Nodes - ReportBeforeSuite and ReportAfterSuite -`ReportBeforeSuite` and `ReportAfterSuite` nodes behave similarly to `BeforeSuite` and `AfterSuite` and can be placed at the top-level of your suite (typically in the suite bootstrap file). `ReportBeforeSuite` and `ReportAfterSuite` nodes take a closure that accepts a single [`Report`]((https://pkg.go.dev/github.com/onsi/ginkgo/v2/types#Report)) argument: +`ReportBeforeSuite` and `ReportAfterSuite` nodes behave similarly to `BeforeSuite` and `AfterSuite` and can be placed at the top-level of your suite (typically in the suite bootstrap file). +`ReportBeforeSuite` node take a closure that accepts a single [`Report`]((https://pkg.go.dev/github.com/onsi/ginkgo/v2/types#Report)) argument, `ReportAfterSuite` can accept either +closer that accepts `Report` or, both `SpecContext` and `Report` converting the node to an interruptible node. ```go var _ = ReportBeforeSuite(func(report Report) { @@ -3542,6 +3546,10 @@ var _ = ReportBeforeSuite(func(report Report) { var _ = ReportAfterSuite("custom report", func(report Report) { // process report }) + +var _ = ReportAfterSuite("interruptible ReportAfterSuite", func(ctx SpecContext, report Report) { + // process report +}, NodeTimeout(10 * time.Minutes)) ``` `Report` contains all available information about the suite. For `ReportAfterSuite` this will include individual `SpecReport` entries for each spec that ran in the suite, and the overall status of the suite (whether it passed or failed). Since `ReportBeforeSuite` runs before the suite starts - it does not contain any spec reports, however the count of the number of specs that _will_ be run can be extracted from `report.PreRunStats.SpecsThatWillBeRun`. From fd929c6e27e6b53886f2d76525c97f9f130cb560 Mon Sep 17 00:00:00 2001 From: Eugene Nosenko Date: Sun, 25 Feb 2024 06:48:35 +0100 Subject: [PATCH 045/102] update test description --- internal/internal_integration/report_suite_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/internal_integration/report_suite_test.go b/internal/internal_integration/report_suite_test.go index 4702e7936..c2ff026ad 100644 --- a/internal/internal_integration/report_suite_test.go +++ b/internal/internal_integration/report_suite_test.go @@ -190,7 +190,7 @@ var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite node }) }) - Context("when a ReportAfterSuiteContext times out", func() { + Context("when a ReportAfterSuite times out", func() { BeforeEach(func() { timeoutInReportAfterSuiteC = true success, _ := RunFixture("report-after-suite-C-timed-out", fixture) From 372d26a2c9cfda920b52f6230cdd2d94f1cdec2e Mon Sep 17 00:00:00 2001 From: Eugene Nosenko Date: Sun, 25 Feb 2024 06:53:25 +0100 Subject: [PATCH 046/102] update docs --- reporting_dsl.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/reporting_dsl.go b/reporting_dsl.go index 3447c2ecf..2eb79ea32 100644 --- a/reporting_dsl.go +++ b/reporting_dsl.go @@ -128,12 +128,6 @@ Example Usage: ReportAfterSuite("Non-interruptible ReportAfterSuite", func(r Report) { }) ReportAfterSuite("Interruptible ReportAfterSuite", func(ctx SpecContext, r Report) { }) -These nodes must be placed at the top-level of your test suite, ensuring they're not nested within Context, Describe, or When nodes, to maintain clear, hierarchical test structures. - -In parallel test execution, Ginkgo ensures a singular ReportAfterSuite node runs, aggregating reports across all nodes for consistency. - -ReportAfterSuite supports generating detailed suite reports programmatically and via CLI flags (--json-report, --junit-report, and --teamcity-report) for various report formats. However, nesting other Ginkgo nodes within ReportAfterSuite's closure is not permitted. - They are called at the end of the suite, after all specs have run and any AfterSuite or SynchronizedAfterSuite nodes, and are passed in the final report for the suite. ReportAfterSuite nodes must be created at the top-level (i.e. not nested in a Context/Describe/When node) From 06de43198fea28d265ee93530424252028f30181 Mon Sep 17 00:00:00 2001 From: Eugene Nosenko Date: Sun, 25 Feb 2024 09:19:27 +0100 Subject: [PATCH 047/102] fix docs --- docs/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 7552bf23b..19fcf4691 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3535,8 +3535,7 @@ you'll end up with multiple processes writing to the same file and the output wi #### Reporting Nodes - ReportBeforeSuite and ReportAfterSuite `ReportBeforeSuite` and `ReportAfterSuite` nodes behave similarly to `BeforeSuite` and `AfterSuite` and can be placed at the top-level of your suite (typically in the suite bootstrap file). -`ReportBeforeSuite` node take a closure that accepts a single [`Report`]((https://pkg.go.dev/github.com/onsi/ginkgo/v2/types#Report)) argument, `ReportAfterSuite` can accept either -closer that accepts `Report` or, both `SpecContext` and `Report` converting the node to an interruptible node. +`ReportBeforeSuite` node take a closure that accepts either [`Report`]((https://pkg.go.dev/github.com/onsi/ginkgo/v2/types#Report)) or, both `SpecContext` and `Report` converting the node to an interruptible node. ```go var _ = ReportBeforeSuite(func(report Report) { From c4e219ff5f317e6f0b78e30c2554088ee3ea2f92 Mon Sep 17 00:00:00 2001 From: Eugene Nosenko Date: Mon, 26 Feb 2024 09:25:13 +0100 Subject: [PATCH 048/102] add SpecContext to other reporting nodes and update tests --- .../internal_integration/report_each_test.go | 22 ++++++-- .../internal_integration/report_suite_test.go | 36 +++++++++++-- internal/node.go | 21 +++++--- internal/node_test.go | 8 +-- internal/suite.go | 12 ++--- reporting_dsl.go | 51 +++++++++++++++---- 6 files changed, 113 insertions(+), 37 deletions(-) diff --git a/internal/internal_integration/report_each_test.go b/internal/internal_integration/report_each_test.go index 1fff7cf3e..3456772e2 100644 --- a/internal/internal_integration/report_each_test.go +++ b/internal/internal_integration/report_each_test.go @@ -98,6 +98,17 @@ var _ = Describe("Sending reports to ReportBeforeEach and ReportAfterEach nodes" reports["interrupt"] = append(reports["interrupt"], report) }) }) + Context("when a after each reporter times out", func() { + It("passes", rt.T("passes")) + ReportAfterEach(func(ctx SpecContext, report types.SpecReport) { + select { + case <-ctx.Done(): + rt.Run("timeout-reporter") + reports["timeout"] = append(reports["timeout"], report) + case <-time.After(100 * time.Millisecond): + } + }, NodeTimeout(10*time.Millisecond)) + }) }) ReportBeforeEach(func(report types.SpecReport) { rt.Run("outer-RBE") @@ -114,15 +125,16 @@ var _ = Describe("Sending reports to ReportBeforeEach and ReportAfterEach nodes" "outer-RBE", "inner-RBE", "passes", "inner-RAE", "outer-RAE", "outer-RBE", "inner-RBE", "fails", "inner-RAE", "outer-RAE", "outer-RBE", "inner-RBE", "panics", "inner-RAE", "outer-RAE", - "outer-RBE", "inner-RBE", "inner-RAE", "outer-RAE", //pending test + "outer-RBE", "inner-RBE", "inner-RAE", "outer-RAE", // pending test "outer-RBE", "inner-RBE", "skipped", "inner-RAE", "outer-RAE", - "outer-RBE", "inner-RBE", "inner-RAE", "outer-RAE", //flag-skipped test + "outer-RBE", "inner-RBE", "inner-RAE", "outer-RAE", // flag-skipped test "outer-RBE", "inner-RBE", "also-passes", "failing-RAE", "inner-RAE", "outer-RAE", - "outer-RBE", "inner-RBE", "failing-in-skip-RAE", "inner-RAE", "outer-RAE", //is also flag-skipped + "outer-RBE", "inner-RBE", "failing-in-skip-RAE", "inner-RAE", "outer-RAE", // is also flag-skipped "outer-RBE", "inner-RBE", "writer", "writing-reporter", "inner-RAE", "outer-RAE", "outer-RBE", "inner-RBE", "failing-RBE", "not-failing-RBE", "inner-RAE", "outer-RAE", "outer-RBE", "inner-RBE", "passes-yet-again", "inner-RAE", "outer-RAE", - "outer-RBE", "inner-RBE", "interrupt-reporter", "inner-RAE", "outer-RAE", //skipped by interrupt + "outer-RBE", "inner-RBE", "interrupt-reporter", "inner-RAE", "outer-RAE", // skipped by interrupt + "outer-RBE", "inner-RBE", "timeout-reporter", "inner-RAE", "outer-RAE", // skipped by timeout "after-suite", )) }) @@ -191,7 +203,7 @@ var _ = Describe("Sending reports to ReportBeforeEach and ReportAfterEach nodes" Ω(reports["inner-RAE"].Find("writes stuff").CapturedGinkgoWriterOutput).Should(Equal("GinkgoWriter from It\nGinkgoWriter from ReportAfterEach\n")) Ω(reports["inner-RAE"].Find("writes stuff").CapturedStdOutErr).Should(Equal("Output from It\nOutput from ReportAfterEach\n")) - //but a report containing the additional output will be send to Ginkgo's reporter... + // but a report containing the additional output will be send to Ginkgo's reporter... Ω(reporter.Did.Find("writes stuff").CapturedGinkgoWriterOutput).Should((Equal("GinkgoWriter from It\nGinkgoWriter from ReportAfterEach\n"))) Ω(reporter.Did.Find("writes stuff").CapturedStdOutErr).Should((Equal("Output from It\nOutput from ReportAfterEach\n"))) }) diff --git a/internal/internal_integration/report_suite_test.go b/internal/internal_integration/report_suite_test.go index c2ff026ad..a724bd6a9 100644 --- a/internal/internal_integration/report_suite_test.go +++ b/internal/internal_integration/report_suite_test.go @@ -11,11 +11,12 @@ import ( ) var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite nodes", func() { - var failInReportBeforeSuiteA, failInReportAfterSuiteA, timeoutInReportAfterSuiteC, interruptSuiteB bool + var failInReportBeforeSuiteA, timeoutInReportBeforeSuiteB, failInReportAfterSuiteA, timeoutInReportAfterSuiteC, interruptSuiteB bool var fixture func() BeforeEach(func() { failInReportBeforeSuiteA = false + timeoutInReportBeforeSuiteB = false failInReportAfterSuiteA = false timeoutInReportAfterSuiteC = false interruptSuiteB = false @@ -32,11 +33,20 @@ var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite node F("fail in report-before-suite-A") } }) - ReportBeforeSuite(func(report Report) { + ReportBeforeSuite(func(ctx SpecContext, report Report) { + timeout := 200 * time.Millisecond + if timeoutInReportBeforeSuiteB { + timeout = timeout + 1*time.Second + } rt.RunWithData("report-before-suite-B", "report", report) writer.Print("gw-report-before-suite-B") - outputInterceptor.AppendInterceptedOutput("out-report-before-suite-B") - }) + select { + case <-ctx.Done(): + outputInterceptor.AppendInterceptedOutput("timeout-report-before-suite-B") + case <-time.After(timeout): + outputInterceptor.AppendInterceptedOutput("out-report-before-suite-B") + } + }, NodeTimeout(500*time.Millisecond)) Context("container", func() { It("A", rt.T("A")) It("B", rt.T("B", func() { @@ -190,6 +200,24 @@ var _ = Describe("Sending reports to ReportBeforeSuite and ReportAfterSuite node }) }) + Context("when a ReportBeforeSuite times out", func() { + BeforeEach(func() { + timeoutInReportBeforeSuiteB = true + success, _ := RunFixture("report-before-suite-B-timed-out", fixture) + Ω(success).Should(BeFalse()) + }) + + It("reports on the failure, to Ginkgo's reporter and any subsequent reporters", func() { + Ω(reporter.Did.WithLeafNodeType(types.NodeTypeReportBeforeSuite).WithState(types.SpecStateTimedout)). + Should(ContainElement(HaveTimedOut( + types.NodeTypeReportBeforeSuite, + "A node timeout occurred", + CapturedGinkgoWriterOutput("gw-report-before-suite-B"), + CapturedStdOutput("timeout-report-before-suite-B"), + ))) + }) + }) + Context("when a ReportAfterSuite times out", func() { BeforeEach(func() { timeoutInReportAfterSuiteC = true diff --git a/internal/node.go b/internal/node.go index 5fe3b024f..6a15f19ae 100644 --- a/internal/node.go +++ b/internal/node.go @@ -15,8 +15,8 @@ var _global_node_id_counter = uint(0) var _global_id_mutex = &sync.Mutex{} func UniqueNodeID() uint { - //There's a reace in the internal integration tests if we don't make - //accessing _global_node_id_counter safe across goroutines. + // There's a reace in the internal integration tests if we don't make + // accessing _global_node_id_counter safe across goroutines. _global_id_mutex.Lock() defer _global_id_mutex.Unlock() _global_node_id_counter += 1 @@ -43,7 +43,7 @@ type Node struct { SynchronizedAfterSuiteProc1Body func(SpecContext) SynchronizedAfterSuiteProc1BodyHasContext bool - ReportEachBody func(types.SpecReport) + ReportEachBody func(SpecContext, types.SpecReport) ReportSuiteBody func(SpecContext, types.Report) MarkedFocus bool @@ -208,7 +208,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy args = unrollInterfaceSlice(args) remainingArgs := []interface{}{} - //First get the CodeLocation up-to-date + // First get the CodeLocation up-to-date for _, arg := range args { switch v := arg.(type) { case Offset: @@ -224,11 +224,11 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy trackedFunctionError := false args = remainingArgs remainingArgs = []interface{}{} - //now process the rest of the args + // now process the rest of the args for _, arg := range args { switch t := reflect.TypeOf(arg); { case t == reflect.TypeOf(float64(0)): - break //ignore deprecated timeouts + break // ignore deprecated timeouts case t == reflect.TypeOf(Focus): node.MarkedFocus = bool(arg.(focusType)) if !nodeType.Is(types.NodeTypesForContainerAndIt) { @@ -324,7 +324,12 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy node.Body = func(SpecContext) { body() } } else if nodeType.Is(types.NodeTypeReportBeforeEach | types.NodeTypeReportAfterEach) { if node.ReportEachBody == nil { - node.ReportEachBody = arg.(func(types.SpecReport)) + if fn, ok := arg.(func(types.SpecReport)); ok { + node.ReportEachBody = func(_ SpecContext, r types.SpecReport) { fn(r) } + } else { + node.ReportEachBody = arg.(func(SpecContext, types.SpecReport)) + node.HasContext = true + } } else { appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType)) trackedFunctionError = true @@ -399,7 +404,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy } } - //validations + // validations if node.MarkedPending && node.MarkedFocus { appendError(types.GinkgoErrors.InvalidDeclarationOfFocusedAndPending(node.CodeLocation, nodeType)) } diff --git a/internal/node_test.go b/internal/node_test.go index 05641a65c..8d98e316f 100644 --- a/internal/node_test.go +++ b/internal/node_test.go @@ -142,7 +142,7 @@ var _ = Describe("Constructing nodes", func() { Ω(node.ID).Should(BeNumerically(">", 0)) Ω(node.NodeType).Should(Equal(types.NodeTypeReportBeforeEach)) - node.ReportEachBody(types.SpecReport{}) + node.ReportEachBody(internal.NewSpecContext(nil), types.SpecReport{}) Ω(didRun).Should(BeTrue()) Ω(node.Body).Should(BeNil()) @@ -162,7 +162,7 @@ var _ = Describe("Constructing nodes", func() { Ω(node.ID).Should(BeNumerically(">", 0)) Ω(node.NodeType).Should(Equal(types.NodeTypeReportAfterEach)) - node.ReportEachBody(types.SpecReport{}) + node.ReportEachBody(internal.NewSpecContext(nil), types.SpecReport{}) Ω(didRun).Should(BeTrue()) Ω(node.Body).Should(BeNil()) @@ -196,7 +196,7 @@ var _ = Describe("Constructing nodes", func() { cl := types.NewCodeLocation(2) cl2 := types.NewCustomCodeLocation("hi") node, errors := internal.NewNode(dt, ntIt, "text", body, cl2, Offset(1)) - //note that Offset overrides cl2 + // note that Offset overrides cl2 Ω(node.CodeLocation.FileName).Should(Equal(cl.FileName)) ExpectAllWell(errors) }) @@ -655,7 +655,7 @@ var _ = Describe("Constructing nodes", func() { }) var _ = Describe("Node", func() { - //HERE - and all the fun edge cases + // HERE - and all the fun edge cases Describe("The nodes that take more specific functions", func() { var dt *types.DeprecationTracker BeforeEach(func() { diff --git a/internal/suite.go b/internal/suite.go index 44b531ffd..a994ee3d6 100644 --- a/internal/suite.go +++ b/internal/suite.go @@ -594,8 +594,8 @@ func (suite *Suite) reportEach(spec Spec, nodeType types.NodeType) { suite.writer.Truncate() suite.outputInterceptor.StartInterceptingOutput() report := suite.currentSpecReport - nodes[i].Body = func(SpecContext) { - nodes[i].ReportEachBody(report) + nodes[i].Body = func(ctx SpecContext) { + nodes[i].ReportEachBody(ctx, report) } state, failure := suite.runNode(nodes[i], time.Time{}, spec.Nodes.BestTextFor(nodes[i])) @@ -840,7 +840,7 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ timeoutInPlay = "node" } 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 + // 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) timeoutInPlay = "node" @@ -918,9 +918,9 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ if outcomeFromRun != types.SpecStatePassed { additionalFailure := types.AdditionalFailure{ State: outcomeFromRun, - Failure: failure, //we make a copy - this will include all the configuration set up above... + Failure: failure, // we make a copy - this will include all the configuration set up above... } - //...and then we update the failure with the details from failureFromRun + // ...and then we update the failure with the details from failureFromRun additionalFailure.Failure.Location, additionalFailure.Failure.ForwardedPanic, additionalFailure.Failure.TimelineLocation = failureFromRun.Location, failureFromRun.ForwardedPanic, failureFromRun.TimelineLocation additionalFailure.Failure.ProgressReport = types.ProgressReport{} if outcome == types.SpecStateTimedout { @@ -959,7 +959,7 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ // 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(fmt.Errorf("%s timeout occurred", timeoutInPlay)) - //and now we wait for the grace period + // and now we wait for the grace period gracePeriodChannel = time.After(gracePeriod) case <-interruptStatus.Channel: interruptStatus = suite.interruptHandler.Status() diff --git a/reporting_dsl.go b/reporting_dsl.go index 2eb79ea32..aa1a35176 100644 --- a/reporting_dsl.go +++ b/reporting_dsl.go @@ -74,12 +74,21 @@ func AddReportEntry(name string, args ...interface{}) { /* ReportBeforeEach nodes are run for each spec, even if the spec is skipped or pending. ReportBeforeEach nodes take a function that -receives a SpecReport. They are called before the spec starts. +receives a SpecReport or both SpecContext and Report for interruptible behavior. They are called before the spec starts. + +Example: + + ReportBeforeEach(func(report SpecReport) { // process report }) + ReportBeforeEach(func(ctx SpecContext, report SpecReport) { + // process report + }), NodeTimeout(1 * time.Minute)) You cannot nest any other Ginkgo nodes within a ReportBeforeEach node's closure. You can learn more about ReportBeforeEach here: https://onsi.github.io/ginkgo/#generating-reports-programmatically + +You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes */ -func ReportBeforeEach(body func(SpecReport), args ...interface{}) bool { +func ReportBeforeEach(body any, args ...any) bool { combinedArgs := []interface{}{body} combinedArgs = append(combinedArgs, args...) @@ -87,13 +96,23 @@ func ReportBeforeEach(body func(SpecReport), args ...interface{}) bool { } /* -ReportAfterEach nodes are run for each spec, even if the spec is skipped or pending. ReportAfterEach nodes take a function that -receives a SpecReport. They are called after the spec has completed and receive the final report for the spec. +ReportAfterEach nodes are run for each spec, even if the spec is skipped or pending. +ReportAfterEach nodes take a function that receives a SpecReport or both SpecContext and Report for interruptible behavior. +They are called after the spec has completed and receive the final report for the spec. + +Example: + + ReportAfterEach(func(report SpecReport) { // process report }) + ReportAfterEach(func(ctx SpecContext, report SpecReport) { + // process report + }), NodeTimeout(1 * time.Minute)) You cannot nest any other Ginkgo nodes within a ReportAfterEach node's closure. You can learn more about ReportAfterEach here: https://onsi.github.io/ginkgo/#generating-reports-programmatically + +You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes */ -func ReportAfterEach(body func(SpecReport), args ...interface{}) bool { +func ReportAfterEach(body any, args ...any) bool { combinedArgs := []interface{}{body} combinedArgs = append(combinedArgs, args...) @@ -101,7 +120,15 @@ func ReportAfterEach(body func(SpecReport), args ...interface{}) bool { } /* -ReportBeforeSuite nodes are run at the beginning of the suite. ReportBeforeSuite nodes take a function that receives a suite Report. +ReportBeforeSuite nodes are run at the beginning of the suite. ReportBeforeSuite nodes take a function +that can either receive Report or both SpecContext and Report for interruptible behavior. + +Example Usage: + + ReportBeforeSuite(func(r Report) { // process report }) + ReportBeforeSuite(func(ctx SpecContext, r Report) { + // process report + }, NodeTimeout(1 * time.Minute)) They are called at the beginning of the suite, before any specs have run and any BeforeSuite or SynchronizedBeforeSuite nodes, and are passed in the initial report for the suite. ReportBeforeSuite nodes must be created at the top-level (i.e. not nested in a Context/Describe/When node) @@ -112,8 +139,10 @@ You cannot nest any other Ginkgo nodes within a ReportAfterSuite node's closure. You can learn more about ReportAfterSuite here: https://onsi.github.io/ginkgo/#generating-reports-programmatically You can learn more about Ginkgo's reporting infrastructure, including generating reports with the CLI here: https://onsi.github.io/ginkgo/#generating-machine-readable-reports + +You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes */ -func ReportBeforeSuite(body func(Report), args ...interface{}) bool { +func ReportBeforeSuite(body any, args ...any) bool { combinedArgs := []interface{}{body} combinedArgs = append(combinedArgs, args...) return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportBeforeSuite, "", combinedArgs...)) @@ -121,12 +150,14 @@ func ReportBeforeSuite(body func(Report), args ...interface{}) bool { /* ReportAfterSuite nodes are run at the end of the suite. ReportAfterSuite nodes execute at the suite's conclusion, -accepting a function that can either receives Report or both SpecContext and Report for interruptible behavior. +and accept a function that can either receive Report or both SpecContext and Report for interruptible behavior. Example Usage: - ReportAfterSuite("Non-interruptible ReportAfterSuite", func(r Report) { }) - ReportAfterSuite("Interruptible ReportAfterSuite", func(ctx SpecContext, r Report) { }) + ReportAfterSuite("Non-interruptible ReportAfterSuite", func(r Report) { // process report }) + ReportAfterSuite("Interruptible ReportAfterSuite", func(ctx SpecContext, r Report) { + // process report + }, NodeTimeout(1 * time.Minute)) They are called at the end of the suite, after all specs have run and any AfterSuite or SynchronizedAfterSuite nodes, and are passed in the final report for the suite. ReportAfterSuite nodes must be created at the top-level (i.e. not nested in a Context/Describe/When node) From 881efde71ccc44d0d2ebc02f3641941e143a1c1d Mon Sep 17 00:00:00 2001 From: Eugene Nosenko Date: Mon, 26 Feb 2024 09:25:37 +0100 Subject: [PATCH 049/102] update documentation to reflect changes to reporting nodes --- docs/index.md | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/docs/index.md b/docs/index.md index 19fcf4691..5435a2e3f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3098,9 +3098,8 @@ SynchronizedBeforeSuite(func(ctx SpecContext) []byte { ``` are all valid interruptible signatures. Of course you can specify `context.Context` instead and can mix-and-match interruptibility between the two functions. -Currently only `ReportAfterSuite` node can be made interruptible, to do this you need to provide it a node function which accepts both `SpecContext` and `Report`. -The remaining **Reporting** nodes (`ReportAfterEach`, and `ReportBeforeEach`) are not interruptible and do not accept callbacks that receive a `SpecContext`. -This may change in a future release of Ginkgo (in a backward compatible way). +**Reporting** nodes `ReportAfterEach`, `ReportBeforeEach`, `ReportBeforeSuite` `ReportAfterSuite` can be made interruptible, +to do this you need to provide it a node function which accepts both `SpecContext` and `SpecReport` for `*Each` nodes and `Report` for `*Suite` nodes. As for **Container** nodes, since these run during the Tree Construction Phase they cannot be made interruptible and so do not accept functions that expect a context. And since the `By` annotation is simply syntactic sugar enabling more detailed spec documentation, any callbacks passed to `By` cannot be independently marked as interruptible (you should, instead, use the `context` passed into the node that you're calling `By` from). @@ -3500,22 +3499,30 @@ Ginkgo's reporting infrastructure provides an alternative solution for this use #### Reporting Nodes - ReportAfterEach and ReportBeforeEach -Ginkgo provides three reporting-focused nodes `ReportAfterEach`, `ReportAfterSuite`, and `ReportBeforeEach`. +Ginkgo provides four reporting-focused nodes `ReportAfterEach`, `ReportBeforeEach` `ReportBeforeSuite`, and `ReportAfterSuite`. -`ReportAfterEach` behaves similarly to a standard `AfterEach` node and can be declared anywhere an `AfterEach` node can be declared. `ReportAfterEach` takes a closure that accepts a single [`SpecReport`](https://pkg.go.dev/github.com/onsi/ginkgo/v2/types#SpecReport) argument. For example, we could implement a top-level ReportAfterEach that emits information about every spec to a remote server: +`ReportAfterEach` behaves similarly to a standard `AfterEach` node and can be declared anywhere an `AfterEach` node can be declared. +`ReportAfterEach` can take either a closure that accepts a single [`SpecReport`](https://pkg.go.dev/github.com/onsi/ginkgo/v2/types#SpecReport) argument or both `SpecContext` and `SpecReport` +For example, we could implement a top-level ReportAfterEach that emits information about every spec to a remote server: ```go ReportAfterEach(func(report SpecReport) { customFormat := fmt.Sprintf("%s | %s", report.State, report.FullText()) client.SendReport(customFormat) }) +// interruptible ReportAfterEach node +ReportAfterEach(func(ctx SpecContext, report SpecReport) { + customFormat := fmt.Sprintf("%s | %s", report.State, report.FullText()) + client.SendReport(customFormat) +}, NodeTimeout(1 * time.Minute)) ``` `ReportAfterEach` has several unique properties that distinguish it from `AfterEach`. Most importantly, `ReportAfterEach` closures are **always** called - even if the spec has failed, is marked pending, or is skipped. This ensures reports that rely on `ReportAfterEach` are complete. In addition, `ReportAfterEach` closures are called after a spec completes. i.e. _after_ all `AfterEach` closures have run. This gives them access to the complete final state of the spec. Note that if a failure occurs in a `ReportAfterEach` your the spec will be marked as failed. Subsequent `ReportAfterEach` closures will see the failed state, but not the closure in which the failure occurred. -`ReportAfterEach` is useful if you need to stream or emit up-to-date information about the suite as it runs. Ginkgo also provides `ReportBeforeEach` which is called before the test runs and receives a preliminary `types.SpecReport` - the state of this report will indicate whether the test will be skipped or is marked pending. +`ReportAfterEach` is useful if you need to stream or emit up-to-date information about the suite as it runs. Ginkgo also provides `ReportBeforeEach` which is called before the test runs and +receives a preliminary `types.SpecReport` ( or both `SpecContext` and `types.SpecReport` for interruptible behaviour) - the state of this report will indicate whether the test will be skipped or is marked pending. You should be aware that when running in parallel, each parallel process will be running specs and their `ReportAfterEach`es. This means that multiple `ReportAfterEach` blocks can be running concurrently on independent processes. Given that, code like this won't work: @@ -3542,20 +3549,24 @@ var _ = ReportBeforeSuite(func(report Report) { // process report }) +var _ = ReportBeforeSuite(func(ctx SpecContext, report Report) { + // process report +}, NodeTimeout(1 * time.Minutes)) + var _ = ReportAfterSuite("custom report", func(report Report) { // process report }) var _ = ReportAfterSuite("interruptible ReportAfterSuite", func(ctx SpecContext, report Report) { // process report -}, NodeTimeout(10 * time.Minutes)) +}, NodeTimeout(1 * time.Minutes)) ``` `Report` contains all available information about the suite. For `ReportAfterSuite` this will include individual `SpecReport` entries for each spec that ran in the suite, and the overall status of the suite (whether it passed or failed). Since `ReportBeforeSuite` runs before the suite starts - it does not contain any spec reports, however the count of the number of specs that _will_ be run can be extracted from `report.PreRunStats.SpecsThatWillBeRun`. The closure passed to `ReportBeforeSuite` is called exactly once at the beginning of the suite before any `BeforeSuite` nodes or specs run have run. The closure passed to `ReportAfterSuite` is called exactly once at the end of the suite after any `AfterSuite` nodes have run. -Finally, and most importantly, when running in parallel both `ReportBeforeSuite` and `ReportAfterSuite` **only run on process #1**. Gingko guarantess that no other processes will start running their specs until after `ReportBeforeSuite` on process #1 has completed. Similarly, Ginkgo will only run `ReportAfterSuite` on process #1 after all other processes have finished and exited. Ginkgo provides a sinle `Report` that aggregates the `SpecReports` from all processes. This allows you to perform any custom suite reporting in one place after all specs have run and not have to worry about aggregating information across multiple parallel processes. +Finally, and most importantly, when running in parallel both `ReportBeforeSuite` and `ReportAfterSuite` **only run on process #1**. Gingko guarantess that no other processes will start running their specs until after `ReportBeforeSuite` on process #1 has completed. Similarly, Ginkgo will only run `ReportAfterSuite` on process #1 after all other processes have finished and exited. Ginkgo provides a single `Report` that aggregates the `SpecReports` from all processes. This allows you to perform any custom suite reporting in one place after all specs have run and not have to worry about aggregating information across multiple parallel processes. Given all this, we can rewrite our invalid `ReportAfterEach` example from above into a valid `ReportAfterSuite` example: @@ -5251,8 +5262,12 @@ The `SuppressProgressOutput` decorator allows you to disable progress reporting ```go ReportAfterEach(func(report SpecReport) { - //... + // ... }, SuppressProgressReporting) + +ReportAfterEach(func(ctx SpecContext, report SpecReport) { + // ... +}, NodeTimeout(1 * time.Minute), SuppressProgressReporting) ``` #### The PollProgressAfter and PollProgressInterval Decorators From 2cebe8d4def1a24d5df12819defbc980a0fcaea2 Mon Sep 17 00:00:00 2001 From: Josef Johansson Date: Sun, 3 Mar 2024 19:44:01 +0100 Subject: [PATCH 050/102] docs/index.md: Typo Code was incorrect, this commit fixes that. Also change the name of the chan variable to be the same as in the invalid case above it. --- docs/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 5435a2e3f..1a88b476e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1221,13 +1221,13 @@ It("panics in a goroutine", func() { ```go It("panics in a goroutine", func() { - done := make(chan struct{}) + c := make(chan struct{}) go func() { defer GinkgoRecover() Fail("boom") close(c) }() - Eventually(done).Should(BeClosed()) + Eventually(c).Should(BeClosed()) }) ``` From a181ee22f50186b1be81d3d3011a6841518782d2 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Mon, 4 Mar 2024 12:06:34 -0700 Subject: [PATCH 051/102] v2.16.0 --- CHANGELOG.md | 19 +++++++++++++++++++ types/version.go | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a65dd10c..b79ee9c5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## 2.16.0 + +### Features +- add SpecContext to reporting nodes + +### Fixes +- merge coverages instead of combining them (#1329) (#1340) [23f0cc5] +- core_dsl: disable Getwd() with environment variable (#1357) [cd418b7] + +### Maintenance +- docs/index.md: Typo [2cebe8d] +- fix docs [06de431] +- chore: test with Go 1.22 (#1352) [898cba9] +- Bump golang.org/x/tools from 0.16.1 to 0.17.0 (#1336) [17ae120] +- Bump golang.org/x/sys from 0.15.0 to 0.16.0 (#1327) [5a179ed] +- Bump github.com/go-logr/logr from 1.3.0 to 1.4.1 (#1321) [a1e6b69] +- Bump github-pages and jekyll-feed in /docs (#1351) [d52951d] +- Fix docs for handling failures in goroutines (#1339) [4471b2e] + ## 2.15.0 ### Features diff --git a/types/version.go b/types/version.go index ed9346474..675f8db2f 100644 --- a/types/version.go +++ b/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.15.0" +const VERSION = "2.16.0" From e297e7bbf0ee4ccd0086c5e940293ea3221ff661 Mon Sep 17 00:00:00 2001 From: Ingve Vormestrand Date: Fri, 8 Mar 2024 09:00:14 +0100 Subject: [PATCH 052/102] Fix typo in docs --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 1a88b476e..3f0aa622d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1724,7 +1724,7 @@ Describe("handling requests", func() { }) ``` -all the infrastructure around generating table entry descriptions applies here as well - though the description will be the title of the generatd container. Note that you **must** add subject nodes in the body function if you want `DescribeHandleSubtree` to add specs. +all the infrastructure around generating table entry descriptions applies here as well - though the description will be the title of the generated container. Note that you **must** add subject nodes in the body function if you want `DescribeHandleSubtree` to add specs. ### Alternatives to Dot-Importing Ginkgo From 977bc6f813af032b7499f7876a963e6d3f20b685 Mon Sep 17 00:00:00 2001 From: Ryotaro Banno Date: Mon, 11 Mar 2024 09:45:24 +0900 Subject: [PATCH 053/102] fix typo in core_dsl.go --- core_dsl.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core_dsl.go b/core_dsl.go index 0e633f309..a3e8237e9 100644 --- a/core_dsl.go +++ b/core_dsl.go @@ -792,8 +792,8 @@ DeferCleanup can be passed: For example: BeforeEach(func() { - DeferCleanup(os.SetEnv, "FOO", os.GetEnv("FOO")) - os.SetEnv("FOO", "BAR") + DeferCleanup(os.Setenv, "FOO", os.GetEnv("FOO")) + os.Setenv("FOO", "BAR") }) will register a cleanup handler that will set the environment variable "FOO" to its current value (obtained by os.GetEnv("FOO")) after the spec runs and then sets the environment variable "FOO" to "BAR" for the current spec. From e8a2056f48b297343a97e7f77dd8902d345de649 Mon Sep 17 00:00:00 2001 From: Charly Molter Date: Wed, 13 Mar 2024 18:59:12 +0100 Subject: [PATCH 054/102] add `--github-output` for nicer output in github actions Leverage github's special formats to output nicer output https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#using-workflow-commands-to-access-toolkit-functions Fix #1372 Signed-off-by: Charly Molter --- docs/index.md | 3 +++ reporters/default_reporter.go | 47 ++++++++++++++++++++++++----------- types/config.go | 3 +++ 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/docs/index.md b/docs/index.md index 3f0aa622d..4afe5a32d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3382,6 +3382,7 @@ When you [filter specs](#filtering-specs) using Ginkgo's various filtering mecha Here are a grab bag of other settings: You can disable Ginkgo's color output by running `ginkgo --no-color`. +You can also output in a format that makes it easier to read in github actions console by running `ginkgo --github-output`. By default, Ginkgo only emits full stack traces when a spec panics. When a normal assertion failure occurs, Ginkgo simply emits the line at which the failure occurred. You can, instead, have Ginkgo always emit the full stack trace by running `ginkgo --trace`. @@ -3706,6 +3707,8 @@ Here's why: - `--timeout` allows you to specify a timeout for the `ginkgo` run. The default duration is one hour, which may or may not be enough! - `--poll-progress-after` and `--poll-progress-interval` will allow you to learn where long-running specs are getting stuck. Choose a values for `X` and `Y` that are appropriate to your suite. A long-running integration suite, for example, might set `X` to `120s` and `Y` to `30s` - whereas a quicker set of unit tests might not need this setting. Note that if you precompile suites and run them from a different directory relative to your source code, you may also need to set `--source-root` to enable Ginkgo to emit source code lines when generating progress reports. +If running on Github actions: `--github-output` will make the output more readable in the Github actions console. + ### Supporting Custom Suite Configuration There are contexts where you may want to change some aspects of a suite's behavior based on user-provided configuration. There are two widely adopted means of doing this: environment variables and command-line flags. diff --git a/reporters/default_reporter.go b/reporters/default_reporter.go index 56b7be758..bfd8b892c 100644 --- a/reporters/default_reporter.go +++ b/reporters/default_reporter.go @@ -182,6 +182,22 @@ func (r *DefaultReporter) WillRun(report types.SpecReport) { r.emitBlock(r.f(r.codeLocationBlock(report, "{{/}}", v.Is(types.VerbosityLevelVeryVerbose), false))) } +func (r *DefaultReporter) wrapTextBlock(sectionName string, fn func()) { + r.emitBlock("\n") + if r.conf.GithubOutput { + r.emitBlock(r.fi(1, "::group::%s", sectionName)) + } else { + r.emitBlock(r.fi(1, "{{gray}}<< %s{{/}}", sectionName)) + } + fn() + if r.conf.GithubOutput { + r.emitBlock(r.fi(1, "::endgroup::")) + } else { + r.emitBlock(r.fi(1, "{{gray}}%s >>{{/}}", sectionName)) + } + +} + func (r *DefaultReporter) DidRun(report types.SpecReport) { v := r.conf.Verbosity() inParallel := report.RunningInParallel @@ -283,26 +299,23 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) { //Emit Stdout/Stderr Output if showSeparateStdSection { - r.emitBlock("\n") - r.emitBlock(r.fi(1, "{{gray}}Captured StdOut/StdErr Output >>{{/}}")) - r.emitBlock(r.fi(1, "%s", report.CapturedStdOutErr)) - r.emitBlock(r.fi(1, "{{gray}}<< Captured StdOut/StdErr Output{{/}}")) + r.wrapTextBlock("Captured StdOut/StdErr Output", func() { + r.emitBlock(r.fi(1, "%s", report.CapturedStdOutErr)) + }) } if showSeparateVisibilityAlwaysReportsSection { - r.emitBlock("\n") - r.emitBlock(r.fi(1, "{{gray}}Report Entries >>{{/}}")) - for _, entry := range report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways) { - r.emitReportEntry(1, entry) - } - r.emitBlock(r.fi(1, "{{gray}}<< Report Entries{{/}}")) + r.wrapTextBlock("Report Entries", func() { + for _, entry := range report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways) { + r.emitReportEntry(1, entry) + } + }) } if showTimeline { - r.emitBlock("\n") - r.emitBlock(r.fi(1, "{{gray}}Timeline >>{{/}}")) - r.emitTimeline(1, report, timeline) - r.emitBlock(r.fi(1, "{{gray}}<< Timeline{{/}}")) + r.wrapTextBlock("Timeline", func() { + r.emitTimeline(1, report, timeline) + }) } // Emit Failure Message @@ -405,7 +418,11 @@ func (r *DefaultReporter) emitShortFailure(indent uint, state types.SpecState, f func (r *DefaultReporter) emitFailure(indent uint, state types.SpecState, failure types.Failure, includeAdditionalFailure bool) { highlightColor := r.highlightColorForState(state) r.emitBlock(r.fi(indent, highlightColor+"[%s] %s{{/}}", r.humanReadableState(state), failure.Message)) - r.emitBlock(r.fi(indent, highlightColor+"In {{bold}}[%s]{{/}}"+highlightColor+" at: {{bold}}%s{{/}} {{gray}}@ %s{{/}}\n", failure.FailureNodeType, failure.Location, failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) + if r.conf.GithubOutput { + r.emitBlock(r.fi(indent, "::error file=%s,line=%d::%s %s", failure.Location.FileName, failure.Location.LineNumber, failure.FailureNodeType, failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) + } else { + r.emitBlock(r.fi(indent, highlightColor+"In {{bold}}[%s]{{/}}"+highlightColor+" at: {{bold}}%s{{/}} {{gray}}@ %s{{/}}\n", failure.FailureNodeType, failure.Location, failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) + } if failure.ForwardedPanic != "" { r.emitBlock("\n") r.emitBlock(r.fi(indent, highlightColor+"%s{{/}}", failure.ForwardedPanic)) diff --git a/types/config.go b/types/config.go index c88fc85a7..7c82065df 100644 --- a/types/config.go +++ b/types/config.go @@ -89,6 +89,7 @@ type ReporterConfig struct { VeryVerbose bool FullTrace bool ShowNodeEvents bool + GithubOutput bool JSONReport string JUnitReport string @@ -331,6 +332,8 @@ var ReporterConfigFlags = GinkgoFlags{ Usage: "If set, default reporter prints out the full stack trace when a failure occurs"}, {KeyPath: "R.ShowNodeEvents", Name: "show-node-events", SectionKey: "output", Usage: "If set, default reporter prints node > Enter and < Exit events when specs fail"}, + {KeyPath: "R.GithubOutput", Name: "github-output", SectionKey: "output", + Usage: "If set, default reporter prints easier to manage output in Github Actions."}, {KeyPath: "R.JSONReport", Name: "json-report", UsageArgument: "filename.json", SectionKey: "output", Usage: "If set, Ginkgo will generate a JSON-formatted test report at the specified location."}, From 6e80d3f4f5ea154e8c33ae6b2467fd84381c9969 Mon Sep 17 00:00:00 2001 From: Charly Molter Date: Wed, 13 Mar 2024 20:52:15 +0100 Subject: [PATCH 055/102] use github formwat in CI Signed-off-by: Charly Molter --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 91e5402dd..eb02b3544 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,4 +27,4 @@ jobs: go-version: ${{ matrix.version }} - uses: actions/checkout@v4 - run: go vet ./... - - run: go run ./ginkgo -r -randomize-all -randomize-suites -race -trace -procs=2 -poll-progress-after=10s -poll-progress-interval=10s + - run: go run ./ginkgo --github-output -r -randomize-all -randomize-suites -race -trace -procs=2 -poll-progress-after=10s -poll-progress-interval=10s From 3a6097aafcdf510313435ab9d2c04cc1cde8891d Mon Sep 17 00:00:00 2001 From: Charly Molter Date: Wed, 13 Mar 2024 21:08:04 +0100 Subject: [PATCH 056/102] add test Signed-off-by: Charly Molter --- reporters/default_reporter.go | 4 ++-- reporters/default_reporter_test.go | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/reporters/default_reporter.go b/reporters/default_reporter.go index bfd8b892c..4026859ec 100644 --- a/reporters/default_reporter.go +++ b/reporters/default_reporter.go @@ -187,13 +187,13 @@ func (r *DefaultReporter) wrapTextBlock(sectionName string, fn func()) { if r.conf.GithubOutput { r.emitBlock(r.fi(1, "::group::%s", sectionName)) } else { - r.emitBlock(r.fi(1, "{{gray}}<< %s{{/}}", sectionName)) + r.emitBlock(r.fi(1, "{{gray}}%s >>{{/}}", sectionName)) } fn() if r.conf.GithubOutput { r.emitBlock(r.fi(1, "::endgroup::")) } else { - r.emitBlock(r.fi(1, "{{gray}}%s >>{{/}}", sectionName)) + r.emitBlock(r.fi(1, "{{gray}}<< %s{{/}}", sectionName)) } } diff --git a/reporters/default_reporter_test.go b/reporters/default_reporter_test.go index 27d357159..b9a46612c 100644 --- a/reporters/default_reporter_test.go +++ b/reporters/default_reporter_test.go @@ -176,6 +176,7 @@ const ( VeryVerbose FullTrace ShowNodeEvents + GithubOutput Parallel //used in the WillRun => DidRun specs to capture behavior when running in parallel ) @@ -204,6 +205,9 @@ func (cf ConfigFlag) String() string { if cf.Has(Parallel) { out = append(out, "parallel") } + if cf.Has(GithubOutput) { + out = append(out, "github-output") + } return strings.Join(out, "|") } @@ -226,6 +230,7 @@ func C(flags ...ConfigFlag) types.ReporterConfig { VeryVerbose: f.Has(VeryVerbose), FullTrace: f.Has(FullTrace), ShowNodeEvents: f.Has(ShowNodeEvents), + GithubOutput: f.Has(GithubOutput), } } @@ -770,6 +775,18 @@ var _ = Describe("DefaultReporter", func() { " {{gray}}<< Captured StdOut/StdErr Output{{/}}", DELIMITER, ""), + Case(Parallel|GithubOutput, + DELIMITER, + spr("{{green}}%s [1.000 seconds]{{/}}", DENOTER), + "{{green}}{{bold}}A{{/}}", + "{{gray}}cl0.go:12{{/}}", + "", + " ::group::Captured StdOut/StdErr Output", + " hello there", + " this is my output", + " ::endgroup::", + DELIMITER, + ""), ), Entry("a passing test with a full timeline that is only visible in verbose/very-verbose mode", S(types.NodeTypeIt, "A", cl0, GW("some GinkgoWriter\noutput is interspersed\nhere and there\n"), From 75ad73b7ed8b0a8a0ee2528619135c0c5b70fc23 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Mon, 18 Mar 2024 09:22:30 -0600 Subject: [PATCH 057/102] v2.17.0 --- CHANGELOG.md | 11 +++++++++++ types/version.go | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b79ee9c5a..57992854b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## 2.17.0 + +### Features + +- add `--github-output` for nicer output in github actions [e8a2056] + +### Maintenance + +- fix typo in core_dsl.go [977bc6f] +- Fix typo in docs [e297e7b] + ## 2.16.0 ### Features diff --git a/types/version.go b/types/version.go index 675f8db2f..ccd6516fa 100644 --- a/types/version.go +++ b/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.16.0" +const VERSION = "2.17.0" From af0330d31fa540b51756c14daf6b1c55515a379c Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Sun, 24 Mar 2024 07:50:02 -0600 Subject: [PATCH 058/102] If the user sets --seed=0, make sure all parallel nodes get the same seed --- .../seed_fixture/seed_fixture_suite_test.go | 21 ++++++++++++++++++ integration/flags_test.go | 6 +++++ types/config.go | 2 +- types/flags.go | 15 +++++++------ types/flags_test.go | 22 +++++++++++++++++-- 5 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 integration/_fixtures/seed_fixture/seed_fixture_suite_test.go diff --git a/integration/_fixtures/seed_fixture/seed_fixture_suite_test.go b/integration/_fixtures/seed_fixture/seed_fixture_suite_test.go new file mode 100644 index 000000000..3aed97c65 --- /dev/null +++ b/integration/_fixtures/seed_fixture/seed_fixture_suite_test.go @@ -0,0 +1,21 @@ +package seed_fixture_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestSeedFixture(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "SeedFixture Suite") +} + +var _ = BeforeSuite(func() { + Ω(GinkgoRandomSeed()).Should(Equal(int64(0))) +}) + +var _ = It("has the expected seed (namely, 0)", func() { + Ω(GinkgoRandomSeed()).Should(Equal(int64(0))) +}) diff --git a/integration/flags_test.go b/integration/flags_test.go index 18fcdea9b..5c4e6f31e 100644 --- a/integration/flags_test.go +++ b/integration/flags_test.go @@ -66,6 +66,12 @@ var _ = Describe("Flags Specs", func() { Ω(orders[0]).ShouldNot(BeNumerically("<", orders[1])) }) + It("should consistently pass in a zero seed when asked to", func() { + fm.MountFixture("seed") + session := startGinkgo(fm.PathTo("seed"), "--no-color", "--seed=0", "--nodes=2") + Eventually(session).Should(gexec.Exit(0)) + }) + It("should pass additional arguments in", func() { session := startGinkgo(fm.PathTo("flags"), "--", "--customFlag=madagascar") Eventually(session).Should(gexec.Exit(1)) diff --git a/types/config.go b/types/config.go index 7c82065df..cef273ee1 100644 --- a/types/config.go +++ b/types/config.go @@ -265,7 +265,7 @@ var FlagSections = GinkgoFlagSections{ // SuiteConfigFlags provides flags for the Ginkgo test process, and CLI var SuiteConfigFlags = GinkgoFlags{ {KeyPath: "S.RandomSeed", Name: "seed", SectionKey: "order", UsageDefaultValue: "randomly generated by Ginkgo", - Usage: "The seed used to randomize the spec suite."}, + Usage: "The seed used to randomize the spec suite.", AlwaysExport: true}, {KeyPath: "S.RandomizeAllSpecs", Name: "randomize-all", SectionKey: "order", DeprecatedName: "randomizeAllSpecs", DeprecatedDocLink: "changed-command-line-flags", Usage: "If set, ginkgo will randomize all specs together. By default, ginkgo only randomizes the top level Describe, Context and When containers."}, diff --git a/types/flags.go b/types/flags.go index 9186ae873..de69f3022 100644 --- a/types/flags.go +++ b/types/flags.go @@ -24,7 +24,8 @@ type GinkgoFlag struct { DeprecatedDocLink string DeprecatedVersion string - ExportAs string + ExportAs string + AlwaysExport bool } type GinkgoFlags []GinkgoFlag @@ -431,7 +432,7 @@ func (ssv stringSliceVar) Set(s string) error { return nil } -//given a set of GinkgoFlags and bindings, generate flag arguments suitable to be passed to an application with that set of flags configured. +// given a set of GinkgoFlags and bindings, generate flag arguments suitable to be passed to an application with that set of flags configured. func GenerateFlagArgs(flags GinkgoFlags, bindings interface{}) ([]string, error) { result := []string{} for _, flag := range flags { @@ -451,19 +452,19 @@ func GenerateFlagArgs(flags GinkgoFlags, bindings interface{}) ([]string, error) iface := value.Interface() switch value.Type() { case reflect.TypeOf(string("")): - if iface.(string) != "" { + if iface.(string) != "" || flag.AlwaysExport { result = append(result, fmt.Sprintf("--%s=%s", name, iface)) } case reflect.TypeOf(int64(0)): - if iface.(int64) != 0 { + if iface.(int64) != 0 || flag.AlwaysExport { result = append(result, fmt.Sprintf("--%s=%d", name, iface)) } case reflect.TypeOf(float64(0)): - if iface.(float64) != 0 { + if iface.(float64) != 0 || flag.AlwaysExport { result = append(result, fmt.Sprintf("--%s=%f", name, iface)) } case reflect.TypeOf(int(0)): - if iface.(int) != 0 { + if iface.(int) != 0 || flag.AlwaysExport { result = append(result, fmt.Sprintf("--%s=%d", name, iface)) } case reflect.TypeOf(bool(true)): @@ -471,7 +472,7 @@ func GenerateFlagArgs(flags GinkgoFlags, bindings interface{}) ([]string, error) result = append(result, fmt.Sprintf("--%s", name)) } case reflect.TypeOf(time.Duration(0)): - if iface.(time.Duration) != time.Duration(0) { + if iface.(time.Duration) != time.Duration(0) || flag.AlwaysExport { result = append(result, fmt.Sprintf("--%s=%s", name, iface)) } diff --git a/types/flags_test.go b/types/flags_test.go index 17d52ad28..11d9ff55a 100644 --- a/types/flags_test.go +++ b/types/flags_test.go @@ -427,10 +427,10 @@ var _ = Describe("Flags", func() { } flags = types.GinkgoFlags{ {Name: "string-flag", KeyPath: "A.StringProperty", DeprecatedName: "stringFlag"}, - {Name: "int-64-flag", KeyPath: "A.Int64Property"}, + {Name: "int-64-flag", KeyPath: "A.Int64Property", AlwaysExport: true}, {Name: "float-64-flag", KeyPath: "A.Float64Property"}, {Name: "int-flag", KeyPath: "B.IntProperty", ExportAs: "alias-int-flag"}, - {Name: "bool-flag", KeyPath: "B.BoolProperty", ExportAs: "alias-bool-flag"}, + {Name: "bool-flag", KeyPath: "B.BoolProperty", ExportAs: "alias-bool-flag", AlwaysExport: true}, {Name: "string-slice-flag", KeyPath: "B.StringSliceProperty"}, {DeprecatedName: "deprecated-flag", KeyPath: "B.DeprecatedProperty"}, } @@ -452,6 +452,24 @@ var _ = Describe("Flags", func() { })) }) + It("does not include 0 values unless AlwaysExport is true", func() { + A.StringProperty = "" + A.Int64Property = 0 + B.IntProperty = 0 + B.BoolProperty = false + + args, err := types.GenerateFlagArgs(flags, bindings) + Ω(err).ShouldNot(HaveOccurred()) + + Ω(args).Should(Equal([]string{ + "--int-64-flag=0", //always export + "--float-64-flag=3.141000", + "--string-slice-flag=once", + "--string-slice-flag=upon", + "--string-slice-flag=a time", + })) + }) + It("errors if there is a keypath issue", func() { flags[0] = types.GinkgoFlag{Name: "unsupported-type", KeyPath: "A.UnsupportedInt32"} args, err := types.GenerateFlagArgs(flags, bindings) From 92423385b96b8be0ac6c4686ff305f30f885e59e Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Sun, 24 Mar 2024 07:59:47 -0600 Subject: [PATCH 059/102] v2.17.1 --- CHANGELOG.md | 5 +++++ types/version.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57992854b..44222220a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.17.1 + +### Fixes +- If the user sets --seed=0, make sure all parallel nodes get the same seed [af0330d] + ## 2.17.0 ### Features diff --git a/types/version.go b/types/version.go index ccd6516fa..851d42b45 100644 --- a/types/version.go +++ b/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.17.0" +const VERSION = "2.17.1" From 780e7a34f234c0915629de3a38535df9b65b62e9 Mon Sep 17 00:00:00 2001 From: zhangzujian Date: Mon, 25 Mar 2024 02:44:31 +0000 Subject: [PATCH 060/102] fix github output log level for skipped specs Signed-off-by: zhangzujian --- reporters/default_reporter.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/reporters/default_reporter.go b/reporters/default_reporter.go index 4026859ec..980973370 100644 --- a/reporters/default_reporter.go +++ b/reporters/default_reporter.go @@ -419,7 +419,11 @@ func (r *DefaultReporter) emitFailure(indent uint, state types.SpecState, failur highlightColor := r.highlightColorForState(state) r.emitBlock(r.fi(indent, highlightColor+"[%s] %s{{/}}", r.humanReadableState(state), failure.Message)) if r.conf.GithubOutput { - r.emitBlock(r.fi(indent, "::error file=%s,line=%d::%s %s", failure.Location.FileName, failure.Location.LineNumber, failure.FailureNodeType, failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) + level := "error" + if state.Is(types.SpecStateSkipped) { + level = "notice" + } + r.emitBlock(r.fi(indent, "::%s file=%s,line=%d::%s %s", level, failure.Location.FileName, failure.Location.LineNumber, failure.FailureNodeType, failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) } else { r.emitBlock(r.fi(indent, highlightColor+"In {{bold}}[%s]{{/}}"+highlightColor+" at: {{bold}}%s{{/}} {{gray}}@ %s{{/}}\n", failure.FailureNodeType, failure.Location, failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) } From f15239a3e6d09f1342611b7cbfcf75c1c8230710 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:16:31 +0100 Subject: [PATCH 061/102] Bump golang.org/x/net from 0.20.0 to 0.23.0 (#1380) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.20.0 to 0.23.0. - [Commits](https://github.com/golang/net/compare/v0.20.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index a4adb6692..6e55ddd9a 100644 --- a/go.mod +++ b/go.mod @@ -7,8 +7,8 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 github.com/onsi/gomega v1.30.0 - golang.org/x/net v0.20.0 - golang.org/x/sys v0.16.0 + golang.org/x/net v0.23.0 + golang.org/x/sys v0.18.0 golang.org/x/tools v0.17.0 ) diff --git a/go.sum b/go.sum index 58f1a1d5a..b4d0a09e0 100644 --- a/go.sum +++ b/go.sum @@ -24,11 +24,11 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= From 7f447b2a8f6b8c29c7640703a6e295b0db9b885c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:16:51 +0100 Subject: [PATCH 062/102] Bump google.golang.org/protobuf from 1.28.0 to 1.33.0 (#1374) Bumps google.golang.org/protobuf from 1.28.0 to 1.33.0. --- updated-dependencies: - dependency-name: google.golang.org/protobuf dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6e55ddd9a..f92ebc09d 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,6 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.6.0 // indirect golang.org/x/text v0.14.0 // indirect - google.golang.org/protobuf v1.28.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index b4d0a09e0..2771db5f1 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From e6d1170c81c6294347ff15d3ba014df2ae74e23f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:17:05 +0100 Subject: [PATCH 063/102] Bump github-pages from 229 to 230 in /docs (#1359) Bumps [github-pages](https://github.com/github/pages-gem) from 229 to 230. - [Release notes](https://github.com/github/pages-gem/releases) - [Commits](https://github.com/github/pages-gem/compare/v229...v230) --- updated-dependencies: - dependency-name: github-pages dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Gemfile | 2 +- docs/Gemfile.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/Gemfile b/docs/Gemfile index 88f454a6a..4a7872a50 100644 --- a/docs/Gemfile +++ b/docs/Gemfile @@ -12,7 +12,7 @@ source "https://rubygems.org" gem "minima", "~> 2.5" # If you want to use GitHub Pages, remove the "gem "jekyll"" above and # uncomment the line below. To upgrade, run `bundle update github-pages`. -gem "github-pages", "~> 229", group: :jekyll_plugins +gem "github-pages", "~> 230", group: :jekyll_plugins # If you have any plugins, put them here! group :jekyll_plugins do gem "jekyll-feed", "~> 0.17" diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 09cf58cd2..51a751910 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -32,9 +32,9 @@ GEM ffi (1.16.3) forwardable-extended (2.6.0) gemoji (4.1.0) - github-pages (229) + github-pages (230) github-pages-health-check (= 1.18.2) - jekyll (= 3.9.4) + jekyll (= 3.9.5) jekyll-avatar (= 0.8.0) jekyll-coffeescript (= 1.2.2) jekyll-commonmark-ghpages (= 0.4.0) @@ -89,7 +89,7 @@ GEM http_parser.rb (0.8.0) i18n (1.14.1) concurrent-ruby (~> 1.0) - jekyll (3.9.4) + jekyll (3.9.5) addressable (~> 2.4) colorator (~> 1.0) em-websocket (~> 0.5) @@ -210,7 +210,7 @@ GEM jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) - minitest (5.22.0) + minitest (5.22.2) net-http (0.4.1) uri nokogiri (1.16.2-x86_64-linux) @@ -258,7 +258,7 @@ PLATFORMS x86_64-linux DEPENDENCIES - github-pages (~> 229) + github-pages (~> 230) jekyll-feed (~> 0.17) minima (~> 2.5) tzinfo (~> 1.2) From 5474a26914bc40fbd4f5fe70e9d4c954e7c8de15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:24:07 +0100 Subject: [PATCH 064/102] Bump golang.org/x/tools from 0.17.0 to 0.19.0 (#1368) Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.17.0 to 0.19.0. - [Release notes](https://github.com/golang/tools/releases) - [Commits](https://github.com/golang/tools/compare/v0.17.0...v0.19.0) --- updated-dependencies: - dependency-name: golang.org/x/tools dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f92ebc09d..0f93e54ba 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/onsi/gomega v1.30.0 golang.org/x/net v0.23.0 golang.org/x/sys v0.18.0 - golang.org/x/tools v0.17.0 + golang.org/x/tools v0.19.0 ) require ( diff --git a/go.sum b/go.sum index 2771db5f1..572cbf3f6 100644 --- a/go.sum +++ b/go.sum @@ -31,8 +31,8 @@ golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= From fd622d239cddeaa27827beebc514f619549541fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 17:47:17 +0100 Subject: [PATCH 065/102] Bump github.com/onsi/gomega from 1.30.0 to 1.33.0 (#1390) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.30.0 to 1.33.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.30.0...v1.33.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 3 +-- go.sum | 11 ++--------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 0f93e54ba..cefce7477 100644 --- a/go.mod +++ b/go.mod @@ -6,14 +6,13 @@ require ( github.com/go-logr/logr v1.4.1 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 - github.com/onsi/gomega v1.30.0 + github.com/onsi/gomega v1.33.0 golang.org/x/net v0.23.0 golang.org/x/sys v0.18.0 golang.org/x/tools v0.19.0 ) require ( - github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.6.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/protobuf v1.33.0 // indirect diff --git a/go.sum b/go.sum index 572cbf3f6..d288d0d2f 100644 --- a/go.sum +++ b/go.sum @@ -8,17 +8,13 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= +github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= 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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -33,9 +29,6 @@ golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= From f2fcd97cfb472bcafac5b2ddfb9ec567e9e702c9 Mon Sep 17 00:00:00 2001 From: Ignas Baranauskas Date: Mon, 22 Apr 2024 17:22:55 +0100 Subject: [PATCH 066/102] Fix test for gomega version bump --- internal/internal_integration/interrupt_and_timeout_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/internal_integration/interrupt_and_timeout_test.go b/internal/internal_integration/interrupt_and_timeout_test.go index 566866b24..38b5dbba2 100644 --- a/internal/internal_integration/interrupt_and_timeout_test.go +++ b/internal/internal_integration/interrupt_and_timeout_test.go @@ -924,7 +924,7 @@ var _ = Describe("Interrupts and Timeouts", func() { Ω(rt).Should(HaveTracked("A")) Ω(reporter.Did.Find("A")).Should(HaveTimedOut(clLine(-1))) Ω(reporter.Did.Find("A")).Should(HaveTimedOut(`A spec timeout occurred`)) - Ω(reporter.Did.Find("A").Failure.AdditionalFailure).Should(HaveFailed(MatchRegexp("A spec timeout occurred and then the following failure was recorded in the timedout node before it exited:\nContext was cancelled after .*\nExpected\n : foo\nto equal\n : bar"), clLine(1))) + Ω(reporter.Did.Find("A").Failure.AdditionalFailure).Should(HaveFailed(MatchRegexp("A spec timeout occurred and then the following failure was recorded in the timedout node before it exited:\nContext was cancelled \\(cause: spec timeout occurred\\) after .*\nExpected\n : foo\nto equal\n : bar"), clLine(1))) Ω(reporter.Did.Find("A").Failure.ProgressReport.Message).Should(Equal("{{bold}}This is the Progress Report generated when the spec timeout occurred:{{/}}")) Ω(reporter.Did.Find("A").Failure.ProgressReport.AdditionalReports).Should(ConsistOf("Expected\n : foo\nto equal\n : bar")) }) From 4ce33f4df3dc1b1b0388ace2a2555b00343c9670 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 20:44:51 +0100 Subject: [PATCH 067/102] Bump golang.org/x/net from 0.23.0 to 0.24.0 (#1381) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.23.0 to 0.24.0. - [Commits](https://github.com/golang/net/compare/v0.23.0...v0.24.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index cefce7477..503434d19 100644 --- a/go.mod +++ b/go.mod @@ -7,8 +7,8 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 github.com/onsi/gomega v1.33.0 - golang.org/x/net v0.23.0 - golang.org/x/sys v0.18.0 + golang.org/x/net v0.24.0 + golang.org/x/sys v0.19.0 golang.org/x/tools v0.19.0 ) diff --git a/go.sum b/go.sum index d288d0d2f..beb02ae04 100644 --- a/go.sum +++ b/go.sum @@ -20,11 +20,11 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= From 760def865e81163b67e4ccda3fc2f7f5ab4109b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 21:03:43 +0100 Subject: [PATCH 068/102] Bump golang.org/x/tools from 0.19.0 to 0.20.0 (#1383) Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.19.0 to 0.20.0. - [Release notes](https://github.com/golang/tools/releases) - [Commits](https://github.com/golang/tools/compare/v0.19.0...v0.20.0) --- updated-dependencies: - dependency-name: golang.org/x/tools dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 503434d19..154b83125 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/onsi/gomega v1.33.0 golang.org/x/net v0.24.0 golang.org/x/sys v0.19.0 - golang.org/x/tools v0.19.0 + golang.org/x/tools v0.20.0 ) require ( diff --git a/go.sum b/go.sum index beb02ae04..e1b840095 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,8 @@ golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= -golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= From eca81b4f8c35793e37922f82275f3c8dfa724f67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 21:04:11 +0100 Subject: [PATCH 069/102] Bump github-pages from 230 to 231 in /docs (#1384) Bumps [github-pages](https://github.com/github/pages-gem) from 230 to 231. - [Release notes](https://github.com/github/pages-gem/releases) - [Commits](https://github.com/github/pages-gem/compare/v230...v231) --- updated-dependencies: - dependency-name: github-pages dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Gemfile | 2 +- docs/Gemfile.lock | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/Gemfile b/docs/Gemfile index 4a7872a50..6dd3b767a 100644 --- a/docs/Gemfile +++ b/docs/Gemfile @@ -12,7 +12,7 @@ source "https://rubygems.org" gem "minima", "~> 2.5" # If you want to use GitHub Pages, remove the "gem "jekyll"" above and # uncomment the line below. To upgrade, run `bundle update github-pages`. -gem "github-pages", "~> 230", group: :jekyll_plugins +gem "github-pages", "~> 231", group: :jekyll_plugins # If you have any plugins, put them here! group :jekyll_plugins do gem "jekyll-feed", "~> 0.17" diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 51a751910..670be1d3e 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -16,7 +16,7 @@ GEM colorator (1.1.0) commonmarker (0.23.10) concurrent-ruby (1.2.3) - dnsruby (1.70.0) + dnsruby (1.72.0) simpleidn (~> 0.2.1) em-websocket (0.5.3) eventmachine (>= 0.12.9) @@ -32,7 +32,7 @@ GEM ffi (1.16.3) forwardable-extended (2.6.0) gemoji (4.1.0) - github-pages (230) + github-pages (231) github-pages-health-check (= 1.18.2) jekyll (= 3.9.5) jekyll-avatar (= 0.8.0) @@ -48,7 +48,7 @@ GEM jekyll-paginate (= 1.1.0) jekyll-readme-index (= 0.3.0) jekyll-redirect-from (= 0.16.0) - jekyll-relative-links (= 0.7.0) + jekyll-relative-links (= 0.6.1) jekyll-remote-theme (= 0.4.3) jekyll-sass-converter (= 1.5.2) jekyll-seo-tag (= 2.8.0) @@ -87,7 +87,7 @@ GEM activesupport (>= 2) nokogiri (>= 1.4) http_parser.rb (0.8.0) - i18n (1.14.1) + i18n (1.14.4) concurrent-ruby (~> 1.0) jekyll (3.9.5) addressable (~> 2.4) @@ -135,7 +135,7 @@ GEM jekyll (>= 3.0, < 5.0) jekyll-redirect-from (0.16.0) jekyll (>= 3.3, < 5.0) - jekyll-relative-links (0.7.0) + jekyll-relative-links (0.6.1) jekyll (>= 3.3, < 5.0) jekyll-remote-theme (0.4.3) addressable (~> 2.0) @@ -202,7 +202,7 @@ GEM kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) liquid (4.0.4) - listen (3.8.0) + listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) mercenary (0.3.6) @@ -210,17 +210,17 @@ GEM jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) - minitest (5.22.2) + minitest (5.22.3) net-http (0.4.1) uri - nokogiri (1.16.2-x86_64-linux) + nokogiri (1.16.3-x86_64-linux) racc (~> 1.4) octokit (4.25.1) faraday (>= 1, < 3) sawyer (~> 0.9) pathutil (0.16.2) forwardable-extended (~> 2.6) - public_suffix (5.0.4) + public_suffix (5.0.5) racc (1.7.3) rb-fsevent (0.11.2) rb-inotify (0.10.1) @@ -258,7 +258,7 @@ PLATFORMS x86_64-linux DEPENDENCIES - github-pages (~> 230) + github-pages (~> 231) jekyll-feed (~> 0.17) minima (~> 2.5) tzinfo (~> 1.2) From 313442296dc90b138c03ddfee47337bdfea186fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 21:04:52 +0100 Subject: [PATCH 070/102] Bump golang.org/x/net in /integration/_fixtures/version_mismatch_fixture (#1391) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.17.0 to 0.23.0. - [Commits](https://github.com/golang/net/compare/v0.17.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../_fixtures/version_mismatch_fixture/go.mod | 6 +++--- .../_fixtures/version_mismatch_fixture/go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/integration/_fixtures/version_mismatch_fixture/go.mod b/integration/_fixtures/version_mismatch_fixture/go.mod index 0216b502c..b22b100c3 100644 --- a/integration/_fixtures/version_mismatch_fixture/go.mod +++ b/integration/_fixtures/version_mismatch_fixture/go.mod @@ -9,8 +9,8 @@ require ( require ( github.com/google/go-cmp v0.5.8 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/net v0.23.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/text v0.14.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/integration/_fixtures/version_mismatch_fixture/go.sum b/integration/_fixtures/version_mismatch_fixture/go.sum index 5bfc394f6..0478e997d 100644 --- a/integration/_fixtures/version_mismatch_fixture/go.sum +++ b/integration/_fixtures/version_mismatch_fixture/go.sum @@ -5,12 +5,12 @@ github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI= github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 32259c8b061575609fcf13c3dc429c3050545027 Mon Sep 17 00:00:00 2001 From: guoguangwu Date: Fri, 26 Apr 2024 13:44:49 +0800 Subject: [PATCH 071/102] fix: close files Signed-off-by: guoguangwu --- ginkgo/generators/generate_command.go | 1 + ginkgo/internal/profiles_and_reports.go | 2 ++ reporters/junit_report.go | 1 + 3 files changed, 4 insertions(+) diff --git a/ginkgo/generators/generate_command.go b/ginkgo/generators/generate_command.go index be01dec97..4385a61ec 100644 --- a/ginkgo/generators/generate_command.go +++ b/ginkgo/generators/generate_command.go @@ -174,6 +174,7 @@ func moduleName(modRoot string) string { if err != nil { return "" } + defer modFile.Close() mod := make([]byte, 128) _, err = modFile.Read(mod) diff --git a/ginkgo/internal/profiles_and_reports.go b/ginkgo/internal/profiles_and_reports.go index 5f35864dd..8e16d2bb0 100644 --- a/ginkgo/internal/profiles_and_reports.go +++ b/ginkgo/internal/profiles_and_reports.go @@ -161,6 +161,7 @@ func MergeAndCleanupCoverProfiles(profiles []string, destination string) error { if err != nil { return err } + defer dst.Close() err = DumpCoverProfiles(merged, dst) if err != nil { return err @@ -196,6 +197,7 @@ func MergeProfiles(profilePaths []string, destination string) error { return fmt.Errorf("Could not open profile: %s\n%s", profilePath, err.Error()) } prof, err := profile.Parse(proFile) + _ = proFile.Close() if err != nil { return fmt.Errorf("Could not parse profile: %s\n%s", profilePath, err.Error()) } diff --git a/reporters/junit_report.go b/reporters/junit_report.go index 43244a9bd..2a3215b51 100644 --- a/reporters/junit_report.go +++ b/reporters/junit_report.go @@ -324,6 +324,7 @@ func MergeAndCleanupJUnitReports(sources []string, dst string) ([]string, error) continue } err = xml.NewDecoder(f).Decode(&report) + _ = f.Close() if err != nil { messages = append(messages, fmt.Sprintf("Could not decode %s:\n%s", source, err.Error())) continue From 8cb662e892ca24d05fa748c26052c5164e44c2f4 Mon Sep 17 00:00:00 2001 From: Luca Comellini Date: Fri, 26 Apr 2024 13:45:54 -0700 Subject: [PATCH 072/102] Bump github.com/go-task/slim-sprig to v3 --- ginkgo/generators/bootstrap_command.go | 2 +- ginkgo/generators/generate_command.go | 2 +- go.mod | 2 +- go.sum | 12 +++--------- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/ginkgo/generators/bootstrap_command.go b/ginkgo/generators/bootstrap_command.go index 73aff0b7a..b2dc59be6 100644 --- a/ginkgo/generators/bootstrap_command.go +++ b/ginkgo/generators/bootstrap_command.go @@ -7,7 +7,7 @@ import ( "os" "text/template" - sprig "github.com/go-task/slim-sprig" + sprig "github.com/go-task/slim-sprig/v3" "github.com/onsi/ginkgo/v2/ginkgo/command" "github.com/onsi/ginkgo/v2/ginkgo/internal" "github.com/onsi/ginkgo/v2/types" diff --git a/ginkgo/generators/generate_command.go b/ginkgo/generators/generate_command.go index 4385a61ec..cf3b7cb6d 100644 --- a/ginkgo/generators/generate_command.go +++ b/ginkgo/generators/generate_command.go @@ -10,7 +10,7 @@ import ( "strings" "text/template" - sprig "github.com/go-task/slim-sprig" + sprig "github.com/go-task/slim-sprig/v3" "github.com/onsi/ginkgo/v2/ginkgo/command" "github.com/onsi/ginkgo/v2/ginkgo/internal" "github.com/onsi/ginkgo/v2/types" diff --git a/go.mod b/go.mod index 154b83125..953df4021 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/go-logr/logr v1.4.1 - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 + github.com/go-task/slim-sprig/v3 v3.0.0 github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 github.com/onsi/gomega v1.33.0 golang.org/x/net v0.24.0 diff --git a/go.sum b/go.sum index e1b840095..a9ef79fca 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,11 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= @@ -16,10 +14,7 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= 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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -33,6 +28,5 @@ google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGm google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From d91fe4e0f1465425ec119c2a55901a5f18b79079 Mon Sep 17 00:00:00 2001 From: Luca Comellini Date: Fri, 26 Apr 2024 12:47:47 -0700 Subject: [PATCH 073/102] Bump github.com/google/pprof --- go.mod | 2 +- go.sum | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 953df4021..8c40585e6 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( github.com/go-logr/logr v1.4.1 github.com/go-task/slim-sprig/v3 v3.0.0 - github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 + github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 github.com/onsi/gomega v1.33.0 golang.org/x/net v0.24.0 golang.org/x/sys v0.19.0 diff --git a/go.sum b/go.sum index a9ef79fca..2d27b6c64 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,3 @@ -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -8,16 +5,14 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= From 7836496233b965f84a4e0268c0173ff1154a9447 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Sat, 27 Apr 2024 13:29:32 -0600 Subject: [PATCH 074/102] v2.17.2 --- CHANGELOG.md | 20 ++++++++++++++++++++ types/version.go | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44222220a..0a8949799 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +## 2.17.2 + +### Fixes +- fix: close files [32259c8] +- fix github output log level for skipped specs [780e7a3] + +### Maintenance +- Bump github.com/google/pprof [d91fe4e] +- Bump github.com/go-task/slim-sprig to v3 [8cb662e] +- Bump golang.org/x/net in /integration/_fixtures/version_mismatch_fixture (#1391) [3134422] +- Bump github-pages from 230 to 231 in /docs (#1384) [eca81b4] +- Bump golang.org/x/tools from 0.19.0 to 0.20.0 (#1383) [760def8] +- Bump golang.org/x/net from 0.23.0 to 0.24.0 (#1381) [4ce33f4] +- Fix test for gomega version bump [f2fcd97] +- Bump github.com/onsi/gomega from 1.30.0 to 1.33.0 (#1390) [fd622d2] +- Bump golang.org/x/tools from 0.17.0 to 0.19.0 (#1368) [5474a26] +- Bump github-pages from 229 to 230 in /docs (#1359) [e6d1170] +- Bump google.golang.org/protobuf from 1.28.0 to 1.33.0 (#1374) [7f447b2] +- Bump golang.org/x/net from 0.20.0 to 0.23.0 (#1380) [f15239a] + ## 2.17.1 ### Fixes diff --git a/types/version.go b/types/version.go index 851d42b45..5dd0140cd 100644 --- a/types/version.go +++ b/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.17.1" +const VERSION = "2.17.2" From bde6e003110d37f75576dc7c9dadffcf10c66676 Mon Sep 17 00:00:00 2001 From: Eric Wollesen Date: Mon, 6 May 2024 10:48:13 -0600 Subject: [PATCH 075/102] ignore hidden files Hidden files are defined here as those beginning with '.' or '_'. This is a departure from previous behavior, where hidden source and test files were evaluated via watch. Evaluating hidden files is undesirable because some editors create hidden temporary files, and these files shouldn't trigger test runs. No flag is added to restore the original behavior at this time as the new behavior is the same as "go test", and it is not expected that it will cause problems. If this change affects you, consider opening a PR to add a CLI flag to restore the previous behavior. --- ginkgo/watch/package_hash.go | 9 +++++++++ integration/watch_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/ginkgo/watch/package_hash.go b/ginkgo/watch/package_hash.go index 17d052bdc..0e6ae1f29 100644 --- a/ginkgo/watch/package_hash.go +++ b/ginkgo/watch/package_hash.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "regexp" + "strings" "time" ) @@ -79,6 +80,10 @@ func (p *PackageHash) computeHashes() (codeHash string, codeModifiedTime time.Ti continue } + if isHiddenFile(info) { + continue + } + if goTestRegExp.MatchString(info.Name()) { testHash += p.hashForFileInfo(info) if info.ModTime().After(testModifiedTime) { @@ -103,6 +108,10 @@ func (p *PackageHash) computeHashes() (codeHash string, codeModifiedTime time.Ti return } +func isHiddenFile(info os.FileInfo) bool { + return strings.HasPrefix(info.Name(), ".") || strings.HasPrefix(info.Name(), "_") +} + func (p *PackageHash) hashForFileInfo(info os.FileInfo) string { return fmt.Sprintf("%s_%d_%d", info.Name(), info.Size(), info.ModTime().UnixNano()) } diff --git a/integration/watch_test.go b/integration/watch_test.go index a1e08ac0f..4d1ab71a8 100644 --- a/integration/watch_test.go +++ b/integration/watch_test.go @@ -20,6 +20,18 @@ var _ = Describe("Watch", Label("SLOW"), func() { fm.MountFixture("watch", "C") }) + createFile := func(path string, contents []byte) { + time.Sleep(time.Second) + err := os.WriteFile(path, contents, 0666) + Ω(err).ShouldNot(HaveOccurred()) + } + + createHiddenTest := func(pkgToModify string) { + path := filepath.Join(pkgToModify, ".#"+pkgToModify+"_test.go") + fm.MkEmpty(filepath.Join("watch", pkgToModify)) + createFile(fm.PathTo("watch", path), []byte("//")) + } + modifyFile := func(path string) { time.Sleep(time.Second) content, err := os.ReadFile(path) @@ -185,6 +197,19 @@ var _ = Describe("Watch", Label("SLOW"), func() { Eventually(session).Should(gbytes.Say("C Suite")) Consistently(session).ShouldNot(gbytes.Say("A Suite|B Suite")) }) + + Context("when a hidden test file is created", func() { + It("shouldn't trigger the test suite", func() { + session = startGinkgo(fm.PathTo("watch"), "watch", "-r") + Eventually(session).Should(gbytes.Say("Identified 3 test suites")) + Eventually(session).Should(gbytes.Say(`A \[`)) + Eventually(session).Should(gbytes.Say(`B \[`)) + Eventually(session).Should(gbytes.Say(`C \[`)) + + createHiddenTest("A") + Consistently(session).ShouldNot(gbytes.Say("Detected changes in")) + }) + }) }) Describe("adjusting the watch regular expression", func() { From d8a5ef9f311b1b5f11208ce958b13c6cb6f03861 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Tue, 7 May 2024 06:57:58 -0600 Subject: [PATCH 076/102] v2.17.3 --- CHANGELOG.md | 5 +++++ types/version.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a8949799..13be7ec6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.17.3 + +### Fixes +`ginkgo watch` now ignores hidden files [bde6e00] + ## 2.17.2 ### Fixes diff --git a/types/version.go b/types/version.go index 5dd0140cd..52cc3abc8 100644 --- a/types/version.go +++ b/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.17.2" +const VERSION = "2.17.3" From 04bfad7dc0b74ac9126b77953230f6514e067339 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 11 May 2024 21:54:23 +0100 Subject: [PATCH 077/102] Bump golang.org/x/net from 0.24.0 to 0.25.0 (#1407) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.24.0 to 0.25.0. - [Commits](https://github.com/golang/net/compare/v0.24.0...v0.25.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 8c40585e6..14fc4a4be 100644 --- a/go.mod +++ b/go.mod @@ -7,14 +7,14 @@ require ( github.com/go-task/slim-sprig/v3 v3.0.0 github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 github.com/onsi/gomega v1.33.0 - golang.org/x/net v0.24.0 - golang.org/x/sys v0.19.0 + golang.org/x/net v0.25.0 + golang.org/x/sys v0.20.0 golang.org/x/tools v0.20.0 ) require ( github.com/google/go-cmp v0.6.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/text v0.15.0 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 2d27b6c64..20ea87441 100644 --- a/go.sum +++ b/go.sum @@ -11,12 +11,12 @@ github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= From 8bb14fd00f7c76dddcab0c33d899dbac785f86bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 11 May 2024 22:02:03 +0100 Subject: [PATCH 078/102] Bump github.com/onsi/gomega from 1.33.0 to 1.33.1 (#1399) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.33.0 to 1.33.1. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.33.0...v1.33.1) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 14fc4a4be..30c57fc8f 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/go-logr/logr v1.4.1 github.com/go-task/slim-sprig/v3 v3.0.0 github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 - github.com/onsi/gomega v1.33.0 + github.com/onsi/gomega v1.33.1 golang.org/x/net v0.25.0 golang.org/x/sys v0.20.0 golang.org/x/tools v0.20.0 diff --git a/go.sum b/go.sum index 20ea87441..8a3155bb0 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= -github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= -github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= From fcf1fd732d356c5adc24378abbde70d7f5ba047f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 11 May 2024 22:02:17 +0100 Subject: [PATCH 079/102] Bump golang.org/x/tools from 0.20.0 to 0.21.0 (#1406) Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.20.0 to 0.21.0. - [Release notes](https://github.com/golang/tools/releases) - [Commits](https://github.com/golang/tools/compare/v0.20.0...v0.21.0) --- updated-dependencies: - dependency-name: golang.org/x/tools dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 30c57fc8f..b4e83a80c 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/onsi/gomega v1.33.1 golang.org/x/net v0.25.0 golang.org/x/sys v0.20.0 - golang.org/x/tools v0.20.0 + golang.org/x/tools v0.21.0 ) require ( diff --git a/go.sum b/go.sum index 8a3155bb0..392898966 100644 --- a/go.sum +++ b/go.sum @@ -17,8 +17,8 @@ golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= From d80eebe83f14a3474bfaf776fa61f48077f19815 Mon Sep 17 00:00:00 2001 From: Michael Grosser Date: Thu, 9 May 2024 09:50:51 +0200 Subject: [PATCH 080/102] fail when no tests were run and --fail-on-empty was set --- CONTRIBUTING.md | 2 +- docs/index.md | 18 ++++++++++++------ internal/suite.go | 7 ++++++- reporters/junit_report.go | 1 + types/config.go | 3 +++ 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1da92fe7e..ab932d911 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,4 +10,4 @@ Your contributions to Ginkgo are essential for its long-term maintenance and imp - Vet your changes via `go vet ./...` - Update the documentation. Ginkgo uses `godoc` comments and documentation in `docs/index.md`. You can run `bundle exec jekyll serve` in the `docs` directory to preview your changes. -Thanks for supporting Ginkgo! \ No newline at end of file +Thanks for supporting Ginkgo! diff --git a/docs/index.md b/docs/index.md index 4afe5a32d..21865f61a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2697,6 +2697,12 @@ These mechanisms can all be used in concert. They combine with the following ru - Programmatic filters always apply and result in a non-zero exit code. Any additional CLI filters only apply to the subset of specs selected by the programmatic filters. - When multiple CLI filters (`--label-filter`, `--focus-file/--skip-file`, `--focus/--skip`) are provided they are all ANDed together. The spec must satisfy the label filter query **and** any location-based filters **and** any description based filters. +#### Avoiding filtering out all tests + +Especially for CI it is useful to fail when all tests were filtered out by accident (either via skip or typo in label filter). + +`ginkgo --fail-on-empty --label-filter mytypo ./...` will fail since no test was run. + ### Repeating Spec Runs and Managing Flaky Specs Ginkgo wants to help you write reliable, deterministic, tests. Flaky specs - i.e. specs that fail _sometimes_ in non-deterministic or difficult to reason about ways - can be incredibly frustrating to debug and can erode faith in the value of a spec suite. @@ -3098,8 +3104,8 @@ SynchronizedBeforeSuite(func(ctx SpecContext) []byte { ``` are all valid interruptible signatures. Of course you can specify `context.Context` instead and can mix-and-match interruptibility between the two functions. -**Reporting** nodes `ReportAfterEach`, `ReportBeforeEach`, `ReportBeforeSuite` `ReportAfterSuite` can be made interruptible, -to do this you need to provide it a node function which accepts both `SpecContext` and `SpecReport` for `*Each` nodes and `Report` for `*Suite` nodes. +**Reporting** nodes `ReportAfterEach`, `ReportBeforeEach`, `ReportBeforeSuite` `ReportAfterSuite` can be made interruptible, +to do this you need to provide it a node function which accepts both `SpecContext` and `SpecReport` for `*Each` nodes and `Report` for `*Suite` nodes. As for **Container** nodes, since these run during the Tree Construction Phase they cannot be made interruptible and so do not accept functions that expect a context. And since the `By` annotation is simply syntactic sugar enabling more detailed spec documentation, any callbacks passed to `By` cannot be independently marked as interruptible (you should, instead, use the `context` passed into the node that you're calling `By` from). @@ -3502,7 +3508,7 @@ Ginkgo's reporting infrastructure provides an alternative solution for this use Ginkgo provides four reporting-focused nodes `ReportAfterEach`, `ReportBeforeEach` `ReportBeforeSuite`, and `ReportAfterSuite`. -`ReportAfterEach` behaves similarly to a standard `AfterEach` node and can be declared anywhere an `AfterEach` node can be declared. +`ReportAfterEach` behaves similarly to a standard `AfterEach` node and can be declared anywhere an `AfterEach` node can be declared. `ReportAfterEach` can take either a closure that accepts a single [`SpecReport`](https://pkg.go.dev/github.com/onsi/ginkgo/v2/types#SpecReport) argument or both `SpecContext` and `SpecReport` For example, we could implement a top-level ReportAfterEach that emits information about every spec to a remote server: @@ -3511,7 +3517,7 @@ ReportAfterEach(func(report SpecReport) { customFormat := fmt.Sprintf("%s | %s", report.State, report.FullText()) client.SendReport(customFormat) }) -// interruptible ReportAfterEach node +// interruptible ReportAfterEach node ReportAfterEach(func(ctx SpecContext, report SpecReport) { customFormat := fmt.Sprintf("%s | %s", report.State, report.FullText()) client.SendReport(customFormat) @@ -3522,7 +3528,7 @@ ReportAfterEach(func(ctx SpecContext, report SpecReport) { In addition, `ReportAfterEach` closures are called after a spec completes. i.e. _after_ all `AfterEach` closures have run. This gives them access to the complete final state of the spec. Note that if a failure occurs in a `ReportAfterEach` your the spec will be marked as failed. Subsequent `ReportAfterEach` closures will see the failed state, but not the closure in which the failure occurred. -`ReportAfterEach` is useful if you need to stream or emit up-to-date information about the suite as it runs. Ginkgo also provides `ReportBeforeEach` which is called before the test runs and +`ReportAfterEach` is useful if you need to stream or emit up-to-date information about the suite as it runs. Ginkgo also provides `ReportBeforeEach` which is called before the test runs and receives a preliminary `types.SpecReport` ( or both `SpecContext` and `types.SpecReport` for interruptible behaviour) - the state of this report will indicate whether the test will be skipped or is marked pending. You should be aware that when running in parallel, each parallel process will be running specs and their `ReportAfterEach`es. This means that multiple `ReportAfterEach` blocks can be running concurrently on independent processes. Given that, code like this won't work: @@ -3542,7 +3548,7 @@ ReportAfterEach(func(report SpecReport) { you'll end up with multiple processes writing to the same file and the output will be a mess. There is a better approach for this usecase... #### Reporting Nodes - ReportBeforeSuite and ReportAfterSuite -`ReportBeforeSuite` and `ReportAfterSuite` nodes behave similarly to `BeforeSuite` and `AfterSuite` and can be placed at the top-level of your suite (typically in the suite bootstrap file). +`ReportBeforeSuite` and `ReportAfterSuite` nodes behave similarly to `BeforeSuite` and `AfterSuite` and can be placed at the top-level of your suite (typically in the suite bootstrap file). `ReportBeforeSuite` node take a closure that accepts either [`Report`]((https://pkg.go.dev/github.com/onsi/ginkgo/v2/types#Report)) or, both `SpecContext` and `Report` converting the node to an interruptible node. ```go diff --git a/internal/suite.go b/internal/suite.go index a994ee3d6..a3c9e6bf1 100644 --- a/internal/suite.go +++ b/internal/suite.go @@ -489,10 +489,15 @@ func (suite *Suite) runSpecs(description string, suiteLabels Labels, suitePath s newGroup(suite).run(specs.AtIndices(groupedSpecIndices[groupedSpecIdx])) } - if specs.HasAnySpecsMarkedPending() && suite.config.FailOnPending { + if suite.config.FailOnPending && specs.HasAnySpecsMarkedPending() { suite.report.SpecialSuiteFailureReasons = append(suite.report.SpecialSuiteFailureReasons, "Detected pending specs and --fail-on-pending is set") suite.report.SuiteSucceeded = false } + + if suite.config.FailOnEmpty && specs.CountWithoutSkip() == 0 { + suite.report.SpecialSuiteFailureReasons = append(suite.report.SpecialSuiteFailureReasons, "Detected no specs ran and --fail-on-empty is set") + suite.report.SuiteSucceeded = false + } } if ranBeforeSuite { diff --git a/reporters/junit_report.go b/reporters/junit_report.go index 2a3215b51..562e0f62b 100644 --- a/reporters/junit_report.go +++ b/reporters/junit_report.go @@ -177,6 +177,7 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit {"FocusFiles", strings.Join(report.SuiteConfig.FocusFiles, ";")}, {"SkipFiles", strings.Join(report.SuiteConfig.SkipFiles, ";")}, {"FailOnPending", fmt.Sprintf("%t", report.SuiteConfig.FailOnPending)}, + {"FailOnEmpty", fmt.Sprintf("%t", report.SuiteConfig.FailOnEmpty)}, {"FailFast", fmt.Sprintf("%t", report.SuiteConfig.FailFast)}, {"FlakeAttempts", fmt.Sprintf("%d", report.SuiteConfig.FlakeAttempts)}, {"DryRun", fmt.Sprintf("%t", report.SuiteConfig.DryRun)}, diff --git a/types/config.go b/types/config.go index cef273ee1..ad92f4271 100644 --- a/types/config.go +++ b/types/config.go @@ -25,6 +25,7 @@ type SuiteConfig struct { SkipFiles []string LabelFilter string FailOnPending bool + FailOnEmpty bool FailFast bool FlakeAttempts int MustPassRepeatedly int @@ -275,6 +276,8 @@ var SuiteConfigFlags = GinkgoFlags{ Usage: "If set, ginkgo will stop running a test suite after a failure occurs."}, {KeyPath: "S.FlakeAttempts", Name: "flake-attempts", SectionKey: "failure", UsageDefaultValue: "0 - failed tests are not retried", DeprecatedName: "flakeAttempts", DeprecatedDocLink: "changed-command-line-flags", Usage: "Make up to this many attempts to run each spec. If any of the attempts succeed, the suite will not be failed."}, + {KeyPath: "S.FailOnEmpty", Name: "fail-on-empty", SectionKey: "failure", + Usage: "If set, ginkgo will mark the test suite as failed if no specs are run."}, {KeyPath: "S.DryRun", Name: "dry-run", SectionKey: "debug", DeprecatedName: "dryRun", DeprecatedDocLink: "changed-command-line-flags", Usage: "If set, ginkgo will walk the test hierarchy without actually running anything. Best paired with -v."}, From 3ffbf8ba363200cb669caba0477025cb1f552d58 Mon Sep 17 00:00:00 2001 From: Michael Grosser Date: Thu, 9 May 2024 09:26:55 +0200 Subject: [PATCH 081/102] add makefile --- CONTRIBUTING.md | 8 +++++--- Makefile | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 Makefile diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ab932d911..80de566a5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,8 +6,10 @@ Your contributions to Ginkgo are essential for its long-term maintenance and imp - Ensure adequate test coverage: - When adding to the Ginkgo library, add unit and/or integration tests (under the `integration` folder). - When adding to the Ginkgo CLI, note that there are very few unit tests. Please add an integration test. -- Make sure all the tests succeed via `ginkgo -r -p` -- Vet your changes via `go vet ./...` -- Update the documentation. Ginkgo uses `godoc` comments and documentation in `docs/index.md`. You can run `bundle exec jekyll serve` in the `docs` directory to preview your changes. +- Run `make` or: + - Install ginkgo locally via `go install ./...` + - Make sure all the tests succeed via `ginkgo -r -p` + - Vet your changes via `go vet ./...` +- Update the documentation. Ginkgo uses `godoc` comments and documentation in `docs/index.md`. You can run `bundle && bundle exec jekyll serve` in the `docs` directory to preview your changes. Thanks for supporting Ginkgo! diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..93eb2e515 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +# default task since it's first +.PHONY: all +all: install vet test + +.PHONY: install +install: + which ginkgo 2>&1 >/dev/null || go install ./... + +.PHONY: test +test: + ginkgo -r -p + +.PHONY: vet +vet: + go vet ./... From 5ce83552e545ee3e99b4480abbbfb9929bd8e0dd Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Tue, 21 May 2024 09:26:03 -0600 Subject: [PATCH 082/102] add --fail-on-empty to recommended CI flags in docs --- docs/index.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 21865f61a..a7fce4a87 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3696,7 +3696,7 @@ When running in CI you must make sure that the version of the `ginkgo` CLI you a Once you have `ginkgo` running on CI, you'll want to pick and choose the optimal set of flags for your test runs. We recommend the following set of flags when running in a continuous integration environment: ```bash -go run github.com/onsi/ginkgo/v2/ginkgo -r --procs=N --compilers=N --randomize-all --randomize-suites --fail-on-pending --keep-going --cover --coverprofile=cover.profile --race --trace --json-report=report.json --timeout=TIMEOUT --poll-progress-after=Xs --poll-progress-interval=Ys +go run github.com/onsi/ginkgo/v2/ginkgo -r --procs=N --compilers=N --randomize-all --randomize-suites --fail-on-pending --fail-on-empty --keep-going --cover --coverprofile=cover.profile --race --trace --json-report=report.json --timeout=TIMEOUT --poll-progress-after=Xs --poll-progress-interval=Ys ``` Here's why: @@ -3705,6 +3705,8 @@ Here's why: - `-procs=N` will run each suite in parallel. This can substantially speed up suites and you should experiment with different values of `N`. Note that it is not recommended that you run specs in parallel with `-p` on CI. Some CI services run on shared machines that will report (e.g.) `32` cores but will not actually give an individual account access to all those compute resources! - `--compilers=N` will control how many cores to use to compile suites in parallel. You may need to set this explicitly to avoid accidentally trying to use all `32` cores on that CI machine! - `--randomize-all` and `--randomize-suites` will randomize all specs and randomize the order in which suites run. This will help you suss out spec pollution early! +- `--fail-on-pending` will fail the suite if it contains any pending specs. These are generally only used while developing the suite and should not be committed. +- `--fail-on-empty` will fail the suite if it contains no specs or if all specs have been filtered out. This can help you ensure that the CLI filters have not filtered out all specs (which typically means the filters are malformed). - `--keep-going` will instruct Ginkgo to keep running suites, even after a suite fails. This can help you get a set of all failures instead of stopping after the first failed suite. - `--cover` and `--coverprofile=cover.profile` will compute coverage scores and generate a single coverage file for all your specs. - `--race` will run the race detector. From 9e234ea2631167a81714300910f68c412afa2eb4 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Tue, 21 May 2024 10:16:27 -0600 Subject: [PATCH 083/102] always rebuild and run ginkgo in makefile --- Makefile | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 93eb2e515..cb099aff9 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,10 @@ # default task since it's first .PHONY: all -all: install vet test - -.PHONY: install -install: - which ginkgo 2>&1 >/dev/null || go install ./... +all: vet test .PHONY: test test: - ginkgo -r -p + go run github.com/onsi/ginkgo/v2/ginkgo -r -p .PHONY: vet vet: From 42013d62fc790e61915bef369d5769ed38ec1924 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Tue, 21 May 2024 10:42:11 -0600 Subject: [PATCH 084/102] Fix table entry context edge case --- .../interrupt_and_timeout_test.go | 145 ++++++++++-------- internal/internal_integration/table_test.go | 1 + table_dsl.go | 8 +- 3 files changed, 92 insertions(+), 62 deletions(-) diff --git a/internal/internal_integration/interrupt_and_timeout_test.go b/internal/internal_integration/interrupt_and_timeout_test.go index 38b5dbba2..b3d2b170c 100644 --- a/internal/internal_integration/interrupt_and_timeout_test.go +++ b/internal/internal_integration/interrupt_and_timeout_test.go @@ -2,6 +2,7 @@ package internal_integration_test import ( "context" + "strconv" "sync" "time" @@ -1013,71 +1014,95 @@ var _ = Describe("Interrupts and Timeouts", func() { }) Describe("passing contexts to TableEntries", func() { - var times *TimeMap - BeforeEach(func() { - times = NewTimeMap() + Describe("the happy path", func() { + var times *TimeMap + BeforeEach(func() { + times = NewTimeMap() - success, _ := RunFixture(CurrentSpecReport().LeafNodeText, func() { - Context("container", func() { - DescribeTable("timeout table", - func(c SpecContext, d context.Context, key string) { - key = d.Value("key").(string) + key - rt.Run(CurrentSpecReport().LeafNodeText) - t := time.Now() - <-c.Done() - times.Set(key, time.Since(t)) - }, - func(d context.Context, key string) string { - key = d.Value("key").(string) + key - return key - }, - Entry(nil, context.WithValue(context.Background(), "key", "entry-"), "1", NodeTimeout(time.Millisecond)*100), - Entry(nil, context.WithValue(context.Background(), "key", "entry-"), "2", SpecTimeout(time.Millisecond)*150), - ) - - DescribeTable("timeout table", - func(c context.Context, key string) { - rt.Run(CurrentSpecReport().LeafNodeText) - t := time.Now() - <-c.Done() - times.Set(key, time.Since(t)) - }, - func(key string) string { - return key - }, - Entry(nil, "entry-3", NodeTimeout(time.Millisecond)*100), - Entry(nil, "entry-4", SpecTimeout(time.Millisecond)*150), - ) - - DescribeTable("timeout table", - func(c context.Context, key string) { - key = c.Value("key").(string) + key - rt.Run(CurrentSpecReport().LeafNodeText + "-" + key) - }, - func(d context.Context, key string) string { - key = d.Value("key").(string) + key - return key - }, - Entry(nil, context.WithValue(context.Background(), "key", "entry-"), "5"), - Entry(nil, context.WithValue(context.Background(), "key", "entry-"), "6"), - ) + success, _ := RunFixture(CurrentSpecReport().LeafNodeText, func() { + Context("container", func() { + DescribeTable("timeout table", + func(c SpecContext, d context.Context, key string) { + key = d.Value("key").(string) + key + rt.Run(CurrentSpecReport().LeafNodeText) + t := time.Now() + <-c.Done() + times.Set(key, time.Since(t)) + }, + func(d context.Context, key string) string { + key = d.Value("key").(string) + key + return key + }, + Entry(nil, context.WithValue(context.Background(), "key", "entry-"), "1", NodeTimeout(time.Millisecond)*100), + Entry(nil, context.WithValue(context.Background(), "key", "entry-"), "2", SpecTimeout(time.Millisecond)*150), + ) + + DescribeTable("timeout table", + func(c context.Context, key string) { + rt.Run(CurrentSpecReport().LeafNodeText) + t := time.Now() + <-c.Done() + times.Set(key, time.Since(t)) + }, + func(key string) string { + return key + }, + Entry(nil, "entry-3", NodeTimeout(time.Millisecond)*100), + Entry(nil, "entry-4", SpecTimeout(time.Millisecond)*150), + ) + + DescribeTable("timeout table", + func(c context.Context, key string) { + key = c.Value("key").(string) + key + rt.Run(CurrentSpecReport().LeafNodeText + "-" + key) + }, + func(d context.Context, key string) string { + key = d.Value("key").(string) + key + return key + }, + Entry(nil, context.WithValue(context.Background(), "key", "entry-"), "5"), + Entry(nil, context.WithValue(context.Background(), "key", "entry-"), "6"), + ) + }) }) + Ω(success).Should(Equal(false)) + }) + + It("should work", func() { + Ω(rt).Should(HaveTracked("entry-1", "entry-2", "entry-3", "entry-4", "entry-5-entry-5", "entry-6-entry-6")) + Ω(reporter.Did.Find("entry-1")).Should(HaveTimedOut()) + Ω(reporter.Did.Find("entry-2")).Should(HaveTimedOut()) + Ω(reporter.Did.Find("entry-3")).Should(HaveTimedOut()) + Ω(reporter.Did.Find("entry-4")).Should(HaveTimedOut()) + Ω(reporter.Did.Find("entry-1").Failure.ProgressReport.CurrentNodeType).Should(Equal(types.NodeTypeIt)) + + Ω(times.Get("entry-1")).Should(BeNumerically("~", 100*time.Millisecond, 50*time.Millisecond)) + Ω(times.Get("entry-2")).Should(BeNumerically("~", 150*time.Millisecond, 50*time.Millisecond)) + Ω(times.Get("entry-3")).Should(BeNumerically("~", 100*time.Millisecond, 50*time.Millisecond)) + Ω(times.Get("entry-4")).Should(BeNumerically("~", 150*time.Millisecond, 50*time.Millisecond)) }) - Ω(success).Should(Equal(false)) }) - It("should work", func() { - Ω(rt).Should(HaveTracked("entry-1", "entry-2", "entry-3", "entry-4", "entry-5-entry-5", "entry-6-entry-6")) - Ω(reporter.Did.Find("entry-1")).Should(HaveTimedOut()) - Ω(reporter.Did.Find("entry-2")).Should(HaveTimedOut()) - Ω(reporter.Did.Find("entry-3")).Should(HaveTimedOut()) - Ω(reporter.Did.Find("entry-4")).Should(HaveTimedOut()) - Ω(reporter.Did.Find("entry-1").Failure.ProgressReport.CurrentNodeType).Should(Equal(types.NodeTypeIt)) - - Ω(times.Get("entry-1")).Should(BeNumerically("~", 100*time.Millisecond, 50*time.Millisecond)) - Ω(times.Get("entry-2")).Should(BeNumerically("~", 150*time.Millisecond, 50*time.Millisecond)) - Ω(times.Get("entry-3")).Should(BeNumerically("~", 100*time.Millisecond, 50*time.Millisecond)) - Ω(times.Get("entry-4")).Should(BeNumerically("~", 150*time.Millisecond, 50*time.Millisecond)) + Describe("the edge case in #1415", func() { + var four = 4 + var nSix = -6 + DescribeTable("it supports receiving a SpecContext and works with nil parameters", func(ctx context.Context, num *int, s string, cVal string) { + Ω(ctx).ShouldNot(BeNil()) + if num == nil { + Ω(s).Should(Equal("nil")) + } else { + Ω(s).Should(Equal(strconv.Itoa(*num))) + } + if cVal != "" { + Ω(ctx.Value("key")).Should(Equal(cVal)) + } + }, + Entry("4", &four, "4", ""), + Entry("-6", &nSix, "-6", ""), + Entry("nil", nil, "nil", ""), + Entry("4 with context value", context.WithValue(context.Background(), "key", "val"), &four, "4", "val"), + Entry("nil with context value", context.WithValue(context.Background(), "key", "val"), nil, "nil", "val"), + ) }) }) }) diff --git a/internal/internal_integration/table_test.go b/internal/internal_integration/table_test.go index bf954bb63..c8d01b455 100644 --- a/internal/internal_integration/table_test.go +++ b/internal/internal_integration/table_test.go @@ -348,6 +348,7 @@ var _ = Describe("Table driven tests", func() { Ω(b).Should(Equal(c[1])) Ω(c[2]).Should(BeNil()) }, Entry("variadic arguments", 1, "one", 1, "one", nil)) + }) Describe("when table entries are marked pending", func() { diff --git a/table_dsl.go b/table_dsl.go index a3aef821b..c7de7a8be 100644 --- a/table_dsl.go +++ b/table_dsl.go @@ -269,11 +269,15 @@ func generateTable(description string, isSubtree bool, args ...interface{}) { internalNodeArgs = append(internalNodeArgs, entry.decorations...) hasContext := false - if internalBodyType.NumIn() > 0. { + if internalBodyType.NumIn() > 0 { if internalBodyType.In(0).Implements(specContextType) { hasContext = true - } else if internalBodyType.In(0).Implements(contextType) && (len(entry.parameters) == 0 || !reflect.TypeOf(entry.parameters[0]).Implements(contextType)) { + } else if internalBodyType.In(0).Implements(contextType) { hasContext = true + if len(entry.parameters) > 0 && reflect.TypeOf(entry.parameters[0]) != nil && reflect.TypeOf(entry.parameters[0]).Implements(contextType) { + // we allow you to pass in a non-nil context + hasContext = false + } } } From f010b650124cfd7f70d1dbb8f999947d8923f688 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Tue, 21 May 2024 11:16:27 -0600 Subject: [PATCH 085/102] Add --slience-skips and --force-newlines --silence-skips makes it easier to declutter test debugging sessions where only a single spec is being run --force-newlines ensures a newline character appears after every spec. this may help some CI systems flush their output. --- docs/index.md | 4 +++ reporters/default_reporter.go | 10 ++++++- reporters/default_reporter_test.go | 42 +++++++++++++++++++++++++----- types/config.go | 6 +++++ 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/docs/index.md b/docs/index.md index a7fce4a87..c2b88dcde 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2697,6 +2697,8 @@ These mechanisms can all be used in concert. They combine with the following ru - Programmatic filters always apply and result in a non-zero exit code. Any additional CLI filters only apply to the subset of specs selected by the programmatic filters. - When multiple CLI filters (`--label-filter`, `--focus-file/--skip-file`, `--focus/--skip`) are provided they are all ANDed together. The spec must satisfy the label filter query **and** any location-based filters **and** any description based filters. +If you have a large test suite and would like to avoid printing out all the `S` skip delimiters you can run with `--silence-skips` to suppress them. + #### Avoiding filtering out all tests Especially for CI it is useful to fail when all tests were filtered out by accident (either via skip or typo in label filter). @@ -3717,6 +3719,8 @@ Here's why: If running on Github actions: `--github-output` will make the output more readable in the Github actions console. +If your CI system will only flush if a newline character is seen you may want to set `--force-newlines` to ensure that the output is flushed correctly. + ### Supporting Custom Suite Configuration There are contexts where you may want to change some aspects of a suite's behavior based on user-provided configuration. There are two widely adopted means of doing this: environment variables and command-line flags. diff --git a/reporters/default_reporter.go b/reporters/default_reporter.go index 980973370..480730486 100644 --- a/reporters/default_reporter.go +++ b/reporters/default_reporter.go @@ -202,6 +202,11 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) { v := r.conf.Verbosity() inParallel := report.RunningInParallel + //should we completely omit this spec? + if report.State.Is(types.SpecStateSkipped) && r.conf.SilenceSkips { + return + } + header := r.specDenoter if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { header = fmt.Sprintf("[%s]", report.LeafNodeType) @@ -278,9 +283,12 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) { } } - // If we have no content to show, jsut emit the header and return + // If we have no content to show, just emit the header and return if !reportHasContent { r.emit(r.f(highlightColor + header + "{{/}}")) + if r.conf.ForceNewlines { + r.emit("\n") + } return } diff --git a/reporters/default_reporter_test.go b/reporters/default_reporter_test.go index b9a46612c..04f37410e 100644 --- a/reporters/default_reporter_test.go +++ b/reporters/default_reporter_test.go @@ -167,7 +167,7 @@ func S(options ...interface{}) types.SpecReport { return report } -type ConfigFlag uint8 +type ConfigFlag uint16 const ( Succinct ConfigFlag = 1 << iota @@ -177,6 +177,8 @@ const ( FullTrace ShowNodeEvents GithubOutput + SilenceSkips + ForceNewlines Parallel //used in the WillRun => DidRun specs to capture behavior when running in parallel ) @@ -208,6 +210,12 @@ func (cf ConfigFlag) String() string { if cf.Has(GithubOutput) { out = append(out, "github-output") } + if cf.Has(SilenceSkips) { + out = append(out, "silence-skips") + } + if cf.Has(ForceNewlines) { + out = append(out, "force-newlines") + } return strings.Join(out, "|") } @@ -231,6 +239,8 @@ func C(flags ...ConfigFlag) types.ReporterConfig { FullTrace: f.Has(FullTrace), ShowNodeEvents: f.Has(ShowNodeEvents), GithubOutput: f.Has(GithubOutput), + SilenceSkips: f.Has(SilenceSkips), + ForceNewlines: f.Has(ForceNewlines), } } @@ -572,7 +582,10 @@ var _ = Describe("DefaultReporter", func() { S(CLS(cl0, cl1), CTS("A", "B"), "C", cl2), Case(Succinct, Normal, Succinct|Parallel, Normal|Parallel, "{{green}}"+DENOTER+"{{/}}"), - Case(Verbose, + Case(Succinct|ForceNewlines, Normal|ForceNewlines, Succinct|Parallel|ForceNewlines, Normal|Parallel|ForceNewlines, + "{{green}}"+DENOTER+"{{/}}", + ""), + Case(Verbose, Verbose|ForceNewlines, DELIMITER, "{{/}}A {{gray}}B {{/}}{{bold}}C{{/}}", "{{gray}}cl2.go:80{{/}}", @@ -694,7 +707,10 @@ var _ = Describe("DefaultReporter", func() { ), Case(Succinct, Normal, Succinct|Parallel, Normal|Parallel, spr("{{green}}%s{{/}}", DENOTER)), - Case(Verbose, VeryVerbose, + Case(Succinct|ForceNewlines, Normal|ForceNewlines, Succinct|Parallel|ForceNewlines, Normal|Parallel|ForceNewlines, + spr("{{green}}%s{{/}}", DENOTER), + ""), + Case(Verbose, VeryVerbose, Verbose|ForceNewlines, VeryVerbose|ForceNewlines, DELIMITER, "{{/}}{{bold}}A{{/}}", "{{gray}}cl0.go:12{{/}}", @@ -722,7 +738,7 @@ var _ = Describe("DefaultReporter", func() { S(types.NodeTypeIt, "A", cl0, RE("my entry", cl1), ), - Case(Succinct, Normal, Succinct|Parallel, Normal|Parallel, + Case(Succinct, Normal, Succinct|Parallel, Normal|Parallel, Succinct|ForceNewlines, Normal|ForceNewlines, Succinct|Parallel|ForceNewlines, Normal|Parallel|ForceNewlines, DELIMITER, spr("{{green}}%s [1.000 seconds]{{/}}", DENOTER), "{{green}}{{bold}}A{{/}}", @@ -733,7 +749,7 @@ var _ = Describe("DefaultReporter", func() { " {{gray}}<< Report Entries{{/}}", DELIMITER, ""), - Case(Verbose, VeryVerbose, + Case(Verbose, VeryVerbose, Verbose|ForceNewlines, VeryVerbose|ForceNewlines, DELIMITER, "{{/}}{{bold}}A{{/}}", "{{gray}}cl0.go:12{{/}}", @@ -800,6 +816,9 @@ var _ = Describe("DefaultReporter", func() { ), Case(Succinct, Normal, Succinct|Parallel, Normal|Parallel, Succinct|ShowNodeEvents, Normal|ShowNodeEvents, spr("{{green}}%s{{/}}", DENOTER)), + Case(Succinct|ForceNewlines, Normal|ForceNewlines, Succinct|Parallel|ForceNewlines, Normal|Parallel|ForceNewlines, Succinct|ShowNodeEvents|ForceNewlines, Normal|ShowNodeEvents|ForceNewlines, + spr("{{green}}%s{{/}}", DENOTER), + ""), Case(Verbose, VeryVerbose, //nothing to see here since things are emitted while streaming, which we don't simulate DELIMITER, "{{/}}{{bold}}A{{/}}", @@ -873,7 +892,10 @@ var _ = Describe("DefaultReporter", func() { S(types.NodeTypeIt, "A", types.SpecStateSkipped, cl0), Case(Succinct, Normal, Succinct|Parallel, Normal|Parallel, Verbose, Verbose|Parallel, "{{cyan}}S{{/}}"), - Case(VeryVerbose, + Case(Succinct|ForceNewlines, Normal|ForceNewlines, Succinct|Parallel|ForceNewlines, Normal|Parallel|ForceNewlines, Verbose|ForceNewlines, Verbose|Parallel|ForceNewlines, + "{{cyan}}S{{/}}", + ""), + Case(VeryVerbose, VeryVerbose|ForceNewlines, "{{cyan}}S [SKIPPED]{{/}}", "{{cyan}}{{bold}}A{{/}}", "{{gray}}cl0.go:12{{/}}", @@ -886,6 +908,7 @@ var _ = Describe("DefaultReporter", func() { "{{gray}}cl0.go:12{{/}}", DELIMITER, ""), + Case(Succinct|SilenceSkips, Normal|SilenceSkips, Succinct|Parallel|SilenceSkips, Normal|Parallel|SilenceSkips, Verbose|SilenceSkips, Verbose|Parallel|SilenceSkips, VeryVerbose|SilenceSkips, VeryVerbose|Parallel|SilenceSkips, ""), ), Entry("a user-skipped test", S(types.NodeTypeIt, "A", types.SpecStateSkipped, cl0, @@ -931,6 +954,7 @@ var _ = Describe("DefaultReporter", func() { " {{gray}}<< Timeline{{/}}", DELIMITER, ""), + Case(Succinct|SilenceSkips, Normal|SilenceSkips, Succinct|Parallel|SilenceSkips, Normal|Parallel|SilenceSkips, Verbose|SilenceSkips, Verbose|Parallel|SilenceSkips, VeryVerbose|SilenceSkips, VeryVerbose|Parallel|SilenceSkips, ""), ), Entry("a user-skipped test with timeline content", S(types.NodeTypeIt, "A", types.SpecStateSkipped, cl0, @@ -983,12 +1007,16 @@ var _ = Describe("DefaultReporter", func() { DELIMITER, "", ), + Case(Succinct|SilenceSkips, Normal|SilenceSkips, Succinct|Parallel|SilenceSkips, Normal|Parallel|SilenceSkips, Verbose|SilenceSkips, Verbose|Parallel|SilenceSkips, VeryVerbose|SilenceSkips, VeryVerbose|Parallel|SilenceSkips, ""), ), Entry("a pending test", S(types.NodeTypeIt, "C", types.SpecStatePending, cl2, CTS("A", "B"), CLS(cl0, cl1)), Case(Succinct, Succinct|Parallel, "{{yellow}}P{{/}}"), - Case(Normal, Normal|Parallel, Verbose|Parallel, + Case(Succinct|ForceNewlines, Succinct|Parallel|ForceNewlines, + "{{yellow}}P{{/}}", + ""), + Case(Normal, Normal|Parallel, Verbose|Parallel, Normal|ForceNewlines, Normal|Parallel|ForceNewlines, Verbose|Parallel|ForceNewlines, DELIMITER, "{{yellow}}P [PENDING]{{/}}", "{{/}}A {{gray}}B {{yellow}}{{bold}}C{{/}}", diff --git a/types/config.go b/types/config.go index ad92f4271..66463cf5e 100644 --- a/types/config.go +++ b/types/config.go @@ -91,6 +91,8 @@ type ReporterConfig struct { FullTrace bool ShowNodeEvents bool GithubOutput bool + SilenceSkips bool + ForceNewlines bool JSONReport string JUnitReport string @@ -337,6 +339,10 @@ var ReporterConfigFlags = GinkgoFlags{ Usage: "If set, default reporter prints node > Enter and < Exit events when specs fail"}, {KeyPath: "R.GithubOutput", Name: "github-output", SectionKey: "output", Usage: "If set, default reporter prints easier to manage output in Github Actions."}, + {KeyPath: "R.SilenceSkips", Name: "silence-skips", SectionKey: "output", + Usage: "If set, default reporter will not print out skipped tests."}, + {KeyPath: "R.ForceNewlines", Name: "force-newlines", SectionKey: "output", + Usage: "If set, default reporter will ensure a newline appears after each test."}, {KeyPath: "R.JSONReport", Name: "json-report", UsageArgument: "filename.json", SectionKey: "output", Usage: "If set, Ginkgo will generate a JSON-formatted test report at the specified location."}, From eb27ca84327794debfca31af5faeeb66d1b1b964 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Tue, 21 May 2024 11:30:42 -0600 Subject: [PATCH 086/102] v2.18.0 --- CHANGELOG.md | 14 ++++++++++++++ types/version.go | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13be7ec6a..e0688be3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## 2.18.0 + +### Features +- Add --slience-skips and --force-newlines [f010b65] +- fail when no tests were run and --fail-on-empty was set [d80eebe] + +### Fixes +- Fix table entry context edge case [42013d6] + +### Maintenance +- Bump golang.org/x/tools from 0.20.0 to 0.21.0 (#1406) [fcf1fd7] +- Bump github.com/onsi/gomega from 1.33.0 to 1.33.1 (#1399) [8bb14fd] +- Bump golang.org/x/net from 0.24.0 to 0.25.0 (#1407) [04bfad7] + ## 2.17.3 ### Fixes diff --git a/types/version.go b/types/version.go index 52cc3abc8..cd9945415 100644 --- a/types/version.go +++ b/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.17.3" +const VERSION = "2.18.0" From cd231fdac44981705fc1b939d29a040c5b897787 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Wed, 22 May 2024 13:25:30 -0600 Subject: [PATCH 087/102] Label sets allow for more expressive label filtering --- docs/index.md | 58 ++++- .../_fixtures/filter_fixture/widget_b_test.go | 6 +- integration/filter_test.go | 6 +- internal/focus_test.go | 21 ++ internal/internal_integration/labels_test.go | 30 ++- internal/node_test.go | 4 +- types/label_filter.go | 229 +++++++++++++++++- types/label_filter_test.go | 51 ++++ 8 files changed, 391 insertions(+), 14 deletions(-) diff --git a/docs/index.md b/docs/index.md index c2b88dcde..93ef8369d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2590,8 +2590,8 @@ The real power, of labels, however, is around filtering. You can filter by labe - The `!` unary operator representing the NOT operation. - The `,` binary operator equivalent to `||`. - The `()` for grouping expressions. -- All other characters will match as label literals. Label matches are **case insensitive** and trailing and leading whitespace is trimmed. - Regular expressions can be provided using `/REGEXP/` notation. +- All other characters will match as label literals. Label matches are **case insensitive** and trailing and leading whitespace is trimmed. To build on our example above, here are some label filter queries and their behavior: @@ -2602,10 +2602,63 @@ To build on our example above, here are some label filter queries and their beha | `ginkgo --label-filter="network && !slow"` | Run specs labelled `network` that aren't `slow` | | `ginkgo --label-filter=/library/` | Run specs with labels matching the regular expression `library` - this will match the three library-related specs in our example. +##### Label Sets + +In addition to flat strings, Labels can also construct sets. If a label has the format `KEY:VALUE` then a set with key `KEY` is created and the value `VALUE` is added to the set. For example: + +```go +Describe("The Library API", Label("API:Library"), func() { + It("can fetch a list of books", func() { + // has the labels [API:Library] + // API is a set with value {Library} + }) + It("can fetch a list of books by shelf", Label("API:Shelf", "Readiness:Alpha"), func() { + // has the labels [API:Library, API:Shelf, Readiness:Alpha] + // API is a set with value {Library, Shelf} + // Readiness is a set with value {Alpha} + + }) + It("can fetch a list of books by zip code", Label("API:Geo", "Readiness:Beta"), func() { + // has the labels [API:Library, API:Geo, Readiness:Beta] + // API is a set with value {Library, Geo} + // Readiness is a set with value {Beta} + }) +}) +``` + +Label filters can operate on sets using the notation: `KEY: SET_OPERATION `. The following set operations are supported: + +| Set Operation | Argument | Description | +| --- | --- | --- | +| `isEmpty` | None | Matches if the set with key `KEY` is empty (i.e. no label of the form `KEY:*` exists) | +| `containsAny` | `SINGLE_VALUE` or `{VALUE1, VALUE2, ...}` | Matches if the `KEY` set contains _any_ of the elements in `ARGUMENT` | +| `containsAll` | `SINGLE_VALUE` or `{VALUE1, VALUE2, ...}` | Matches if the `KEY` set contains _all_ of the elements in `ARGUMENT` | +| `consistsOf` | `SINGLE_VALUE` or `{VALUE1, VALUE2, ...}` | Matches if the `KEY` set contains _exactly_ the elements in `ARGUMENT` | +| `isSubsetOf` | `SINGLE_VALUE` or `{VALUE1, VALUE2, ...}` | Matches if the elements in the `KEY` set are a subset of the elements in `ARGUMENT` | + +leading and trailing whitespace is alwasy trimmed around keys and values and comparisons are always case-insensitive. Keys and values in the filter-language set operations are always literals; regular expressions are not supported. A special note should be made about the behavior of `isSubsetOf`: if the `KEY` set is empty then the filter will always match. This is because an empty set is always a subset of any other set. + +You can combine set operations with other label filters using the logical operators. For example: `ginkgo --label-filter="integration && !slow && Readiness: isSubsetOf {Beta, RC}"` will run all tests that have the label `integration`, do not have the label `slow` and have a `Readiness` set that is a subset of `{Beta, RC}`. This would exclude `Readiness:Alpha` but include specs with `Readiness:Beta` and `Readiness:RC` as well as specs with no `Readiness:*` label. + +Some more examples: + +| Query | Behavior | +| --- | --- | +| `ginkgo --label-filter="API: consistsOf {Library, Geo}"` | Match any specs for which the `API` set contains exactly `Library` and `Geo` | +| `ginkgo --label-filter="API: containsAny Library"` | Match any specs for which the `API` set contains either `Library` | +| `ginkgo --label-filter="Readiness: isEmpty"` | Match any specs for which the `Readiness` set is empty | +| `ginkgo --label-filter="Readiness: isSubsetOf Beta && !(API: containsAny Geo)"` | Match any specs for which the `Readiness` set is a subset of `{Beta}` (or empty) and the `API` set does not contain `Geo` | + +Label sets are helpful for organizing and filtering large spec suites in which different specs satisfy multiple overlapping concerns. The use of label set filters is intended to be a more powerful and expressive alterantive to the use of regular expressions. If you find yourself using a regular expression, consider if you should be using a label set instead. + +##### Listing Labels + You can list the labels used in a given package using the `ginkgo labels` subcommand. This does a simple/naive scan of your test files for calls to `Label` and returns any labels it finds. You can iterate on different filters quickly with `ginkgo --dry-run -v --label-filter=FILTER`. This will cause Ginkgo to tell you which specs it will run for a given filter without actually running anything. +##### Runtime Label Evaluation + If you want to have finer-grained control within a test about what code to run/not-run depending on what labels match/don't match the filter you can perform a manual check against the label-filter passed into Ginkgo like so: ```go @@ -2620,6 +2673,8 @@ It("can save books remotely", Label("network", "slow", "library query") { here `GinkgoLabelFilter()` returns the configured label filter passed in via `--label-filter`. With a setup like this you could run `ginkgo --label-filter="network && !performance"` - this would select the `"can save books remotely"` spec but not run the benchmarking code in the spec. Of course, this could also have been modeled as a separate spec with the `performance` label. +##### Suite-Level Labels + Finally, in addition to specifying Labels on subject and container nodes you can also specify suite-wide labels by decorating the `RunSpecs` command with `Label`: ```go @@ -2631,7 +2686,6 @@ func TestBooks(t *testing.T) { Suite-level labels apply to the entire suite making it easy to filter out entire suites using label filters. - #### Location-Based Filtering Ginkgo allows you to filter specs based on their source code location from the command line. You do this using the `ginkgo --focus-file` and `ginkgo --skip-file` flags. Ginkgo will only run specs that are in files that _do_ match the `--focus-file` filter *and* _don't_ match the `--skip-file` filter. You can provide multiple `--focus-file` and `--skip-file` flags. The `--focus-file`s will be ORed together and the `--skip-file`s will be ORed together. diff --git a/integration/_fixtures/filter_fixture/widget_b_test.go b/integration/_fixtures/filter_fixture/widget_b_test.go index cff5c1eca..4271048e5 100644 --- a/integration/_fixtures/filter_fixture/widget_b_test.go +++ b/integration/_fixtures/filter_fixture/widget_b_test.go @@ -13,11 +13,15 @@ var _ = Describe("WidgetB", func() { }) + It("fish", Label("Feature:Alpha"), func() { + + }) + It("cat fish", func() { }) - It("dog fish", func() { + It("dog fish", Label("Feature:Beta"), func() { }) }) diff --git a/integration/filter_test.go b/integration/filter_test.go index a4f8802a2..95ef4a3a5 100644 --- a/integration/filter_test.go +++ b/integration/filter_test.go @@ -21,7 +21,7 @@ var _ = Describe("Filter", func() { "--focus-file=sprocket", "--focus-file=widget:1-24", "--focus-file=_b:24-42", "--skip-file=_c", "--json-report=report.json", - "--label-filter=TopLevelLabel && !SLOW", + "--label-filter=TopLevelLabel && !SLOW && !(Feature: containsAny Alpha)", ) Eventually(session).Should(gexec.Exit(0)) specs := Reports(fm.LoadJSONReports("filter", "report.json")[0].SpecReports) @@ -43,6 +43,8 @@ var _ = Describe("Filter", func() { "SprocketA cat", "SprocketB cat", "WidgetA cat", "WidgetB cat", "More WidgetB cat", // fish is in -focus but cat is in -skip "SprocketA cat fish", "SprocketB cat fish", "WidgetA cat fish", "WidgetB cat fish", "More WidgetB cat fish", + // Tests with Feature:Alpha + "WidgetB fish", // Tests labelled 'slow' "WidgetB dog", "SprocketB fish", @@ -95,7 +97,7 @@ var _ = Describe("Filter", func() { It("can list labels", func() { session := startGinkgo(fm.TmpDir, "labels", "-r") Eventually(session).Should(gexec.Exit(0)) - Ω(session).Should(gbytes.Say(`filter: \["TopLevelLabel", "slow"\]`)) + Ω(session).Should(gbytes.Say(`filter: \["Feature:Alpha", "Feature:Beta", "TopLevelLabel", "slow"\]`)) Ω(session).Should(gbytes.Say(`labels: \["beluga", "bird", "cat", "chicken", "cow", "dog", "giraffe", "koala", "monkey", "otter", "owl", "panda"\]`)) Ω(session).Should(gbytes.Say(`nolabels: No labels found`)) Ω(session).Should(gbytes.Say(`onepkg: \["beluga", "bird", "cat", "chicken", "cow", "dog", "giraffe", "koala", "monkey", "otter", "owl", "panda"\]`)) diff --git a/internal/focus_test.go b/internal/focus_test.go index 99f08504c..b8332669b 100644 --- a/internal/focus_test.go +++ b/internal/focus_test.go @@ -254,6 +254,27 @@ var _ = Describe("Focus", func() { }) }) + Context("when configured with a label set filter", func() { + BeforeEach(func() { + conf.LabelFilter = "Feature: consistsOf {A, B} || Feature: containsAny C" + specs = Specs{ + S(N(ntCon, Label("Feature:A", "dog")), N(ntIt, "A", Label("fish"))), //skip because fish no feature:B + S(N(ntCon, Label("Feature:A", "dog")), N(ntIt, "B", Label("apple", "Feature:B"))), //include because has Feature:A and Feature:B + S(N(ntCon, Label("Feature:A")), N(ntIt, "C", Label("Feature:B", "Feature:D"))), //skip because it has Feature:D + S(N(ntCon, Label("Feature:C")), N(ntIt, "D", Label("fish", "Feature:D"))), //include because it has Feature:C + S(N(ntCon, Label("cow")), N(ntIt, "E")), //skip because no Feature: + S(N(ntCon, Label("Feature:A", "Feature:B")), N(ntIt, "F", Pending)), //skip because pending + } + }) + + It("applies the label filters", func() { + specs, hasProgrammaticFocus := internal.ApplyFocusToSpecs(specs, description, suiteLabels, conf) + Ω(harvestSkips(specs)).Should(Equal([]bool{true, false, true, false, true, true})) + Ω(hasProgrammaticFocus).Should(BeFalse()) + + }) + }) + Context("when configured with a label filter that filters on the suite level label", func() { BeforeEach(func() { conf.LabelFilter = "cat && TopLevelLabel" diff --git a/internal/internal_integration/labels_test.go b/internal/internal_integration/labels_test.go index 09811c49e..9ed6d35be 100644 --- a/internal/internal_integration/labels_test.go +++ b/internal/internal_integration/labels_test.go @@ -27,10 +27,18 @@ var _ = Describe("Labels", func() { It("H", rt.T("H"), Label("fish", "chicken")) }) }) + Describe("feature container", Label("Feature:Beta"), func() { + It("I", rt.T("I"), Label("Feature: Gamma")) + Describe("inner container", Label(" feature : alpha "), func() { + It("J", rt.T("J"), Label("Feature:Alpha")) + It("K", rt.T("K"), Label("Feature:Delta", "Feature:Beta")) + }) + + }) }) } BeforeEach(func() { - conf.LabelFilter = "TopLevelLabel && (dog || cow)" + conf.LabelFilter = "TopLevelLabel && (dog || cow) || Feature: containsAny Alpha" success, hPF := RunFixture("labelled tests", fixture) Ω(success).Should(BeTrue()) Ω(hPF).Should(BeFalse()) @@ -68,6 +76,18 @@ var _ = Describe("Labels", func() { Ω(reporter.Did.Find("H").ContainerHierarchyLabels).Should(Equal([][]string{{}, {"giraffe"}, {"cow"}})) Ω(reporter.Did.Find("H").LeafNodeLabels).Should(Equal([]string{"fish", "chicken"})) Ω(reporter.Did.Find("H").Labels()).Should(Equal([]string{"giraffe", "cow", "fish", "chicken"})) + + Ω(reporter.Did.Find("I").ContainerHierarchyLabels).Should(Equal([][]string{{}, {"Feature:Beta"}})) + Ω(reporter.Did.Find("I").LeafNodeLabels).Should(Equal([]string{"Feature: Gamma"})) + Ω(reporter.Did.Find("I").Labels()).Should(Equal([]string{"Feature:Beta", "Feature: Gamma"})) + + Ω(reporter.Did.Find("J").ContainerHierarchyLabels).Should(Equal([][]string{{}, {"Feature:Beta"}, {"feature : alpha"}})) + Ω(reporter.Did.Find("J").LeafNodeLabels).Should(Equal([]string{"Feature:Alpha"})) + Ω(reporter.Did.Find("J").Labels()).Should(Equal([]string{"Feature:Beta", "feature : alpha", "Feature:Alpha"})) + + Ω(reporter.Did.Find("K").ContainerHierarchyLabels).Should(Equal([][]string{{}, {"Feature:Beta"}, {"feature : alpha"}})) + Ω(reporter.Did.Find("K").LeafNodeLabels).Should(Equal([]string{"Feature:Delta", "Feature:Beta"})) + Ω(reporter.Did.Find("K").Labels()).Should(Equal([]string{"Feature:Beta", "feature : alpha", "Feature:Delta"})) }) It("includes suite labels in the suite report", func() { @@ -76,11 +96,11 @@ var _ = Describe("Labels", func() { }) It("honors the LabelFilter config and skips tests appropriately", func() { - Ω(rt).Should(HaveTracked("B", "C", "D", "F", "H")) - Ω(reporter.Did.WithState(types.SpecStatePassed).Names()).Should(ConsistOf("B", "C", "D", "F", "H")) - Ω(reporter.Did.WithState(types.SpecStateSkipped).Names()).Should(ConsistOf("A", "E")) + Ω(rt).Should(HaveTracked("B", "C", "D", "F", "H", "J", "K")) + Ω(reporter.Did.WithState(types.SpecStatePassed).Names()).Should(ConsistOf("B", "C", "D", "F", "H", "J", "K")) + Ω(reporter.Did.WithState(types.SpecStateSkipped).Names()).Should(ConsistOf("A", "E", "I")) Ω(reporter.Did.WithState(types.SpecStatePending).Names()).Should(ConsistOf("G")) - Ω(reporter.End).Should(BeASuiteSummary(true, NPassed(5), NSkipped(2), NPending(1), NSpecs(8), NWillRun(5))) + Ω(reporter.End).Should(BeASuiteSummary(true, NPassed(7), NSkipped(3), NPending(1), NSpecs(11), NWillRun(7))) }) }) diff --git a/internal/node_test.go b/internal/node_test.go index 8d98e316f..138bf49fe 100644 --- a/internal/node_test.go +++ b/internal/node_test.go @@ -444,9 +444,9 @@ var _ = Describe("Constructing nodes", func() { }) It("validates labels", func() { - node, errors := internal.NewNode(dt, ntIt, "", body, cl, Label("A", "B&C", "C,D", "C,D ", " ")) + node, errors := internal.NewNode(dt, ntIt, "", body, cl, Label("A", "B&C", "C,D", "C,D ", " ", ":Foo")) Ω(node).Should(BeZero()) - Ω(errors).Should(ConsistOf(types.GinkgoErrors.InvalidLabel("B&C", cl), types.GinkgoErrors.InvalidLabel("C,D", cl), types.GinkgoErrors.InvalidLabel("C,D ", cl), types.GinkgoErrors.InvalidEmptyLabel(cl))) + Ω(errors).Should(ConsistOf(types.GinkgoErrors.InvalidLabel("B&C", cl), types.GinkgoErrors.InvalidLabel("C,D", cl), types.GinkgoErrors.InvalidLabel("C,D ", cl), types.GinkgoErrors.InvalidEmptyLabel(cl), types.GinkgoErrors.InvalidLabel(":Foo", cl))) Ω(dt.DidTrackDeprecations()).Should(BeFalse()) }) }) diff --git a/types/label_filter.go b/types/label_filter.go index b0d3b651e..7fdc8aa23 100644 --- a/types/label_filter.go +++ b/types/label_filter.go @@ -45,6 +45,83 @@ func orAction(a, b LabelFilter) LabelFilter { return func(labels []string) bool { return a(labels) || b(labels) } } +func labelSetFor(key string, labels []string) map[string]bool { + key = strings.ToLower(strings.TrimSpace(key)) + out := map[string]bool{} + for _, label := range labels { + components := strings.SplitN(label, ":", 2) + if len(components) < 2 { + continue + } + if key == strings.ToLower(strings.TrimSpace(components[0])) { + out[strings.ToLower(strings.TrimSpace(components[1]))] = true + } + } + + return out +} + +func isEmptyLabelSetAction(key string) LabelFilter { + return func(labels []string) bool { + return len(labelSetFor(key, labels)) == 0 + } +} + +func containsAnyLabelSetAction(key string, expectedValues []string) LabelFilter { + return func(labels []string) bool { + set := labelSetFor(key, labels) + for _, value := range expectedValues { + if set[value] { + return true + } + } + return false + } +} + +func containsAllLabelSetAction(key string, expectedValues []string) LabelFilter { + return func(labels []string) bool { + set := labelSetFor(key, labels) + for _, value := range expectedValues { + if !set[value] { + return false + } + } + return true + } +} + +func consistsOfLabelSetAction(key string, expectedValues []string) LabelFilter { + return func(labels []string) bool { + set := labelSetFor(key, labels) + if len(set) != len(expectedValues) { + return false + } + for _, value := range expectedValues { + if !set[value] { + return false + } + } + return true + } +} + +func isSubsetOfLabelSetAction(key string, expectedValues []string) LabelFilter { + expectedSet := map[string]bool{} + for _, value := range expectedValues { + expectedSet[value] = true + } + return func(labels []string) bool { + set := labelSetFor(key, labels) + for value := range set { + if !expectedSet[value] { + return false + } + } + return true + } +} + type lfToken uint const ( @@ -58,6 +135,9 @@ const ( lfTokenOr lfTokenRegexp lfTokenLabel + lfTokenSetKey + lfTokenSetOperation + lfTokenSetArgument lfTokenEOF ) @@ -71,6 +151,8 @@ func (l lfToken) Precedence() int { return 2 case lfTokenNot: return 3 + case lfTokenSetOperation: + return 4 } return -1 } @@ -93,6 +175,12 @@ func (l lfToken) String() string { return "/regexp/" case lfTokenLabel: return "label" + case lfTokenSetKey: + return "set_key" + case lfTokenSetOperation: + return "set_operation" + case lfTokenSetArgument: + return "set_argument" case lfTokenEOF: return "EOF" } @@ -148,6 +236,35 @@ func (tn *treeNode) constructLabelFilter(input string) (LabelFilter, error) { return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf("RegExp compilation error: %s", err)) } return matchLabelRegexAction(re), nil + case lfTokenSetOperation: + tokenSetOperation := strings.ToLower(tn.value) + if tokenSetOperation == "isempty" { + return isEmptyLabelSetAction(tn.leftNode.value), nil + } + if tn.rightNode == nil { + return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf("Set operation '%s' is missing an argument.", tn.value)) + } + + rawValues := strings.Split(tn.rightNode.value, ",") + values := make([]string, len(rawValues)) + for i := range rawValues { + values[i] = strings.ToLower(strings.TrimSpace(rawValues[i])) + if strings.ContainsAny(values[i], "&|!,()/") { + return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.rightNode.location, fmt.Sprintf("Invalid label value '%s' in set operation argument.", values[i])) + } else if values[i] == "" { + return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.rightNode.location, "Empty label value in set operation argument.") + } + } + switch tokenSetOperation { + case "containsany": + return containsAnyLabelSetAction(tn.leftNode.value, values), nil + case "containsall": + return containsAllLabelSetAction(tn.leftNode.value, values), nil + case "consistsof": + return consistsOfLabelSetAction(tn.leftNode.value, values), nil + case "issubsetof": + return isSubsetOfLabelSetAction(tn.leftNode.value, values), nil + } } if tn.rightNode == nil { @@ -203,7 +320,17 @@ func (tn *treeNode) toString(indent int) string { return out } +var validSetOperations = map[string]string{ + "containsany": "containsAny", + "containsall": "containsAll", + "consistsof": "consistsOf", + "issubsetof": "isSubsetOf", + "isempty": "isEmpty", +} + func tokenize(input string) func() (*treeNode, error) { + lastToken := lfTokenInvalid + lastValue := "" runes, i := []rune(input), 0 peekIs := func(r rune) bool { @@ -233,6 +360,53 @@ func tokenize(input string) func() (*treeNode, error) { } node := &treeNode{location: i} + defer func() { + lastToken = node.token + lastValue = node.value + }() + + if lastToken == lfTokenSetKey { + //we should get a valid set operation next + value, n := consumeUntil(" )") + if validSetOperations[strings.ToLower(value)] == "" { + return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, fmt.Sprintf("Invalid set operation '%s'.", value)) + } + i += n + node.token, node.value = lfTokenSetOperation, value + return node, nil + } + if lastToken == lfTokenSetOperation { + //we should get an argument next, if we aren't isempty + var arg = "" + origI := i + if runes[i] == '{' { + i += 1 + value, n := consumeUntil("}") + if i+n >= len(runes) { + return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i-1, "Missing closing '}' in set operation argument?") + } + i += n + 1 + arg = value + } else { + value, n := consumeUntil("&|!,()/") + i += n + arg = strings.TrimSpace(value) + } + if strings.ToLower(lastValue) == "isempty" && arg != "" { + return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, fmt.Sprintf("isEmpty does not take arguments, was passed '%s'.", arg)) + } + if arg == "" && strings.ToLower(lastValue) != "isempty" { + if i < len(runes) && runes[i] == '/' { + return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, "Set operations do not support regular expressions.") + } else { + return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, fmt.Sprintf("Set operation '%s' requires an argument.", lastValue)) + } + } + // note that we sent an empty SetArgument token if we are isempty + node.token, node.value = lfTokenSetArgument, arg + return node, nil + } + switch runes[i] { case '&': if !peekIs('&') { @@ -264,8 +438,38 @@ func tokenize(input string) func() (*treeNode, error) { i += n + 1 node.token, node.value = lfTokenRegexp, value default: - value, n := consumeUntil("&|!,()/") + value, n := consumeUntil("&|!,()/:") i += n + value = strings.TrimSpace(value) + + //are we the beginning of a set operation? + if i < len(runes) && runes[i] == ':' { + if peekIs(' ') { + if value == "" { + return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, "Missing set key.") + } + i += 1 + //we are the beginning of a set operation + node.token, node.value = lfTokenSetKey, value + return node, nil + } + additionalValue, n := consumeUntil("&|!,()/") + additionalValue = strings.TrimSpace(additionalValue) + if additionalValue == ":" { + return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, "Missing set operation.") + } + i += n + value += additionalValue + } + + valueToCheckForSetOperation := strings.ToLower(value) + for setOperation := range validSetOperations { + idx := strings.Index(valueToCheckForSetOperation, " "+setOperation) + if idx > 0 { + return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i-n+idx+1, fmt.Sprintf("Looks like you are using the set operator '%s' but did not provide a set key. Did you forget the ':'?", validSetOperations[setOperation])) + } + } + node.token, node.value = lfTokenLabel, strings.TrimSpace(value) } return node, nil @@ -307,7 +511,7 @@ LOOP: switch node.token { case lfTokenEOF: break LOOP - case lfTokenLabel, lfTokenRegexp: + case lfTokenLabel, lfTokenRegexp, lfTokenSetKey: if current.rightNode != nil { return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, "Found two adjacent labels. You need an operator between them.") } @@ -326,6 +530,18 @@ LOOP: node.setLeftNode(nodeToStealFrom.rightNode) nodeToStealFrom.setRightNode(node) current = node + case lfTokenSetOperation: + if current.rightNode == nil { + return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf("Set operation '%s' missing left hand operand.", node.value)) + } + node.setLeftNode(current.rightNode) + current.setRightNode(node) + current = node + case lfTokenSetArgument: + if current.rightNode != nil { + return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf("Unexpected set argument '%s'.", node.token)) + } + current.setRightNode(node) case lfTokenCloseGroup: firstUnmatchedOpenNode := current.firstUnmatchedOpenNode() if firstUnmatchedOpenNode == nil { @@ -354,5 +570,14 @@ func ValidateAndCleanupLabel(label string, cl CodeLocation) (string, error) { if strings.ContainsAny(out, "&|!,()/") { return "", GinkgoErrors.InvalidLabel(label, cl) } + if out[0] == ':' { + return "", GinkgoErrors.InvalidLabel(label, cl) + } + if strings.Contains(out, ":") { + components := strings.SplitN(out, ":", 2) + if len(components) < 2 || components[1] == "" { + return "", GinkgoErrors.InvalidLabel(label, cl) + } + } return out, nil } diff --git a/types/label_filter_test.go b/types/label_filter_test.go index cca3d2166..fb3139551 100644 --- a/types/label_filter_test.go +++ b/types/label_filter_test.go @@ -40,6 +40,18 @@ var _ = Describe("LabelFilter", func() { Entry(nil, " || B", 1, "Operator '||' missing left hand operand."), Entry(nil, "&&", 0, "Operator '&&' missing left hand operand."), Entry(nil, "&& || B", 0, "Operator '&&' missing left hand operand."), + Entry(nil, ":", 0, "Missing set operation."), + Entry(nil, ": isEmpty", 0, "Missing set key."), + Entry(nil, "A:", 1, "Missing set operation."), + Entry(nil, "A: B", 3, "Invalid set operation 'B'."), + Entry(nil, "A: B C", 3, "Invalid set operation 'B'."), + Entry(nil, "A isEmpty", 2, "Looks like you are using the set operator 'isEmpty' but did not provide a set key. Did you forget the ':'?"), + Entry(nil, "A bloop containsAny", 8, "Looks like you are using the set operator 'containsAny' but did not provide a set key. Did you forget the ':'?"), + Entry(nil, "A: isEmpty B", 11, "isEmpty does not take arguments, was passed 'B'."), + Entry(nil, "A: containsAny", 3, "Set operation 'containsAny' is missing an argument."), + Entry(nil, "A: containsAny {Foo", 15, "Missing closing '}' in set operation argument?"), + Entry(nil, "A: containsAny /[a]/", 15, "Set operations do not support regular expressions."), + Entry(nil, "/A/: containsAny Foo", 3, "Missing set key."), ) type matchingLabels []string @@ -163,6 +175,42 @@ var _ = Describe("LabelFilter", func() { M("dog", "cat"), M("dog", "cow"), M("cat", "cow", "dog"), M("dog", "orca"), NM("dog"), NM("cow"), NM("cat"), NM("dog", "fruit"), NM("dog", "cup"), ), + Entry("Matching set keys explicitly", "Feature:Alpha", + M("Feature:Alpha"), M("Feature:Alpha", "Feature:Beta"), M("Feature:Beta", "Feature:Alpha"), NM("Feature:Beta"), NM("dog"), + ), + Entry("Set operation: isEmpty", "Feature: isEmpty", + M(), NM("Feature:Beta"), NM("Feature:Beta", "Feature:Alpha"), M("dog"), M("Feature"), M("Widget:Foo"), + ), + Entry("Set operation: containsAny (one)", "Feature: containsAny Alpha", + M("Feature:Alpha"), M("Feature:Alpha", "Feature:Beta"), M("Feature:Beta", "Feature:Alpha"), NM("Feature:Beta"), NM("dog"), NM("Feature"), + ), + Entry("Set operation: containsAny (many)", "Feature: containsAny {Alpha, Beta}", + M("Feature:Alpha"), M("Feature: alpha", "Feature : beta"), M("Feature:Beta", "Feature:Alpha"), M("Feature:Beta"), M("Feature:Alpha", "Feature:Gamma"), NM("Feature:Gamma"), NM("dog"), NM("Feature"), + ), + Entry("Set operation: containsAll (one)", "Feature: containsAll Alpha", + M("Feature:Alpha"), M("Feature:Alpha", "Feature:Beta"), M("Feature:Beta", "Feature:Alpha"), NM("Feature:Beta"), NM("dog"), NM("Feature"), + ), + Entry("Set operation: containsAll (many)", "Feature: containsAll {Alpha, Beta}", + NM("Feature:Alpha"), M("Feature:alpha", "Feature:Beta"), M("Feature:beta", "Feature:Alpha"), M("feature:alpha", "feature: beta", "Feature:Gamma"), NM("Feature:Beta"), NM("Feature:Gamma"), NM("dog"), NM("Feature"), + ), + Entry("Set operation: consistsOf (one)", "Feature: consistsOf Alpha", + M("Feature:Alpha"), NM("Feature:Alpha", "Feature:Beta"), NM("Feature:Beta", "Feature:Alpha"), NM("Feature:Beta"), NM("dog"), NM("Feature"), + ), + Entry("Set operation: consistsOf (many)", "Feature: consistsOf {Alpha, Beta}", + NM("Feature:Alpha"), M("Feature:alpha", "Feature:Beta"), M("Feature:beta", "Feature:Alpha"), NM("feature:alpha", "feature: beta", "Feature:Gamma"), NM("Feature:Beta"), NM("Feature:Gamma"), NM("dog"), NM("Feature"), + ), + Entry("Set operation: isSubsetOf (one)", "Feature: isSubsetOf Alpha", + M("Feature:Alpha"), NM("Feature:Alpha", "Feature:Beta"), NM("Feature:Beta", "Feature:Alpha"), NM("Feature:Beta"), M("dog"), M("Feature"), M(""), + ), + Entry("Set operation: isSubsetOf (many)", "Feature: isSubsetOf {Alpha, Beta}", + M("Feature:Alpha"), M("Feature:alpha", "Feature:Beta"), M("Feature:beta", "Feature:Alpha"), NM("feature:alpha", "feature: beta", "Feature:Gamma"), M("Feature:Beta"), NM("Feature:Gamma"), M("dog"), M("Feature"), M(""), + ), + Entry("Set operations with booleans and explicit labels", "Production && (Feature: isSubsetOf {Alpha, Beta} && !(Feature: isEmpty))", + M("Production", "Feature:Alpha"), M("Production", "Feature:Beta"), M("Production", "Feature:Beta", "Feature:Alpha"), NM("Production", "dog"), NM("Production", "Feature:Gamma", "Feature:Alpha"), NM("Staging", "Feature:Alpha"), NM("Production"), NM(""), + ), + Entry("Set operation: values can have colons", "Feature: containsAny Alpha:1", + M("Feature:Alpha:1"), M("Feature: Alpha:1"), M("Feature :Alpha:1"), M("Feature : Alpha:1"), NM("Feature:Alpha:2"), NM("Feature:Alpha"), NM("Feature:Beta:1"), NM("Feature:Alpha : 1"), + ), ) cl := types.NewCodeLocation(0) @@ -190,6 +238,9 @@ var _ = Describe("LabelFilter", func() { Entry(nil, "cow()", "", types.GinkgoErrors.InvalidLabel("cow()", cl)), Entry(nil, "cow)", "", types.GinkgoErrors.InvalidLabel("cow)", cl)), Entry(nil, "cow/", "", types.GinkgoErrors.InvalidLabel("cow/", cl)), + Entry(nil, ":", "", types.GinkgoErrors.InvalidLabel(":", cl)), + Entry(nil, "Feature:", "", types.GinkgoErrors.InvalidLabel("Feature:", cl)), + Entry(nil, ":Alpha", "", types.GinkgoErrors.InvalidLabel(":Alpha", cl)), ) Describe("MustParseLabelFilter", func() { From 966a28cb713d24386362dc06f53b2786c49256cf Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Thu, 23 May 2024 12:22:16 -0600 Subject: [PATCH 088/102] Fix typos in label sets docs Co-authored-by: Patrick Ohly --- docs/index.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/index.md b/docs/index.md index 93ef8369d..689af5271 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2636,7 +2636,9 @@ Label filters can operate on sets using the notation: `KEY: SET_OPERATION Date: Thu, 23 May 2024 12:52:20 -0600 Subject: [PATCH 089/102] fix another typo --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 689af5271..2434d6f38 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2636,7 +2636,7 @@ Label filters can operate on sets using the notation: `KEY: SET_OPERATION Date: Fri, 24 May 2024 07:49:06 -0600 Subject: [PATCH 090/102] v2.19.0 --- CHANGELOG.md | 6 ++++++ types/version.go | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0688be3b..76577dc78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.19.0 + +### Features + +[Label Sets](https://onsi.github.io/ginkgo/#label-sets) allow for more expressive and flexible label filtering. + ## 2.18.0 ### Features diff --git a/types/version.go b/types/version.go index cd9945415..acab03492 100644 --- a/types/version.go +++ b/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.18.0" +const VERSION = "2.19.0" From ff41e27cde41de31abf27e4e80dffc6bde12a2da Mon Sep 17 00:00:00 2001 From: Nahshon Unna-Tsameret Date: Sun, 9 Jun 2024 15:05:23 +0300 Subject: [PATCH 091/102] [build] Allow custom name for binaries. Added the go build flag `-o` for custom path and name of the binary output of `ginkgo build`. --- ginkgo/build/build_command.go | 15 +++++++++++++- ginkgo/internal/compile.go | 14 ++++++++++++- integration/precompiled_test.go | 36 ++++++++++++++++++++++++++++++++- types/config.go | 7 +++++-- 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/ginkgo/build/build_command.go b/ginkgo/build/build_command.go index 5db5d1a7b..fd1726084 100644 --- a/ginkgo/build/build_command.go +++ b/ginkgo/build/build_command.go @@ -2,6 +2,8 @@ package build import ( "fmt" + "os" + "path" "github.com/onsi/ginkgo/v2/ginkgo/command" "github.com/onsi/ginkgo/v2/ginkgo/internal" @@ -53,7 +55,18 @@ func buildSpecs(args []string, cliConfig types.CLIConfig, goFlagsConfig types.Go if suite.State.Is(internal.TestSuiteStateFailedToCompile) { fmt.Println(suite.CompilationError.Error()) } else { - fmt.Printf("Compiled %s.test\n", suite.PackageName) + if len(goFlagsConfig.O) == 0 { + goFlagsConfig.O = path.Join(suite.Path, suite.PackageName+".test") + } else { + stat, err := os.Stat(goFlagsConfig.O) + if err != nil { + panic(err) + } + if stat.IsDir() { + goFlagsConfig.O += "/" + suite.PackageName + ".test" + } + } + fmt.Printf("Compiled %s\n", goFlagsConfig.O) } } diff --git a/ginkgo/internal/compile.go b/ginkgo/internal/compile.go index 86da7340d..48827cc5e 100644 --- a/ginkgo/internal/compile.go +++ b/ginkgo/internal/compile.go @@ -25,6 +25,18 @@ func CompileSuite(suite TestSuite, goFlagsConfig types.GoFlagsConfig) TestSuite return suite } + if len(goFlagsConfig.O) > 0 { + userDefinedPath, err := filepath.Abs(goFlagsConfig.O) + if err != nil { + suite.State = TestSuiteStateFailedToCompile + suite.CompilationError = fmt.Errorf("Failed to compute compilation target path %s:\n%s", goFlagsConfig.O, err.Error()) + return suite + } + path = userDefinedPath + } + + goFlagsConfig.O = path + ginkgoInvocationPath, _ := os.Getwd() ginkgoInvocationPath, _ = filepath.Abs(ginkgoInvocationPath) packagePath := suite.AbsPath() @@ -34,7 +46,7 @@ func CompileSuite(suite TestSuite, goFlagsConfig types.GoFlagsConfig) TestSuite suite.CompilationError = fmt.Errorf("Failed to get relative path from package to the current working directory:\n%s", err.Error()) return suite } - args, err := types.GenerateGoTestCompileArgs(goFlagsConfig, path, "./", pathToInvocationPath) + args, err := types.GenerateGoTestCompileArgs(goFlagsConfig, "./", pathToInvocationPath) if err != nil { suite.State = TestSuiteStateFailedToCompile suite.CompilationError = fmt.Errorf("Failed to generate go test compile flags:\n%s", err.Error()) diff --git a/integration/precompiled_test.go b/integration/precompiled_test.go index 201f6cbf3..b11c79a2e 100644 --- a/integration/precompiled_test.go +++ b/integration/precompiled_test.go @@ -1,12 +1,15 @@ package integration_test import ( + "os" "os/exec" + "path" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/onsi/gomega/gbytes" "github.com/onsi/gomega/gexec" + + . "github.com/onsi/ginkgo/v2" ) var _ = Describe("ginkgo build", func() { @@ -44,3 +47,34 @@ var _ = Describe("ginkgo build", func() { Ω(session).Should(gbytes.Say("Running in parallel across 2 processes")) }) }) + +var _ = Describe("ginkgo build with custom output", Label("build"), func() { + const customPath = "mycustomdir" + var fullPath string + + BeforeEach(func() { + fm.MountFixture("passing_ginkgo_tests") + fullPath = fm.PathTo("passing_ginkgo_tests", customPath) + Ω(os.Mkdir(fullPath, 0777)).To(Succeed()) + + DeferCleanup(func() { + Ω(os.RemoveAll(fullPath)).Should(Succeed()) + }) + }) + + It("should build with custom path", func() { + session := startGinkgo(fm.PathTo("passing_ginkgo_tests"), "build", "-o", customPath+"/mytestapp") + Eventually(session).Should(gexec.Exit(0)) + output := string(session.Out.Contents()) + Ω(output).Should(And(ContainSubstring("Compiled"), ContainSubstring(customPath+"/mytestapp"))) + Ω(path.Join(fullPath, "/mytestapp")).Should(BeAnExistingFile()) + }) + + It("should build with custom directory", func() { + session := startGinkgo(fm.PathTo("passing_ginkgo_tests"), "build", "-o", customPath) + Eventually(session).Should(gexec.Exit(0)) + output := string(session.Out.Contents()) + Ω(output).Should(And(ContainSubstring("Compiled"), ContainSubstring(customPath+"/passing_ginkgo_tests.test"))) + Ω(path.Join(fullPath, "/passing_ginkgo_tests.test")).Should(BeAnExistingFile()) + }) +}) diff --git a/types/config.go b/types/config.go index 66463cf5e..efd539a6b 100644 --- a/types/config.go +++ b/types/config.go @@ -219,6 +219,7 @@ type GoFlagsConfig struct { ToolExec string Work bool X bool + O string } func NewDefaultGoFlagsConfig() GoFlagsConfig { @@ -561,6 +562,8 @@ var GoBuildFlags = GinkgoFlags{ Usage: "print the name of the temporary work directory and do not delete it when exiting."}, {KeyPath: "Go.X", Name: "x", SectionKey: "go-build", Usage: "print the commands."}, + {KeyPath: "Go.O", Name: "o", SectionKey: "go-build", + Usage: "output binary path (including name)."}, } // GoRunFlags provides flags for the Ginkgo CLI run, and watch commands that capture go's run-time flags. These are passed to the compiled test binary by the ginkgo CLI @@ -614,7 +617,7 @@ func VetAndInitializeCLIAndGoConfig(cliConfig CLIConfig, goFlagsConfig GoFlagsCo } // GenerateGoTestCompileArgs is used by the Ginkgo CLI to generate command line arguments to pass to the go test -c command when compiling the test -func GenerateGoTestCompileArgs(goFlagsConfig GoFlagsConfig, destination string, packageToBuild string, pathToInvocationPath string) ([]string, error) { +func GenerateGoTestCompileArgs(goFlagsConfig GoFlagsConfig, packageToBuild string, pathToInvocationPath string) ([]string, error) { // if the user has set the CoverProfile run-time flag make sure to set the build-time cover flag to make sure // the built test binary can generate a coverprofile if goFlagsConfig.CoverProfile != "" { @@ -637,7 +640,7 @@ func GenerateGoTestCompileArgs(goFlagsConfig GoFlagsConfig, destination string, goFlagsConfig.CoverPkg = strings.Join(adjustedCoverPkgs, ",") } - args := []string{"test", "-c", "-o", destination, packageToBuild} + args := []string{"test", "-c", packageToBuild} goArgs, err := GenerateFlagArgs( GoBuildFlags, map[string]interface{}{ From 628dbb9415becabe8c58ca09f4ba9767e8369a1e Mon Sep 17 00:00:00 2001 From: "muming.zhouxi" Date: Tue, 11 Jun 2024 19:46:24 +0800 Subject: [PATCH 092/102] fix: issue-1427 --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 2434d6f38..8f71df21d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3639,7 +3639,7 @@ Given all this, we can rewrite our invalid `ReportAfterEach` example from above ReportAfterSuite("custom report", func(report Report) { f := os.Create("report.custom") for _, specReport := range report.SpecReports { - fmt.Fprintf(f, "%s | %s\n", report.FullText(), specReport.State) + fmt.Fprintf(f, "%s | %s\n", specReport.FullText(), specReport.State) } f.Close() }) From f09774112b383b2cda8f470c8301f066ae9add83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 15 Jun 2024 22:34:41 +0100 Subject: [PATCH 093/102] Bump golang.org/x/sys from 0.20.0 to 0.21.0 (#1425) Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.20.0 to 0.21.0. - [Commits](https://github.com/golang/sys/compare/v0.20.0...v0.21.0) --- updated-dependencies: - dependency-name: golang.org/x/sys dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b4e83a80c..459102cb4 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 github.com/onsi/gomega v1.33.1 golang.org/x/net v0.25.0 - golang.org/x/sys v0.20.0 + golang.org/x/sys v0.21.0 golang.org/x/tools v0.21.0 ) diff --git a/go.sum b/go.sum index 392898966..5a21c023f 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= From 2e7a930655d6d7ac3a3445d50c0a7d7cc0dddf9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 15 Jun 2024 22:36:09 +0100 Subject: [PATCH 094/102] --- (#1418) updated-dependencies: - dependency-name: github.com/go-logr/logr dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 459102cb4..9d9b887bc 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/onsi/ginkgo/v2 go 1.20 require ( - github.com/go-logr/logr v1.4.1 + github.com/go-logr/logr v1.4.2 github.com/go-task/slim-sprig/v3 v3.0.0 github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 github.com/onsi/gomega v1.33.1 diff --git a/go.sum b/go.sum index 5a21c023f..46d31c6ce 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= From b69c00d4ce8b2d0bb408b8cf6dc3317e6a9deeb1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 15 Jun 2024 22:36:40 +0100 Subject: [PATCH 095/102] Bump rexml from 3.2.6 to 3.2.8 in /docs (#1417) Bumps [rexml](https://github.com/ruby/rexml) from 3.2.6 to 3.2.8. - [Release notes](https://github.com/ruby/rexml/releases) - [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md) - [Commits](https://github.com/ruby/rexml/compare/v3.2.6...v3.2.8) --- updated-dependencies: - dependency-name: rexml dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Gemfile.lock | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 670be1d3e..927174fde 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -225,7 +225,8 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - rexml (3.2.6) + rexml (3.2.8) + strscan (>= 3.0.9) rouge (3.30.0) rubyzip (2.3.2) safe_yaml (1.0.5) @@ -239,6 +240,7 @@ GEM faraday (>= 0.17.3, < 3) simpleidn (0.2.1) unf (~> 0.1.4) + strscan (3.1.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) thread_safe (0.3.6) From 63c8c309603c777514d203eb8fea190d79949d94 Mon Sep 17 00:00:00 2001 From: pg2000 <10741029+PG2000@users.noreply.github.com> Date: Wed, 3 Jul 2024 21:37:21 +0200 Subject: [PATCH 096/102] update supported platforms for race conditions --- types/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/config.go b/types/config.go index efd539a6b..9ca408eae 100644 --- a/types/config.go +++ b/types/config.go @@ -512,7 +512,7 @@ var GinkgoCLIWatchFlags = GinkgoFlags{ // GoBuildFlags provides flags for the Ginkgo CLI build, run, and watch commands that capture go's build-time flags. These are passed to go test -c by the ginkgo CLI var GoBuildFlags = GinkgoFlags{ {KeyPath: "Go.Race", Name: "race", SectionKey: "code-and-coverage-analysis", - Usage: "enable data race detection. Supported only on linux/amd64, freebsd/amd64, darwin/amd64, windows/amd64, linux/ppc64le and linux/arm64 (only for 48-bit VMA)."}, + Usage: "enable data race detection. Supported on linux/amd64, linux/ppc64le, linux/arm64, linux/s390x, freebsd/amd64, netbsd/amd64, darwin/amd64, darwin/arm64, and windows/amd64."}, {KeyPath: "Go.Vet", Name: "vet", UsageArgument: "list", SectionKey: "code-and-coverage-analysis", Usage: `Configure the invocation of "go vet" during "go test" to use the comma-separated list of vet checks. If list is empty, "go test" runs "go vet" with a curated list of checks believed to be always worth addressing. If list is "off", "go test" does not run "go vet" at all. Available checks can be found by running 'go doc cmd/vet'`}, {KeyPath: "Go.Cover", Name: "cover", SectionKey: "code-and-coverage-analysis", From 76f4e0c7a23a0b727cb891f8bbeeacdfc546df77 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Fri, 26 Jul 2024 06:35:56 -0600 Subject: [PATCH 097/102] bump gomega --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 9d9b887bc..faaddbcb8 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/go-logr/logr v1.4.2 github.com/go-task/slim-sprig/v3 v3.0.0 github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 - github.com/onsi/gomega v1.33.1 + github.com/onsi/gomega v1.34.0 golang.org/x/net v0.25.0 golang.org/x/sys v0.21.0 golang.org/x/tools v0.21.0 @@ -15,6 +15,6 @@ require ( require ( github.com/google/go-cmp v0.6.0 // indirect golang.org/x/text v0.15.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 46d31c6ce..3c3dcc190 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= -github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os= +github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= @@ -19,8 +19,8 @@ golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= From 224be5bf5590e4159b19e750f013cb77d68f2609 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Fri, 26 Jul 2024 06:39:06 -0600 Subject: [PATCH 098/102] v2.19.1 --- CHANGELOG.md | 11 +++++++++++ types/version.go | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76577dc78..782817c39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## 2.19.1 + +### Fixes +- update supported platforms for race conditions [63c8c30] +- [build] Allow custom name for binaries. [ff41e27] + +### Maintenance +- bump gomega [76f4e0c] +- Bump rexml from 3.2.6 to 3.2.8 in /docs (#1417) [b69c00d] +- Bump golang.org/x/sys from 0.20.0 to 0.21.0 (#1425) [f097741] + ## 2.19.0 ### Features diff --git a/types/version.go b/types/version.go index acab03492..f2ee0501d 100644 --- a/types/version.go +++ b/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.19.0" +const VERSION = "2.19.1" From be5ab950a71528b5d0dc2b82f8e1ae833cff2149 Mon Sep 17 00:00:00 2001 From: Luca Comellini Date: Thu, 1 Aug 2024 23:59:40 -0700 Subject: [PATCH 099/102] Add buildvcs flag Signed-off-by: Luca Comellini --- types/config.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/types/config.go b/types/config.go index 9ca408eae..97a049e0c 100644 --- a/types/config.go +++ b/types/config.go @@ -202,6 +202,7 @@ type GoFlagsConfig struct { A bool ASMFlags string BuildMode string + BuildVCS bool Compiler string GCCGoFlags string GCFlags string @@ -528,6 +529,8 @@ var GoBuildFlags = GinkgoFlags{ Usage: "arguments to pass on each go tool asm invocation."}, {KeyPath: "Go.BuildMode", Name: "buildmode", UsageArgument: "mode", SectionKey: "go-build", Usage: "build mode to use. See 'go help buildmode' for more."}, + {KeyPath: "Go.BuildVCS", Name: "buildvcs", SectionKey: "go-build", + Usage: "adds version control information."}, {KeyPath: "Go.Compiler", Name: "compiler", UsageArgument: "name", SectionKey: "go-build", Usage: "name of compiler to use, as in runtime.Compiler (gccgo or gc)."}, {KeyPath: "Go.GCCGoFlags", Name: "gccgoflags", UsageArgument: "'[pattern=]arg list'", SectionKey: "go-build", From 7a502216054d1cfd0e243d9eabafbfaa4a1d3fb5 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Wed, 7 Aug 2024 12:05:04 -0600 Subject: [PATCH 100/102] bump all dependencies --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index faaddbcb8..ee94843e9 100644 --- a/go.mod +++ b/go.mod @@ -5,16 +5,16 @@ go 1.20 require ( github.com/go-logr/logr v1.4.2 github.com/go-task/slim-sprig/v3 v3.0.0 - github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 + github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 github.com/onsi/gomega v1.34.0 - golang.org/x/net v0.25.0 - golang.org/x/sys v0.21.0 - golang.org/x/tools v0.21.0 + golang.org/x/net v0.28.0 + golang.org/x/sys v0.23.0 + golang.org/x/tools v0.24.0 ) require ( github.com/google/go-cmp v0.6.0 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 3c3dcc190..64a0fc2c5 100644 --- a/go.sum +++ b/go.sum @@ -5,20 +5,20 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os= github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= -golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= From d303d14edd13cbc4413c3de8e8c2460754cc88ce Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Wed, 7 Aug 2024 12:06:39 -0600 Subject: [PATCH 101/102] Add update-deps to makefile --- Makefile | 7 ++++++- go.mod | 3 ++- go.sum | 6 ++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index cb099aff9..06dff97cd 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,13 @@ all: vet test .PHONY: test test: - go run github.com/onsi/ginkgo/v2/ginkgo -r -p + go run github.com/onsi/ginkgo/v2/ginkgo -r -p -randomize-all -keep-going .PHONY: vet vet: go vet ./... + +.PHONY: update-deps +update-deps: + go get -u ./... + go mod tidy \ No newline at end of file diff --git a/go.mod b/go.mod index ee94843e9..1e49ae1e5 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/go-logr/logr v1.4.2 github.com/go-task/slim-sprig/v3 v3.0.0 github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 - github.com/onsi/gomega v1.34.0 + github.com/onsi/gomega v1.34.1 golang.org/x/net v0.28.0 golang.org/x/sys v0.23.0 golang.org/x/tools v0.24.0 @@ -14,6 +14,7 @@ require ( require ( github.com/google/go-cmp v0.6.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 64a0fc2c5..05a408d5f 100644 --- a/go.sum +++ b/go.sum @@ -7,10 +7,12 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= -github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os= -github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= From 265b1a00989abc6d0b648b0e89d34f05b7c617aa Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Wed, 7 Aug 2024 12:08:42 -0600 Subject: [PATCH 102/102] v2.20.0 --- CHANGELOG.md | 9 +++++++++ types/version.go | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 782817c39..56fa8d24c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 2.20.0 + +### Features +- Add buildvcs flag [be5ab95] + +### Maintenance +- Add update-deps to makefile [d303d14] +- bump all dependencies [7a50221] + ## 2.19.1 ### Fixes diff --git a/types/version.go b/types/version.go index f2ee0501d..c6af20b68 100644 --- a/types/version.go +++ b/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.19.1" +const VERSION = "2.20.0"