Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Cai <jcai@gitlab.com>2019-05-18 02:33:16 +0300
committerJohn Cai <jcai@gitlab.com>2019-05-18 02:33:16 +0300
commitc3ce2a347d6f3bfd5a8ca4183e4ecadde3c50d0e (patch)
tree3358d918ec314c387da9697a3524254d546f4ec2
parent72f2e61f1de98d4b824d842e8e21587bf6c915cb (diff)
parentabc6a9f87aaa00bd6d0c137406d157db2947c028 (diff)
Merge branch 'po-fork-proxy' into 'master'
Absorb grpc-proxy into Gitaly See merge request gitlab-org/gitaly!1248
-rw-r--r--NOTICE393
-rw-r--r--changelogs/unreleased/po-fork-proxy.yml5
-rw-r--r--internal/praefect/coordinator.go2
-rw-r--r--internal/praefect/grpc-proxy/LICENSE.txt (renamed from vendor/github.com/mwitkow/grpc-proxy/LICENSE.txt)0
-rw-r--r--internal/praefect/grpc-proxy/README.md59
-rwxr-xr-xinternal/praefect/grpc-proxy/checkup.sh21
-rwxr-xr-xinternal/praefect/grpc-proxy/fixup.sh31
-rw-r--r--internal/praefect/grpc-proxy/proxy/DOC.md (renamed from vendor/github.com/mwitkow/grpc-proxy/proxy/DOC.md)0
l---------internal/praefect/grpc-proxy/proxy/README.md1
-rw-r--r--internal/praefect/grpc-proxy/proxy/codec.go (renamed from vendor/github.com/mwitkow/grpc-proxy/proxy/codec.go)4
-rw-r--r--internal/praefect/grpc-proxy/proxy/codec_test.go24
-rw-r--r--internal/praefect/grpc-proxy/proxy/director.go (renamed from vendor/github.com/mwitkow/grpc-proxy/proxy/director.go)0
-rw-r--r--internal/praefect/grpc-proxy/proxy/doc.go (renamed from vendor/github.com/mwitkow/grpc-proxy/proxy/doc.go)0
-rw-r--r--internal/praefect/grpc-proxy/proxy/examples_test.go64
-rw-r--r--internal/praefect/grpc-proxy/proxy/handler.go (renamed from vendor/github.com/mwitkow/grpc-proxy/proxy/handler.go)5
-rw-r--r--internal/praefect/grpc-proxy/proxy/handler_test.go267
-rw-r--r--internal/praefect/grpc-proxy/testdata/Makefile11
-rw-r--r--internal/praefect/grpc-proxy/testdata/test.pb.go375
-rw-r--r--internal/praefect/grpc-proxy/testdata/test.proto29
-rw-r--r--internal/praefect/server.go2
-rw-r--r--internal/praefect/server_test.go2
-rw-r--r--vendor/github.com/mwitkow/grpc-proxy/proxy/README.md83
-rw-r--r--vendor/github.com/stretchr/testify/LICENSE35
-rw-r--r--vendor/github.com/stretchr/testify/suite/doc.go65
-rw-r--r--vendor/github.com/stretchr/testify/suite/interfaces.go46
-rw-r--r--vendor/github.com/stretchr/testify/suite/suite.go166
-rw-r--r--vendor/vendor.json12
27 files changed, 1394 insertions, 308 deletions
diff --git a/NOTICE b/NOTICE
index 9920d3dca..ee50990a3 100644
--- a/NOTICE
+++ b/NOTICE
@@ -101,6 +101,181 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LICENSE.txt - gitlab.com/gitlab-org/gitaly/internal/praefect/grpc-proxy
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LICENSE - gitlab.com/gitlab-org/gitaly/vendor/github.com/Bowery/prompt
The MIT License (MIT)
@@ -1482,181 +1657,6 @@ LICENSE - gitlab.com/gitlab-org/gitaly/vendor/github.com/matttproud/golang_proto
NOTICE - gitlab.com/gitlab-org/gitaly/vendor/github.com/matttproud/golang_protobuf_extensions
Copyright 2012 Matt T. Proud (matt.proud@gmail.com)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-LICENSE.txt - gitlab.com/gitlab-org/gitaly/vendor/github.com/mwitkow/grpc-proxy
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LICENSE - gitlab.com/gitlab-org/gitaly/vendor/github.com/opentracing/opentracing-go
Apache License
Version 2.0, January 2004
@@ -2806,28 +2806,27 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LICENSE - gitlab.com/gitlab-org/gitaly/vendor/github.com/stretchr/testify
-Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
-
-Please consider promoting this project if you find it useful.
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of the Software,
-and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
-OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
-OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+MIT License
+
+Copyright (c) 2012-2018 Mat Ryer and Tyler Bunnell
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LICENSE - gitlab.com/gitlab-org/gitaly/vendor/github.com/tinylib/msgp
Copyright (c) 2014 Philip Hofer
diff --git a/changelogs/unreleased/po-fork-proxy.yml b/changelogs/unreleased/po-fork-proxy.yml
new file mode 100644
index 000000000..afa0ce0f8
--- /dev/null
+++ b/changelogs/unreleased/po-fork-proxy.yml
@@ -0,0 +1,5 @@
+---
+title: Absorb grpc-proxy into Gitaly
+merge_request: 1248
+author:
+type: other
diff --git a/internal/praefect/coordinator.go b/internal/praefect/coordinator.go
index 9c6634a2e..61cd08be0 100644
--- a/internal/praefect/coordinator.go
+++ b/internal/praefect/coordinator.go
@@ -8,9 +8,9 @@ import (
"gitlab.com/gitlab-org/gitaly/internal/praefect/protoregistry"
"github.com/golang/protobuf/protoc-gen-go/descriptor"
- "github.com/mwitkow/grpc-proxy/proxy"
"github.com/sirupsen/logrus"
"gitlab.com/gitlab-org/gitaly/client"
+ "gitlab.com/gitlab-org/gitaly/internal/praefect/grpc-proxy/proxy"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
diff --git a/vendor/github.com/mwitkow/grpc-proxy/LICENSE.txt b/internal/praefect/grpc-proxy/LICENSE.txt
index cbfdef8c5..cbfdef8c5 100644
--- a/vendor/github.com/mwitkow/grpc-proxy/LICENSE.txt
+++ b/internal/praefect/grpc-proxy/LICENSE.txt
diff --git a/internal/praefect/grpc-proxy/README.md b/internal/praefect/grpc-proxy/README.md
new file mode 100644
index 000000000..06195e40f
--- /dev/null
+++ b/internal/praefect/grpc-proxy/README.md
@@ -0,0 +1,59 @@
+# gRPC Proxy
+
+[![Travis Build](https://travis-ci.org/mwitkow/grpc-proxy.svg?branch=master)](https://travis-ci.org/mwitkow/grpc-proxy)
+[![Go Report Card](https://goreportcard.com/badge/github.com/mwitkow/grpc-proxy)](https://goreportcard.com/report/github.com/mwitkow/grpc-proxy)
+[![GoDoc](http://img.shields.io/badge/GoDoc-Reference-blue.svg)](https://godoc.org/github.com/mwitkow/grpc-proxy)
+[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
+
+[gRPC Go](https://github.com/grpc/grpc-go) Proxy server
+
+## Project Goal
+
+Build a transparent reverse proxy for gRPC targets that will make it easy to expose gRPC services
+over the internet. This includes:
+ * no needed knowledge of the semantics of requests exchanged in the call (independent rollouts)
+ * easy, declarative definition of backends and their mappings to frontends
+ * simple round-robin load balancing of inbound requests from a single connection to multiple backends
+
+The project now exists as a **proof of concept**, with the key piece being the `proxy` package that
+is a generic gRPC reverse proxy handler.
+
+## Proxy Handler
+
+The package [`proxy`](proxy/) contains a generic gRPC reverse proxy handler that allows a gRPC server to
+not know about registered handlers or their data types. Please consult the docs, here's an exaple usage.
+
+Defining a `StreamDirector` that decides where (if at all) to send the request
+```go
+director = func(ctx context.Context, fullMethodName string) (*grpc.ClientConn, error) {
+ // Make sure we never forward internal services.
+ if strings.HasPrefix(fullMethodName, "/com.example.internal.") {
+ return nil, grpc.Errorf(codes.Unimplemented, "Unknown method")
+ }
+ md, ok := metadata.FromContext(ctx)
+ if ok {
+ // Decide on which backend to dial
+ if val, exists := md[":authority"]; exists && val[0] == "staging.api.example.com" {
+ // Make sure we use DialContext so the dialing can be cancelled/time out together with the context.
+ return grpc.DialContext(ctx, "api-service.staging.svc.local", grpc.WithCodec(proxy.Codec()))
+ } else if val, exists := md[":authority"]; exists && val[0] == "api.example.com" {
+ return grpc.DialContext(ctx, "api-service.prod.svc.local", grpc.WithCodec(proxy.Codec()))
+ }
+ }
+ return nil, grpc.Errorf(codes.Unimplemented, "Unknown method")
+}
+```
+Then you need to register it with a `grpc.Server`. The server may have other handlers that will be served
+locally:
+
+```go
+server := grpc.NewServer(
+ grpc.CustomCodec(proxy.Codec()),
+ grpc.UnknownServiceHandler(proxy.TransparentHandler(director)))
+pb_test.RegisterTestServiceServer(server, &testImpl{})
+```
+
+## License
+
+`grpc-proxy` is released under the Apache 2.0 license. See [LICENSE.txt](LICENSE.txt).
+
diff --git a/internal/praefect/grpc-proxy/checkup.sh b/internal/praefect/grpc-proxy/checkup.sh
new file mode 100755
index 000000000..37e9aac6e
--- /dev/null
+++ b/internal/praefect/grpc-proxy/checkup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# Script that checks up code (govet).
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
+
+function print_real_go_files {
+ grep --files-without-match 'DO NOT EDIT!' $(find . -iname '*.go')
+}
+
+function govet_all {
+ ret=0
+ for i in $(print_real_go_files); do
+ output=$(go tool vet -all=true -tests=false ${i})
+ ret=$(($ret | $?))
+ echo -n ${output}
+ done;
+ return ${ret}
+}
+
+govet_all
+echo "returning $?" \ No newline at end of file
diff --git a/internal/praefect/grpc-proxy/fixup.sh b/internal/praefect/grpc-proxy/fixup.sh
new file mode 100755
index 000000000..5b4a66ade
--- /dev/null
+++ b/internal/praefect/grpc-proxy/fixup.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# Script that checks the code for errors.
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
+
+function print_real_go_files {
+ grep --files-without-match 'DO NOT EDIT!' $(find . -iname '*.go')
+}
+
+function generate_markdown {
+ echo "Generating markdown"
+ oldpwd=$(pwd)
+ for i in $(find . -iname 'doc.go'); do
+ dir=${i%/*}
+ echo "$dir"
+ cd ${dir}
+ ${GOPATH}/bin/godocdown -heading=Title -o DOC.md
+ ln -s DOC.md README.md 2> /dev/null # can fail
+ cd ${oldpwd}
+ done;
+}
+
+function goimports_all {
+ echo "Running goimports"
+ goimports -l -w $(print_real_go_files)
+ return $?
+}
+
+generate_markdown
+goimports_all
+echo "returning $?" \ No newline at end of file
diff --git a/vendor/github.com/mwitkow/grpc-proxy/proxy/DOC.md b/internal/praefect/grpc-proxy/proxy/DOC.md
index 85c411a10..85c411a10 100644
--- a/vendor/github.com/mwitkow/grpc-proxy/proxy/DOC.md
+++ b/internal/praefect/grpc-proxy/proxy/DOC.md
diff --git a/internal/praefect/grpc-proxy/proxy/README.md b/internal/praefect/grpc-proxy/proxy/README.md
new file mode 120000
index 000000000..71bfc07c9
--- /dev/null
+++ b/internal/praefect/grpc-proxy/proxy/README.md
@@ -0,0 +1 @@
+DOC.md \ No newline at end of file
diff --git a/vendor/github.com/mwitkow/grpc-proxy/proxy/codec.go b/internal/praefect/grpc-proxy/proxy/codec.go
index 846b9c4eb..24d5f5cea 100644
--- a/vendor/github.com/mwitkow/grpc-proxy/proxy/codec.go
+++ b/internal/praefect/grpc-proxy/proxy/codec.go
@@ -1,5 +1,9 @@
package proxy
+// TODO: remove the following linter override when the deprecations are fixed
+// in issue https://gitlab.com/gitlab-org/gitaly/issues/1663
+//lint:file-ignore SA1019 Ignore all gRPC deprecations until issue #1663
+
import (
"fmt"
diff --git a/internal/praefect/grpc-proxy/proxy/codec_test.go b/internal/praefect/grpc-proxy/proxy/codec_test.go
new file mode 100644
index 000000000..dd3893c16
--- /dev/null
+++ b/internal/praefect/grpc-proxy/proxy/codec_test.go
@@ -0,0 +1,24 @@
+package proxy
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestCodec_ReadYourWrites(t *testing.T) {
+ framePtr := &frame{}
+ data := []byte{0xDE, 0xAD, 0xBE, 0xEF}
+ codec := rawCodec{}
+ require.NoError(t, codec.Unmarshal(data, framePtr), "unmarshalling must go ok")
+ out, err := codec.Marshal(framePtr)
+ require.NoError(t, err, "no marshal error")
+ require.Equal(t, data, out, "output and data must be the same")
+
+ // reuse
+ require.NoError(t, codec.Unmarshal([]byte{0x55}, framePtr), "unmarshalling must go ok")
+ out, err = codec.Marshal(framePtr)
+ require.NoError(t, err, "no marshal error")
+ require.Equal(t, []byte{0x55}, out, "output and data must be the same")
+
+}
diff --git a/vendor/github.com/mwitkow/grpc-proxy/proxy/director.go b/internal/praefect/grpc-proxy/proxy/director.go
index 371ca6050..371ca6050 100644
--- a/vendor/github.com/mwitkow/grpc-proxy/proxy/director.go
+++ b/internal/praefect/grpc-proxy/proxy/director.go
diff --git a/vendor/github.com/mwitkow/grpc-proxy/proxy/doc.go b/internal/praefect/grpc-proxy/proxy/doc.go
index 01328f332..01328f332 100644
--- a/vendor/github.com/mwitkow/grpc-proxy/proxy/doc.go
+++ b/internal/praefect/grpc-proxy/proxy/doc.go
diff --git a/internal/praefect/grpc-proxy/proxy/examples_test.go b/internal/praefect/grpc-proxy/proxy/examples_test.go
new file mode 100644
index 000000000..36580dbdd
--- /dev/null
+++ b/internal/praefect/grpc-proxy/proxy/examples_test.go
@@ -0,0 +1,64 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+// TODO: remove the following linter override when the deprecations are fixed
+// in issue https://gitlab.com/gitlab-org/gitaly/issues/1663
+//lint:file-ignore SA1019 Ignore all gRPC deprecations until issue #1663
+
+package proxy_test
+
+import (
+ "strings"
+
+ "gitlab.com/gitlab-org/gitaly/internal/praefect/grpc-proxy/proxy"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/metadata"
+)
+
+var (
+ director proxy.StreamDirector
+)
+
+func ExampleRegisterService() {
+ // A gRPC server with the proxying codec enabled.
+ server := grpc.NewServer(grpc.CustomCodec(proxy.Codec()))
+ // Register a TestService with 4 of its methods explicitly.
+ proxy.RegisterService(server, director,
+ "mwitkow.testproto.TestService",
+ "PingEmpty", "Ping", "PingError", "PingList")
+}
+
+func ExampleTransparentHandler() {
+ grpc.NewServer(
+ grpc.CustomCodec(proxy.Codec()),
+ grpc.UnknownServiceHandler(proxy.TransparentHandler(director)))
+}
+
+// Provide sa simple example of a director that shields internal services and dials a staging or production backend.
+// This is a *very naive* implementation that creates a new connection on every request. Consider using pooling.
+func ExampleStreamDirector() {
+ director = func(ctx context.Context, fullMethodName string) (context.Context, *grpc.ClientConn, error) {
+ // Make sure we never forward internal services.
+ if strings.HasPrefix(fullMethodName, "/com.example.internal.") {
+ return nil, nil, grpc.Errorf(codes.Unimplemented, "Unknown method")
+ }
+ md, ok := metadata.FromIncomingContext(ctx)
+ // Copy the inbound metadata explicitly.
+ outCtx, _ := context.WithCancel(ctx)
+ outCtx = metadata.NewOutgoingContext(outCtx, md.Copy())
+ if ok {
+ // Decide on which backend to dial
+ if val, exists := md[":authority"]; exists && val[0] == "staging.api.example.com" {
+ // Make sure we use DialContext so the dialing can be cancelled/time out together with the context.
+ conn, err := grpc.DialContext(ctx, "api-service.staging.svc.local", grpc.WithCodec(proxy.Codec()))
+ return outCtx, conn, err
+ } else if val, exists := md[":authority"]; exists && val[0] == "api.example.com" {
+ conn, err := grpc.DialContext(ctx, "api-service.prod.svc.local", grpc.WithCodec(proxy.Codec()))
+ return outCtx, conn, err
+ }
+ }
+ return nil, nil, grpc.Errorf(codes.Unimplemented, "Unknown method")
+ }
+}
diff --git a/vendor/github.com/mwitkow/grpc-proxy/proxy/handler.go b/internal/praefect/grpc-proxy/proxy/handler.go
index 752f892a1..998cd2607 100644
--- a/vendor/github.com/mwitkow/grpc-proxy/proxy/handler.go
+++ b/internal/praefect/grpc-proxy/proxy/handler.go
@@ -1,6 +1,10 @@
// Copyright 2017 Michal Witkowski. All Rights Reserved.
// See LICENSE for licensing terms.
+// TODO: remove the following linter override when the deprecations are fixed
+// in issue https://gitlab.com/gitlab-org/gitaly/issues/1663
+//lint:file-ignore SA1019 Ignore all gRPC deprecations until issue #1663
+
package proxy
import (
@@ -88,7 +92,6 @@ func (s *handler) handler(srv interface{}, serverStream grpc.ServerStream) error
// this is the happy case where the sender has encountered io.EOF, and won't be sending anymore./
// the clientStream>serverStream may continue pumping though.
clientStream.CloseSend()
- break
} else {
// however, we may have gotten a receive error (stream disconnected, a read error etc) in which case we need
// to cancel the clientStream to the backend, let all of its goroutines be freed up by the CancelFunc and
diff --git a/internal/praefect/grpc-proxy/proxy/handler_test.go b/internal/praefect/grpc-proxy/proxy/handler_test.go
new file mode 100644
index 000000000..f5a24914c
--- /dev/null
+++ b/internal/praefect/grpc-proxy/proxy/handler_test.go
@@ -0,0 +1,267 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+// TODO: remove the following linter override when the deprecations are fixed
+// in issue https://gitlab.com/gitlab-org/gitaly/issues/1663
+//lint:file-ignore SA1019 Ignore all gRPC deprecations until issue #1663
+
+package proxy_test
+
+import (
+ "io"
+ "log"
+ "net"
+ "os"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "github.com/stretchr/testify/suite"
+ "gitlab.com/gitlab-org/gitaly/internal/praefect/grpc-proxy/proxy"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/grpclog"
+ "google.golang.org/grpc/metadata"
+
+ "fmt"
+
+ pb "gitlab.com/gitlab-org/gitaly/internal/praefect/grpc-proxy/testdata"
+)
+
+const (
+ pingDefaultValue = "I like kittens."
+ clientMdKey = "test-client-header"
+ serverHeaderMdKey = "test-client-header"
+ serverTrailerMdKey = "test-client-trailer"
+
+ rejectingMdKey = "test-reject-rpc-if-in-context"
+
+ countListResponses = 20
+)
+
+// asserting service is implemented on the server side and serves as a handler for stuff
+type assertingService struct {
+ t *testing.T
+}
+
+func (s *assertingService) PingEmpty(ctx context.Context, _ *pb.Empty) (*pb.PingResponse, error) {
+ // Check that this call has client's metadata.
+ md, ok := metadata.FromIncomingContext(ctx)
+ assert.True(s.t, ok, "PingEmpty call must have metadata in context")
+ _, ok = md[clientMdKey]
+ assert.True(s.t, ok, "PingEmpty call must have clients's custom headers in metadata")
+ return &pb.PingResponse{Value: pingDefaultValue, Counter: 42}, nil
+}
+
+func (s *assertingService) Ping(ctx context.Context, ping *pb.PingRequest) (*pb.PingResponse, error) {
+ // Send user trailers and headers.
+ grpc.SendHeader(ctx, metadata.Pairs(serverHeaderMdKey, "I like turtles."))
+ grpc.SetTrailer(ctx, metadata.Pairs(serverTrailerMdKey, "I like ending turtles."))
+ return &pb.PingResponse{Value: ping.Value, Counter: 42}, nil
+}
+
+func (s *assertingService) PingError(ctx context.Context, ping *pb.PingRequest) (*pb.Empty, error) {
+ return nil, grpc.Errorf(codes.FailedPrecondition, "Userspace error.")
+}
+
+func (s *assertingService) PingList(ping *pb.PingRequest, stream pb.TestService_PingListServer) error {
+ // Send user trailers and headers.
+ stream.SendHeader(metadata.Pairs(serverHeaderMdKey, "I like turtles."))
+ for i := 0; i < countListResponses; i++ {
+ stream.Send(&pb.PingResponse{Value: ping.Value, Counter: int32(i)})
+ }
+ stream.SetTrailer(metadata.Pairs(serverTrailerMdKey, "I like ending turtles."))
+ return nil
+}
+
+func (s *assertingService) PingStream(stream pb.TestService_PingStreamServer) error {
+ stream.SendHeader(metadata.Pairs(serverHeaderMdKey, "I like turtles."))
+ counter := int32(0)
+ for {
+ ping, err := stream.Recv()
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ require.NoError(s.t, err, "can't fail reading stream")
+ return err
+ }
+ pong := &pb.PingResponse{Value: ping.Value, Counter: counter}
+ if err := stream.Send(pong); err != nil {
+ require.NoError(s.t, err, "can't fail sending back a pong")
+ }
+ counter += 1
+ }
+ stream.SetTrailer(metadata.Pairs(serverTrailerMdKey, "I like ending turtles."))
+ return nil
+}
+
+// ProxyHappySuite tests the "happy" path of handling: that everything works in absence of connection issues.
+type ProxyHappySuite struct {
+ suite.Suite
+
+ serverListener net.Listener
+ server *grpc.Server
+ proxyListener net.Listener
+ proxy *grpc.Server
+ serverClientConn *grpc.ClientConn
+
+ client *grpc.ClientConn
+ testClient pb.TestServiceClient
+}
+
+func (s *ProxyHappySuite) ctx() context.Context {
+ // Make all RPC calls last at most 1 sec, meaning all async issues or deadlock will not kill tests.
+ ctx, _ := context.WithTimeout(context.TODO(), 120*time.Second)
+ return ctx
+}
+
+func (s *ProxyHappySuite) TestPingEmptyCarriesClientMetadata() {
+ ctx := metadata.NewOutgoingContext(s.ctx(), metadata.Pairs(clientMdKey, "true"))
+ out, err := s.testClient.PingEmpty(ctx, &pb.Empty{})
+ require.NoError(s.T(), err, "PingEmpty should succeed without errors")
+ require.Equal(s.T(), &pb.PingResponse{Value: pingDefaultValue, Counter: 42}, out)
+}
+
+func (s *ProxyHappySuite) TestPingEmpty_StressTest() {
+ for i := 0; i < 50; i++ {
+ s.TestPingEmptyCarriesClientMetadata()
+ }
+}
+
+func (s *ProxyHappySuite) TestPingCarriesServerHeadersAndTrailers() {
+ headerMd := make(metadata.MD)
+ trailerMd := make(metadata.MD)
+ // This is an awkward calling convention... but meh.
+ out, err := s.testClient.Ping(s.ctx(), &pb.PingRequest{Value: "foo"}, grpc.Header(&headerMd), grpc.Trailer(&trailerMd))
+ require.NoError(s.T(), err, "Ping should succeed without errors")
+ require.Equal(s.T(), &pb.PingResponse{Value: "foo", Counter: 42}, out)
+ assert.Contains(s.T(), headerMd, serverHeaderMdKey, "server response headers must contain server data")
+ assert.Len(s.T(), trailerMd, 1, "server response trailers must contain server data")
+}
+
+func (s *ProxyHappySuite) TestPingErrorPropagatesAppError() {
+ _, err := s.testClient.PingError(s.ctx(), &pb.PingRequest{Value: "foo"})
+ require.Error(s.T(), err, "PingError should never succeed")
+ assert.Equal(s.T(), codes.FailedPrecondition, grpc.Code(err))
+ assert.Equal(s.T(), "Userspace error.", grpc.ErrorDesc(err))
+}
+
+func (s *ProxyHappySuite) TestDirectorErrorIsPropagated() {
+ // See SetupSuite where the StreamDirector has a special case.
+ ctx := metadata.NewOutgoingContext(s.ctx(), metadata.Pairs(rejectingMdKey, "true"))
+ _, err := s.testClient.Ping(ctx, &pb.PingRequest{Value: "foo"})
+ require.Error(s.T(), err, "Director should reject this RPC")
+ assert.Equal(s.T(), codes.PermissionDenied, grpc.Code(err))
+ assert.Equal(s.T(), "testing rejection", grpc.ErrorDesc(err))
+}
+
+func (s *ProxyHappySuite) TestPingStream_FullDuplexWorks() {
+ stream, err := s.testClient.PingStream(s.ctx())
+ require.NoError(s.T(), err, "PingStream request should be successful.")
+
+ for i := 0; i < countListResponses; i++ {
+ ping := &pb.PingRequest{Value: fmt.Sprintf("foo:%d", i)}
+ require.NoError(s.T(), stream.Send(ping), "sending to PingStream must not fail")
+ resp, err := stream.Recv()
+ if err == io.EOF {
+ break
+ }
+ if i == 0 {
+ // Check that the header arrives before all entries.
+ headerMd, err := stream.Header()
+ require.NoError(s.T(), err, "PingStream headers should not error.")
+ assert.Contains(s.T(), headerMd, serverHeaderMdKey, "PingStream response headers user contain metadata")
+ }
+ assert.EqualValues(s.T(), i, resp.Counter, "ping roundtrip must succeed with the correct id")
+ }
+ require.NoError(s.T(), stream.CloseSend(), "no error on close send")
+ _, err = stream.Recv()
+ require.Equal(s.T(), io.EOF, err, "stream should close with io.EOF, meaining OK")
+ // Check that the trailer headers are here.
+ trailerMd := stream.Trailer()
+ assert.Len(s.T(), trailerMd, 1, "PingList trailer headers user contain metadata")
+}
+
+func (s *ProxyHappySuite) TestPingStream_StressTest() {
+ for i := 0; i < 50; i++ {
+ s.TestPingStream_FullDuplexWorks()
+ }
+}
+
+func (s *ProxyHappySuite) SetupSuite() {
+ var err error
+
+ s.proxyListener, err = net.Listen("tcp", "127.0.0.1:0")
+ require.NoError(s.T(), err, "must be able to allocate a port for proxyListener")
+ s.serverListener, err = net.Listen("tcp", "127.0.0.1:0")
+ require.NoError(s.T(), err, "must be able to allocate a port for serverListener")
+
+ grpclog.SetLogger(log.New(os.Stderr, "grpc: ", log.LstdFlags))
+
+ s.server = grpc.NewServer()
+ pb.RegisterTestServiceServer(s.server, &assertingService{t: s.T()})
+
+ // Setup of the proxy's Director.
+ s.serverClientConn, err = grpc.Dial(s.serverListener.Addr().String(), grpc.WithInsecure(), grpc.WithCodec(proxy.Codec()))
+ require.NoError(s.T(), err, "must not error on deferred client Dial")
+ director := func(ctx context.Context, fullName string) (context.Context, *grpc.ClientConn, error) {
+ md, ok := metadata.FromIncomingContext(ctx)
+ if ok {
+ if _, exists := md[rejectingMdKey]; exists {
+ return ctx, nil, grpc.Errorf(codes.PermissionDenied, "testing rejection")
+ }
+ }
+ // Explicitly copy the metadata, otherwise the tests will fail.
+ outCtx, _ := context.WithCancel(ctx)
+ outCtx = metadata.NewOutgoingContext(outCtx, md.Copy())
+ return outCtx, s.serverClientConn, nil
+ }
+ s.proxy = grpc.NewServer(
+ grpc.CustomCodec(proxy.Codec()),
+ grpc.UnknownServiceHandler(proxy.TransparentHandler(director)),
+ )
+ // Ping handler is handled as an explicit registration and not as a TransparentHandler.
+ proxy.RegisterService(s.proxy, director,
+ "mwitkow.testproto.TestService",
+ "Ping")
+
+ // Start the serving loops.
+ s.T().Logf("starting grpc.Server at: %v", s.serverListener.Addr().String())
+ go func() {
+ s.server.Serve(s.serverListener)
+ }()
+ s.T().Logf("starting grpc.Proxy at: %v", s.proxyListener.Addr().String())
+ go func() {
+ s.proxy.Serve(s.proxyListener)
+ }()
+
+ clientConn, err := grpc.Dial(strings.Replace(s.proxyListener.Addr().String(), "127.0.0.1", "localhost", 1), grpc.WithInsecure(), grpc.WithTimeout(1*time.Second))
+ require.NoError(s.T(), err, "must not error on deferred client Dial")
+ s.testClient = pb.NewTestServiceClient(clientConn)
+}
+
+func (s *ProxyHappySuite) TearDownSuite() {
+ if s.client != nil {
+ s.client.Close()
+ }
+ if s.serverClientConn != nil {
+ s.serverClientConn.Close()
+ }
+ // Close all transports so the logs don't get spammy.
+ time.Sleep(10 * time.Millisecond)
+ if s.proxy != nil {
+ s.proxy.Stop()
+ s.proxyListener.Close()
+ }
+ if s.serverListener != nil {
+ s.server.Stop()
+ s.serverListener.Close()
+ }
+}
+
+func TestProxyHappySuite(t *testing.T) {
+ suite.Run(t, &ProxyHappySuite{})
+}
diff --git a/internal/praefect/grpc-proxy/testdata/Makefile b/internal/praefect/grpc-proxy/testdata/Makefile
new file mode 100644
index 000000000..f2c95584b
--- /dev/null
+++ b/internal/praefect/grpc-proxy/testdata/Makefile
@@ -0,0 +1,11 @@
+
+all: test_go
+
+test_go: test.proto
+ PATH="${GOPATH}/bin:${PATH}" protoc \
+ -I. \
+ -I${GOPATH}/src \
+ --go_out=plugins=grpc:. \
+ test.proto
+
+
diff --git a/internal/praefect/grpc-proxy/testdata/test.pb.go b/internal/praefect/grpc-proxy/testdata/test.pb.go
new file mode 100644
index 000000000..1f1f48253
--- /dev/null
+++ b/internal/praefect/grpc-proxy/testdata/test.pb.go
@@ -0,0 +1,375 @@
+// Code generated by protoc-gen-go.
+// source: test.proto
+// DO NOT EDIT!
+
+/*
+Package mwitkow_testproto is a generated protocol buffer package.
+
+It is generated from these files:
+ test.proto
+
+It has these top-level messages:
+ Empty
+ PingRequest
+ PingResponse
+*/
+package mwitkow_testproto
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+import (
+ context "golang.org/x/net/context"
+ grpc "google.golang.org/grpc"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type Empty struct {
+}
+
+func (m *Empty) Reset() { *m = Empty{} }
+func (m *Empty) String() string { return proto.CompactTextString(m) }
+func (*Empty) ProtoMessage() {}
+func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+
+type PingRequest struct {
+ Value string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"`
+}
+
+func (m *PingRequest) Reset() { *m = PingRequest{} }
+func (m *PingRequest) String() string { return proto.CompactTextString(m) }
+func (*PingRequest) ProtoMessage() {}
+func (*PingRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
+
+func (m *PingRequest) GetValue() string {
+ if m != nil {
+ return m.Value
+ }
+ return ""
+}
+
+type PingResponse struct {
+ Value string `protobuf:"bytes,1,opt,name=Value" json:"Value,omitempty"`
+ Counter int32 `protobuf:"varint,2,opt,name=counter" json:"counter,omitempty"`
+}
+
+func (m *PingResponse) Reset() { *m = PingResponse{} }
+func (m *PingResponse) String() string { return proto.CompactTextString(m) }
+func (*PingResponse) ProtoMessage() {}
+func (*PingResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
+
+func (m *PingResponse) GetValue() string {
+ if m != nil {
+ return m.Value
+ }
+ return ""
+}
+
+func (m *PingResponse) GetCounter() int32 {
+ if m != nil {
+ return m.Counter
+ }
+ return 0
+}
+
+func init() {
+ proto.RegisterType((*Empty)(nil), "mwitkow.testproto.Empty")
+ proto.RegisterType((*PingRequest)(nil), "mwitkow.testproto.PingRequest")
+ proto.RegisterType((*PingResponse)(nil), "mwitkow.testproto.PingResponse")
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// Client API for TestService service
+
+type TestServiceClient interface {
+ PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PingResponse, error)
+ Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error)
+ PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*Empty, error)
+ PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (TestService_PingListClient, error)
+ PingStream(ctx context.Context, opts ...grpc.CallOption) (TestService_PingStreamClient, error)
+}
+
+type testServiceClient struct {
+ cc *grpc.ClientConn
+}
+
+func NewTestServiceClient(cc *grpc.ClientConn) TestServiceClient {
+ return &testServiceClient{cc}
+}
+
+func (c *testServiceClient) PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PingResponse, error) {
+ out := new(PingResponse)
+ err := grpc.Invoke(ctx, "/mwitkow.testproto.TestService/PingEmpty", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *testServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) {
+ out := new(PingResponse)
+ err := grpc.Invoke(ctx, "/mwitkow.testproto.TestService/Ping", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *testServiceClient) PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*Empty, error) {
+ out := new(Empty)
+ err := grpc.Invoke(ctx, "/mwitkow.testproto.TestService/PingError", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *testServiceClient) PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (TestService_PingListClient, error) {
+ stream, err := grpc.NewClientStream(ctx, &_TestService_serviceDesc.Streams[0], c.cc, "/mwitkow.testproto.TestService/PingList", opts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &testServicePingListClient{stream}
+ if err := x.ClientStream.SendMsg(in); err != nil {
+ return nil, err
+ }
+ if err := x.ClientStream.CloseSend(); err != nil {
+ return nil, err
+ }
+ return x, nil
+}
+
+type TestService_PingListClient interface {
+ Recv() (*PingResponse, error)
+ grpc.ClientStream
+}
+
+type testServicePingListClient struct {
+ grpc.ClientStream
+}
+
+func (x *testServicePingListClient) Recv() (*PingResponse, error) {
+ m := new(PingResponse)
+ if err := x.ClientStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (c *testServiceClient) PingStream(ctx context.Context, opts ...grpc.CallOption) (TestService_PingStreamClient, error) {
+ stream, err := grpc.NewClientStream(ctx, &_TestService_serviceDesc.Streams[1], c.cc, "/mwitkow.testproto.TestService/PingStream", opts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &testServicePingStreamClient{stream}
+ return x, nil
+}
+
+type TestService_PingStreamClient interface {
+ Send(*PingRequest) error
+ Recv() (*PingResponse, error)
+ grpc.ClientStream
+}
+
+type testServicePingStreamClient struct {
+ grpc.ClientStream
+}
+
+func (x *testServicePingStreamClient) Send(m *PingRequest) error {
+ return x.ClientStream.SendMsg(m)
+}
+
+func (x *testServicePingStreamClient) Recv() (*PingResponse, error) {
+ m := new(PingResponse)
+ if err := x.ClientStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+// Server API for TestService service
+
+type TestServiceServer interface {
+ PingEmpty(context.Context, *Empty) (*PingResponse, error)
+ Ping(context.Context, *PingRequest) (*PingResponse, error)
+ PingError(context.Context, *PingRequest) (*Empty, error)
+ PingList(*PingRequest, TestService_PingListServer) error
+ PingStream(TestService_PingStreamServer) error
+}
+
+func RegisterTestServiceServer(s *grpc.Server, srv TestServiceServer) {
+ s.RegisterService(&_TestService_serviceDesc, srv)
+}
+
+func _TestService_PingEmpty_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(Empty)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(TestServiceServer).PingEmpty(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/mwitkow.testproto.TestService/PingEmpty",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(TestServiceServer).PingEmpty(ctx, req.(*Empty))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _TestService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(PingRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(TestServiceServer).Ping(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/mwitkow.testproto.TestService/Ping",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(TestServiceServer).Ping(ctx, req.(*PingRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _TestService_PingError_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(PingRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(TestServiceServer).PingError(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/mwitkow.testproto.TestService/PingError",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(TestServiceServer).PingError(ctx, req.(*PingRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _TestService_PingList_Handler(srv interface{}, stream grpc.ServerStream) error {
+ m := new(PingRequest)
+ if err := stream.RecvMsg(m); err != nil {
+ return err
+ }
+ return srv.(TestServiceServer).PingList(m, &testServicePingListServer{stream})
+}
+
+type TestService_PingListServer interface {
+ Send(*PingResponse) error
+ grpc.ServerStream
+}
+
+type testServicePingListServer struct {
+ grpc.ServerStream
+}
+
+func (x *testServicePingListServer) Send(m *PingResponse) error {
+ return x.ServerStream.SendMsg(m)
+}
+
+func _TestService_PingStream_Handler(srv interface{}, stream grpc.ServerStream) error {
+ return srv.(TestServiceServer).PingStream(&testServicePingStreamServer{stream})
+}
+
+type TestService_PingStreamServer interface {
+ Send(*PingResponse) error
+ Recv() (*PingRequest, error)
+ grpc.ServerStream
+}
+
+type testServicePingStreamServer struct {
+ grpc.ServerStream
+}
+
+func (x *testServicePingStreamServer) Send(m *PingResponse) error {
+ return x.ServerStream.SendMsg(m)
+}
+
+func (x *testServicePingStreamServer) Recv() (*PingRequest, error) {
+ m := new(PingRequest)
+ if err := x.ServerStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+var _TestService_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "mwitkow.testproto.TestService",
+ HandlerType: (*TestServiceServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "PingEmpty",
+ Handler: _TestService_PingEmpty_Handler,
+ },
+ {
+ MethodName: "Ping",
+ Handler: _TestService_Ping_Handler,
+ },
+ {
+ MethodName: "PingError",
+ Handler: _TestService_PingError_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{
+ {
+ StreamName: "PingList",
+ Handler: _TestService_PingList_Handler,
+ ServerStreams: true,
+ },
+ {
+ StreamName: "PingStream",
+ Handler: _TestService_PingStream_Handler,
+ ServerStreams: true,
+ ClientStreams: true,
+ },
+ },
+ Metadata: "test.proto",
+}
+
+func init() { proto.RegisterFile("test.proto", fileDescriptor0) }
+
+var fileDescriptor0 = []byte{
+ // 237 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x8f, 0x31, 0x4b, 0xc4, 0x40,
+ 0x10, 0x85, 0x6f, 0xd5, 0x78, 0xde, 0x9c, 0x8d, 0x83, 0xc5, 0x62, 0xa1, 0xc7, 0xda, 0xa4, 0x5a,
+ 0x0e, 0xed, 0xed, 0x44, 0x05, 0x41, 0x49, 0xc4, 0xfe, 0x0c, 0x83, 0x2c, 0x9a, 0x6c, 0xdc, 0x9d,
+ 0x24, 0xf8, 0x33, 0xfc, 0xc7, 0xb2, 0x1b, 0x85, 0x80, 0x06, 0x2d, 0x52, 0xce, 0x7b, 0x1f, 0x8f,
+ 0x6f, 0x00, 0x98, 0x3c, 0xeb, 0xda, 0x59, 0xb6, 0x78, 0x50, 0x76, 0x86, 0x5f, 0x6c, 0xa7, 0x43,
+ 0x16, 0x23, 0x35, 0x87, 0xe4, 0xb2, 0xac, 0xf9, 0x5d, 0x9d, 0xc2, 0xf2, 0xde, 0x54, 0xcf, 0x19,
+ 0xbd, 0x35, 0xe4, 0x19, 0x0f, 0x21, 0x69, 0x37, 0xaf, 0x0d, 0x49, 0xb1, 0x12, 0xe9, 0x22, 0xeb,
+ 0x0f, 0x75, 0x01, 0xfb, 0x3d, 0xe4, 0x6b, 0x5b, 0x79, 0x0a, 0xd4, 0xe3, 0x90, 0x8a, 0x07, 0x4a,
+ 0x98, 0x17, 0xb6, 0xa9, 0x98, 0x9c, 0xdc, 0x5a, 0x89, 0x34, 0xc9, 0xbe, 0xcf, 0xb3, 0x8f, 0x6d,
+ 0x58, 0x3e, 0x90, 0xe7, 0x9c, 0x5c, 0x6b, 0x0a, 0xc2, 0x6b, 0x58, 0x84, 0xbd, 0x68, 0x80, 0x52,
+ 0xff, 0xd0, 0xd3, 0xb1, 0x39, 0x3a, 0xf9, 0xa5, 0x19, 0x7a, 0xa8, 0x19, 0xde, 0xc0, 0x4e, 0x48,
+ 0xf0, 0x78, 0x14, 0x8d, 0x7f, 0xfd, 0x67, 0xea, 0xea, 0x4b, 0xca, 0x39, 0xeb, 0xfe, 0xdc, 0x1b,
+ 0x95, 0x56, 0x33, 0xbc, 0x83, 0xbd, 0x80, 0xde, 0x1a, 0xcf, 0x13, 0x78, 0xad, 0x05, 0xe6, 0x00,
+ 0x21, 0xcb, 0xd9, 0xd1, 0xa6, 0x9c, 0x60, 0x32, 0x15, 0x6b, 0xf1, 0xb4, 0x1b, 0x9b, 0xf3, 0xcf,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0x4a, 0xc0, 0x8e, 0xe7, 0x29, 0x02, 0x00, 0x00,
+}
diff --git a/internal/praefect/grpc-proxy/testdata/test.proto b/internal/praefect/grpc-proxy/testdata/test.proto
new file mode 100644
index 000000000..54e3cf56a
--- /dev/null
+++ b/internal/praefect/grpc-proxy/testdata/test.proto
@@ -0,0 +1,29 @@
+syntax = "proto3";
+
+package mwitkow.testproto;
+
+message Empty {
+}
+
+message PingRequest {
+ string value = 1;
+}
+
+message PingResponse {
+ string Value = 1;
+ int32 counter = 2;
+}
+
+service TestService {
+ rpc PingEmpty(Empty) returns (PingResponse) {}
+
+ rpc Ping(PingRequest) returns (PingResponse) {}
+
+ rpc PingError(PingRequest) returns (Empty) {}
+
+ rpc PingList(PingRequest) returns (stream PingResponse) {}
+
+ rpc PingStream(stream PingRequest) returns (stream PingResponse) {}
+
+}
+
diff --git a/internal/praefect/server.go b/internal/praefect/server.go
index 29414b5a1..766123584 100644
--- a/internal/praefect/server.go
+++ b/internal/praefect/server.go
@@ -8,11 +8,11 @@ import (
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
- "github.com/mwitkow/grpc-proxy/proxy"
"github.com/sirupsen/logrus"
"gitlab.com/gitlab-org/gitaly/internal/middleware/cancelhandler"
"gitlab.com/gitlab-org/gitaly/internal/middleware/metadatahandler"
"gitlab.com/gitlab-org/gitaly/internal/middleware/panichandler"
+ "gitlab.com/gitlab-org/gitaly/internal/praefect/grpc-proxy/proxy"
grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc"
grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc"
"google.golang.org/grpc"
diff --git a/internal/praefect/server_test.go b/internal/praefect/server_test.go
index 5b9456206..e82ba87c6 100644
--- a/internal/praefect/server_test.go
+++ b/internal/praefect/server_test.go
@@ -7,12 +7,12 @@ import (
"testing"
"time"
- "github.com/mwitkow/grpc-proxy/proxy"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/client"
"gitlab.com/gitlab-org/gitaly/internal/praefect"
"gitlab.com/gitlab-org/gitaly/internal/praefect/config"
+ "gitlab.com/gitlab-org/gitaly/internal/praefect/grpc-proxy/proxy"
"gitlab.com/gitlab-org/gitaly/internal/praefect/mock"
"google.golang.org/grpc"
)
diff --git a/vendor/github.com/mwitkow/grpc-proxy/proxy/README.md b/vendor/github.com/mwitkow/grpc-proxy/proxy/README.md
deleted file mode 100644
index 85c411a10..000000000
--- a/vendor/github.com/mwitkow/grpc-proxy/proxy/README.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# proxy
---
- import "github.com/mwitkow/grpc-proxy/proxy"
-
-Package proxy provides a reverse proxy handler for gRPC.
-
-The implementation allows a `grpc.Server` to pass a received ServerStream to a
-ClientStream without understanding the semantics of the messages exchanged. It
-basically provides a transparent reverse-proxy.
-
-This package is intentionally generic, exposing a `StreamDirector` function that
-allows users of this package to implement whatever logic of backend-picking,
-dialing and service verification to perform.
-
-See examples on documented functions.
-
-## Usage
-
-#### func Codec
-
-```go
-func Codec() grpc.Codec
-```
-Codec returns a proxying grpc.Codec with the default protobuf codec as parent.
-
-See CodecWithParent.
-
-#### func CodecWithParent
-
-```go
-func CodecWithParent(fallback grpc.Codec) grpc.Codec
-```
-CodecWithParent returns a proxying grpc.Codec with a user provided codec as
-parent.
-
-This codec is *crucial* to the functioning of the proxy. It allows the proxy
-server to be oblivious to the schema of the forwarded messages. It basically
-treats a gRPC message frame as raw bytes. However, if the server handler, or the
-client caller are not proxy-internal functions it will fall back to trying to
-decode the message using a fallback codec.
-
-#### func RegisterService
-
-```go
-func RegisterService(server *grpc.Server, director StreamDirector, serviceName string, methodNames ...string)
-```
-RegisterService sets up a proxy handler for a particular gRPC service and
-method. The behaviour is the same as if you were registering a handler method,
-e.g. from a codegenerated pb.go file.
-
-This can *only* be used if the `server` also uses grpcproxy.CodecForServer()
-ServerOption.
-
-#### func TransparentHandler
-
-```go
-func TransparentHandler(director StreamDirector) grpc.StreamHandler
-```
-TransparentHandler returns a handler that attempts to proxy all requests that
-are not registered in the server. The indented use here is as a transparent
-proxy, where the server doesn't know about the services implemented by the
-backends. It should be used as a `grpc.UnknownServiceHandler`.
-
-This can *only* be used if the `server` also uses grpcproxy.CodecForServer()
-ServerOption.
-
-#### type StreamDirector
-
-```go
-type StreamDirector func(ctx context.Context, fullMethodName string) (*grpc.ClientConn, error)
-```
-
-StreamDirector returns a gRPC ClientConn to be used to forward the call to.
-
-The presence of the `Context` allows for rich filtering, e.g. based on Metadata
-(headers). If no handling is meant to be done, a `codes.NotImplemented` gRPC
-error should be returned.
-
-It is worth noting that the StreamDirector will be fired *after* all server-side
-stream interceptors are invoked. So decisions around authorization, monitoring
-etc. are better to be handled there.
-
-See the rather rich example.
diff --git a/vendor/github.com/stretchr/testify/LICENSE b/vendor/github.com/stretchr/testify/LICENSE
index 473b670a7..f38ec5956 100644
--- a/vendor/github.com/stretchr/testify/LICENSE
+++ b/vendor/github.com/stretchr/testify/LICENSE
@@ -1,22 +1,21 @@
-Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
+MIT License
-Please consider promoting this project if you find it useful.
+Copyright (c) 2012-2018 Mat Ryer and Tyler Bunnell
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of the Software,
-and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
-OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
-OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/stretchr/testify/suite/doc.go b/vendor/github.com/stretchr/testify/suite/doc.go
new file mode 100644
index 000000000..f91a245d3
--- /dev/null
+++ b/vendor/github.com/stretchr/testify/suite/doc.go
@@ -0,0 +1,65 @@
+// Package suite contains logic for creating testing suite structs
+// and running the methods on those structs as tests. The most useful
+// piece of this package is that you can create setup/teardown methods
+// on your testing suites, which will run before/after the whole suite
+// or individual tests (depending on which interface(s) you
+// implement).
+//
+// A testing suite is usually built by first extending the built-in
+// suite functionality from suite.Suite in testify. Alternatively,
+// you could reproduce that logic on your own if you wanted (you
+// just need to implement the TestingSuite interface from
+// suite/interfaces.go).
+//
+// After that, you can implement any of the interfaces in
+// suite/interfaces.go to add setup/teardown functionality to your
+// suite, and add any methods that start with "Test" to add tests.
+// Methods that do not match any suite interfaces and do not begin
+// with "Test" will not be run by testify, and can safely be used as
+// helper methods.
+//
+// Once you've built your testing suite, you need to run the suite
+// (using suite.Run from testify) inside any function that matches the
+// identity that "go test" is already looking for (i.e.
+// func(*testing.T)).
+//
+// Regular expression to select test suites specified command-line
+// argument "-run". Regular expression to select the methods
+// of test suites specified command-line argument "-m".
+// Suite object has assertion methods.
+//
+// A crude example:
+// // Basic imports
+// import (
+// "testing"
+// "github.com/stretchr/testify/assert"
+// "github.com/stretchr/testify/suite"
+// )
+//
+// // Define the suite, and absorb the built-in basic suite
+// // functionality from testify - including a T() method which
+// // returns the current testing context
+// type ExampleTestSuite struct {
+// suite.Suite
+// VariableThatShouldStartAtFive int
+// }
+//
+// // Make sure that VariableThatShouldStartAtFive is set to five
+// // before each test
+// func (suite *ExampleTestSuite) SetupTest() {
+// suite.VariableThatShouldStartAtFive = 5
+// }
+//
+// // All methods that begin with "Test" are run as tests within a
+// // suite.
+// func (suite *ExampleTestSuite) TestExample() {
+// assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
+// suite.Equal(5, suite.VariableThatShouldStartAtFive)
+// }
+//
+// // In order for 'go test' to run this suite, we need to create
+// // a normal test function and pass our suite to suite.Run
+// func TestExampleTestSuite(t *testing.T) {
+// suite.Run(t, new(ExampleTestSuite))
+// }
+package suite
diff --git a/vendor/github.com/stretchr/testify/suite/interfaces.go b/vendor/github.com/stretchr/testify/suite/interfaces.go
new file mode 100644
index 000000000..b37cb0409
--- /dev/null
+++ b/vendor/github.com/stretchr/testify/suite/interfaces.go
@@ -0,0 +1,46 @@
+package suite
+
+import "testing"
+
+// TestingSuite can store and return the current *testing.T context
+// generated by 'go test'.
+type TestingSuite interface {
+ T() *testing.T
+ SetT(*testing.T)
+}
+
+// SetupAllSuite has a SetupSuite method, which will run before the
+// tests in the suite are run.
+type SetupAllSuite interface {
+ SetupSuite()
+}
+
+// SetupTestSuite has a SetupTest method, which will run before each
+// test in the suite.
+type SetupTestSuite interface {
+ SetupTest()
+}
+
+// TearDownAllSuite has a TearDownSuite method, which will run after
+// all the tests in the suite have been run.
+type TearDownAllSuite interface {
+ TearDownSuite()
+}
+
+// TearDownTestSuite has a TearDownTest method, which will run after
+// each test in the suite.
+type TearDownTestSuite interface {
+ TearDownTest()
+}
+
+// BeforeTest has a function to be executed right before the test
+// starts and receives the suite and test names as input
+type BeforeTest interface {
+ BeforeTest(suiteName, testName string)
+}
+
+// AfterTest has a function to be executed right after the test
+// finishes and receives the suite and test names as input
+type AfterTest interface {
+ AfterTest(suiteName, testName string)
+}
diff --git a/vendor/github.com/stretchr/testify/suite/suite.go b/vendor/github.com/stretchr/testify/suite/suite.go
new file mode 100644
index 000000000..d708d7d75
--- /dev/null
+++ b/vendor/github.com/stretchr/testify/suite/suite.go
@@ -0,0 +1,166 @@
+package suite
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "reflect"
+ "regexp"
+ "runtime/debug"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+var allTestsFilter = func(_, _ string) (bool, error) { return true, nil }
+var matchMethod = flag.String("testify.m", "", "regular expression to select tests of the testify suite to run")
+
+// Suite is a basic testing suite with methods for storing and
+// retrieving the current *testing.T context.
+type Suite struct {
+ *assert.Assertions
+ require *require.Assertions
+ t *testing.T
+}
+
+// T retrieves the current *testing.T context.
+func (suite *Suite) T() *testing.T {
+ return suite.t
+}
+
+// SetT sets the current *testing.T context.
+func (suite *Suite) SetT(t *testing.T) {
+ suite.t = t
+ suite.Assertions = assert.New(t)
+ suite.require = require.New(t)
+}
+
+// Require returns a require context for suite.
+func (suite *Suite) Require() *require.Assertions {
+ if suite.require == nil {
+ suite.require = require.New(suite.T())
+ }
+ return suite.require
+}
+
+// Assert returns an assert context for suite. Normally, you can call
+// `suite.NoError(expected, actual)`, but for situations where the embedded
+// methods are overridden (for example, you might want to override
+// assert.Assertions with require.Assertions), this method is provided so you
+// can call `suite.Assert().NoError()`.
+func (suite *Suite) Assert() *assert.Assertions {
+ if suite.Assertions == nil {
+ suite.Assertions = assert.New(suite.T())
+ }
+ return suite.Assertions
+}
+
+func failOnPanic(t *testing.T) {
+ r := recover()
+ if r != nil {
+ t.Errorf("test panicked: %v\n%s", r, debug.Stack())
+ t.FailNow()
+ }
+}
+
+// Run provides suite functionality around golang subtests. It should be
+// called in place of t.Run(name, func(t *testing.T)) in test suite code.
+// The passed-in func will be executed as a subtest with a fresh instance of t.
+// Provides compatibility with go test pkg -run TestSuite/TestName/SubTestName.
+func (suite *Suite) Run(name string, subtest func()) bool {
+ oldT := suite.T()
+ defer suite.SetT(oldT)
+ return oldT.Run(name, func(t *testing.T) {
+ suite.SetT(t)
+ subtest()
+ })
+}
+
+// Run takes a testing suite and runs all of the tests attached
+// to it.
+func Run(t *testing.T, suite TestingSuite) {
+ suite.SetT(t)
+ defer failOnPanic(t)
+
+ suiteSetupDone := false
+
+ methodFinder := reflect.TypeOf(suite)
+ tests := []testing.InternalTest{}
+ for index := 0; index < methodFinder.NumMethod(); index++ {
+ method := methodFinder.Method(index)
+ ok, err := methodFilter(method.Name)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "testify: invalid regexp for -m: %s\n", err)
+ os.Exit(1)
+ }
+ if !ok {
+ continue
+ }
+ if !suiteSetupDone {
+ if setupAllSuite, ok := suite.(SetupAllSuite); ok {
+ setupAllSuite.SetupSuite()
+ }
+ defer func() {
+ if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
+ tearDownAllSuite.TearDownSuite()
+ }
+ }()
+ suiteSetupDone = true
+ }
+ test := testing.InternalTest{
+ Name: method.Name,
+ F: func(t *testing.T) {
+ parentT := suite.T()
+ suite.SetT(t)
+ defer failOnPanic(t)
+
+ if setupTestSuite, ok := suite.(SetupTestSuite); ok {
+ setupTestSuite.SetupTest()
+ }
+ if beforeTestSuite, ok := suite.(BeforeTest); ok {
+ beforeTestSuite.BeforeTest(methodFinder.Elem().Name(), method.Name)
+ }
+ defer func() {
+ if afterTestSuite, ok := suite.(AfterTest); ok {
+ afterTestSuite.AfterTest(methodFinder.Elem().Name(), method.Name)
+ }
+ if tearDownTestSuite, ok := suite.(TearDownTestSuite); ok {
+ tearDownTestSuite.TearDownTest()
+ }
+ suite.SetT(parentT)
+ }()
+ method.Func.Call([]reflect.Value{reflect.ValueOf(suite)})
+ },
+ }
+ tests = append(tests, test)
+ }
+ runTests(t, tests)
+}
+
+func runTests(t testing.TB, tests []testing.InternalTest) {
+ r, ok := t.(runner)
+ if !ok { // backwards compatibility with Go 1.6 and below
+ if !testing.RunTests(allTestsFilter, tests) {
+ t.Fail()
+ }
+ return
+ }
+
+ for _, test := range tests {
+ r.Run(test.Name, test.F)
+ }
+}
+
+// Filtering method according to set regular expression
+// specified command-line argument -m
+func methodFilter(name string) (bool, error) {
+ if ok, _ := regexp.MatchString("^Test", name); !ok {
+ return false, nil
+ }
+ return regexp.MatchString(*matchMethod, name)
+}
+
+type runner interface {
+ Run(name string, f func(t *testing.T)) bool
+}
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 5f4027f65..5561b6c06 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -323,12 +323,6 @@
"versionExact": "v1.0.1"
},
{
- "checksumSHA1": "603wOI+hKduL75jXGGxfLKP5GE4=",
- "path": "github.com/mwitkow/grpc-proxy/proxy",
- "revision": "0f1106ef9c766333b9acb4b81e705da4bade7215",
- "revisionTime": "2018-10-17T16:41:39Z"
- },
- {
"checksumSHA1": "jqEjDv//suCrQUg8iOGI7oxwfRU=",
"path": "github.com/opentracing/opentracing-go",
"revision": "be550b025b433cdfa2f11efb962afa2ea3c4d967",
@@ -481,6 +475,12 @@
"versionExact": "v1.2.2"
},
{
+ "checksumSHA1": "lIp4dQzfVYRQARgsmRm3h3wRFgs=",
+ "path": "github.com/stretchr/testify/suite",
+ "revision": "34c6fa2dc70986bccbbffcc6130f6920a924b075",
+ "revisionTime": "2019-03-04T09:57:49Z"
+ },
+ {
"checksumSHA1": "DAZUaXNahejywdwKXvMohfyHKNc=",
"path": "github.com/tinylib/msgp/msgp",
"revision": "af6442a0fcf6e2a1b824f70dd0c734f01e817751",