diff --git a/Makefile b/Makefile index f7bc6b36..76a9a868 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ ginkgo: | $(GINKGO) MOCKGEN ?= $(GOPATH)/bin/mockgen $(MOCKGEN): @printf "$(GREEN)Installing mockgen CLI$(NORMAL)\n" - $(GO) install -mod=mod github.com/golang/mock/mockgen + $(GO) install -mod=mod go.uber.org/mock/mockgen .PHONY: mockgen mockgen: | $(MOCKGEN) @@ -50,16 +50,17 @@ install-tools: ## Install tool dependencies for development ### Golang targets .PHONY: go-mod-tidy -go-mod-tidy: ## Run 'go mod tidy' with compatibility to Go 1.18 - $(GO) mod tidy -go=1.18 +go-mod-tidy: ## Run 'go mod tidy' with compatibility to Go 1.19 + $(GO) mod tidy -go=1.19 .PHONY: go-generate-mocks go-generate-mocks: | $(MOCKGEN) ## Generate Mocks for testing - $(MOCKGEN) -destination=./pkg/raw/mock_conn_test.go -package=raw_test net Conn + $(MOCKGEN) -destination=./pkg/mock/mock_conn.go -package=mock net Conn $(MOCKGEN) -source=pkg/raw/client_types.go -package stream \ -destination=pkg/stream/mock_raw_client_test.go \ -mock_names Clienter=MockRawClient \ pkg/raw Clienter + $(GO) generate internal/command_types.go ### build diff --git a/go.mod b/go.mod index 4a29a2ee..eb2af435 100644 --- a/go.mod +++ b/go.mod @@ -3,22 +3,22 @@ module github.com/rabbitmq/rabbitmq-stream-go-client/v2 go 1.19 require ( - github.com/golang/mock v1.6.0 github.com/michaelklishin/rabbit-hole/v2 v2.13.0 - github.com/onsi/ginkgo/v2 v2.9.4 - github.com/onsi/gomega v1.27.6 + github.com/onsi/ginkgo/v2 v2.11.0 + github.com/onsi/gomega v1.27.10 + go.uber.org/mock v0.2.0 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 - golang.org/x/mod v0.11.0 + golang.org/x/mod v0.12.0 ) require ( github.com/go-logr/logr v1.2.4 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/google/go-cmp v0.5.9 // indirect - github.com/google/pprof v0.0.0-20230502171905-255e3b9b56de // indirect - golang.org/x/net v0.9.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.8.0 // indirect + github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/tools v0.11.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 5a8cc743..06f184d2 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,6 @@ github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= 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/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -34,8 +32,8 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN 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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230502171905-255e3b9b56de h1:6bMcLOeKoNo0+mTOb1ee3McF6CCKGixjLR3EDQY1Jik= -github.com/google/pprof v0.0.0-20230502171905-255e3b9b56de/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= +github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA= +github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -62,8 +60,8 @@ github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkA github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= -github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= -github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= @@ -75,8 +73,8 @@ github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2 github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= -github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= -github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= 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/rabbitmq/amqp091-go v1.7.0 h1:V5CF5qPem5OGSnEo8BoSbsDGwejg6VUJsKEdneaoTUo= @@ -93,6 +91,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= +go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -108,8 +108,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= -golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -129,8 +129,8 @@ golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -164,8 +164,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.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 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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= @@ -181,21 +181,20 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.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 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= -golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= 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= diff --git a/internal/command_types.go b/internal/command_types.go index 5649edb6..4505103d 100644 --- a/internal/command_types.go +++ b/internal/command_types.go @@ -6,7 +6,7 @@ import ( "sync" ) -//go:generate mockgen -source command_types.go -destination ../pkg/raw/mock_internal_interfaces_test.go -package raw_test +//go:generate mockgen -source command_types.go -destination ../pkg/mock/mock_internal_interfaces.go -package mock // CommandRead is the interface that wraps the Read method. // Read reads the command from the reader. diff --git a/internal/publish_error.go b/internal/publish_error.go index 7a3efaca..b80ea54a 100644 --- a/internal/publish_error.go +++ b/internal/publish_error.go @@ -3,11 +3,12 @@ package internal import ( "bufio" "bytes" + "fmt" ) type PublishErrorResponse struct { - publisherId uint8 // publisher id - publishingError PublishingError + publisherId uint8 + publishingErrors []PublishingError } type PublishingError struct { @@ -15,10 +16,26 @@ type PublishingError struct { code uint16 } -func NewPublishErrorResponse(publisherId uint8, publishingId uint64, code uint16) *PublishErrorResponse { +func NewPublishingError(pubId uint64, code uint16) *PublishingError { + return &PublishingError{publishingId: pubId, code: code} +} + +func (p *PublishingError) Error() string { + return fmt.Sprintf("error publishing message: publishingId: %d code: %#x", p.publishingId, p.code) +} + +func (p *PublishingError) PublishingId() uint64 { + return p.publishingId +} + +func (p *PublishingError) Code() uint16 { + return p.code +} + +func NewPublishErrorResponse(publisherId uint8, publishingErrors ...PublishingError) *PublishErrorResponse { return &PublishErrorResponse{ - publisherId: publisherId, - publishingError: PublishingError{publishingId: publishingId, code: code}, + publisherId: publisherId, + publishingErrors: publishingErrors, } } @@ -38,29 +55,43 @@ func (p *PublishErrorResponse) PublisherId() uint8 { return p.publisherId } -func (p *PublishErrorResponse) PublishingId() uint64 { - return p.publishingError.publishingId -} - -func (p *PublishErrorResponse) Code() uint16 { - return p.publishingError.code +func (p *PublishErrorResponse) PublishErrors() []PublishingError { + return p.publishingErrors } func (p *PublishErrorResponse) Read(rd *bufio.Reader) error { - err := readMany(rd, &p.publisherId, &p.publishingError.publishingId, &p.publishingError.code) + var errCount uint32 + err := readMany(rd, &p.publisherId, &errCount) if err != nil { return err } + for i := uint32(0); i < errCount; i++ { + var ( + publishingId uint64 + errCode uint16 + ) + err := readMany(rd, &publishingId, &errCode) + if err != nil { + return err + } + p.publishingErrors = append(p.publishingErrors, PublishingError{publishingId, errCode}) + } + return nil } func (p *PublishErrorResponse) MarshalBinary() (data []byte, err error) { buff := &bytes.Buffer{} - _, err = writeMany(buff, p.publisherId, p.publishingError.publishingId, p.publishingError.code) + _, err = writeMany(buff, p.publisherId, len(p.publishingErrors)) if err != nil { return nil, err } + + for _, publishingError := range p.publishingErrors { + _, err = writeMany(buff, publishingError.publishingId, publishingError.code) + } + data = buff.Bytes() return } diff --git a/internal/publish_error_test.go b/internal/publish_error_test.go index fe47fc78..5ad22dd6 100644 --- a/internal/publish_error_test.go +++ b/internal/publish_error_test.go @@ -17,20 +17,19 @@ var _ = Describe("Publish Error Response", func() { //Code => uint16 // code to identify the problem It("has the required fields", func() { - pubErr := NewPublishErrorResponse(1, 42, 8) + pubErr := NewPublishErrorResponse(1, PublishingError{42, 8}) Expect(pubErr.Key()).To(BeNumerically("==", 0x0004)) Expect(pubErr.MinVersion()).To(BeNumerically("==", 1)) Expect(pubErr.MaxVersion()).To(BeNumerically("==", 1)) - Expect(pubErr.PublisherId()).To(BeNumerically("==", 1)) - Expect(pubErr.PublishingId()).To(BeNumerically("==", 42)) - Expect(pubErr.Code()).To(BeNumerically("==", 8)) - + Expect(pubErr.publishingErrors).To(HaveLen(1)) + Expect(pubErr.publishingErrors[0].publishingId).To(BeNumerically("==", 42)) + Expect(pubErr.publishingErrors[0].code).To(BeNumerically("==", 8)) }) It("decodes a binary sequence", func() { buff := new(bytes.Buffer) wr := bufio.NewWriter(buff) - _, err := writeMany(wr, uint8(4), uint64(42), uint16(1)) + _, err := writeMany(wr, uint8(4), uint32(1), uint64(42), uint16(1)) Expect(err).ToNot(HaveOccurred()) Expect(wr.Flush()).To(Succeed()) @@ -38,7 +37,8 @@ var _ = Describe("Publish Error Response", func() { Expect(response.Read(bufio.NewReader(buff))).To(Succeed()) Expect(response.publisherId).To(BeNumerically("==", 4)) - Expect(response.publishingError.publishingId).To(BeNumerically("==", 42)) - Expect(response.publishingError.code).To(BeNumerically("==", 1)) + Expect(response.publishingErrors).To(HaveLen(1)) + Expect(response.publishingErrors[0].publishingId).To(BeNumerically("==", 42)) + Expect(response.publishingErrors[0].code).To(BeNumerically("==", 1)) }) }) diff --git a/internal/wire_formatting.go b/internal/wire_formatting.go index d74d6aad..afd823fc 100644 --- a/internal/wire_formatting.go +++ b/internal/wire_formatting.go @@ -52,7 +52,7 @@ func ExtractCommandCode(code uint16) uint16 { return code & 0b0111_1111_1111_1111 } -func readMany(readerStream io.Reader, args ...interface{}) error { +func readMany(readerStream io.Reader, args ...any) error { for _, arg := range args { err := readAny(readerStream, arg) if err != nil { @@ -62,7 +62,7 @@ func readMany(readerStream io.Reader, args ...interface{}) error { return nil } -func readAny(readerStream io.Reader, arg interface{}) error { +func readAny(readerStream io.Reader, arg any) error { switch arg := arg.(type) { case *int: diff --git a/pkg/raw/mock_conn_test.go b/pkg/mock/mock_conn.go similarity index 97% rename from pkg/raw/mock_conn_test.go rename to pkg/mock/mock_conn.go index cc22347c..91817fd3 100644 --- a/pkg/raw/mock_conn_test.go +++ b/pkg/mock/mock_conn.go @@ -1,8 +1,8 @@ // Code generated by MockGen. DO NOT EDIT. // Source: net (interfaces: Conn) -// Package raw_test is a generated GoMock package. -package raw_test +// Package mock is a generated GoMock package. +package mock import ( ginkgo "github.com/onsi/ginkgo/v2" @@ -10,7 +10,7 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockConn is a mock of Conn interface. diff --git a/pkg/raw/mock_internal_interfaces_test.go b/pkg/mock/mock_internal_interfaces.go similarity index 81% rename from pkg/raw/mock_internal_interfaces_test.go rename to pkg/mock/mock_internal_interfaces.go index e49c5677..ffd63c2c 100644 --- a/pkg/raw/mock_internal_interfaces_test.go +++ b/pkg/mock/mock_internal_interfaces.go @@ -1,14 +1,14 @@ // Code generated by MockGen. DO NOT EDIT. // Source: command_types.go -// Package raw_test is a generated GoMock package. -package raw_test +// Package mock is a generated GoMock package. +package mock import ( bufio "bufio" reflect "reflect" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockCommandRead is a mock of CommandRead interface. @@ -298,3 +298,68 @@ func (mr *MockSyncCommandWriteMockRecorder) Write(writer interface{}) *gomock.Ca mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockSyncCommandWrite)(nil).Write), writer) } + +// MockcommandInformer is a mock of commandInformer interface. +type MockcommandInformer struct { + ctrl *gomock.Controller + recorder *MockcommandInformerMockRecorder +} + +// MockcommandInformerMockRecorder is the mock recorder for MockcommandInformer. +type MockcommandInformerMockRecorder struct { + mock *MockcommandInformer +} + +// NewMockcommandInformer creates a new mock instance. +func NewMockcommandInformer(ctrl *gomock.Controller) *MockcommandInformer { + mock := &MockcommandInformer{ctrl: ctrl} + mock.recorder = &MockcommandInformerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockcommandInformer) EXPECT() *MockcommandInformerMockRecorder { + return m.recorder +} + +// Key mocks base method. +func (m *MockcommandInformer) Key() uint16 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Key") + ret0, _ := ret[0].(uint16) + return ret0 +} + +// Key indicates an expected call of Key. +func (mr *MockcommandInformerMockRecorder) Key() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Key", reflect.TypeOf((*MockcommandInformer)(nil).Key)) +} + +// MaxVersion mocks base method. +func (m *MockcommandInformer) MaxVersion() int16 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MaxVersion") + ret0, _ := ret[0].(int16) + return ret0 +} + +// MaxVersion indicates an expected call of MaxVersion. +func (mr *MockcommandInformerMockRecorder) MaxVersion() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaxVersion", reflect.TypeOf((*MockcommandInformer)(nil).MaxVersion)) +} + +// MinVersion mocks base method. +func (m *MockcommandInformer) MinVersion() int16 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MinVersion") + ret0, _ := ret[0].(int16) + return ret0 +} + +// MinVersion indicates an expected call of MinVersion. +func (mr *MockcommandInformerMockRecorder) MinVersion() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinVersion", reflect.TypeOf((*MockcommandInformer)(nil).MinVersion)) +} diff --git a/pkg/raw/client.go b/pkg/raw/client.go index fd9a1d1d..3725034b 100644 --- a/pkg/raw/client.go +++ b/pkg/raw/client.go @@ -360,12 +360,9 @@ func (tc *Client) handleIncoming(ctx context.Context) error { case <-ctx.Done(): return ctx.Err() case tc.publishErrorCh <- publishError: - log.Debug("sent a publish error", - "publisherId", publishError.PublisherId(), - "publishingId", publishError.PublishingId(), - "code", publishError.Code(), - ) + log.Debug("sent a publish error", "publisherId", publishError.PublisherId()) } + case internal.CommandMetadataUpdate: metadataUpdate := new(internal.MetadataUpdateResponse) err = metadataUpdate.Read(buffer) diff --git a/pkg/raw/client_test.go b/pkg/raw/client_test.go index 18ea1955..178f6376 100644 --- a/pkg/raw/client_test.go +++ b/pkg/raw/client_test.go @@ -7,11 +7,12 @@ import ( "net" "time" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/rabbitmq/rabbitmq-stream-go-client/v2/pkg/constants" + "github.com/rabbitmq/rabbitmq-stream-go-client/v2/pkg/mock" "github.com/rabbitmq/rabbitmq-stream-go-client/v2/pkg/raw" + "go.uber.org/mock/gomock" ) const ( @@ -41,14 +42,14 @@ var _ = Describe("Client", func() { fakeServerConn net.Conn fakeClientConn net.Conn mockCtrl *gomock.Controller - fakeConn *MockConn + fakeConn *mock.MockConn fakeRabbitMQ *fakeRabbitMQServer conf *raw.ClientConfiguration ) BeforeEach(func() { mockCtrl = gomock.NewController(GinkgoT()) - fakeConn = NewMockConn(mockCtrl) + fakeConn = mock.NewMockConn(mockCtrl) fakeServerConn, fakeClientConn = net.Pipe() fakeRabbitMQ = &fakeRabbitMQServer{ correlationIdSeq: autoIncrementingSequence{0}, @@ -86,10 +87,10 @@ var _ = Describe("Client", func() { Context("request", func() { When("the context is cancelled", func() { var ctx context.Context - var fakeCommandWrite *MockCommandWrite + var fakeCommandWrite *mock.MockCommandWrite BeforeEach(func() { - fakeCommandWrite = NewMockCommandWrite(mockCtrl) + fakeCommandWrite = mock.NewMockCommandWrite(mockCtrl) var cancel context.CancelFunc ctx, cancel = context.WithCancel(context.Background()) cancel() @@ -398,11 +399,12 @@ var _ = Describe("Client", func() { defer cancel() select { case <-eventuallyCtx.Done(): - Fail("did not receive from confirmation channel") + Fail("did not receive from publish-error channel") case p := <-pubErrsCh: Expect(p.PublisherId()).To(BeNumerically("==", 1)) - Expect(p.PublishingId()).To(BeNumerically("==", 5)) - Expect(p.Code()).To(BeNumerically("==", 42)) + Expect(p.PublishErrors()).To(HaveLen(1)) + Expect(p.PublishErrors()[0].PublishingId()).To(BeNumerically("==", 5)) + Expect(p.PublishErrors()[0].Code()).To(BeNumerically("==", 42)) } }, SpecTimeout(3*time.Second)) diff --git a/pkg/raw/client_types.go b/pkg/raw/client_types.go index 068efb9d..0e154593 100644 --- a/pkg/raw/client_types.go +++ b/pkg/raw/client_types.go @@ -109,6 +109,7 @@ func NewClientConfiguration(rabbitmqUrl string) (*ClientConfiguration, error) { type PublishConfirm = internal.PublishConfirmResponse type PublishError = internal.PublishErrorResponse +type PublishingError = internal.PublishingError type Chunk = internal.ChunkResponse type CreditError = internal.CreditResponse type MetadataResponse = internal.MetadataResponse diff --git a/pkg/raw/stream_suite_test.go b/pkg/raw/stream_suite_test.go index 07b64b1b..7b676853 100644 --- a/pkg/raw/stream_suite_test.go +++ b/pkg/raw/stream_suite_test.go @@ -959,16 +959,19 @@ func (rmq *fakeRabbitMQServer) fakeRabbitMQPublishError(publisherId uint8, publi // publish error frame size frameSize := 4 + // header 1 + // uint8 publisherId + 4 + // list size 8 + // publishingId 2 // publishing Error code header := internal.NewHeader(frameSize, 0x0004, 1) expectOffset1(header.Write(rmq.connection)).To(BeNumerically("==", 8), "expected to write 8 bytes") - bodyRequest, err := internal.NewPublishErrorResponse(publisherId, publishingId, code).MarshalBinary() + publishingError := internal.NewPublishingError(publishingId, code) + bodyRequest, err := internal.NewPublishErrorResponse(publisherId, *publishingError).MarshalBinary() expectOffset1(err).ToNot(HaveOccurred()) - _, err = rmq.connection.Write(bodyRequest) + nn, err := rmq.connection.Write(bodyRequest) expectOffset1(err).ToNot(HaveOccurred()) + Expect(nn).To(BeNumerically("==", 15)) } func (rmq *fakeRabbitMQServer) fakeRabbitMQSendHeartbeat() { diff --git a/pkg/stream/environment_test.go b/pkg/stream/environment_test.go index 6d16a729..be47e69f 100644 --- a/pkg/stream/environment_test.go +++ b/pkg/stream/environment_test.go @@ -3,12 +3,12 @@ package stream_test import ( "context" "errors" - "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/onsi/gomega/gbytes" "github.com/rabbitmq/rabbitmq-stream-go-client/v2/pkg/raw" "github.com/rabbitmq/rabbitmq-stream-go-client/v2/pkg/stream" + "go.uber.org/mock/gomock" "golang.org/x/exp/slog" "reflect" "sync" diff --git a/pkg/stream/mock_raw_client_test.go b/pkg/stream/mock_raw_client_test.go index aebfa678..d1068fd2 100644 --- a/pkg/stream/mock_raw_client_test.go +++ b/pkg/stream/mock_raw_client_test.go @@ -8,9 +8,9 @@ import ( context "context" reflect "reflect" - gomock "github.com/golang/mock/gomock" common "github.com/rabbitmq/rabbitmq-stream-go-client/v2/pkg/common" raw "github.com/rabbitmq/rabbitmq-stream-go-client/v2/pkg/raw" + gomock "go.uber.org/mock/gomock" ) // MockRawClient is a mock of Clienter interface.