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>2020-03-12 04:31:28 +0300
committerJohn Cai <jcai@gitlab.com>2020-03-13 21:01:24 +0300
commit35beb530957158c839265143a744184867b308fc (patch)
tree43aa618913f0dbb46039ce887f8f2eb33a8e08e6 /internal/praefect/protoregistry
parentf414810c76834bfb3370af0b4b0f46e1f00b58d7 (diff)
Use praefect server in repository tests
Diffstat (limited to 'internal/praefect/protoregistry')
-rw-r--r--internal/praefect/protoregistry/find_oid.go55
1 files changed, 55 insertions, 0 deletions
diff --git a/internal/praefect/protoregistry/find_oid.go b/internal/praefect/protoregistry/find_oid.go
index 8b73d4943..7d8691fe3 100644
--- a/internal/praefect/protoregistry/find_oid.go
+++ b/internal/praefect/protoregistry/find_oid.go
@@ -3,6 +3,7 @@ package protoregistry
import (
"errors"
"fmt"
+ "math"
"reflect"
"regexp"
"strconv"
@@ -22,6 +23,9 @@ var ErrTargetRepoMissing = errors.New("empty Repository")
func reflectFindRepoTarget(pbMsg proto.Message, targetOID []int) (*gitalypb.Repository, error) {
msgV, e := reflectFindOID(pbMsg, targetOID)
if e != nil {
+ if e == ErrProtoFieldEmpty {
+ return nil, ErrTargetRepoMissing
+ }
return nil, e
}
@@ -47,6 +51,9 @@ func reflectFindStorage(pbMsg proto.Message, targetOID []int) (string, error) {
return targetRepo, nil
}
+// ErrProtoFieldEmpty indicates the protobuf field is empty
+var ErrProtoFieldEmpty = errors.New("proto field is empty")
+
// reflectFindOID finds the target repository by using the OID to
// navigate the struct tags
// Warning: this reflection filled function is full of forbidden dark elf magic
@@ -74,7 +81,51 @@ const (
protobufTagRegexFieldGroup = 2
)
+// TODO: This code is copied from the go standard library's reflect package in go 1.13. Once we deprecate support
+// for go 1.12, we need to remove this code and call value.isZero directly
+func isZero(v reflect.Value) bool {
+ switch v.Kind() {
+ case reflect.Bool:
+ return !v.Bool()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return v.Int() == 0
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return v.Uint() == 0
+ case reflect.Float32, reflect.Float64:
+ return math.Float64bits(v.Float()) == 0
+ case reflect.Complex64, reflect.Complex128:
+ c := v.Complex()
+ return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
+ case reflect.Array:
+ for i := 0; i < v.Len(); i++ {
+ if !isZero(v.Index(i)) {
+ return false
+ }
+ }
+ return true
+ case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
+ return v.IsNil()
+ case reflect.String:
+ return v.Len() == 0
+ case reflect.Struct:
+ for i := 0; i < v.NumField(); i++ {
+ if !isZero(v.Field(i)) {
+ return false
+ }
+ }
+ return true
+ default:
+ // This should never happens, but will act as a safeguard for
+ // later, as a default value doesn't makes sense here.
+ panic(&reflect.ValueError{"reflect.Value.IsZero", v.Kind()})
+ }
+}
+
func findProtoField(msgV reflect.Value, protoField int) (reflect.Value, error) {
+ if isZero(msgV) {
+ return reflect.Value{}, ErrProtoFieldEmpty
+ }
+
msgV = reflect.Indirect(msgV)
for i := 0; i < msgV.NumField(); i++ {
field := msgV.Type().Field(i)
@@ -115,6 +166,10 @@ func tryNumberedField(field reflect.StructField, protoField int) (bool, error) {
}
func tryOneOfField(msgV reflect.Value, field reflect.StructField, protoField int) (reflect.Value, bool) {
+ if isZero(msgV) {
+ return reflect.Value{}, false
+ }
+
oneOfTag := field.Tag.Get(protobufOneOfTag)
if oneOfTag == "" {
return reflect.Value{}, false // empty tag means this is not a oneOf field