diff --git a/go.mod b/go.mod index 12baf09c..3b78e51c 100644 --- a/go.mod +++ b/go.mod @@ -6,12 +6,12 @@ require ( github.com/containerd/containerd v1.6.9 github.com/containernetworking/cni v1.1.2 github.com/gogo/protobuf v1.3.2 - github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.3.0 + github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0 github.com/onsi/ginkgo v1.16.5 - github.com/onsi/ginkgo/v2 v2.5.1 - github.com/onsi/gomega v1.24.1 + github.com/onsi/ginkgo/v2 v2.1.4 + github.com/onsi/gomega v1.20.1 github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 - google.golang.org/grpc v1.51.0 + google.golang.org/grpc v1.51.0-dev gopkg.in/k8snetworkplumbingwg/multus-cni.v3 v3.9.1 k8s.io/api v0.24.4 k8s.io/apimachinery v0.24.4 @@ -66,12 +66,12 @@ require ( github.com/sirupsen/logrus v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect go.opencensus.io v0.23.0 // indirect - golang.org/x/net v0.2.0 // indirect + golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.2.0 // indirect golang.org/x/term v0.2.0 // indirect - golang.org/x/text v0.4.0 // indirect + golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect diff --git a/go.sum b/go.sum index e68a9fa3..3775c75f 100644 --- a/go.sum +++ b/go.sum @@ -572,8 +572,8 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/k8snetworkplumbingwg/multus-cni v0.0.0-20221014153412-fa8a6e688081 h1:lonGN339dXcAMpSuluEvSN1GdCFgSFY5rNTlzKW8pUQ= github.com/k8snetworkplumbingwg/multus-cni v0.0.0-20221014153412-fa8a6e688081/go.mod h1:6Gc0CK1oJNOqUY3bGC6tppdnsNzwj0BZhNLrvEN1BWc= -github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.3.0 h1:MjRRgZyTGo90G+UrwlDQjU+uG4Z7By65qvQxGoILT/8= -github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.3.0/go.mod h1:nqCI7aelBJU61wiBeeZWJ6oi4bJy5nrjkM6lWIMA4j0= +github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0 h1:VzM3TYHDgqPkettiP6I6q2jOeQFL4nrJM+UcAc4f6Fs= +github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0/go.mod h1:nqCI7aelBJU61wiBeeZWJ6oi4bJy5nrjkM6lWIMA4j0= github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -683,8 +683,8 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= -github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -694,8 +694,8 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= -github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1053,8 +1053,8 @@ golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1198,9 +1198,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1399,8 +1398,8 @@ google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.51.0-dev h1:JIZpGUpbGAukP4rGiKJ/AnpK9BqMYV6Rdx94XWZckHY= +google.golang.org/grpc v1.51.0-dev/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/vendor/github.com/go-logr/logr/funcr/funcr.go b/vendor/github.com/go-logr/logr/funcr/funcr.go deleted file mode 100644 index 7accdb0c..00000000 --- a/vendor/github.com/go-logr/logr/funcr/funcr.go +++ /dev/null @@ -1,787 +0,0 @@ -/* -Copyright 2021 The logr Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package funcr implements formatting of structured log messages and -// optionally captures the call site and timestamp. -// -// The simplest way to use it is via its implementation of a -// github.com/go-logr/logr.LogSink with output through an arbitrary -// "write" function. See New and NewJSON for details. -// -// Custom LogSinks -// -// For users who need more control, a funcr.Formatter can be embedded inside -// your own custom LogSink implementation. This is useful when the LogSink -// needs to implement additional methods, for example. -// -// Formatting -// -// This will respect logr.Marshaler, fmt.Stringer, and error interfaces for -// values which are being logged. When rendering a struct, funcr will use Go's -// standard JSON tags (all except "string"). -package funcr - -import ( - "bytes" - "encoding" - "fmt" - "path/filepath" - "reflect" - "runtime" - "strconv" - "strings" - "time" - - "github.com/go-logr/logr" -) - -// New returns a logr.Logger which is implemented by an arbitrary function. -func New(fn func(prefix, args string), opts Options) logr.Logger { - return logr.New(newSink(fn, NewFormatter(opts))) -} - -// NewJSON returns a logr.Logger which is implemented by an arbitrary function -// and produces JSON output. -func NewJSON(fn func(obj string), opts Options) logr.Logger { - fnWrapper := func(_, obj string) { - fn(obj) - } - return logr.New(newSink(fnWrapper, NewFormatterJSON(opts))) -} - -// Underlier exposes access to the underlying logging function. Since -// callers only have a logr.Logger, they have to know which -// implementation is in use, so this interface is less of an -// abstraction and more of a way to test type conversion. -type Underlier interface { - GetUnderlying() func(prefix, args string) -} - -func newSink(fn func(prefix, args string), formatter Formatter) logr.LogSink { - l := &fnlogger{ - Formatter: formatter, - write: fn, - } - // For skipping fnlogger.Info and fnlogger.Error. - l.Formatter.AddCallDepth(1) - return l -} - -// Options carries parameters which influence the way logs are generated. -type Options struct { - // LogCaller tells funcr to add a "caller" key to some or all log lines. - // This has some overhead, so some users might not want it. - LogCaller MessageClass - - // LogCallerFunc tells funcr to also log the calling function name. This - // has no effect if caller logging is not enabled (see Options.LogCaller). - LogCallerFunc bool - - // LogTimestamp tells funcr to add a "ts" key to log lines. This has some - // overhead, so some users might not want it. - LogTimestamp bool - - // TimestampFormat tells funcr how to render timestamps when LogTimestamp - // is enabled. If not specified, a default format will be used. For more - // details, see docs for Go's time.Layout. - TimestampFormat string - - // Verbosity tells funcr which V logs to produce. Higher values enable - // more logs. Info logs at or below this level will be written, while logs - // above this level will be discarded. - Verbosity int - - // RenderBuiltinsHook allows users to mutate the list of key-value pairs - // while a log line is being rendered. The kvList argument follows logr - // conventions - each pair of slice elements is comprised of a string key - // and an arbitrary value (verified and sanitized before calling this - // hook). The value returned must follow the same conventions. This hook - // can be used to audit or modify logged data. For example, you might want - // to prefix all of funcr's built-in keys with some string. This hook is - // only called for built-in (provided by funcr itself) key-value pairs. - // Equivalent hooks are offered for key-value pairs saved via - // logr.Logger.WithValues or Formatter.AddValues (see RenderValuesHook) and - // for user-provided pairs (see RenderArgsHook). - RenderBuiltinsHook func(kvList []interface{}) []interface{} - - // RenderValuesHook is the same as RenderBuiltinsHook, except that it is - // only called for key-value pairs saved via logr.Logger.WithValues. See - // RenderBuiltinsHook for more details. - RenderValuesHook func(kvList []interface{}) []interface{} - - // RenderArgsHook is the same as RenderBuiltinsHook, except that it is only - // called for key-value pairs passed directly to Info and Error. See - // RenderBuiltinsHook for more details. - RenderArgsHook func(kvList []interface{}) []interface{} - - // MaxLogDepth tells funcr how many levels of nested fields (e.g. a struct - // that contains a struct, etc.) it may log. Every time it finds a struct, - // slice, array, or map the depth is increased by one. When the maximum is - // reached, the value will be converted to a string indicating that the max - // depth has been exceeded. If this field is not specified, a default - // value will be used. - MaxLogDepth int -} - -// MessageClass indicates which category or categories of messages to consider. -type MessageClass int - -const ( - // None ignores all message classes. - None MessageClass = iota - // All considers all message classes. - All - // Info only considers info messages. - Info - // Error only considers error messages. - Error -) - -// fnlogger inherits some of its LogSink implementation from Formatter -// and just needs to add some glue code. -type fnlogger struct { - Formatter - write func(prefix, args string) -} - -func (l fnlogger) WithName(name string) logr.LogSink { - l.Formatter.AddName(name) - return &l -} - -func (l fnlogger) WithValues(kvList ...interface{}) logr.LogSink { - l.Formatter.AddValues(kvList) - return &l -} - -func (l fnlogger) WithCallDepth(depth int) logr.LogSink { - l.Formatter.AddCallDepth(depth) - return &l -} - -func (l fnlogger) Info(level int, msg string, kvList ...interface{}) { - prefix, args := l.FormatInfo(level, msg, kvList) - l.write(prefix, args) -} - -func (l fnlogger) Error(err error, msg string, kvList ...interface{}) { - prefix, args := l.FormatError(err, msg, kvList) - l.write(prefix, args) -} - -func (l fnlogger) GetUnderlying() func(prefix, args string) { - return l.write -} - -// Assert conformance to the interfaces. -var _ logr.LogSink = &fnlogger{} -var _ logr.CallDepthLogSink = &fnlogger{} -var _ Underlier = &fnlogger{} - -// NewFormatter constructs a Formatter which emits a JSON-like key=value format. -func NewFormatter(opts Options) Formatter { - return newFormatter(opts, outputKeyValue) -} - -// NewFormatterJSON constructs a Formatter which emits strict JSON. -func NewFormatterJSON(opts Options) Formatter { - return newFormatter(opts, outputJSON) -} - -// Defaults for Options. -const defaultTimestampFormat = "2006-01-02 15:04:05.000000" -const defaultMaxLogDepth = 16 - -func newFormatter(opts Options, outfmt outputFormat) Formatter { - if opts.TimestampFormat == "" { - opts.TimestampFormat = defaultTimestampFormat - } - if opts.MaxLogDepth == 0 { - opts.MaxLogDepth = defaultMaxLogDepth - } - f := Formatter{ - outputFormat: outfmt, - prefix: "", - values: nil, - depth: 0, - opts: opts, - } - return f -} - -// Formatter is an opaque struct which can be embedded in a LogSink -// implementation. It should be constructed with NewFormatter. Some of -// its methods directly implement logr.LogSink. -type Formatter struct { - outputFormat outputFormat - prefix string - values []interface{} - valuesStr string - depth int - opts Options -} - -// outputFormat indicates which outputFormat to use. -type outputFormat int - -const ( - // outputKeyValue emits a JSON-like key=value format, but not strict JSON. - outputKeyValue outputFormat = iota - // outputJSON emits strict JSON. - outputJSON -) - -// PseudoStruct is a list of key-value pairs that gets logged as a struct. -type PseudoStruct []interface{} - -// render produces a log line, ready to use. -func (f Formatter) render(builtins, args []interface{}) string { - // Empirically bytes.Buffer is faster than strings.Builder for this. - buf := bytes.NewBuffer(make([]byte, 0, 1024)) - if f.outputFormat == outputJSON { - buf.WriteByte('{') - } - vals := builtins - if hook := f.opts.RenderBuiltinsHook; hook != nil { - vals = hook(f.sanitize(vals)) - } - f.flatten(buf, vals, false, false) // keys are ours, no need to escape - continuing := len(builtins) > 0 - if len(f.valuesStr) > 0 { - if continuing { - if f.outputFormat == outputJSON { - buf.WriteByte(',') - } else { - buf.WriteByte(' ') - } - } - continuing = true - buf.WriteString(f.valuesStr) - } - vals = args - if hook := f.opts.RenderArgsHook; hook != nil { - vals = hook(f.sanitize(vals)) - } - f.flatten(buf, vals, continuing, true) // escape user-provided keys - if f.outputFormat == outputJSON { - buf.WriteByte('}') - } - return buf.String() -} - -// flatten renders a list of key-value pairs into a buffer. If continuing is -// true, it assumes that the buffer has previous values and will emit a -// separator (which depends on the output format) before the first pair it -// writes. If escapeKeys is true, the keys are assumed to have -// non-JSON-compatible characters in them and must be evaluated for escapes. -// -// This function returns a potentially modified version of kvList, which -// ensures that there is a value for every key (adding a value if needed) and -// that each key is a string (substituting a key if needed). -func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing bool, escapeKeys bool) []interface{} { - // This logic overlaps with sanitize() but saves one type-cast per key, - // which can be measurable. - if len(kvList)%2 != 0 { - kvList = append(kvList, noValue) - } - for i := 0; i < len(kvList); i += 2 { - k, ok := kvList[i].(string) - if !ok { - k = f.nonStringKey(kvList[i]) - kvList[i] = k - } - v := kvList[i+1] - - if i > 0 || continuing { - if f.outputFormat == outputJSON { - buf.WriteByte(',') - } else { - // In theory the format could be something we don't understand. In - // practice, we control it, so it won't be. - buf.WriteByte(' ') - } - } - - if escapeKeys { - buf.WriteString(prettyString(k)) - } else { - // this is faster - buf.WriteByte('"') - buf.WriteString(k) - buf.WriteByte('"') - } - if f.outputFormat == outputJSON { - buf.WriteByte(':') - } else { - buf.WriteByte('=') - } - buf.WriteString(f.pretty(v)) - } - return kvList -} - -func (f Formatter) pretty(value interface{}) string { - return f.prettyWithFlags(value, 0, 0) -} - -const ( - flagRawStruct = 0x1 // do not print braces on structs -) - -// TODO: This is not fast. Most of the overhead goes here. -func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) string { - if depth > f.opts.MaxLogDepth { - return `""` - } - - // Handle types that take full control of logging. - if v, ok := value.(logr.Marshaler); ok { - // Replace the value with what the type wants to get logged. - // That then gets handled below via reflection. - value = invokeMarshaler(v) - } - - // Handle types that want to format themselves. - switch v := value.(type) { - case fmt.Stringer: - value = invokeStringer(v) - case error: - value = invokeError(v) - } - - // Handling the most common types without reflect is a small perf win. - switch v := value.(type) { - case bool: - return strconv.FormatBool(v) - case string: - return prettyString(v) - case int: - return strconv.FormatInt(int64(v), 10) - case int8: - return strconv.FormatInt(int64(v), 10) - case int16: - return strconv.FormatInt(int64(v), 10) - case int32: - return strconv.FormatInt(int64(v), 10) - case int64: - return strconv.FormatInt(int64(v), 10) - case uint: - return strconv.FormatUint(uint64(v), 10) - case uint8: - return strconv.FormatUint(uint64(v), 10) - case uint16: - return strconv.FormatUint(uint64(v), 10) - case uint32: - return strconv.FormatUint(uint64(v), 10) - case uint64: - return strconv.FormatUint(v, 10) - case uintptr: - return strconv.FormatUint(uint64(v), 10) - case float32: - return strconv.FormatFloat(float64(v), 'f', -1, 32) - case float64: - return strconv.FormatFloat(v, 'f', -1, 64) - case complex64: - return `"` + strconv.FormatComplex(complex128(v), 'f', -1, 64) + `"` - case complex128: - return `"` + strconv.FormatComplex(v, 'f', -1, 128) + `"` - case PseudoStruct: - buf := bytes.NewBuffer(make([]byte, 0, 1024)) - v = f.sanitize(v) - if flags&flagRawStruct == 0 { - buf.WriteByte('{') - } - for i := 0; i < len(v); i += 2 { - if i > 0 { - buf.WriteByte(',') - } - k, _ := v[i].(string) // sanitize() above means no need to check success - // arbitrary keys might need escaping - buf.WriteString(prettyString(k)) - buf.WriteByte(':') - buf.WriteString(f.prettyWithFlags(v[i+1], 0, depth+1)) - } - if flags&flagRawStruct == 0 { - buf.WriteByte('}') - } - return buf.String() - } - - buf := bytes.NewBuffer(make([]byte, 0, 256)) - t := reflect.TypeOf(value) - if t == nil { - return "null" - } - v := reflect.ValueOf(value) - switch t.Kind() { - case reflect.Bool: - return strconv.FormatBool(v.Bool()) - case reflect.String: - return prettyString(v.String()) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return strconv.FormatInt(int64(v.Int()), 10) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return strconv.FormatUint(uint64(v.Uint()), 10) - case reflect.Float32: - return strconv.FormatFloat(float64(v.Float()), 'f', -1, 32) - case reflect.Float64: - return strconv.FormatFloat(v.Float(), 'f', -1, 64) - case reflect.Complex64: - return `"` + strconv.FormatComplex(complex128(v.Complex()), 'f', -1, 64) + `"` - case reflect.Complex128: - return `"` + strconv.FormatComplex(v.Complex(), 'f', -1, 128) + `"` - case reflect.Struct: - if flags&flagRawStruct == 0 { - buf.WriteByte('{') - } - for i := 0; i < t.NumField(); i++ { - fld := t.Field(i) - if fld.PkgPath != "" { - // reflect says this field is only defined for non-exported fields. - continue - } - if !v.Field(i).CanInterface() { - // reflect isn't clear exactly what this means, but we can't use it. - continue - } - name := "" - omitempty := false - if tag, found := fld.Tag.Lookup("json"); found { - if tag == "-" { - continue - } - if comma := strings.Index(tag, ","); comma != -1 { - if n := tag[:comma]; n != "" { - name = n - } - rest := tag[comma:] - if strings.Contains(rest, ",omitempty,") || strings.HasSuffix(rest, ",omitempty") { - omitempty = true - } - } else { - name = tag - } - } - if omitempty && isEmpty(v.Field(i)) { - continue - } - if i > 0 { - buf.WriteByte(',') - } - if fld.Anonymous && fld.Type.Kind() == reflect.Struct && name == "" { - buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), flags|flagRawStruct, depth+1)) - continue - } - if name == "" { - name = fld.Name - } - // field names can't contain characters which need escaping - buf.WriteByte('"') - buf.WriteString(name) - buf.WriteByte('"') - buf.WriteByte(':') - buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), 0, depth+1)) - } - if flags&flagRawStruct == 0 { - buf.WriteByte('}') - } - return buf.String() - case reflect.Slice, reflect.Array: - buf.WriteByte('[') - for i := 0; i < v.Len(); i++ { - if i > 0 { - buf.WriteByte(',') - } - e := v.Index(i) - buf.WriteString(f.prettyWithFlags(e.Interface(), 0, depth+1)) - } - buf.WriteByte(']') - return buf.String() - case reflect.Map: - buf.WriteByte('{') - // This does not sort the map keys, for best perf. - it := v.MapRange() - i := 0 - for it.Next() { - if i > 0 { - buf.WriteByte(',') - } - // If a map key supports TextMarshaler, use it. - keystr := "" - if m, ok := it.Key().Interface().(encoding.TextMarshaler); ok { - txt, err := m.MarshalText() - if err != nil { - keystr = fmt.Sprintf("", err.Error()) - } else { - keystr = string(txt) - } - keystr = prettyString(keystr) - } else { - // prettyWithFlags will produce already-escaped values - keystr = f.prettyWithFlags(it.Key().Interface(), 0, depth+1) - if t.Key().Kind() != reflect.String { - // JSON only does string keys. Unlike Go's standard JSON, we'll - // convert just about anything to a string. - keystr = prettyString(keystr) - } - } - buf.WriteString(keystr) - buf.WriteByte(':') - buf.WriteString(f.prettyWithFlags(it.Value().Interface(), 0, depth+1)) - i++ - } - buf.WriteByte('}') - return buf.String() - case reflect.Ptr, reflect.Interface: - if v.IsNil() { - return "null" - } - return f.prettyWithFlags(v.Elem().Interface(), 0, depth) - } - return fmt.Sprintf(`""`, t.Kind().String()) -} - -func prettyString(s string) string { - // Avoid escaping (which does allocations) if we can. - if needsEscape(s) { - return strconv.Quote(s) - } - b := bytes.NewBuffer(make([]byte, 0, 1024)) - b.WriteByte('"') - b.WriteString(s) - b.WriteByte('"') - return b.String() -} - -// needsEscape determines whether the input string needs to be escaped or not, -// without doing any allocations. -func needsEscape(s string) bool { - for _, r := range s { - if !strconv.IsPrint(r) || r == '\\' || r == '"' { - return true - } - } - return false -} - -func isEmpty(v reflect.Value) bool { - switch v.Kind() { - case reflect.Array, reflect.Map, reflect.Slice, reflect.String: - return v.Len() == 0 - 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 v.Float() == 0 - case reflect.Complex64, reflect.Complex128: - return v.Complex() == 0 - case reflect.Interface, reflect.Ptr: - return v.IsNil() - } - return false -} - -func invokeMarshaler(m logr.Marshaler) (ret interface{}) { - defer func() { - if r := recover(); r != nil { - ret = fmt.Sprintf("", r) - } - }() - return m.MarshalLog() -} - -func invokeStringer(s fmt.Stringer) (ret string) { - defer func() { - if r := recover(); r != nil { - ret = fmt.Sprintf("", r) - } - }() - return s.String() -} - -func invokeError(e error) (ret string) { - defer func() { - if r := recover(); r != nil { - ret = fmt.Sprintf("", r) - } - }() - return e.Error() -} - -// Caller represents the original call site for a log line, after considering -// logr.Logger.WithCallDepth and logr.Logger.WithCallStackHelper. The File and -// Line fields will always be provided, while the Func field is optional. -// Users can set the render hook fields in Options to examine logged key-value -// pairs, one of which will be {"caller", Caller} if the Options.LogCaller -// field is enabled for the given MessageClass. -type Caller struct { - // File is the basename of the file for this call site. - File string `json:"file"` - // Line is the line number in the file for this call site. - Line int `json:"line"` - // Func is the function name for this call site, or empty if - // Options.LogCallerFunc is not enabled. - Func string `json:"function,omitempty"` -} - -func (f Formatter) caller() Caller { - // +1 for this frame, +1 for Info/Error. - pc, file, line, ok := runtime.Caller(f.depth + 2) - if !ok { - return Caller{"", 0, ""} - } - fn := "" - if f.opts.LogCallerFunc { - if fp := runtime.FuncForPC(pc); fp != nil { - fn = fp.Name() - } - } - - return Caller{filepath.Base(file), line, fn} -} - -const noValue = "" - -func (f Formatter) nonStringKey(v interface{}) string { - return fmt.Sprintf("", f.snippet(v)) -} - -// snippet produces a short snippet string of an arbitrary value. -func (f Formatter) snippet(v interface{}) string { - const snipLen = 16 - - snip := f.pretty(v) - if len(snip) > snipLen { - snip = snip[:snipLen] - } - return snip -} - -// sanitize ensures that a list of key-value pairs has a value for every key -// (adding a value if needed) and that each key is a string (substituting a key -// if needed). -func (f Formatter) sanitize(kvList []interface{}) []interface{} { - if len(kvList)%2 != 0 { - kvList = append(kvList, noValue) - } - for i := 0; i < len(kvList); i += 2 { - _, ok := kvList[i].(string) - if !ok { - kvList[i] = f.nonStringKey(kvList[i]) - } - } - return kvList -} - -// Init configures this Formatter from runtime info, such as the call depth -// imposed by logr itself. -// Note that this receiver is a pointer, so depth can be saved. -func (f *Formatter) Init(info logr.RuntimeInfo) { - f.depth += info.CallDepth -} - -// Enabled checks whether an info message at the given level should be logged. -func (f Formatter) Enabled(level int) bool { - return level <= f.opts.Verbosity -} - -// GetDepth returns the current depth of this Formatter. This is useful for -// implementations which do their own caller attribution. -func (f Formatter) GetDepth() int { - return f.depth -} - -// FormatInfo renders an Info log message into strings. The prefix will be -// empty when no names were set (via AddNames), or when the output is -// configured for JSON. -func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (prefix, argsStr string) { - args := make([]interface{}, 0, 64) // using a constant here impacts perf - prefix = f.prefix - if f.outputFormat == outputJSON { - args = append(args, "logger", prefix) - prefix = "" - } - if f.opts.LogTimestamp { - args = append(args, "ts", time.Now().Format(f.opts.TimestampFormat)) - } - if policy := f.opts.LogCaller; policy == All || policy == Info { - args = append(args, "caller", f.caller()) - } - args = append(args, "level", level, "msg", msg) - return prefix, f.render(args, kvList) -} - -// FormatError renders an Error log message into strings. The prefix will be -// empty when no names were set (via AddNames), or when the output is -// configured for JSON. -func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string) { - args := make([]interface{}, 0, 64) // using a constant here impacts perf - prefix = f.prefix - if f.outputFormat == outputJSON { - args = append(args, "logger", prefix) - prefix = "" - } - if f.opts.LogTimestamp { - args = append(args, "ts", time.Now().Format(f.opts.TimestampFormat)) - } - if policy := f.opts.LogCaller; policy == All || policy == Error { - args = append(args, "caller", f.caller()) - } - args = append(args, "msg", msg) - var loggableErr interface{} - if err != nil { - loggableErr = err.Error() - } - args = append(args, "error", loggableErr) - return f.prefix, f.render(args, kvList) -} - -// AddName appends the specified name. funcr uses '/' characters to separate -// name elements. Callers should not pass '/' in the provided name string, but -// this library does not actually enforce that. -func (f *Formatter) AddName(name string) { - if len(f.prefix) > 0 { - f.prefix += "/" - } - f.prefix += name -} - -// AddValues adds key-value pairs to the set of saved values to be logged with -// each log line. -func (f *Formatter) AddValues(kvList []interface{}) { - // Three slice args forces a copy. - n := len(f.values) - f.values = append(f.values[:n:n], kvList...) - - vals := f.values - if hook := f.opts.RenderValuesHook; hook != nil { - vals = hook(f.sanitize(vals)) - } - - // Pre-render values, so we don't have to do it on each Info/Error call. - buf := bytes.NewBuffer(make([]byte, 0, 1024)) - f.flatten(buf, vals, false, true) // escape user-provided keys - f.valuesStr = buf.String() -} - -// AddCallDepth increases the number of stack-frames to skip when attributing -// the log line to a file and line. -func (f *Formatter) AddCallDepth(depth int) { - f.depth += depth -} diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go index 31ada492..2b81d048 100644 --- a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go @@ -43,7 +43,7 @@ const ( DeviceInfoTypeVHostUser = "vhost-user" DeviceInfoTypeMemif = "memif" DeviceInfoTypeVDPA = "vdpa" - DeviceInfoVersion = "1.0.0" + DeviceInfoVersion = "1.1.0" ) // DeviceInfo contains the information of the device associated @@ -58,18 +58,20 @@ type DeviceInfo struct { } type PciDevice struct { - PciAddress string `json:"pci-address,omitempty"` - Vhostnet string `json:"vhost-net,omitempty"` - RdmaDevice string `json:"rdma-device,omitempty"` - PfPciAddress string `json:"pf-pci-address,omitempty"` + PciAddress string `json:"pci-address,omitempty"` + Vhostnet string `json:"vhost-net,omitempty"` + RdmaDevice string `json:"rdma-device,omitempty"` + PfPciAddress string `json:"pf-pci-address,omitempty"` + RepresentorDevice string `json:"representor-device,omitempty"` } type VdpaDevice struct { - ParentDevice string `json:"parent-device,omitempty"` - Driver string `json:"driver,omitempty"` - Path string `json:"path,omitempty"` - PciAddress string `json:"pci-address,omitempty"` - PfPciAddress string `json:"pf-pci-address,omitempty"` + ParentDevice string `json:"parent-device,omitempty"` + Driver string `json:"driver,omitempty"` + Path string `json:"path,omitempty"` + PciAddress string `json:"pci-address,omitempty"` + PfPciAddress string `json:"pf-pci-address,omitempty"` + RepresentorDevice string `json:"representor-device,omitempty"` } const ( @@ -106,6 +108,7 @@ type NetworkStatus struct { Default bool `json:"default,omitempty"` DNS DNS `json:"dns,omitempty"` DeviceInfo *DeviceInfo `json:"device-info,omitempty"` + Gateway []string `json:"gateway,omitempty"` } // PortMapEntry for CNI PortMapEntry diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go index 6e1d56dd..4bca1645 100644 --- a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go @@ -18,6 +18,7 @@ import ( "context" "encoding/json" "fmt" + "net" "regexp" "strings" @@ -72,7 +73,7 @@ func SetNetworkStatus(client kubernetes.Interface, pod *corev1.Pod, statuses []v return nil } -func setPodNetworkStatus(client kubernetes.Interface, pod *corev1.Pod, networkstatus string) (error) { +func setPodNetworkStatus(client kubernetes.Interface, pod *corev1.Pod, networkstatus string) error { if len(pod.Annotations) == 0 { pod.Annotations = make(map[string]string) } @@ -145,6 +146,12 @@ func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork b netStatus.IPs = append(netStatus.IPs, ipconfig.Address.IP.String()) } + for _, route := range result.Routes { + if isDefaultRoute(route) { + netStatus.Gateway = append(netStatus.Gateway, route.GW.String()) + } + } + v1dns := convertDNS(result.DNS) netStatus.DNS = *v1dns @@ -155,6 +162,12 @@ func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork b return netStatus, nil } +func isDefaultRoute(route *cnitypes.Route) bool { + return route.Dst.IP == nil && route.Dst.Mask == nil || + route.Dst.IP.Equal(net.IPv4zero) || + route.Dst.IP.Equal(net.IPv6zero) +} + // ParsePodNetworkAnnotation parses Pod annotation for net-attach-def and get NetworkSelectionElement func ParsePodNetworkAnnotation(pod *corev1.Pod) ([]*v1.NetworkSelectionElement, error) { netAnnot := pod.Annotations[v1.NetworkAttachmentAnnot] diff --git a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md index b723d4e5..66e313d0 100644 --- a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md +++ b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md @@ -1,171 +1,3 @@ -## 2.5.1 - -### Fixes -- skipped tests only show as 'S' when running with -v [3ab38ae] -- Fix typo in docs/index.md (#1082) [55fc58d] -- Fix typo in docs/index.md (#1081) [8a14f1f] -- Fix link notation in docs/index.md (#1080) [2669612] -- Fix typo in `--progress` deprecation message (#1076) [b4b7edc] - -### Maintenance -- chore: Included githubactions in the dependabot config (#976) [baea341] -- Bump golang.org/x/sys from 0.1.0 to 0.2.0 (#1075) [9646297] - -## 2.5.0 - -### Ginkgo output now includes a timeline-view of the spec - -This commit changes Ginkgo's default output. Spec details are now -presented as a **timeline** that includes events that occur during the spec -lifecycle interleaved with any GinkgoWriter content. This makes is much easier -to understand the flow of a spec and where a given failure occurs. - -The --progress, --slow-spec-threshold, --always-emit-ginkgo-writer flags -and the SuppressProgressReporting decorator have all been deprecated. Instead -the existing -v and -vv flags better capture the level of verbosity to display. However, -a new --show-node-events flag is added to include node `> Enter` and `< Exit` events -in the spec timeline. - -In addition, JUnit reports now include the timeline (rendered with -vv) and custom JUnit -reports can be configured and generated using -`GenerateJUnitReportWithConfig(report types.Report, dst string, config JunitReportConfig)` - -Code should continue to work unchanged with this version of Ginkgo - however if you have tooling that -was relying on the specific output format of Ginkgo you _may_ run into issues. Ginkgo's console output is not guaranteed to be stable for tooling and automation purposes. You should, instead, use Ginkgo's JSON format -to build tooling on top of as it has stronger guarantees to be stable from version to version. - -### Features -- Provide details about which timeout expired [0f2fa27] - -### Fixes -- Add Support Policy to docs [c70867a] - -### Maintenance -- Bump github.com/onsi/gomega from 1.22.1 to 1.23.0 (#1070) [bb3b4e2] - -## 2.4.0 - -### Features - -- DeferCleanup supports functions with multiple-return values [5e33c75] -- Add GinkgoLogr (#1067) [bf78c28] -- Introduction of 'MustPassRepeatedly' decorator (#1051) [047c02f] - -### Fixes -- correcting some typos (#1064) [1403d3c] -- fix flaky internal_integration interupt specs [2105ba3] -- Correct busted link in README [be6b5b9] - -### Maintenance -- Bump actions/checkout from 2 to 3 (#1062) [8a2f483] -- Bump golang.org/x/tools from 0.1.12 to 0.2.0 (#1065) [529c4e8] -- Bump github/codeql-action from 1 to 2 (#1061) [da09146] -- Bump actions/setup-go from 2 to 3 (#1060) [918040d] -- Bump github.com/onsi/gomega from 1.22.0 to 1.22.1 (#1053) [2098e4d] -- Bump nokogiri from 1.13.8 to 1.13.9 in /docs (#1066) [1d74122] -- Add GHA to dependabot config [4442772] - -## 2.3.1 - -## Fixes -Several users were invoking `ginkgo` by installing the latest version of the cli via `go install github.com/onsi/ginkgo/v2/ginkgo@latest`. When 2.3.0 was released this resulted in an influx of issues as CI systems failed due to a change in the internal contract between the Ginkgo CLI and the Ginkgo library. Ginkgo only supports running the same version of the library as the cli (which is why both are packaged in the same repository). - -With this patch release, the ginkgo CLI can now identify a version mismatch and emit a helpful error message. - -- Ginkgo cli can identify version mismatches and emit a helpful error message [bc4ae2f] -- further emphasize that a version match is required when running Ginkgo on CI and/or locally [2691dd8] - -### Maintenance -- bump gomega to v1.22.0 [822a937] - -## 2.3.0 - -### Interruptible Nodes and Timeouts - -Ginkgo now supports per-node and per-spec timeouts on interruptible nodes. Check out the [documentation for all the details](https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes) but the gist is you can now write specs like this: - -```go -It("is interruptible", func(ctx SpecContext) { // or context.Context instead of SpecContext, both are valid. - // do things until `ctx.Done()` is closed, for example: - req, err := http.NewRequestWithContext(ctx, "POST", "/build-widgets", nil) - Expect(err).NotTo(HaveOccured()) - _, err := http.DefaultClient.Do(req) - Expect(err).NotTo(HaveOccured()) - - Eventually(client.WidgetCount).WithContext(ctx).Should(Equal(17)) -}, NodeTimeout(time.Second*20), GracePeriod(5*time.Second)) -``` - -and have Ginkgo ensure that the node completes before the timeout elapses. If it does elapse, or if an external interrupt is received (e.g. `^C`) then Ginkgo will cancel the context and wait for the Grace Period for the node to exit before proceeding with any cleanup nodes associated with the spec. The `ctx` provided by Ginkgo can also be passed down to Gomega's `Eventually` to have all assertions within the node governed by a single deadline. - -### Features - -- Ginkgo now records any additional failures that occur during the cleanup of a failed spec. In prior versions this information was quietly discarded, but the introduction of a more rigorous approach to timeouts and interruptions allows Ginkgo to better track subsequent failures. -- `SpecContext` also provides a mechanism for third-party libraries to provide additional information when a Progress Report is generated. Gomega uses this to provide the current state of an `Eventually().WithContext()` assertion when a Progress Report is requested. -- DescribeTable now exits with an error if it is not passed any Entries [a4c9865] - -## Fixes -- fixes crashes on newer Ruby 3 installations by upgrading github-pages gem dependency [92c88d5] -- Make the outline command able to use the DSL import [1be2427] - -## Maintenance -- chore(docs): delete no meaning d [57c373c] -- chore(docs): Fix hyperlinks [30526d5] -- chore(docs): fix code blocks without language settings [cf611c4] -- fix intra-doc link [b541bcb] - -## 2.2.0 - -### Generate real-time Progress Reports [f91377c] - -Ginkgo can now generate Progress Reports to point users at the current running line of code (including a preview of the actual source code) and a best guess at the most relevant subroutines. - -These Progress Reports allow users to debug stuck or slow tests without exiting the Ginkgo process. A Progress Report can be generated at any time by sending Ginkgo a `SIGINFO` (`^T` on MacOS/BSD) or `SIGUSR1`. - -In addition, the user can specify `--poll-progress-after` and `--poll-progress-interval` to have Ginkgo start periodically emitting progress reports if a given node takes too long. These can be overriden/set on a per-node basis with the `PollProgressAfter` and `PollProgressInterval` decorators. - -Progress Reports are emitted to stdout, and also stored in the machine-redable report formats that Ginkgo supports. - -Ginkgo also uses this progress reporting infrastructure under the hood when handling timeouts and interrupts. This yields much more focused, useful, and informative stack traces than previously. - -### Features -- `BeforeSuite`, `AfterSuite`, `SynchronizedBeforeSuite`, `SynchronizedAfterSuite`, and `ReportAfterSuite` now support (the relevant subset of) decorators. These can be passed in _after_ the callback functions that are usually passed into these nodes. - - As a result the **signature of these methods has changed** and now includes a trailing `args ...interface{}`. For most users simply using the DSL, this change is transparent. However if you were assigning one of these functions to a custom variable (or passing it around) then your code may need to change to reflect the new signature. - -### Maintenance -- Modernize the invocation of Ginkgo in github actions [0ffde58] -- Update reocmmended CI settings in docs [896bbb9] -- Speed up unnecessarily slow integration test [6d3a90e] - -## 2.1.6 - -### Fixes -- Add `SuppressProgressReporting` decorator to turn off --progress announcements for a given node [dfef62a] -- chore: remove duplicate word in comments [7373214] - -## 2.1.5 - -### Fixes -- drop -mod=mod instructions; fixes #1026 [6ad7138] -- Ensure `CurrentSpecReport` and `AddReportEntry` are thread-safe [817c09b] -- remove stale importmap gcflags flag test [3cd8b93] -- Always emit spec summary [5cf23e2] - even when only one spec has failed -- Fix ReportAfterSuite usage in docs [b1864ad] -- fixed typo (#997) [219cc00] -- TrimRight is not designed to trim Suffix [71ebb74] -- refactor: replace strings.Replace with strings.ReplaceAll (#978) [143d208] -- fix syntax in examples (#975) [b69554f] - -### Maintenance -- Bump github.com/onsi/gomega from 1.20.0 to 1.20.1 (#1027) [e5dfce4] -- Bump tzinfo from 1.2.9 to 1.2.10 in /docs (#1006) [7ae91c4] -- Bump github.com/onsi/gomega from 1.19.0 to 1.20.0 (#1005) [e87a85a] -- test: add new Go 1.19 to test matrix (#1014) [bbefe12] -- Bump golang.org/x/tools from 0.1.11 to 0.1.12 (#1012) [9327906] -- Bump golang.org/x/tools from 0.1.10 to 0.1.11 (#993) [f44af96] -- Bump nokogiri from 1.13.3 to 1.13.6 in /docs (#981) [ef336aa] - ## 2.1.4 ### Fixes @@ -217,7 +49,7 @@ See [https://onsi.github.io/ginkgo/MIGRATING_TO_V2](https://onsi.github.io/ginkg Ginkgo 2.0 now has a Release Candidate. 1.16.5 advertises the existence of the RC. 1.16.5 deprecates GinkgoParallelNode in favor of GinkgoParallelProcess -You can silence the RC advertisement by setting an `ACK_GINKGO_RC=true` environment variable or creating a file in your home directory called `.ack-ginkgo-rc` +You can silence the RC advertisement by setting an `ACK_GINKG_RC=true` environment variable or creating a file in your home directory called `.ack-ginkgo-rc` ## 1.16.4 @@ -324,7 +156,7 @@ You can silence the RC advertisement by setting an `ACK_GINKGO_RC=true` environm - replace tail package with maintained one. this fixes go get errors (#667) [4ba33d4] - improve ginkgo performance - makes progress on #644 [a14f98e] - fix convert integration tests [1f8ba69] -- fix typo successful -> successful (#663) [1ea49cf] +- fix typo succesful -> successful (#663) [1ea49cf] - Fix invalid link (#658) [b886136] - convert utility : Include comments from source (#657) [1077c6d] - Explain what BDD means [d79e7fb] @@ -418,7 +250,7 @@ You can silence the RC advertisement by setting an `ACK_GINKGO_RC=true` environm - Make generated Junit file compatible with "Maven Surefire" (#488) [e51bee6] - all: gofmt [000d317] - Increase eventually timeout to 30s [c73579c] -- Clarify asynchronous test behavior [294d8f4] +- Clarify asynchronous test behaviour [294d8f4] - Travis badge should only show master [26d2143] ## 1.5.0 5/10/2018 @@ -436,13 +268,13 @@ You can silence the RC advertisement by setting an `ACK_GINKGO_RC=true` environm - When running a test and calculating the coverage using the `-coverprofile` and `-outputdir` flags, Ginkgo fails with an error if the directory does not exist. This is due to an [issue in go 1.10](https://github.com/golang/go/issues/24588) (#446) [b36a6e0] - `unfocus` command ignores vendor folder (#459) [e5e551c, c556e43, a3b6351, 9a820dd] - Ignore packages whose tests are all ignored by go (#456) [7430ca7, 6d8be98] -- Increase the threshold when checking time measurements (#455) [2f714bf, 68f622c] +- Increase the threshold when checking time measuments (#455) [2f714bf, 68f622c] - Fix race condition in coverage tests (#423) [a5a8ff7, ab9c08b] - Add an extra new line after reporting spec run completion for test2json [874520d] - added name name field to junit reported testsuite [ae61c63] - Do not set the run time of a spec when the dryRun flag is used (#438) [457e2d9, ba8e856] - Process FWhen and FSpecify when unfocusing (#434) [9008c7b, ee65bd, df87dfe] -- Synchronies the access to the state of specs to avoid race conditions (#430) [7d481bc, ae6829d] +- Synchronise the access to the state of specs to avoid race conditions (#430) [7d481bc, ae6829d] - Added Duration on GinkgoTestDescription (#383) [5f49dad, 528417e, 0747408, 329d7ed] - Fix Ginkgo stack trace on failure for Specify (#415) [b977ede, 65ca40e, 6c46eb8] - Update README with Go 1.6+, Golang -> Go (#409) [17f6b97, bc14b66, 20d1598] diff --git a/vendor/github.com/onsi/ginkgo/v2/CONTRIBUTING.md b/vendor/github.com/onsi/ginkgo/v2/CONTRIBUTING.md index 1da92fe7..15079406 100644 --- a/vendor/github.com/onsi/ginkgo/v2/CONTRIBUTING.md +++ b/vendor/github.com/onsi/ginkgo/v2/CONTRIBUTING.md @@ -8,6 +8,6 @@ Your contributions to Ginkgo are essential for its long-term maintenance and imp - When adding to the Ginkgo CLI, note that there are very few unit tests. Please add an integration test. - Make sure all the tests succeed via `ginkgo -r -p` - Vet your changes via `go vet ./...` -- Update the documentation. Ginkgo uses `godoc` comments and documentation in `docs/index.md`. You can run `bundle exec jekyll serve` in the `docs` directory to preview your changes. +- Update the documentation. Ginko uses `godoc` comments and documentation in `docs/index.md`. You can run `bundle exec jekyll serve` in the `docs` directory to preview your changes. Thanks for supporting Ginkgo! \ No newline at end of file diff --git a/vendor/github.com/onsi/ginkgo/v2/README.md b/vendor/github.com/onsi/ginkgo/v2/README.md index d0473a46..58507c36 100644 --- a/vendor/github.com/onsi/ginkgo/v2/README.md +++ b/vendor/github.com/onsi/ginkgo/v2/README.md @@ -4,7 +4,11 @@ --- -# Ginkgo +# Ginkgo 2.0 is now Generally Available! + +You can learn more about 2.0 in the [Migration Guide](https://onsi.github.io/ginkgo/MIGRATING_TO_V2)! + +--- Ginkgo is a mature testing framework for Go designed to help you write expressive specs. Ginkgo builds on top of Go's `testing` foundation and is complemented by the [Gomega](https://github.com/onsi/gomega) matcher library. Together, Ginkgo and Gomega let you express the intent behind your specs clearly: @@ -29,53 +33,53 @@ Describe("Checking books out of the library", Label("library"), func() { }) When("the library has the book in question", func() { - BeforeEach(func(ctx SpecContext) { - Expect(library.Store(ctx, book)).To(Succeed()) + BeforeEach(func() { + Expect(library.Store(book)).To(Succeed()) }) Context("and the book is available", func() { - It("lends it to the reader", func(ctx SpecContext) { - Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed()) + It("lends it to the reader", func() { + Expect(valjean.Checkout(library, "Les Miserables")).To(Succeed()) Expect(valjean.Books()).To(ContainElement(book)) - Expect(library.UserWithBook(ctx, book)).To(Equal(valjean)) - }, SpecTimeout(time.Second * 5)) + Expect(library.UserWithBook(book)).To(Equal(valjean)) + }) }) Context("but the book has already been checked out", func() { var javert *users.User - BeforeEach(func(ctx SpecContext) { + BeforeEach(func() { javert = users.NewUser("Javert") - Expect(javert.Checkout(ctx, library, "Les Miserables")).To(Succeed()) + Expect(javert.Checkout(library, "Les Miserables")).To(Succeed()) }) - It("tells the user", func(ctx SpecContext) { - err := valjean.Checkout(ctx, library, "Les Miserables") + It("tells the user", func() { + err := valjean.Checkout(library, "Les Miserables") Expect(error).To(MatchError("Les Miserables is currently checked out")) - }, SpecTimeout(time.Second * 5)) + }) - It("lets the user place a hold and get notified later", func(ctx SpecContext) { - Expect(valjean.Hold(ctx, library, "Les Miserables")).To(Succeed()) - Expect(valjean.Holds(ctx)).To(ContainElement(book)) + It("lets the user place a hold and get notified later", func() { + Expect(valjean.Hold(library, "Les Miserables")).To(Succeed()) + Expect(valjean.Holds()).To(ContainElement(book)) By("when Javert returns the book") - Expect(javert.Return(ctx, library, book)).To(Succeed()) + Expect(javert.Return(library, book)).To(Succeed()) By("it eventually informs Valjean") notification := "Les Miserables is ready for pick up" - Eventually(ctx, valjean.Notifications).Should(ContainElement(notification)) + Eventually(valjean.Notifications).Should(ContainElement(notification)) - Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed()) - Expect(valjean.Books(ctx)).To(ContainElement(book)) - Expect(valjean.Holds(ctx)).To(BeEmpty()) - }, SpecTimeout(time.Second * 10)) + Expect(valjean.Checkout(library, "Les Miserables")).To(Succeed()) + Expect(valjean.Books()).To(ContainElement(book)) + Expect(valjean.Holds()).To(BeEmpty()) + }) }) }) When("the library does not have the book in question", func() { - It("tells the reader the book is unavailable", func(ctx SpecContext) { - err := valjean.Checkout(ctx, library, "Les Miserables") + It("tells the reader the book is unavailable", func() { + err := valjean.Checkout(library, "Les Miserables") Expect(error).To(MatchError("Les Miserables is not in the library catalog")) - }, SpecTimeout(time.Second * 5)) + }) }) }) ``` @@ -86,9 +90,9 @@ If you have a question, comment, bug report, feature request, etc. please open a ## Capabilities -Whether writing basic unit specs, complex integration specs, or even performance specs - Ginkgo gives you an expressive Domain-Specific Language (DSL) that will be familiar to users coming from frameworks such as [Quick](https://github.com/Quick/Quick), [RSpec](https://rspec.info), [Jasmine](https://jasmine.github.io), and [Busted](https://lunarmodules.github.io/busted/). This style of testing is sometimes referred to as "Behavior-Driven Development" (BDD) though Ginkgo's utility extends beyond acceptance-level testing. +Whether writing basic unit specs, complex integration specs, or even performance specs - Ginkgo gives you an expressive Domain-Specific Language (DSL) that will be familiar to users coming from frameworks such as [Quick](https://github.com/Quick/Quick), [RSpec](https://rspec.info), [Jasmine](https://jasmine.github.io), and [Busted](https://olivinelabs.com/busted/). This style of testing is sometimes referred to as "Behavior-Driven Development" (BDD) though Ginkgo's utility extends beyond acceptance-level testing. -With Ginkgo's DSL you can use nestable [`Describe`, `Context` and `When` container nodes](https://onsi.github.io/ginkgo/#organizing-specs-with-container-nodes) to help you organize your specs. [`BeforeEach` and `AfterEach` setup nodes](https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach) for setup and cleanup. [`It` and `Specify` subject nodes](https://onsi.github.io/ginkgo/#spec-subjects-it) that hold your assertions. [`BeforeSuite` and `AfterSuite` nodes](https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite) to prep for and cleanup after a suite... and [much more!](https://onsi.github.io/ginkgo/#writing-specs). +With Ginkgo's DSL you can use nestable [`Describe`, `Context` and `When` container nodes](https://onsi.github.io/ginkgo/#organizing-specs-with-container-nodes) to help you organize your specs. [`BeforeEach` and `AfterEach` setup nodes](https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach) for setup and cleanup. [`It` and `Specify` subject nodes](https://onsi.github.io/ginkgo/#spec-subjects-it) that hold your assertions. [`BeforeSuite` and `AfterSuite` nodes](https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite) to prep for and cleanup after a suite... and [much more!](https://onsi.github.io/ginkgo/#writing-specs) At runtime, Ginkgo can run your specs in reproducibly [random order](https://onsi.github.io/ginkgo/#spec-randomization) and has sophisticated support for [spec parallelization](https://onsi.github.io/ginkgo/#spec-parallelization). In fact, running specs in parallel is as easy as @@ -96,7 +100,7 @@ At runtime, Ginkgo can run your specs in reproducibly [random order](https://ons ginkgo -p ``` -By following [established patterns for writing parallel specs](https://onsi.github.io/ginkgo/#patterns-for-parallel-integration-specs) you can build even large, complex integration suites that parallelize cleanly and run performantly. And you don't have to worry about your spec suite hanging or leaving a mess behind - Ginkgo provides a per-node `context.Context` and the capability to interrupt the spec after a set period of time - and then clean up. +By following [established patterns for writing parallel specs](https://onsi.github.io/ginkgo/#patterns-for-parallel-integration-specs) you can build even large, complex integration suites that parallelize cleanly and run performantly. As your suites grow Ginkgo helps you keep your specs organized with [labels](https://onsi.github.io/ginkgo/#spec-labels) and lets you easily run [subsets of specs](https://onsi.github.io/ginkgo/#filtering-specs), either [programmatically](https://onsi.github.io/ginkgo/#focused-specs) or on the [command line](https://onsi.github.io/ginkgo/#combining-filters). And Ginkgo's reporting infrastructure generates machine-readable output in a [variety of formats](https://onsi.github.io/ginkgo/#generating-machine-readable-reports) _and_ allows you to build your own [custom reporting infrastructure](https://onsi.github.io/ginkgo/#generating-reports-programmatically). diff --git a/vendor/github.com/onsi/ginkgo/v2/RELEASING.md b/vendor/github.com/onsi/ginkgo/v2/RELEASING.md index 363815d7..0c80f668 100644 --- a/vendor/github.com/onsi/ginkgo/v2/RELEASING.md +++ b/vendor/github.com/onsi/ginkgo/v2/RELEASING.md @@ -1,13 +1,7 @@ A Ginkgo release is a tagged git sha and a GitHub release. To cut a release: 1. Ensure CHANGELOG.md is up to date. - - Use - ```bash - LAST_VERSION=$(git tag --sort=version:refname | tail -n1) - CHANGES=$(git log --pretty=format:'- %s [%h]' HEAD...$LAST_VERSION) - echo -e "## NEXT\n\n$CHANGES\n\n### Features\n\n### Fixes\n\n### Maintenance\n\n$(cat CHANGELOG.md)" > CHANGELOG.md - ``` - to update the changelog + - Use `git log --pretty=format:'- %s [%h]' HEAD...vX.X.X` to list all the commits since the last release - Categorize the changes into - Breaking Changes (requires a major version) - New Features (minor version) diff --git a/vendor/github.com/onsi/ginkgo/v2/core_dsl.go b/vendor/github.com/onsi/ginkgo/v2/core_dsl.go index 5a08574c..bdb90860 100644 --- a/vendor/github.com/onsi/ginkgo/v2/core_dsl.go +++ b/vendor/github.com/onsi/ginkgo/v2/core_dsl.go @@ -21,8 +21,8 @@ import ( "os" "path/filepath" "strings" + "time" - "github.com/go-logr/logr" "github.com/onsi/ginkgo/v2/formatter" "github.com/onsi/ginkgo/v2/internal" "github.com/onsi/ginkgo/v2/internal/global" @@ -46,9 +46,7 @@ func init() { var err error flagSet, err = types.BuildTestSuiteFlagSet(&suiteConfig, &reporterConfig) exitIfErr(err) - writer := internal.NewWriter(os.Stdout) - GinkgoWriter = writer - GinkgoLogr = internal.GinkgoLogrFunc(writer) + GinkgoWriter = internal.NewWriter(os.Stdout) } func exitIfErr(err error) { @@ -79,7 +77,7 @@ func exitIfErrors(errors []error) { } } -// The interface implemented by GinkgoWriter +//The interface implemented by GinkgoWriter type GinkgoWriterInterface interface { io.Writer @@ -91,15 +89,6 @@ type GinkgoWriterInterface interface { ClearTeeWriters() } -/* -SpecContext is the context object passed into nodes that are subject to a timeout or need to be notified of an interrupt. It implements the standard context.Context interface but also contains additional helpers to provide an extensibility point for Ginkgo. (As an example, Gomega's Eventually can use the methods defined on SpecContext to provide deeper integratoin with Ginkgo). - -You can do anything with SpecContext that you do with a typical context.Context including wrapping it with any of the context.With* methods. - -Ginkgo will cancel the SpecContext when a node is interrupted (e.g. by the user sending an interupt signal) or when a node has exceeded it's allowed run-time. Note, however, that even in cases where a node has a deadline, SpecContext will not return a deadline via .Deadline(). This is because Ginkgo does not use a WithDeadline() context to model node deadlines as Ginkgo needs control over the precise timing of the context cancellation to ensure it can provide an accurate progress report at the moment of cancellation. -*/ -type SpecContext = internal.SpecContext - /* GinkgoWriter implements a GinkgoWriterInterface and io.Writer @@ -114,12 +103,7 @@ You can learn more at https://onsi.github.io/ginkgo/#logging-output */ var GinkgoWriter GinkgoWriterInterface -/* -GinkgoLogr is a logr.Logger that writes to GinkgoWriter -*/ -var GinkgoLogr logr.Logger - -// The interface by which Ginkgo receives *testing.T +//The interface by which Ginkgo receives *testing.T type GinkgoTestingT interface { Fail() } @@ -184,7 +168,7 @@ func PauseOutputInterception() { outputInterceptor.PauseIntercepting() } -// ResumeOutputInterception() - see docs for PauseOutputInterception() +//ResumeOutputInterception() - see docs for PauseOutputInterception() func ResumeOutputInterception() { if outputInterceptor == nil { return @@ -275,7 +259,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...interface{}) bool { } writer := GinkgoWriter.(*internal.Writer) - if reporterConfig.Verbosity().GTE(types.VerbosityLevelVerbose) && suiteConfig.ParallelTotal == 1 { + if reporterConfig.Verbose && suiteConfig.ParallelTotal == 1 { writer.SetMode(internal.WriterModeStreamAndBuffer) } else { writer.SetMode(internal.WriterModeBufferOnly) @@ -293,7 +277,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...interface{}) bool { suitePath, err = filepath.Abs(suitePath) exitIfErr(err) - passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig) + passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(suiteConfig.Timeout, client), client, suiteConfig) outputInterceptor.Shutdown() flagSet.ValidateDeprecations(deprecationTracker) @@ -460,8 +444,6 @@ It nodes are Subject nodes that contain your spec code and assertions. Each It node corresponds to an individual Ginkgo spec. You cannot nest any other Ginkgo nodes within an It node's closure. -You can pass It nodes bare functions (func() {}) or functions that receive a SpecContext or context.Context: func(ctx SpecContext) {} and func (ctx context.Context) {}. If the function takes a context then the It is deemed interruptible and Ginkgo will cancel the context in the event of a timeout (configured via the SpecTimeout() or NodeTimeout() decorators) or of an interrupt signal. - You can learn more at https://onsi.github.io/ginkgo/#spec-subjects-it In addition, subject nodes can be decorated with a variety of decorators. You can learn more here: https://onsi.github.io/ginkgo/#decorator-reference */ @@ -512,7 +494,26 @@ Note that By does not generate a new Ginkgo node - rather it is simply synctacti You can learn more about By here: https://onsi.github.io/ginkgo/#documenting-complex-specs-by */ func By(text string, callback ...func()) { - exitIfErr(global.Suite.By(text, callback...)) + if !global.Suite.InRunPhase() { + exitIfErr(types.GinkgoErrors.ByNotDuringRunPhase(types.NewCodeLocation(1))) + } + value := struct { + Text string + Duration time.Duration + }{ + Text: text, + } + t := time.Now() + AddReportEntry("By Step", ReportEntryVisibilityNever, Offset(1), &value, t) + formatter := formatter.NewWithNoColorBool(reporterConfig.NoColor) + GinkgoWriter.Println(formatter.F("{{bold}}STEP:{{/}} %s {{gray}}%s{{/}}", text, t.Format(types.GINKGO_TIME_FORMAT))) + if len(callback) == 1 { + callback[0]() + value.Duration = time.Since(t) + } + if len(callback) > 1 { + panic("just one callback per By, please") + } } /* @@ -521,15 +522,11 @@ When running in parallel, each parallel process will call BeforeSuite. You may only register *one* BeforeSuite handler per test suite. You typically do so in your bootstrap file at the top level. -BeforeSuite can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body. - You cannot nest any other Ginkgo nodes within a BeforeSuite node's closure. You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite */ -func BeforeSuite(body interface{}, args ...interface{}) bool { - combinedArgs := []interface{}{body} - combinedArgs = append(combinedArgs, args...) - return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeSuite, "", combinedArgs...)) +func BeforeSuite(body func()) bool { + return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeSuite, "", body)) } /* @@ -540,15 +537,11 @@ When running in parallel, each parallel process will call AfterSuite. You may only register *one* AfterSuite handler per test suite. You typically do so in your bootstrap file at the top level. -AfterSuite can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body. - You cannot nest any other Ginkgo nodes within an AfterSuite node's closure. You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite */ -func AfterSuite(body interface{}, args ...interface{}) bool { - combinedArgs := []interface{}{body} - combinedArgs = append(combinedArgs, args...) - return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterSuite, "", combinedArgs...)) +func AfterSuite(body func()) bool { + return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterSuite, "", body)) } /* @@ -559,34 +552,19 @@ information from that setup to all parallel processes. SynchronizedBeforeSuite accomplishes this by taking *two* function arguments and passing data between them. The first function is only run on parallel process #1. The second is run on all processes, but *only* after the first function completes successfully. The functions have the following signatures: -The first function (which only runs on process #1) can have any of the following the signatures: +The first function (which only runs on process #1) has the signature: - func() - func(ctx context.Context) - func(ctx SpecContext) func() []byte - func(ctx context.Context) []byte - func(ctx SpecContext) []byte -The byte array returned by the first function (if present) is then passed to the second function, which can have any of the following signature: +The byte array returned by the first function is then passed to the second function, which has the signature: - func() - func(ctx context.Context) - func(ctx SpecContext) func(data []byte) - func(ctx context.Context, data []byte) - func(ctx SpecContext, data []byte) - -If either function receives a context.Context/SpecContext it is considered interruptible. You cannot nest any other Ginkgo nodes within an SynchronizedBeforeSuite node's closure. You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite */ -func SynchronizedBeforeSuite(process1Body interface{}, allProcessBody interface{}, args ...interface{}) bool { - combinedArgs := []interface{}{process1Body, allProcessBody} - combinedArgs = append(combinedArgs, args...) - - return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeSynchronizedBeforeSuite, "", combinedArgs...)) +func SynchronizedBeforeSuite(process1Body func() []byte, allProcessBody func([]byte)) bool { + return pushNode(internal.NewSynchronizedBeforeSuiteNode(process1Body, allProcessBody, types.NewCodeLocation(1))) } /* @@ -595,26 +573,21 @@ and a piece that must only run once - on process #1. SynchronizedAfterSuite accomplishes this by taking *two* function arguments. The first runs on all processes. The second runs only on parallel process #1 and *only* after all other processes have finished and exited. This ensures that process #1, and any resources it is managing, remain alive until -all other processes are finished. These two functions can be bare functions (func()) or interruptible (func(context.Context)/func(SpecContext)) +all other processes are finished. Note that you can also use DeferCleanup() in SynchronizedBeforeSuite to accomplish similar results. You cannot nest any other Ginkgo nodes within an SynchronizedAfterSuite node's closure. You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite */ -func SynchronizedAfterSuite(allProcessBody interface{}, process1Body interface{}, args ...interface{}) bool { - combinedArgs := []interface{}{allProcessBody, process1Body} - combinedArgs = append(combinedArgs, args...) - - return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeSynchronizedAfterSuite, "", combinedArgs...)) +func SynchronizedAfterSuite(allProcessBody func(), process1Body func()) bool { + return pushNode(internal.NewSynchronizedAfterSuiteNode(allProcessBody, process1Body, types.NewCodeLocation(1))) } /* BeforeEach nodes are Setup nodes whose closures run before It node closures. When multiple BeforeEach nodes are defined in nested Container nodes the outermost BeforeEach node closures are run first. -BeforeEach can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body. - You cannot nest any other Ginkgo nodes within a BeforeEach node's closure. You can learn more here: https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach */ @@ -626,8 +599,6 @@ func BeforeEach(args ...interface{}) bool { JustBeforeEach nodes are similar to BeforeEach nodes, however they are guaranteed to run *after* all BeforeEach node closures - just before the It node closure. This can allow you to separate configuration from creation of resources for a spec. -JustBeforeEach can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body. - You cannot nest any other Ginkgo nodes within a JustBeforeEach node's closure. You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-creation-and-configuration-justbeforeeach */ @@ -641,8 +612,6 @@ are defined in nested Container nodes the innermost AfterEach node closures are Note that you can also use DeferCleanup() in other Setup or Subject nodes to accomplish similar results. -AfterEach can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body. - You cannot nest any other Ginkgo nodes within an AfterEach node's closure. You can learn more here: https://onsi.github.io/ginkgo/#spec-cleanup-aftereach-and-defercleanup */ @@ -653,8 +622,6 @@ func AfterEach(args ...interface{}) bool { /* JustAfterEach nodes are similar to AfterEach nodes, however they are guaranteed to run *before* all AfterEach node closures - just after the It node closure. This can allow you to separate diagnostics collection from teardown for a spec. -JustAfterEach can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body. - You cannot nest any other Ginkgo nodes within a JustAfterEach node's closure. You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-diagnostics-collection-and-teardown-justaftereach */ @@ -663,12 +630,10 @@ func JustAfterEach(args ...interface{}) bool { } /* -BeforeAll nodes are Setup nodes that can occur inside Ordered containers. They run just once before any specs in the Ordered container run. +BeforeAll nodes are Setup nodes that can occur inside Ordered contaienrs. They run just once before any specs in the Ordered container run. Multiple BeforeAll nodes can be defined in a given Ordered container however they cannot be nested inside any other container. -BeforeAll can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body. - You cannot nest any other Ginkgo nodes within a BeforeAll node's closure. You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers And you can learn more about BeforeAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall @@ -678,14 +643,12 @@ func BeforeAll(args ...interface{}) bool { } /* -AfterAll nodes are Setup nodes that can occur inside Ordered containers. They run just once after all specs in the Ordered container have run. +AfterAll nodes are Setup nodes that can occur inside Ordered contaienrs. They run just once after all specs in the Ordered container have run. Multiple AfterAll nodes can be defined in a given Ordered container however they cannot be nested inside any other container. Note that you can also use DeferCleanup() in a BeforeAll node to accomplish similar behavior. -AfterAll can take a func() body, or an interruptible func(SpecContext)/func(context.Context) body. - You cannot nest any other Ginkgo nodes within an AfterAll node's closure. You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers And you can learn more about AfterAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall @@ -699,33 +662,16 @@ DeferCleanup can be called within any Setup or Subject node to register a cleanu DeferCleanup can be passed: 1. A function that takes no arguments and returns no values. -2. A function that returns multiple values. `DeferCleanup` will ignore all these return values except for the last one. If this last return value is a non-nil error `DeferCleanup` will fail the spec). -3. A function that takes a context.Context or SpecContext (and optionally returns multiple values). The resulting cleanup node is deemed interruptible and the passed-in context will be cancelled in the event of a timeout or interrupt. -4. A function that takes arguments (and optionally returns multiple values) followed by a list of arguments to pass to the function. -5. A function that takes SpecContext and a list of arguments (and optionally returns multiple values) followed by a list of arguments to pass to the function. - -For example: +2. A function that returns an error (in which case it will assert that the returned error was nil, or it will fail the spec). +3. A function that takes arguments (and optionally returns an error) followed by a list of arguments to passe to the function. For example: - BeforeEach(func() { - DeferCleanup(os.SetEnv, "FOO", os.GetEnv("FOO")) - os.SetEnv("FOO", "BAR") - }) + BeforeEach(func() { + DeferCleanup(os.SetEnv, "FOO", os.GetEnv("FOO")) + os.SetEnv("FOO", "BAR") + }) will register a cleanup handler that will set the environment variable "FOO" to it's current value (obtained by os.GetEnv("FOO")) after the spec runs and then sets the environment variable "FOO" to "BAR" for the current spec. -Similarly: - - BeforeEach(func() { - DeferCleanup(func(ctx SpecContext, path) { - req, err := http.NewRequestWithContext(ctx, "POST", path, nil) - Expect(err).NotTo(HaveOccured()) - _, err := http.DefaultClient.Do(req) - Expect(err).NotTo(HaveOccured()) - }, "example.com/cleanup", NodeTimeout(time.Second*3)) - }) - -will register a cleanup handler that will have three seconds to successfully complete a request to the specified path. Note that we do not specify a context in the list of arguments passed to DeferCleanup - only in the signature of the function we pass in. Ginkgo will detect the requested context and supply a SpecContext when it invokes the cleanup node. If you want to pass in your own context in addition to the Ginkgo-provided SpecContext you must specify the SpecContext as the first argument (e.g. func(ctx SpecContext, otherCtx context.Context)). - When DeferCleanup is called in BeforeEach, JustBeforeEach, It, AfterEach, or JustAfterEach the registered callback will be invoked when the spec completes (i.e. it will behave like an AfterEach node) When DeferCleanup is called in BeforeAll or AfterAll the registered callback will be invoked when the ordered container completes (i.e. it will behave like an AfterAll node) When DeferCleanup is called in BeforeSuite, SynchronizedBeforeSuite, AfterSuite, or SynchronizedAfterSuite the registered callback will be invoked when the suite completes (i.e. it will behave like an AfterSuite node) @@ -737,5 +683,5 @@ func DeferCleanup(args ...interface{}) { fail := func(message string, cl types.CodeLocation) { global.Failer.Fail(message, cl) } - pushNode(internal.NewCleanupNode(deprecationTracker, fail, args...)) + pushNode(internal.NewCleanupNode(fail, args...)) } diff --git a/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go b/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go index e43d9cbb..f23e526f 100644 --- a/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go +++ b/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go @@ -13,21 +13,13 @@ You can learn more about decorators here: https://onsi.github.io/ginkgo/#decorat type Offset = internal.Offset /* -FlakeAttempts(uint N) is a decorator that allows you to mark individual specs or spec containers as flaky. Ginkgo will run them up to `N` times until they pass. +FlakeAttempts(uint N) is a decorator that allows you to mark individual specs or spec containers as flaky. Ginkgo will run them up to `N` times until they pass. -You can learn more here: https://onsi.github.io/ginkgo/#the-flakeattempts-decorator +You can learn more here: https://onsi.github.io/ginkgo/#repeating-spec-runs-and-managing-flaky-specs You can learn more about decorators here: https://onsi.github.io/ginkgo/#decorator-reference */ type FlakeAttempts = internal.FlakeAttempts -/* -MustPassRepeatedly(uint N) is a decorator that allows you to repeat the execution of individual specs or spec containers. Ginkgo will run them up to `N` times until they fail. - -You can learn more here: https://onsi.github.io/ginkgo/#the-mustpassrepeatedly-decorator -You can learn more about decorators here: https://onsi.github.io/ginkgo/#decorator-reference -*/ -type MustPassRepeatedly = internal.MustPassRepeatedly - /* Focus is a decorator that allows you to mark a spec or container as focused. Identical to FIt and FDescribe. @@ -67,7 +59,7 @@ OncePerOrdered is a decorator that allows you to mark outer BeforeEach, AfterEac per ordered context. Normally these setup nodes run around each individual spec, with OncePerOrdered they will run once around the set of specs in an ordered container. The behavior for non-Ordered containers/specs is unchanged. -You can learn more here: https://onsi.github.io/ginkgo/#setup-around-ordered-containers-the-onceperordered-decorator +You can learh more here: https://onsi.github.io/ginkgo/#setup-around-ordered-containers-the-onceperordered-decorator You can learn more about decorators here: https://onsi.github.io/ginkgo/#decorator-reference */ const OncePerOrdered = internal.OncePerOrdered @@ -88,46 +80,3 @@ Labels are the type for spec Label decorators. Use Label(...) to construct Labe You can learn more here: https://onsi.github.io/ginkgo/#spec-labels */ type Labels = internal.Labels - -/* -PollProgressAfter allows you to override the configured value for --poll-progress-after for a particular node. - -Ginkgo will start emitting node progress if the node is still running after a duration of PollProgressAfter. This allows you to get quicker feedback about the state of a long-running spec. -*/ -type PollProgressAfter = internal.PollProgressAfter - -/* -PollProgressInterval allows you to override the configured value for --poll-progress-interval for a particular node. - -Once a node has been running for longer than PollProgressAfter Ginkgo will emit node progress periodically at an interval of PollProgresInterval. -*/ -type PollProgressInterval = internal.PollProgressInterval - -/* -NodeTimeout allows you to specify a timeout for an indivdiual node. The node cannot be a container and must be interruptible (i.e. it must be passed a function that accepts a SpecContext or context.Context). - -If the node does not exit within the specified NodeTimeout its context will be cancelled. The node wil then have a period of time controlled by the GracePeriod decorator (or global --grace-period command-line argument) to exit. If the node does not exit within GracePeriod Ginkgo will leak the node and proceed to any clean-up nodes associated with the current spec. -*/ -type NodeTimeout = internal.NodeTimeout - -/* -SpecTimeout allows you to specify a timeout for an indivdiual spec. SpecTimeout can only decorate interruptible It nodes. - -All nodes associated with the It node will need to complete before the SpecTimeout has elapsed. Individual nodes (e.g. BeforeEach) may be decorated with different NodeTimeouts - but these can only serve to provide a more stringent deadline for the node in question; they cannot extend the deadline past the SpecTimeout. - -If the spec does not complete within the specified SpecTimeout the currently running node will have its context cancelled. The node wil then have a period of time controlled by that node's GracePeriod decorator (or global --grace-period command-line argument) to exit. If the node does not exit within GracePeriod Ginkgo will leak the node and proceed to any clean-up nodes associated with the current spec. -*/ -type SpecTimeout = internal.SpecTimeout - -/* -GracePeriod denotes the period of time Ginkgo will wait for an interruptible node to exit once an interruption (whether due to a timeout or a user-invoked signal) has occurred. If both the global --grace-period cli flag and a GracePeriod decorator are specified the value in the decorator will take precedence. - -Nodes that do not finish within a GracePeriod will be leaked and Ginkgo will proceed to run subsequent nodes. In the event of a timeout, such leaks will be reported to the user. -*/ -type GracePeriod = internal.GracePeriod - -/* -SuppressProgressReporting is a decorator that allows you to disable progress reporting of a particular node. This is useful if `ginkgo -v -progress` is generating too much noise; particularly -if you have a `ReportAfterEach` node that is running for every skipped spec and is generating lots of progress reports. -*/ -const SuppressProgressReporting = internal.SuppressProgressReporting diff --git a/vendor/github.com/onsi/ginkgo/v2/deprecated_dsl.go b/vendor/github.com/onsi/ginkgo/v2/deprecated_dsl.go index f912bbec..d20e5a8c 100644 --- a/vendor/github.com/onsi/ginkgo/v2/deprecated_dsl.go +++ b/vendor/github.com/onsi/ginkgo/v2/deprecated_dsl.go @@ -13,7 +13,7 @@ import ( Deprecated: Done Channel for asynchronous testing The Done channel pattern is no longer supported in Ginkgo 2.0. -See here for better patterns for asynchronous testing: https://onsi.github.io/ginkgo/#patterns-for-asynchronous-testing +See here for better patterns for asynchronouse testing: https://onsi.github.io/ginkgo/#patterns-for-asynchronous-testing For a migration guide see: https://onsi.github.io/ginkgo/MIGRATING_TO_V2#removed-async-testing */ diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/group.go b/vendor/github.com/onsi/ginkgo/v2/internal/group.go index 5c782d3f..c6546bba 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/group.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/group.go @@ -116,11 +116,8 @@ func (g *group) initialReportForSpec(spec Spec) types.SpecReport { LeafNodeText: spec.FirstNodeWithType(types.NodeTypeIt).Text, LeafNodeLabels: []string(spec.FirstNodeWithType(types.NodeTypeIt).Labels), ParallelProcess: g.suite.config.ParallelProcess, - RunningInParallel: g.suite.isRunningInParallel(), IsSerial: spec.Nodes.HasNodeMarkedSerial(), IsInOrderedContainer: !spec.Nodes.FirstNodeMarkedOrdered().IsZero(), - MaxFlakeAttempts: spec.Nodes.GetMaxFlakeAttempts(), - MaxMustPassRepeatedly: spec.Nodes.GetMaxMustPassRepeatedly(), } } @@ -131,10 +128,7 @@ func (g *group) evaluateSkipStatus(spec Spec) (types.SpecState, types.Failure) { if spec.Skip { return types.SpecStateSkipped, types.Failure{} } - if g.suite.interruptHandler.Status().Interrupted() || g.suite.skipAll { - return types.SpecStateSkipped, types.Failure{} - } - if !g.suite.deadline.IsZero() && g.suite.deadline.Before(time.Now()) { + if g.suite.interruptHandler.Status().Interrupted || g.suite.skipAll { return types.SpecStateSkipped, types.Failure{} } if !g.succeeded { @@ -169,6 +163,8 @@ func (g *group) isLastSpecWithPair(specID uint, pair runOncePair) bool { } func (g *group) attemptSpec(isFinalAttempt bool, spec Spec) { + interruptStatus := g.suite.interruptHandler.Status() + pairs := g.runOncePairs[spec.SubjectID()] nodes := spec.Nodes.WithType(types.NodeTypeBeforeAll) @@ -177,17 +173,12 @@ func (g *group) attemptSpec(isFinalAttempt bool, spec Spec) { nodes = append(nodes, spec.Nodes.FirstNodeWithType(types.NodeTypeIt)) terminatingNode, terminatingPair := Node{}, runOncePair{} - deadline := time.Time{} - if spec.SpecTimeout() > 0 { - deadline = time.Now().Add(spec.SpecTimeout()) - } - for _, node := range nodes { oncePair := pairs.runOncePairFor(node.ID) if !oncePair.isZero() && g.runOnceTracker[oncePair].Is(types.SpecStatePassed) { continue } - g.suite.currentSpecReport.State, g.suite.currentSpecReport.Failure = g.suite.runNode(node, deadline, spec.Nodes.BestTextFor(node)) + g.suite.currentSpecReport.State, g.suite.currentSpecReport.Failure = g.suite.runNode(node, interruptStatus.Channel, spec.Nodes.BestTextFor(node)) g.suite.currentSpecReport.RunTime = time.Since(g.suite.currentSpecReport.StartTime) if !oncePair.isZero() { g.runOnceTracker[oncePair] = g.suite.currentSpecReport.State @@ -269,13 +260,11 @@ func (g *group) attemptSpec(isFinalAttempt bool, spec Spec) { for _, node := range nodes { afterNodeWasRun[node.ID] = true - state, failure := g.suite.runNode(node, deadline, spec.Nodes.BestTextFor(node)) + state, failure := g.suite.runNode(node, g.suite.interruptHandler.Status().Channel, spec.Nodes.BestTextFor(node)) g.suite.currentSpecReport.RunTime = time.Since(g.suite.currentSpecReport.StartTime) if g.suite.currentSpecReport.State == types.SpecStatePassed || state == types.SpecStateAborted { g.suite.currentSpecReport.State = state g.suite.currentSpecReport.Failure = failure - } else if state.Is(types.SpecStateFailureStates) { - g.suite.currentSpecReport.AdditionalFailures = append(g.suite.currentSpecReport.AdditionalFailures, types.AdditionalFailure{State: state, Failure: failure}) } } includeDeferCleanups = true @@ -290,10 +279,7 @@ func (g *group) run(specs Specs) { } for _, spec := range g.specs { - g.suite.selectiveLock.Lock() g.suite.currentSpecReport = g.initialReportForSpec(spec) - g.suite.selectiveLock.Unlock() - g.suite.currentSpecReport.State, g.suite.currentSpecReport.Failure = g.evaluateSkipStatus(spec) g.suite.reporter.WillRun(g.suite.currentSpecReport) g.suite.reportEach(spec, types.NodeTypeReportBeforeEach) @@ -302,29 +288,16 @@ func (g *group) run(specs Specs) { g.suite.currentSpecReport.StartTime = time.Now() if !skip { - - var maxAttempts = 1 - - if g.suite.currentSpecReport.MaxMustPassRepeatedly > 0 { - maxAttempts = max(1, spec.MustPassRepeatedly()) - } else if g.suite.config.FlakeAttempts > 0 { + maxAttempts := max(1, spec.FlakeAttempts()) + if g.suite.config.FlakeAttempts > 0 { maxAttempts = g.suite.config.FlakeAttempts - g.suite.currentSpecReport.MaxFlakeAttempts = maxAttempts - } else if g.suite.currentSpecReport.MaxFlakeAttempts > 0 { - maxAttempts = max(1, spec.FlakeAttempts()) } - for attempt := 0; attempt < maxAttempts; attempt++ { g.suite.currentSpecReport.NumAttempts = attempt + 1 g.suite.writer.Truncate() g.suite.outputInterceptor.StartInterceptingOutput() if attempt > 0 { - if g.suite.currentSpecReport.MaxMustPassRepeatedly > 0 { - g.suite.handleSpecEvent(types.SpecEvent{SpecEventType: types.SpecEventSpecRepeat, Attempt: attempt}) - } - if g.suite.currentSpecReport.MaxFlakeAttempts > 0 { - g.suite.handleSpecEvent(types.SpecEvent{SpecEventType: types.SpecEventSpecRetry, Attempt: attempt}) - } + fmt.Fprintf(g.suite.writer, "\nGinkgo: Attempt #%d Failed. Retrying...\n", attempt) } g.attemptSpec(attempt == maxAttempts-1, spec) @@ -334,19 +307,8 @@ func (g *group) run(specs Specs) { g.suite.currentSpecReport.CapturedGinkgoWriterOutput += string(g.suite.writer.Bytes()) g.suite.currentSpecReport.CapturedStdOutErr += g.suite.outputInterceptor.StopInterceptingAndReturnOutput() - if g.suite.currentSpecReport.MaxMustPassRepeatedly > 0 { - if g.suite.currentSpecReport.State.Is(types.SpecStateFailureStates | types.SpecStateSkipped) { - break - } - } - if g.suite.currentSpecReport.MaxFlakeAttempts > 0 { - if g.suite.currentSpecReport.State.Is(types.SpecStatePassed | types.SpecStateSkipped | types.SpecStateAborted | types.SpecStateInterrupted) { - break - } else if attempt < maxAttempts-1 { - af := types.AdditionalFailure{State: g.suite.currentSpecReport.State, Failure: g.suite.currentSpecReport.Failure} - af.Failure.Message = fmt.Sprintf("Failure recorded during attempt %d:\n%s", attempt+1, af.Failure.Message) - g.suite.currentSpecReport.AdditionalFailures = append(g.suite.currentSpecReport.AdditionalFailures, af) - } + if g.suite.currentSpecReport.State.Is(types.SpecStatePassed | types.SpecStateSkipped | types.SpecStateAborted | types.SpecStateInterrupted) { + break } } } @@ -356,8 +318,227 @@ func (g *group) run(specs Specs) { if g.suite.currentSpecReport.State.Is(types.SpecStateFailureStates) { g.succeeded = false } - g.suite.selectiveLock.Lock() g.suite.currentSpecReport = types.SpecReport{} - g.suite.selectiveLock.Unlock() + } +} + +func (g *group) oldRun(specs Specs) { + var suite = g.suite + nodeState := map[uint]types.SpecState{} + groupSucceeded := true + + indexOfLastSpecContainingNodeID := func(id uint) int { + lastIdx := -1 + for idx := range specs { + if specs[idx].Nodes.ContainsNodeID(id) && !specs[idx].Skip { + lastIdx = idx + } + } + return lastIdx + } + + for i, spec := range specs { + suite.currentSpecReport = types.SpecReport{ + ContainerHierarchyTexts: spec.Nodes.WithType(types.NodeTypeContainer).Texts(), + ContainerHierarchyLocations: spec.Nodes.WithType(types.NodeTypeContainer).CodeLocations(), + ContainerHierarchyLabels: spec.Nodes.WithType(types.NodeTypeContainer).Labels(), + LeafNodeLocation: spec.FirstNodeWithType(types.NodeTypeIt).CodeLocation, + LeafNodeType: types.NodeTypeIt, + LeafNodeText: spec.FirstNodeWithType(types.NodeTypeIt).Text, + LeafNodeLabels: []string(spec.FirstNodeWithType(types.NodeTypeIt).Labels), + ParallelProcess: suite.config.ParallelProcess, + IsSerial: spec.Nodes.HasNodeMarkedSerial(), + IsInOrderedContainer: !spec.Nodes.FirstNodeMarkedOrdered().IsZero(), + } + + skip := spec.Skip + if spec.Nodes.HasNodeMarkedPending() { + skip = true + suite.currentSpecReport.State = types.SpecStatePending + } else { + if suite.interruptHandler.Status().Interrupted || suite.skipAll { + skip = true + } + if !groupSucceeded { + skip = true + suite.currentSpecReport.Failure = suite.failureForLeafNodeWithMessage(spec.FirstNodeWithType(types.NodeTypeIt), + "Spec skipped because an earlier spec in an ordered container failed") + } + for _, node := range spec.Nodes.WithType(types.NodeTypeBeforeAll) { + if nodeState[node.ID] == types.SpecStateSkipped { + skip = true + suite.currentSpecReport.Failure = suite.failureForLeafNodeWithMessage(spec.FirstNodeWithType(types.NodeTypeIt), + "Spec skipped because Skip() was called in BeforeAll") + break + } + } + if skip { + suite.currentSpecReport.State = types.SpecStateSkipped + } + } + + if suite.config.DryRun && !skip { + skip = true + suite.currentSpecReport.State = types.SpecStatePassed + } + + suite.reporter.WillRun(suite.currentSpecReport) + //send the spec report to any attached ReportBeforeEach blocks - this will update suite.currentSpecReport if failures occur in these blocks + suite.reportEach(spec, types.NodeTypeReportBeforeEach) + if suite.currentSpecReport.State.Is(types.SpecStateFailureStates) { + //the reportEach failed, skip this spec + skip = true + } + + suite.currentSpecReport.StartTime = time.Now() + maxAttempts := max(1, spec.FlakeAttempts()) + if suite.config.FlakeAttempts > 0 { + maxAttempts = suite.config.FlakeAttempts + } + + for attempt := 0; !skip && (attempt < maxAttempts); attempt++ { + suite.currentSpecReport.NumAttempts = attempt + 1 + suite.writer.Truncate() + suite.outputInterceptor.StartInterceptingOutput() + if attempt > 0 { + fmt.Fprintf(suite.writer, "\nGinkgo: Attempt #%d Failed. Retrying...\n", attempt) + } + isFinalAttempt := (attempt == maxAttempts-1) + + interruptStatus := suite.interruptHandler.Status() + deepestNestingLevelAttained := -1 + var nodes = spec.Nodes.WithType(types.NodeTypeBeforeAll).Filter(func(n Node) bool { + return nodeState[n.ID] != types.SpecStatePassed + }) + nodes = nodes.CopyAppend(spec.Nodes.WithType(types.NodeTypeBeforeEach)...).SortedByAscendingNestingLevel() + nodes = nodes.CopyAppend(spec.Nodes.WithType(types.NodeTypeJustBeforeEach).SortedByAscendingNestingLevel()...) + nodes = nodes.CopyAppend(spec.Nodes.WithType(types.NodeTypeIt)...) + + var terminatingNode Node + for j := range nodes { + deepestNestingLevelAttained = max(deepestNestingLevelAttained, nodes[j].NestingLevel) + suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(nodes[j], interruptStatus.Channel, spec.Nodes.BestTextFor(nodes[j])) + suite.currentSpecReport.RunTime = time.Since(suite.currentSpecReport.StartTime) + nodeState[nodes[j].ID] = suite.currentSpecReport.State + if suite.currentSpecReport.State != types.SpecStatePassed { + terminatingNode = nodes[j] + break + } + } + + afterAllNodesThatRan := map[uint]bool{} + // pull out some shared code so we aren't repeating ourselves down below. this just runs after and cleanup nodes + runAfterAndCleanupNodes := func(nodes Nodes) { + for j := range nodes { + state, failure := suite.runNode(nodes[j], suite.interruptHandler.Status().Channel, spec.Nodes.BestTextFor(nodes[j])) + suite.currentSpecReport.RunTime = time.Since(suite.currentSpecReport.StartTime) + nodeState[nodes[j].ID] = state + if suite.currentSpecReport.State == types.SpecStatePassed || state == types.SpecStateAborted { + suite.currentSpecReport.State = state + suite.currentSpecReport.Failure = failure + if state != types.SpecStatePassed { + terminatingNode = nodes[j] + } + } + if nodes[j].NodeType.Is(types.NodeTypeAfterAll) { + afterAllNodesThatRan[nodes[j].ID] = true + } + } + } + + // pull out a helper that captures the logic of whether or not we should run a given After node. + // there is complexity here stemming from the fact that we allow nested ordered contexts and flakey retries + shouldRunAfterNode := func(n Node) bool { + if n.NodeType.Is(types.NodeTypeAfterEach | types.NodeTypeJustAfterEach) { + return true + } + var id uint + if n.NodeType.Is(types.NodeTypeAfterAll) { + id = n.ID + if afterAllNodesThatRan[id] { //we've already run on this attempt. don't run again. + return false + } + } + if n.NodeType.Is(types.NodeTypeCleanupAfterAll) { + id = n.NodeIDWhereCleanupWasGenerated + } + isLastSpecWithNode := indexOfLastSpecContainingNodeID(id) == i + + switch suite.currentSpecReport.State { + case types.SpecStatePassed: //we've passed so far... + return isLastSpecWithNode //... and we're the last spec with this AfterNode, so we should run it + case types.SpecStateSkipped: //the spec was skipped by the user... + if isLastSpecWithNode { + return true //...we're the last spec, so we should run the AfterNode + } + if terminatingNode.NodeType.Is(types.NodeTypeBeforeAll) && terminatingNode.NestingLevel == n.NestingLevel { + return true //...or, a BeforeAll was skipped and it's at our nesting level, so our subgroup is going to skip + } + case types.SpecStateFailed, types.SpecStatePanicked: // the spec has failed... + if isFinalAttempt { + return true //...if this was the last attempt then we're the last spec to run and so the AfterNode should run + } + if terminatingNode.NodeType.Is(types.NodeTypeBeforeAll) { + //...we'll be rerunning a BeforeAll so we should cleanup after it if... + if n.NodeType.Is(types.NodeTypeAfterAll) && terminatingNode.NestingLevel == n.NestingLevel { + return true //we're at the same nesting level + } + if n.NodeType.Is(types.NodeTypeCleanupAfterAll) && terminatingNode.ID == n.NodeIDWhereCleanupWasGenerated { + return true //we're a DeferCleanup generated by it + } + } + if terminatingNode.NodeType.Is(types.NodeTypeAfterAll) { + //...we'll be rerunning an AfterAll so we should cleanup after it if... + if n.NodeType.Is(types.NodeTypeCleanupAfterAll) && terminatingNode.ID == n.NodeIDWhereCleanupWasGenerated { + return true //we're a DeferCleanup generated by it + } + } + case types.SpecStateInterrupted, types.SpecStateAborted: // ...we've been interrupted and/or aborted + return true //...that means the test run is over and we should clean up the stack. Run the AfterNode + } + return false + } + + // first pass - run all the JustAfterEach, Aftereach, and AfterAlls. Our shoudlRunAfterNode filter function will clean up the AfterAlls for us. + afterNodes := spec.Nodes.WithType(types.NodeTypeJustAfterEach).SortedByDescendingNestingLevel() + afterNodes = afterNodes.CopyAppend(spec.Nodes.WithType(types.NodeTypeAfterEach).CopyAppend(spec.Nodes.WithType(types.NodeTypeAfterAll)...).SortedByDescendingNestingLevel()...) + afterNodes = afterNodes.WithinNestingLevel(deepestNestingLevelAttained) + afterNodes = afterNodes.Filter(shouldRunAfterNode) + runAfterAndCleanupNodes(afterNodes) + + // second-pass perhaps we didn't run the AfterAlls but a state change due to an AfterEach now requires us to run the AfterAlls: + afterNodes = spec.Nodes.WithType(types.NodeTypeAfterAll).WithinNestingLevel(deepestNestingLevelAttained).Filter(shouldRunAfterNode) + runAfterAndCleanupNodes(afterNodes) + + // now we run any DeferCleanups + afterNodes = suite.cleanupNodes.WithType(types.NodeTypeCleanupAfterEach).Reverse() + afterNodes = append(afterNodes, suite.cleanupNodes.WithType(types.NodeTypeCleanupAfterAll).Filter(shouldRunAfterNode).Reverse()...) + runAfterAndCleanupNodes(afterNodes) + + // third-pass, perhaps a DeferCleanup failed and now we need to run the AfterAlls. + afterNodes = spec.Nodes.WithType(types.NodeTypeAfterAll).WithinNestingLevel(deepestNestingLevelAttained).Filter(shouldRunAfterNode) + runAfterAndCleanupNodes(afterNodes) + + // and finally - running AfterAlls may have generated some new DeferCleanup nodes, let's run them to finish up + afterNodes = suite.cleanupNodes.WithType(types.NodeTypeCleanupAfterAll).Reverse().Filter(shouldRunAfterNode) + runAfterAndCleanupNodes(afterNodes) + + suite.currentSpecReport.EndTime = time.Now() + suite.currentSpecReport.RunTime = suite.currentSpecReport.EndTime.Sub(suite.currentSpecReport.StartTime) + suite.currentSpecReport.CapturedGinkgoWriterOutput += string(suite.writer.Bytes()) + suite.currentSpecReport.CapturedStdOutErr += suite.outputInterceptor.StopInterceptingAndReturnOutput() + + if suite.currentSpecReport.State.Is(types.SpecStatePassed | types.SpecStateSkipped | types.SpecStateAborted | types.SpecStateInterrupted) { + break + } + } + + //send the spec report to any attached ReportAfterEach blocks - this will update suite.currentSpecReport if failures occur in these blocks + suite.reportEach(spec, types.NodeTypeReportAfterEach) + suite.processCurrentSpecReport() + if suite.currentSpecReport.State.Is(types.SpecStateFailureStates) { + groupSucceeded = false + } + suite.currentSpecReport = types.SpecReport{} } } diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go b/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go index ac6f5104..aca7d1c4 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go @@ -1,38 +1,39 @@ package interrupt_handler import ( + "fmt" "os" "os/signal" + "runtime" "sync" "syscall" "time" + "github.com/onsi/ginkgo/v2/formatter" "github.com/onsi/ginkgo/v2/internal/parallel_support" ) +const TIMEOUT_REPEAT_INTERRUPT_MAXIMUM_DURATION = 30 * time.Second +const TIMEOUT_REPEAT_INTERRUPT_FRACTION_OF_TIMEOUT = 10 const ABORT_POLLING_INTERVAL = 500 * time.Millisecond +const ABORT_REPEAT_INTERRUPT_DURATION = 30 * time.Second type InterruptCause uint const ( InterruptCauseInvalid InterruptCause = iota + InterruptCauseSignal + InterruptCauseTimeout InterruptCauseAbortByOtherProcess ) -type InterruptLevel uint - -const ( - InterruptLevelUninterrupted InterruptLevel = iota - InterruptLevelCleanupAndReport - InterruptLevelReportOnly - InterruptLevelBailOut -) - func (ic InterruptCause) String() string { switch ic { case InterruptCauseSignal: return "Interrupted by User" + case InterruptCauseTimeout: + return "Interrupted by Timeout" case InterruptCauseAbortByOtherProcess: return "Interrupted by Other Ginkgo Process" } @@ -40,49 +41,37 @@ func (ic InterruptCause) String() string { } type InterruptStatus struct { - Channel chan interface{} - Level InterruptLevel - Cause InterruptCause -} - -func (s InterruptStatus) Interrupted() bool { - return s.Level != InterruptLevelUninterrupted -} - -func (s InterruptStatus) Message() string { - return s.Cause.String() -} - -func (s InterruptStatus) ShouldIncludeProgressReport() bool { - return s.Cause != InterruptCauseAbortByOtherProcess + Interrupted bool + Channel chan interface{} + Cause InterruptCause } type InterruptHandlerInterface interface { Status() InterruptStatus + SetInterruptPlaceholderMessage(string) + ClearInterruptPlaceholderMessage() + InterruptMessageWithStackTraces() string } type InterruptHandler struct { - c chan interface{} - lock *sync.Mutex - level InterruptLevel - cause InterruptCause - client parallel_support.Client - stop chan interface{} - signals []os.Signal + c chan interface{} + lock *sync.Mutex + interrupted bool + interruptPlaceholderMessage string + interruptCause InterruptCause + client parallel_support.Client + stop chan interface{} } -func NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *InterruptHandler { - if len(signals) == 0 { - signals = []os.Signal{os.Interrupt, syscall.SIGTERM} - } +func NewInterruptHandler(timeout time.Duration, client parallel_support.Client) *InterruptHandler { handler := &InterruptHandler{ - c: make(chan interface{}), - lock: &sync.Mutex{}, - stop: make(chan interface{}), - client: client, - signals: signals, + c: make(chan interface{}), + lock: &sync.Mutex{}, + interrupted: false, + stop: make(chan interface{}), + client: client, } - handler.registerForInterrupts() + handler.registerForInterrupts(timeout) return handler } @@ -90,22 +79,30 @@ func (handler *InterruptHandler) Stop() { close(handler.stop) } -func (handler *InterruptHandler) registerForInterrupts() { +func (handler *InterruptHandler) registerForInterrupts(timeout time.Duration) { // os signal handling signalChannel := make(chan os.Signal, 1) - signal.Notify(signalChannel, handler.signals...) + signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM) + + // timeout handling + var timeoutChannel <-chan time.Time + var timeoutTimer *time.Timer + if timeout > 0 { + timeoutTimer = time.NewTimer(timeout) + timeoutChannel = timeoutTimer.C + } // cross-process abort handling - var abortChannel chan interface{} + var abortChannel chan bool if handler.client != nil { - abortChannel = make(chan interface{}) + abortChannel = make(chan bool) go func() { pollTicker := time.NewTicker(ABORT_POLLING_INTERVAL) for { select { case <-pollTicker.C: if handler.client.ShouldAbort() { - close(abortChannel) + abortChannel <- true pollTicker.Stop() return } @@ -117,37 +114,55 @@ func (handler *InterruptHandler) registerForInterrupts() { }() } - go func(abortChannel chan interface{}) { + // listen for any interrupt signals + // note that some (timeouts, cross-process aborts) will only trigger once + // for these we set up a ticker to keep interrupting the suite until it ends + // this ensures any `AfterEach` or `AfterSuite`s that get stuck cleaning up + // get interrupted eventually + go func() { var interruptCause InterruptCause + var repeatChannel <-chan time.Time + var repeatTicker *time.Ticker for { select { case <-signalChannel: interruptCause = InterruptCauseSignal + case <-timeoutChannel: + interruptCause = InterruptCauseTimeout + repeatInterruptTimeout := timeout / time.Duration(TIMEOUT_REPEAT_INTERRUPT_FRACTION_OF_TIMEOUT) + if repeatInterruptTimeout > TIMEOUT_REPEAT_INTERRUPT_MAXIMUM_DURATION { + repeatInterruptTimeout = TIMEOUT_REPEAT_INTERRUPT_MAXIMUM_DURATION + } + timeoutTimer.Stop() + repeatTicker = time.NewTicker(repeatInterruptTimeout) + repeatChannel = repeatTicker.C case <-abortChannel: interruptCause = InterruptCauseAbortByOtherProcess + repeatTicker = time.NewTicker(ABORT_REPEAT_INTERRUPT_DURATION) + repeatChannel = repeatTicker.C + case <-repeatChannel: + //do nothing, just interrupt again using the same interruptCause case <-handler.stop: + if timeoutTimer != nil { + timeoutTimer.Stop() + } + if repeatTicker != nil { + repeatTicker.Stop() + } signal.Stop(signalChannel) return } - abortChannel = nil - handler.lock.Lock() - oldLevel := handler.level - handler.cause = interruptCause - if handler.level == InterruptLevelUninterrupted { - handler.level = InterruptLevelCleanupAndReport - } else if handler.level == InterruptLevelCleanupAndReport { - handler.level = InterruptLevelReportOnly - } else if handler.level == InterruptLevelReportOnly { - handler.level = InterruptLevelBailOut - } - if handler.level != oldLevel { - close(handler.c) - handler.c = make(chan interface{}) + handler.interruptCause = interruptCause + if handler.interruptPlaceholderMessage != "" { + fmt.Println(handler.interruptPlaceholderMessage) } + handler.interrupted = true + close(handler.c) + handler.c = make(chan interface{}) handler.lock.Unlock() } - }(abortChannel) + }() } func (handler *InterruptHandler) Status() InterruptStatus { @@ -155,8 +170,43 @@ func (handler *InterruptHandler) Status() InterruptStatus { defer handler.lock.Unlock() return InterruptStatus{ - Level: handler.level, - Channel: handler.c, - Cause: handler.cause, + Interrupted: handler.interrupted, + Channel: handler.c, + Cause: handler.interruptCause, + } +} + +func (handler *InterruptHandler) SetInterruptPlaceholderMessage(message string) { + handler.lock.Lock() + defer handler.lock.Unlock() + + handler.interruptPlaceholderMessage = message +} + +func (handler *InterruptHandler) ClearInterruptPlaceholderMessage() { + handler.lock.Lock() + defer handler.lock.Unlock() + + handler.interruptPlaceholderMessage = "" +} + +func (handler *InterruptHandler) InterruptMessageWithStackTraces() string { + handler.lock.Lock() + out := fmt.Sprintf("%s\n\n", handler.interruptCause.String()) + defer handler.lock.Unlock() + if handler.interruptCause == InterruptCauseAbortByOtherProcess { + return out + } + out += "Here's a stack trace of all running goroutines:\n" + buf := make([]byte, 8192) + for { + n := runtime.Stack(buf, true) + if n < len(buf) { + buf = buf[:n] + break + } + buf = make([]byte, 2*len(buf)) } + out += formatter.Fi(1, "%s", string(buf)) + return out } diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/node.go b/vendor/github.com/onsi/ginkgo/v2/internal/node.go index 0878c672..289e4dde 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/node.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/node.go @@ -1,11 +1,9 @@ package internal import ( - "context" "fmt" "reflect" "sort" - "time" "sync" @@ -29,20 +27,15 @@ type Node struct { NodeType types.NodeType Text string - Body func(SpecContext) + Body func() CodeLocation types.CodeLocation NestingLevel int - HasContext bool - SynchronizedBeforeSuiteProc1Body func(SpecContext) []byte - SynchronizedBeforeSuiteProc1BodyHasContext bool - SynchronizedBeforeSuiteAllProcsBody func(SpecContext, []byte) - SynchronizedBeforeSuiteAllProcsBodyHasContext bool + SynchronizedBeforeSuiteProc1Body func() []byte + SynchronizedBeforeSuiteAllProcsBody func([]byte) - SynchronizedAfterSuiteAllProcsBody func(SpecContext) - SynchronizedAfterSuiteAllProcsBodyHasContext bool - SynchronizedAfterSuiteProc1Body func(SpecContext) - SynchronizedAfterSuiteProc1BodyHasContext bool + SynchronizedAfterSuiteAllProcsBody func() + SynchronizedAfterSuiteProc1Body func() ReportEachBody func(types.SpecReport) ReportAfterSuiteBody func(types.Report) @@ -53,13 +46,7 @@ type Node struct { MarkedOrdered bool MarkedOncePerOrdered bool FlakeAttempts int - MustPassRepeatedly int Labels Labels - PollProgressAfter time.Duration - PollProgressInterval time.Duration - NodeTimeout time.Duration - SpecTimeout time.Duration - GracePeriod time.Duration NodeIDWhereCleanupWasGenerated uint } @@ -70,25 +57,17 @@ type pendingType bool type serialType bool type orderedType bool type honorsOrderedType bool -type suppressProgressReporting bool const Focus = focusType(true) const Pending = pendingType(true) const Serial = serialType(true) const Ordered = orderedType(true) const OncePerOrdered = honorsOrderedType(true) -const SuppressProgressReporting = suppressProgressReporting(true) type FlakeAttempts uint -type MustPassRepeatedly uint type Offset uint type Done chan<- interface{} // Deprecated Done Channel for asynchronous testing type Labels []string -type PollProgressInterval time.Duration -type PollProgressAfter time.Duration -type NodeTimeout time.Duration -type SpecTimeout time.Duration -type GracePeriod time.Duration func UnionOfLabels(labels ...Labels) Labels { out := Labels{} @@ -135,24 +114,10 @@ func isDecoration(arg interface{}) bool { return true case t == reflect.TypeOf(OncePerOrdered): return true - case t == reflect.TypeOf(SuppressProgressReporting): - return true case t == reflect.TypeOf(FlakeAttempts(0)): return true - case t == reflect.TypeOf(MustPassRepeatedly(0)): - return true case t == reflect.TypeOf(Labels{}): return true - case t == reflect.TypeOf(PollProgressInterval(0)): - return true - case t == reflect.TypeOf(PollProgressAfter(0)): - return true - case t == reflect.TypeOf(NodeTimeout(0)): - return true - case t == reflect.TypeOf(SpecTimeout(0)): - return true - case t == reflect.TypeOf(GracePeriod(0)): - return true case t.Kind() == reflect.Slice && isSliceOfDecorations(arg): return true default: @@ -173,23 +138,16 @@ func isSliceOfDecorations(slice interface{}) bool { return true } -var contextType = reflect.TypeOf(new(context.Context)).Elem() -var specContextType = reflect.TypeOf(new(SpecContext)).Elem() - func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...interface{}) (Node, []error) { baseOffset := 2 node := Node{ - ID: UniqueNodeID(), - NodeType: nodeType, - Text: text, - Labels: Labels{}, - CodeLocation: types.NewCodeLocation(baseOffset), - NestingLevel: -1, - PollProgressAfter: -1, - PollProgressInterval: -1, - GracePeriod: -1, + ID: UniqueNodeID(), + NodeType: nodeType, + Text: text, + Labels: Labels{}, + CodeLocation: types.NewCodeLocation(baseOffset), + NestingLevel: -1, } - errors := []error{} appendError := func(err error) { if err != nil { @@ -218,6 +176,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy remainingArgs = []interface{}{} //now process the rest of the args for _, arg := range args { + switch t := reflect.TypeOf(arg); { case t == reflect.TypeOf(float64(0)): break //ignore deprecated timeouts @@ -246,43 +205,11 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy if !nodeType.Is(types.NodeTypeBeforeEach | types.NodeTypeJustBeforeEach | types.NodeTypeAfterEach | types.NodeTypeJustAfterEach) { appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "OncePerOrdered")) } - case t == reflect.TypeOf(SuppressProgressReporting): - deprecationTracker.TrackDeprecation(types.Deprecations.SuppressProgressReporting()) case t == reflect.TypeOf(FlakeAttempts(0)): node.FlakeAttempts = int(arg.(FlakeAttempts)) if !nodeType.Is(types.NodeTypesForContainerAndIt) { appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "FlakeAttempts")) } - case t == reflect.TypeOf(MustPassRepeatedly(0)): - node.MustPassRepeatedly = int(arg.(MustPassRepeatedly)) - if !nodeType.Is(types.NodeTypesForContainerAndIt) { - appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "MustPassRepeatedly")) - } - case t == reflect.TypeOf(PollProgressAfter(0)): - node.PollProgressAfter = time.Duration(arg.(PollProgressAfter)) - if nodeType.Is(types.NodeTypeContainer) { - appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "PollProgressAfter")) - } - case t == reflect.TypeOf(PollProgressInterval(0)): - node.PollProgressInterval = time.Duration(arg.(PollProgressInterval)) - if nodeType.Is(types.NodeTypeContainer) { - appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "PollProgressInterval")) - } - case t == reflect.TypeOf(NodeTimeout(0)): - node.NodeTimeout = time.Duration(arg.(NodeTimeout)) - if nodeType.Is(types.NodeTypeContainer) { - appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "NodeTimeout")) - } - case t == reflect.TypeOf(SpecTimeout(0)): - node.SpecTimeout = time.Duration(arg.(SpecTimeout)) - if !nodeType.Is(types.NodeTypeIt) { - appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "SpecTimeout")) - } - case t == reflect.TypeOf(GracePeriod(0)): - node.GracePeriod = time.Duration(arg.(GracePeriod)) - if nodeType.Is(types.NodeTypeContainer) { - appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "GracePeriod")) - } case t == reflect.TypeOf(Labels{}): if !nodeType.Is(types.NodeTypesForContainerAndIt) { appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "Label")) @@ -296,85 +223,23 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy } } case t.Kind() == reflect.Func: - if nodeType.Is(types.NodeTypeContainer) { - if node.Body != nil { - appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType)) - trackedFunctionError = true - break - } - if t.NumOut() > 0 || t.NumIn() > 0 { - appendError(types.GinkgoErrors.InvalidBodyTypeForContainer(t, node.CodeLocation, nodeType)) - trackedFunctionError = true - break - } - body := arg.(func()) - node.Body = func(SpecContext) { body() } - } else if nodeType.Is(types.NodeTypeReportBeforeEach | types.NodeTypeReportAfterEach) { - if node.ReportEachBody == nil { - node.ReportEachBody = arg.(func(types.SpecReport)) - } else { - appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType)) - trackedFunctionError = true - break - } - } else if nodeType.Is(types.NodeTypeReportAfterSuite) { - if node.ReportAfterSuiteBody == nil { - node.ReportAfterSuiteBody = arg.(func(types.Report)) - } else { - appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType)) - trackedFunctionError = true - break - } - } else if nodeType.Is(types.NodeTypeSynchronizedBeforeSuite) { - if node.SynchronizedBeforeSuiteProc1Body != nil && node.SynchronizedBeforeSuiteAllProcsBody != nil { - appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType)) - trackedFunctionError = true - break - } - if node.SynchronizedBeforeSuiteProc1Body == nil { - body, hasContext := extractSynchronizedBeforeSuiteProc1Body(arg) - if body == nil { - appendError(types.GinkgoErrors.InvalidBodyTypeForSynchronizedBeforeSuiteProc1(t, node.CodeLocation)) - trackedFunctionError = true - } - node.SynchronizedBeforeSuiteProc1Body, node.SynchronizedBeforeSuiteProc1BodyHasContext = body, hasContext - } else if node.SynchronizedBeforeSuiteAllProcsBody == nil { - body, hasContext := extractSynchronizedBeforeSuiteAllProcsBody(arg) - if body == nil { - appendError(types.GinkgoErrors.InvalidBodyTypeForSynchronizedBeforeSuiteAllProcs(t, node.CodeLocation)) - trackedFunctionError = true - } - node.SynchronizedBeforeSuiteAllProcsBody, node.SynchronizedBeforeSuiteAllProcsBodyHasContext = body, hasContext - } - } else if nodeType.Is(types.NodeTypeSynchronizedAfterSuite) { - if node.SynchronizedAfterSuiteAllProcsBody != nil && node.SynchronizedAfterSuiteProc1Body != nil { - appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType)) - trackedFunctionError = true - break - } - body, hasContext := extractBodyFunction(deprecationTracker, node.CodeLocation, arg) - if body == nil { - appendError(types.GinkgoErrors.InvalidBodyType(t, node.CodeLocation, nodeType)) - trackedFunctionError = true - break - } - if node.SynchronizedAfterSuiteAllProcsBody == nil { - node.SynchronizedAfterSuiteAllProcsBody, node.SynchronizedAfterSuiteAllProcsBodyHasContext = body, hasContext - } else if node.SynchronizedAfterSuiteProc1Body == nil { - node.SynchronizedAfterSuiteProc1Body, node.SynchronizedAfterSuiteProc1BodyHasContext = body, hasContext - } + if node.Body != nil { + appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType)) + trackedFunctionError = true + break + } + isValid := (t.NumOut() == 0) && (t.NumIn() <= 1) && (t.NumIn() == 0 || t.In(0) == reflect.TypeOf(make(Done))) + if !isValid { + appendError(types.GinkgoErrors.InvalidBodyType(t, node.CodeLocation, nodeType)) + trackedFunctionError = true + break + } + if t.NumIn() == 0 { + node.Body = arg.(func()) } else { - if node.Body != nil { - appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType)) - trackedFunctionError = true - break - } - node.Body, node.HasContext = extractBodyFunction(deprecationTracker, node.CodeLocation, arg) - if node.Body == nil { - appendError(types.GinkgoErrors.InvalidBodyType(t, node.CodeLocation, nodeType)) - trackedFunctionError = true - break - } + deprecationTracker.TrackDeprecation(types.Deprecations.Async(), node.CodeLocation) + deprecatedAsyncBody := arg.(func(Done)) + node.Body = func() { deprecatedAsyncBody(make(Done)) } } default: remainingArgs = append(remainingArgs, arg) @@ -386,32 +251,13 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy appendError(types.GinkgoErrors.InvalidDeclarationOfFocusedAndPending(node.CodeLocation, nodeType)) } - hasContext := node.HasContext || node.SynchronizedAfterSuiteProc1BodyHasContext || node.SynchronizedAfterSuiteAllProcsBodyHasContext || node.SynchronizedBeforeSuiteProc1BodyHasContext || node.SynchronizedBeforeSuiteAllProcsBodyHasContext - - if !hasContext && (node.NodeTimeout > 0 || node.SpecTimeout > 0 || node.GracePeriod > 0) && len(errors) == 0 { - appendError(types.GinkgoErrors.InvalidTimeoutOrGracePeriodForNonContextNode(node.CodeLocation, nodeType)) - } - - if !node.NodeType.Is(types.NodeTypeReportBeforeEach|types.NodeTypeReportAfterEach|types.NodeTypeSynchronizedBeforeSuite|types.NodeTypeSynchronizedAfterSuite|types.NodeTypeReportAfterSuite) && node.Body == nil && !node.MarkedPending && !trackedFunctionError { - appendError(types.GinkgoErrors.MissingBodyFunction(node.CodeLocation, nodeType)) - } - - if node.NodeType.Is(types.NodeTypeSynchronizedBeforeSuite) && !trackedFunctionError && (node.SynchronizedBeforeSuiteProc1Body == nil || node.SynchronizedBeforeSuiteAllProcsBody == nil) { + if node.Body == nil && !node.MarkedPending && !trackedFunctionError { appendError(types.GinkgoErrors.MissingBodyFunction(node.CodeLocation, nodeType)) } - - if node.NodeType.Is(types.NodeTypeSynchronizedAfterSuite) && !trackedFunctionError && (node.SynchronizedAfterSuiteProc1Body == nil || node.SynchronizedAfterSuiteAllProcsBody == nil) { - appendError(types.GinkgoErrors.MissingBodyFunction(node.CodeLocation, nodeType)) - } - for _, arg := range remainingArgs { appendError(types.GinkgoErrors.UnknownDecorator(node.CodeLocation, nodeType, arg)) } - if node.FlakeAttempts > 0 && node.MustPassRepeatedly > 0 { - appendError(types.GinkgoErrors.InvalidDeclarationOfFlakeAttemptsAndMustPassRepeatedly(node.CodeLocation, nodeType)) - } - if len(errors) > 0 { return Node{}, errors } @@ -419,157 +265,96 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy return node, errors } -var doneType = reflect.TypeOf(make(Done)) - -func extractBodyFunction(deprecationTracker *types.DeprecationTracker, cl types.CodeLocation, arg interface{}) (func(SpecContext), bool) { - t := reflect.TypeOf(arg) - if t.NumOut() > 0 || t.NumIn() > 1 { - return nil, false - } - if t.NumIn() == 1 { - if t.In(0) == doneType { - deprecationTracker.TrackDeprecation(types.Deprecations.Async(), cl) - deprecatedAsyncBody := arg.(func(Done)) - return func(SpecContext) { deprecatedAsyncBody(make(Done)) }, false - } else if t.In(0).Implements(specContextType) { - return arg.(func(SpecContext)), true - } else if t.In(0).Implements(contextType) { - body := arg.(func(context.Context)) - return func(c SpecContext) { body(c) }, true - } - - return nil, false - } - - body := arg.(func()) - return func(SpecContext) { body() }, false -} - -var byteType = reflect.TypeOf([]byte{}) - -func extractSynchronizedBeforeSuiteProc1Body(arg interface{}) (func(SpecContext) []byte, bool) { - t := reflect.TypeOf(arg) - v := reflect.ValueOf(arg) - - if t.NumOut() > 1 || t.NumIn() > 1 { - return nil, false - } else if t.NumOut() == 1 && t.Out(0) != byteType { - return nil, false - } else if t.NumIn() == 1 && !t.In(0).Implements(contextType) { - return nil, false - } - hasContext := t.NumIn() == 1 - - return func(c SpecContext) []byte { - var out []reflect.Value - if hasContext { - out = v.Call([]reflect.Value{reflect.ValueOf(c)}) - } else { - out = v.Call([]reflect.Value{}) - } - if len(out) == 1 { - return (out[0].Interface()).([]byte) - } else { - return []byte{} - } - }, hasContext -} - -func extractSynchronizedBeforeSuiteAllProcsBody(arg interface{}) (func(SpecContext, []byte), bool) { - t := reflect.TypeOf(arg) - v := reflect.ValueOf(arg) - hasContext, hasByte := false, false - - if t.NumOut() > 0 || t.NumIn() > 2 { - return nil, false - } else if t.NumIn() == 2 && t.In(0).Implements(contextType) && t.In(1) == byteType { - hasContext, hasByte = true, true - } else if t.NumIn() == 1 && t.In(0).Implements(contextType) { - hasContext = true - } else if t.NumIn() == 1 && t.In(0) == byteType { - hasByte = true - } else if t.NumIn() != 0 { - return nil, false - } - - return func(c SpecContext, b []byte) { - in := []reflect.Value{} - if hasContext { - in = append(in, reflect.ValueOf(c)) - } - if hasByte { - in = append(in, reflect.ValueOf(b)) - } - v.Call(in) - }, hasContext +func NewSynchronizedBeforeSuiteNode(proc1Body func() []byte, allProcsBody func([]byte), codeLocation types.CodeLocation) (Node, []error) { + return Node{ + ID: UniqueNodeID(), + NodeType: types.NodeTypeSynchronizedBeforeSuite, + SynchronizedBeforeSuiteProc1Body: proc1Body, + SynchronizedBeforeSuiteAllProcsBody: allProcsBody, + CodeLocation: codeLocation, + }, nil +} + +func NewSynchronizedAfterSuiteNode(allProcsBody func(), proc1Body func(), codeLocation types.CodeLocation) (Node, []error) { + return Node{ + ID: UniqueNodeID(), + NodeType: types.NodeTypeSynchronizedAfterSuite, + SynchronizedAfterSuiteAllProcsBody: allProcsBody, + SynchronizedAfterSuiteProc1Body: proc1Body, + CodeLocation: codeLocation, + }, nil +} + +func NewReportBeforeEachNode(body func(types.SpecReport), codeLocation types.CodeLocation) (Node, []error) { + return Node{ + ID: UniqueNodeID(), + NodeType: types.NodeTypeReportBeforeEach, + ReportEachBody: body, + CodeLocation: codeLocation, + NestingLevel: -1, + }, nil +} + +func NewReportAfterEachNode(body func(types.SpecReport), codeLocation types.CodeLocation) (Node, []error) { + return Node{ + ID: UniqueNodeID(), + NodeType: types.NodeTypeReportAfterEach, + ReportEachBody: body, + CodeLocation: codeLocation, + NestingLevel: -1, + }, nil +} + +func NewReportAfterSuiteNode(text string, body func(types.Report), codeLocation types.CodeLocation) (Node, []error) { + return Node{ + ID: UniqueNodeID(), + Text: text, + NodeType: types.NodeTypeReportAfterSuite, + ReportAfterSuiteBody: body, + CodeLocation: codeLocation, + }, nil } -var errInterface = reflect.TypeOf((*error)(nil)).Elem() - -func NewCleanupNode(deprecationTracker *types.DeprecationTracker, fail func(string, types.CodeLocation), args ...interface{}) (Node, []error) { - decorations, remainingArgs := PartitionDecorations(args...) +func NewCleanupNode(fail func(string, types.CodeLocation), args ...interface{}) (Node, []error) { baseOffset := 2 - cl := types.NewCodeLocation(baseOffset) - finalArgs := []interface{}{} - for _, arg := range decorations { + node := Node{ + ID: UniqueNodeID(), + NodeType: types.NodeTypeCleanupInvalid, + CodeLocation: types.NewCodeLocation(baseOffset), + NestingLevel: -1, + } + remainingArgs := []interface{}{} + for _, arg := range args { switch t := reflect.TypeOf(arg); { case t == reflect.TypeOf(Offset(0)): - cl = types.NewCodeLocation(baseOffset + int(arg.(Offset))) + node.CodeLocation = types.NewCodeLocation(baseOffset + int(arg.(Offset))) case t == reflect.TypeOf(types.CodeLocation{}): - cl = arg.(types.CodeLocation) + node.CodeLocation = arg.(types.CodeLocation) default: - finalArgs = append(finalArgs, arg) + remainingArgs = append(remainingArgs, arg) } } - finalArgs = append(finalArgs, cl) if len(remainingArgs) == 0 { - return Node{}, []error{types.GinkgoErrors.DeferCleanupInvalidFunction(cl)} + return Node{}, []error{types.GinkgoErrors.DeferCleanupInvalidFunction(node.CodeLocation)} } - callback := reflect.ValueOf(remainingArgs[0]) - if !(callback.Kind() == reflect.Func) { - return Node{}, []error{types.GinkgoErrors.DeferCleanupInvalidFunction(cl)} + if !(callback.Kind() == reflect.Func && callback.Type().NumOut() <= 1) { + return Node{}, []error{types.GinkgoErrors.DeferCleanupInvalidFunction(node.CodeLocation)} } - callArgs := []reflect.Value{} for _, arg := range remainingArgs[1:] { callArgs = append(callArgs, reflect.ValueOf(arg)) } - - hasContext := false - t := callback.Type() - if t.NumIn() > 0 { - if t.In(0).Implements(specContextType) { - hasContext = true - } else if t.In(0).Implements(contextType) && (len(callArgs) == 0 || !callArgs[0].Type().Implements(contextType)) { - hasContext = true + cl := node.CodeLocation + node.Body = func() { + out := callback.Call(callArgs) + if len(out) == 1 && !out[0].IsNil() { + fail(fmt.Sprintf("DeferCleanup callback returned error: %v", out[0]), cl) } } - handleFailure := func(out []reflect.Value) { - if len(out) == 0 { - return - } - last := out[len(out)-1] - if last.Type().Implements(errInterface) && !last.IsNil() { - fail(fmt.Sprintf("DeferCleanup callback returned error: %v", last), cl) - } - } - - if hasContext { - finalArgs = append(finalArgs, func(c SpecContext) { - out := callback.Call(append([]reflect.Value{reflect.ValueOf(c)}, callArgs...)) - handleFailure(out) - }) - } else { - finalArgs = append(finalArgs, func() { - out := callback.Call(callArgs) - handleFailure(out) - }) - } - - return NewNode(deprecationTracker, types.NodeTypeCleanupInvalid, "", finalArgs...) + return node, nil } func (n Node) IsZero() bool { @@ -857,26 +642,6 @@ func (n Nodes) FirstNodeMarkedOrdered() Node { return Node{} } -func (n Nodes) GetMaxFlakeAttempts() int { - maxFlakeAttempts := 0 - for i := range n { - if n[i].FlakeAttempts > 0 { - maxFlakeAttempts = n[i].FlakeAttempts - } - } - return maxFlakeAttempts -} - -func (n Nodes) GetMaxMustPassRepeatedly() int { - maxMustPassRepeatedly := 0 - for i := range n { - if n[i].MustPassRepeatedly > 0 { - maxMustPassRepeatedly = n[i].MustPassRepeatedly - } - } - return maxMustPassRepeatedly -} - func unrollInterfaceSlice(args interface{}) []interface{} { v := reflect.ValueOf(args) if v.Kind() != reflect.Slice { diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor.go b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor.go index 4a1c0946..b59918a8 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor.go @@ -143,7 +143,7 @@ func (interceptor *genericOutputInterceptor) ResumeIntercepting() { go startPipeFactory(interceptor.pipeChannel, interceptor.shutdown) } - // Now we make a pipe, we'll use this to redirect the input to the 1 and 2 file descriptors (this is how everything else in the world is string to log to stdout and stderr) + // Now we make a pipe, we'll use this to redirect the input to the 1 and 2 file descriptors (this is how everything else in the world is tring to log to stdout and stderr) // we get the pipe from our pipe factory. it runs in the background so we can request the next pipe while the spec being intercepted is running interceptor.pipe = <-interceptor.pipeChannel diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go index f5ae15b8..e875001c 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go @@ -28,7 +28,7 @@ func (impl *dupSyscallOutputInterceptorImpl) CreateStdoutStderrClones() (*os.Fil // And then wrap the clone file descriptors in files. // One benefit of this (that we don't use yet) is that we can actually write - // to these files to emit output to the console even though we're intercepting output + // to these files to emit output to the console evne though we're intercepting output stdoutClone := os.NewFile(uintptr(stdoutCloneFD), "stdout-clone") stderrClone := os.NewFile(uintptr(stderrCloneFD), "stderr-clone") diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go index b417bf5b..7d5cb0b6 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go @@ -49,7 +49,6 @@ type Client interface { FetchNextCounter() (int, error) PostAbort() error ShouldAbort() bool - PostEmitProgressReport(report types.ProgressReport) error Write(p []byte) (int, error) } diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go index ad9932f2..d076d5d1 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go @@ -94,10 +94,6 @@ func (client *httpClient) PostSuiteDidEnd(report types.Report) error { return client.post("/suite-did-end", report) } -func (client *httpClient) PostEmitProgressReport(report types.ProgressReport) error { - return client.post("/progress-report", report) -} - func (client *httpClient) PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error { beforeSuiteState := BeforeSuiteState{ State: state, diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go index fa3ac682..ca1dcdca 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go @@ -49,7 +49,6 @@ func (server *httpServer) Start() { mux.HandleFunc("/did-run", server.didRun) mux.HandleFunc("/suite-did-end", server.specSuiteDidEnd) mux.HandleFunc("/emit-output", server.emitOutput) - mux.HandleFunc("/progress-report", server.emitProgressReport) //synchronization endpoints mux.HandleFunc("/before-suite-completed", server.handleBeforeSuiteCompleted) @@ -156,14 +155,6 @@ func (server *httpServer) emitOutput(writer http.ResponseWriter, request *http.R server.handleError(server.handler.EmitOutput(output, &n), writer) } -func (server *httpServer) emitProgressReport(writer http.ResponseWriter, request *http.Request) { - var report types.ProgressReport - if !server.decode(writer, request, &report) { - return - } - server.handleError(server.handler.EmitProgressReport(report, voidReceiver), writer) -} - func (server *httpServer) handleBeforeSuiteCompleted(writer http.ResponseWriter, request *http.Request) { var beforeSuiteState BeforeSuiteState if !server.decode(writer, request, &beforeSuiteState) { diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go index fe93cc2b..4e83b097 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go @@ -72,10 +72,6 @@ func (client *rpcClient) Write(p []byte) (int, error) { return n, err } -func (client *rpcClient) PostEmitProgressReport(report types.ProgressReport) error { - return client.client.Call("Server.EmitProgressReport", report, voidReceiver) -} - func (client *rpcClient) PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error { beforeSuiteState := BeforeSuiteState{ State: state, diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go index 7c6e67b9..ca471cf3 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go @@ -108,13 +108,6 @@ func (handler *ServerHandler) EmitOutput(output []byte, n *int) error { return err } -func (handler *ServerHandler) EmitProgressReport(report types.ProgressReport, _ *Void) error { - handler.lock.Lock() - defer handler.lock.Unlock() - handler.reporter.EmitProgressReport(report) - return nil -} - func (handler *ServerHandler) registerAlive(proc int, alive func() bool) { handler.lock.Lock() defer handler.lock.Unlock() diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/progress_report.go b/vendor/github.com/onsi/ginkgo/v2/internal/progress_report.go deleted file mode 100644 index 7dd3ca96..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/progress_report.go +++ /dev/null @@ -1,288 +0,0 @@ -package internal - -import ( - "bufio" - "bytes" - "context" - "fmt" - "io" - "os" - "os/signal" - "path/filepath" - "runtime" - "strconv" - "strings" - "time" - - "github.com/onsi/ginkgo/v2/types" -) - -var _SOURCE_CACHE = map[string][]string{} - -type ProgressSignalRegistrar func(func()) context.CancelFunc - -func RegisterForProgressSignal(handler func()) context.CancelFunc { - signalChannel := make(chan os.Signal, 1) - if len(PROGRESS_SIGNALS) > 0 { - signal.Notify(signalChannel, PROGRESS_SIGNALS...) - } - ctx, cancel := context.WithCancel(context.Background()) - go func() { - for { - select { - case <-signalChannel: - handler() - case <-ctx.Done(): - signal.Stop(signalChannel) - return - } - } - }() - - return cancel -} - -type ProgressStepCursor struct { - Text string - CodeLocation types.CodeLocation - StartTime time.Time -} - -func NewProgressReport(isRunningInParallel bool, report types.SpecReport, currentNode Node, currentNodeStartTime time.Time, currentStep types.SpecEvent, gwOutput string, timelineLocation types.TimelineLocation, additionalReports []string, sourceRoots []string, includeAll bool) (types.ProgressReport, error) { - pr := types.ProgressReport{ - ParallelProcess: report.ParallelProcess, - RunningInParallel: isRunningInParallel, - ContainerHierarchyTexts: report.ContainerHierarchyTexts, - LeafNodeText: report.LeafNodeText, - LeafNodeLocation: report.LeafNodeLocation, - SpecStartTime: report.StartTime, - - CurrentNodeType: currentNode.NodeType, - CurrentNodeText: currentNode.Text, - CurrentNodeLocation: currentNode.CodeLocation, - CurrentNodeStartTime: currentNodeStartTime, - - CurrentStepText: currentStep.Message, - CurrentStepLocation: currentStep.CodeLocation, - CurrentStepStartTime: currentStep.TimelineLocation.Time, - - AdditionalReports: additionalReports, - - CapturedGinkgoWriterOutput: gwOutput, - TimelineLocation: timelineLocation, - } - - goroutines, err := extractRunningGoroutines() - if err != nil { - return pr, err - } - pr.Goroutines = goroutines - - // now we want to try to find goroutines of interest. these will be goroutines that have any function calls with code in packagesOfInterest: - packagesOfInterest := map[string]bool{} - packageFromFilename := func(filename string) string { - return filepath.Dir(filename) - } - addPackageFor := func(filename string) { - if filename != "" { - packagesOfInterest[packageFromFilename(filename)] = true - } - } - isPackageOfInterest := func(filename string) bool { - stackPackage := packageFromFilename(filename) - for packageOfInterest := range packagesOfInterest { - if strings.HasPrefix(stackPackage, packageOfInterest) { - return true - } - } - return false - } - for _, location := range report.ContainerHierarchyLocations { - addPackageFor(location.FileName) - } - addPackageFor(report.LeafNodeLocation.FileName) - addPackageFor(currentNode.CodeLocation.FileName) - addPackageFor(currentStep.CodeLocation.FileName) - - //First, we find the SpecGoroutine - this will be the goroutine that includes `runNode` - specGoRoutineIdx := -1 - runNodeFunctionCallIdx := -1 -OUTER: - for goroutineIdx, goroutine := range pr.Goroutines { - for functionCallIdx, functionCall := range goroutine.Stack { - if strings.Contains(functionCall.Function, "ginkgo/v2/internal.(*Suite).runNode.func") { - specGoRoutineIdx = goroutineIdx - runNodeFunctionCallIdx = functionCallIdx - break OUTER - } - } - } - - //Now, we find the first non-Ginkgo function call - if specGoRoutineIdx > -1 { - for runNodeFunctionCallIdx >= 0 { - fn := goroutines[specGoRoutineIdx].Stack[runNodeFunctionCallIdx].Function - file := goroutines[specGoRoutineIdx].Stack[runNodeFunctionCallIdx].Filename - // these are all things that could potentially happen from within ginkgo - if strings.Contains(fn, "ginkgo/v2/internal") || strings.Contains(fn, "reflect.Value") || strings.Contains(file, "ginkgo/table_dsl") || strings.Contains(file, "ginkgo/core_dsl") { - runNodeFunctionCallIdx-- - continue - } - if strings.Contains(goroutines[specGoRoutineIdx].Stack[runNodeFunctionCallIdx].Function, "ginkgo/table_dsl") { - - } - //found it! lets add its package of interest - addPackageFor(goroutines[specGoRoutineIdx].Stack[runNodeFunctionCallIdx].Filename) - break - } - } - - ginkgoEntryPointIdx := -1 -OUTER_GINKGO_ENTRY_POINT: - for goroutineIdx, goroutine := range pr.Goroutines { - for _, functionCall := range goroutine.Stack { - if strings.Contains(functionCall.Function, "ginkgo/v2.RunSpecs") { - ginkgoEntryPointIdx = goroutineIdx - break OUTER_GINKGO_ENTRY_POINT - } - } - } - - // Now we go through all goroutines and highlight any lines with packages in `packagesOfInterest` - // Any goroutines with highlighted lines end up in the HighlightGoRoutines - for goroutineIdx, goroutine := range pr.Goroutines { - if goroutineIdx == ginkgoEntryPointIdx { - continue - } - if goroutineIdx == specGoRoutineIdx { - pr.Goroutines[goroutineIdx].IsSpecGoroutine = true - } - for functionCallIdx, functionCall := range goroutine.Stack { - if isPackageOfInterest(functionCall.Filename) { - goroutine.Stack[functionCallIdx].Highlight = true - goroutine.Stack[functionCallIdx].Source, goroutine.Stack[functionCallIdx].SourceHighlight = fetchSource(functionCall.Filename, functionCall.Line, 2, sourceRoots) - } - } - } - - if !includeAll { - goroutines := []types.Goroutine{pr.SpecGoroutine()} - goroutines = append(goroutines, pr.HighlightedGoroutines()...) - pr.Goroutines = goroutines - } - - return pr, nil -} - -func extractRunningGoroutines() ([]types.Goroutine, error) { - var stack []byte - for size := 64 * 1024; ; size *= 2 { - stack = make([]byte, size) - if n := runtime.Stack(stack, true); n < size { - stack = stack[:n] - break - } - } - - r := bufio.NewReader(bytes.NewReader(stack)) - out := []types.Goroutine{} - idx := -1 - for { - line, err := r.ReadString('\n') - if err == io.EOF { - break - } - - line = strings.TrimSuffix(line, "\n") - - //skip blank lines - if line == "" { - continue - } - - //parse headers for new goroutine frames - if strings.HasPrefix(line, "goroutine") { - out = append(out, types.Goroutine{}) - idx = len(out) - 1 - - line = strings.TrimPrefix(line, "goroutine ") - line = strings.TrimSuffix(line, ":") - fields := strings.SplitN(line, " ", 2) - if len(fields) != 2 { - return nil, types.GinkgoErrors.FailedToParseStackTrace(fmt.Sprintf("Invalid goroutine frame header: %s", line)) - } - out[idx].ID, err = strconv.ParseUint(fields[0], 10, 64) - if err != nil { - return nil, types.GinkgoErrors.FailedToParseStackTrace(fmt.Sprintf("Invalid goroutine ID: %s", fields[1])) - } - - out[idx].State = strings.TrimSuffix(strings.TrimPrefix(fields[1], "["), "]") - continue - } - - //if we are here we must be at a function call entry in the stack - functionCall := types.FunctionCall{ - Function: strings.TrimPrefix(line, "created by "), // no need to track 'created by' - } - - line, err = r.ReadString('\n') - line = strings.TrimSuffix(line, "\n") - if err == io.EOF { - return nil, types.GinkgoErrors.FailedToParseStackTrace(fmt.Sprintf("Invalid function call: %s -- missing file name and line number", functionCall.Function)) - } - line = strings.TrimLeft(line, " \t") - fields := strings.SplitN(line, ":", 2) - if len(fields) != 2 { - return nil, types.GinkgoErrors.FailedToParseStackTrace(fmt.Sprintf("Invalid filename nad line number: %s", line)) - } - functionCall.Filename = fields[0] - line = strings.Split(fields[1], " ")[0] - lineNumber, err := strconv.ParseInt(line, 10, 64) - functionCall.Line = int(lineNumber) - if err != nil { - return nil, types.GinkgoErrors.FailedToParseStackTrace(fmt.Sprintf("Invalid function call line number: %s\n%s", line, err.Error())) - } - out[idx].Stack = append(out[idx].Stack, functionCall) - } - - return out, nil -} - -func fetchSource(filename string, lineNumber int, span int, configuredSourceRoots []string) ([]string, int) { - if filename == "" { - return []string{}, 0 - } - - var lines []string - var ok bool - if lines, ok = _SOURCE_CACHE[filename]; !ok { - sourceRoots := []string{""} - sourceRoots = append(sourceRoots, configuredSourceRoots...) - var data []byte - var err error - var found bool - for _, root := range sourceRoots { - data, err = os.ReadFile(filepath.Join(root, filename)) - if err == nil { - found = true - break - } - } - if !found { - return []string{}, 0 - } - lines = strings.Split(string(data), "\n") - _SOURCE_CACHE[filename] = lines - } - - startIndex := lineNumber - span - 1 - endIndex := startIndex + span + span + 1 - if startIndex < 0 { - startIndex = 0 - } - if endIndex > len(lines) { - endIndex = len(lines) - } - highlightIndex := lineNumber - 1 - startIndex - return lines[startIndex:endIndex], highlightIndex -} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/progress_report_bsd.go b/vendor/github.com/onsi/ginkgo/v2/internal/progress_report_bsd.go deleted file mode 100644 index 61e0ed30..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/progress_report_bsd.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build freebsd || openbsd || netbsd || darwin || dragonfly -// +build freebsd openbsd netbsd darwin dragonfly - -package internal - -import ( - "os" - "syscall" -) - -var PROGRESS_SIGNALS = []os.Signal{syscall.SIGINFO, syscall.SIGUSR1} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/progress_report_unix.go b/vendor/github.com/onsi/ginkgo/v2/internal/progress_report_unix.go deleted file mode 100644 index ad30de45..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/progress_report_unix.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build linux || solaris -// +build linux solaris - -package internal - -import ( - "os" - "syscall" -) - -var PROGRESS_SIGNALS = []os.Signal{syscall.SIGUSR1} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/progress_report_win.go b/vendor/github.com/onsi/ginkgo/v2/internal/progress_report_win.go deleted file mode 100644 index 0eca2516..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/progress_report_win.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows -// +build windows - -package internal - -import "os" - -var PROGRESS_SIGNALS = []os.Signal{} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/report_entry.go b/vendor/github.com/onsi/ginkgo/v2/internal/report_entry.go index cc351a39..74199f39 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/report_entry.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/report_entry.go @@ -1,6 +1,7 @@ package internal import ( + "reflect" "time" "github.com/onsi/ginkgo/v2/types" @@ -12,20 +13,20 @@ func NewReportEntry(name string, cl types.CodeLocation, args ...interface{}) (Re out := ReportEntry{ Visibility: types.ReportEntryVisibilityAlways, Name: name, - Location: cl, Time: time.Now(), + Location: cl, } var didSetValue = false for _, arg := range args { - switch x := arg.(type) { - case types.ReportEntryVisibility: - out.Visibility = x - case types.CodeLocation: - out.Location = x - case Offset: - out.Location = types.NewCodeLocation(2 + int(x)) - case time.Time: - out.Time = x + switch reflect.TypeOf(arg) { + case reflect.TypeOf(types.ReportEntryVisibilityAlways): + out.Visibility = arg.(types.ReportEntryVisibility) + case reflect.TypeOf(types.CodeLocation{}): + out.Location = arg.(types.CodeLocation) + case reflect.TypeOf(Offset(0)): + out.Location = types.NewCodeLocation(2 + int(arg.(Offset))) + case reflect.TypeOf(out.Time): + out.Time = arg.(time.Time) default: if didSetValue { return ReportEntry{}, types.GinkgoErrors.TooManyReportEntryValues(out.Location, arg) diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/spec.go b/vendor/github.com/onsi/ginkgo/v2/internal/spec.go index 7c4ee5bb..92072edd 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/spec.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/spec.go @@ -2,7 +2,6 @@ package internal import ( "strings" - "time" "github.com/onsi/ginkgo/v2/types" ) @@ -41,21 +40,6 @@ func (s Spec) FlakeAttempts() int { return flakeAttempts } -func (s Spec) MustPassRepeatedly() int { - mustPassRepeatedly := 0 - for i := range s.Nodes { - if s.Nodes[i].MustPassRepeatedly > 0 { - mustPassRepeatedly = s.Nodes[i].MustPassRepeatedly - } - } - - return mustPassRepeatedly -} - -func (s Spec) SpecTimeout() time.Duration { - return s.FirstNodeWithType(types.NodeTypeIt).SpecTimeout -} - type Specs []Spec func (s Specs) HasAnySpecsMarkedPending() bool { diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/spec_context.go b/vendor/github.com/onsi/ginkgo/v2/internal/spec_context.go deleted file mode 100644 index 8f569dd3..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/spec_context.go +++ /dev/null @@ -1,90 +0,0 @@ -package internal - -import ( - "context" - "sort" - "sync" - - "github.com/onsi/ginkgo/v2/types" -) - -type SpecContext interface { - context.Context - - SpecReport() types.SpecReport - AttachProgressReporter(func() string) func() -} - -type specContext struct { - context.Context - - cancel context.CancelFunc - lock *sync.Mutex - progressReporters map[int]func() string - prCounter int - - suite *Suite -} - -/* -SpecContext includes a reference to `suite` and embeds itself in itself as a "GINKGO_SPEC_CONTEXT" value. This allows users to create child Contexts without having down-stream consumers (e.g. Gomega) lose access to the SpecContext and its methods. This allows us to build extensions on top of Ginkgo that simply take an all-encompassing context. - -Note that while SpecContext is used to enforce deadlines by Ginkgo it is not configured as a context.WithDeadline. Instead, Ginkgo owns responsibility for cancelling the context when the deadline elapses. - -This is because Ginkgo needs finer control over when the context is canceled. Specifically, Ginkgo needs to generate a ProgressReport before it cancels the context to ensure progress is captured where the spec is currently running. The only way to avoid a race here is to manually control the cancellation. -*/ -func NewSpecContext(suite *Suite) *specContext { - ctx, cancel := context.WithCancel(context.Background()) - sc := &specContext{ - cancel: cancel, - suite: suite, - lock: &sync.Mutex{}, - prCounter: 0, - progressReporters: map[int]func() string{}, - } - ctx = context.WithValue(ctx, "GINKGO_SPEC_CONTEXT", sc) //yes, yes, the go docs say don't use a string for a key... but we'd rather avoid a circular dependency between Gomega and Ginkgo - sc.Context = ctx //thank goodness for garbage collectors that can handle circular dependencies - - return sc -} - -func (sc *specContext) SpecReport() types.SpecReport { - return sc.suite.CurrentSpecReport() -} - -func (sc *specContext) AttachProgressReporter(reporter func() string) func() { - sc.lock.Lock() - defer sc.lock.Unlock() - sc.prCounter += 1 - prCounter := sc.prCounter - sc.progressReporters[prCounter] = reporter - - return func() { - sc.lock.Lock() - defer sc.lock.Unlock() - delete(sc.progressReporters, prCounter) - } -} - -func (sc *specContext) QueryProgressReporters() []string { - sc.lock.Lock() - keys := []int{} - for key := range sc.progressReporters { - keys = append(keys, key) - } - sort.Ints(keys) - reporters := []func() string{} - for _, key := range keys { - reporters = append(reporters, sc.progressReporters[key]) - } - sc.lock.Unlock() - - if len(reporters) == 0 { - return nil - } - out := []string{} - for _, reporter := range reporters { - out = append(out, reporter()) - } - return out -} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/suite.go b/vendor/github.com/onsi/ginkgo/v2/internal/suite.go index d3671ebc..a521ccbd 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/suite.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/suite.go @@ -2,9 +2,9 @@ package internal import ( "fmt" - "sync" "time" + "github.com/onsi/ginkgo/v2/formatter" "github.com/onsi/ginkgo/v2/internal/interrupt_handler" "github.com/onsi/ginkgo/v2/internal/parallel_support" "github.com/onsi/ginkgo/v2/reporters" @@ -34,30 +34,11 @@ type Suite struct { outputInterceptor OutputInterceptor interruptHandler interrupt_handler.InterruptHandlerInterface config types.SuiteConfig - deadline time.Time - skipAll bool - report types.Report - currentSpecReport types.SpecReport - currentNode Node - currentNodeStartTime time.Time - - currentSpecContext *specContext - - currentByStep types.SpecEvent - timelineOrder int - - /* - We don't need to lock around all operations. Just those that *could* happen concurrently. - - Suite, generally, only runs one node at a time - and so the possibiity for races is small. In fact, the presence of a race usually indicates the user has launched a goroutine that has leaked past the node it was launched in. - - However, there are some operations that can happen concurrently: - - - AddReportEntry and CurrentSpecReport can be accessed at any point by the user - including in goroutines that outlive the node intentionally (see, e.g. #1020). They both form a self-contained read-write pair and so a lock in them is sufficent. - - generateProgressReport can be invoked at any point in time by an interrupt or a progres poll. Moreover, it requires access to currentSpecReport, currentNode, currentNodeStartTime, and progressStepCursor. To make it threadsafe we need to lock around generateProgressReport when we read those variables _and_ everywhere those variables are *written*. In general we don't need to worry about all possible field writes to these variables as what `generateProgressReport` does with these variables is fairly selective (hence the name of the lock). Specifically, we dont' need to lock around state and failure message changes on `currentSpecReport` - just the setting of the variable itself. - */ - selectiveLock *sync.Mutex + skipAll bool + report types.Report + currentSpecReport types.SpecReport + currentNode Node client parallel_support.Client } @@ -66,8 +47,6 @@ func NewSuite() *Suite { return &Suite{ tree: &TreeNode{}, phase: PhaseBuildTopLevel, - - selectiveLock: &sync.Mutex{}, } } @@ -84,7 +63,7 @@ func (suite *Suite) BuildTree() error { return nil } -func (suite *Suite) Run(description string, suiteLabels Labels, suitePath string, failer *Failer, reporter reporters.Reporter, writer WriterInterface, outputInterceptor OutputInterceptor, interruptHandler interrupt_handler.InterruptHandlerInterface, client parallel_support.Client, progressSignalRegistrar ProgressSignalRegistrar, suiteConfig types.SuiteConfig) (bool, bool) { +func (suite *Suite) Run(description string, suiteLabels Labels, suitePath string, failer *Failer, reporter reporters.Reporter, writer WriterInterface, outputInterceptor OutputInterceptor, interruptHandler interrupt_handler.InterruptHandlerInterface, client parallel_support.Client, suiteConfig types.SuiteConfig) (bool, bool) { if suite.phase != PhaseBuildTree { panic("cannot run before building the tree = call suite.BuildTree() first") } @@ -101,16 +80,8 @@ func (suite *Suite) Run(description string, suiteLabels Labels, suitePath string suite.interruptHandler = interruptHandler suite.config = suiteConfig - if suite.config.Timeout > 0 { - suite.deadline = time.Now().Add(suite.config.Timeout) - } - - cancelProgressHandler := progressSignalRegistrar(suite.handleProgressSignal) - success := suite.runSpecs(description, suiteLabels, suitePath, hasProgrammaticFocus, specs) - cancelProgressHandler() - return success, hasProgrammaticFocus } @@ -172,7 +143,7 @@ func (suite *Suite) PushNode(node Node) error { err = types.GinkgoErrors.CaughtPanicDuringABuildPhase(e, node.CodeLocation) } }() - node.Body(nil) + node.Body() return err }() suite.tree = parentTree @@ -237,79 +208,14 @@ func (suite *Suite) pushCleanupNode(node Node) error { return nil } -func (suite *Suite) generateTimelineLocation() types.TimelineLocation { - suite.selectiveLock.Lock() - defer suite.selectiveLock.Unlock() - - suite.timelineOrder += 1 - return types.TimelineLocation{ - Offset: len(suite.currentSpecReport.CapturedGinkgoWriterOutput) + suite.writer.Len(), - Order: suite.timelineOrder, - Time: time.Now(), - } -} - -func (suite *Suite) handleSpecEvent(event types.SpecEvent) types.SpecEvent { - event.TimelineLocation = suite.generateTimelineLocation() - suite.selectiveLock.Lock() - suite.currentSpecReport.SpecEvents = append(suite.currentSpecReport.SpecEvents, event) - suite.selectiveLock.Unlock() - suite.reporter.EmitSpecEvent(event) - return event -} - -func (suite *Suite) handleSpecEventEnd(eventType types.SpecEventType, startEvent types.SpecEvent) { - event := startEvent - event.SpecEventType = eventType - event.TimelineLocation = suite.generateTimelineLocation() - event.Duration = event.TimelineLocation.Time.Sub(startEvent.TimelineLocation.Time) - suite.selectiveLock.Lock() - suite.currentSpecReport.SpecEvents = append(suite.currentSpecReport.SpecEvents, event) - suite.selectiveLock.Unlock() - suite.reporter.EmitSpecEvent(event) -} - -func (suite *Suite) By(text string, callback ...func()) error { - cl := types.NewCodeLocation(2) - if suite.phase != PhaseRun { - return types.GinkgoErrors.ByNotDuringRunPhase(cl) - } - - event := suite.handleSpecEvent(types.SpecEvent{ - SpecEventType: types.SpecEventByStart, - CodeLocation: cl, - Message: text, - }) - suite.selectiveLock.Lock() - suite.currentByStep = event - suite.selectiveLock.Unlock() - - if len(callback) == 1 { - defer func() { - suite.selectiveLock.Lock() - suite.currentByStep = types.SpecEvent{} - suite.selectiveLock.Unlock() - suite.handleSpecEventEnd(types.SpecEventByEnd, event) - }() - callback[0]() - } else if len(callback) > 1 { - panic("just one callback per By, please") - } - return nil -} - /* -Spec Running methods - used during PhaseRun + Spec Running methods - used during PhaseRun */ func (suite *Suite) CurrentSpecReport() types.SpecReport { - suite.selectiveLock.Lock() - defer suite.selectiveLock.Unlock() report := suite.currentSpecReport if suite.writer != nil { report.CapturedGinkgoWriterOutput = string(suite.writer.Bytes()) } - report.ReportEntries = make([]ReportEntry, len(report.ReportEntries)) - copy(report.ReportEntries, suite.currentSpecReport.ReportEntries) return report } @@ -317,53 +223,10 @@ func (suite *Suite) AddReportEntry(entry ReportEntry) error { if suite.phase != PhaseRun { return types.GinkgoErrors.AddReportEntryNotDuringRunPhase(entry.Location) } - entry.TimelineLocation = suite.generateTimelineLocation() - entry.Time = entry.TimelineLocation.Time - suite.selectiveLock.Lock() suite.currentSpecReport.ReportEntries = append(suite.currentSpecReport.ReportEntries, entry) - suite.selectiveLock.Unlock() - suite.reporter.EmitReportEntry(entry) return nil } -func (suite *Suite) generateProgressReport(fullReport bool) types.ProgressReport { - timelineLocation := suite.generateTimelineLocation() - suite.selectiveLock.Lock() - defer suite.selectiveLock.Unlock() - - var additionalReports []string - if suite.currentSpecContext != nil { - additionalReports = suite.currentSpecContext.QueryProgressReporters() - } - gwOutput := suite.currentSpecReport.CapturedGinkgoWriterOutput + string(suite.writer.Bytes()) - pr, err := NewProgressReport(suite.isRunningInParallel(), suite.currentSpecReport, suite.currentNode, suite.currentNodeStartTime, suite.currentByStep, gwOutput, timelineLocation, additionalReports, suite.config.SourceRoots, fullReport) - - if err != nil { - fmt.Printf("{{red}}Failed to generate progress report:{{/}}\n%s\n", err.Error()) - } - return pr -} - -func (suite *Suite) handleProgressSignal() { - report := suite.generateProgressReport(false) - report.Message = "{{bold}}You've requested a progress report:{{/}}" - suite.emitProgressReport(report) -} - -func (suite *Suite) emitProgressReport(report types.ProgressReport) { - suite.selectiveLock.Lock() - suite.currentSpecReport.ProgressReports = append(suite.currentSpecReport.ProgressReports, report.WithoutCapturedGinkgoWriterOutput()) - suite.selectiveLock.Unlock() - - suite.reporter.EmitProgressReport(report) - if suite.isRunningInParallel() { - err := suite.client.PostEmitProgressReport(report) - if err != nil { - fmt.Println(err.Error()) - } - } -} - func (suite *Suite) isRunningInParallel() bool { return suite.config.ParallelTotal > 1 } @@ -450,16 +313,12 @@ func (suite *Suite) runSpecs(description string, suiteLabels Labels, suitePath s suite.runAfterSuiteCleanup(numSpecsThatWillBeRun) interruptStatus := suite.interruptHandler.Status() - if interruptStatus.Interrupted() { + if interruptStatus.Interrupted { suite.report.SpecialSuiteFailureReasons = append(suite.report.SpecialSuiteFailureReasons, interruptStatus.Cause.String()) suite.report.SuiteSucceeded = false } suite.report.EndTime = time.Now() suite.report.RunTime = suite.report.EndTime.Sub(suite.report.StartTime) - if !suite.deadline.IsZero() && suite.report.EndTime.After(suite.deadline) { - suite.report.SpecialSuiteFailureReasons = append(suite.report.SpecialSuiteFailureReasons, "Suite Timeout Elapsed") - suite.report.SuiteSucceeded = false - } if suite.config.ParallelProcess == 1 { suite.runReportAfterSuite() @@ -473,19 +332,16 @@ func (suite *Suite) runSpecs(description string, suiteLabels Labels, suitePath s } func (suite *Suite) runBeforeSuite(numSpecsThatWillBeRun int) { + interruptStatus := suite.interruptHandler.Status() beforeSuiteNode := suite.suiteNodes.FirstNodeWithType(types.NodeTypeBeforeSuite | types.NodeTypeSynchronizedBeforeSuite) - if !beforeSuiteNode.IsZero() && numSpecsThatWillBeRun > 0 { - suite.selectiveLock.Lock() + if !beforeSuiteNode.IsZero() && !interruptStatus.Interrupted && numSpecsThatWillBeRun > 0 { suite.currentSpecReport = types.SpecReport{ - LeafNodeType: beforeSuiteNode.NodeType, - LeafNodeLocation: beforeSuiteNode.CodeLocation, - ParallelProcess: suite.config.ParallelProcess, - RunningInParallel: suite.isRunningInParallel(), + LeafNodeType: beforeSuiteNode.NodeType, + LeafNodeLocation: beforeSuiteNode.CodeLocation, + ParallelProcess: suite.config.ParallelProcess, } - suite.selectiveLock.Unlock() - suite.reporter.WillRun(suite.currentSpecReport) - suite.runSuiteNode(beforeSuiteNode) + suite.runSuiteNode(beforeSuiteNode, interruptStatus.Channel) if suite.currentSpecReport.State.Is(types.SpecStateSkipped) { suite.report.SpecialSuiteFailureReasons = append(suite.report.SpecialSuiteFailureReasons, "Suite skipped in BeforeSuite") suite.skipAll = true @@ -497,34 +353,26 @@ func (suite *Suite) runBeforeSuite(numSpecsThatWillBeRun int) { func (suite *Suite) runAfterSuiteCleanup(numSpecsThatWillBeRun int) { afterSuiteNode := suite.suiteNodes.FirstNodeWithType(types.NodeTypeAfterSuite | types.NodeTypeSynchronizedAfterSuite) if !afterSuiteNode.IsZero() && numSpecsThatWillBeRun > 0 { - suite.selectiveLock.Lock() suite.currentSpecReport = types.SpecReport{ - LeafNodeType: afterSuiteNode.NodeType, - LeafNodeLocation: afterSuiteNode.CodeLocation, - ParallelProcess: suite.config.ParallelProcess, - RunningInParallel: suite.isRunningInParallel(), + LeafNodeType: afterSuiteNode.NodeType, + LeafNodeLocation: afterSuiteNode.CodeLocation, + ParallelProcess: suite.config.ParallelProcess, } - suite.selectiveLock.Unlock() - suite.reporter.WillRun(suite.currentSpecReport) - suite.runSuiteNode(afterSuiteNode) + suite.runSuiteNode(afterSuiteNode, suite.interruptHandler.Status().Channel) suite.processCurrentSpecReport() } afterSuiteCleanup := suite.cleanupNodes.WithType(types.NodeTypeCleanupAfterSuite).Reverse() if len(afterSuiteCleanup) > 0 { for _, cleanupNode := range afterSuiteCleanup { - suite.selectiveLock.Lock() suite.currentSpecReport = types.SpecReport{ - LeafNodeType: cleanupNode.NodeType, - LeafNodeLocation: cleanupNode.CodeLocation, - ParallelProcess: suite.config.ParallelProcess, - RunningInParallel: suite.isRunningInParallel(), + LeafNodeType: cleanupNode.NodeType, + LeafNodeLocation: cleanupNode.CodeLocation, + ParallelProcess: suite.config.ParallelProcess, } - suite.selectiveLock.Unlock() - suite.reporter.WillRun(suite.currentSpecReport) - suite.runSuiteNode(cleanupNode) + suite.runSuiteNode(cleanupNode, suite.interruptHandler.Status().Channel) suite.processCurrentSpecReport() } } @@ -532,16 +380,12 @@ func (suite *Suite) runAfterSuiteCleanup(numSpecsThatWillBeRun int) { func (suite *Suite) runReportAfterSuite() { for _, node := range suite.suiteNodes.WithType(types.NodeTypeReportAfterSuite) { - suite.selectiveLock.Lock() suite.currentSpecReport = types.SpecReport{ - LeafNodeType: node.NodeType, - LeafNodeLocation: node.CodeLocation, - LeafNodeText: node.Text, - ParallelProcess: suite.config.ParallelProcess, - RunningInParallel: suite.isRunningInParallel(), + LeafNodeType: node.NodeType, + LeafNodeLocation: node.CodeLocation, + LeafNodeText: node.Text, + ParallelProcess: suite.config.ParallelProcess, } - suite.selectiveLock.Unlock() - suite.reporter.WillRun(suite.currentSpecReport) suite.runReportAfterSuiteNode(node, suite.report) suite.processCurrentSpecReport() @@ -564,11 +408,16 @@ func (suite *Suite) reportEach(spec Spec, nodeType types.NodeType) { suite.writer.Truncate() suite.outputInterceptor.StartInterceptingOutput() report := suite.currentSpecReport - nodes[i].Body = func(SpecContext) { + nodes[i].Body = func() { nodes[i].ReportEachBody(report) } - state, failure := suite.runNode(nodes[i], time.Time{}, spec.Nodes.BestTextFor(nodes[i])) - + suite.interruptHandler.SetInterruptPlaceholderMessage(formatter.Fiw(0, formatter.COLS, + "{{yellow}}Ginkgo received an interrupt signal but is currently running a %s node. To avoid an invalid report the %s node will not be interrupted however subsequent tests will be skipped.{{/}}\n\n{{bold}}The running %s node is at:\n%s.{{/}}", + nodeType, nodeType, nodeType, + nodes[i].CodeLocation, + )) + state, failure := suite.runNode(nodes[i], nil, spec.Nodes.BestTextFor(nodes[i])) + suite.interruptHandler.ClearInterruptPlaceholderMessage() // If the spec is not in a failure state (i.e. it's Passed/Skipped/Pending) and the reporter has failed, override the state. // Also, if the reporter is every aborted - always override the state to propagate the abort if (!suite.currentSpecReport.State.Is(types.SpecStateFailureStates) && state.Is(types.SpecStateFailureStates)) || state.Is(types.SpecStateAborted) { @@ -580,7 +429,7 @@ func (suite *Suite) reportEach(spec Spec, nodeType types.NodeType) { } } -func (suite *Suite) runSuiteNode(node Node) { +func (suite *Suite) runSuiteNode(node Node, interruptChannel chan interface{}) { if suite.config.DryRun { suite.currentSpecReport.State = types.SpecStatePassed return @@ -593,13 +442,13 @@ func (suite *Suite) runSuiteNode(node Node) { var err error switch node.NodeType { case types.NodeTypeBeforeSuite, types.NodeTypeAfterSuite: - suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "") + suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, interruptChannel, "") case types.NodeTypeCleanupAfterSuite: if suite.config.ParallelTotal > 1 && suite.config.ParallelProcess == 1 { err = suite.client.BlockUntilNonprimaryProcsHaveFinished() } if err == nil { - suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "") + suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, interruptChannel, "") } case types.NodeTypeSynchronizedBeforeSuite: var data []byte @@ -609,9 +458,8 @@ func (suite *Suite) runSuiteNode(node Node) { suite.outputInterceptor.StopInterceptingAndReturnOutput() suite.outputInterceptor.StartInterceptingOutputAndForwardTo(suite.client) } - node.Body = func(c SpecContext) { data = node.SynchronizedBeforeSuiteProc1Body(c) } - node.HasContext = node.SynchronizedBeforeSuiteProc1BodyHasContext - suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "") + node.Body = func() { data = node.SynchronizedBeforeSuiteProc1Body() } + suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, interruptChannel, "") if suite.config.ParallelTotal > 1 { suite.currentSpecReport.CapturedStdOutErr += suite.outputInterceptor.StopInterceptingAndReturnOutput() suite.outputInterceptor.StartInterceptingOutput() @@ -628,21 +476,19 @@ func (suite *Suite) runSuiteNode(node Node) { switch proc1State { case types.SpecStatePassed: runAllProcs = true - case types.SpecStateFailed, types.SpecStatePanicked, types.SpecStateTimedout: + case types.SpecStateFailed, types.SpecStatePanicked: err = types.GinkgoErrors.SynchronizedBeforeSuiteFailedOnProc1() case types.SpecStateInterrupted, types.SpecStateAborted, types.SpecStateSkipped: suite.currentSpecReport.State = proc1State } } if runAllProcs { - node.Body = func(c SpecContext) { node.SynchronizedBeforeSuiteAllProcsBody(c, data) } - node.HasContext = node.SynchronizedBeforeSuiteAllProcsBodyHasContext - suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "") + node.Body = func() { node.SynchronizedBeforeSuiteAllProcsBody(data) } + suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, interruptChannel, "") } case types.NodeTypeSynchronizedAfterSuite: node.Body = node.SynchronizedAfterSuiteAllProcsBody - node.HasContext = node.SynchronizedAfterSuiteAllProcsBodyHasContext - suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "") + suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, interruptChannel, "") if suite.config.ParallelProcess == 1 { if suite.config.ParallelTotal > 1 { err = suite.client.BlockUntilNonprimaryProcsHaveFinished() @@ -654,8 +500,7 @@ func (suite *Suite) runSuiteNode(node Node) { } node.Body = node.SynchronizedAfterSuiteProc1Body - node.HasContext = node.SynchronizedAfterSuiteProc1BodyHasContext - state, failure := suite.runNode(node, time.Time{}, "") + state, failure := suite.runNode(node, interruptChannel, "") if suite.currentSpecReport.State.Is(types.SpecStatePassed) { suite.currentSpecReport.State, suite.currentSpecReport.Failure = state, failure } @@ -665,7 +510,6 @@ func (suite *Suite) runSuiteNode(node Node) { if err != nil && !suite.currentSpecReport.State.Is(types.SpecStateFailureStates) { suite.currentSpecReport.State, suite.currentSpecReport.Failure = types.SpecStateFailed, suite.failureForLeafNodeWithMessage(node, err.Error()) - suite.reporter.EmitFailure(suite.currentSpecReport.State, suite.currentSpecReport.Failure) } suite.currentSpecReport.EndTime = time.Now() @@ -685,14 +529,18 @@ func (suite *Suite) runReportAfterSuiteNode(node Node, report types.Report) { aggregatedReport, err := suite.client.BlockUntilAggregatedNonprimaryProcsReport() if err != nil { suite.currentSpecReport.State, suite.currentSpecReport.Failure = types.SpecStateFailed, suite.failureForLeafNodeWithMessage(node, err.Error()) - suite.reporter.EmitFailure(suite.currentSpecReport.State, suite.currentSpecReport.Failure) return } report = report.Add(aggregatedReport) } - node.Body = func(SpecContext) { node.ReportAfterSuiteBody(report) } - suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "") + node.Body = func() { node.ReportAfterSuiteBody(report) } + suite.interruptHandler.SetInterruptPlaceholderMessage(formatter.Fiw(0, formatter.COLS, + "{{yellow}}Ginkgo received an interrupt signal but is currently running a ReportAfterSuite node. To avoid an invalid report the ReportAfterSuite node will not be interrupted.{{/}}\n\n{{bold}}The running ReportAfterSuite node is at:\n%s.{{/}}", + node.CodeLocation, + )) + suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, nil, "") + suite.interruptHandler.ClearInterruptPlaceholderMessage() suite.currentSpecReport.EndTime = time.Now() suite.currentSpecReport.RunTime = suite.currentSpecReport.EndTime.Sub(suite.currentSpecReport.StartTime) @@ -702,46 +550,23 @@ func (suite *Suite) runReportAfterSuiteNode(node Node, report types.Report) { return } -func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (types.SpecState, types.Failure) { +func (suite *Suite) runNode(node Node, interruptChannel chan interface{}, text string) (types.SpecState, types.Failure) { if node.NodeType.Is(types.NodeTypeCleanupAfterEach | types.NodeTypeCleanupAfterAll | types.NodeTypeCleanupAfterSuite) { suite.cleanupNodes = suite.cleanupNodes.WithoutNode(node) } - interruptStatus := suite.interruptHandler.Status() - if interruptStatus.Level == interrupt_handler.InterruptLevelBailOut { - return types.SpecStateSkipped, types.Failure{} - } - if interruptStatus.Level == interrupt_handler.InterruptLevelReportOnly && !node.NodeType.Is(types.NodeTypesAllowedDuringReportInterrupt) { - return types.SpecStateSkipped, types.Failure{} - } - if interruptStatus.Level == interrupt_handler.InterruptLevelCleanupAndReport && !node.NodeType.Is(types.NodeTypesAllowedDuringReportInterrupt|types.NodeTypesAllowedDuringCleanupInterrupt) { - return types.SpecStateSkipped, types.Failure{} - } - - suite.selectiveLock.Lock() suite.currentNode = node - suite.currentNodeStartTime = time.Now() - suite.currentByStep = types.SpecEvent{} - suite.selectiveLock.Unlock() defer func() { - suite.selectiveLock.Lock() suite.currentNode = Node{} - suite.currentNodeStartTime = time.Time{} - suite.selectiveLock.Unlock() }() - if text == "" { - text = "TOP-LEVEL" + if suite.config.EmitSpecProgress { + if text == "" { + text = "TOP-LEVEL" + } + s := fmt.Sprintf("[%s] %s\n %s\n", node.NodeType.String(), text, node.CodeLocation.String()) + suite.writer.Write([]byte(s)) } - event := suite.handleSpecEvent(types.SpecEvent{ - SpecEventType: types.SpecEventNodeStart, - NodeType: node.NodeType, - Message: text, - CodeLocation: node.CodeLocation, - }) - defer func() { - suite.handleSpecEventEnd(types.SpecEventNodeEnd, event) - }() var failure types.Failure failure.FailureNodeType, failure.FailureNodeLocation = node.NodeType, node.CodeLocation @@ -752,54 +577,6 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ } else { failure.FailureNodeContext, failure.FailureNodeContainerIndex = types.FailureNodeInContainer, node.NestingLevel-1 } - var outcome types.SpecState - - gracePeriod := suite.config.GracePeriod - if node.GracePeriod >= 0 { - gracePeriod = node.GracePeriod - } - - now := time.Now() - deadline := suite.deadline - timeoutInPlay := "suite" - if deadline.IsZero() || (!specDeadline.IsZero() && specDeadline.Before(deadline)) { - deadline = specDeadline - timeoutInPlay = "spec" - } - if node.NodeTimeout > 0 && (deadline.IsZero() || deadline.Sub(now) > node.NodeTimeout) { - deadline = now.Add(node.NodeTimeout) - timeoutInPlay = "node" - } - if (!deadline.IsZero() && deadline.Before(now)) || interruptStatus.Interrupted() { - //we're out of time already. let's wait for a NodeTimeout if we have it, or GracePeriod if we don't - if node.NodeTimeout > 0 { - deadline = now.Add(node.NodeTimeout) - timeoutInPlay = "node" - } else { - deadline = now.Add(gracePeriod) - timeoutInPlay = "grace period" - } - } - - if !node.HasContext { - // this maps onto the pre-context behavior: - // - an interrupted node exits immediately. with this, context-less nodes that are in a spec with a SpecTimeout and/or are interrupted by other means will simply exit immediately after the timeout/interrupt - // - clean up nodes have up to GracePeriod (formerly hard-coded at 30s) to complete before they are interrupted - gracePeriod = 0 - } - - sc := NewSpecContext(suite) - defer sc.cancel() - - suite.selectiveLock.Lock() - suite.currentSpecContext = sc - suite.selectiveLock.Unlock() - - var deadlineChannel <-chan time.Time - if !deadline.IsZero() { - deadlineChannel = time.After(deadline.Sub(now)) - } - var gracePeriodChannel <-chan time.Time outcomeC := make(chan types.SpecState) failureC := make(chan types.Failure) @@ -811,147 +588,33 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ suite.failer.Panic(types.NewCodeLocationWithStackTrace(2), e) } - outcomeFromRun, failureFromRun := suite.failer.Drain() - failureFromRun.TimelineLocation = suite.generateTimelineLocation() - outcomeC <- outcomeFromRun + outcome, failureFromRun := suite.failer.Drain() + outcomeC <- outcome failureC <- failureFromRun }() - node.Body(sc) + node.Body() finished = true }() - // progress polling timer and channel - var emitProgressNow <-chan time.Time - var progressPoller *time.Timer - var pollProgressAfter, pollProgressInterval = suite.config.PollProgressAfter, suite.config.PollProgressInterval - if node.PollProgressAfter >= 0 { - pollProgressAfter = node.PollProgressAfter - } - if node.PollProgressInterval >= 0 { - pollProgressInterval = node.PollProgressInterval - } - if pollProgressAfter > 0 { - progressPoller = time.NewTimer(pollProgressAfter) - emitProgressNow = progressPoller.C - defer progressPoller.Stop() - } - - // now we wait for an outcome, an interrupt, a timeout, or a progress poll - for { - select { - case outcomeFromRun := <-outcomeC: - failureFromRun := <-failureC - if outcome.Is(types.SpecStateInterrupted | types.SpecStateTimedout) { - // we've already been interrupted/timed out. we just managed to actually exit - // before the grace period elapsed - // if we have a failure message we attach it as an additional failure - if outcomeFromRun != types.SpecStatePassed { - additionalFailure := types.AdditionalFailure{ - State: outcomeFromRun, - Failure: failure, //we make a copy - this will include all the configuration set up above... - } - //...and then we update the failure with the details from failureFromRun - additionalFailure.Failure.Location, additionalFailure.Failure.ForwardedPanic, additionalFailure.Failure.TimelineLocation = failureFromRun.Location, failureFromRun.ForwardedPanic, failureFromRun.TimelineLocation - additionalFailure.Failure.ProgressReport = types.ProgressReport{} - if outcome == types.SpecStateTimedout { - additionalFailure.Failure.Message = fmt.Sprintf("A %s timeout occurred and then the following failure was recorded in the timedout node before it exited:\n%s", timeoutInPlay, failureFromRun.Message) - } else { - additionalFailure.Failure.Message = fmt.Sprintf("An interrupt occurred and then the following failure was recorded in the interrupted node before it exited:\n%s", failureFromRun.Message) - } - suite.reporter.EmitFailure(additionalFailure.State, additionalFailure.Failure) - failure.AdditionalFailure = &additionalFailure - } - return outcome, failure - } - if outcomeFromRun.Is(types.SpecStatePassed) { - return outcomeFromRun, types.Failure{} - } else { - failure.Message, failure.Location, failure.ForwardedPanic, failure.TimelineLocation = failureFromRun.Message, failureFromRun.Location, failureFromRun.ForwardedPanic, failureFromRun.TimelineLocation - suite.reporter.EmitFailure(outcomeFromRun, failure) - return outcomeFromRun, failure - } - case <-gracePeriodChannel: - if node.HasContext && outcome.Is(types.SpecStateTimedout) { - report := suite.generateProgressReport(false) - report.Message = "{{bold}}{{orange}}A running node failed to exit in time{{/}}\nGinkgo is moving on but a node has timed out and failed to exit before its grace period elapsed. The node has now leaked and is running in the background.\nHere's a current progress report:" - suite.emitProgressReport(report) - } - return outcome, failure - case <-deadlineChannel: - // we're out of time - the outcome is a timeout and we capture the failure and progress report - outcome = types.SpecStateTimedout - failure.Message, failure.Location, failure.TimelineLocation = fmt.Sprintf("A %s timeout occurred", timeoutInPlay), node.CodeLocation, suite.generateTimelineLocation() - failure.ProgressReport = suite.generateProgressReport(false).WithoutCapturedGinkgoWriterOutput() - failure.ProgressReport.Message = fmt.Sprintf("{{bold}}This is the Progress Report generated when the %s timeout occurred:{{/}}", timeoutInPlay) - deadlineChannel = nil - suite.reporter.EmitFailure(outcome, failure) - - // tell the spec to stop. it's important we generate the progress report first to make sure we capture where - // the spec is actually stuck - sc.cancel() - //and now we wait for the grace period - gracePeriodChannel = time.After(gracePeriod) - case <-interruptStatus.Channel: - interruptStatus = suite.interruptHandler.Status() - deadlineChannel = nil // don't worry about deadlines, time's up now - - failureTimelineLocation := suite.generateTimelineLocation() - progressReport := suite.generateProgressReport(true) - - if outcome == types.SpecStateInvalid { - outcome = types.SpecStateInterrupted - failure.Message, failure.Location, failure.TimelineLocation = interruptStatus.Message(), node.CodeLocation, failureTimelineLocation - if interruptStatus.ShouldIncludeProgressReport() { - failure.ProgressReport = progressReport.WithoutCapturedGinkgoWriterOutput() - failure.ProgressReport.Message = "{{bold}}This is the Progress Report generated when the interrupt was received:{{/}}" - } - suite.reporter.EmitFailure(outcome, failure) - } - - progressReport = progressReport.WithoutOtherGoroutines() - sc.cancel() - - if interruptStatus.Level == interrupt_handler.InterruptLevelBailOut { - if interruptStatus.ShouldIncludeProgressReport() { - progressReport.Message = fmt.Sprintf("{{bold}}{{orange}}%s{{/}}\n{{bold}}{{red}}Final interrupt received{{/}}; Ginkgo will not run any cleanup or reporting nodes and will terminate as soon as possible.\nHere's a current progress report:", interruptStatus.Message()) - suite.emitProgressReport(progressReport) - } - return outcome, failure - } - if interruptStatus.ShouldIncludeProgressReport() { - if interruptStatus.Level == interrupt_handler.InterruptLevelCleanupAndReport { - progressReport.Message = fmt.Sprintf("{{bold}}{{orange}}%s{{/}}\nFirst interrupt received; Ginkgo will run any cleanup and reporting nodes but will skip all remaining specs. {{bold}}Interrupt again to skip cleanup{{/}}.\nHere's a current progress report:", interruptStatus.Message()) - } else if interruptStatus.Level == interrupt_handler.InterruptLevelReportOnly { - progressReport.Message = fmt.Sprintf("{{bold}}{{orange}}%s{{/}}\nSecond interrupt received; Ginkgo will run any reporting nodes but will skip all remaining specs and cleanup nodes. {{bold}}Interrupt again to bail immediately{{/}}.\nHere's a current progress report:", interruptStatus.Message()) - } - suite.emitProgressReport(progressReport) - } - - if gracePeriodChannel == nil { - // we haven't given grace yet... so let's - gracePeriodChannel = time.After(gracePeriod) - } else { - // we've already given grace. time's up. now. - return outcome, failure - } - case <-emitProgressNow: - report := suite.generateProgressReport(false) - report.Message = "{{bold}}Automatically polling progress:{{/}}" - suite.emitProgressReport(report) - if pollProgressInterval > 0 { - progressPoller.Reset(pollProgressInterval) - } + select { + case outcome := <-outcomeC: + failureFromRun := <-failureC + if outcome == types.SpecStatePassed { + return outcome, types.Failure{} } + failure.Message, failure.Location, failure.ForwardedPanic = failureFromRun.Message, failureFromRun.Location, failureFromRun.ForwardedPanic + return outcome, failure + case <-interruptChannel: + failure.Message, failure.Location = suite.interruptHandler.InterruptMessageWithStackTraces(), node.CodeLocation + return types.SpecStateInterrupted, failure } } -// TODO: search for usages and consider if reporter.EmitFailure() is necessary func (suite *Suite) failureForLeafNodeWithMessage(node Node, message string) types.Failure { return types.Failure{ Message: message, Location: node.CodeLocation, - TimelineLocation: suite.generateTimelineLocation(), FailureNodeContext: types.FailureNodeIsLeafNode, FailureNodeType: node.NodeType, FailureNodeLocation: node.CodeLocation, diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/writer.go b/vendor/github.com/onsi/ginkgo/v2/internal/writer.go index 28a45b0f..70f0a41f 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/writer.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/writer.go @@ -5,9 +5,6 @@ import ( "fmt" "io" "sync" - - "github.com/go-logr/logr" - "github.com/go-logr/logr/funcr" ) type WriterMode uint @@ -22,30 +19,24 @@ type WriterInterface interface { Truncate() Bytes() []byte - Len() int } -// Writer implements WriterInterface and GinkgoWriterInterface +//Writer implements WriterInterface and GinkgoWriterInterface type Writer struct { buffer *bytes.Buffer outWriter io.Writer lock *sync.Mutex mode WriterMode - streamIndent []byte - indentNext bool - teeWriters []io.Writer } func NewWriter(outWriter io.Writer) *Writer { return &Writer{ - buffer: &bytes.Buffer{}, - lock: &sync.Mutex{}, - outWriter: outWriter, - mode: WriterModeStreamAndBuffer, - streamIndent: []byte(" "), - indentNext: true, + buffer: &bytes.Buffer{}, + lock: &sync.Mutex{}, + outWriter: outWriter, + mode: WriterModeStreamAndBuffer, } } @@ -55,14 +46,6 @@ func (w *Writer) SetMode(mode WriterMode) { w.mode = mode } -func (w *Writer) Len() int { - w.lock.Lock() - defer w.lock.Unlock() - return w.buffer.Len() -} - -var newline = []byte("\n") - func (w *Writer) Write(b []byte) (n int, err error) { w.lock.Lock() defer w.lock.Unlock() @@ -72,21 +55,7 @@ func (w *Writer) Write(b []byte) (n int, err error) { } if w.mode == WriterModeStreamAndBuffer { - line, remaining, found := []byte{}, b, false - for len(remaining) > 0 { - line, remaining, found = bytes.Cut(remaining, newline) - if len(line) > 0 { - if w.indentNext { - w.outWriter.Write(w.streamIndent) - w.indentNext = false - } - w.outWriter.Write(line) - } - if found { - w.outWriter.Write(newline) - w.indentNext = true - } - } + w.outWriter.Write(b) } return w.buffer.Write(b) } @@ -106,7 +75,7 @@ func (w *Writer) Bytes() []byte { return copied } -// GinkgoWriterInterface +//GinkgoWriterInterface func (w *Writer) TeeTo(writer io.Writer) { w.lock.Lock() defer w.lock.Unlock() @@ -132,9 +101,3 @@ func (w *Writer) Printf(format string, a ...interface{}) { func (w *Writer) Println(a ...interface{}) { fmt.Fprintln(w, a...) } - -func GinkgoLogrFunc(writer *Writer) logr.Logger { - return funcr.New(func(prefix, args string) { - writer.Printf("%s", args) - }, funcr.Options{}) -} diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go index 7a27220c..f39802ff 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go @@ -12,7 +12,6 @@ import ( "io" "runtime" "strings" - "time" "github.com/onsi/ginkgo/v2/formatter" "github.com/onsi/ginkgo/v2/types" @@ -30,8 +29,6 @@ type DefaultReporter struct { specDenoter string retryDenoter string formatter formatter.Formatter - - runningInParallel bool } func NewDefaultReporterUnderTest(conf types.ReporterConfig, writer io.Writer) *DefaultReporter { @@ -99,521 +96,217 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) { } } -func (r *DefaultReporter) SuiteDidEnd(report types.Report) { - failures := report.SpecReports.WithState(types.SpecStateFailureStates) - if len(failures) > 0 { - r.emitBlock("\n") - if len(failures) > 1 { - r.emitBlock(r.f("{{red}}{{bold}}Summarizing %d Failures:{{/}}", len(failures))) - } else { - r.emitBlock(r.f("{{red}}{{bold}}Summarizing 1 Failure:{{/}}")) - } - for _, specReport := range failures { - highlightColor, heading := "{{red}}", "[FAIL]" - switch specReport.State { - case types.SpecStatePanicked: - highlightColor, heading = "{{magenta}}", "[PANICKED!]" - case types.SpecStateAborted: - highlightColor, heading = "{{coral}}", "[ABORTED]" - case types.SpecStateTimedout: - highlightColor, heading = "{{orange}}", "[TIMEDOUT]" - case types.SpecStateInterrupted: - highlightColor, heading = "{{orange}}", "[INTERRUPTED]" - } - locationBlock := r.codeLocationBlock(specReport, highlightColor, false, true) - r.emitBlock(r.fi(1, highlightColor+"%s{{/}} %s", heading, locationBlock)) - } - } - - //summarize the suite - if r.conf.Verbosity().Is(types.VerbosityLevelSuccinct) && report.SuiteSucceeded { - r.emit(r.f(" {{green}}SUCCESS!{{/}} %s ", report.RunTime)) +func (r *DefaultReporter) WillRun(report types.SpecReport) { + if r.conf.Verbosity().LT(types.VerbosityLevelVerbose) || report.State.Is(types.SpecStatePending|types.SpecStateSkipped) { return } - r.emitBlock("\n") - color, status := "{{green}}{{bold}}", "SUCCESS!" - if !report.SuiteSucceeded { - color, status = "{{red}}{{bold}}", "FAIL!" - } - - specs := report.SpecReports.WithLeafNodeType(types.NodeTypeIt) //exclude any suite setup nodes - r.emitBlock(r.f(color+"Ran %d of %d Specs in %.3f seconds{{/}}", - specs.CountWithState(types.SpecStatePassed)+specs.CountWithState(types.SpecStateFailureStates), - report.PreRunStats.TotalSpecs, - report.RunTime.Seconds()), - ) - - switch len(report.SpecialSuiteFailureReasons) { - case 0: - r.emit(r.f(color+"%s{{/}} -- ", status)) - case 1: - r.emit(r.f(color+"%s - %s{{/}} -- ", status, report.SpecialSuiteFailureReasons[0])) - default: - r.emitBlock(r.f(color+"%s - %s{{/}}\n", status, strings.Join(report.SpecialSuiteFailureReasons, ", "))) - } - - if len(specs) == 0 && report.SpecReports.WithLeafNodeType(types.NodeTypeBeforeSuite|types.NodeTypeSynchronizedBeforeSuite).CountWithState(types.SpecStateFailureStates) > 0 { - r.emit(r.f("{{cyan}}{{bold}}A BeforeSuite node failed so all tests were skipped.{{/}}\n")) + r.emitDelimiter() + indentation := uint(0) + if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { + r.emitBlock(r.f("{{bold}}[%s] %s{{/}}", report.LeafNodeType.String(), report.LeafNodeText)) } else { - r.emit(r.f("{{green}}{{bold}}%d Passed{{/}} | ", specs.CountWithState(types.SpecStatePassed))) - r.emit(r.f("{{red}}{{bold}}%d Failed{{/}} | ", specs.CountWithState(types.SpecStateFailureStates))) - if specs.CountOfFlakedSpecs() > 0 { - r.emit(r.f("{{light-yellow}}{{bold}}%d Flaked{{/}} | ", specs.CountOfFlakedSpecs())) + if len(report.ContainerHierarchyTexts) > 0 { + r.emitBlock(r.cycleJoin(report.ContainerHierarchyTexts, " ")) + indentation = 1 } - if specs.CountOfRepeatedSpecs() > 0 { - r.emit(r.f("{{light-yellow}}{{bold}}%d Repeated{{/}} | ", specs.CountOfRepeatedSpecs())) + line := r.fi(indentation, "{{bold}}%s{{/}}", report.LeafNodeText) + labels := report.Labels() + if len(labels) > 0 { + line += r.f(" {{coral}}[%s]{{/}}", strings.Join(labels, ", ")) } - r.emit(r.f("{{yellow}}{{bold}}%d Pending{{/}} | ", specs.CountWithState(types.SpecStatePending))) - r.emit(r.f("{{cyan}}{{bold}}%d Skipped{{/}}\n", specs.CountWithState(types.SpecStateSkipped))) - } -} - -func (r *DefaultReporter) WillRun(report types.SpecReport) { - v := r.conf.Verbosity() - if v.LT(types.VerbosityLevelVerbose) || report.State.Is(types.SpecStatePending|types.SpecStateSkipped) || report.RunningInParallel { - return + r.emitBlock(line) } - - r.emitDelimiter(0) - r.emitBlock(r.f(r.codeLocationBlock(report, "{{/}}", v.Is(types.VerbosityLevelVeryVerbose), false))) + r.emitBlock(r.fi(indentation, "{{gray}}%s{{/}}", report.LeafNodeLocation)) } func (r *DefaultReporter) DidRun(report types.SpecReport) { v := r.conf.Verbosity() - inParallel := report.RunningInParallel + var header, highlightColor string + includeRuntime, emitGinkgoWriterOutput, stream, denoter := true, true, false, r.specDenoter + succinctLocationBlock := v.Is(types.VerbosityLevelSuccinct) + + hasGW := report.CapturedGinkgoWriterOutput != "" + hasStd := report.CapturedStdOutErr != "" + hasEmittableReports := report.ReportEntries.HasVisibility(types.ReportEntryVisibilityAlways) || (report.ReportEntries.HasVisibility(types.ReportEntryVisibilityFailureOrVerbose) && (!report.Failure.IsZero() || v.GTE(types.VerbosityLevelVerbose))) - header := r.specDenoter if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { - header = fmt.Sprintf("[%s]", report.LeafNodeType) - } - highlightColor := r.highlightColorForState(report.State) - - // have we already been streaming the timeline? - timelineHasBeenStreaming := v.GTE(types.VerbosityLevelVerbose) && !inParallel - - // should we show the timeline? - var timeline types.Timeline - showTimeline := !timelineHasBeenStreaming && (v.GTE(types.VerbosityLevelVerbose) || report.Failed()) - if showTimeline { - timeline = report.Timeline().WithoutHiddenReportEntries() - keepVeryVerboseSpecEvents := v.Is(types.VerbosityLevelVeryVerbose) || - (v.Is(types.VerbosityLevelVerbose) && r.conf.ShowNodeEvents) || - (report.Failed() && r.conf.ShowNodeEvents) - if !keepVeryVerboseSpecEvents { - timeline = timeline.WithoutVeryVerboseSpecEvents() - } - if len(timeline) == 0 && report.CapturedGinkgoWriterOutput == "" { - // the timeline is completely empty - don't show it - showTimeline = false - } - if v.LT(types.VerbosityLevelVeryVerbose) && report.CapturedGinkgoWriterOutput == "" && len(timeline) > 0 { - //if we aren't -vv and the timeline only has a single failure, don't show it as it will appear at the end of the report - failure, isFailure := timeline[0].(types.Failure) - if isFailure && (len(timeline) == 1 || (len(timeline) == 2 && failure.AdditionalFailure != nil)) { - showTimeline = false - } - } + denoter = fmt.Sprintf("[%s]", report.LeafNodeType) } - // should we have a separate section for always-visible reports? - showSeparateVisibilityAlwaysReportsSection := !timelineHasBeenStreaming && !showTimeline && report.ReportEntries.HasVisibility(types.ReportEntryVisibilityAlways) - - // should we have a separate section for captured stdout/stderr - showSeparateStdSection := inParallel && (report.CapturedStdOutErr != "") - - // given all that - do we have any actual content to show? or are we a single denoter in a stream? - reportHasContent := v.Is(types.VerbosityLevelVeryVerbose) || showTimeline || showSeparateVisibilityAlwaysReportsSection || showSeparateStdSection || report.Failed() || (v.Is(types.VerbosityLevelVerbose) && !report.State.Is(types.SpecStateSkipped)) - - // should we show a runtime? - includeRuntime := !report.State.Is(types.SpecStateSkipped|types.SpecStatePending) || (report.State.Is(types.SpecStateSkipped) && report.Failure.Message != "") - - // should we show the codelocation block? - showCodeLocation := !timelineHasBeenStreaming || !report.State.Is(types.SpecStatePassed) - switch report.State { case types.SpecStatePassed: - if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) && !reportHasContent { - return - } + highlightColor, succinctLocationBlock = "{{green}}", v.LT(types.VerbosityLevelVerbose) + emitGinkgoWriterOutput = (r.conf.AlwaysEmitGinkgoWriter || v.GTE(types.VerbosityLevelVerbose)) && hasGW if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { - header = fmt.Sprintf("%s PASSED", header) + if v.GTE(types.VerbosityLevelVerbose) || hasStd || hasEmittableReports { + header = fmt.Sprintf("%s PASSED", denoter) + } else { + return + } + } else { + header, stream = denoter, true + if report.NumAttempts > 1 { + header, stream = fmt.Sprintf("%s [FLAKEY TEST - TOOK %d ATTEMPTS TO PASS]", r.retryDenoter, report.NumAttempts), false + } + if report.RunTime > r.conf.SlowSpecThreshold { + header, stream = fmt.Sprintf("%s [SLOW TEST]", header), false + } } - if report.NumAttempts > 1 && report.MaxFlakeAttempts > 1 { - header, reportHasContent = fmt.Sprintf("%s [FLAKEY TEST - TOOK %d ATTEMPTS TO PASS]", r.retryDenoter, report.NumAttempts), true + if hasStd || emitGinkgoWriterOutput || hasEmittableReports { + stream = false } case types.SpecStatePending: - header = "P" - if v.GT(types.VerbosityLevelSuccinct) { - header, reportHasContent = "P [PENDING]", true + highlightColor = "{{yellow}}" + includeRuntime, emitGinkgoWriterOutput = false, false + if v.Is(types.VerbosityLevelSuccinct) { + header, stream = "P", true + } else { + header, succinctLocationBlock = "P [PENDING]", v.LT(types.VerbosityLevelVeryVerbose) } case types.SpecStateSkipped: - header = "S" - if v.Is(types.VerbosityLevelVeryVerbose) || (v.Is(types.VerbosityLevelVerbose) && report.Failure.Message != "") { - header, reportHasContent = "S [SKIPPED]", true - } - default: - header = fmt.Sprintf("%s [%s]", header, r.humanReadableState(report.State)) - if report.MaxMustPassRepeatedly > 1 { - header = fmt.Sprintf("%s DURING REPETITION #%d", header, report.NumAttempts) + highlightColor = "{{cyan}}" + if report.Failure.Message != "" || v.Is(types.VerbosityLevelVeryVerbose) { + header = "S [SKIPPED]" + } else { + header, stream = "S", true } + case types.SpecStateFailed: + highlightColor, header = "{{red}}", fmt.Sprintf("%s [FAILED]", denoter) + case types.SpecStatePanicked: + highlightColor, header = "{{magenta}}", fmt.Sprintf("%s! [PANICKED]", denoter) + case types.SpecStateInterrupted: + highlightColor, header = "{{orange}}", fmt.Sprintf("%s! [INTERRUPTED]", denoter) + case types.SpecStateAborted: + highlightColor, header = "{{coral}}", fmt.Sprintf("%s! [ABORTED]", denoter) } - // If we have no content to show, jsut emit the header and return - if !reportHasContent { + // Emit stream and return + if stream { r.emit(r.f(highlightColor + header + "{{/}}")) return } + // Emit header + r.emitDelimiter() if includeRuntime { header = r.f("%s [%.3f seconds]", header, report.RunTime.Seconds()) } - - // Emit header - if !timelineHasBeenStreaming { - r.emitDelimiter(0) - } r.emitBlock(r.f(highlightColor + header + "{{/}}")) - if showCodeLocation { - r.emitBlock(r.codeLocationBlock(report, highlightColor, v.Is(types.VerbosityLevelVeryVerbose), false)) - } - //Emit Stdout/Stderr Output - if showSeparateStdSection { - r.emitBlock("\n") - r.emitBlock(r.fi(1, "{{gray}}Captured StdOut/StdErr Output >>{{/}}")) - r.emitBlock(r.fi(1, "%s", report.CapturedStdOutErr)) - r.emitBlock(r.fi(1, "{{gray}}<< Captured StdOut/StdErr Output{{/}}")) - } + // Emit Code Location Block + r.emitBlock(r.codeLocationBlock(report, highlightColor, succinctLocationBlock, false)) - if showSeparateVisibilityAlwaysReportsSection { + //Emit Stdout/Stderr Output + if hasStd { r.emitBlock("\n") - r.emitBlock(r.fi(1, "{{gray}}Report Entries >>{{/}}")) - for _, entry := range report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways) { - r.emitReportEntry(1, entry) - } - r.emitBlock(r.fi(1, "{{gray}}<< Report Entries{{/}}")) + r.emitBlock(r.fi(1, "{{gray}}Begin Captured StdOut/StdErr Output >>{{/}}")) + r.emitBlock(r.fi(2, "%s", report.CapturedStdOutErr)) + r.emitBlock(r.fi(1, "{{gray}}<< End Captured StdOut/StdErr Output{{/}}")) } - if showTimeline { + //Emit Captured GinkgoWriter Output + if emitGinkgoWriterOutput && hasGW { r.emitBlock("\n") - r.emitBlock(r.fi(1, "{{gray}}Timeline >>{{/}}")) - r.emitTimeline(1, report, timeline) - r.emitBlock(r.fi(1, "{{gray}}<< Timeline{{/}}")) + r.emitBlock(r.fi(1, "{{gray}}Begin Captured GinkgoWriter Output >>{{/}}")) + r.emitBlock(r.fi(2, "%s", report.CapturedGinkgoWriterOutput)) + r.emitBlock(r.fi(1, "{{gray}}<< End Captured GinkgoWriter Output{{/}}")) } - // Emit Failure Message - if !report.Failure.IsZero() && !v.Is(types.VerbosityLevelVeryVerbose) { + if hasEmittableReports { r.emitBlock("\n") - r.emitFailure(1, report.State, report.Failure, true) - if len(report.AdditionalFailures) > 0 { - r.emitBlock(r.fi(1, "\nThere were {{bold}}{{red}}additional failures{{/}} detected. To view them in detail run {{bold}}ginkgo -vv{{/}}")) - } - } - - r.emitDelimiter(0) -} - -func (r *DefaultReporter) highlightColorForState(state types.SpecState) string { - switch state { - case types.SpecStatePassed: - return "{{green}}" - case types.SpecStatePending: - return "{{yellow}}" - case types.SpecStateSkipped: - return "{{cyan}}" - case types.SpecStateFailed: - return "{{red}}" - case types.SpecStateTimedout: - return "{{orange}}" - case types.SpecStatePanicked: - return "{{magenta}}" - case types.SpecStateInterrupted: - return "{{orange}}" - case types.SpecStateAborted: - return "{{coral}}" - default: - return "{{gray}}" - } -} - -func (r *DefaultReporter) humanReadableState(state types.SpecState) string { - return strings.ToUpper(state.String()) -} - -func (r *DefaultReporter) emitTimeline(indent uint, report types.SpecReport, timeline types.Timeline) { - isVeryVerbose := r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose) - gw := report.CapturedGinkgoWriterOutput - cursor := 0 - for _, entry := range timeline { - tl := entry.GetTimelineLocation() - if tl.Offset < len(gw) { - r.emit(r.fi(indent, "%s", gw[cursor:tl.Offset])) - cursor = tl.Offset - } else if cursor < len(gw) { - r.emit(r.fi(indent, "%s", gw[cursor:])) - cursor = len(gw) - } - switch x := entry.(type) { - case types.Failure: - if isVeryVerbose { - r.emitFailure(indent, report.State, x, false) - } else { - r.emitShortFailure(indent, report.State, x) - } - case types.AdditionalFailure: - if isVeryVerbose { - r.emitFailure(indent, x.State, x.Failure, true) - } else { - r.emitShortFailure(indent, x.State, x.Failure) - } - case types.ReportEntry: - r.emitReportEntry(indent, x) - case types.ProgressReport: - r.emitProgressReport(indent, false, x) - case types.SpecEvent: - if isVeryVerbose || !x.IsOnlyVisibleAtVeryVerbose() || r.conf.ShowNodeEvents { - r.emitSpecEvent(indent, x, isVeryVerbose) + r.emitBlock(r.fi(1, "{{gray}}Begin Report Entries >>{{/}}")) + reportEntries := report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways) + if !report.Failure.IsZero() || v.GTE(types.VerbosityLevelVerbose) { + reportEntries = report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways, types.ReportEntryVisibilityFailureOrVerbose) + } + for _, entry := range reportEntries { + r.emitBlock(r.fi(2, "{{bold}}"+entry.Name+"{{gray}} - %s @ %s{{/}}", entry.Location, entry.Time.Format(types.GINKGO_TIME_FORMAT))) + if representation := entry.StringRepresentation(); representation != "" { + r.emitBlock(r.fi(3, representation)) } } - } - if cursor < len(gw) { - r.emit(r.fi(indent, "%s", gw[cursor:])) - } -} - -func (r *DefaultReporter) EmitFailure(state types.SpecState, failure types.Failure) { - if r.conf.Verbosity().Is(types.VerbosityLevelVerbose) { - r.emitShortFailure(1, state, failure) - } else if r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose) { - r.emitFailure(1, state, failure, true) - } -} - -func (r *DefaultReporter) emitShortFailure(indent uint, state types.SpecState, failure types.Failure) { - r.emitBlock(r.fi(indent, r.highlightColorForState(state)+"[%s]{{/}} in [%s] - %s {{gray}}@ %s{{/}}", - r.humanReadableState(state), - failure.FailureNodeType, - failure.Location, - failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT), - )) -} - -func (r *DefaultReporter) emitFailure(indent uint, state types.SpecState, failure types.Failure, includeAdditionalFailure bool) { - highlightColor := r.highlightColorForState(state) - r.emitBlock(r.fi(indent, highlightColor+"[%s] %s{{/}}", r.humanReadableState(state), failure.Message)) - r.emitBlock(r.fi(indent, highlightColor+"In {{bold}}[%s]{{/}}"+highlightColor+" at: {{bold}}%s{{/}} {{gray}}@ %s{{/}}\n", failure.FailureNodeType, failure.Location, failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) - if failure.ForwardedPanic != "" { - r.emitBlock("\n") - r.emitBlock(r.fi(indent, highlightColor+"%s{{/}}", failure.ForwardedPanic)) + r.emitBlock(r.fi(1, "{{gray}}<< End Report Entries{{/}}")) } - if r.conf.FullTrace || failure.ForwardedPanic != "" { - r.emitBlock("\n") - r.emitBlock(r.fi(indent, highlightColor+"Full Stack Trace{{/}}")) - r.emitBlock(r.fi(indent+1, "%s", failure.Location.FullStackTrace)) - } - - if !failure.ProgressReport.IsZero() { - r.emitBlock("\n") - r.emitProgressReport(indent, false, failure.ProgressReport) - } - - if failure.AdditionalFailure != nil && includeAdditionalFailure { + // Emit Failure Message + if !report.Failure.IsZero() { r.emitBlock("\n") - r.emitFailure(indent, failure.AdditionalFailure.State, failure.AdditionalFailure.Failure, true) - } -} - -func (r *DefaultReporter) EmitProgressReport(report types.ProgressReport) { - r.emitDelimiter(1) - - if report.RunningInParallel { - r.emit(r.fi(1, "{{coral}}Progress Report for Ginkgo Process #{{bold}}%d{{/}}\n", report.ParallelProcess)) - } - shouldEmitGW := report.RunningInParallel || r.conf.Verbosity().LT(types.VerbosityLevelVerbose) - r.emitProgressReport(1, shouldEmitGW, report) - r.emitDelimiter(1) -} - -func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput bool, report types.ProgressReport) { - if report.Message != "" { - r.emitBlock(r.fi(indent, report.Message+"\n")) - indent += 1 - } - if report.LeafNodeText != "" { - subjectIndent := indent - if len(report.ContainerHierarchyTexts) > 0 { - r.emit(r.fi(indent, r.cycleJoin(report.ContainerHierarchyTexts, " "))) - r.emit(" ") - subjectIndent = 0 + r.emitBlock(r.fi(1, highlightColor+"%s{{/}}", report.Failure.Message)) + r.emitBlock(r.fi(1, highlightColor+"In {{bold}}[%s]{{/}}"+highlightColor+" at: {{bold}}%s{{/}}\n", report.Failure.FailureNodeType, report.Failure.Location)) + if report.Failure.ForwardedPanic != "" { + r.emitBlock("\n") + r.emitBlock(r.fi(1, highlightColor+"%s{{/}}", report.Failure.ForwardedPanic)) } - r.emit(r.fi(subjectIndent, "{{bold}}{{orange}}%s{{/}} (Spec Runtime: %s)\n", report.LeafNodeText, report.Time().Sub(report.SpecStartTime).Round(time.Millisecond))) - r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.LeafNodeLocation)) - indent += 1 - } - if report.CurrentNodeType != types.NodeTypeInvalid { - r.emit(r.fi(indent, "In {{bold}}{{orange}}[%s]{{/}}", report.CurrentNodeType)) - if report.CurrentNodeText != "" && !report.CurrentNodeType.Is(types.NodeTypeIt) { - r.emit(r.f(" {{bold}}{{orange}}%s{{/}}", report.CurrentNodeText)) - } - - r.emit(r.f(" (Node Runtime: %s)\n", report.Time().Sub(report.CurrentNodeStartTime).Round(time.Millisecond))) - r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.CurrentNodeLocation)) - indent += 1 - } - if report.CurrentStepText != "" { - r.emit(r.fi(indent, "At {{bold}}{{orange}}[By Step] %s{{/}} (Step Runtime: %s)\n", report.CurrentStepText, report.Time().Sub(report.CurrentStepStartTime).Round(time.Millisecond))) - r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.CurrentStepLocation)) - indent += 1 - } - if indent > 0 { - indent -= 1 - } - - if emitGinkgoWriterOutput && report.CapturedGinkgoWriterOutput != "" { - r.emit("\n") - r.emitBlock(r.fi(indent, "{{gray}}Begin Captured GinkgoWriter Output >>{{/}}")) - limit, lines := 10, strings.Split(report.CapturedGinkgoWriterOutput, "\n") - if len(lines) <= limit { - r.emitBlock(r.fi(indent+1, "%s", report.CapturedGinkgoWriterOutput)) - } else { - r.emitBlock(r.fi(indent+1, "{{gray}}...{{/}}")) - for _, line := range lines[len(lines)-limit-1:] { - r.emitBlock(r.fi(indent+1, "%s", line)) - } + if r.conf.FullTrace || report.Failure.ForwardedPanic != "" { + r.emitBlock("\n") + r.emitBlock(r.fi(1, highlightColor+"Full Stack Trace{{/}}")) + r.emitBlock(r.fi(2, "%s", report.Failure.Location.FullStackTrace)) } - r.emitBlock(r.fi(indent, "{{gray}}<< End Captured GinkgoWriter Output{{/}}")) } - if !report.SpecGoroutine().IsZero() { - r.emit("\n") - r.emit(r.fi(indent, "{{bold}}{{underline}}Spec Goroutine{{/}}\n")) - r.emitGoroutines(indent, report.SpecGoroutine()) - } + r.emitDelimiter() +} - if len(report.AdditionalReports) > 0 { - r.emit("\n") - r.emitBlock(r.fi(indent, "{{gray}}Begin Additional Progress Reports >>{{/}}")) - for i, additionalReport := range report.AdditionalReports { - r.emit(r.fi(indent+1, additionalReport)) - if i < len(report.AdditionalReports)-1 { - r.emitBlock(r.fi(indent+1, "{{gray}}%s{{/}}", strings.Repeat("-", 10))) +func (r *DefaultReporter) SuiteDidEnd(report types.Report) { + failures := report.SpecReports.WithState(types.SpecStateFailureStates) + if len(failures) > 1 { + r.emitBlock("\n\n") + r.emitBlock(r.f("{{red}}{{bold}}Summarizing %d Failures:{{/}}", len(failures))) + for _, specReport := range failures { + highlightColor, heading := "{{red}}", "[FAIL]" + switch specReport.State { + case types.SpecStatePanicked: + highlightColor, heading = "{{magenta}}", "[PANICKED!]" + case types.SpecStateAborted: + highlightColor, heading = "{{coral}}", "[ABORTED]" + case types.SpecStateInterrupted: + highlightColor, heading = "{{orange}}", "[INTERRUPTED]" } + locationBlock := r.codeLocationBlock(specReport, highlightColor, true, true) + r.emitBlock(r.fi(1, highlightColor+"%s{{/}} %s", heading, locationBlock)) } - r.emitBlock(r.fi(indent, "{{gray}}<< End Additional Progress Reports{{/}}")) } - highlightedGoroutines := report.HighlightedGoroutines() - if len(highlightedGoroutines) > 0 { - r.emit("\n") - r.emit(r.fi(indent, "{{bold}}{{underline}}Goroutines of Interest{{/}}\n")) - r.emitGoroutines(indent, highlightedGoroutines...) - } - - otherGoroutines := report.OtherGoroutines() - if len(otherGoroutines) > 0 { - r.emit("\n") - r.emit(r.fi(indent, "{{gray}}{{bold}}{{underline}}Other Goroutines{{/}}\n")) - r.emitGoroutines(indent, otherGoroutines...) - } -} - -func (r *DefaultReporter) EmitReportEntry(entry types.ReportEntry) { - if r.conf.Verbosity().LT(types.VerbosityLevelVerbose) || entry.Visibility == types.ReportEntryVisibilityNever { - return - } - r.emitReportEntry(1, entry) -} - -func (r *DefaultReporter) emitReportEntry(indent uint, entry types.ReportEntry) { - r.emitBlock(r.fi(indent, "{{bold}}"+entry.Name+"{{gray}} - %s @ %s{{/}}", entry.Location, entry.Time.Format(types.GINKGO_TIME_FORMAT))) - if representation := entry.StringRepresentation(); representation != "" { - r.emitBlock(r.fi(indent+1, representation)) - } -} - -func (r *DefaultReporter) EmitSpecEvent(event types.SpecEvent) { - v := r.conf.Verbosity() - if v.Is(types.VerbosityLevelVeryVerbose) || (v.Is(types.VerbosityLevelVerbose) && (r.conf.ShowNodeEvents || !event.IsOnlyVisibleAtVeryVerbose())) { - r.emitSpecEvent(1, event, r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose)) - } -} - -func (r *DefaultReporter) emitSpecEvent(indent uint, event types.SpecEvent, includeLocation bool) { - location := "" - if includeLocation { - location = fmt.Sprintf("- %s ", event.CodeLocation.String()) - } - switch event.SpecEventType { - case types.SpecEventInvalid: + //summarize the suite + if r.conf.Verbosity().Is(types.VerbosityLevelSuccinct) && report.SuiteSucceeded { + r.emit(r.f(" {{green}}SUCCESS!{{/}} %s ", report.RunTime)) return - case types.SpecEventByStart: - r.emitBlock(r.fi(indent, "{{bold}}STEP:{{/}} %s {{gray}}%s@ %s{{/}}", event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) - case types.SpecEventByEnd: - r.emitBlock(r.fi(indent, "{{bold}}END STEP:{{/}} %s {{gray}}%s@ %s (%s){{/}}", event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT), event.Duration.Round(time.Millisecond))) - case types.SpecEventNodeStart: - r.emitBlock(r.fi(indent, "> Enter {{bold}}[%s]{{/}} %s {{gray}}%s@ %s{{/}}", event.NodeType.String(), event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) - case types.SpecEventNodeEnd: - r.emitBlock(r.fi(indent, "< Exit {{bold}}[%s]{{/}} %s {{gray}}%s@ %s (%s){{/}}", event.NodeType.String(), event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT), event.Duration.Round(time.Millisecond))) - case types.SpecEventSpecRepeat: - r.emitBlock(r.fi(indent, "\n{{bold}}Attempt #%d {{green}}Passed{{/}}{{bold}}. Repeating %s{{/}} {{gray}}@ %s{{/}}\n\n", event.Attempt, r.retryDenoter, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) - case types.SpecEventSpecRetry: - r.emitBlock(r.fi(indent, "\n{{bold}}Attempt #%d {{red}}Failed{{/}}{{bold}}. Retrying %s{{/}} {{gray}}@ %s{{/}}\n\n", event.Attempt, r.retryDenoter, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) } -} - -func (r *DefaultReporter) emitGoroutines(indent uint, goroutines ...types.Goroutine) { - for idx, g := range goroutines { - color := "{{gray}}" - if g.HasHighlights() { - color = "{{orange}}" - } - r.emit(r.fi(indent, color+"goroutine %d [%s]{{/}}\n", g.ID, g.State)) - for _, fc := range g.Stack { - if fc.Highlight { - r.emit(r.fi(indent, color+"{{bold}}> %s{{/}}\n", fc.Function)) - r.emit(r.fi(indent+2, color+"{{bold}}%s:%d{{/}}\n", fc.Filename, fc.Line)) - r.emitSource(indent+3, fc) - } else { - r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", fc.Function)) - r.emit(r.fi(indent+2, "{{gray}}%s:%d{{/}}\n", fc.Filename, fc.Line)) - } - } - if idx+1 < len(goroutines) { - r.emit("\n") - } + r.emitBlock("\n") + color, status := "{{green}}{{bold}}", "SUCCESS!" + if !report.SuiteSucceeded { + color, status = "{{red}}{{bold}}", "FAIL!" } -} -func (r *DefaultReporter) emitSource(indent uint, fc types.FunctionCall) { - lines := fc.Source - if len(lines) == 0 { - return - } + specs := report.SpecReports.WithLeafNodeType(types.NodeTypeIt) //exclude any suite setup nodes + r.emitBlock(r.f(color+"Ran %d of %d Specs in %.3f seconds{{/}}", + specs.CountWithState(types.SpecStatePassed)+specs.CountWithState(types.SpecStateFailureStates), + report.PreRunStats.TotalSpecs, + report.RunTime.Seconds()), + ) - lTrim := 100000 - for _, line := range lines { - lTrimLine := len(line) - len(strings.TrimLeft(line, " \t")) - if lTrimLine < lTrim && len(line) > 0 { - lTrim = lTrimLine - } - } - if lTrim == 100000 { - lTrim = 0 + switch len(report.SpecialSuiteFailureReasons) { + case 0: + r.emit(r.f(color+"%s{{/}} -- ", status)) + case 1: + r.emit(r.f(color+"%s - %s{{/}} -- ", status, report.SpecialSuiteFailureReasons[0])) + default: + r.emitBlock(r.f(color+"%s - %s{{/}}\n", status, strings.Join(report.SpecialSuiteFailureReasons, ", "))) } - for idx, line := range lines { - if len(line) > lTrim { - line = line[lTrim:] - } - if idx == fc.SourceHighlight { - r.emit(r.fi(indent, "{{bold}}{{orange}}> %s{{/}}\n", line)) - } else { - r.emit(r.fi(indent, "| %s\n", line)) + if len(specs) == 0 && report.SpecReports.WithLeafNodeType(types.NodeTypeBeforeSuite|types.NodeTypeSynchronizedBeforeSuite).CountWithState(types.SpecStateFailureStates) > 0 { + r.emit(r.f("{{cyan}}{{bold}}A BeforeSuite node failed so all tests were skipped.{{/}}\n")) + } else { + r.emit(r.f("{{green}}{{bold}}%d Passed{{/}} | ", specs.CountWithState(types.SpecStatePassed))) + r.emit(r.f("{{red}}{{bold}}%d Failed{{/}} | ", specs.CountWithState(types.SpecStateFailureStates))) + if specs.CountOfFlakedSpecs() > 0 { + r.emit(r.f("{{light-yellow}}{{bold}}%d Flaked{{/}} | ", specs.CountOfFlakedSpecs())) } + r.emit(r.f("{{yellow}}{{bold}}%d Pending{{/}} | ", specs.CountWithState(types.SpecStatePending))) + r.emit(r.f("{{cyan}}{{bold}}%d Skipped{{/}}\n", specs.CountWithState(types.SpecStateSkipped))) } } @@ -638,11 +331,11 @@ func (r *DefaultReporter) emitBlock(s string) { } } -func (r *DefaultReporter) emitDelimiter(indent uint) { +func (r *DefaultReporter) emitDelimiter() { if r.lastEmissionWasDelimiter { return } - r.emitBlock(r.fi(indent, "{{gray}}%s{{/}}", strings.Repeat("-", 30))) + r.emitBlock(r.f("{{gray}}%s{{/}}", strings.Repeat("-", 30))) r.lastEmissionWasDelimiter = true } @@ -659,14 +352,13 @@ func (r *DefaultReporter) cycleJoin(elements []string, joiner string) string { return r.formatter.CycleJoin(elements, joiner, []string{"{{/}}", "{{gray}}"}) } -func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightColor string, veryVerbose bool, usePreciseFailureLocation bool) string { +func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightColor string, succinct bool, usePreciseFailureLocation bool) string { texts, locations, labels := []string{}, []types.CodeLocation{}, [][]string{} texts, locations, labels = append(texts, report.ContainerHierarchyTexts...), append(locations, report.ContainerHierarchyLocations...), append(labels, report.ContainerHierarchyLabels...) - if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { texts = append(texts, r.f("[%s] %s", report.LeafNodeType, report.LeafNodeText)) } else { - texts = append(texts, r.f(report.LeafNodeText)) + texts = append(texts, report.LeafNodeText) } labels = append(labels, report.LeafNodeLabels) locations = append(locations, report.LeafNodeLocation) @@ -676,58 +368,24 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo failureLocation = report.Failure.Location } - highlightIndex := -1 switch report.Failure.FailureNodeContext { case types.FailureNodeAtTopLevel: - texts = append([]string{fmt.Sprintf("TOP-LEVEL [%s]", report.Failure.FailureNodeType)}, texts...) + texts = append([]string{r.f(highlightColor+"{{bold}}TOP-LEVEL [%s]{{/}}", report.Failure.FailureNodeType)}, texts...) locations = append([]types.CodeLocation{failureLocation}, locations...) labels = append([][]string{{}}, labels...) - highlightIndex = 0 case types.FailureNodeInContainer: i := report.Failure.FailureNodeContainerIndex - texts[i] = fmt.Sprintf("%s [%s]", texts[i], report.Failure.FailureNodeType) + texts[i] = r.f(highlightColor+"{{bold}}%s [%s]{{/}}", texts[i], report.Failure.FailureNodeType) locations[i] = failureLocation - highlightIndex = i case types.FailureNodeIsLeafNode: i := len(texts) - 1 - texts[i] = fmt.Sprintf("[%s] %s", report.LeafNodeType, report.LeafNodeText) + texts[i] = r.f(highlightColor+"{{bold}}[%s] %s{{/}}", report.LeafNodeType, report.LeafNodeText) locations[i] = failureLocation - highlightIndex = i - default: - //there is no failure, so we highlight the leaf ndoe - highlightIndex = len(texts) - 1 } out := "" - if veryVerbose { - for i := range texts { - if i == highlightIndex { - out += r.fi(uint(i), highlightColor+"{{bold}}%s{{/}}", texts[i]) - } else { - out += r.fi(uint(i), "%s", texts[i]) - } - if len(labels[i]) > 0 { - out += r.f(" {{coral}}[%s]{{/}}", strings.Join(labels[i], ", ")) - } - out += "\n" - out += r.fi(uint(i), "{{gray}}%s{{/}}\n", locations[i]) - } - } else { - for i := range texts { - style := "{{/}}" - if i%2 == 1 { - style = "{{gray}}" - } - if i == highlightIndex { - style = highlightColor + "{{bold}}" - } - out += r.f(style+"%s", texts[i]) - if i < len(texts)-1 { - out += " " - } else { - out += r.f("{{/}}") - } - } + if succinct { + out += r.f("%s", r.cycleJoin(texts, " ")) flattenedLabels := report.Labels() if len(flattenedLabels) > 0 { out += r.f(" {{coral}}[%s]{{/}}", strings.Join(flattenedLabels, ", ")) @@ -736,15 +394,17 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo if usePreciseFailureLocation { out += r.f("{{gray}}%s{{/}}", failureLocation) } else { - leafLocation := locations[len(locations)-1] - if (report.Failure.FailureNodeLocation != types.CodeLocation{}) && (report.Failure.FailureNodeLocation != leafLocation) { - out += r.fi(1, highlightColor+"[%s]{{/}} {{gray}}%s{{/}}\n", report.Failure.FailureNodeType, report.Failure.FailureNodeLocation) - out += r.fi(1, "{{gray}}[%s] %s{{/}}", report.LeafNodeType, leafLocation) - } else { - out += r.f("{{gray}}%s{{/}}", leafLocation) + out += r.f("{{gray}}%s{{/}}", locations[len(locations)-1]) + } + } else { + for i := range texts { + out += r.fi(uint(i), "%s", texts[i]) + if len(labels[i]) > 0 { + out += r.f(" {{coral}}[%s]{{/}}", strings.Join(labels[i], ", ")) } + out += "\n" + out += r.fi(uint(i), "{{gray}}%s{{/}}\n", locations[i]) } - } return out } diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go b/vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go index 613072eb..89d30076 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go @@ -35,7 +35,7 @@ func ReportViaDeprecatedReporter(reporter DeprecatedReporter, report types.Repor FailOnPending: report.SuiteConfig.FailOnPending, FailFast: report.SuiteConfig.FailFast, FlakeAttempts: report.SuiteConfig.FlakeAttempts, - EmitSpecProgress: false, + EmitSpecProgress: report.SuiteConfig.EmitSpecProgress, DryRun: report.SuiteConfig.DryRun, ParallelNode: report.SuiteConfig.ParallelProcess, ParallelTotal: report.SuiteConfig.ParallelTotal, diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go index 576962e8..febcc650 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go @@ -15,23 +15,12 @@ import ( "fmt" "os" "strings" + "time" "github.com/onsi/ginkgo/v2/config" "github.com/onsi/ginkgo/v2/types" ) -type JunitReportConfig struct { - // Spec States for which no timeline should be emitted for system-err - // set this to types.SpecStatePassed|types.SpecStateSkipped|types.SpecStatePending to only match failing specs - OmitTimelinesForSpecState types.SpecState - - // Enable OmitFailureMessageAttr to prevent failure messages appearing in the "message" attribute of the Failure and Error tags - OmitFailureMessageAttr bool - - //Enable OmitCapturedStdOutErr to prevent captured stdout/stderr appearing in system-out - OmitCapturedStdOutErr bool -} - type JUnitTestSuites struct { XMLName xml.Name `xml:"testsuites"` // Tests maps onto the total number of specs in all test suites (this includes any suite nodes such as BeforeSuite) @@ -139,10 +128,6 @@ type JUnitFailure struct { } func GenerateJUnitReport(report types.Report, dst string) error { - return GenerateJUnitReportWithConfig(report, dst, JunitReportConfig{}) -} - -func GenerateJUnitReportWithConfig(report types.Report, dst string, config JunitReportConfig) error { suite := JUnitTestSuite{ Name: report.SuiteDescription, Package: report.SuitePath, @@ -164,6 +149,7 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit {"FailOnPending", fmt.Sprintf("%t", report.SuiteConfig.FailOnPending)}, {"FailFast", fmt.Sprintf("%t", report.SuiteConfig.FailFast)}, {"FlakeAttempts", fmt.Sprintf("%d", report.SuiteConfig.FlakeAttempts)}, + {"EmitSpecProgress", fmt.Sprintf("%t", report.SuiteConfig.EmitSpecProgress)}, {"DryRun", fmt.Sprintf("%t", report.SuiteConfig.DryRun)}, {"ParallelTotal", fmt.Sprintf("%d", report.SuiteConfig.ParallelTotal)}, {"OutputInterceptorMode", report.SuiteConfig.OutputInterceptorMode}, @@ -185,12 +171,8 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit Classname: report.SuiteDescription, Status: spec.State.String(), Time: spec.RunTime.Seconds(), - } - if !spec.State.Is(config.OmitTimelinesForSpecState) { - test.SystemErr = systemErrForUnstructuredReporters(spec) - } - if !config.OmitCapturedStdOutErr { - test.SystemOut = systemOutForUnstructuredReporters(spec) + SystemOut: systemOutForUnstructureReporters(spec), + SystemErr: spec.CapturedGinkgoWriterOutput, } suite.Tests += 1 @@ -209,50 +191,28 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit test.Failure = &JUnitFailure{ Message: spec.Failure.Message, Type: "failed", - Description: failureDescriptionForUnstructuredReporters(spec), - } - if config.OmitFailureMessageAttr { - test.Failure.Message = "" - } - suite.Failures += 1 - case types.SpecStateTimedout: - test.Failure = &JUnitFailure{ - Message: spec.Failure.Message, - Type: "timedout", - Description: failureDescriptionForUnstructuredReporters(spec), - } - if config.OmitFailureMessageAttr { - test.Failure.Message = "" + Description: fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace), } suite.Failures += 1 case types.SpecStateInterrupted: test.Error = &JUnitError{ - Message: spec.Failure.Message, + Message: "interrupted", Type: "interrupted", - Description: failureDescriptionForUnstructuredReporters(spec), - } - if config.OmitFailureMessageAttr { - test.Error.Message = "" + Description: spec.Failure.Message, } suite.Errors += 1 case types.SpecStateAborted: test.Failure = &JUnitFailure{ Message: spec.Failure.Message, Type: "aborted", - Description: failureDescriptionForUnstructuredReporters(spec), - } - if config.OmitFailureMessageAttr { - test.Failure.Message = "" + Description: fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace), } suite.Errors += 1 case types.SpecStatePanicked: test.Error = &JUnitError{ Message: spec.Failure.ForwardedPanic, Type: "panicked", - Description: failureDescriptionForUnstructuredReporters(spec), - } - if config.OmitFailureMessageAttr { - test.Error.Message = "" + Description: fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace), } suite.Errors += 1 } @@ -318,23 +278,21 @@ func MergeAndCleanupJUnitReports(sources []string, dst string) ([]string, error) return messages, f.Close() } -func failureDescriptionForUnstructuredReporters(spec types.SpecReport) string { - out := &strings.Builder{} - NewDefaultReporter(types.ReporterConfig{NoColor: true, VeryVerbose: true}, out).emitFailure(0, spec.State, spec.Failure, true) - if len(spec.AdditionalFailures) > 0 { - out.WriteString("\nThere were additional failures detected after the initial failure. These are visible in the timeline\n") +func systemOutForUnstructureReporters(spec types.SpecReport) string { + systemOut := spec.CapturedStdOutErr + if len(spec.ReportEntries) > 0 { + systemOut += "\nReport Entries:\n" + for i, entry := range spec.ReportEntries { + systemOut += fmt.Sprintf("%s\n%s\n%s\n", entry.Name, entry.Location, entry.Time.Format(time.RFC3339Nano)) + if representation := entry.StringRepresentation(); representation != "" { + systemOut += representation + "\n" + } + if i+1 < len(spec.ReportEntries) { + systemOut += "--\n" + } + } } - return out.String() -} - -func systemErrForUnstructuredReporters(spec types.SpecReport) string { - out := &strings.Builder{} - NewDefaultReporter(types.ReporterConfig{NoColor: true, VeryVerbose: true}, out).emitTimeline(0, spec, spec.Timeline()) - return out.String() -} - -func systemOutForUnstructuredReporters(spec types.SpecReport) string { - return spec.CapturedStdOutErr + return systemOut } // Deprecated JUnitReporter (so folks can still compile their suites) diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go b/vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go index 5e726c46..29f84e7c 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go @@ -9,21 +9,11 @@ type Reporter interface { WillRun(report types.SpecReport) DidRun(report types.SpecReport) SuiteDidEnd(report types.Report) - - //Timeline emission - EmitFailure(state types.SpecState, failure types.Failure) - EmitProgressReport(progressReport types.ProgressReport) - EmitReportEntry(entry types.ReportEntry) - EmitSpecEvent(event types.SpecEvent) } type NoopReporter struct{} -func (n NoopReporter) SuiteWillBegin(report types.Report) {} -func (n NoopReporter) WillRun(report types.SpecReport) {} -func (n NoopReporter) DidRun(report types.SpecReport) {} -func (n NoopReporter) SuiteDidEnd(report types.Report) {} -func (n NoopReporter) EmitFailure(state types.SpecState, failure types.Failure) {} -func (n NoopReporter) EmitProgressReport(progressReport types.ProgressReport) {} -func (n NoopReporter) EmitReportEntry(entry types.ReportEntry) {} -func (n NoopReporter) EmitSpecEvent(event types.SpecEvent) {} +func (n NoopReporter) SuiteWillBegin(report types.Report) {} +func (n NoopReporter) WillRun(report types.SpecReport) {} +func (n NoopReporter) DidRun(report types.SpecReport) {} +func (n NoopReporter) SuiteDidEnd(report types.Report) {} diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go index c1863496..2aa2f184 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go @@ -17,12 +17,12 @@ import ( ) func tcEscape(s string) string { - s = strings.ReplaceAll(s, "|", "||") - s = strings.ReplaceAll(s, "'", "|'") - s = strings.ReplaceAll(s, "\n", "|n") - s = strings.ReplaceAll(s, "\r", "|r") - s = strings.ReplaceAll(s, "[", "|[") - s = strings.ReplaceAll(s, "]", "|]") + s = strings.Replace(s, "|", "||", -1) + s = strings.Replace(s, "'", "|'", -1) + s = strings.Replace(s, "\n", "|n", -1) + s = strings.Replace(s, "\r", "|r", -1) + s = strings.Replace(s, "[", "|[", -1) + s = strings.Replace(s, "]", "|]", -1) return s } @@ -60,24 +60,20 @@ func GenerateTeamcityReport(report types.Report, dst string) error { } fmt.Fprintf(f, "##teamcity[testIgnored name='%s' message='%s']\n", name, tcEscape(message)) case types.SpecStateFailed: - details := failureDescriptionForUnstructuredReporters(spec) + details := fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace) fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='failed - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details)) case types.SpecStatePanicked: - details := failureDescriptionForUnstructuredReporters(spec) + details := fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace) fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='panicked - %s' details='%s']\n", name, tcEscape(spec.Failure.ForwardedPanic), tcEscape(details)) - case types.SpecStateTimedout: - details := failureDescriptionForUnstructuredReporters(spec) - fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='timedout - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details)) case types.SpecStateInterrupted: - details := failureDescriptionForUnstructuredReporters(spec) - fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='interrupted - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details)) + fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='interrupted' details='%s']\n", name, tcEscape(spec.Failure.Message)) case types.SpecStateAborted: - details := failureDescriptionForUnstructuredReporters(spec) + details := fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace) fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='aborted - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details)) } - fmt.Fprintf(f, "##teamcity[testStdOut name='%s' out='%s']\n", name, tcEscape(systemOutForUnstructuredReporters(spec))) - fmt.Fprintf(f, "##teamcity[testStdErr name='%s' out='%s']\n", name, tcEscape(systemErrForUnstructuredReporters(spec))) + fmt.Fprintf(f, "##teamcity[testStdOut name='%s' out='%s']\n", name, tcEscape(systemOutForUnstructureReporters(spec))) + fmt.Fprintf(f, "##teamcity[testStdErr name='%s' out='%s']\n", name, tcEscape(spec.CapturedGinkgoWriterOutput)) fmt.Fprintf(f, "##teamcity[testFinished name='%s' duration='%d']\n", name, int(spec.RunTime.Seconds()*1000.0)) } fmt.Fprintf(f, "##teamcity[testSuiteFinished name='%s']\n", tcEscape(report.SuiteDescription)) diff --git a/vendor/github.com/onsi/ginkgo/v2/reporting_dsl.go b/vendor/github.com/onsi/ginkgo/v2/reporting_dsl.go index afc151b1..07b4c612 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporting_dsl.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporting_dsl.go @@ -79,11 +79,8 @@ receives a SpecReport. They are called before the spec starts. You cannot nest any other Ginkgo nodes within a ReportBeforeEach node's closure. You can learn more about ReportBeforeEach here: https://onsi.github.io/ginkgo/#generating-reports-programmatically */ -func ReportBeforeEach(body func(SpecReport), args ...interface{}) bool { - combinedArgs := []interface{}{body} - combinedArgs = append(combinedArgs, args...) - - return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportBeforeEach, "", combinedArgs...)) +func ReportBeforeEach(body func(SpecReport)) bool { + return pushNode(internal.NewReportBeforeEachNode(body, types.NewCodeLocation(1))) } /* @@ -93,11 +90,8 @@ receives a SpecReport. They are called after the spec has completed and receive You cannot nest any other Ginkgo nodes within a ReportAfterEach node's closure. You can learn more about ReportAfterEach here: https://onsi.github.io/ginkgo/#generating-reports-programmatically */ -func ReportAfterEach(body func(SpecReport), args ...interface{}) bool { - combinedArgs := []interface{}{body} - combinedArgs = append(combinedArgs, args...) - - return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterEach, "", combinedArgs...)) +func ReportAfterEach(body func(SpecReport)) bool { + return pushNode(internal.NewReportAfterEachNode(body, types.NewCodeLocation(1))) } /* @@ -115,10 +109,8 @@ You cannot nest any other Ginkgo nodes within a ReportAfterSuite node's closure. You can learn more about ReportAfterSuite here: https://onsi.github.io/ginkgo/#generating-reports-programmatically You can learn more about Ginkgo's reporting infrastructure, including generating reports with the CLI here: https://onsi.github.io/ginkgo/#generating-machine-readable-reports */ -func ReportAfterSuite(text string, body func(Report), args ...interface{}) bool { - combinedArgs := []interface{}{body} - combinedArgs = append(combinedArgs, args...) - return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterSuite, text, combinedArgs...)) +func ReportAfterSuite(text string, body func(Report)) bool { + return pushNode(internal.NewReportAfterSuiteNode(text, body, types.NewCodeLocation(1))) } func registerReportAfterSuiteNodeForAutogeneratedReports(reporterConfig types.ReporterConfig) { @@ -153,8 +145,7 @@ func registerReportAfterSuiteNodeForAutogeneratedReports(reporterConfig types.Re if reporterConfig.TeamcityReport != "" { flags = append(flags, "--teamcity-report") } - pushNode(internal.NewNode( - deprecationTracker, types.NodeTypeReportAfterSuite, + pushNode(internal.NewReportAfterSuiteNode( fmt.Sprintf("Autogenerated ReportAfterSuite for %s", strings.Join(flags, " ")), body, types.NewCustomCodeLocation("autogenerated by Ginkgo"), diff --git a/vendor/github.com/onsi/ginkgo/v2/table_dsl.go b/vendor/github.com/onsi/ginkgo/v2/table_dsl.go index 68367446..0db0e718 100644 --- a/vendor/github.com/onsi/ginkgo/v2/table_dsl.go +++ b/vendor/github.com/onsi/ginkgo/v2/table_dsl.go @@ -1,7 +1,6 @@ package ginkgo import ( - "context" "fmt" "reflect" "strings" @@ -90,8 +89,6 @@ Subsequent arguments accept any Ginkgo decorators. These are filtered out and t Each Entry ends up generating an individual Ginkgo It. The body of the it is the Table Body function with the Entry parameters passed in. -If you want to generate interruptible specs simply write a Table function that accepts a SpecContext as its first argument. You can then decorate individual Entrys with the NodeTimeout and SpecTimeout decorators. - You can learn more about Entry here: https://onsi.github.io/ginkgo/#table-specs */ func Entry(description interface{}, args ...interface{}) TableEntry { @@ -122,16 +119,12 @@ You can mark a particular entry as pending with XEntry. This is equivalent to X */ var XEntry = PEntry -var contextType = reflect.TypeOf(new(context.Context)).Elem() -var specContextType = reflect.TypeOf(new(SpecContext)).Elem() - func generateTable(description string, args ...interface{}) { cl := types.NewCodeLocation(2) containerNodeArgs := []interface{}{cl} entries := []TableEntry{} var itBody interface{} - var itBodyType reflect.Type var tableLevelEntryDescription interface{} tableLevelEntryDescription = func(args ...interface{}) string { @@ -142,10 +135,6 @@ func generateTable(description string, args ...interface{}) { return "Entry: " + strings.Join(out, ", ") } - if len(args) == 1 { - exitIfErr(types.GinkgoErrors.MissingParametersForTableFunction(cl)) - } - for i, arg := range args { switch t := reflect.TypeOf(arg); { case t == nil: @@ -163,7 +152,6 @@ func generateTable(description string, args ...interface{}) { exitIfErr(types.GinkgoErrors.MultipleEntryBodyFunctionsForTable(cl)) } itBody = arg - itBodyType = reflect.TypeOf(itBody) default: containerNodeArgs = append(containerNodeArgs, arg) } @@ -176,7 +164,7 @@ func generateTable(description string, args ...interface{}) { var description string switch t := reflect.TypeOf(entry.description); { case t == nil: - err = validateParameters(tableLevelEntryDescription, entry.parameters, "Entry Description function", entry.codeLocation, false) + err = validateParameters(tableLevelEntryDescription, entry.parameters, "Entry Description function", entry.codeLocation) if err == nil { description = invokeFunction(tableLevelEntryDescription, entry.parameters)[0].String() } @@ -185,7 +173,7 @@ func generateTable(description string, args ...interface{}) { case t == reflect.TypeOf(""): description = entry.description.(string) case t.Kind() == reflect.Func && t.NumOut() == 1 && t.Out(0) == reflect.TypeOf(""): - err = validateParameters(entry.description, entry.parameters, "Entry Description function", entry.codeLocation, false) + err = validateParameters(entry.description, entry.parameters, "Entry Description function", entry.codeLocation) if err == nil { description = invokeFunction(entry.description, entry.parameters)[0].String() } @@ -193,37 +181,17 @@ func generateTable(description string, args ...interface{}) { err = types.GinkgoErrors.InvalidEntryDescription(entry.codeLocation) } + if err == nil { + err = validateParameters(itBody, entry.parameters, "Table Body function", entry.codeLocation) + } itNodeArgs := []interface{}{entry.codeLocation} itNodeArgs = append(itNodeArgs, entry.decorations...) - - hasContext := false - if itBodyType.NumIn() > 0. { - if itBodyType.In(0).Implements(specContextType) { - hasContext = true - } else if itBodyType.In(0).Implements(contextType) && (len(entry.parameters) == 0 || !reflect.TypeOf(entry.parameters[0]).Implements(contextType)) { - hasContext = true + itNodeArgs = append(itNodeArgs, func() { + if err != nil { + panic(err) } - } - - if err == nil { - err = validateParameters(itBody, entry.parameters, "Table Body function", entry.codeLocation, hasContext) - } - - if hasContext { - itNodeArgs = append(itNodeArgs, func(c SpecContext) { - if err != nil { - panic(err) - } - invokeFunction(itBody, append([]interface{}{c}, entry.parameters...)) - }) - } else { - itNodeArgs = append(itNodeArgs, func() { - if err != nil { - panic(err) - } - invokeFunction(itBody, entry.parameters) - }) - } + invokeFunction(itBody, entry.parameters) + }) pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, description, itNodeArgs...)) } @@ -255,14 +223,9 @@ func invokeFunction(function interface{}, parameters []interface{}) []reflect.Va return reflect.ValueOf(function).Call(inValues) } -func validateParameters(function interface{}, parameters []interface{}, kind string, cl types.CodeLocation, hasContext bool) error { +func validateParameters(function interface{}, parameters []interface{}, kind string, cl types.CodeLocation) error { funcType := reflect.TypeOf(function) limit := funcType.NumIn() - offset := 0 - if hasContext { - limit = limit - 1 - offset = 1 - } if funcType.IsVariadic() { limit = limit - 1 } @@ -275,13 +238,13 @@ func validateParameters(function interface{}, parameters []interface{}, kind str var i = 0 for ; i < limit; i++ { actual := reflect.TypeOf(parameters[i]) - expected := funcType.In(i + offset) + expected := funcType.In(i) if !(actual == nil) && !actual.AssignableTo(expected) { return types.GinkgoErrors.IncorrectParameterTypeToTableFunction(i+1, expected, actual, kind, cl) } } if funcType.IsVariadic() { - expected := funcType.In(limit + offset).Elem() + expected := funcType.In(limit).Elem() for ; i < len(parameters); i++ { actual := reflect.TypeOf(parameters[i]) if !(actual == nil) && !actual.AssignableTo(expected) { diff --git a/vendor/github.com/onsi/ginkgo/v2/types/code_location.go b/vendor/github.com/onsi/ginkgo/v2/types/code_location.go index 12910918..00107d3a 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/code_location.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/code_location.go @@ -65,7 +65,7 @@ func NewCodeLocationWithStackTrace(skip int) CodeLocation { func PruneStack(fullStackTrace string, skip int) string { stack := strings.Split(fullStackTrace, "\n") // Ensure that the even entries are the method names and the - // odd entries the source code information. + // the odd entries the source code information. if len(stack) > 0 && strings.HasPrefix(stack[0], "goroutine ") { // Ignore "goroutine 29 [running]:" line. stack = stack[1:] diff --git a/vendor/github.com/onsi/ginkgo/v2/types/config.go b/vendor/github.com/onsi/ginkgo/v2/types/config.go index 4ec636eb..07ef4c3a 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/config.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/config.go @@ -26,13 +26,10 @@ type SuiteConfig struct { FailOnPending bool FailFast bool FlakeAttempts int + EmitSpecProgress bool DryRun bool - PollProgressAfter time.Duration - PollProgressInterval time.Duration Timeout time.Duration OutputInterceptorMode string - SourceRoots []string - GracePeriod time.Duration ParallelProcess int ParallelTotal int @@ -45,7 +42,6 @@ func NewDefaultSuiteConfig() SuiteConfig { Timeout: time.Hour, ParallelProcess: 1, ParallelTotal: 1, - GracePeriod: 30 * time.Second, } } @@ -80,12 +76,13 @@ func (vl VerbosityLevel) LT(comp VerbosityLevel) bool { // Configuration for Ginkgo's reporter type ReporterConfig struct { - NoColor bool - Succinct bool - Verbose bool - VeryVerbose bool - FullTrace bool - ShowNodeEvents bool + NoColor bool + SlowSpecThreshold time.Duration + Succinct bool + Verbose bool + VeryVerbose bool + FullTrace bool + AlwaysEmitGinkgoWriter bool JSONReport string JUnitReport string @@ -108,7 +105,9 @@ func (rc ReporterConfig) WillGenerateReport() bool { } func NewDefaultReporterConfig() ReporterConfig { - return ReporterConfig{} + return ReporterConfig{ + SlowSpecThreshold: 5 * time.Second, + } } // Configuration for the Ginkgo CLI @@ -231,9 +230,6 @@ type deprecatedConfig struct { SlowSpecThresholdWithFLoatUnits float64 Stream bool Notify bool - EmitSpecProgress bool - SlowSpecThreshold time.Duration - AlwaysEmitGinkgoWriter bool } // Flags @@ -274,16 +270,10 @@ var SuiteConfigFlags = GinkgoFlags{ {KeyPath: "S.DryRun", Name: "dry-run", SectionKey: "debug", DeprecatedName: "dryRun", DeprecatedDocLink: "changed-command-line-flags", Usage: "If set, ginkgo will walk the test hierarchy without actually running anything. Best paired with -v."}, - {KeyPath: "S.PollProgressAfter", Name: "poll-progress-after", SectionKey: "debug", UsageDefaultValue: "0", - Usage: "Emit node progress reports periodically if node hasn't completed after this duration."}, - {KeyPath: "S.PollProgressInterval", Name: "poll-progress-interval", SectionKey: "debug", UsageDefaultValue: "10s", - Usage: "The rate at which to emit node progress reports after poll-progress-after has elapsed."}, - {KeyPath: "S.SourceRoots", Name: "source-root", SectionKey: "debug", - Usage: "The location to look for source code when generating progress reports. You can pass multiple --source-root flags."}, + {KeyPath: "S.EmitSpecProgress", Name: "progress", SectionKey: "debug", + Usage: "If set, ginkgo will emit progress information as each spec runs to the GinkgoWriter."}, {KeyPath: "S.Timeout", Name: "timeout", SectionKey: "debug", UsageDefaultValue: "1h", Usage: "Test suite fails if it does not complete within the specified timeout."}, - {KeyPath: "S.GracePeriod", Name: "grace-period", SectionKey: "debug", UsageDefaultValue: "30s", - Usage: "When interrupted, Ginkgo will wait for GracePeriod for the current running node to exit before moving on to the next one."}, {KeyPath: "S.OutputInterceptorMode", Name: "output-interceptor-mode", SectionKey: "debug", UsageArgument: "dup, swap, or none", Usage: "If set, ginkgo will use the specified output interception strategy when running in parallel. Defaults to dup on unix and swap on windows."}, @@ -300,8 +290,6 @@ var SuiteConfigFlags = GinkgoFlags{ {KeyPath: "D.RegexScansFilePath", DeprecatedName: "regexScansFilePath", DeprecatedDocLink: "removed--regexscansfilepath", DeprecatedVersion: "2.0.0"}, {KeyPath: "D.DebugParallel", DeprecatedName: "debug", DeprecatedDocLink: "removed--debug", DeprecatedVersion: "2.0.0"}, - {KeyPath: "D.EmitSpecProgress", DeprecatedName: "progress", SectionKey: "debug", - DeprecatedVersion: "2.5.0", Usage: ". The functionality provided by --progress was confusing and is no longer needed. Use --show-node-events instead to see node entry and exit events included in the timeline of failed and verbose specs. Or you can run with -vv to always see all node events. Lastly, --poll-progress-after and the PollProgressAfter decorator now provide a better mechanism for debugging specs that tend to get stuck."}, } // ParallelConfigFlags provides flags for the Ginkgo test process (not the CLI) @@ -318,6 +306,8 @@ var ParallelConfigFlags = GinkgoFlags{ var ReporterConfigFlags = GinkgoFlags{ {KeyPath: "R.NoColor", Name: "no-color", SectionKey: "output", DeprecatedName: "noColor", DeprecatedDocLink: "changed-command-line-flags", Usage: "If set, suppress color output in default reporter."}, + {KeyPath: "R.SlowSpecThreshold", Name: "slow-spec-threshold", SectionKey: "output", UsageArgument: "duration", UsageDefaultValue: "5s", + Usage: "Specs that take longer to run than this threshold are flagged as slow by the default reporter."}, {KeyPath: "R.Verbose", Name: "v", SectionKey: "output", Usage: "If set, emits more output including GinkgoWriter contents."}, {KeyPath: "R.VeryVerbose", Name: "vv", SectionKey: "output", @@ -326,8 +316,8 @@ var ReporterConfigFlags = GinkgoFlags{ Usage: "If set, default reporter prints out a very succinct report"}, {KeyPath: "R.FullTrace", Name: "trace", SectionKey: "output", Usage: "If set, default reporter prints out the full stack trace when a failure occurs"}, - {KeyPath: "R.ShowNodeEvents", Name: "show-node-events", SectionKey: "output", - Usage: "If set, default reporter prints node > Enter and < Exit events when specs fail"}, + {KeyPath: "R.AlwaysEmitGinkgoWriter", Name: "always-emit-ginkgo-writer", SectionKey: "output", DeprecatedName: "reportPassed", DeprecatedDocLink: "renamed--reportpassed", + Usage: "If set, default reporter prints out captured output of passed tests."}, {KeyPath: "R.JSONReport", Name: "json-report", UsageArgument: "filename.json", SectionKey: "output", Usage: "If set, Ginkgo will generate a JSON-formatted test report at the specified location."}, @@ -340,8 +330,6 @@ var ReporterConfigFlags = GinkgoFlags{ Usage: "use --slow-spec-threshold instead and pass in a duration string (e.g. '5s', not '5.0')"}, {KeyPath: "D.NoisyPendings", DeprecatedName: "noisyPendings", DeprecatedDocLink: "removed--noisypendings-and--noisyskippings", DeprecatedVersion: "2.0.0"}, {KeyPath: "D.NoisySkippings", DeprecatedName: "noisySkippings", DeprecatedDocLink: "removed--noisypendings-and--noisyskippings", DeprecatedVersion: "2.0.0"}, - {KeyPath: "D.SlowSpecThreshold", DeprecatedName: "slow-spec-threshold", SectionKey: "output", Usage: "--slow-spec-threshold has been deprecated and will be removed in a future version of Ginkgo. This feature has proved to be more noisy than useful. You can use --poll-progress-after, instead, to get more actionable feedback about potentially slow specs and understand where they might be getting stuck.", DeprecatedVersion: "2.5.0"}, - {KeyPath: "D.AlwaysEmitGinkgoWriter", DeprecatedName: "always-emit-ginkgo-writer", SectionKey: "output", Usage: " - use -v instead, or one of Ginkgo's machine-readable report formats to get GinkgoWriter output for passing specs."}, } // BuildTestSuiteFlagSet attaches to the CommandLine flagset and provides flags for the Ginkgo test process @@ -393,10 +381,6 @@ func VetConfig(flagSet GinkgoFlagSet, suiteConfig SuiteConfig, reporterConfig Re errors = append(errors, GinkgoErrors.DryRunInParallelConfiguration()) } - if suiteConfig.GracePeriod <= 0 { - errors = append(errors, GinkgoErrors.GracePeriodCannotBeZero()) - } - if len(suiteConfig.FocusFiles) > 0 { _, err := ParseFileFilters(suiteConfig.FocusFiles) if err != nil { diff --git a/vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go b/vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go index f267bdef..2948dfa0 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go @@ -83,13 +83,6 @@ func (d deprecations) Nodot() Deprecation { } } -func (d deprecations) SuppressProgressReporting() Deprecation { - return Deprecation{ - Message: "Improvements to how reporters emit timeline information means that SuppressProgressReporting is no longer necessary and has been deprecated.", - Version: "2.5.0", - } -} - type DeprecationTracker struct { deprecations map[Deprecation][]CodeLocation lock *sync.Mutex diff --git a/vendor/github.com/onsi/ginkgo/v2/types/errors.go b/vendor/github.com/onsi/ginkgo/v2/types/errors.go index b7ed5a21..40331d29 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/errors.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/errors.go @@ -180,15 +180,6 @@ func (g ginkgoErrors) InvalidDeclarationOfFocusedAndPending(cl CodeLocation, nod } } -func (g ginkgoErrors) InvalidDeclarationOfFlakeAttemptsAndMustPassRepeatedly(cl CodeLocation, nodeType NodeType) error { - return GinkgoError{ - Heading: "Invalid Combination of Decorators: FlakeAttempts and MustPassRepeatedly", - Message: formatter.F(`[%s] node was decorated with both FlakeAttempts and MustPassRepeatedly. At most one is allowed.`, nodeType), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - func (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decorator interface{}) error { return GinkgoError{ Heading: "Unknown Decorator", @@ -198,55 +189,20 @@ func (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decor } } -func (g ginkgoErrors) InvalidBodyTypeForContainer(t reflect.Type, cl CodeLocation, nodeType NodeType) error { - return GinkgoError{ - Heading: "Invalid Function", - Message: formatter.F(`[%s] node must be passed {{bold}}func(){{/}} - i.e. functions that take nothing and return nothing. You passed {{bold}}%s{{/}} instead.`, nodeType, t), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - func (g ginkgoErrors) InvalidBodyType(t reflect.Type, cl CodeLocation, nodeType NodeType) error { - mustGet := "{{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}" - if nodeType.Is(NodeTypeContainer) { - mustGet = "{{bold}}func(){{/}}" - } return GinkgoError{ Heading: "Invalid Function", - Message: formatter.F(`[%s] node must be passed `+mustGet+`. + Message: formatter.F(`[%s] node must be passed {{bold}}func(){{/}} - i.e. functions that take nothing and return nothing. You passed {{bold}}%s{{/}} instead.`, nodeType, t), CodeLocation: cl, DocLink: "node-decorators-overview", } } -func (g ginkgoErrors) InvalidBodyTypeForSynchronizedBeforeSuiteProc1(t reflect.Type, cl CodeLocation) error { - mustGet := "{{bold}}func() []byte{{/}}, {{bold}}func(ctx SpecContext) []byte{{/}}, or {{bold}}func(ctx context.Context) []byte{{/}}, {{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}" - return GinkgoError{ - Heading: "Invalid Function", - Message: formatter.F(`[SynchronizedBeforeSuite] node must be passed `+mustGet+` for its first function. -You passed {{bold}}%s{{/}} instead.`, t), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - -func (g ginkgoErrors) InvalidBodyTypeForSynchronizedBeforeSuiteAllProcs(t reflect.Type, cl CodeLocation) error { - mustGet := "{{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}, {{bold}}func([]byte){{/}}, {{bold}}func(ctx SpecContext, []byte){{/}}, or {{bold}}func(ctx context.Context, []byte){{/}}" - return GinkgoError{ - Heading: "Invalid Function", - Message: formatter.F(`[SynchronizedBeforeSuite] node must be passed `+mustGet+` for its second function. -You passed {{bold}}%s{{/}} instead.`, t), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - func (g ginkgoErrors) MultipleBodyFunctions(cl CodeLocation, nodeType NodeType) error { return GinkgoError{ Heading: "Multiple Functions", - Message: formatter.F(`[%s] node must be passed a single function - but more than one was passed in.`, nodeType), + Message: formatter.F(`[%s] node must be passed a single {{bold}}func(){{/}} - but more than one was passed in.`, nodeType), CodeLocation: cl, DocLink: "node-decorators-overview", } @@ -255,30 +211,12 @@ func (g ginkgoErrors) MultipleBodyFunctions(cl CodeLocation, nodeType NodeType) func (g ginkgoErrors) MissingBodyFunction(cl CodeLocation, nodeType NodeType) error { return GinkgoError{ Heading: "Missing Functions", - Message: formatter.F(`[%s] node must be passed a single function - but none was passed in.`, nodeType), + Message: formatter.F(`[%s] node must be passed a single {{bold}}func(){{/}} - but none was passed in.`, nodeType), CodeLocation: cl, DocLink: "node-decorators-overview", } } -func (g ginkgoErrors) InvalidTimeoutOrGracePeriodForNonContextNode(cl CodeLocation, nodeType NodeType) error { - return GinkgoError{ - Heading: "Invalid NodeTimeout SpecTimeout, or GracePeriod", - Message: formatter.F(`[%s] was passed NodeTimeout, SpecTimeout, or GracePeriod but does not have a callback that accepts a {{bold}}SpecContext{{/}} or {{bold}}context.Context{{/}}. You must accept a context to enable timeouts and grace periods`, nodeType), - CodeLocation: cl, - DocLink: "spec-timeouts-and-interruptible-nodes", - } -} - -func (g ginkgoErrors) InvalidTimeoutOrGracePeriodForNonContextCleanupNode(cl CodeLocation) error { - return GinkgoError{ - Heading: "Invalid NodeTimeout SpecTimeout, or GracePeriod", - Message: formatter.F(`[DeferCleanup] was passed NodeTimeout or GracePeriod but does not have a callback that accepts a {{bold}}SpecContext{{/}} or {{bold}}context.Context{{/}}. You must accept a context to enable timeouts and grace periods`), - CodeLocation: cl, - DocLink: "spec-timeouts-and-interruptible-nodes", - } -} - /* Ordered Container errors */ func (g ginkgoErrors) InvalidSerialNodeInNonSerialOrderedContainer(cl CodeLocation, nodeType NodeType) error { return GinkgoError{ @@ -442,15 +380,6 @@ func (g ginkgoErrors) InvalidEntryDescription(cl CodeLocation) error { } } -func (g ginkgoErrors) MissingParametersForTableFunction(cl CodeLocation) error { - return GinkgoError{ - Heading: fmt.Sprintf("No parameters have been passed to the Table Function"), - Message: fmt.Sprintf("The Table Function expected at least 1 parameter"), - CodeLocation: cl, - DocLink: "table-specs", - } -} - func (g ginkgoErrors) IncorrectParameterTypeForTable(i int, name string, cl CodeLocation) error { return GinkgoError{ Heading: "DescribeTable passed incorrect parameter type", @@ -569,13 +498,6 @@ func (g ginkgoErrors) DryRunInParallelConfiguration() error { } } -func (g ginkgoErrors) GracePeriodCannotBeZero() error { - return GinkgoError{ - Heading: "Ginkgo requires a positive --grace-period.", - Message: "Please set --grace-period to a positive duration. The default is 30s.", - } -} - func (g ginkgoErrors) ConflictingVerbosityConfiguration() error { return GinkgoError{ Heading: "Conflicting reporter verbosity settings.", @@ -610,12 +532,3 @@ func (g ginkgoErrors) BothRepeatAndUntilItFails() error { Message: "--until-it-fails directs Ginkgo to rerun specs indefinitely until they fail. --repeat directs Ginkgo to rerun specs a set number of times. You can't set both... which would you like?", } } - -/* Stack-Trace parsing errors */ - -func (g ginkgoErrors) FailedToParseStackTrace(message string) error { - return GinkgoError{ - Heading: "Failed to Parse Stack Trace", - Message: message, - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go b/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go index 7b1524b5..c64866c6 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go @@ -6,8 +6,8 @@ import ( "time" ) -// ReportEntryValue wraps a report entry's value ensuring it can be encoded and decoded safely into reports -// and across the network connection when running in parallel +//ReportEntryValue wraps a report entry's value ensuring it can be encoded and decoded safely into reports +//and across the network connection when running in parallel type ReportEntryValue struct { raw interface{} //unexported to prevent gob from freaking out about unregistered structs AsJSON string @@ -50,6 +50,7 @@ func (rev ReportEntryValue) MarshalJSON() ([]byte, error) { }{ Representation: rev.String(), } + asJSON, err := json.Marshal(rev.raw) if err != nil { return nil, err @@ -85,12 +86,10 @@ func (rev *ReportEntryValue) GobDecode(data []byte) error { type ReportEntry struct { // Visibility captures the visibility policy for this ReportEntry Visibility ReportEntryVisibility + // Time captures the time the AddReportEntry was called + Time time.Time // Location captures the location of the AddReportEntry call Location CodeLocation - - Time time.Time //need this for backwards compatibility - TimelineLocation TimelineLocation - // Name captures the name of this report Name string // Value captures the (optional) object passed into AddReportEntry - this can be @@ -99,7 +98,7 @@ type ReportEntry struct { Value ReportEntryValue } -// ColorableStringer is an interface that ReportEntry values can satisfy. If they do then ColorableString() is used to generate their representation. +// ColorableStringer is an interface that ReportEntry values can satisfy. If they do then ColorableStirng() is used to generate their representation. type ColorableStringer interface { ColorableString() string } @@ -122,10 +121,6 @@ func (entry ReportEntry) GetRawValue() interface{} { return entry.Value.GetRawValue() } -func (entry ReportEntry) GetTimelineLocation() TimelineLocation { - return entry.TimelineLocation -} - type ReportEntries []ReportEntry func (re ReportEntries) HasVisibility(visibilities ...ReportEntryVisibility) bool { diff --git a/vendor/github.com/onsi/ginkgo/v2/types/types.go b/vendor/github.com/onsi/ginkgo/v2/types/types.go index a388f70c..f30d23c6 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/types.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/types.go @@ -2,8 +2,6 @@ package types import ( "encoding/json" - "fmt" - "sort" "strings" "time" ) @@ -61,16 +59,16 @@ type Report struct { SpecReports SpecReports } -// PreRunStats contains a set of stats captured before the test run begins. This is primarily used -// by Ginkgo's reporter to tell the user how many specs are in the current suite (PreRunStats.TotalSpecs) -// and how many it intends to run (PreRunStats.SpecsThatWillRun) after applying any relevant focus or skip filters. +//PreRunStats contains a set of stats captured before the test run begins. This is primarily used +//by Ginkgo's reporter to tell the user how many specs are in the current suite (PreRunStats.TotalSpecs) +//and how many it intends to run (PreRunStats.SpecsThatWillRun) after applying any relevant focus or skip filters. type PreRunStats struct { TotalSpecs int SpecsThatWillRun int } -// Add is used by Ginkgo's parallel aggregation mechanisms to combine test run reports form individual parallel processes -// to form a complete final report. +//Add is ued by Ginkgo's parallel aggregation mechanisms to combine test run reports form individual parallel processes +//to form a complete final report. func (report Report) Add(other Report) Report { report.SuiteSucceeded = report.SuiteSucceeded && other.SuiteSucceeded @@ -149,24 +147,14 @@ type SpecReport struct { // ParallelProcess captures the parallel process that this spec ran on ParallelProcess int - // RunningInParallel captures whether this spec is part of a suite that ran in parallel - RunningInParallel bool - //Failure is populated if a spec has failed, panicked, been interrupted, or skipped by the user (e.g. calling Skip()) //It includes detailed information about the Failure Failure Failure - // NumAttempts captures the number of times this Spec was run. - // Flakey specs can be retried with ginkgo --flake-attempts=N or the use of the FlakeAttempts decorator. - // Repeated specs can be retried with the use of the MustPassRepeatedly decorator + // NumAttempts captures the number of times this Spec was run. Flakey specs can be retried with + // ginkgo --flake-attempts=N NumAttempts int - // MaxFlakeAttempts captures whether the spec has been retried with ginkgo --flake-attempts=N or the use of the FlakeAttempts decorator. - MaxFlakeAttempts int - - // MaxMustPassRepeatedly captures whether the spec has the MustPassRepeatedly decorator - MaxMustPassRepeatedly int - // CapturedGinkgoWriterOutput contains text printed to the GinkgoWriter CapturedGinkgoWriterOutput string @@ -177,15 +165,6 @@ type SpecReport struct { // ReportEntries contains any reports added via `AddReportEntry` ReportEntries ReportEntries - - // ProgressReports contains any progress reports generated during this spec. These can either be manually triggered, or automatically generated by Ginkgo via the PollProgressAfter() decorator - ProgressReports []ProgressReport - - // AdditionalFailures contains any failures that occurred after the initial spec failure. These typically occur in cleanup nodes after the initial failure and are only emitted when running in verbose mode. - AdditionalFailures []AdditionalFailure - - // SpecEvents capture additional events that occur during the spec run - SpecEvents SpecEvents } func (report SpecReport) MarshalJSON() ([]byte, error) { @@ -205,14 +184,9 @@ func (report SpecReport) MarshalJSON() ([]byte, error) { ParallelProcess int Failure *Failure `json:",omitempty"` NumAttempts int - MaxFlakeAttempts int - MaxMustPassRepeatedly int - CapturedGinkgoWriterOutput string `json:",omitempty"` - CapturedStdOutErr string `json:",omitempty"` - ReportEntries ReportEntries `json:",omitempty"` - ProgressReports []ProgressReport `json:",omitempty"` - AdditionalFailures []AdditionalFailure `json:",omitempty"` - SpecEvents SpecEvents `json:",omitempty"` + CapturedGinkgoWriterOutput string `json:",omitempty"` + CapturedStdOutErr string `json:",omitempty"` + ReportEntries ReportEntries `json:",omitempty"` }{ ContainerHierarchyTexts: report.ContainerHierarchyTexts, ContainerHierarchyLocations: report.ContainerHierarchyLocations, @@ -229,8 +203,6 @@ func (report SpecReport) MarshalJSON() ([]byte, error) { Failure: nil, ReportEntries: nil, NumAttempts: report.NumAttempts, - MaxFlakeAttempts: report.MaxFlakeAttempts, - MaxMustPassRepeatedly: report.MaxMustPassRepeatedly, CapturedGinkgoWriterOutput: report.CapturedGinkgoWriterOutput, CapturedStdOutErr: report.CapturedStdOutErr, } @@ -241,15 +213,6 @@ func (report SpecReport) MarshalJSON() ([]byte, error) { if len(report.ReportEntries) > 0 { out.ReportEntries = report.ReportEntries } - if len(report.ProgressReports) > 0 { - out.ProgressReports = report.ProgressReports - } - if len(report.AdditionalFailures) > 0 { - out.AdditionalFailures = report.AdditionalFailures - } - if len(report.SpecEvents) > 0 { - out.SpecEvents = report.SpecEvents - } return json.Marshal(out) } @@ -267,13 +230,13 @@ func (report SpecReport) CombinedOutput() string { return report.CapturedStdOutErr + "\n" + report.CapturedGinkgoWriterOutput } -// Failed returns true if report.State is one of the SpecStateFailureStates +//Failed returns true if report.State is one of the SpecStateFailureStates // (SpecStateFailed, SpecStatePanicked, SpecStateinterrupted, SpecStateAborted) func (report SpecReport) Failed() bool { return report.State.Is(SpecStateFailureStates) } -// FullText returns a concatenation of all the report.ContainerHierarchyTexts and report.LeafNodeText +//FullText returns a concatenation of all the report.ContainerHierarchyTexts and report.LeafNodeText func (report SpecReport) FullText() string { texts := []string{} texts = append(texts, report.ContainerHierarchyTexts...) @@ -283,7 +246,7 @@ func (report SpecReport) FullText() string { return strings.Join(texts, " ") } -// Labels returns a deduped set of all the spec's Labels. +//Labels returns a deduped set of all the spec's Labels. func (report SpecReport) Labels() []string { out := []string{} seen := map[string]bool{} @@ -305,7 +268,7 @@ func (report SpecReport) Labels() []string { return out } -// MatchesLabelFilter returns true if the spec satisfies the passed in label filter query +//MatchesLabelFilter returns true if the spec satisfies the passed in label filter query func (report SpecReport) MatchesLabelFilter(query string) (bool, error) { filter, err := ParseLabelFilter(query) if err != nil { @@ -314,54 +277,29 @@ func (report SpecReport) MatchesLabelFilter(query string) (bool, error) { return filter(report.Labels()), nil } -// FileName() returns the name of the file containing the spec +//FileName() returns the name of the file containing the spec func (report SpecReport) FileName() string { return report.LeafNodeLocation.FileName } -// LineNumber() returns the line number of the leaf node +//LineNumber() returns the line number of the leaf node func (report SpecReport) LineNumber() int { return report.LeafNodeLocation.LineNumber } -// FailureMessage() returns the failure message (or empty string if the test hasn't failed) +//FailureMessage() returns the failure message (or empty string if the test hasn't failed) func (report SpecReport) FailureMessage() string { return report.Failure.Message } -// FailureLocation() returns the location of the failure (or an empty CodeLocation if the test hasn't failed) +//FailureLocation() returns the location of the failure (or an empty CodeLocation if the test hasn't failed) func (report SpecReport) FailureLocation() CodeLocation { return report.Failure.Location } -// Timeline() returns a timeline view of the report -func (report SpecReport) Timeline() Timeline { - timeline := Timeline{} - if !report.Failure.IsZero() { - timeline = append(timeline, report.Failure) - if report.Failure.AdditionalFailure != nil { - timeline = append(timeline, *(report.Failure.AdditionalFailure)) - } - } - for _, additionalFailure := range report.AdditionalFailures { - timeline = append(timeline, additionalFailure) - } - for _, reportEntry := range report.ReportEntries { - timeline = append(timeline, reportEntry) - } - for _, progressReport := range report.ProgressReports { - timeline = append(timeline, progressReport) - } - for _, specEvent := range report.SpecEvents { - timeline = append(timeline, specEvent) - } - sort.Sort(timeline) - return timeline -} - type SpecReports []SpecReport -// WithLeafNodeType returns the subset of SpecReports with LeafNodeType matching one of the requested NodeTypes +//WithLeafNodeType returns the subset of SpecReports with LeafNodeType matching one of the requested NodeTypes func (reports SpecReports) WithLeafNodeType(nodeTypes NodeType) SpecReports { count := 0 for i := range reports { @@ -381,7 +319,7 @@ func (reports SpecReports) WithLeafNodeType(nodeTypes NodeType) SpecReports { return out } -// WithState returns the subset of SpecReports with State matching one of the requested SpecStates +//WithState returns the subset of SpecReports with State matching one of the requested SpecStates func (reports SpecReports) WithState(states SpecState) SpecReports { count := 0 for i := range reports { @@ -400,7 +338,7 @@ func (reports SpecReports) WithState(states SpecState) SpecReports { return out } -// CountWithState returns the number of SpecReports with State matching one of the requested SpecStates +//CountWithState returns the number of SpecReports with State matching one of the requested SpecStates func (reports SpecReports) CountWithState(states SpecState) int { n := 0 for i := range reports { @@ -411,75 +349,17 @@ func (reports SpecReports) CountWithState(states SpecState) int { return n } -// If the Spec passes, CountOfFlakedSpecs returns the number of SpecReports that failed after multiple attempts. +//CountWithState returns the number of SpecReports that passed after multiple attempts func (reports SpecReports) CountOfFlakedSpecs() int { n := 0 for i := range reports { - if reports[i].MaxFlakeAttempts > 1 && reports[i].State.Is(SpecStatePassed) && reports[i].NumAttempts > 1 { + if reports[i].State.Is(SpecStatePassed) && reports[i].NumAttempts > 1 { n += 1 } } return n } -// If the Spec fails, CountOfRepeatedSpecs returns the number of SpecReports that passed after multiple attempts -func (reports SpecReports) CountOfRepeatedSpecs() int { - n := 0 - for i := range reports { - if reports[i].MaxMustPassRepeatedly > 1 && reports[i].State.Is(SpecStateFailureStates) && reports[i].NumAttempts > 1 { - n += 1 - } - } - return n -} - -// TimelineLocation captures the location of an event in the spec's timeline -type TimelineLocation struct { - //Offset is the offset (in bytes) of the event relative to the GinkgoWriter stream - Offset int `json:",omitempty"` - - //Order is the order of the event with respect to other events. The absolute value of Order - //is irrelevant. All that matters is that an event with a lower Order occurs before ane vent with a higher Order - Order int `json:",omitempty"` - - Time time.Time -} - -// TimelineEvent represent an event on the timeline -// consumers of Timeline will need to check the concrete type of each entry to determine how to handle it -type TimelineEvent interface { - GetTimelineLocation() TimelineLocation -} - -type Timeline []TimelineEvent - -func (t Timeline) Len() int { return len(t) } -func (t Timeline) Less(i, j int) bool { - return t[i].GetTimelineLocation().Order < t[j].GetTimelineLocation().Order -} -func (t Timeline) Swap(i, j int) { t[i], t[j] = t[j], t[i] } -func (t Timeline) WithoutHiddenReportEntries() Timeline { - out := Timeline{} - for _, event := range t { - if reportEntry, isReportEntry := event.(ReportEntry); isReportEntry && reportEntry.Visibility == ReportEntryVisibilityNever { - continue - } - out = append(out, event) - } - return out -} - -func (t Timeline) WithoutVeryVerboseSpecEvents() Timeline { - out := Timeline{} - for _, event := range t { - if specEvent, isSpecEvent := event.(SpecEvent); isSpecEvent && specEvent.IsOnlyVisibleAtVeryVerbose() { - continue - } - out = append(out, event) - } - return out -} - // Failure captures failure information for an individual test type Failure struct { // Message - the failure message passed into Fail(...). When using a matcher library @@ -492,8 +372,6 @@ type Failure struct { // This CodeLocation will include a fully-populated StackTrace Location CodeLocation - TimelineLocation TimelineLocation - // ForwardedPanic - if the failure represents a captured panic (i.e. Summary.State == SpecStatePanicked) // then ForwardedPanic will be populated with a string representation of the captured panic. ForwardedPanic string `json:",omitempty"` @@ -501,32 +379,19 @@ type Failure struct { // FailureNodeContext - one of three contexts describing the node in which the failure occurred: // FailureNodeIsLeafNode means the failure occurred in the leaf node of the associated SpecReport. None of the other FailureNode fields will be populated // FailureNodeAtTopLevel means the failure occurred in a non-leaf node that is defined at the top-level of the spec (i.e. not in a container). FailureNodeType and FailureNodeLocation will be populated. - // FailureNodeInContainer means the failure occurred in a non-leaf node that is defined within a container. FailureNodeType, FailureNodeLocation, and FailureNodeContainerIndex will be populated. + // FailureNodeInContainer means the failure occurred in a non-leaf node that is defined within a container. FailureNodeType, FailureNodeLocaiton, and FailureNodeContainerIndex will be populated. // // FailureNodeType will contain the NodeType of the node in which the failure occurred. // FailureNodeLocation will contain the CodeLocation of the node in which the failure occurred. // If populated, FailureNodeContainerIndex will be the index into SpecReport.ContainerHierarchyTexts and SpecReport.ContainerHierarchyLocations that represents the parent container of the node in which the failure occurred. - FailureNodeContext FailureNodeContext `json:",omitempty"` - - FailureNodeType NodeType `json:",omitempty"` - - FailureNodeLocation CodeLocation `json:",omitempty"` - - FailureNodeContainerIndex int `json:",omitempty"` - - //ProgressReport is populated if the spec was interrupted or timed out - ProgressReport ProgressReport `json:",omitempty"` - - //AdditionalFailure is non-nil if a follow-on failure occurred within the same node after the primary failure. This only happens when a node has timed out or been interrupted. In such cases the AdditionalFailure can include information about where/why the spec was stuck. - AdditionalFailure *AdditionalFailure `json:",omitempty"` + FailureNodeContext FailureNodeContext + FailureNodeType NodeType + FailureNodeLocation CodeLocation + FailureNodeContainerIndex int } func (f Failure) IsZero() bool { - return f.Message == "" && (f.Location == CodeLocation{}) -} - -func (f Failure) GetTimelineLocation() TimelineLocation { - return f.TimelineLocation + return f == Failure{} } // FailureNodeContext captures the location context for the node containing the failing line of code @@ -559,18 +424,6 @@ func (fnc FailureNodeContext) MarshalJSON() ([]byte, error) { return fncEnumSupport.MarshJSON(uint(fnc)) } -// AdditionalFailure capturs any additional failures that occur after the initial failure of a psec -// these typically occur in clean up nodes after the spec has failed. -// We can't simply use Failure as we want to track the SpecState to know what kind of failure this is -type AdditionalFailure struct { - State SpecState - Failure Failure -} - -func (f AdditionalFailure) GetTimelineLocation() TimelineLocation { - return f.Failure.TimelineLocation -} - // SpecState captures the state of a spec // To determine if a given `state` represents a failure state, use `state.Is(SpecStateFailureStates)` type SpecState uint @@ -585,7 +438,6 @@ const ( SpecStateAborted SpecStatePanicked SpecStateInterrupted - SpecStateTimedout ) var ssEnumSupport = NewEnumSupport(map[uint]string{ @@ -597,7 +449,6 @@ var ssEnumSupport = NewEnumSupport(map[uint]string{ uint(SpecStateAborted): "aborted", uint(SpecStatePanicked): "panicked", uint(SpecStateInterrupted): "interrupted", - uint(SpecStateTimedout): "timedout", }) func (ss SpecState) String() string { @@ -612,131 +463,12 @@ func (ss SpecState) MarshalJSON() ([]byte, error) { return ssEnumSupport.MarshJSON(uint(ss)) } -var SpecStateFailureStates = SpecStateFailed | SpecStateTimedout | SpecStateAborted | SpecStatePanicked | SpecStateInterrupted +var SpecStateFailureStates = SpecStateFailed | SpecStateAborted | SpecStatePanicked | SpecStateInterrupted func (ss SpecState) Is(states SpecState) bool { return ss&states != 0 } -// ProgressReport captures the progress of the current spec. It is, effectively, a structured Ginkgo-aware stack trace -type ProgressReport struct { - Message string `json:",omitempty"` - ParallelProcess int `json:",omitempty"` - RunningInParallel bool `json:",omitempty"` - - ContainerHierarchyTexts []string `json:",omitempty"` - LeafNodeText string `json:",omitempty"` - LeafNodeLocation CodeLocation `json:",omitempty"` - SpecStartTime time.Time `json:",omitempty"` - - CurrentNodeType NodeType `json:",omitempty"` - CurrentNodeText string `json:",omitempty"` - CurrentNodeLocation CodeLocation `json:",omitempty"` - CurrentNodeStartTime time.Time `json:",omitempty"` - - CurrentStepText string `json:",omitempty"` - CurrentStepLocation CodeLocation `json:",omitempty"` - CurrentStepStartTime time.Time `json:",omitempty"` - - AdditionalReports []string `json:",omitempty"` - - CapturedGinkgoWriterOutput string `json:",omitempty"` - TimelineLocation TimelineLocation `json:",omitempty"` - - Goroutines []Goroutine `json:",omitempty"` -} - -func (pr ProgressReport) IsZero() bool { - return pr.CurrentNodeType == NodeTypeInvalid -} - -func (pr ProgressReport) Time() time.Time { - return pr.TimelineLocation.Time -} - -func (pr ProgressReport) SpecGoroutine() Goroutine { - for _, goroutine := range pr.Goroutines { - if goroutine.IsSpecGoroutine { - return goroutine - } - } - return Goroutine{} -} - -func (pr ProgressReport) HighlightedGoroutines() []Goroutine { - out := []Goroutine{} - for _, goroutine := range pr.Goroutines { - if goroutine.IsSpecGoroutine || !goroutine.HasHighlights() { - continue - } - out = append(out, goroutine) - } - return out -} - -func (pr ProgressReport) OtherGoroutines() []Goroutine { - out := []Goroutine{} - for _, goroutine := range pr.Goroutines { - if goroutine.IsSpecGoroutine || goroutine.HasHighlights() { - continue - } - out = append(out, goroutine) - } - return out -} - -func (pr ProgressReport) WithoutCapturedGinkgoWriterOutput() ProgressReport { - out := pr - out.CapturedGinkgoWriterOutput = "" - return out -} - -func (pr ProgressReport) WithoutOtherGoroutines() ProgressReport { - out := pr - filteredGoroutines := []Goroutine{} - for _, goroutine := range pr.Goroutines { - if goroutine.IsSpecGoroutine || goroutine.HasHighlights() { - filteredGoroutines = append(filteredGoroutines, goroutine) - } - } - out.Goroutines = filteredGoroutines - return out -} - -func (pr ProgressReport) GetTimelineLocation() TimelineLocation { - return pr.TimelineLocation -} - -type Goroutine struct { - ID uint64 - State string - Stack []FunctionCall - IsSpecGoroutine bool -} - -func (g Goroutine) IsZero() bool { - return g.ID == 0 -} - -func (g Goroutine) HasHighlights() bool { - for _, fc := range g.Stack { - if fc.Highlight { - return true - } - } - - return false -} - -type FunctionCall struct { - Function string - Filename string - Line int - Highlight bool `json:",omitempty"` - Source []string `json:",omitempty"` - SourceHighlight int `json:",omitempty"` -} - // NodeType captures the type of a given Ginkgo Node type NodeType uint @@ -771,8 +503,6 @@ const ( var NodeTypesForContainerAndIt = NodeTypeContainer | NodeTypeIt var NodeTypesForSuiteLevelNodes = NodeTypeBeforeSuite | NodeTypeSynchronizedBeforeSuite | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeReportAfterSuite | NodeTypeCleanupAfterSuite -var NodeTypesAllowedDuringCleanupInterrupt = NodeTypeAfterEach | NodeTypeJustAfterEach | NodeTypeAfterAll | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeCleanupAfterEach | NodeTypeCleanupAfterAll | NodeTypeCleanupAfterSuite -var NodeTypesAllowedDuringReportInterrupt = NodeTypeReportBeforeEach | NodeTypeReportAfterEach | NodeTypeReportAfterSuite var ntEnumSupport = NewEnumSupport(map[uint]string{ uint(NodeTypeInvalid): "INVALID NODE TYPE", @@ -791,8 +521,8 @@ var ntEnumSupport = NewEnumSupport(map[uint]string{ uint(NodeTypeReportBeforeEach): "ReportBeforeEach", uint(NodeTypeReportAfterEach): "ReportAfterEach", uint(NodeTypeReportAfterSuite): "ReportAfterSuite", - uint(NodeTypeCleanupInvalid): "DeferCleanup", - uint(NodeTypeCleanupAfterEach): "DeferCleanup (Each)", + uint(NodeTypeCleanupInvalid): "INVALID CLEANUP NODE", + uint(NodeTypeCleanupAfterEach): "DeferCleanup", uint(NodeTypeCleanupAfterAll): "DeferCleanup (All)", uint(NodeTypeCleanupAfterSuite): "DeferCleanup (Suite)", }) @@ -812,99 +542,3 @@ func (nt NodeType) MarshalJSON() ([]byte, error) { func (nt NodeType) Is(nodeTypes NodeType) bool { return nt&nodeTypes != 0 } - -/* -SpecEvent captures a vareity of events that can occur when specs run. See SpecEventType for the list of available events. -*/ -type SpecEvent struct { - SpecEventType SpecEventType - - CodeLocation CodeLocation - TimelineLocation TimelineLocation - - Message string `json:",omitempty"` - Duration time.Duration `json:",omitempty"` - NodeType NodeType `json:",omitempty"` - Attempt int `json:",omitempty"` -} - -func (se SpecEvent) GetTimelineLocation() TimelineLocation { - return se.TimelineLocation -} - -func (se SpecEvent) IsOnlyVisibleAtVeryVerbose() bool { - return se.SpecEventType.Is(SpecEventByEnd | SpecEventNodeStart | SpecEventNodeEnd) -} - -func (se SpecEvent) GomegaString() string { - out := &strings.Builder{} - out.WriteString("[" + se.SpecEventType.String() + " SpecEvent] ") - if se.Message != "" { - out.WriteString("Message=") - out.WriteString(`"` + se.Message + `",`) - } - if se.Duration != 0 { - out.WriteString("Duration=" + se.Duration.String() + ",") - } - if se.NodeType != NodeTypeInvalid { - out.WriteString("NodeType=" + se.NodeType.String() + ",") - } - if se.Attempt != 0 { - out.WriteString(fmt.Sprintf("Attempt=%d", se.Attempt) + ",") - } - out.WriteString("CL=" + se.CodeLocation.String() + ",") - out.WriteString(fmt.Sprintf("TL.Offset=%d", se.TimelineLocation.Offset)) - - return out.String() -} - -type SpecEvents []SpecEvent - -func (se SpecEvents) WithType(seType SpecEventType) SpecEvents { - out := SpecEvents{} - for _, event := range se { - if event.SpecEventType.Is(seType) { - out = append(out, event) - } - } - return out -} - -type SpecEventType uint - -const ( - SpecEventInvalid SpecEventType = 0 - - SpecEventByStart SpecEventType = 1 << iota - SpecEventByEnd - SpecEventNodeStart - SpecEventNodeEnd - SpecEventSpecRepeat - SpecEventSpecRetry -) - -var seEnumSupport = NewEnumSupport(map[uint]string{ - uint(SpecEventInvalid): "INVALID SPEC EVENT", - uint(SpecEventByStart): "By", - uint(SpecEventByEnd): "By (End)", - uint(SpecEventNodeStart): "Node", - uint(SpecEventNodeEnd): "Node (End)", - uint(SpecEventSpecRepeat): "Repeat", - uint(SpecEventSpecRetry): "Retry", -}) - -func (se SpecEventType) String() string { - return seEnumSupport.String(uint(se)) -} -func (se *SpecEventType) UnmarshalJSON(b []byte) error { - out, err := seEnumSupport.UnmarshJSON(b) - *se = SpecEventType(out) - return err -} -func (se SpecEventType) MarshalJSON() ([]byte, error) { - return seEnumSupport.MarshJSON(uint(se)) -} - -func (se SpecEventType) Is(specEventTypes SpecEventType) bool { - return se&specEventTypes != 0 -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go index 7745c9a7..f4015031 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/version.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.5.1" +const VERSION = "2.1.4" diff --git a/vendor/github.com/onsi/gomega/.gitignore b/vendor/github.com/onsi/gomega/.gitignore index 5f12ff05..720c13cb 100644 --- a/vendor/github.com/onsi/gomega/.gitignore +++ b/vendor/github.com/onsi/gomega/.gitignore @@ -3,4 +3,3 @@ . .idea gomega.iml -TODO.md \ No newline at end of file diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md index 5ebd74a5..5bbf7a1b 100644 --- a/vendor/github.com/onsi/gomega/CHANGELOG.md +++ b/vendor/github.com/onsi/gomega/CHANGELOG.md @@ -1,109 +1,3 @@ -## 1.24.1 - -### Fixes -- maintain backward compatibility for Eventually and Consisntetly's signatures [4c7df5e] -- fix small typo (#601) [ea0ebe6] - -### Maintenance -- Bump golang.org/x/net from 0.1.0 to 0.2.0 (#603) [1ba8372] -- Bump github.com/onsi/ginkgo/v2 from 2.4.0 to 2.5.0 (#602) [f9426cb] -- fix label-filter in test.yml [d795db6] -- stop running flakey tests and rely on external network dependencies in CI [7133290] - -## 1.24.0 - -### Features - -Introducting [gcustom](https://onsi.github.io/gomega/#gcustom-a-convenient-mechanism-for-buildling-custom-matchers) - a convenient mechanism for building custom matchers. - -This is an RC release for `gcustom`. The external API may be tweaked in response to feedback however it is expected to remain mostly stable. - -### Maintenance - -- Update BeComparableTo documentation [756eaa0] - -## 1.23.0 - -### Features -- Custom formatting on a per-type basis can be provided using `format.RegisterCustomFormatter()` -- see the docs [here](https://onsi.github.io/gomega/#adjusting-output) - -- Substantial improvement have been made to `StopTrying()`: - - Users can now use `StopTrying().Wrap(err)` to wrap errors and `StopTrying().Attach(description, object)` to attach arbitrary objects to the `StopTrying()` error - - `StopTrying()` is now always interpreted as a failure. If you are an early adopter of `StopTrying()` you may need to change your code as the prior version would match against the returned value even if `StopTrying()` was returned. Going forward the `StopTrying()` api should remain stable. - - `StopTrying()` and `StopTrying().Now()` can both be used in matchers - not just polled functions. - -- `TryAgainAfter(duration)` is used like `StopTrying()` but instructs `Eventually` and `Consistently` that the poll should be tried again after the specified duration. This allows you to dynamically adjust the polling duration. - -- `ctx` can now be passed-in as the first argument to `Eventually` and `Consistently`. - -## Maintenance - -- Bump github.com/onsi/ginkgo/v2 from 2.3.0 to 2.3.1 (#597) [afed901] -- Bump nokogiri from 1.13.8 to 1.13.9 in /docs (#599) [7c691b3] -- Bump github.com/google/go-cmp from 0.5.8 to 0.5.9 (#587) [ff22665] - -## 1.22.1 - -## Fixes -- When passed a context and no explicit timeout, Eventually will only timeout when the context is cancelled [e5105cf] -- Allow StopTrying() to be wrapped [bf3cba9] - -## Maintenance -- bump to ginkgo v2.3.0 [c5d5c39] - -## 1.22.0 - -### Features - -Several improvements have been made to `Eventually` and `Consistently` in this and the most recent releases: - -- Eventually and Consistently can take a context.Context [65c01bc] - This enables integration with Ginkgo 2.3.0's interruptible nodes and node timeouts. -- Eventually and Consistently that are passed a SpecContext can provide reports when an interrupt occurs [0d063c9] -- Eventually/Consistently will forward an attached context to functions that ask for one [e2091c5] -- Eventually/Consistently supports passing arguments to functions via WithArguments() [a2dc7c3] -- Eventually and Consistently can now be stopped early with StopTrying(message) and StopTrying(message).Now() [52976bb] - -These improvements are all documented in [Gomega's docs](https://onsi.github.io/gomega/#making-asynchronous-assertions) - -## Fixes - -## Maintenance - -## 1.21.1 - -### Features -- Eventually and Consistently that are passed a SpecContext can provide reports when an interrupt occurs [0d063c9] - -## 1.21.0 - -### Features -- Eventually and Consistently can take a context.Context [65c01bc] - This enables integration with Ginkgo 2.3.0's interruptible nodes and node timeouts. -- Introduces Eventually.Within.ProbeEvery with tests and documentation (#591) [f633800] -- New BeKeyOf matcher with documentation and unit tests (#590) [fb586b3] - -## Fixes -- Cover the entire gmeasure suite with leak detection [8c54344] -- Fix gmeasure leak [119d4ce] -- Ignore new Ginkgo ProgressSignal goroutine in gleak [ba548e2] - -## Maintenance - -- Fixes crashes on newer Ruby 3 installations by upgrading github-pages gem dependency (#596) [12469a0] - - -## 1.20.2 - -## Fixes -- label specs that rely on remote access; bump timeout on short-circuit test to make it less flaky [35eeadf] -- gexec: allow more headroom for SIGABRT-related unit tests (#581) [5b78f40] -- Enable reading from a closed gbytes.Buffer (#575) [061fd26] - -## Maintenance -- Bump github.com/onsi/ginkgo/v2 from 2.1.5 to 2.1.6 (#583) [55d895b] -- Bump github.com/onsi/ginkgo/v2 from 2.1.4 to 2.1.5 (#582) [346de7c] - ## 1.20.1 ## Fixes diff --git a/vendor/github.com/onsi/gomega/RELEASING.md b/vendor/github.com/onsi/gomega/RELEASING.md index 9973fff4..2d30d999 100644 --- a/vendor/github.com/onsi/gomega/RELEASING.md +++ b/vendor/github.com/onsi/gomega/RELEASING.md @@ -1,13 +1,7 @@ A Gomega release is a tagged sha and a GitHub release. To cut a release: 1. Ensure CHANGELOG.md is up to date. - - Use - ```bash - LAST_VERSION=$(git tag --sort=version:refname | tail -n1) - CHANGES=$(git log --pretty=format:'- %s [%h]' HEAD...$LAST_VERSION) - echo -e "## NEXT\n\n$CHANGES\n\n### Features\n\n### Fixes\n\n### Maintenance\n\n$(cat CHANGELOG.md)" > CHANGELOG.md - ``` - to update the changelog + - Use `git log --pretty=format:'- %s [%h]' HEAD...vX.X.X` to list all the commits since the last release - Categorize the changes into - Breaking Changes (requires a major version) - New Features (minor version) diff --git a/vendor/github.com/onsi/gomega/format/format.go b/vendor/github.com/onsi/gomega/format/format.go index 1a2ed877..6e78c391 100644 --- a/vendor/github.com/onsi/gomega/format/format.go +++ b/vendor/github.com/onsi/gomega/format/format.go @@ -65,52 +65,6 @@ type GomegaStringer interface { GomegaString() string } -/* -CustomFormatters can be registered with Gomega via RegisterCustomFormatter() -Any value to be rendered by Gomega is passed to each registered CustomFormatters. -The CustomFormatter signals that it will handle formatting the value by returning (formatted-string, true) -If the CustomFormatter does not want to handle the object it should return ("", false) - -Strings returned by CustomFormatters are not truncated -*/ -type CustomFormatter func(value interface{}) (string, bool) -type CustomFormatterKey uint - -var customFormatterKey CustomFormatterKey = 1 - -type customFormatterKeyPair struct { - CustomFormatter - CustomFormatterKey -} - -/* -RegisterCustomFormatter registers a CustomFormatter and returns a CustomFormatterKey - -You can call UnregisterCustomFormatter with the returned key to unregister the associated CustomFormatter -*/ -func RegisterCustomFormatter(customFormatter CustomFormatter) CustomFormatterKey { - key := customFormatterKey - customFormatterKey += 1 - customFormatters = append(customFormatters, customFormatterKeyPair{customFormatter, key}) - return key -} - -/* -UnregisterCustomFormatter unregisters a previously registered CustomFormatter. You should pass in the key returned by RegisterCustomFormatter -*/ -func UnregisterCustomFormatter(key CustomFormatterKey) { - formatters := []customFormatterKeyPair{} - for _, f := range customFormatters { - if f.CustomFormatterKey == key { - continue - } - formatters = append(formatters, f) - } - customFormatters = formatters -} - -var customFormatters = []customFormatterKeyPair{} - /* Generates a formatted matcher success/failure message of the form: @@ -265,24 +219,17 @@ func Object(object interface{}, indentation uint) string { IndentString takes a string and indents each line by the specified amount. */ func IndentString(s string, indentation uint) string { - return indentString(s, indentation, true) -} - -func indentString(s string, indentation uint, indentFirstLine bool) string { - result := &strings.Builder{} components := strings.Split(s, "\n") + result := "" indent := strings.Repeat(Indent, int(indentation)) for i, component := range components { - if i > 0 || indentFirstLine { - result.WriteString(indent) - } - result.WriteString(component) + result += indent + component if i < len(components)-1 { - result.WriteString("\n") + result += "\n" } } - return result.String() + return result } func formatType(v reflect.Value) string { @@ -314,27 +261,18 @@ func formatValue(value reflect.Value, indentation uint) string { if value.CanInterface() { obj := value.Interface() - // if a CustomFormatter handles this values, we'll go with that - for _, customFormatter := range customFormatters { - formatted, handled := customFormatter.CustomFormatter(obj) - // do not truncate a user-provided CustomFormatter() - if handled { - return indentString(formatted, indentation+1, false) - } - } - // GomegaStringer will take precedence to other representations and disregards UseStringerRepresentation if x, ok := obj.(GomegaStringer); ok { - // do not truncate a user-defined GomegaString() value - return indentString(x.GomegaString(), indentation+1, false) + // do not truncate a user-defined GoMegaString() value + return x.GomegaString() } if UseStringerRepresentation { switch x := obj.(type) { case fmt.GoStringer: - return indentString(truncateLongStrings(x.GoString()), indentation+1, false) + return truncateLongStrings(x.GoString()) case fmt.Stringer: - return indentString(truncateLongStrings(x.String()), indentation+1, false) + return truncateLongStrings(x.String()) } } } diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go index d00383e1..996dae8f 100644 --- a/vendor/github.com/onsi/gomega/gomega_dsl.go +++ b/vendor/github.com/onsi/gomega/gomega_dsl.go @@ -22,7 +22,7 @@ import ( "github.com/onsi/gomega/types" ) -const GOMEGA_VERSION = "1.24.1" +const GOMEGA_VERSION = "1.20.1" const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler. If you're using Ginkgo then you probably forgot to put your assertion in an It(). @@ -86,12 +86,12 @@ func internalGomega(g Gomega) *internal.Gomega { // NewWithT takes a *testing.T and returns a `gomega.WithT` allowing you to use `Expect`, `Eventually`, and `Consistently` along with // Gomega's rich ecosystem of matchers in standard `testing` test suits. // -// func TestFarmHasCow(t *testing.T) { -// g := gomega.NewWithT(t) +// func TestFarmHasCow(t *testing.T) { +// g := gomega.NewWithT(t) // -// f := farm.New([]string{"Cow", "Horse"}) -// g.Expect(f.HasCow()).To(BeTrue(), "Farm should have cow") -// } +// f := farm.New([]string{"Cow", "Horse"}) +// g.Expect(f.HasCow()).To(BeTrue(), "Farm should have cow") +// } func NewWithT(t types.GomegaTestingT) *WithT { return internal.NewGomega(internalGomega(Default).DurationBundle).ConfigureWithT(t) } @@ -171,8 +171,7 @@ func ensureDefaultGomegaIsConfigured() { } // Ω wraps an actual value allowing assertions to be made on it: -// -// Ω("foo").Should(Equal("foo")) +// Ω("foo").Should(Equal("foo")) // // If Ω is passed more than one argument it will pass the *first* argument to the matcher. // All subsequent arguments will be required to be nil/zero. @@ -181,13 +180,10 @@ func ensureDefaultGomegaIsConfigured() { // a value and an error - a common patter in Go. // // For example, given a function with signature: -// -// func MyAmazingThing() (int, error) +// func MyAmazingThing() (int, error) // // Then: -// -// Ω(MyAmazingThing()).Should(Equal(3)) -// +// Ω(MyAmazingThing()).Should(Equal(3)) // Will succeed only if `MyAmazingThing()` returns `(3, nil)` // // Ω and Expect are identical @@ -197,8 +193,7 @@ func Ω(actual interface{}, extra ...interface{}) Assertion { } // Expect wraps an actual value allowing assertions to be made on it: -// -// Expect("foo").To(Equal("foo")) +// Expect("foo").To(Equal("foo")) // // If Expect is passed more than one argument it will pass the *first* argument to the matcher. // All subsequent arguments will be required to be nil/zero. @@ -207,13 +202,10 @@ func Ω(actual interface{}, extra ...interface{}) Assertion { // a value and an error - a common patter in Go. // // For example, given a function with signature: -// -// func MyAmazingThing() (int, error) +// func MyAmazingThing() (int, error) // // Then: -// -// Expect(MyAmazingThing()).Should(Equal(3)) -// +// Expect(MyAmazingThing()).Should(Equal(3)) // Will succeed only if `MyAmazingThing()` returns `(3, nil)` // // Expect and Ω are identical @@ -223,8 +215,7 @@ func Expect(actual interface{}, extra ...interface{}) Assertion { } // ExpectWithOffset wraps an actual value allowing assertions to be made on it: -// -// ExpectWithOffset(1, "foo").To(Equal("foo")) +// ExpectWithOffset(1, "foo").To(Equal("foo")) // // Unlike `Expect` and `Ω`, `ExpectWithOffset` takes an additional integer argument // that is used to modify the call-stack offset when computing line numbers. It is @@ -242,7 +233,7 @@ func ExpectWithOffset(offset int, actual interface{}, extra ...interface{}) Asse Eventually enables making assertions on asynchronous behavior. Eventually checks that an assertion *eventually* passes. Eventually blocks when called and attempts an assertion periodically until it passes or a timeout occurs. Both the timeout and polling interval are configurable as optional arguments. -The first optional argument is the timeout (which defaults to 1s), the second is the polling interval (which defaults to 10ms). Both intervals can be specified as time.Duration, parsable duration strings or floats/integers (in which case they are interpreted as seconds). In addition an optional context.Context can be passed in - Eventually will keep trying until either the timeout epxires or the context is cancelled, whichever comes first. +The first optional argument is the timeout (which defaults to 1s), the second is the polling interval (which defaults to 10ms). Both intervals can be specified as time.Duration, parsable duration strings or floats/integers (in which case they are interpreted as seconds). Eventually works with any Gomega compatible matcher and supports making assertions against three categories of actual value: @@ -250,15 +241,15 @@ Eventually works with any Gomega compatible matcher and supports making assertio There are several examples of values that can change over time. These can be passed in to Eventually and will be passed to the matcher repeatedly until a match occurs. For example: - c := make(chan bool) - go DoStuff(c) - Eventually(c, "50ms").Should(BeClosed()) + c := make(chan bool) + go DoStuff(c) + Eventually(c, "50ms").Should(BeClosed()) will poll the channel repeatedly until it is closed. In this example `Eventually` will block until either the specified timeout of 50ms has elapsed or the channel is closed, whichever comes first. Several Gomega libraries allow you to use Eventually in this way. For example, the gomega/gexec package allows you to block until a *gexec.Session exits successfully via: - Eventually(session).Should(gexec.Exit(0)) + Eventually(session).Should(gexec.Exit(0)) And the gomega/gbytes package allows you to monitor a streaming *gbytes.Buffer until a given string is seen: @@ -275,51 +266,27 @@ this will trigger Go's race detector as the goroutine polling via Eventually wil **Category 2: Make Eventually assertions on functions** -Eventually can be passed functions that **return at least one value**. When configured this way, Eventually will poll the function repeatedly and pass the first returned value to the matcher. +Eventually can be passed functions that **take no arguments** and **return at least one value**. When configured this way, Eventually will poll the function repeatedly and pass the first returned value to the matcher. For example: - Eventually(func() int { - return client.FetchCount() - }).Should(BeNumerically(">=", 17)) + Eventually(func() int { + return client.FetchCount() + }).Should(BeNumerically(">=", 17)) - will repeatedly poll client.FetchCount until the BeNumerically matcher is satisfied. (Note that this example could have been written as Eventually(client.FetchCount).Should(BeNumerically(">=", 17))) + will repeatedly poll client.FetchCount until the BeNumerically matcher is satisfied. (Note that this example could have been written as Eventually(client.FetchCount).Should(BeNumerically(">=", 17))) If multiple values are returned by the function, Eventually will pass the first value to the matcher and require that all others are zero-valued. This allows you to pass Eventually a function that returns a value and an error - a common pattern in Go. For example, consider a method that returns a value and an error: - - func FetchFromDB() (string, error) + func FetchFromDB() (string, error) Then - - Eventually(FetchFromDB).Should(Equal("got it")) + Eventually(FetchFromDB).Should(Equal("got it")) will pass only if and when the returned error is nil *and* the returned string satisfies the matcher. -Eventually can also accept functions that take arguments, however you must provide those arguments using .WithArguments(). For example, consider a function that takes a user-id and makes a network request to fetch a full name: - - func FetchFullName(userId int) (string, error) - -You can poll this function like so: - - Eventually(FetchFullName).WithArguments(1138).Should(Equal("Wookie")) - -It is important to note that the function passed into Eventually is invoked *synchronously* when polled. Eventually does not (in fact, it cannot) kill the function if it takes longer to return than Eventually's configured timeout. A common practice here is to use a context. Here's an example that combines Ginkgo's spec timeout support with Eventually: - - It("fetches the correct count", func(ctx SpecContext) { - Eventually(ctx, func() int { - return client.FetchCount(ctx, "/users") - }).Should(BeNumerically(">=", 17)) - }, SpecTimeout(time.Second)) - -you an also use Eventually().WithContext(ctx) to pass in the context. Passed-in contexts play nicely with paseed-in arguments as long as the context appears first. You can rewrite the above example as: - - It("fetches the correct count", func(ctx SpecContext) { - Eventually(client.FetchCount).WithContext(ctx).WithArguments("/users").Should(BeNumerically(">=", 17)) - }, SpecTimeout(time.Second)) - -Either way the context passd to Eventually is also passed to the underlying funciton. Now, when Ginkgo cancels the context both the FetchCount client and Gomega will be informed and can exit. +It is important to note that the function passed into Eventually is invoked *synchronously* when polled. Eventually does not (in fact, it cannot) kill the function if it takes longer to return than Eventually's configured timeout. You should design your functions with this in mind. **Category 3: Making assertions _in_ the function passed into Eventually** @@ -339,38 +306,22 @@ will pass only if all the assertions in the polled function pass and the return Eventually also supports a special case polling function that takes a single Gomega argument and returns no values. Eventually assumes such a function is making assertions and is designed to work with the Succeed matcher to validate that all assertions have passed. For example: - Eventually(func(g Gomega) { - model, err := client.Find(1138) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(model.Reticulate()).To(Succeed()) - g.Expect(model.IsReticulated()).To(BeTrue()) - g.Expect(model.Save()).To(Succeed()) - }).Should(Succeed()) + Eventually(func(g Gomega) { + model, err := client.Find(1138) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(model.Reticulate()).To(Succeed()) + g.Expect(model.IsReticulated()).To(BeTrue()) + g.Expect(model.Save()).To(Succeed()) + }).Should(Succeed()) will rerun the function until all assertions pass. -You can also pass additional arugments to functions that take a Gomega. The only rule is that the Gomega argument must be first. If you also want to pass the context attached to Eventually you must ensure that is the second argument. For example: - - Eventually(func(g Gomega, ctx context.Context, path string, expected ...string){ - tok, err := client.GetToken(ctx) - g.Expect(err).NotTo(HaveOccurred()) - - elements, err := client.Fetch(ctx, tok, path) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(elements).To(ConsistOf(expected)) - }).WithContext(ctx).WithArguments("/names", "Joe", "Jane", "Sam").Should(Succeed()) - -Finally, in addition to passing timeouts and a context to Eventually you can be more explicit with Eventually's chaining configuration methods: - - Eventually(..., "1s", "2s", ctx).Should(...) - -is equivalent to - - Eventually(...).WithTimeout(time.Second).WithPolling(2*time.Second).WithContext(ctx).Should(...) +`Eventually` specifying a timeout interval (and an optional polling interval) are +the same as `Eventually(...).WithTimeout` or `Eventually(...).WithTimeout(...).WithPolling`. */ -func Eventually(actualOrCtx interface{}, args ...interface{}) AsyncAssertion { +func Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() - return Default.Eventually(actualOrCtx, args...) + return Default.Eventually(actual, intervals...) } // EventuallyWithOffset operates like Eventually but takes an additional @@ -382,9 +333,9 @@ func Eventually(actualOrCtx interface{}, args ...interface{}) AsyncAssertion { // `EventuallyWithOffset` specifying a timeout interval (and an optional polling interval) are // the same as `Eventually(...).WithOffset(...).WithTimeout` or // `Eventually(...).WithOffset(...).WithTimeout(...).WithPolling`. -func EventuallyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) AsyncAssertion { +func EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() - return Default.EventuallyWithOffset(offset, actualOrCtx, args...) + return Default.EventuallyWithOffset(offset, actual, intervals...) } /* @@ -392,19 +343,19 @@ Consistently, like Eventually, enables making assertions on asynchronous behavio Consistently blocks when called for a specified duration. During that duration Consistently repeatedly polls its matcher and ensures that it is satisfied. If the matcher is consistently satisfied, then Consistently will pass. Otherwise Consistently will fail. -Both the total waiting duration and the polling interval are configurable as optional arguments. The first optional argument is the duration that Consistently will run for (defaults to 100ms), and the second argument is the polling interval (defaults to 10ms). As with Eventually, these intervals can be passed in as time.Duration, parsable duration strings or an integer or float number of seconds. You can also pass in an optional context.Context - Consistently will exit early (with a failure) if the context is cancelled before the waiting duration expires. +Both the total waiting duration and the polling interval are configurable as optional arguments. The first optional argument is the duration that Consistently will run for (defaults to 100ms), and the second argument is the polling interval (defaults to 10ms). As with Eventually, these intervals can be passed in as time.Duration, parsable duration strings or an integer or float number of seconds. Consistently accepts the same three categories of actual as Eventually, check the Eventually docs to learn more. Consistently is useful in cases where you want to assert that something *does not happen* for a period of time. For example, you may want to assert that a goroutine does *not* send data down a channel. In this case you could write: - Consistently(channel, "200ms").ShouldNot(Receive()) + Consistently(channel, "200ms").ShouldNot(Receive()) This will block for 200 milliseconds and repeatedly check the channel and ensure nothing has been received. */ -func Consistently(actualOrCtx interface{}, args ...interface{}) AsyncAssertion { +func Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() - return Default.Consistently(actualOrCtx, args...) + return Default.Consistently(actual, intervals...) } // ConsistentlyWithOffset operates like Consistently but takes an additional @@ -413,54 +364,11 @@ func Consistently(actualOrCtx interface{}, args ...interface{}) AsyncAssertion { // // `ConsistentlyWithOffset` is the same as `Consistently(...).WithOffset` and // optional `WithTimeout` and `WithPolling`. -func ConsistentlyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) AsyncAssertion { +func ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() - return Default.ConsistentlyWithOffset(offset, actualOrCtx, args...) + return Default.ConsistentlyWithOffset(offset, actual, intervals...) } -/* -StopTrying can be used to signal to Eventually and Consistentlythat they should abort and stop trying. This always results in a failure of the assertion - and the failure message is the content of the StopTrying signal. - -You can send the StopTrying signal by either returning StopTrying("message") as an error from your passed-in function _or_ by calling StopTrying("message").Now() to trigger a panic and end execution. - -You can also wrap StopTrying around an error with `StopTrying("message").Wrap(err)` and can attach additional objects via `StopTrying("message").Attach("description", object). When rendered, the signal will include the wrapped error and any attached objects rendered using Gomega's default formatting. - -Here are a couple of examples. This is how you might use StopTrying() as an error to signal that Eventually should stop: - - playerIndex, numPlayers := 0, 11 - Eventually(func() (string, error) { - if playerIndex == numPlayers { - return "", StopTrying("no more players left") - } - name := client.FetchPlayer(playerIndex) - playerIndex += 1 - return name, nil - }).Should(Equal("Patrick Mahomes")) - -And here's an example where `StopTrying().Now()` is called to halt execution immediately: - - Eventually(func() []string { - names, err := client.FetchAllPlayers() - if err == client.IRRECOVERABLE_ERROR { - StopTrying("Irrecoverable error occurred").Wrap(err).Now() - } - return names - }).Should(ContainElement("Patrick Mahomes")) -*/ -var StopTrying = internal.StopTrying - -/* -TryAgainAfter() allows you to adjust the polling interval for the _next_ iteration of `Eventually` or `Consistently`. Like `StopTrying` you can either return `TryAgainAfter` as an error or trigger it immedieately with `.Now()` - -When `TryAgainAfter(` is triggered `Eventually` and `Consistently` will wait for that duration. If a timeout occurs before the next poll is triggered both `Eventually` and `Consistently` will always fail with the content of the TryAgainAfter message. As with StopTrying you can `.Wrap()` and error and `.Attach()` additional objects to `TryAgainAfter`. -*/ -var TryAgainAfter = internal.TryAgainAfter - -/* -PollingSignalError is the error returned by StopTrying() and TryAgainAfter() -*/ -type PollingSignalError = internal.PollingSignalError - // SetDefaultEventuallyTimeout sets the default timeout duration for Eventually. Eventually will repeatedly poll your condition until it succeeds, or until this timeout elapses. func SetDefaultEventuallyTimeout(t time.Duration) { Default.SetDefaultEventuallyTimeout(t) @@ -494,8 +402,8 @@ func SetDefaultConsistentlyPollingInterval(t time.Duration) { // // Example: // -// Eventually(myChannel).Should(Receive(), "Something should have come down the pipe.") -// Consistently(myChannel).ShouldNot(Receive(), func() string { return "Nothing should have come down the pipe." }) +// Eventually(myChannel).Should(Receive(), "Something should have come down the pipe.") +// Consistently(myChannel).ShouldNot(Receive(), func() string { return "Nothing should have come down the pipe." }) type AsyncAssertion = types.AsyncAssertion // GomegaAsyncAssertion is deprecated in favor of AsyncAssertion, which does not stutter. @@ -517,7 +425,7 @@ type GomegaAsyncAssertion = types.AsyncAssertion // // Example: // -// Ω(farm.HasCow()).Should(BeTrue(), "Farm %v should have a cow", farm) +// Ω(farm.HasCow()).Should(BeTrue(), "Farm %v should have a cow", farm) type Assertion = types.Assertion // GomegaAssertion is deprecated in favor of Assertion, which does not stutter. diff --git a/vendor/github.com/onsi/gomega/internal/assertion.go b/vendor/github.com/onsi/gomega/internal/assertion.go index 08356a61..7b7bdd14 100644 --- a/vendor/github.com/onsi/gomega/internal/assertion.go +++ b/vendor/github.com/onsi/gomega/internal/assertion.go @@ -4,7 +4,6 @@ import ( "fmt" "reflect" - "github.com/onsi/gomega/format" "github.com/onsi/gomega/types" ) @@ -147,12 +146,7 @@ func vetActuals(actuals []interface{}, skipIndex int) (bool, string) { if actual != nil { zeroValue := reflect.Zero(reflect.TypeOf(actual)).Interface() if !reflect.DeepEqual(zeroValue, actual) { - var message string - if err, ok := actual.(error); ok { - message = fmt.Sprintf("Unexpected error: %s\n%s", err, format.Object(err, 1)) - } else { - message = fmt.Sprintf("Unexpected non-nil/non-zero argument at index %d:\n\t<%T>: %#v", i, actual, actual) - } + message := fmt.Sprintf("Unexpected non-nil/non-zero argument at index %d:\n\t<%T>: %#v", i, actual, actual) return false, message } } diff --git a/vendor/github.com/onsi/gomega/internal/async_assertion.go b/vendor/github.com/onsi/gomega/internal/async_assertion.go index c1e4a999..126bbcb3 100644 --- a/vendor/github.com/onsi/gomega/internal/async_assertion.go +++ b/vendor/github.com/onsi/gomega/internal/async_assertion.go @@ -1,25 +1,15 @@ package internal import ( - "context" + "errors" "fmt" "reflect" "runtime" - "sync" "time" - "github.com/onsi/gomega/format" "github.com/onsi/gomega/types" ) -var errInterface = reflect.TypeOf((*error)(nil)).Elem() -var gomegaType = reflect.TypeOf((*types.Gomega)(nil)).Elem() -var contextType = reflect.TypeOf(new(context.Context)).Elem() - -type contextWithAttachProgressReporter interface { - AttachProgressReporter(func() string) func() -} - type AsyncAssertionType uint const ( @@ -27,43 +17,71 @@ const ( AsyncAssertionTypeConsistently ) -func (at AsyncAssertionType) String() string { - switch at { - case AsyncAssertionTypeEventually: - return "Eventually" - case AsyncAssertionTypeConsistently: - return "Consistently" - } - return "INVALID ASYNC ASSERTION TYPE" -} - type AsyncAssertion struct { asyncType AsyncAssertionType - actualIsFunc bool - actual interface{} - argsToForward []interface{} + actualIsFunc bool + actualValue interface{} + actualFunc func() ([]reflect.Value, error) timeoutInterval time.Duration pollingInterval time.Duration - ctx context.Context offset int g *Gomega } -func NewAsyncAssertion(asyncType AsyncAssertionType, actualInput interface{}, g *Gomega, timeoutInterval time.Duration, pollingInterval time.Duration, ctx context.Context, offset int) *AsyncAssertion { +func NewAsyncAssertion(asyncType AsyncAssertionType, actualInput interface{}, g *Gomega, timeoutInterval time.Duration, pollingInterval time.Duration, offset int) *AsyncAssertion { out := &AsyncAssertion{ asyncType: asyncType, timeoutInterval: timeoutInterval, pollingInterval: pollingInterval, offset: offset, - ctx: ctx, g: g, } - out.actual = actualInput - if actualInput != nil && reflect.TypeOf(actualInput).Kind() == reflect.Func { + switch actualType := reflect.TypeOf(actualInput); { + case actualInput == nil || actualType.Kind() != reflect.Func: + out.actualValue = actualInput + case actualType.NumIn() == 0 && actualType.NumOut() > 0: + out.actualIsFunc = true + out.actualFunc = func() ([]reflect.Value, error) { + return reflect.ValueOf(actualInput).Call([]reflect.Value{}), nil + } + case actualType.NumIn() == 1 && actualType.In(0).Implements(reflect.TypeOf((*types.Gomega)(nil)).Elem()): out.actualIsFunc = true + out.actualFunc = func() (values []reflect.Value, err error) { + var assertionFailure error + assertionCapturingGomega := NewGomega(g.DurationBundle).ConfigureWithFailHandler(func(message string, callerSkip ...int) { + skip := 0 + if len(callerSkip) > 0 { + skip = callerSkip[0] + } + _, file, line, _ := runtime.Caller(skip + 1) + assertionFailure = fmt.Errorf("Assertion in callback at %s:%d failed:\n%s", file, line, message) + panic("stop execution") + }) + + defer func() { + if actualType.NumOut() == 0 { + if assertionFailure == nil { + values = []reflect.Value{reflect.Zero(reflect.TypeOf((*error)(nil)).Elem())} + } else { + values = []reflect.Value{reflect.ValueOf(assertionFailure)} + } + } else { + err = assertionFailure + } + if e := recover(); e != nil && assertionFailure == nil { + panic(e) + } + }() + + values = reflect.ValueOf(actualInput).Call([]reflect.Value{reflect.ValueOf(assertionCapturingGomega)}) + return + } + default: + msg := fmt.Sprintf("The function passed to Gomega's async assertions should either take no arguments and return values, or take a single Gomega interface that it can use to make assertions within the body of the function. When taking a Gomega interface the function can optionally return values or return nothing. The function you passed takes %d arguments and returns %d values.", actualType.NumIn(), actualType.NumOut()) + g.Fail(msg, offset+4) } return out @@ -84,26 +102,6 @@ func (assertion *AsyncAssertion) WithPolling(interval time.Duration) types.Async return assertion } -func (assertion *AsyncAssertion) Within(timeout time.Duration) types.AsyncAssertion { - assertion.timeoutInterval = timeout - return assertion -} - -func (assertion *AsyncAssertion) ProbeEvery(interval time.Duration) types.AsyncAssertion { - assertion.pollingInterval = interval - return assertion -} - -func (assertion *AsyncAssertion) WithContext(ctx context.Context) types.AsyncAssertion { - assertion.ctx = ctx - return assertion -} - -func (assertion *AsyncAssertion) WithArguments(argsToForward ...interface{}) types.AsyncAssertion { - assertion.argsToForward = argsToForward - return assertion -} - func (assertion *AsyncAssertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() vetOptionalDescription("Asynchronous assertion", optionalDescription...) @@ -128,237 +126,54 @@ func (assertion *AsyncAssertion) buildDescription(optionalDescription ...interfa return fmt.Sprintf(optionalDescription[0].(string), optionalDescription[1:]...) + "\n" } -func (assertion *AsyncAssertion) processReturnValues(values []reflect.Value) (interface{}, error) { - if len(values) == 0 { - return nil, fmt.Errorf("No values were returned by the function passed to Gomega") - } - - actual := values[0].Interface() - if _, ok := AsPollingSignalError(actual); ok { - return actual, actual.(error) - } - - var err error - for i, extraValue := range values[1:] { - extra := extraValue.Interface() - if extra == nil { - continue - } - if _, ok := AsPollingSignalError(extra); ok { - return actual, extra.(error) - } - extraType := reflect.TypeOf(extra) - zero := reflect.Zero(extraType).Interface() - if reflect.DeepEqual(extra, zero) { - continue - } - if i == len(values)-2 && extraType.Implements(errInterface) { - err = fmt.Errorf("function returned error: %w", extra.(error)) - } - if err == nil { - err = fmt.Errorf("Unexpected non-nil/non-zero return value at index %d:\n\t<%T>: %#v", i+1, extra, extra) - } - } - - return actual, err -} - -func (assertion *AsyncAssertion) invalidFunctionError(t reflect.Type) error { - return fmt.Errorf(`The function passed to %s had an invalid signature of %s. Functions passed to %s must either: - - (a) have return values or - (b) take a Gomega interface as their first argument and use that Gomega instance to make assertions. - -You can learn more at https://onsi.github.io/gomega/#eventually -`, assertion.asyncType, t, assertion.asyncType) -} - -func (assertion *AsyncAssertion) noConfiguredContextForFunctionError() error { - return fmt.Errorf(`The function passed to %s requested a context.Context, but no context has been provided. Please pass one in using %s().WithContext(). - -You can learn more at https://onsi.github.io/gomega/#eventually -`, assertion.asyncType, assertion.asyncType) -} - -func (assertion *AsyncAssertion) argumentMismatchError(t reflect.Type, numProvided int) error { - have := "have" - if numProvided == 1 { - have = "has" - } - return fmt.Errorf(`The function passed to %s has signature %s takes %d arguments but %d %s been provided. Please use %s().WithArguments() to pass the corect set of arguments. - -You can learn more at https://onsi.github.io/gomega/#eventually -`, assertion.asyncType, t, t.NumIn(), numProvided, have, assertion.asyncType) -} - -func (assertion *AsyncAssertion) buildActualPoller() (func() (interface{}, error), error) { +func (assertion *AsyncAssertion) pollActual() (interface{}, error) { if !assertion.actualIsFunc { - return func() (interface{}, error) { return assertion.actual, nil }, nil - } - actualValue := reflect.ValueOf(assertion.actual) - actualType := reflect.TypeOf(assertion.actual) - numIn, numOut, isVariadic := actualType.NumIn(), actualType.NumOut(), actualType.IsVariadic() - - if numIn == 0 && numOut == 0 { - return nil, assertion.invalidFunctionError(actualType) - } - takesGomega, takesContext := false, false - if numIn > 0 { - takesGomega, takesContext = actualType.In(0).Implements(gomegaType), actualType.In(0).Implements(contextType) - } - if takesGomega && numIn > 1 && actualType.In(1).Implements(contextType) { - takesContext = true - } - if takesContext && len(assertion.argsToForward) > 0 && reflect.TypeOf(assertion.argsToForward[0]).Implements(contextType) { - takesContext = false - } - if !takesGomega && numOut == 0 { - return nil, assertion.invalidFunctionError(actualType) - } - if takesContext && assertion.ctx == nil { - return nil, assertion.noConfiguredContextForFunctionError() + return assertion.actualValue, nil } - var assertionFailure error - inValues := []reflect.Value{} - if takesGomega { - inValues = append(inValues, reflect.ValueOf(NewGomega(assertion.g.DurationBundle).ConfigureWithFailHandler(func(message string, callerSkip ...int) { - skip := 0 - if len(callerSkip) > 0 { - skip = callerSkip[0] - } - _, file, line, _ := runtime.Caller(skip + 1) - assertionFailure = fmt.Errorf("Assertion in callback at %s:%d failed:\n%s", file, line, message) - panic("stop execution") - }))) - } - if takesContext { - inValues = append(inValues, reflect.ValueOf(assertion.ctx)) + values, err := assertion.actualFunc() + if err != nil { + return nil, err } - for _, arg := range assertion.argsToForward { - inValues = append(inValues, reflect.ValueOf(arg)) + extras := []interface{}{nil} + for _, value := range values[1:] { + extras = append(extras, value.Interface()) } - - if !isVariadic && numIn != len(inValues) { - return nil, assertion.argumentMismatchError(actualType, len(inValues)) - } else if isVariadic && len(inValues) < numIn-1 { - return nil, assertion.argumentMismatchError(actualType, len(inValues)) + success, message := vetActuals(extras, 0) + if !success { + return nil, errors.New(message) } - return func() (actual interface{}, err error) { - var values []reflect.Value - assertionFailure = nil - defer func() { - if numOut == 0 && takesGomega { - actual = assertionFailure - } else { - actual, err = assertion.processReturnValues(values) - _, isAsyncError := AsPollingSignalError(err) - if assertionFailure != nil && !isAsyncError { - err = assertionFailure - } - } - if e := recover(); e != nil { - if _, isAsyncError := AsPollingSignalError(e); isAsyncError { - err = e.(error) - } else if assertionFailure == nil { - panic(e) - } - } - }() - values = actualValue.Call(inValues) - return - }, nil + return values[0].Interface(), nil } -func (assertion *AsyncAssertion) afterTimeout() <-chan time.Time { - if assertion.timeoutInterval >= 0 { - return time.After(assertion.timeoutInterval) - } - - if assertion.asyncType == AsyncAssertionTypeConsistently { - return time.After(assertion.g.DurationBundle.ConsistentlyDuration) - } else { - if assertion.ctx == nil { - return time.After(assertion.g.DurationBundle.EventuallyTimeout) - } else { - return nil - } +func (assertion *AsyncAssertion) matcherMayChange(matcher types.GomegaMatcher, value interface{}) bool { + if assertion.actualIsFunc { + return true } -} - -func (assertion *AsyncAssertion) afterPolling() <-chan time.Time { - if assertion.pollingInterval >= 0 { - return time.After(assertion.pollingInterval) - } - if assertion.asyncType == AsyncAssertionTypeConsistently { - return time.After(assertion.g.DurationBundle.ConsistentlyPollingInterval) - } else { - return time.After(assertion.g.DurationBundle.EventuallyPollingInterval) - } -} - -func (assertion *AsyncAssertion) matcherSaysStopTrying(matcher types.GomegaMatcher, value interface{}) bool { - if assertion.actualIsFunc || types.MatchMayChangeInTheFuture(matcher, value) { - return false - } - return true -} - -func (assertion *AsyncAssertion) pollMatcher(matcher types.GomegaMatcher, value interface{}) (matches bool, err error) { - defer func() { - if e := recover(); e != nil { - if _, isAsyncError := AsPollingSignalError(e); isAsyncError { - err = e.(error) - } else { - panic(e) - } - } - }() - - matches, err = matcher.Match(value) - - return + return types.MatchMayChangeInTheFuture(matcher, value) } func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch bool, optionalDescription ...interface{}) bool { timer := time.Now() - timeout := assertion.afterTimeout() - lock := sync.Mutex{} + timeout := time.After(assertion.timeoutInterval) var matches bool var err error - var oracleMatcherSaysStop bool - - assertion.g.THelper() - - pollActual, err := assertion.buildActualPoller() - if err != nil { - assertion.g.Fail(err.Error(), 2+assertion.offset) - return false - } - - value, err := pollActual() + mayChange := true + value, err := assertion.pollActual() if err == nil { - oracleMatcherSaysStop = assertion.matcherSaysStopTrying(matcher, value) - matches, err = assertion.pollMatcher(matcher, value) + mayChange = assertion.matcherMayChange(matcher, value) + matches, err = matcher.Match(value) } - messageGenerator := func() string { - // can be called out of band by Ginkgo if the user requests a progress report - lock.Lock() - defer lock.Unlock() + assertion.g.THelper() + + fail := func(preamble string) { + errMsg := "" message := "" if err != nil { - if pollingSignalErr, ok := AsPollingSignalError(err); ok && pollingSignalErr.IsStopTrying() { - message = err.Error() - for _, attachment := range pollingSignalErr.Attachments { - message += fmt.Sprintf("\n%s:\n", attachment.Description) - message += format.Object(attachment.Object, 1) - } - } else { - message = "Error: " + err.Error() + "\n" + format.Object(err, 1) - } + errMsg = "Error: " + err.Error() } else { if desiredMatch { message = matcher.FailureMessage(value) @@ -366,90 +181,57 @@ func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch message = matcher.NegatedFailureMessage(value) } } - description := assertion.buildDescription(optionalDescription...) - return fmt.Sprintf("%s%s", description, message) - } - - fail := func(preamble string) { assertion.g.THelper() - assertion.g.Fail(fmt.Sprintf("%s after %.3fs.\n%s", preamble, time.Since(timer).Seconds(), messageGenerator()), 3+assertion.offset) - } - - var contextDone <-chan struct{} - if assertion.ctx != nil { - contextDone = assertion.ctx.Done() - if v, ok := assertion.ctx.Value("GINKGO_SPEC_CONTEXT").(contextWithAttachProgressReporter); ok { - detach := v.AttachProgressReporter(messageGenerator) - defer detach() - } + description := assertion.buildDescription(optionalDescription...) + assertion.g.Fail(fmt.Sprintf("%s after %.3fs.\n%s%s%s", preamble, time.Since(timer).Seconds(), description, message, errMsg), 3+assertion.offset) } - for { - var nextPoll <-chan time.Time = nil - var isTryAgainAfterError = false + if assertion.asyncType == AsyncAssertionTypeEventually { + for { + if err == nil && matches == desiredMatch { + return true + } - if pollingSignalErr, ok := AsPollingSignalError(err); ok { - if pollingSignalErr.IsStopTrying() { - fail("Told to stop trying") + if !mayChange { + fail("No future change is possible. Bailing out early") return false } - if pollingSignalErr.IsTryAgainAfter() { - nextPoll = time.After(pollingSignalErr.TryAgainDuration()) - isTryAgainAfterError = true - } - } - if err == nil && matches == desiredMatch { - if assertion.asyncType == AsyncAssertionTypeEventually { - return true + select { + case <-time.After(assertion.pollingInterval): + value, err = assertion.pollActual() + if err == nil { + mayChange = assertion.matcherMayChange(matcher, value) + matches, err = matcher.Match(value) + } + case <-timeout: + fail("Timed out") + return false } - } else if !isTryAgainAfterError { - if assertion.asyncType == AsyncAssertionTypeConsistently { + } + } else if assertion.asyncType == AsyncAssertionTypeConsistently { + for { + if !(err == nil && matches == desiredMatch) { fail("Failed") return false } - } - if oracleMatcherSaysStop { - if assertion.asyncType == AsyncAssertionTypeEventually { - fail("No future change is possible. Bailing out early") - return false - } else { + if !mayChange { return true } - } - - if nextPoll == nil { - nextPoll = assertion.afterPolling() - } - select { - case <-nextPoll: - v, e := pollActual() - lock.Lock() - value, err = v, e - lock.Unlock() - if err == nil { - oracleMatcherSaysStop = assertion.matcherSaysStopTrying(matcher, value) - m, e := assertion.pollMatcher(matcher, value) - lock.Lock() - matches, err = m, e - lock.Unlock() - } - case <-contextDone: - fail("Context was cancelled") - return false - case <-timeout: - if assertion.asyncType == AsyncAssertionTypeEventually { - fail("Timed out") - return false - } else { - if isTryAgainAfterError { - fail("Timed out while waiting on TryAgainAfter") - return false + select { + case <-time.After(assertion.pollingInterval): + value, err = assertion.pollActual() + if err == nil { + mayChange = assertion.matcherMayChange(matcher, value) + matches, err = matcher.Match(value) } + case <-timeout: return true } } } + + return false } diff --git a/vendor/github.com/onsi/gomega/internal/duration_bundle.go b/vendor/github.com/onsi/gomega/internal/duration_bundle.go index 6e0d90d3..af8d989f 100644 --- a/vendor/github.com/onsi/gomega/internal/duration_bundle.go +++ b/vendor/github.com/onsi/gomega/internal/duration_bundle.go @@ -44,28 +44,28 @@ func durationFromEnv(key string, defaultDuration time.Duration) time.Duration { return duration } -func toDuration(input interface{}) (time.Duration, error) { +func toDuration(input interface{}) time.Duration { duration, ok := input.(time.Duration) if ok { - return duration, nil + return duration } value := reflect.ValueOf(input) kind := reflect.TypeOf(input).Kind() if reflect.Int <= kind && kind <= reflect.Int64 { - return time.Duration(value.Int()) * time.Second, nil + return time.Duration(value.Int()) * time.Second } else if reflect.Uint <= kind && kind <= reflect.Uint64 { - return time.Duration(value.Uint()) * time.Second, nil + return time.Duration(value.Uint()) * time.Second } else if reflect.Float32 <= kind && kind <= reflect.Float64 { - return time.Duration(value.Float() * float64(time.Second)), nil + return time.Duration(value.Float() * float64(time.Second)) } else if reflect.String == kind { duration, err := time.ParseDuration(value.String()) if err != nil { - return 0, fmt.Errorf("%#v is not a valid parsable duration string: %w", input, err) + panic(fmt.Sprintf("%#v is not a valid parsable duration string.", input)) } - return duration, nil + return duration } - return 0, fmt.Errorf("%#v is not a valid interval. Must be a time.Duration, a parsable duration string, or a number.", input) + panic(fmt.Sprintf("%v is not a valid interval. Must be time.Duration, parsable duration string or a number.", input)) } diff --git a/vendor/github.com/onsi/gomega/internal/gomega.go b/vendor/github.com/onsi/gomega/internal/gomega.go index 2d92877f..d26a6748 100644 --- a/vendor/github.com/onsi/gomega/internal/gomega.go +++ b/vendor/github.com/onsi/gomega/internal/gomega.go @@ -1,7 +1,6 @@ package internal import ( - "context" "time" "github.com/onsi/gomega/types" @@ -52,64 +51,38 @@ func (g *Gomega) ExpectWithOffset(offset int, actual interface{}, extra ...inter return NewAssertion(actual, g, offset, extra...) } -func (g *Gomega) Eventually(actualOrCtx interface{}, args ...interface{}) types.AsyncAssertion { - return g.makeAsyncAssertion(AsyncAssertionTypeEventually, 0, actualOrCtx, args...) +func (g *Gomega) Eventually(actual interface{}, intervals ...interface{}) types.AsyncAssertion { + return g.EventuallyWithOffset(0, actual, intervals...) } -func (g *Gomega) EventuallyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) types.AsyncAssertion { - return g.makeAsyncAssertion(AsyncAssertionTypeEventually, offset, actualOrCtx, args...) -} +func (g *Gomega) EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) types.AsyncAssertion { + timeoutInterval := g.DurationBundle.EventuallyTimeout + pollingInterval := g.DurationBundle.EventuallyPollingInterval + if len(intervals) > 0 { + timeoutInterval = toDuration(intervals[0]) + } + if len(intervals) > 1 { + pollingInterval = toDuration(intervals[1]) + } -func (g *Gomega) Consistently(actualOrCtx interface{}, args ...interface{}) types.AsyncAssertion { - return g.makeAsyncAssertion(AsyncAssertionTypeConsistently, 0, actualOrCtx, args...) + return NewAsyncAssertion(AsyncAssertionTypeEventually, actual, g, timeoutInterval, pollingInterval, offset) } -func (g *Gomega) ConsistentlyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) types.AsyncAssertion { - return g.makeAsyncAssertion(AsyncAssertionTypeConsistently, offset, actualOrCtx, args...) +func (g *Gomega) Consistently(actual interface{}, intervals ...interface{}) types.AsyncAssertion { + return g.ConsistentlyWithOffset(0, actual, intervals...) } -func (g *Gomega) makeAsyncAssertion(asyncAssertionType AsyncAssertionType, offset int, actualOrCtx interface{}, args ...interface{}) types.AsyncAssertion { - baseOffset := 3 - timeoutInterval := -time.Duration(1) - pollingInterval := -time.Duration(1) - intervals := []interface{}{} - var ctx context.Context - - actual := actualOrCtx - startingIndex := 0 - if _, isCtx := actualOrCtx.(context.Context); isCtx && len(args) > 0 { - // the first argument is a context, we should accept it as the context _only if_ it is **not** the only argumnent **and** the second argument is not a parseable duration - // this is due to an unfortunate ambiguity in early version of Gomega in which multi-type durations are allowed after the actual - if _, err := toDuration(args[0]); err != nil { - ctx = actualOrCtx.(context.Context) - actual = args[0] - startingIndex = 1 - } - } - - for _, arg := range args[startingIndex:] { - switch v := arg.(type) { - case context.Context: - ctx = v - default: - intervals = append(intervals, arg) - } - } - var err error +func (g *Gomega) ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) types.AsyncAssertion { + timeoutInterval := g.DurationBundle.ConsistentlyDuration + pollingInterval := g.DurationBundle.ConsistentlyPollingInterval if len(intervals) > 0 { - timeoutInterval, err = toDuration(intervals[0]) - if err != nil { - g.Fail(err.Error(), offset+baseOffset) - } + timeoutInterval = toDuration(intervals[0]) } if len(intervals) > 1 { - pollingInterval, err = toDuration(intervals[1]) - if err != nil { - g.Fail(err.Error(), offset+baseOffset) - } + pollingInterval = toDuration(intervals[1]) } - return NewAsyncAssertion(asyncAssertionType, actual, g, timeoutInterval, pollingInterval, ctx, offset) + return NewAsyncAssertion(AsyncAssertionTypeConsistently, actual, g, timeoutInterval, pollingInterval, offset) } func (g *Gomega) SetDefaultEventuallyTimeout(t time.Duration) { diff --git a/vendor/github.com/onsi/gomega/internal/polling_signal_error.go b/vendor/github.com/onsi/gomega/internal/polling_signal_error.go deleted file mode 100644 index 83b04b1a..00000000 --- a/vendor/github.com/onsi/gomega/internal/polling_signal_error.go +++ /dev/null @@ -1,106 +0,0 @@ -package internal - -import ( - "errors" - "fmt" - "time" -) - -type PollingSignalErrorType int - -const ( - PollingSignalErrorTypeStopTrying PollingSignalErrorType = iota - PollingSignalErrorTypeTryAgainAfter -) - -type PollingSignalError interface { - error - Wrap(err error) PollingSignalError - Attach(description string, obj any) PollingSignalError - Now() -} - -var StopTrying = func(message string) PollingSignalError { - return &PollingSignalErrorImpl{ - message: message, - pollingSignalErrorType: PollingSignalErrorTypeStopTrying, - } -} - -var TryAgainAfter = func(duration time.Duration) PollingSignalError { - return &PollingSignalErrorImpl{ - message: fmt.Sprintf("told to try again after %s", duration), - duration: duration, - pollingSignalErrorType: PollingSignalErrorTypeTryAgainAfter, - } -} - -type PollingSignalErrorAttachment struct { - Description string - Object any -} - -type PollingSignalErrorImpl struct { - message string - wrappedErr error - pollingSignalErrorType PollingSignalErrorType - duration time.Duration - Attachments []PollingSignalErrorAttachment -} - -func (s *PollingSignalErrorImpl) Wrap(err error) PollingSignalError { - s.wrappedErr = err - return s -} - -func (s *PollingSignalErrorImpl) Attach(description string, obj any) PollingSignalError { - s.Attachments = append(s.Attachments, PollingSignalErrorAttachment{description, obj}) - return s -} - -func (s *PollingSignalErrorImpl) Error() string { - if s.wrappedErr == nil { - return s.message - } else { - return s.message + ": " + s.wrappedErr.Error() - } -} - -func (s *PollingSignalErrorImpl) Unwrap() error { - if s == nil { - return nil - } - return s.wrappedErr -} - -func (s *PollingSignalErrorImpl) Now() { - panic(s) -} - -func (s *PollingSignalErrorImpl) IsStopTrying() bool { - return s.pollingSignalErrorType == PollingSignalErrorTypeStopTrying -} - -func (s *PollingSignalErrorImpl) IsTryAgainAfter() bool { - return s.pollingSignalErrorType == PollingSignalErrorTypeTryAgainAfter -} - -func (s *PollingSignalErrorImpl) TryAgainDuration() time.Duration { - return s.duration -} - -func AsPollingSignalError(actual interface{}) (*PollingSignalErrorImpl, bool) { - if actual == nil { - return nil, false - } - if actualErr, ok := actual.(error); ok { - var target *PollingSignalErrorImpl - if errors.As(actualErr, &target) { - return target, true - } else { - return nil, false - } - } - - return nil, false -} diff --git a/vendor/github.com/onsi/gomega/matchers.go b/vendor/github.com/onsi/gomega/matchers.go index 857586a9..d6a09906 100644 --- a/vendor/github.com/onsi/gomega/matchers.go +++ b/vendor/github.com/onsi/gomega/matchers.go @@ -8,28 +8,27 @@ import ( "github.com/onsi/gomega/types" ) -// Equal uses reflect.DeepEqual to compare actual with expected. Equal is strict about -// types when performing comparisons. -// It is an error for both actual and expected to be nil. Use BeNil() instead. +//Equal uses reflect.DeepEqual to compare actual with expected. Equal is strict about +//types when performing comparisons. +//It is an error for both actual and expected to be nil. Use BeNil() instead. func Equal(expected interface{}) types.GomegaMatcher { return &matchers.EqualMatcher{ Expected: expected, } } -// BeEquivalentTo is more lax than Equal, allowing equality between different types. -// This is done by converting actual to have the type of expected before -// attempting equality with reflect.DeepEqual. -// It is an error for actual and expected to be nil. Use BeNil() instead. +//BeEquivalentTo is more lax than Equal, allowing equality between different types. +//This is done by converting actual to have the type of expected before +//attempting equality with reflect.DeepEqual. +//It is an error for actual and expected to be nil. Use BeNil() instead. func BeEquivalentTo(expected interface{}) types.GomegaMatcher { return &matchers.BeEquivalentToMatcher{ Expected: expected, } } -// BeComparableTo uses gocmp.Equal from github.com/google/go-cmp (instead of reflect.DeepEqual) to perform a deep comparison. -// You can pass cmp.Option as options. -// It is an error for actual and expected to be nil. Use BeNil() instead. +//BeComparableTo uses gocmp.Equal to compare. You can pass cmp.Option as options. +//It is an error for actual and expected to be nil. Use BeNil() instead. func BeComparableTo(expected interface{}, opts ...cmp.Option) types.GomegaMatcher { return &matchers.BeComparableToMatcher{ Expected: expected, @@ -37,124 +36,116 @@ func BeComparableTo(expected interface{}, opts ...cmp.Option) types.GomegaMatche } } -// BeIdenticalTo uses the == operator to compare actual with expected. -// BeIdenticalTo is strict about types when performing comparisons. -// It is an error for both actual and expected to be nil. Use BeNil() instead. +//BeIdenticalTo uses the == operator to compare actual with expected. +//BeIdenticalTo is strict about types when performing comparisons. +//It is an error for both actual and expected to be nil. Use BeNil() instead. func BeIdenticalTo(expected interface{}) types.GomegaMatcher { return &matchers.BeIdenticalToMatcher{ Expected: expected, } } -// BeNil succeeds if actual is nil +//BeNil succeeds if actual is nil func BeNil() types.GomegaMatcher { return &matchers.BeNilMatcher{} } -// BeTrue succeeds if actual is true +//BeTrue succeeds if actual is true func BeTrue() types.GomegaMatcher { return &matchers.BeTrueMatcher{} } -// BeFalse succeeds if actual is false +//BeFalse succeeds if actual is false func BeFalse() types.GomegaMatcher { return &matchers.BeFalseMatcher{} } -// HaveOccurred succeeds if actual is a non-nil error -// The typical Go error checking pattern looks like: -// -// err := SomethingThatMightFail() -// Expect(err).ShouldNot(HaveOccurred()) +//HaveOccurred succeeds if actual is a non-nil error +//The typical Go error checking pattern looks like: +// err := SomethingThatMightFail() +// Expect(err).ShouldNot(HaveOccurred()) func HaveOccurred() types.GomegaMatcher { return &matchers.HaveOccurredMatcher{} } -// Succeed passes if actual is a nil error -// Succeed is intended to be used with functions that return a single error value. Instead of -// -// err := SomethingThatMightFail() -// Expect(err).ShouldNot(HaveOccurred()) +//Succeed passes if actual is a nil error +//Succeed is intended to be used with functions that return a single error value. Instead of +// err := SomethingThatMightFail() +// Expect(err).ShouldNot(HaveOccurred()) // -// You can write: +//You can write: +// Expect(SomethingThatMightFail()).Should(Succeed()) // -// Expect(SomethingThatMightFail()).Should(Succeed()) -// -// It is a mistake to use Succeed with a function that has multiple return values. Gomega's Ω and Expect -// functions automatically trigger failure if any return values after the first return value are non-zero/non-nil. -// This means that Ω(MultiReturnFunc()).ShouldNot(Succeed()) can never pass. +//It is a mistake to use Succeed with a function that has multiple return values. Gomega's Ω and Expect +//functions automatically trigger failure if any return values after the first return value are non-zero/non-nil. +//This means that Ω(MultiReturnFunc()).ShouldNot(Succeed()) can never pass. func Succeed() types.GomegaMatcher { return &matchers.SucceedMatcher{} } -// MatchError succeeds if actual is a non-nil error that matches the passed in string/error. -// -// These are valid use-cases: +//MatchError succeeds if actual is a non-nil error that matches the passed in string/error. // -// Expect(err).Should(MatchError("an error")) //asserts that err.Error() == "an error" -// Expect(err).Should(MatchError(SomeError)) //asserts that err == SomeError (via reflect.DeepEqual) +//These are valid use-cases: +// Expect(err).Should(MatchError("an error")) //asserts that err.Error() == "an error" +// Expect(err).Should(MatchError(SomeError)) //asserts that err == SomeError (via reflect.DeepEqual) // -// It is an error for err to be nil or an object that does not implement the Error interface +//It is an error for err to be nil or an object that does not implement the Error interface func MatchError(expected interface{}) types.GomegaMatcher { return &matchers.MatchErrorMatcher{ Expected: expected, } } -// BeClosed succeeds if actual is a closed channel. -// It is an error to pass a non-channel to BeClosed, it is also an error to pass nil +//BeClosed succeeds if actual is a closed channel. +//It is an error to pass a non-channel to BeClosed, it is also an error to pass nil // -// In order to check whether or not the channel is closed, Gomega must try to read from the channel -// (even in the `ShouldNot(BeClosed())` case). You should keep this in mind if you wish to make subsequent assertions about -// values coming down the channel. +//In order to check whether or not the channel is closed, Gomega must try to read from the channel +//(even in the `ShouldNot(BeClosed())` case). You should keep this in mind if you wish to make subsequent assertions about +//values coming down the channel. // -// Also, if you are testing that a *buffered* channel is closed you must first read all values out of the channel before -// asserting that it is closed (it is not possible to detect that a buffered-channel has been closed until all its buffered values are read). +//Also, if you are testing that a *buffered* channel is closed you must first read all values out of the channel before +//asserting that it is closed (it is not possible to detect that a buffered-channel has been closed until all its buffered values are read). // -// Finally, as a corollary: it is an error to check whether or not a send-only channel is closed. +//Finally, as a corollary: it is an error to check whether or not a send-only channel is closed. func BeClosed() types.GomegaMatcher { return &matchers.BeClosedMatcher{} } -// Receive succeeds if there is a value to be received on actual. -// Actual must be a channel (and cannot be a send-only channel) -- anything else is an error. -// -// Receive returns immediately and never blocks: -// -// - If there is nothing on the channel `c` then Expect(c).Should(Receive()) will fail and Ω(c).ShouldNot(Receive()) will pass. -// -// - If the channel `c` is closed then Expect(c).Should(Receive()) will fail and Ω(c).ShouldNot(Receive()) will pass. -// -// - If there is something on the channel `c` ready to be read, then Expect(c).Should(Receive()) will pass and Ω(c).ShouldNot(Receive()) will fail. +//Receive succeeds if there is a value to be received on actual. +//Actual must be a channel (and cannot be a send-only channel) -- anything else is an error. // -// If you have a go-routine running in the background that will write to channel `c` you can: +//Receive returns immediately and never blocks: // -// Eventually(c).Should(Receive()) +//- If there is nothing on the channel `c` then Expect(c).Should(Receive()) will fail and Ω(c).ShouldNot(Receive()) will pass. // -// This will timeout if nothing gets sent to `c` (you can modify the timeout interval as you normally do with `Eventually`) +//- If the channel `c` is closed then Expect(c).Should(Receive()) will fail and Ω(c).ShouldNot(Receive()) will pass. // -// A similar use-case is to assert that no go-routine writes to a channel (for a period of time). You can do this with `Consistently`: +//- If there is something on the channel `c` ready to be read, then Expect(c).Should(Receive()) will pass and Ω(c).ShouldNot(Receive()) will fail. // -// Consistently(c).ShouldNot(Receive()) +//If you have a go-routine running in the background that will write to channel `c` you can: +// Eventually(c).Should(Receive()) // -// You can pass `Receive` a matcher. If you do so, it will match the received object against the matcher. For example: +//This will timeout if nothing gets sent to `c` (you can modify the timeout interval as you normally do with `Eventually`) // -// Expect(c).Should(Receive(Equal("foo"))) +//A similar use-case is to assert that no go-routine writes to a channel (for a period of time). You can do this with `Consistently`: +// Consistently(c).ShouldNot(Receive()) // -// When given a matcher, `Receive` will always fail if there is nothing to be received on the channel. +//You can pass `Receive` a matcher. If you do so, it will match the received object against the matcher. For example: +// Expect(c).Should(Receive(Equal("foo"))) // -// Passing Receive a matcher is especially useful when paired with Eventually: +//When given a matcher, `Receive` will always fail if there is nothing to be received on the channel. // -// Eventually(c).Should(Receive(ContainSubstring("bar"))) +//Passing Receive a matcher is especially useful when paired with Eventually: // -// will repeatedly attempt to pull values out of `c` until a value matching "bar" is received. +// Eventually(c).Should(Receive(ContainSubstring("bar"))) // -// Finally, if you want to have a reference to the value *sent* to the channel you can pass the `Receive` matcher a pointer to a variable of the appropriate type: +//will repeatedly attempt to pull values out of `c` until a value matching "bar" is received. // -// var myThing thing -// Eventually(thingChan).Should(Receive(&myThing)) -// Expect(myThing.Sprocket).Should(Equal("foo")) -// Expect(myThing.IsValid()).Should(BeTrue()) +//Finally, if you want to have a reference to the value *sent* to the channel you can pass the `Receive` matcher a pointer to a variable of the appropriate type: +// var myThing thing +// Eventually(thingChan).Should(Receive(&myThing)) +// Expect(myThing.Sprocket).Should(Equal("foo")) +// Expect(myThing.IsValid()).Should(BeTrue()) func Receive(args ...interface{}) types.GomegaMatcher { var arg interface{} if len(args) > 0 { @@ -166,27 +157,27 @@ func Receive(args ...interface{}) types.GomegaMatcher { } } -// BeSent succeeds if a value can be sent to actual. -// Actual must be a channel (and cannot be a receive-only channel) that can sent the type of the value passed into BeSent -- anything else is an error. -// In addition, actual must not be closed. +//BeSent succeeds if a value can be sent to actual. +//Actual must be a channel (and cannot be a receive-only channel) that can sent the type of the value passed into BeSent -- anything else is an error. +//In addition, actual must not be closed. // -// BeSent never blocks: +//BeSent never blocks: // -// - If the channel `c` is not ready to receive then Expect(c).Should(BeSent("foo")) will fail immediately -// - If the channel `c` is eventually ready to receive then Eventually(c).Should(BeSent("foo")) will succeed.. presuming the channel becomes ready to receive before Eventually's timeout -// - If the channel `c` is closed then Expect(c).Should(BeSent("foo")) and Ω(c).ShouldNot(BeSent("foo")) will both fail immediately +//- If the channel `c` is not ready to receive then Expect(c).Should(BeSent("foo")) will fail immediately +//- If the channel `c` is eventually ready to receive then Eventually(c).Should(BeSent("foo")) will succeed.. presuming the channel becomes ready to receive before Eventually's timeout +//- If the channel `c` is closed then Expect(c).Should(BeSent("foo")) and Ω(c).ShouldNot(BeSent("foo")) will both fail immediately // -// Of course, the value is actually sent to the channel. The point of `BeSent` is less to make an assertion about the availability of the channel (which is typically an implementation detail that your test should not be concerned with). -// Rather, the point of `BeSent` is to make it possible to easily and expressively write tests that can timeout on blocked channel sends. +//Of course, the value is actually sent to the channel. The point of `BeSent` is less to make an assertion about the availability of the channel (which is typically an implementation detail that your test should not be concerned with). +//Rather, the point of `BeSent` is to make it possible to easily and expressively write tests that can timeout on blocked channel sends. func BeSent(arg interface{}) types.GomegaMatcher { return &matchers.BeSentMatcher{ Arg: arg, } } -// MatchRegexp succeeds if actual is a string or stringer that matches the -// passed-in regexp. Optional arguments can be provided to construct a regexp -// via fmt.Sprintf(). +//MatchRegexp succeeds if actual is a string or stringer that matches the +//passed-in regexp. Optional arguments can be provided to construct a regexp +//via fmt.Sprintf(). func MatchRegexp(regexp string, args ...interface{}) types.GomegaMatcher { return &matchers.MatchRegexpMatcher{ Regexp: regexp, @@ -194,9 +185,9 @@ func MatchRegexp(regexp string, args ...interface{}) types.GomegaMatcher { } } -// ContainSubstring succeeds if actual is a string or stringer that contains the -// passed-in substring. Optional arguments can be provided to construct the substring -// via fmt.Sprintf(). +//ContainSubstring succeeds if actual is a string or stringer that contains the +//passed-in substring. Optional arguments can be provided to construct the substring +//via fmt.Sprintf(). func ContainSubstring(substr string, args ...interface{}) types.GomegaMatcher { return &matchers.ContainSubstringMatcher{ Substr: substr, @@ -204,9 +195,9 @@ func ContainSubstring(substr string, args ...interface{}) types.GomegaMatcher { } } -// HavePrefix succeeds if actual is a string or stringer that contains the -// passed-in string as a prefix. Optional arguments can be provided to construct -// via fmt.Sprintf(). +//HavePrefix succeeds if actual is a string or stringer that contains the +//passed-in string as a prefix. Optional arguments can be provided to construct +//via fmt.Sprintf(). func HavePrefix(prefix string, args ...interface{}) types.GomegaMatcher { return &matchers.HavePrefixMatcher{ Prefix: prefix, @@ -214,9 +205,9 @@ func HavePrefix(prefix string, args ...interface{}) types.GomegaMatcher { } } -// HaveSuffix succeeds if actual is a string or stringer that contains the -// passed-in string as a suffix. Optional arguments can be provided to construct -// via fmt.Sprintf(). +//HaveSuffix succeeds if actual is a string or stringer that contains the +//passed-in string as a suffix. Optional arguments can be provided to construct +//via fmt.Sprintf(). func HaveSuffix(suffix string, args ...interface{}) types.GomegaMatcher { return &matchers.HaveSuffixMatcher{ Suffix: suffix, @@ -224,74 +215,73 @@ func HaveSuffix(suffix string, args ...interface{}) types.GomegaMatcher { } } -// MatchJSON succeeds if actual is a string or stringer of JSON that matches -// the expected JSON. The JSONs are decoded and the resulting objects are compared via -// reflect.DeepEqual so things like key-ordering and whitespace shouldn't matter. +//MatchJSON succeeds if actual is a string or stringer of JSON that matches +//the expected JSON. The JSONs are decoded and the resulting objects are compared via +//reflect.DeepEqual so things like key-ordering and whitespace shouldn't matter. func MatchJSON(json interface{}) types.GomegaMatcher { return &matchers.MatchJSONMatcher{ JSONToMatch: json, } } -// MatchXML succeeds if actual is a string or stringer of XML that matches -// the expected XML. The XMLs are decoded and the resulting objects are compared via -// reflect.DeepEqual so things like whitespaces shouldn't matter. +//MatchXML succeeds if actual is a string or stringer of XML that matches +//the expected XML. The XMLs are decoded and the resulting objects are compared via +//reflect.DeepEqual so things like whitespaces shouldn't matter. func MatchXML(xml interface{}) types.GomegaMatcher { return &matchers.MatchXMLMatcher{ XMLToMatch: xml, } } -// MatchYAML succeeds if actual is a string or stringer of YAML that matches -// the expected YAML. The YAML's are decoded and the resulting objects are compared via -// reflect.DeepEqual so things like key-ordering and whitespace shouldn't matter. +//MatchYAML succeeds if actual is a string or stringer of YAML that matches +//the expected YAML. The YAML's are decoded and the resulting objects are compared via +//reflect.DeepEqual so things like key-ordering and whitespace shouldn't matter. func MatchYAML(yaml interface{}) types.GomegaMatcher { return &matchers.MatchYAMLMatcher{ YAMLToMatch: yaml, } } -// BeEmpty succeeds if actual is empty. Actual must be of type string, array, map, chan, or slice. +//BeEmpty succeeds if actual is empty. Actual must be of type string, array, map, chan, or slice. func BeEmpty() types.GomegaMatcher { return &matchers.BeEmptyMatcher{} } -// HaveLen succeeds if actual has the passed-in length. Actual must be of type string, array, map, chan, or slice. +//HaveLen succeeds if actual has the passed-in length. Actual must be of type string, array, map, chan, or slice. func HaveLen(count int) types.GomegaMatcher { return &matchers.HaveLenMatcher{ Count: count, } } -// HaveCap succeeds if actual has the passed-in capacity. Actual must be of type array, chan, or slice. +//HaveCap succeeds if actual has the passed-in capacity. Actual must be of type array, chan, or slice. func HaveCap(count int) types.GomegaMatcher { return &matchers.HaveCapMatcher{ Count: count, } } -// BeZero succeeds if actual is the zero value for its type or if actual is nil. +//BeZero succeeds if actual is the zero value for its type or if actual is nil. func BeZero() types.GomegaMatcher { return &matchers.BeZeroMatcher{} } -// ContainElement succeeds if actual contains the passed in element. By default -// ContainElement() uses Equal() to perform the match, however a matcher can be -// passed in instead: +//ContainElement succeeds if actual contains the passed in element. By default +//ContainElement() uses Equal() to perform the match, however a matcher can be +//passed in instead: +// Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubstring("Bar"))) // -// Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubstring("Bar"))) +//Actual must be an array, slice or map. For maps, ContainElement searches +//through the map's values. // -// Actual must be an array, slice or map. For maps, ContainElement searches -// through the map's values. +//If you want to have a copy of the matching element(s) found you can pass a +//pointer to a variable of the appropriate type. If the variable isn't a slice +//or map, then exactly one match will be expected and returned. If the variable +//is a slice or map, then at least one match is expected and all matches will be +//stored in the variable. // -// If you want to have a copy of the matching element(s) found you can pass a -// pointer to a variable of the appropriate type. If the variable isn't a slice -// or map, then exactly one match will be expected and returned. If the variable -// is a slice or map, then at least one match is expected and all matches will be -// stored in the variable. -// -// var findings []string -// Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubString("Bar", &findings))) +// var findings []string +// Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubString("Bar", &findings))) func ContainElement(element interface{}, result ...interface{}) types.GomegaMatcher { return &matchers.ContainElementMatcher{ Element: element, @@ -299,102 +289,86 @@ func ContainElement(element interface{}, result ...interface{}) types.GomegaMatc } } -// BeElementOf succeeds if actual is contained in the passed in elements. -// BeElementOf() always uses Equal() to perform the match. -// When the passed in elements are comprised of a single element that is either an Array or Slice, BeElementOf() behaves -// as the reverse of ContainElement() that operates with Equal() to perform the match. -// -// Expect(2).Should(BeElementOf([]int{1, 2})) -// Expect(2).Should(BeElementOf([2]int{1, 2})) -// -// Otherwise, BeElementOf() provides a syntactic sugar for Or(Equal(_), Equal(_), ...): -// -// Expect(2).Should(BeElementOf(1, 2)) +//BeElementOf succeeds if actual is contained in the passed in elements. +//BeElementOf() always uses Equal() to perform the match. +//When the passed in elements are comprised of a single element that is either an Array or Slice, BeElementOf() behaves +//as the reverse of ContainElement() that operates with Equal() to perform the match. +// Expect(2).Should(BeElementOf([]int{1, 2})) +// Expect(2).Should(BeElementOf([2]int{1, 2})) +//Otherwise, BeElementOf() provides a syntactic sugar for Or(Equal(_), Equal(_), ...): +// Expect(2).Should(BeElementOf(1, 2)) // -// Actual must be typed. +//Actual must be typed. func BeElementOf(elements ...interface{}) types.GomegaMatcher { return &matchers.BeElementOfMatcher{ Elements: elements, } } -// BeKeyOf succeeds if actual is contained in the keys of the passed in map. -// BeKeyOf() always uses Equal() to perform the match between actual and the map keys. -// -// Expect("foo").Should(BeKeyOf(map[string]bool{"foo": true, "bar": false})) -func BeKeyOf(element interface{}) types.GomegaMatcher { - return &matchers.BeKeyOfMatcher{ - Map: element, - } -} - -// ConsistOf succeeds if actual contains precisely the elements passed into the matcher. The ordering of the elements does not matter. -// By default ConsistOf() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples: +//ConsistOf succeeds if actual contains precisely the elements passed into the matcher. The ordering of the elements does not matter. +//By default ConsistOf() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples: // -// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf("FooBar", "Foo")) -// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Bar"), "Foo")) -// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Foo"), ContainSubstring("Foo"))) +// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf("FooBar", "Foo")) +// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Bar"), "Foo")) +// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Foo"), ContainSubstring("Foo"))) // -// Actual must be an array, slice or map. For maps, ConsistOf matches against the map's values. +//Actual must be an array, slice or map. For maps, ConsistOf matches against the map's values. // -// You typically pass variadic arguments to ConsistOf (as in the examples above). However, if you need to pass in a slice you can provided that it -// is the only element passed in to ConsistOf: +//You typically pass variadic arguments to ConsistOf (as in the examples above). However, if you need to pass in a slice you can provided that it +//is the only element passed in to ConsistOf: // -// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf([]string{"FooBar", "Foo"})) +// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf([]string{"FooBar", "Foo"})) // -// Note that Go's type system does not allow you to write this as ConsistOf([]string{"FooBar", "Foo"}...) as []string and []interface{} are different types - hence the need for this special rule. +//Note that Go's type system does not allow you to write this as ConsistOf([]string{"FooBar", "Foo"}...) as []string and []interface{} are different types - hence the need for this special rule. func ConsistOf(elements ...interface{}) types.GomegaMatcher { return &matchers.ConsistOfMatcher{ Elements: elements, } } -// ContainElements succeeds if actual contains the passed in elements. The ordering of the elements does not matter. -// By default ContainElements() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples: +//ContainElements succeeds if actual contains the passed in elements. The ordering of the elements does not matter. +//By default ContainElements() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples: // -// Expect([]string{"Foo", "FooBar"}).Should(ContainElements("FooBar")) -// Expect([]string{"Foo", "FooBar"}).Should(ContainElements(ContainSubstring("Bar"), "Foo")) +// Expect([]string{"Foo", "FooBar"}).Should(ContainElements("FooBar")) +// Expect([]string{"Foo", "FooBar"}).Should(ContainElements(ContainSubstring("Bar"), "Foo")) // -// Actual must be an array, slice or map. -// For maps, ContainElements searches through the map's values. +//Actual must be an array, slice or map. +//For maps, ContainElements searches through the map's values. func ContainElements(elements ...interface{}) types.GomegaMatcher { return &matchers.ContainElementsMatcher{ Elements: elements, } } -// HaveEach succeeds if actual solely contains elements that match the passed in element. -// Please note that if actual is empty, HaveEach always will succeed. -// By default HaveEach() uses Equal() to perform the match, however a -// matcher can be passed in instead: +//HaveEach succeeds if actual solely contains elements that match the passed in element. +//Please note that if actual is empty, HaveEach always will succeed. +//By default HaveEach() uses Equal() to perform the match, however a +//matcher can be passed in instead: +// Expect([]string{"Foo", "FooBar"}).Should(HaveEach(ContainSubstring("Foo"))) // -// Expect([]string{"Foo", "FooBar"}).Should(HaveEach(ContainSubstring("Foo"))) -// -// Actual must be an array, slice or map. -// For maps, HaveEach searches through the map's values. +//Actual must be an array, slice or map. +//For maps, HaveEach searches through the map's values. func HaveEach(element interface{}) types.GomegaMatcher { return &matchers.HaveEachMatcher{ Element: element, } } -// HaveKey succeeds if actual is a map with the passed in key. -// By default HaveKey uses Equal() to perform the match, however a -// matcher can be passed in instead: -// -// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKey(MatchRegexp(`.+Foo$`))) +//HaveKey succeeds if actual is a map with the passed in key. +//By default HaveKey uses Equal() to perform the match, however a +//matcher can be passed in instead: +// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKey(MatchRegexp(`.+Foo$`))) func HaveKey(key interface{}) types.GomegaMatcher { return &matchers.HaveKeyMatcher{ Key: key, } } -// HaveKeyWithValue succeeds if actual is a map with the passed in key and value. -// By default HaveKeyWithValue uses Equal() to perform the match, however a -// matcher can be passed in instead: -// -// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue("Foo", "Bar")) -// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue(MatchRegexp(`.+Foo$`), "Bar")) +//HaveKeyWithValue succeeds if actual is a map with the passed in key and value. +//By default HaveKeyWithValue uses Equal() to perform the match, however a +//matcher can be passed in instead: +// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue("Foo", "Bar")) +// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue(MatchRegexp(`.+Foo$`), "Bar")) func HaveKeyWithValue(key interface{}, value interface{}) types.GomegaMatcher { return &matchers.HaveKeyWithValueMatcher{ Key: key, @@ -402,27 +376,27 @@ func HaveKeyWithValue(key interface{}, value interface{}) types.GomegaMatcher { } } -// HaveField succeeds if actual is a struct and the value at the passed in field -// matches the passed in matcher. By default HaveField used Equal() to perform the match, -// however a matcher can be passed in in stead. -// -// The field must be a string that resolves to the name of a field in the struct. Structs can be traversed -// using the '.' delimiter. If the field ends with '()' a method named field is assumed to exist on the struct and is invoked. -// Such methods must take no arguments and return a single value: -// -// type Book struct { -// Title string -// Author Person -// } -// type Person struct { -// FirstName string -// LastName string -// DOB time.Time -// } -// Expect(book).To(HaveField("Title", "Les Miserables")) -// Expect(book).To(HaveField("Title", ContainSubstring("Les")) -// Expect(book).To(HaveField("Author.FirstName", Equal("Victor")) -// Expect(book).To(HaveField("Author.DOB.Year()", BeNumerically("<", 1900)) +//HaveField succeeds if actual is a struct and the value at the passed in field +//matches the passed in matcher. By default HaveField used Equal() to perform the match, +//however a matcher can be passed in in stead. +// +//The field must be a string that resolves to the name of a field in the struct. Structs can be traversed +//using the '.' delimiter. If the field ends with '()' a method named field is assumed to exist on the struct and is invoked. +//Such methods must take no arguments and return a single value: +// +// type Book struct { +// Title string +// Author Person +// } +// type Person struct { +// FirstName string +// LastName string +// DOB time.Time +// } +// Expect(book).To(HaveField("Title", "Les Miserables")) +// Expect(book).To(HaveField("Title", ContainSubstring("Les")) +// Expect(book).To(HaveField("Author.FirstName", Equal("Victor")) +// Expect(book).To(HaveField("Author.DOB.Year()", BeNumerically("<", 1900)) func HaveField(field string, expected interface{}) types.GomegaMatcher { return &matchers.HaveFieldMatcher{ Field: field, @@ -436,7 +410,7 @@ func HaveField(field string, expected interface{}) types.GomegaMatcher { // HaveExistingField can be combined with HaveField in order to cover use cases // with optional fields. HaveField alone would trigger an error in such situations. // -// Expect(MrHarmless).NotTo(And(HaveExistingField("Title"), HaveField("Title", "Supervillain"))) +// Expect(MrHarmless).NotTo(And(HaveExistingField("Title"), HaveField("Title", "Supervillain"))) func HaveExistingField(field string) types.GomegaMatcher { return &matchers.HaveExistingFieldMatcher{ Field: field, @@ -454,27 +428,26 @@ func HaveExistingField(field string) types.GomegaMatcher { // be a pointer (as gstruct.PointTo does) but instead also accepts non-pointer // and even interface values. // -// actual := 42 -// Expect(actual).To(HaveValue(42)) -// Expect(&actual).To(HaveValue(42)) +// actual := 42 +// Expect(actual).To(HaveValue(42)) +// Expect(&actual).To(HaveValue(42)) func HaveValue(matcher types.GomegaMatcher) types.GomegaMatcher { return &matchers.HaveValueMatcher{ Matcher: matcher, } } -// BeNumerically performs numerical assertions in a type-agnostic way. -// Actual and expected should be numbers, though the specific type of -// number is irrelevant (float32, float64, uint8, etc...). -// -// There are six, self-explanatory, supported comparators: +//BeNumerically performs numerical assertions in a type-agnostic way. +//Actual and expected should be numbers, though the specific type of +//number is irrelevant (float32, float64, uint8, etc...). // -// Expect(1.0).Should(BeNumerically("==", 1)) -// Expect(1.0).Should(BeNumerically("~", 0.999, 0.01)) -// Expect(1.0).Should(BeNumerically(">", 0.9)) -// Expect(1.0).Should(BeNumerically(">=", 1.0)) -// Expect(1.0).Should(BeNumerically("<", 3)) -// Expect(1.0).Should(BeNumerically("<=", 1.0)) +//There are six, self-explanatory, supported comparators: +// Expect(1.0).Should(BeNumerically("==", 1)) +// Expect(1.0).Should(BeNumerically("~", 0.999, 0.01)) +// Expect(1.0).Should(BeNumerically(">", 0.9)) +// Expect(1.0).Should(BeNumerically(">=", 1.0)) +// Expect(1.0).Should(BeNumerically("<", 3)) +// Expect(1.0).Should(BeNumerically("<=", 1.0)) func BeNumerically(comparator string, compareTo ...interface{}) types.GomegaMatcher { return &matchers.BeNumericallyMatcher{ Comparator: comparator, @@ -482,11 +455,10 @@ func BeNumerically(comparator string, compareTo ...interface{}) types.GomegaMatc } } -// BeTemporally compares time.Time's like BeNumerically -// Actual and expected must be time.Time. The comparators are the same as for BeNumerically -// -// Expect(time.Now()).Should(BeTemporally(">", time.Time{})) -// Expect(time.Now()).Should(BeTemporally("~", time.Now(), time.Second)) +//BeTemporally compares time.Time's like BeNumerically +//Actual and expected must be time.Time. The comparators are the same as for BeNumerically +// Expect(time.Now()).Should(BeTemporally(">", time.Time{})) +// Expect(time.Now()).Should(BeTemporally("~", time.Now(), time.Second)) func BeTemporally(comparator string, compareTo time.Time, threshold ...time.Duration) types.GomegaMatcher { return &matchers.BeTemporallyMatcher{ Comparator: comparator, @@ -495,61 +467,58 @@ func BeTemporally(comparator string, compareTo time.Time, threshold ...time.Dura } } -// BeAssignableToTypeOf succeeds if actual is assignable to the type of expected. -// It will return an error when one of the values is nil. -// -// Expect(0).Should(BeAssignableToTypeOf(0)) // Same values -// Expect(5).Should(BeAssignableToTypeOf(-1)) // different values same type -// Expect("foo").Should(BeAssignableToTypeOf("bar")) // different values same type -// Expect(struct{ Foo string }{}).Should(BeAssignableToTypeOf(struct{ Foo string }{})) +//BeAssignableToTypeOf succeeds if actual is assignable to the type of expected. +//It will return an error when one of the values is nil. +// Expect(0).Should(BeAssignableToTypeOf(0)) // Same values +// Expect(5).Should(BeAssignableToTypeOf(-1)) // different values same type +// Expect("foo").Should(BeAssignableToTypeOf("bar")) // different values same type +// Expect(struct{ Foo string }{}).Should(BeAssignableToTypeOf(struct{ Foo string }{})) func BeAssignableToTypeOf(expected interface{}) types.GomegaMatcher { return &matchers.AssignableToTypeOfMatcher{ Expected: expected, } } -// Panic succeeds if actual is a function that, when invoked, panics. -// Actual must be a function that takes no arguments and returns no results. +//Panic succeeds if actual is a function that, when invoked, panics. +//Actual must be a function that takes no arguments and returns no results. func Panic() types.GomegaMatcher { return &matchers.PanicMatcher{} } -// PanicWith succeeds if actual is a function that, when invoked, panics with a specific value. -// Actual must be a function that takes no arguments and returns no results. +//PanicWith succeeds if actual is a function that, when invoked, panics with a specific value. +//Actual must be a function that takes no arguments and returns no results. // -// By default PanicWith uses Equal() to perform the match, however a -// matcher can be passed in instead: -// -// Expect(fn).Should(PanicWith(MatchRegexp(`.+Foo$`))) +//By default PanicWith uses Equal() to perform the match, however a +//matcher can be passed in instead: +// Expect(fn).Should(PanicWith(MatchRegexp(`.+Foo$`))) func PanicWith(expected interface{}) types.GomegaMatcher { return &matchers.PanicMatcher{Expected: expected} } -// BeAnExistingFile succeeds if a file exists. -// Actual must be a string representing the abs path to the file being checked. +//BeAnExistingFile succeeds if a file exists. +//Actual must be a string representing the abs path to the file being checked. func BeAnExistingFile() types.GomegaMatcher { return &matchers.BeAnExistingFileMatcher{} } -// BeARegularFile succeeds if a file exists and is a regular file. -// Actual must be a string representing the abs path to the file being checked. +//BeARegularFile succeeds if a file exists and is a regular file. +//Actual must be a string representing the abs path to the file being checked. func BeARegularFile() types.GomegaMatcher { return &matchers.BeARegularFileMatcher{} } -// BeADirectory succeeds if a file exists and is a directory. -// Actual must be a string representing the abs path to the file being checked. +//BeADirectory succeeds if a file exists and is a directory. +//Actual must be a string representing the abs path to the file being checked. func BeADirectory() types.GomegaMatcher { return &matchers.BeADirectoryMatcher{} } -// HaveHTTPStatus succeeds if the Status or StatusCode field of an HTTP response matches. -// Actual must be either a *http.Response or *httptest.ResponseRecorder. -// Expected must be either an int or a string. -// -// Expect(resp).Should(HaveHTTPStatus(http.StatusOK)) // asserts that resp.StatusCode == 200 -// Expect(resp).Should(HaveHTTPStatus("404 Not Found")) // asserts that resp.Status == "404 Not Found" -// Expect(resp).Should(HaveHTTPStatus(http.StatusOK, http.StatusNoContent)) // asserts that resp.StatusCode == 200 || resp.StatusCode == 204 +//HaveHTTPStatus succeeds if the Status or StatusCode field of an HTTP response matches. +//Actual must be either a *http.Response or *httptest.ResponseRecorder. +//Expected must be either an int or a string. +// Expect(resp).Should(HaveHTTPStatus(http.StatusOK)) // asserts that resp.StatusCode == 200 +// Expect(resp).Should(HaveHTTPStatus("404 Not Found")) // asserts that resp.Status == "404 Not Found" +// Expect(resp).Should(HaveHTTPStatus(http.StatusOK, http.StatusNoContent)) // asserts that resp.StatusCode == 200 || resp.StatusCode == 204 func HaveHTTPStatus(expected ...interface{}) types.GomegaMatcher { return &matchers.HaveHTTPStatusMatcher{Expected: expected} } @@ -572,70 +541,63 @@ func HaveHTTPBody(expected interface{}) types.GomegaMatcher { return &matchers.HaveHTTPBodyMatcher{Expected: expected} } -// And succeeds only if all of the given matchers succeed. -// The matchers are tried in order, and will fail-fast if one doesn't succeed. -// -// Expect("hi").To(And(HaveLen(2), Equal("hi")) +//And succeeds only if all of the given matchers succeed. +//The matchers are tried in order, and will fail-fast if one doesn't succeed. +// Expect("hi").To(And(HaveLen(2), Equal("hi")) // -// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. +//And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. func And(ms ...types.GomegaMatcher) types.GomegaMatcher { return &matchers.AndMatcher{Matchers: ms} } -// SatisfyAll is an alias for And(). -// -// Expect("hi").Should(SatisfyAll(HaveLen(2), Equal("hi"))) +//SatisfyAll is an alias for And(). +// Expect("hi").Should(SatisfyAll(HaveLen(2), Equal("hi"))) func SatisfyAll(matchers ...types.GomegaMatcher) types.GomegaMatcher { return And(matchers...) } -// Or succeeds if any of the given matchers succeed. -// The matchers are tried in order and will return immediately upon the first successful match. -// -// Expect("hi").To(Or(HaveLen(3), HaveLen(2)) +//Or succeeds if any of the given matchers succeed. +//The matchers are tried in order and will return immediately upon the first successful match. +// Expect("hi").To(Or(HaveLen(3), HaveLen(2)) // -// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. +//And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. func Or(ms ...types.GomegaMatcher) types.GomegaMatcher { return &matchers.OrMatcher{Matchers: ms} } -// SatisfyAny is an alias for Or(). -// -// Expect("hi").SatisfyAny(Or(HaveLen(3), HaveLen(2)) +//SatisfyAny is an alias for Or(). +// Expect("hi").SatisfyAny(Or(HaveLen(3), HaveLen(2)) func SatisfyAny(matchers ...types.GomegaMatcher) types.GomegaMatcher { return Or(matchers...) } -// Not negates the given matcher; it succeeds if the given matcher fails. -// -// Expect(1).To(Not(Equal(2)) +//Not negates the given matcher; it succeeds if the given matcher fails. +// Expect(1).To(Not(Equal(2)) // -// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. +//And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. func Not(matcher types.GomegaMatcher) types.GomegaMatcher { return &matchers.NotMatcher{Matcher: matcher} } -// WithTransform applies the `transform` to the actual value and matches it against `matcher`. -// The given transform must be either a function of one parameter that returns one value or a +//WithTransform applies the `transform` to the actual value and matches it against `matcher`. +//The given transform must be either a function of one parameter that returns one value or a // function of one parameter that returns two values, where the second value must be of the // error type. +// var plus1 = func(i int) int { return i + 1 } +// Expect(1).To(WithTransform(plus1, Equal(2)) // -// var plus1 = func(i int) int { return i + 1 } -// Expect(1).To(WithTransform(plus1, Equal(2)) +// var failingplus1 = func(i int) (int, error) { return 42, "this does not compute" } +// Expect(1).To(WithTransform(failingplus1, Equal(2))) // -// var failingplus1 = func(i int) (int, error) { return 42, "this does not compute" } -// Expect(1).To(WithTransform(failingplus1, Equal(2))) -// -// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. +//And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. func WithTransform(transform interface{}, matcher types.GomegaMatcher) types.GomegaMatcher { return matchers.NewWithTransformMatcher(transform, matcher) } -// Satisfy matches the actual value against the `predicate` function. -// The given predicate must be a function of one paramter that returns bool. -// -// var isEven = func(i int) bool { return i%2 == 0 } -// Expect(2).To(Satisfy(isEven)) +//Satisfy matches the actual value against the `predicate` function. +//The given predicate must be a function of one paramter that returns bool. +// var isEven = func(i int) bool { return i%2 == 0 } +// Expect(2).To(Satisfy(isEven)) func Satisfy(predicate interface{}) types.GomegaMatcher { return matchers.NewSatisfyMatcher(predicate) } diff --git a/vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go b/vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go deleted file mode 100644 index 449a291e..00000000 --- a/vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go +++ /dev/null @@ -1,45 +0,0 @@ -package matchers - -import ( - "fmt" - "reflect" - - "github.com/onsi/gomega/format" -) - -type BeKeyOfMatcher struct { - Map interface{} -} - -func (matcher *BeKeyOfMatcher) Match(actual interface{}) (success bool, err error) { - if !isMap(matcher.Map) { - return false, fmt.Errorf("BeKeyOf matcher needs expected to be a map type") - } - - if reflect.TypeOf(actual) == nil { - return false, fmt.Errorf("BeKeyOf matcher expects actual to be typed") - } - - var lastError error - for _, key := range reflect.ValueOf(matcher.Map).MapKeys() { - matcher := &EqualMatcher{Expected: key.Interface()} - success, err := matcher.Match(actual) - if err != nil { - lastError = err - continue - } - if success { - return true, nil - } - } - - return false, lastError -} - -func (matcher *BeKeyOfMatcher) FailureMessage(actual interface{}) (message string) { - return format.Message(actual, "to be a key of", presentable(valuesOf(matcher.Map))) -} - -func (matcher *BeKeyOfMatcher) NegatedFailureMessage(actual interface{}) (message string) { - return format.Message(actual, "not to be a key of", presentable(valuesOf(matcher.Map))) -} diff --git a/vendor/github.com/onsi/gomega/types/types.go b/vendor/github.com/onsi/gomega/types/types.go index 125de649..c315ef06 100644 --- a/vendor/github.com/onsi/gomega/types/types.go +++ b/vendor/github.com/onsi/gomega/types/types.go @@ -1,13 +1,12 @@ package types import ( - "context" "time" ) type GomegaFailHandler func(message string, callerSkip ...int) -// A simple *testing.T interface wrapper +//A simple *testing.T interface wrapper type GomegaTestingT interface { Helper() Fatalf(format string, args ...interface{}) @@ -19,11 +18,11 @@ type Gomega interface { Expect(actual interface{}, extra ...interface{}) Assertion ExpectWithOffset(offset int, actual interface{}, extra ...interface{}) Assertion - Eventually(actualOrCtx interface{}, args ...interface{}) AsyncAssertion - EventuallyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) AsyncAssertion + Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion + EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion - Consistently(actualOrCtx interface{}, args ...interface{}) AsyncAssertion - ConsistentlyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) AsyncAssertion + Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion + ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion SetDefaultEventuallyTimeout(time.Duration) SetDefaultEventuallyPollingInterval(time.Duration) @@ -31,9 +30,9 @@ type Gomega interface { SetDefaultConsistentlyPollingInterval(time.Duration) } -// All Gomega matchers must implement the GomegaMatcher interface +//All Gomega matchers must implement the GomegaMatcher interface // -// For details on writing custom matchers, check out: http://onsi.github.io/gomega/#adding-your-own-matchers +//For details on writing custom matchers, check out: http://onsi.github.io/gomega/#adding-your-own-matchers type GomegaMatcher interface { Match(actual interface{}) (success bool, err error) FailureMessage(actual interface{}) (message string) @@ -71,10 +70,6 @@ type AsyncAssertion interface { WithOffset(offset int) AsyncAssertion WithTimeout(interval time.Duration) AsyncAssertion WithPolling(interval time.Duration) AsyncAssertion - Within(timeout time.Duration) AsyncAssertion - ProbeEvery(interval time.Duration) AsyncAssertion - WithContext(ctx context.Context) AsyncAssertion - WithArguments(argsToForward ...interface{}) AsyncAssertion } // Assertions are returned by Ω and Expect and enable assertions against Gomega matchers diff --git a/vendor/golang.org/x/net/context/go17.go b/vendor/golang.org/x/net/context/go17.go index 2cb9c408..0a54bdbc 100644 --- a/vendor/golang.org/x/net/context/go17.go +++ b/vendor/golang.org/x/net/context/go17.go @@ -32,7 +32,7 @@ var DeadlineExceeded = context.DeadlineExceeded // call cancel as soon as the operations running in this Context complete. func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { ctx, f := context.WithCancel(parent) - return ctx, f + return ctx, CancelFunc(f) } // WithDeadline returns a copy of the parent context with the deadline adjusted @@ -46,7 +46,7 @@ func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { // call cancel as soon as the operations running in this Context complete. func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { ctx, f := context.WithDeadline(parent, deadline) - return ctx, f + return ctx, CancelFunc(f) } // WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go index 291c9190..038941d7 100644 --- a/vendor/golang.org/x/net/html/parse.go +++ b/vendor/golang.org/x/net/html/parse.go @@ -734,7 +734,7 @@ func inHeadIM(p *parser) bool { return false } -// Section 12.2.6.4.5. +// 12.2.6.4.5. func inHeadNoscriptIM(p *parser) bool { switch p.tok.Type { case DoctypeToken: diff --git a/vendor/golang.org/x/net/html/render.go b/vendor/golang.org/x/net/html/render.go index 497e1320..b46d81ca 100644 --- a/vendor/golang.org/x/net/html/render.go +++ b/vendor/golang.org/x/net/html/render.go @@ -85,7 +85,7 @@ func render1(w writer, n *Node) error { if _, err := w.WriteString(""); err != nil { @@ -96,7 +96,7 @@ func render1(w writer, n *Node) error { if _, err := w.WriteString("" case CommentToken: - return "" + return "" case DoctypeToken: - return "" + return "" } return "Invalid(" + strconv.Itoa(int(t.Type)) + ")" } @@ -605,10 +605,7 @@ func (z *Tokenizer) readComment() { z.data.end = z.data.start } }() - - var dashCount int - beginning := true - for { + for dashCount := 2; ; { c := z.readByte() if z.err != nil { // Ignore up to two dashes at EOF. @@ -623,7 +620,7 @@ func (z *Tokenizer) readComment() { dashCount++ continue case '>': - if dashCount >= 2 || beginning { + if dashCount >= 2 { z.data.end = z.raw.end - len("-->") return } @@ -641,7 +638,6 @@ func (z *Tokenizer) readComment() { } } dashCount = 0 - beginning = false } } diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index 184ac45f..0178647e 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -23,7 +23,7 @@ const frameHeaderLen = 9 var padZeros = make([]byte, 255) // zeros for padding // A FrameType is a registered frame type as defined in -// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2 +// http://http2.github.io/http2-spec/#rfc.section.11.2 type FrameType uint8 const ( @@ -146,7 +146,7 @@ func typeFrameParser(t FrameType) frameParser { // A FrameHeader is the 9 byte header of all HTTP/2 frames. // -// See https://httpwg.org/specs/rfc7540.html#FrameHeader +// See http://http2.github.io/http2-spec/#FrameHeader type FrameHeader struct { valid bool // caller can access []byte fields in the Frame @@ -575,7 +575,7 @@ func (fr *Framer) checkFrameOrder(f Frame) error { // A DataFrame conveys arbitrary, variable-length sequences of octets // associated with a stream. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1 +// See http://http2.github.io/http2-spec/#rfc.section.6.1 type DataFrame struct { FrameHeader data []byte @@ -698,7 +698,7 @@ func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []by // endpoints communicate, such as preferences and constraints on peer // behavior. // -// See https://httpwg.org/specs/rfc7540.html#SETTINGS +// See http://http2.github.io/http2-spec/#SETTINGS type SettingsFrame struct { FrameHeader p []byte @@ -837,7 +837,7 @@ func (f *Framer) WriteSettingsAck() error { // A PingFrame is a mechanism for measuring a minimal round trip time // from the sender, as well as determining whether an idle connection // is still functional. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7 +// See http://http2.github.io/http2-spec/#rfc.section.6.7 type PingFrame struct { FrameHeader Data [8]byte @@ -870,7 +870,7 @@ func (f *Framer) WritePing(ack bool, data [8]byte) error { } // A GoAwayFrame informs the remote peer to stop creating streams on this connection. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8 +// See http://http2.github.io/http2-spec/#rfc.section.6.8 type GoAwayFrame struct { FrameHeader LastStreamID uint32 @@ -934,7 +934,7 @@ func parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p } // A WindowUpdateFrame is used to implement flow control. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9 +// See http://http2.github.io/http2-spec/#rfc.section.6.9 type WindowUpdateFrame struct { FrameHeader Increment uint32 // never read with high bit set @@ -1123,7 +1123,7 @@ func (f *Framer) WriteHeaders(p HeadersFrameParam) error { } // A PriorityFrame specifies the sender-advised priority of a stream. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3 +// See http://http2.github.io/http2-spec/#rfc.section.6.3 type PriorityFrame struct { FrameHeader PriorityParam @@ -1193,7 +1193,7 @@ func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error { } // A RSTStreamFrame allows for abnormal termination of a stream. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4 +// See http://http2.github.io/http2-spec/#rfc.section.6.4 type RSTStreamFrame struct { FrameHeader ErrCode ErrCode @@ -1225,7 +1225,7 @@ func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error { } // A ContinuationFrame is used to continue a sequence of header block fragments. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10 +// See http://http2.github.io/http2-spec/#rfc.section.6.10 type ContinuationFrame struct { FrameHeader headerFragBuf []byte @@ -1266,7 +1266,7 @@ func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlock } // A PushPromiseFrame is used to initiate a server stream. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6 +// See http://http2.github.io/http2-spec/#rfc.section.6.6 type PushPromiseFrame struct { FrameHeader PromiseID uint32 diff --git a/vendor/golang.org/x/net/http2/headermap.go b/vendor/golang.org/x/net/http2/headermap.go index 149b3dd2..9e12941d 100644 --- a/vendor/golang.org/x/net/http2/headermap.go +++ b/vendor/golang.org/x/net/http2/headermap.go @@ -27,14 +27,7 @@ func buildCommonHeaderMaps() { "accept-language", "accept-ranges", "age", - "access-control-allow-credentials", - "access-control-allow-headers", - "access-control-allow-methods", "access-control-allow-origin", - "access-control-expose-headers", - "access-control-max-age", - "access-control-request-headers", - "access-control-request-method", "allow", "authorization", "cache-control", @@ -60,7 +53,6 @@ func buildCommonHeaderMaps() { "link", "location", "max-forwards", - "origin", "proxy-authenticate", "proxy-authorization", "range", @@ -76,8 +68,6 @@ func buildCommonHeaderMaps() { "vary", "via", "www-authenticate", - "x-forwarded-for", - "x-forwarded-proto", } commonLowerHeader = make(map[string]string, len(common)) commonCanonHeader = make(map[string]string, len(common)) @@ -95,11 +85,3 @@ func lowerHeader(v string) (lower string, ascii bool) { } return asciiToLower(v) } - -func canonicalHeader(v string) string { - buildCommonHeaderMapsOnce() - if s, ok := commonCanonHeader[v]; ok { - return s - } - return http.CanonicalHeaderKey(v) -} diff --git a/vendor/golang.org/x/net/http2/hpack/encode.go b/vendor/golang.org/x/net/http2/hpack/encode.go index 6886dc16..97f17831 100644 --- a/vendor/golang.org/x/net/http2/hpack/encode.go +++ b/vendor/golang.org/x/net/http2/hpack/encode.go @@ -191,7 +191,7 @@ func appendTableSize(dst []byte, v uint32) []byte { // bit prefix, to dst and returns the extended buffer. // // See -// https://httpwg.org/specs/rfc7541.html#integer.representation +// http://http2.github.io/http2-spec/compression.html#integer.representation func appendVarInt(dst []byte, n byte, i uint64) []byte { k := uint64((1 << n) - 1) if i < k { diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go index ebdfbee9..85f18a2b 100644 --- a/vendor/golang.org/x/net/http2/hpack/hpack.go +++ b/vendor/golang.org/x/net/http2/hpack/hpack.go @@ -59,7 +59,7 @@ func (hf HeaderField) String() string { // Size returns the size of an entry per RFC 7541 section 4.1. func (hf HeaderField) Size() uint32 { - // https://httpwg.org/specs/rfc7541.html#rfc.section.4.1 + // http://http2.github.io/http2-spec/compression.html#rfc.section.4.1 // "The size of the dynamic table is the sum of the size of // its entries. The size of an entry is the sum of its name's // length in octets (as defined in Section 5.2), its value's @@ -158,7 +158,7 @@ func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) { } type dynamicTable struct { - // https://httpwg.org/specs/rfc7541.html#rfc.section.2.3.2 + // http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2 table headerFieldTable size uint32 // in bytes maxSize uint32 // current maxSize @@ -307,27 +307,27 @@ func (d *Decoder) parseHeaderFieldRepr() error { case b&128 != 0: // Indexed representation. // High bit set? - // https://httpwg.org/specs/rfc7541.html#rfc.section.6.1 + // http://http2.github.io/http2-spec/compression.html#rfc.section.6.1 return d.parseFieldIndexed() case b&192 == 64: // 6.2.1 Literal Header Field with Incremental Indexing // 0b10xxxxxx: top two bits are 10 - // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1 + // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.1 return d.parseFieldLiteral(6, indexedTrue) case b&240 == 0: // 6.2.2 Literal Header Field without Indexing // 0b0000xxxx: top four bits are 0000 - // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2 + // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.2 return d.parseFieldLiteral(4, indexedFalse) case b&240 == 16: // 6.2.3 Literal Header Field never Indexed // 0b0001xxxx: top four bits are 0001 - // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3 + // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.3 return d.parseFieldLiteral(4, indexedNever) case b&224 == 32: // 6.3 Dynamic Table Size Update // Top three bits are '001'. - // https://httpwg.org/specs/rfc7541.html#rfc.section.6.3 + // http://http2.github.io/http2-spec/compression.html#rfc.section.6.3 return d.parseDynamicTableSizeUpdate() } @@ -420,7 +420,7 @@ var errVarintOverflow = DecodingError{errors.New("varint integer overflow")} // readVarInt reads an unsigned variable length integer off the // beginning of p. n is the parameter as described in -// https://httpwg.org/specs/rfc7541.html#rfc.section.5.1. +// http://http2.github.io/http2-spec/compression.html#rfc.section.5.1. // // n must always be between 1 and 8. // diff --git a/vendor/golang.org/x/net/http2/hpack/static_table.go b/vendor/golang.org/x/net/http2/hpack/static_table.go deleted file mode 100644 index 754a1eb9..00000000 --- a/vendor/golang.org/x/net/http2/hpack/static_table.go +++ /dev/null @@ -1,188 +0,0 @@ -// go generate gen.go -// Code generated by the command above; DO NOT EDIT. - -package hpack - -var staticTable = &headerFieldTable{ - evictCount: 0, - byName: map[string]uint64{ - ":authority": 1, - ":method": 3, - ":path": 5, - ":scheme": 7, - ":status": 14, - "accept-charset": 15, - "accept-encoding": 16, - "accept-language": 17, - "accept-ranges": 18, - "accept": 19, - "access-control-allow-origin": 20, - "age": 21, - "allow": 22, - "authorization": 23, - "cache-control": 24, - "content-disposition": 25, - "content-encoding": 26, - "content-language": 27, - "content-length": 28, - "content-location": 29, - "content-range": 30, - "content-type": 31, - "cookie": 32, - "date": 33, - "etag": 34, - "expect": 35, - "expires": 36, - "from": 37, - "host": 38, - "if-match": 39, - "if-modified-since": 40, - "if-none-match": 41, - "if-range": 42, - "if-unmodified-since": 43, - "last-modified": 44, - "link": 45, - "location": 46, - "max-forwards": 47, - "proxy-authenticate": 48, - "proxy-authorization": 49, - "range": 50, - "referer": 51, - "refresh": 52, - "retry-after": 53, - "server": 54, - "set-cookie": 55, - "strict-transport-security": 56, - "transfer-encoding": 57, - "user-agent": 58, - "vary": 59, - "via": 60, - "www-authenticate": 61, - }, - byNameValue: map[pairNameValue]uint64{ - {name: ":authority", value: ""}: 1, - {name: ":method", value: "GET"}: 2, - {name: ":method", value: "POST"}: 3, - {name: ":path", value: "/"}: 4, - {name: ":path", value: "/index.html"}: 5, - {name: ":scheme", value: "http"}: 6, - {name: ":scheme", value: "https"}: 7, - {name: ":status", value: "200"}: 8, - {name: ":status", value: "204"}: 9, - {name: ":status", value: "206"}: 10, - {name: ":status", value: "304"}: 11, - {name: ":status", value: "400"}: 12, - {name: ":status", value: "404"}: 13, - {name: ":status", value: "500"}: 14, - {name: "accept-charset", value: ""}: 15, - {name: "accept-encoding", value: "gzip, deflate"}: 16, - {name: "accept-language", value: ""}: 17, - {name: "accept-ranges", value: ""}: 18, - {name: "accept", value: ""}: 19, - {name: "access-control-allow-origin", value: ""}: 20, - {name: "age", value: ""}: 21, - {name: "allow", value: ""}: 22, - {name: "authorization", value: ""}: 23, - {name: "cache-control", value: ""}: 24, - {name: "content-disposition", value: ""}: 25, - {name: "content-encoding", value: ""}: 26, - {name: "content-language", value: ""}: 27, - {name: "content-length", value: ""}: 28, - {name: "content-location", value: ""}: 29, - {name: "content-range", value: ""}: 30, - {name: "content-type", value: ""}: 31, - {name: "cookie", value: ""}: 32, - {name: "date", value: ""}: 33, - {name: "etag", value: ""}: 34, - {name: "expect", value: ""}: 35, - {name: "expires", value: ""}: 36, - {name: "from", value: ""}: 37, - {name: "host", value: ""}: 38, - {name: "if-match", value: ""}: 39, - {name: "if-modified-since", value: ""}: 40, - {name: "if-none-match", value: ""}: 41, - {name: "if-range", value: ""}: 42, - {name: "if-unmodified-since", value: ""}: 43, - {name: "last-modified", value: ""}: 44, - {name: "link", value: ""}: 45, - {name: "location", value: ""}: 46, - {name: "max-forwards", value: ""}: 47, - {name: "proxy-authenticate", value: ""}: 48, - {name: "proxy-authorization", value: ""}: 49, - {name: "range", value: ""}: 50, - {name: "referer", value: ""}: 51, - {name: "refresh", value: ""}: 52, - {name: "retry-after", value: ""}: 53, - {name: "server", value: ""}: 54, - {name: "set-cookie", value: ""}: 55, - {name: "strict-transport-security", value: ""}: 56, - {name: "transfer-encoding", value: ""}: 57, - {name: "user-agent", value: ""}: 58, - {name: "vary", value: ""}: 59, - {name: "via", value: ""}: 60, - {name: "www-authenticate", value: ""}: 61, - }, - ents: []HeaderField{ - {Name: ":authority", Value: "", Sensitive: false}, - {Name: ":method", Value: "GET", Sensitive: false}, - {Name: ":method", Value: "POST", Sensitive: false}, - {Name: ":path", Value: "/", Sensitive: false}, - {Name: ":path", Value: "/index.html", Sensitive: false}, - {Name: ":scheme", Value: "http", Sensitive: false}, - {Name: ":scheme", Value: "https", Sensitive: false}, - {Name: ":status", Value: "200", Sensitive: false}, - {Name: ":status", Value: "204", Sensitive: false}, - {Name: ":status", Value: "206", Sensitive: false}, - {Name: ":status", Value: "304", Sensitive: false}, - {Name: ":status", Value: "400", Sensitive: false}, - {Name: ":status", Value: "404", Sensitive: false}, - {Name: ":status", Value: "500", Sensitive: false}, - {Name: "accept-charset", Value: "", Sensitive: false}, - {Name: "accept-encoding", Value: "gzip, deflate", Sensitive: false}, - {Name: "accept-language", Value: "", Sensitive: false}, - {Name: "accept-ranges", Value: "", Sensitive: false}, - {Name: "accept", Value: "", Sensitive: false}, - {Name: "access-control-allow-origin", Value: "", Sensitive: false}, - {Name: "age", Value: "", Sensitive: false}, - {Name: "allow", Value: "", Sensitive: false}, - {Name: "authorization", Value: "", Sensitive: false}, - {Name: "cache-control", Value: "", Sensitive: false}, - {Name: "content-disposition", Value: "", Sensitive: false}, - {Name: "content-encoding", Value: "", Sensitive: false}, - {Name: "content-language", Value: "", Sensitive: false}, - {Name: "content-length", Value: "", Sensitive: false}, - {Name: "content-location", Value: "", Sensitive: false}, - {Name: "content-range", Value: "", Sensitive: false}, - {Name: "content-type", Value: "", Sensitive: false}, - {Name: "cookie", Value: "", Sensitive: false}, - {Name: "date", Value: "", Sensitive: false}, - {Name: "etag", Value: "", Sensitive: false}, - {Name: "expect", Value: "", Sensitive: false}, - {Name: "expires", Value: "", Sensitive: false}, - {Name: "from", Value: "", Sensitive: false}, - {Name: "host", Value: "", Sensitive: false}, - {Name: "if-match", Value: "", Sensitive: false}, - {Name: "if-modified-since", Value: "", Sensitive: false}, - {Name: "if-none-match", Value: "", Sensitive: false}, - {Name: "if-range", Value: "", Sensitive: false}, - {Name: "if-unmodified-since", Value: "", Sensitive: false}, - {Name: "last-modified", Value: "", Sensitive: false}, - {Name: "link", Value: "", Sensitive: false}, - {Name: "location", Value: "", Sensitive: false}, - {Name: "max-forwards", Value: "", Sensitive: false}, - {Name: "proxy-authenticate", Value: "", Sensitive: false}, - {Name: "proxy-authorization", Value: "", Sensitive: false}, - {Name: "range", Value: "", Sensitive: false}, - {Name: "referer", Value: "", Sensitive: false}, - {Name: "refresh", Value: "", Sensitive: false}, - {Name: "retry-after", Value: "", Sensitive: false}, - {Name: "server", Value: "", Sensitive: false}, - {Name: "set-cookie", Value: "", Sensitive: false}, - {Name: "strict-transport-security", Value: "", Sensitive: false}, - {Name: "transfer-encoding", Value: "", Sensitive: false}, - {Name: "user-agent", Value: "", Sensitive: false}, - {Name: "vary", Value: "", Sensitive: false}, - {Name: "via", Value: "", Sensitive: false}, - {Name: "www-authenticate", Value: "", Sensitive: false}, - }, -} diff --git a/vendor/golang.org/x/net/http2/hpack/tables.go b/vendor/golang.org/x/net/http2/hpack/tables.go index 8cbdf3f0..a66cfbea 100644 --- a/vendor/golang.org/x/net/http2/hpack/tables.go +++ b/vendor/golang.org/x/net/http2/hpack/tables.go @@ -96,7 +96,8 @@ func (t *headerFieldTable) evictOldest(n int) { // meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic // table, the return value i actually refers to the entry t.ents[t.len()-i]. // -// All tables are assumed to be a dynamic tables except for the global staticTable. +// All tables are assumed to be a dynamic tables except for the global +// staticTable pointer. // // See Section 2.3.3. func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) { @@ -124,6 +125,81 @@ func (t *headerFieldTable) idToIndex(id uint64) uint64 { return k + 1 } +// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B +var staticTable = newStaticTable() +var staticTableEntries = [...]HeaderField{ + {Name: ":authority"}, + {Name: ":method", Value: "GET"}, + {Name: ":method", Value: "POST"}, + {Name: ":path", Value: "/"}, + {Name: ":path", Value: "/index.html"}, + {Name: ":scheme", Value: "http"}, + {Name: ":scheme", Value: "https"}, + {Name: ":status", Value: "200"}, + {Name: ":status", Value: "204"}, + {Name: ":status", Value: "206"}, + {Name: ":status", Value: "304"}, + {Name: ":status", Value: "400"}, + {Name: ":status", Value: "404"}, + {Name: ":status", Value: "500"}, + {Name: "accept-charset"}, + {Name: "accept-encoding", Value: "gzip, deflate"}, + {Name: "accept-language"}, + {Name: "accept-ranges"}, + {Name: "accept"}, + {Name: "access-control-allow-origin"}, + {Name: "age"}, + {Name: "allow"}, + {Name: "authorization"}, + {Name: "cache-control"}, + {Name: "content-disposition"}, + {Name: "content-encoding"}, + {Name: "content-language"}, + {Name: "content-length"}, + {Name: "content-location"}, + {Name: "content-range"}, + {Name: "content-type"}, + {Name: "cookie"}, + {Name: "date"}, + {Name: "etag"}, + {Name: "expect"}, + {Name: "expires"}, + {Name: "from"}, + {Name: "host"}, + {Name: "if-match"}, + {Name: "if-modified-since"}, + {Name: "if-none-match"}, + {Name: "if-range"}, + {Name: "if-unmodified-since"}, + {Name: "last-modified"}, + {Name: "link"}, + {Name: "location"}, + {Name: "max-forwards"}, + {Name: "proxy-authenticate"}, + {Name: "proxy-authorization"}, + {Name: "range"}, + {Name: "referer"}, + {Name: "refresh"}, + {Name: "retry-after"}, + {Name: "server"}, + {Name: "set-cookie"}, + {Name: "strict-transport-security"}, + {Name: "transfer-encoding"}, + {Name: "user-agent"}, + {Name: "vary"}, + {Name: "via"}, + {Name: "www-authenticate"}, +} + +func newStaticTable() *headerFieldTable { + t := &headerFieldTable{} + t.init() + for _, e := range staticTableEntries[:] { + t.addEntry(e) + } + return t +} + var huffmanCodes = [256]uint32{ 0x1ff8, 0x7fffd8, diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go index 6f2df281..479ba4b2 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -55,14 +55,14 @@ const ( ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" // SETTINGS_MAX_FRAME_SIZE default - // https://httpwg.org/specs/rfc7540.html#rfc.section.6.5.2 + // http://http2.github.io/http2-spec/#rfc.section.6.5.2 initialMaxFrameSize = 16384 // NextProtoTLS is the NPN/ALPN protocol negotiated during // HTTP/2's TLS setup. NextProtoTLS = "h2" - // https://httpwg.org/specs/rfc7540.html#SettingValues + // http://http2.github.io/http2-spec/#SettingValues initialHeaderTableSize = 4096 initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size @@ -111,7 +111,7 @@ func (st streamState) String() string { // Setting is a setting parameter: which setting it is, and its value. type Setting struct { // ID is which setting is being set. - // See https://httpwg.org/specs/rfc7540.html#SettingFormat + // See http://http2.github.io/http2-spec/#SettingValues ID SettingID // Val is the value. @@ -143,7 +143,7 @@ func (s Setting) Valid() error { } // A SettingID is an HTTP/2 setting as defined in -// https://httpwg.org/specs/rfc7540.html#iana-settings +// http://http2.github.io/http2-spec/#iana-settings type SettingID uint16 const ( diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index d8a17aa9..47524a61 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -143,7 +143,7 @@ type Server struct { } func (s *Server) initialConnRecvWindowSize() int32 { - if s.MaxUploadBufferPerConnection >= initialWindowSize { + if s.MaxUploadBufferPerConnection > initialWindowSize { return s.MaxUploadBufferPerConnection } return 1 << 20 @@ -622,9 +622,7 @@ type stream struct { resetQueued bool // RST_STREAM queued for write; set by sc.resetStream gotTrailerHeader bool // HEADER frame for trailers was seen wroteHeaders bool // whether we wrote headers (not status 100) - readDeadline *time.Timer // nil if unused writeDeadline *time.Timer // nil if unused - closeErr error // set before cw is closed trailer http.Header // accumulated trailers reqTrailer http.Header // handler's Request.Trailer @@ -950,8 +948,6 @@ func (sc *serverConn) serve() { } case *startPushRequest: sc.startPush(v) - case func(*serverConn): - v(sc) default: panic(fmt.Sprintf("unexpected type %T", v)) } @@ -1375,9 +1371,6 @@ func (sc *serverConn) startGracefulShutdownInternal() { func (sc *serverConn) goAway(code ErrCode) { sc.serveG.check() if sc.inGoAway { - if sc.goAwayCode == ErrCodeNo { - sc.goAwayCode = code - } return } sc.inGoAway = true @@ -1465,21 +1458,6 @@ func (sc *serverConn) processFrame(f Frame) error { sc.sawFirstSettings = true } - // Discard frames for streams initiated after the identified last - // stream sent in a GOAWAY, or all frames after sending an error. - // We still need to return connection-level flow control for DATA frames. - // RFC 9113 Section 6.8. - if sc.inGoAway && (sc.goAwayCode != ErrCodeNo || f.Header().StreamID > sc.maxClientStreamID) { - - if f, ok := f.(*DataFrame); ok { - if sc.inflow.available() < int32(f.Length) { - return sc.countError("data_flow", streamError(f.Header().StreamID, ErrCodeFlowControl)) - } - sc.sendWindowUpdate(nil, int(f.Length)) // conn-level - } - return nil - } - switch f := f.(type) { case *SettingsFrame: return sc.processSettings(f) @@ -1522,6 +1500,9 @@ func (sc *serverConn) processPing(f *PingFrame) error { // PROTOCOL_ERROR." return sc.countError("ping_on_stream", ConnectionError(ErrCodeProtocol)) } + if sc.inGoAway && sc.goAwayCode != ErrCodeNo { + return nil + } sc.writeFrame(FrameWriteRequest{write: writePingAck{f}}) return nil } @@ -1583,9 +1564,6 @@ func (sc *serverConn) closeStream(st *stream, err error) { panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state)) } st.state = stateClosed - if st.readDeadline != nil { - st.readDeadline.Stop() - } if st.writeDeadline != nil { st.writeDeadline.Stop() } @@ -1611,14 +1589,6 @@ func (sc *serverConn) closeStream(st *stream, err error) { p.CloseWithError(err) } - if e, ok := err.(StreamError); ok { - if e.Cause != nil { - err = e.Cause - } else { - err = errStreamClosed - } - } - st.closeErr = err st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc sc.writeSched.CloseStream(st.id) } @@ -1715,6 +1685,16 @@ func (sc *serverConn) processSettingInitialWindowSize(val uint32) error { func (sc *serverConn) processData(f *DataFrame) error { sc.serveG.check() id := f.Header().StreamID + if sc.inGoAway && (sc.goAwayCode != ErrCodeNo || id > sc.maxClientStreamID) { + // Discard all DATA frames if the GOAWAY is due to an + // error, or: + // + // Section 6.8: After sending a GOAWAY frame, the sender + // can discard frames for streams initiated by the + // receiver with identifiers higher than the identified + // last stream. + return nil + } data := f.Data() state, st := sc.state(id) @@ -1767,12 +1747,6 @@ func (sc *serverConn) processData(f *DataFrame) error { // Sender sending more than they'd declared? if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes { - if sc.inflow.available() < int32(f.Length) { - return sc.countError("data_flow", streamError(id, ErrCodeFlowControl)) - } - sc.inflow.take(int32(f.Length)) - sc.sendWindowUpdate(nil, int(f.Length)) // conn-level - st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes)) // RFC 7540, sec 8.1.2.6: A request or response is also malformed if the // value of a content-length header field does not equal the sum of the @@ -1857,27 +1831,19 @@ func (st *stream) copyTrailersToHandlerRequest() { } } -// onReadTimeout is run on its own goroutine (from time.AfterFunc) -// when the stream's ReadTimeout has fired. -func (st *stream) onReadTimeout() { - // Wrap the ErrDeadlineExceeded to avoid callers depending on us - // returning the bare error. - st.body.CloseWithError(fmt.Errorf("%w", os.ErrDeadlineExceeded)) -} - // onWriteTimeout is run on its own goroutine (from time.AfterFunc) // when the stream's WriteTimeout has fired. func (st *stream) onWriteTimeout() { - st.sc.writeFrameFromHandler(FrameWriteRequest{write: StreamError{ - StreamID: st.id, - Code: ErrCodeInternal, - Cause: os.ErrDeadlineExceeded, - }}) + st.sc.writeFrameFromHandler(FrameWriteRequest{write: streamError(st.id, ErrCodeInternal)}) } func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { sc.serveG.check() id := f.StreamID + if sc.inGoAway { + // Ignore. + return nil + } // http://tools.ietf.org/html/rfc7540#section-5.1.1 // Streams initiated by a client MUST use odd-numbered stream // identifiers. [...] An endpoint that receives an unexpected @@ -1980,9 +1946,6 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // (in Go 1.8), though. That's a more sane option anyway. if sc.hs.ReadTimeout != 0 { sc.conn.SetReadDeadline(time.Time{}) - if st.body != nil { - st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout) - } } go sc.runHandler(rw, req, handler) @@ -2051,6 +2014,9 @@ func (sc *serverConn) checkPriority(streamID uint32, p PriorityParam) error { } func (sc *serverConn) processPriority(f *PriorityFrame) error { + if sc.inGoAway { + return nil + } if err := sc.checkPriority(f.StreamID, f.PriorityParam); err != nil { return err } @@ -2124,6 +2090,12 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res return nil, nil, sc.countError("bad_path_method", streamError(f.StreamID, ErrCodeProtocol)) } + bodyOpen := !f.StreamEnded() + if rp.method == "HEAD" && bodyOpen { + // HEAD requests can't have bodies + return nil, nil, sc.countError("head_body", streamError(f.StreamID, ErrCodeProtocol)) + } + rp.header = make(http.Header) for _, hf := range f.RegularFields() { rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value) @@ -2136,7 +2108,6 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res if err != nil { return nil, nil, err } - bodyOpen := !f.StreamEnded() if bodyOpen { if vv, ok := rp.header["Content-Length"]; ok { if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil { @@ -2252,9 +2223,6 @@ func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler didPanic := true defer func() { rw.rws.stream.cancelCtx() - if req.MultipartForm != nil { - req.MultipartForm.RemoveAll() - } if didPanic { e := recover() sc.writeFrameFromHandler(FrameWriteRequest{ @@ -2366,7 +2334,7 @@ func (sc *serverConn) sendWindowUpdate(st *stream, n int) { // a larger Read than this. Very unlikely, but we handle it here // rather than elsewhere for now. const maxUint31 = 1<<31 - 1 - for n > maxUint31 { + for n >= maxUint31 { sc.sendWindowUpdate32(st, maxUint31) n -= maxUint31 } @@ -2486,15 +2454,7 @@ type responseWriterState struct { type chunkWriter struct{ rws *responseWriterState } -func (cw chunkWriter) Write(p []byte) (n int, err error) { - n, err = cw.rws.writeChunk(p) - if err == errStreamClosed { - // If writing failed because the stream has been closed, - // return the reason it was closed. - err = cw.rws.stream.closeErr - } - return n, err -} +func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) } func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 } @@ -2533,10 +2493,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { rws.writeHeader(200) } - if rws.handlerDone { - rws.promoteUndeclaredTrailers() - } - isHeadResp := rws.req.Method == "HEAD" if !rws.sentHeader { rws.sentHeader = true @@ -2608,6 +2564,10 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { return 0, nil } + if rws.handlerDone { + rws.promoteUndeclaredTrailers() + } + // only send trailers if they have actually been defined by the // server handler. hasNonemptyTrailers := rws.hasNonemptyTrailers() @@ -2688,85 +2648,23 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() { } } -func (w *responseWriter) SetReadDeadline(deadline time.Time) error { - st := w.rws.stream - if !deadline.IsZero() && deadline.Before(time.Now()) { - // If we're setting a deadline in the past, reset the stream immediately - // so writes after SetWriteDeadline returns will fail. - st.onReadTimeout() - return nil - } - w.rws.conn.sendServeMsg(func(sc *serverConn) { - if st.readDeadline != nil { - if !st.readDeadline.Stop() { - // Deadline already exceeded, or stream has been closed. - return - } - } - if deadline.IsZero() { - st.readDeadline = nil - } else if st.readDeadline == nil { - st.readDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onReadTimeout) - } else { - st.readDeadline.Reset(deadline.Sub(time.Now())) - } - }) - return nil -} - -func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { - st := w.rws.stream - if !deadline.IsZero() && deadline.Before(time.Now()) { - // If we're setting a deadline in the past, reset the stream immediately - // so writes after SetWriteDeadline returns will fail. - st.onWriteTimeout() - return nil - } - w.rws.conn.sendServeMsg(func(sc *serverConn) { - if st.writeDeadline != nil { - if !st.writeDeadline.Stop() { - // Deadline already exceeded, or stream has been closed. - return - } - } - if deadline.IsZero() { - st.writeDeadline = nil - } else if st.writeDeadline == nil { - st.writeDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onWriteTimeout) - } else { - st.writeDeadline.Reset(deadline.Sub(time.Now())) - } - }) - return nil -} - func (w *responseWriter) Flush() { - w.FlushError() -} - -func (w *responseWriter) FlushError() error { rws := w.rws if rws == nil { panic("Header called after Handler finished") } - var err error if rws.bw.Buffered() > 0 { - err = rws.bw.Flush() + if err := rws.bw.Flush(); err != nil { + // Ignore the error. The frame writer already knows. + return + } } else { // The bufio.Writer won't call chunkWriter.Write // (writeChunk with zero bytes, so we have to do it // ourselves to force the HTTP response header and/or // final DATA frame (with END_STREAM) to be sent. - _, err = chunkWriter{rws}.Write(nil) - if err == nil { - select { - case <-rws.stream.cw: - err = rws.stream.closeErr - default: - } - } + rws.writeChunk(nil) } - return err } func (w *responseWriter) CloseNotify() <-chan bool { diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 46dda4dc..4ded4dfd 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -16,7 +16,6 @@ import ( "errors" "fmt" "io" - "io/fs" "log" "math" mathrand "math/rand" @@ -68,23 +67,13 @@ const ( // A Transport internally caches connections to servers. It is safe // for concurrent use by multiple goroutines. type Transport struct { - // DialTLSContext specifies an optional dial function with context for - // creating TLS connections for requests. - // - // If DialTLSContext and DialTLS is nil, tls.Dial is used. - // - // If the returned net.Conn has a ConnectionState method like tls.Conn, - // it will be used to set http.Response.TLS. - DialTLSContext func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) - // DialTLS specifies an optional dial function for creating // TLS connections for requests. // - // If DialTLSContext and DialTLS is nil, tls.Dial is used. + // If DialTLS is nil, tls.Dial is used. // - // Deprecated: Use DialTLSContext instead, which allows the transport - // to cancel dials as soon as they are no longer needed. - // If both are set, DialTLSContext takes priority. + // If the returned net.Conn has a ConnectionState method like tls.Conn, + // it will be used to set http.Response.TLS. DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error) // TLSClientConfig specifies the TLS configuration to use with @@ -259,8 +248,7 @@ func (t *Transport) initConnPool() { // HTTP/2 server. type ClientConn struct { t *Transport - tconn net.Conn // usually *tls.Conn, except specialized impls - tconnClosed bool + tconn net.Conn // usually *tls.Conn, except specialized impls tlsState *tls.ConnectionState // nil only for specialized impls reused uint32 // whether conn is being reused; atomic singleUse bool // whether being used for a single http.Request @@ -346,8 +334,8 @@ type clientStream struct { readErr error // sticky read error; owned by transportResponseBody.Read reqBody io.ReadCloser - reqBodyContentLength int64 // -1 means unknown - reqBodyClosed chan struct{} // guarded by cc.mu; non-nil on Close, closed when done + reqBodyContentLength int64 // -1 means unknown + reqBodyClosed bool // body has been closed; guarded by cc.mu // owned by writeRequest: sentEndStream bool // sent an END_STREAM flag to the peer @@ -387,8 +375,9 @@ func (cs *clientStream) abortStreamLocked(err error) { cs.abortErr = err close(cs.abort) }) - if cs.reqBody != nil { - cs.closeReqBodyLocked() + if cs.reqBody != nil && !cs.reqBodyClosed { + cs.reqBody.Close() + cs.reqBodyClosed = true } // TODO(dneil): Clean up tests where cs.cc.cond is nil. if cs.cc.cond != nil { @@ -401,24 +390,13 @@ func (cs *clientStream) abortRequestBodyWrite() { cc := cs.cc cc.mu.Lock() defer cc.mu.Unlock() - if cs.reqBody != nil && cs.reqBodyClosed == nil { - cs.closeReqBodyLocked() + if cs.reqBody != nil && !cs.reqBodyClosed { + cs.reqBody.Close() + cs.reqBodyClosed = true cc.cond.Broadcast() } } -func (cs *clientStream) closeReqBodyLocked() { - if cs.reqBodyClosed != nil { - return - } - cs.reqBodyClosed = make(chan struct{}) - reqBodyClosed := cs.reqBodyClosed - go func() { - cs.reqBody.Close() - close(reqBodyClosed) - }() -} - type stickyErrWriter struct { conn net.Conn timeout time.Duration @@ -502,15 +480,6 @@ func authorityAddr(scheme string, authority string) (addr string) { return net.JoinHostPort(host, port) } -var retryBackoffHook func(time.Duration) *time.Timer - -func backoffNewTimer(d time.Duration) *time.Timer { - if retryBackoffHook != nil { - return retryBackoffHook(d) - } - return time.NewTimer(d) -} - // RoundTripOpt is like RoundTrip, but takes options. func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) { @@ -536,14 +505,11 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res } backoff := float64(uint(1) << (uint(retry) - 1)) backoff += backoff * (0.1 * mathrand.Float64()) - d := time.Second * time.Duration(backoff) - timer := backoffNewTimer(d) select { - case <-timer.C: + case <-time.After(time.Second * time.Duration(backoff)): t.vlogf("RoundTrip retrying after failure: %v", err) continue case <-req.Context().Done(): - timer.Stop() err = req.Context().Err() } } @@ -626,7 +592,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b if err != nil { return nil, err } - tconn, err := t.dialTLS(ctx, "tcp", addr, t.newTLSConfig(host)) + tconn, err := t.dialTLS(ctx)("tcp", addr, t.newTLSConfig(host)) if err != nil { return nil, err } @@ -647,25 +613,24 @@ func (t *Transport) newTLSConfig(host string) *tls.Config { return cfg } -func (t *Transport) dialTLS(ctx context.Context, network, addr string, tlsCfg *tls.Config) (net.Conn, error) { - if t.DialTLSContext != nil { - return t.DialTLSContext(ctx, network, addr, tlsCfg) - } else if t.DialTLS != nil { - return t.DialTLS(network, addr, tlsCfg) +func (t *Transport) dialTLS(ctx context.Context) func(string, string, *tls.Config) (net.Conn, error) { + if t.DialTLS != nil { + return t.DialTLS } - - tlsCn, err := t.dialTLSWithContext(ctx, network, addr, tlsCfg) - if err != nil { - return nil, err - } - state := tlsCn.ConnectionState() - if p := state.NegotiatedProtocol; p != NextProtoTLS { - return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, NextProtoTLS) - } - if !state.NegotiatedProtocolIsMutual { - return nil, errors.New("http2: could not negotiate protocol mutually") + return func(network, addr string, cfg *tls.Config) (net.Conn, error) { + tlsCn, err := t.dialTLSWithContext(ctx, network, addr, cfg) + if err != nil { + return nil, err + } + state := tlsCn.ConnectionState() + if p := state.NegotiatedProtocol; p != NextProtoTLS { + return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, NextProtoTLS) + } + if !state.NegotiatedProtocolIsMutual { + return nil, errors.New("http2: could not negotiate protocol mutually") + } + return tlsCn, nil } - return tlsCn, nil } // disableKeepAlives reports whether connections should be closed as @@ -945,10 +910,10 @@ func (cc *ClientConn) onIdleTimeout() { cc.closeIfIdle() } -func (cc *ClientConn) closeConn() { +func (cc *ClientConn) closeConn() error { t := time.AfterFunc(250*time.Millisecond, cc.forceCloseConn) defer t.Stop() - cc.tconn.Close() + return cc.tconn.Close() } // A tls.Conn.Close can hang for a long time if the peer is unresponsive. @@ -1014,8 +979,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { shutdownEnterWaitStateHook() select { case <-done: - cc.closeConn() - return nil + return cc.closeConn() case <-ctx.Done(): cc.mu.Lock() // Free the goroutine above @@ -1052,7 +1016,7 @@ func (cc *ClientConn) sendGoAway() error { // closes the client connection immediately. In-flight requests are interrupted. // err is sent to streams. -func (cc *ClientConn) closeForError(err error) { +func (cc *ClientConn) closeForError(err error) error { cc.mu.Lock() cc.closed = true for _, cs := range cc.streams { @@ -1060,7 +1024,7 @@ func (cc *ClientConn) closeForError(err error) { } cc.cond.Broadcast() cc.mu.Unlock() - cc.closeConn() + return cc.closeConn() } // Close closes the client connection immediately. @@ -1068,17 +1032,16 @@ func (cc *ClientConn) closeForError(err error) { // In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead. func (cc *ClientConn) Close() error { err := errors.New("http2: client connection force closed via ClientConn.Close") - cc.closeForError(err) - return nil + return cc.closeForError(err) } // closes the client connection immediately. In-flight requests are interrupted. -func (cc *ClientConn) closeForLostPing() { +func (cc *ClientConn) closeForLostPing() error { err := errors.New("http2: client connection lost") if f := cc.t.CountError; f != nil { f("conn_close_lost_ping") } - cc.closeForError(err) + return cc.closeForError(err) } // errRequestCanceled is a copy of net/http's errRequestCanceled because it's not @@ -1088,7 +1051,7 @@ var errRequestCanceled = errors.New("net/http: request canceled") func commaSeparatedTrailers(req *http.Request) (string, error) { keys := make([]string, 0, len(req.Trailer)) for k := range req.Trailer { - k = canonicalHeader(k) + k = http.CanonicalHeaderKey(k) switch k { case "Transfer-Encoding", "Trailer", "Content-Length": return "", fmt.Errorf("invalid Trailer key %q", k) @@ -1456,19 +1419,11 @@ func (cs *clientStream) cleanupWriteRequest(err error) { // and in multiple cases: server replies <=299 and >299 // while still writing request body cc.mu.Lock() - mustCloseBody := false - if cs.reqBody != nil && cs.reqBodyClosed == nil { - mustCloseBody = true - cs.reqBodyClosed = make(chan struct{}) - } bodyClosed := cs.reqBodyClosed + cs.reqBodyClosed = true cc.mu.Unlock() - if mustCloseBody { + if !bodyClosed && cs.reqBody != nil { cs.reqBody.Close() - close(bodyClosed) - } - if bodyClosed != nil { - <-bodyClosed } if err != nil && cs.sentEndStream { @@ -1625,7 +1580,7 @@ func (cs *clientStream) writeRequestBody(req *http.Request) (err error) { var sawEOF bool for !sawEOF { - n, err := body.Read(buf) + n, err := body.Read(buf[:len(buf)]) if hasContentLen { remainLen -= int64(n) if remainLen == 0 && err == nil { @@ -1648,7 +1603,7 @@ func (cs *clientStream) writeRequestBody(req *http.Request) (err error) { } if err != nil { cc.mu.Lock() - bodyClosed := cs.reqBodyClosed != nil + bodyClosed := cs.reqBodyClosed cc.mu.Unlock() switch { case bodyClosed: @@ -1743,7 +1698,7 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) if cc.closed { return 0, errClientConnClosed } - if cs.reqBodyClosed != nil { + if cs.reqBodyClosed { return 0, errStopReqBodyWrite } select { @@ -1928,7 +1883,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail // Header list size is ok. Write the headers. enumerateHeaders(func(name, value string) { - name, ascii := lowerHeader(name) + name, ascii := asciiToLower(name) if !ascii { // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header // field names have to be ASCII characters (just as in HTTP/1.x). @@ -1981,7 +1936,7 @@ func (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) { } for k, vv := range trailer { - lowKey, ascii := lowerHeader(k) + lowKey, ascii := asciiToLower(k) if !ascii { // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header // field names have to be ASCII characters (just as in HTTP/1.x). @@ -2039,7 +1994,7 @@ func (cc *ClientConn) forgetStreamID(id uint32) { // wake up RoundTrip if there is a pending request. cc.cond.Broadcast() - closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil + closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 { if VerboseLogs { cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, cc.nextStreamID-2) @@ -2115,7 +2070,6 @@ func (rl *clientConnReadLoop) cleanup() { err = io.ErrUnexpectedEOF } cc.closed = true - for _, cs := range cc.streams { select { case <-cs.peerClosed: @@ -2314,7 +2268,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra Status: status + " " + http.StatusText(statusCode), } for _, hf := range regularFields { - key := canonicalHeader(hf.Name) + key := http.CanonicalHeaderKey(hf.Name) if key == "Trailer" { t := res.Trailer if t == nil { @@ -2322,7 +2276,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra res.Trailer = t } foreachHeaderElement(hf.Value, func(v string) { - t[canonicalHeader(v)] = nil + t[http.CanonicalHeaderKey(v)] = nil }) } else { vv := header[key] @@ -2427,7 +2381,7 @@ func (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFr trailer := make(http.Header) for _, hf := range f.RegularFields() { - key := canonicalHeader(hf.Name) + key := http.CanonicalHeaderKey(hf.Name) trailer[key] = append(trailer[key], hf.Value) } cs.trailer = trailer @@ -2709,6 +2663,7 @@ func (rl *clientConnReadLoop) processGoAway(f *GoAwayFrame) error { if fn := cc.t.CountError; fn != nil { fn("recv_goaway_" + f.ErrCode.stringToken()) } + } cc.setGoAway(f) return nil @@ -2998,11 +2953,7 @@ func (gz *gzipReader) Read(p []byte) (n int, err error) { } func (gz *gzipReader) Close() error { - if err := gz.body.Close(); err != nil { - return err - } - gz.zerr = fs.ErrClosed - return nil + return gz.body.Close() } type errorReader struct{ err error } @@ -3066,7 +3017,7 @@ func traceGotConn(req *http.Request, cc *ClientConn, reused bool) { cc.mu.Lock() ci.WasIdle = len(cc.streams) == 0 && reused if ci.WasIdle && !cc.lastActive.IsZero() { - ci.IdleTime = time.Since(cc.lastActive) + ci.IdleTime = time.Now().Sub(cc.lastActive) } cc.mu.Unlock() diff --git a/vendor/golang.org/x/net/trace/trace.go b/vendor/golang.org/x/net/trace/trace.go index eae2a99f..3ebf6f2d 100644 --- a/vendor/golang.org/x/net/trace/trace.go +++ b/vendor/golang.org/x/net/trace/trace.go @@ -395,7 +395,7 @@ func New(family, title string) Trace { } func (tr *trace) Finish() { - elapsed := time.Since(tr.Start) + elapsed := time.Now().Sub(tr.Start) tr.mu.Lock() tr.Elapsed = elapsed tr.mu.Unlock() diff --git a/vendor/golang.org/x/text/AUTHORS b/vendor/golang.org/x/text/AUTHORS new file mode 100644 index 00000000..15167cd7 --- /dev/null +++ b/vendor/golang.org/x/text/AUTHORS @@ -0,0 +1,3 @@ +# This source code refers to The Go Authors for copyright purposes. +# The master list of authors is in the main Go distribution, +# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/text/CONTRIBUTORS b/vendor/golang.org/x/text/CONTRIBUTORS new file mode 100644 index 00000000..1c4577e9 --- /dev/null +++ b/vendor/golang.org/x/text/CONTRIBUTORS @@ -0,0 +1,3 @@ +# This source code was written by the Go contributors. +# The master list of contributors is in the main Go distribution, +# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/text/encoding/htmlindex/tables.go b/vendor/golang.org/x/text/encoding/htmlindex/tables.go index 9e6daa89..f074e2c6 100644 --- a/vendor/golang.org/x/text/encoding/htmlindex/tables.go +++ b/vendor/golang.org/x/text/encoding/htmlindex/tables.go @@ -93,11 +93,8 @@ var canonical = [numEncodings]string{ var nameMap = map[string]htmlEncoding{ "unicode-1-1-utf-8": utf8, - "unicode11utf8": utf8, - "unicode20utf8": utf8, "utf-8": utf8, "utf8": utf8, - "x-unicode20utf8": utf8, "866": ibm866, "cp866": ibm866, "csibm866": ibm866, @@ -310,13 +307,7 @@ var nameMap = map[string]htmlEncoding{ "iso-2022-cn-ext": replacement, "iso-2022-kr": replacement, "replacement": replacement, - "unicodefffe": utf16be, "utf-16be": utf16be, - "csunicode": utf16le, - "iso-10646-ucs-2": utf16le, - "ucs-2": utf16le, - "unicode": utf16le, - "unicodefeff": utf16le, "utf-16": utf16le, "utf-16le": utf16le, "x-user-defined": xUserDefined, diff --git a/vendor/golang.org/x/text/encoding/internal/identifier/mib.go b/vendor/golang.org/x/text/encoding/internal/identifier/mib.go index 351fb86e..fc7df1bc 100644 --- a/vendor/golang.org/x/text/encoding/internal/identifier/mib.go +++ b/vendor/golang.org/x/text/encoding/internal/identifier/mib.go @@ -905,14 +905,6 @@ const ( // https://www.unicode.org/notes/tn6/ BOCU1 MIB = 1020 - // UTF7IMAP is the MIB identifier with IANA name UTF-7-IMAP. - // - // Note: This charset is used to encode Unicode in IMAP mailbox names; - // see section 5.1.3 of rfc3501 . It should never be used - // outside this context. A name has been assigned so that charset processing - // implementations can refer to it in a consistent way. - UTF7IMAP MIB = 1021 - // Windows30Latin1 is the MIB identifier with IANA name ISO-8859-1-Windows-3.0-Latin-1. // // Extended ISO 8859-1 Latin-1 for Windows 3.0. diff --git a/vendor/golang.org/x/text/encoding/simplifiedchinese/gbk.go b/vendor/golang.org/x/text/encoding/simplifiedchinese/gbk.go index 0e0fabfd..b89c45b0 100644 --- a/vendor/golang.org/x/text/encoding/simplifiedchinese/gbk.go +++ b/vendor/golang.org/x/text/encoding/simplifiedchinese/gbk.go @@ -55,8 +55,6 @@ loop: // Microsoft's Code Page 936 extends GBK 1.0 to encode the euro sign U+20AC // as 0x80. The HTML5 specification at http://encoding.spec.whatwg.org/#gbk // says to treat "gbk" as Code Page 936. - // GBK’s decoder is gb18030’s decoder. https://encoding.spec.whatwg.org/#gbk-decoder - // If byte is 0x80, return code point U+20AC. https://encoding.spec.whatwg.org/#gb18030-decoder case c0 == 0x80: r, size = '€', 1 @@ -182,9 +180,7 @@ func (e gbkEncoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err // Microsoft's Code Page 936 extends GBK 1.0 to encode the euro sign U+20AC // as 0x80. The HTML5 specification at http://encoding.spec.whatwg.org/#gbk // says to treat "gbk" as Code Page 936. - // GBK’s encoder is gb18030’s encoder with its _is GBK_ set to true. https://encoding.spec.whatwg.org/#gbk-encoder - // If _is GBK_ is true and code point is U+20AC, return byte 0x80. https://encoding.spec.whatwg.org/#gb18030-encoder - if !e.gb18030 && r == '€' { + if r == '€' { r = 0x80 goto write1 } diff --git a/vendor/golang.org/x/text/internal/language/compact/tables.go b/vendor/golang.org/x/text/internal/language/compact/tables.go index 32af9de5..fe7ad9ea 100644 --- a/vendor/golang.org/x/text/internal/language/compact/tables.go +++ b/vendor/golang.org/x/text/internal/language/compact/tables.go @@ -966,7 +966,7 @@ var coreTags = []language.CompactCoreInfo{ // 773 elements 0x3fd00000, 0x3fd00072, 0x3fd000da, 0x3fd0010c, 0x3ff00000, 0x3ff000d1, 0x40100000, 0x401000c3, 0x40200000, 0x4020004c, 0x40700000, 0x40800000, - 0x4085a000, 0x4085a0ba, 0x408e8000, 0x408e80ba, + 0x4085a000, 0x4085a0ba, 0x408e3000, 0x408e30ba, 0x40c00000, 0x40c000b3, 0x41200000, 0x41200111, 0x41600000, 0x4160010f, 0x41c00000, 0x41d00000, // Entry 280 - 29F @@ -994,7 +994,7 @@ var coreTags = []language.CompactCoreInfo{ // 773 elements 0x4ae00130, 0x4b400000, 0x4b400099, 0x4b4000e8, 0x4bc00000, 0x4bc05000, 0x4bc05024, 0x4bc20000, 0x4bc20137, 0x4bc5a000, 0x4bc5a137, 0x4be00000, - 0x4be5a000, 0x4be5a0b4, 0x4bef1000, 0x4bef10b4, + 0x4be5a000, 0x4be5a0b4, 0x4beeb000, 0x4beeb0b4, 0x4c000000, 0x4c300000, 0x4c30013e, 0x4c900000, // Entry 2E0 - 2FF 0x4c900001, 0x4cc00000, 0x4cc0012f, 0x4ce00000, @@ -1012,4 +1012,4 @@ var coreTags = []language.CompactCoreInfo{ // 773 elements const specialTagsStr string = "ca-ES-valencia en-US-u-va-posix" -// Total table size 3147 bytes (3KiB); checksum: 6772C83C +// Total table size 3147 bytes (3KiB); checksum: BE816D44 diff --git a/vendor/golang.org/x/text/internal/language/lookup.go b/vendor/golang.org/x/text/internal/language/lookup.go index 231b4fbd..6294b815 100644 --- a/vendor/golang.org/x/text/internal/language/lookup.go +++ b/vendor/golang.org/x/text/internal/language/lookup.go @@ -50,7 +50,7 @@ func (id Language) Canonicalize() (Language, AliasType) { return normLang(id) } -// normLang returns the mapped langID of id according to mapping m. +// mapLang returns the mapped langID of id according to mapping m. func normLang(id Language) (Language, AliasType) { k := sort.Search(len(AliasMap), func(i int) bool { return AliasMap[i].From >= uint16(id) @@ -328,7 +328,7 @@ func (r Region) IsPrivateUse() bool { return r.typ()&iso3166UserAssigned != 0 } -type Script uint16 +type Script uint8 // getScriptID returns the script id for string s. It assumes that s // is of the format [A-Z][a-z]{3}. diff --git a/vendor/golang.org/x/text/internal/language/parse.go b/vendor/golang.org/x/text/internal/language/parse.go index aad1e0ac..47ee0fed 100644 --- a/vendor/golang.org/x/text/internal/language/parse.go +++ b/vendor/golang.org/x/text/internal/language/parse.go @@ -270,7 +270,7 @@ func parse(scan *scanner, s string) (t Tag, err error) { } else if n >= 4 { return Und, ErrSyntax } else { // the usual case - t, end = parseTag(scan, true) + t, end = parseTag(scan) if n := len(scan.token); n == 1 { t.pExt = uint16(end) end = parseExtensions(scan) @@ -296,8 +296,7 @@ func parse(scan *scanner, s string) (t Tag, err error) { // parseTag parses language, script, region and variants. // It returns a Tag and the end position in the input that was parsed. -// If doNorm is true, then - will be normalized to . -func parseTag(scan *scanner, doNorm bool) (t Tag, end int) { +func parseTag(scan *scanner) (t Tag, end int) { var e error // TODO: set an error if an unknown lang, script or region is encountered. t.LangID, e = getLangID(scan.token) @@ -308,17 +307,14 @@ func parseTag(scan *scanner, doNorm bool) (t Tag, end int) { for len(scan.token) == 3 && isAlpha(scan.token[0]) { // From http://tools.ietf.org/html/bcp47, - tags are equivalent // to a tag of the form . - if doNorm { - lang, e := getLangID(scan.token) - if lang != 0 { - t.LangID = lang - langStr := lang.String() - copy(scan.b[langStart:], langStr) - scan.b[langStart+len(langStr)] = '-' - scan.start = langStart + len(langStr) + 1 - } - scan.gobble(e) + lang, e := getLangID(scan.token) + if lang != 0 { + t.LangID = lang + copy(scan.b[langStart:], lang.String()) + scan.b[langStart+3] = '-' + scan.start = langStart + 4 } + scan.gobble(e) end = scan.scan() } if len(scan.token) == 4 && isAlpha(scan.token[0]) { @@ -563,7 +559,7 @@ func parseExtension(scan *scanner) int { case 't': // https://www.ietf.org/rfc/rfc6497.txt scan.scan() if n := len(scan.token); n >= 2 && n <= 3 && isAlpha(scan.token[1]) { - _, end = parseTag(scan, false) + _, end = parseTag(scan) scan.toLower(start, end) } for len(scan.token) == 2 && !isAlpha(scan.token[1]) { diff --git a/vendor/golang.org/x/text/internal/language/tables.go b/vendor/golang.org/x/text/internal/language/tables.go index fb6b5837..a19480c5 100644 --- a/vendor/golang.org/x/text/internal/language/tables.go +++ b/vendor/golang.org/x/text/internal/language/tables.go @@ -7,9 +7,9 @@ import "golang.org/x/text/internal/tag" // CLDRVersion is the CLDR version from which the tables in this package are derived. const CLDRVersion = "32" -const NumLanguages = 8752 +const NumLanguages = 8717 -const NumScripts = 258 +const NumScripts = 251 const NumRegions = 357 @@ -121,10 +121,9 @@ const langPrivateEnd = 0x3179 // lang holds an alphabetically sorted list of ISO-639 language identifiers. // All entries are 4 bytes. The index of the identifier (divided by 4) is the language tag. // For 2-byte language identifiers, the two successive bytes have the following meaning: -// - if the first letter of the 2- and 3-letter ISO codes are the same: -// the second and third letter of the 3-letter ISO code. -// - otherwise: a 0 and a by 2 bits right-shifted index into altLangISO3. -// +// - if the first letter of the 2- and 3-letter ISO codes are the same: +// the second and third letter of the 3-letter ISO code. +// - otherwise: a 0 and a by 2 bits right-shifted index into altLangISO3. // For 3-byte language identifiers the 4th byte is 0. const lang tag.Index = "" + // Size: 5324 bytes "---\x00aaaraai\x00aak\x00aau\x00abbkabi\x00abq\x00abr\x00abt\x00aby\x00a" + @@ -266,7 +265,7 @@ var langNoIndex = [2197]uint8{ 0xad, 0x03, 0xff, 0xff, 0xcf, 0x05, 0x84, 0x62, 0xe9, 0xbf, 0xfd, 0xbf, 0xbf, 0xf7, 0xfd, 0x77, 0x0f, 0xff, 0xef, 0x6f, 0xff, 0xfb, 0xdf, 0xe2, - 0xc9, 0xf8, 0x7f, 0x7e, 0x4d, 0xbc, 0x0a, 0x6a, + 0xc9, 0xf8, 0x7f, 0x7e, 0x4d, 0xb8, 0x0a, 0x6a, 0x7c, 0xea, 0xe3, 0xfa, 0x7a, 0xbf, 0x67, 0xff, // Entry 40 - 7F 0xff, 0xff, 0xff, 0xdf, 0x2a, 0x54, 0x91, 0xc0, @@ -278,7 +277,7 @@ var langNoIndex = [2197]uint8{ 0xa8, 0xff, 0x1f, 0x67, 0x7d, 0xeb, 0xef, 0xce, 0xff, 0xff, 0x9f, 0xff, 0xb7, 0xef, 0xfe, 0xcf, // Entry 80 - BF - 0xdb, 0xff, 0xf3, 0xcd, 0xfb, 0x6f, 0xff, 0xff, + 0xdb, 0xff, 0xf3, 0xcd, 0xfb, 0x2f, 0xff, 0xff, 0xbb, 0xee, 0xf7, 0xbd, 0xdb, 0xff, 0x5f, 0xf7, 0xfd, 0xf2, 0xfd, 0xff, 0x5e, 0x2f, 0x3b, 0xba, 0x7e, 0xff, 0xff, 0xfe, 0xf7, 0xff, 0xdd, 0xff, @@ -291,15 +290,15 @@ var langNoIndex = [2197]uint8{ 0x1b, 0x14, 0x08, 0xf3, 0x2b, 0xe7, 0x17, 0x56, 0x05, 0x7d, 0x0e, 0x1c, 0x37, 0x7b, 0xf3, 0xef, 0x97, 0xff, 0x5d, 0x38, 0x64, 0x08, 0x00, 0x10, - 0xbc, 0x85, 0xaf, 0xdf, 0xff, 0xff, 0x7b, 0x35, - 0x3e, 0xc7, 0xc7, 0xdf, 0xff, 0x01, 0x81, 0x00, + 0xbc, 0x85, 0xaf, 0xdf, 0xff, 0xff, 0x73, 0x35, + 0x3e, 0x87, 0xc7, 0xdf, 0xff, 0x01, 0x81, 0x00, 0xb0, 0x05, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x40, 0x00, 0x40, 0x92, 0x21, 0x50, 0xb1, 0x5d, // Entry 100 - 13F 0xfd, 0xdc, 0xbe, 0x5e, 0x00, 0x00, 0x02, 0x64, 0x0d, 0x19, 0x41, 0xdf, 0x79, 0x22, 0x00, 0x00, 0x00, 0x5e, 0x64, 0xdc, 0x24, 0xe5, 0xd9, 0xe3, - 0xfe, 0xff, 0xfd, 0xcb, 0x9f, 0x14, 0x41, 0x0c, + 0xfe, 0xff, 0xfd, 0xcb, 0x9f, 0x14, 0x01, 0x0c, 0x86, 0x00, 0xd1, 0x00, 0xf0, 0xc7, 0x67, 0x5f, 0x56, 0x99, 0x5e, 0xb5, 0x6c, 0xaf, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x37, 0xda, 0x56, @@ -310,9 +309,9 @@ var langNoIndex = [2197]uint8{ 0x0a, 0x00, 0x01, 0x00, 0x00, 0x10, 0x11, 0x09, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x44, 0x00, 0x00, 0x10, 0x00, 0x04, - 0x08, 0x00, 0x00, 0x05, 0x00, 0x80, 0x28, 0x04, + 0x08, 0x00, 0x00, 0x04, 0x00, 0x80, 0x28, 0x04, 0x00, 0x00, 0x40, 0xd5, 0x2d, 0x00, 0x64, 0x35, - 0x24, 0x52, 0xf4, 0xd5, 0xbf, 0x62, 0xc9, 0x03, + 0x24, 0x52, 0xf4, 0xd4, 0xbd, 0x62, 0xc9, 0x03, // Entry 180 - 1BF 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x13, 0x39, 0x01, 0xdd, 0x57, 0x98, @@ -334,20 +333,20 @@ var langNoIndex = [2197]uint8{ // Entry 200 - 23F 0xdf, 0xc3, 0x83, 0x82, 0xc0, 0xfb, 0x57, 0x27, 0xed, 0x55, 0xe7, 0x01, 0x00, 0x20, 0xb2, 0xc5, - 0xa4, 0x45, 0x25, 0x9b, 0x02, 0xdf, 0xe1, 0xdf, - 0x03, 0x44, 0x08, 0x90, 0x01, 0x04, 0x81, 0xe3, + 0xa4, 0x45, 0x25, 0x9b, 0x02, 0xdf, 0xe0, 0xdf, + 0x03, 0x44, 0x08, 0x90, 0x01, 0x04, 0x01, 0xe3, 0x92, 0x54, 0xdb, 0x28, 0xd3, 0x5f, 0xfe, 0x6d, 0x79, 0xed, 0x1c, 0x7d, 0x04, 0x08, 0x00, 0x01, 0x21, 0x12, 0x64, 0x5f, 0xdd, 0x0e, 0x85, 0x4f, 0x40, 0x40, 0x00, 0x04, 0xf1, 0xfd, 0x3d, 0x54, // Entry 240 - 27F 0xe8, 0x03, 0xb4, 0x27, 0x23, 0x0d, 0x00, 0x00, - 0x20, 0x7b, 0x78, 0x02, 0x07, 0x84, 0x00, 0xf0, + 0x20, 0x7b, 0x78, 0x02, 0x05, 0x84, 0x00, 0xf0, 0xbb, 0x7e, 0x5a, 0x00, 0x18, 0x04, 0x81, 0x00, 0x00, 0x00, 0x80, 0x10, 0x90, 0x1c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x04, 0x08, 0xa0, 0x70, 0xa5, 0x0c, 0x40, 0x00, 0x00, - 0x91, 0x24, 0x04, 0x68, 0x00, 0x20, 0x70, 0xff, + 0x11, 0x24, 0x04, 0x68, 0x00, 0x20, 0x70, 0xff, 0x7b, 0x7f, 0x70, 0x00, 0x05, 0x9b, 0xdd, 0x66, // Entry 280 - 2BF 0x03, 0x00, 0x11, 0x00, 0x00, 0x00, 0x40, 0x05, @@ -366,12 +365,12 @@ var langNoIndex = [2197]uint8{ 0xa7, 0x81, 0x47, 0x97, 0xfb, 0x00, 0x10, 0x00, 0x08, 0x00, 0x80, 0x00, 0x40, 0x04, 0x00, 0x01, 0x02, 0x00, 0x01, 0x40, 0x80, 0x00, 0x00, 0x08, - 0xd8, 0xeb, 0xf6, 0x39, 0xc4, 0x8d, 0x12, 0x00, + 0xd8, 0xeb, 0xf6, 0x39, 0xc4, 0x89, 0x12, 0x00, // Entry 300 - 33F 0x00, 0x0c, 0x04, 0x01, 0x20, 0x20, 0xdd, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x04, 0x10, 0xd0, 0x9d, 0x95, 0x13, 0x04, 0x80, - 0x00, 0x01, 0xd0, 0x16, 0x40, 0x00, 0x10, 0xb0, + 0x00, 0x01, 0xd0, 0x12, 0x40, 0x00, 0x10, 0xb0, 0x10, 0x62, 0x4c, 0xd2, 0x02, 0x01, 0x4a, 0x00, 0x46, 0x04, 0x00, 0x08, 0x02, 0x00, 0x20, 0x80, 0x00, 0x80, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, @@ -398,9 +397,9 @@ var langNoIndex = [2197]uint8{ 0x02, 0x30, 0x9f, 0x7a, 0x16, 0xbd, 0x7f, 0x57, 0xf2, 0xff, 0x31, 0xff, 0xf2, 0x1e, 0x90, 0xf7, 0xf1, 0xf9, 0x45, 0x80, 0x01, 0x02, 0x00, 0x00, - 0x40, 0x54, 0x9f, 0x8a, 0xdb, 0xf9, 0x2e, 0x11, + 0x40, 0x54, 0x9f, 0x8a, 0xd9, 0xf9, 0x2e, 0x11, 0x86, 0x51, 0xc0, 0xf3, 0xfb, 0x47, 0x40, 0x01, - 0x05, 0xd1, 0x50, 0x5c, 0x00, 0x40, 0x00, 0x10, + 0x05, 0xd1, 0x50, 0x5c, 0x00, 0x00, 0x00, 0x10, 0x04, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x17, 0xd2, 0xb9, 0xfd, 0xfc, 0xba, 0xfe, 0xef, 0xc7, 0xbe, // Entry 400 - 43F @@ -422,19 +421,19 @@ var langNoIndex = [2197]uint8{ 0xcd, 0xff, 0xfb, 0xff, 0xdf, 0xd7, 0xea, 0xff, 0xe5, 0x5f, 0x6d, 0x0f, 0xa7, 0x51, 0x06, 0xc4, // Entry 480 - 4BF - 0x93, 0x50, 0x5d, 0xaf, 0xa6, 0xff, 0x99, 0xfb, + 0x13, 0x50, 0x5d, 0xaf, 0xa6, 0xff, 0x99, 0xfb, 0x63, 0x1d, 0x53, 0xff, 0xef, 0xb7, 0x35, 0x20, 0x14, 0x00, 0x55, 0x51, 0x82, 0x65, 0xf5, 0x41, 0xe2, 0xff, 0xfc, 0xdf, 0x02, 0x05, 0xc5, 0x05, - 0x00, 0x22, 0x00, 0x74, 0x69, 0x10, 0x08, 0x05, + 0x00, 0x22, 0x00, 0x74, 0x69, 0x10, 0x08, 0x04, 0x41, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x20, 0x05, 0x04, 0x01, 0x00, 0x00, - 0x06, 0x01, 0x20, 0x00, 0x18, 0x01, 0x92, 0xf1, + 0x06, 0x01, 0x20, 0x00, 0x18, 0x01, 0x92, 0xb1, // Entry 4C0 - 4FF - 0xfd, 0x47, 0x69, 0x06, 0x95, 0x06, 0x57, 0xed, - 0xfb, 0x4d, 0x1c, 0x6b, 0x83, 0x04, 0x62, 0x40, + 0xfd, 0x47, 0x49, 0x06, 0x95, 0x06, 0x57, 0xed, + 0xfb, 0x4c, 0x1c, 0x6b, 0x83, 0x04, 0x62, 0x40, 0x00, 0x11, 0x42, 0x00, 0x00, 0x00, 0x54, 0x83, - 0xb8, 0x4f, 0x10, 0x8e, 0x89, 0x46, 0xde, 0xf7, + 0xb8, 0x4f, 0x10, 0x8c, 0x89, 0x46, 0xde, 0xf7, 0x13, 0x31, 0x00, 0x20, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x00, 0x01, 0x00, 0x00, 0xf0, 0x5b, 0xf4, 0xbe, 0x3d, @@ -471,7 +470,7 @@ var langNoIndex = [2197]uint8{ 0xaa, 0x10, 0x5d, 0x98, 0x52, 0x00, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x02, 0x02, 0x19, 0x00, 0x10, 0x02, 0x10, 0x61, 0x5a, 0x9d, - 0x31, 0x00, 0x00, 0x00, 0x01, 0x18, 0x02, 0x20, + 0x31, 0x00, 0x00, 0x00, 0x01, 0x10, 0x02, 0x20, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x20, 0x00, 0x00, 0x1f, 0xdf, 0xd2, 0xb9, 0xff, 0xfd, 0x3f, 0x1f, 0x98, 0xcf, 0x9c, 0xff, 0xaf, 0x5f, 0xfe, @@ -480,9 +479,9 @@ var langNoIndex = [2197]uint8{ 0xb7, 0xf6, 0xfb, 0xb3, 0xc7, 0xff, 0x6f, 0xf1, 0x73, 0xb1, 0x7f, 0x9f, 0x7f, 0xbd, 0xfc, 0xb7, 0xee, 0x1c, 0xfa, 0xcb, 0xef, 0xdd, 0xf9, 0xbd, - 0x6e, 0xae, 0x55, 0xfd, 0x6e, 0x81, 0x76, 0x9f, + 0x6e, 0xae, 0x55, 0xfd, 0x6e, 0x81, 0x76, 0x1f, 0xd4, 0x77, 0xf5, 0x7d, 0xfb, 0xff, 0xeb, 0xfe, - 0xbe, 0x5f, 0x46, 0x5b, 0xe9, 0x5f, 0x50, 0x18, + 0xbe, 0x5f, 0x46, 0x1b, 0xe9, 0x5f, 0x50, 0x18, 0x02, 0xfa, 0xf7, 0x9d, 0x15, 0x97, 0x05, 0x0f, // Entry 640 - 67F 0x75, 0xc4, 0x7d, 0x81, 0x92, 0xf5, 0x57, 0x6c, @@ -496,14 +495,14 @@ var langNoIndex = [2197]uint8{ // Entry 680 - 6BF 0x97, 0x9d, 0xbf, 0x9f, 0xf7, 0xc7, 0xfd, 0x37, 0xce, 0x7f, 0x04, 0x1d, 0x73, 0x7f, 0xf8, 0xda, - 0x5d, 0xce, 0x7d, 0x06, 0xb9, 0xea, 0x79, 0xa0, + 0x5d, 0xce, 0x7d, 0x06, 0xb9, 0xea, 0x69, 0xa0, 0x1a, 0x20, 0x00, 0x30, 0x02, 0x04, 0x24, 0x08, 0x04, 0x00, 0x00, 0x40, 0xd4, 0x02, 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x20, 0x01, 0x06, 0x50, 0x00, 0x08, 0x00, 0x00, 0x00, 0x24, 0x00, 0x04, 0x00, 0x10, 0xdc, 0x58, 0xd7, 0x0d, 0x0f, // Entry 6C0 - 6FF - 0x14, 0x4d, 0xf1, 0x16, 0x44, 0xd5, 0x42, 0x08, + 0x14, 0x4d, 0xf1, 0x16, 0x44, 0xd1, 0x42, 0x08, 0x40, 0x00, 0x00, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0xdc, 0xfb, 0xcb, 0x0e, 0x58, 0x48, 0x41, 0x24, 0x20, 0x04, 0x00, 0x30, 0x12, 0x40, 0x00, @@ -514,7 +513,7 @@ var langNoIndex = [2197]uint8{ // Entry 700 - 73F 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x80, 0x86, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x01, - 0xff, 0x18, 0x02, 0x00, 0x02, 0xf0, 0xfd, 0x79, + 0xdf, 0x18, 0x00, 0x00, 0x02, 0xf0, 0xfd, 0x79, 0x3b, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x03, 0x00, 0x09, 0x20, 0x00, 0x00, 0x01, 0x00, @@ -526,7 +525,7 @@ var langNoIndex = [2197]uint8{ 0xcd, 0xf9, 0x5c, 0x00, 0x01, 0x00, 0x30, 0x04, 0x04, 0x55, 0x00, 0x01, 0x04, 0xf4, 0x3f, 0x4a, 0x01, 0x00, 0x00, 0xb0, 0x80, 0x20, 0x55, 0x75, - 0x97, 0x7c, 0xdf, 0x31, 0xcc, 0x68, 0xd1, 0x03, + 0x97, 0x7c, 0x9f, 0x31, 0xcc, 0x68, 0xd1, 0x03, 0xd5, 0x57, 0x27, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xf7, 0xcb, 0x1f, 0x14, 0x60, // Entry 780 - 7BF @@ -539,7 +538,7 @@ var langNoIndex = [2197]uint8{ 0xe8, 0x30, 0x90, 0x6a, 0x92, 0x00, 0x00, 0x02, 0xff, 0xef, 0xff, 0x4b, 0x85, 0x53, 0xf4, 0xed, // Entry 7C0 - 7FF - 0xdd, 0xbf, 0xf2, 0x5d, 0xc7, 0x0c, 0xd5, 0x42, + 0xdd, 0xbf, 0x72, 0x1d, 0xc7, 0x0c, 0xd5, 0x42, 0xfc, 0xff, 0xf7, 0x1f, 0x00, 0x80, 0x40, 0x56, 0xcc, 0x16, 0x9e, 0xea, 0x35, 0x7d, 0xef, 0xff, 0xbd, 0xa4, 0xaf, 0x01, 0x44, 0x18, 0x01, 0x4d, @@ -553,15 +552,15 @@ var langNoIndex = [2197]uint8{ 0x40, 0x9c, 0x44, 0xdf, 0xf5, 0x8f, 0x66, 0xb3, 0x55, 0x20, 0xd4, 0xc1, 0xd8, 0x30, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x04, 0xd4, 0x11, 0xc5, 0x84, - 0x2f, 0x50, 0x00, 0x22, 0x50, 0x6e, 0xbd, 0x93, + 0x2e, 0x50, 0x00, 0x22, 0x50, 0x6e, 0xbd, 0x93, 0x07, 0x00, 0x20, 0x10, 0x84, 0xb2, 0x45, 0x10, 0x06, 0x44, 0x00, 0x00, 0x12, 0x02, 0x11, 0x00, // Entry 840 - 87F - 0xf0, 0xfb, 0xfd, 0x7f, 0x05, 0x00, 0x16, 0x81, + 0xf0, 0xfb, 0xfd, 0x7f, 0x05, 0x00, 0x12, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x02, 0x28, 0x84, 0x00, 0x21, 0xc0, 0x23, 0x24, 0x00, 0x00, - 0x00, 0xcb, 0xe4, 0x3a, 0x46, 0x88, 0x14, 0xf1, + 0x00, 0xcb, 0xe4, 0x3a, 0x42, 0x88, 0x14, 0xf1, 0xef, 0xff, 0x7f, 0x12, 0x01, 0x01, 0x84, 0x50, 0x07, 0xfc, 0xff, 0xff, 0x0f, 0x01, 0x00, 0x40, 0x10, 0x38, 0x01, 0x01, 0x1c, 0x12, 0x40, 0xe1, @@ -583,8 +582,8 @@ var altLangIndex = [6]uint16{ } // AliasMap maps langIDs to their suggested replacements. -// Size: 716 bytes, 179 elements -var AliasMap = [179]FromTo{ +// Size: 704 bytes, 176 elements +var AliasMap = [176]FromTo{ 0: {From: 0x82, To: 0x88}, 1: {From: 0x187, To: 0x1ae}, 2: {From: 0x1f3, To: 0x1e1}, @@ -613,176 +612,172 @@ var AliasMap = [179]FromTo{ 25: {From: 0x80c, To: 0x5a}, 26: {From: 0x815, To: 0x8d}, 27: {From: 0x87e, To: 0x810}, - 28: {From: 0x8a8, To: 0x8b7}, - 29: {From: 0x8c3, To: 0xee3}, - 30: {From: 0x8fa, To: 0x1dc}, - 31: {From: 0x9ef, To: 0x331}, - 32: {From: 0xa36, To: 0x2c5}, - 33: {From: 0xa3d, To: 0xbf}, - 34: {From: 0xabe, To: 0x3322}, - 35: {From: 0xb38, To: 0x529}, - 36: {From: 0xb75, To: 0x265a}, - 37: {From: 0xb7e, To: 0xbc3}, - 38: {From: 0xb9b, To: 0x44e}, - 39: {From: 0xbbc, To: 0x4229}, - 40: {From: 0xbbf, To: 0x529}, - 41: {From: 0xbfe, To: 0x2da7}, - 42: {From: 0xc2e, To: 0x3181}, - 43: {From: 0xcb9, To: 0xf3}, - 44: {From: 0xd08, To: 0xfa}, - 45: {From: 0xdc8, To: 0x11a}, - 46: {From: 0xdd7, To: 0x32d}, - 47: {From: 0xdf8, To: 0xdfb}, - 48: {From: 0xdfe, To: 0x531}, - 49: {From: 0xe01, To: 0xdf3}, - 50: {From: 0xedf, To: 0x205a}, - 51: {From: 0xee9, To: 0x222e}, - 52: {From: 0xeee, To: 0x2e9a}, - 53: {From: 0xf39, To: 0x367}, - 54: {From: 0x10d0, To: 0x140}, - 55: {From: 0x1104, To: 0x2d0}, - 56: {From: 0x11a0, To: 0x1ec}, - 57: {From: 0x1279, To: 0x21}, - 58: {From: 0x1424, To: 0x15e}, - 59: {From: 0x1470, To: 0x14e}, - 60: {From: 0x151f, To: 0xd9b}, - 61: {From: 0x1523, To: 0x390}, - 62: {From: 0x1532, To: 0x19f}, - 63: {From: 0x1580, To: 0x210}, - 64: {From: 0x1583, To: 0x10d}, - 65: {From: 0x15a3, To: 0x3caf}, - 66: {From: 0x1630, To: 0x222e}, - 67: {From: 0x166a, To: 0x19b}, - 68: {From: 0x16c8, To: 0x136}, - 69: {From: 0x1700, To: 0x29f8}, - 70: {From: 0x1718, To: 0x194}, - 71: {From: 0x1727, To: 0xf3f}, - 72: {From: 0x177a, To: 0x178}, - 73: {From: 0x1809, To: 0x17b6}, - 74: {From: 0x1816, To: 0x18f3}, - 75: {From: 0x188a, To: 0x436}, - 76: {From: 0x1979, To: 0x1d01}, - 77: {From: 0x1a74, To: 0x2bb0}, - 78: {From: 0x1a8a, To: 0x1f8}, - 79: {From: 0x1b5a, To: 0x1fa}, - 80: {From: 0x1b86, To: 0x1515}, - 81: {From: 0x1d64, To: 0x2c9b}, - 82: {From: 0x2038, To: 0x37b1}, - 83: {From: 0x203d, To: 0x20dd}, - 84: {From: 0x205a, To: 0x30b}, - 85: {From: 0x20e3, To: 0x274}, - 86: {From: 0x20ee, To: 0x263}, - 87: {From: 0x20f2, To: 0x22d}, - 88: {From: 0x20f9, To: 0x256}, - 89: {From: 0x210f, To: 0x21eb}, - 90: {From: 0x2135, To: 0x27d}, - 91: {From: 0x2160, To: 0x913}, - 92: {From: 0x2199, To: 0x121}, - 93: {From: 0x21ce, To: 0x1561}, - 94: {From: 0x21e6, To: 0x504}, - 95: {From: 0x21f4, To: 0x49f}, - 96: {From: 0x21fb, To: 0x269}, - 97: {From: 0x222d, To: 0x121}, - 98: {From: 0x2237, To: 0x121}, - 99: {From: 0x2262, To: 0x92a}, - 100: {From: 0x2316, To: 0x3226}, - 101: {From: 0x236a, To: 0x2835}, - 102: {From: 0x2382, To: 0x3365}, - 103: {From: 0x2472, To: 0x2c7}, - 104: {From: 0x24e4, To: 0x2ff}, - 105: {From: 0x24f0, To: 0x2fa}, - 106: {From: 0x24fa, To: 0x31f}, - 107: {From: 0x2550, To: 0xb5b}, - 108: {From: 0x25a9, To: 0xe2}, - 109: {From: 0x263e, To: 0x2d0}, - 110: {From: 0x26c9, To: 0x26b4}, - 111: {From: 0x26f9, To: 0x3c8}, - 112: {From: 0x2727, To: 0x3caf}, - 113: {From: 0x2755, To: 0x6a4}, - 114: {From: 0x2765, To: 0x26b4}, - 115: {From: 0x2789, To: 0x4358}, - 116: {From: 0x27c9, To: 0x2001}, - 117: {From: 0x28ea, To: 0x27b1}, - 118: {From: 0x28ef, To: 0x2837}, - 119: {From: 0x2914, To: 0x351}, - 120: {From: 0x2986, To: 0x2da7}, - 121: {From: 0x29f0, To: 0x96b}, - 122: {From: 0x2b1a, To: 0x38d}, - 123: {From: 0x2bfc, To: 0x395}, - 124: {From: 0x2c3f, To: 0x3caf}, - 125: {From: 0x2ce1, To: 0x2201}, - 126: {From: 0x2cfc, To: 0x3be}, - 127: {From: 0x2d13, To: 0x597}, - 128: {From: 0x2d47, To: 0x148}, - 129: {From: 0x2d48, To: 0x148}, - 130: {From: 0x2dff, To: 0x2f1}, - 131: {From: 0x2e08, To: 0x19cc}, - 132: {From: 0x2e1a, To: 0x2d95}, - 133: {From: 0x2e21, To: 0x292}, - 134: {From: 0x2e54, To: 0x7d}, - 135: {From: 0x2e65, To: 0x2282}, - 136: {From: 0x2ea0, To: 0x2e9b}, - 137: {From: 0x2eef, To: 0x2ed7}, - 138: {From: 0x3193, To: 0x3c4}, - 139: {From: 0x3366, To: 0x338e}, - 140: {From: 0x342a, To: 0x3dc}, - 141: {From: 0x34ee, To: 0x18d0}, - 142: {From: 0x35c8, To: 0x2c9b}, - 143: {From: 0x35e6, To: 0x412}, - 144: {From: 0x3658, To: 0x246}, - 145: {From: 0x3676, To: 0x3f4}, - 146: {From: 0x36fd, To: 0x445}, - 147: {From: 0x37c0, To: 0x121}, - 148: {From: 0x3816, To: 0x38f2}, - 149: {From: 0x382a, To: 0x2b48}, - 150: {From: 0x382b, To: 0x2c9b}, - 151: {From: 0x382f, To: 0xa9}, - 152: {From: 0x3832, To: 0x3228}, - 153: {From: 0x386c, To: 0x39a6}, - 154: {From: 0x3892, To: 0x3fc0}, - 155: {From: 0x38a5, To: 0x39d7}, - 156: {From: 0x38b4, To: 0x1fa4}, - 157: {From: 0x38b5, To: 0x2e9a}, - 158: {From: 0x395c, To: 0x47e}, - 159: {From: 0x3b4e, To: 0xd91}, - 160: {From: 0x3b78, To: 0x137}, - 161: {From: 0x3c99, To: 0x4bc}, - 162: {From: 0x3fbd, To: 0x100}, - 163: {From: 0x4208, To: 0xa91}, - 164: {From: 0x42be, To: 0x573}, - 165: {From: 0x42f9, To: 0x3f60}, - 166: {From: 0x4378, To: 0x25a}, - 167: {From: 0x43b8, To: 0xe6c}, - 168: {From: 0x43cd, To: 0x10f}, - 169: {From: 0x44af, To: 0x3322}, - 170: {From: 0x44e3, To: 0x512}, - 171: {From: 0x45ca, To: 0x2409}, - 172: {From: 0x45dd, To: 0x26dc}, - 173: {From: 0x4610, To: 0x48ae}, - 174: {From: 0x46ae, To: 0x46a0}, - 175: {From: 0x473e, To: 0x4745}, - 176: {From: 0x4817, To: 0x3503}, - 177: {From: 0x4916, To: 0x31f}, - 178: {From: 0x49a7, To: 0x523}, + 28: {From: 0x8c3, To: 0xee3}, + 29: {From: 0x9ef, To: 0x331}, + 30: {From: 0xa36, To: 0x2c5}, + 31: {From: 0xa3d, To: 0xbf}, + 32: {From: 0xabe, To: 0x3322}, + 33: {From: 0xb38, To: 0x529}, + 34: {From: 0xb75, To: 0x265a}, + 35: {From: 0xb7e, To: 0xbc3}, + 36: {From: 0xb9b, To: 0x44e}, + 37: {From: 0xbbc, To: 0x4229}, + 38: {From: 0xbbf, To: 0x529}, + 39: {From: 0xbfe, To: 0x2da7}, + 40: {From: 0xc2e, To: 0x3181}, + 41: {From: 0xcb9, To: 0xf3}, + 42: {From: 0xd08, To: 0xfa}, + 43: {From: 0xdc8, To: 0x11a}, + 44: {From: 0xdd7, To: 0x32d}, + 45: {From: 0xdf8, To: 0xdfb}, + 46: {From: 0xdfe, To: 0x531}, + 47: {From: 0xe01, To: 0xdf3}, + 48: {From: 0xedf, To: 0x205a}, + 49: {From: 0xee9, To: 0x222e}, + 50: {From: 0xeee, To: 0x2e9a}, + 51: {From: 0xf39, To: 0x367}, + 52: {From: 0x10d0, To: 0x140}, + 53: {From: 0x1104, To: 0x2d0}, + 54: {From: 0x11a0, To: 0x1ec}, + 55: {From: 0x1279, To: 0x21}, + 56: {From: 0x1424, To: 0x15e}, + 57: {From: 0x1470, To: 0x14e}, + 58: {From: 0x151f, To: 0xd9b}, + 59: {From: 0x1523, To: 0x390}, + 60: {From: 0x1532, To: 0x19f}, + 61: {From: 0x1580, To: 0x210}, + 62: {From: 0x1583, To: 0x10d}, + 63: {From: 0x15a3, To: 0x3caf}, + 64: {From: 0x1630, To: 0x222e}, + 65: {From: 0x166a, To: 0x19b}, + 66: {From: 0x16c8, To: 0x136}, + 67: {From: 0x1700, To: 0x29f8}, + 68: {From: 0x1718, To: 0x194}, + 69: {From: 0x1727, To: 0xf3f}, + 70: {From: 0x177a, To: 0x178}, + 71: {From: 0x1809, To: 0x17b6}, + 72: {From: 0x1816, To: 0x18f3}, + 73: {From: 0x188a, To: 0x436}, + 74: {From: 0x1979, To: 0x1d01}, + 75: {From: 0x1a74, To: 0x2bb0}, + 76: {From: 0x1a8a, To: 0x1f8}, + 77: {From: 0x1b5a, To: 0x1fa}, + 78: {From: 0x1b86, To: 0x1515}, + 79: {From: 0x1d64, To: 0x2c9b}, + 80: {From: 0x2038, To: 0x37b1}, + 81: {From: 0x203d, To: 0x20dd}, + 82: {From: 0x205a, To: 0x30b}, + 83: {From: 0x20e3, To: 0x274}, + 84: {From: 0x20ee, To: 0x263}, + 85: {From: 0x20f2, To: 0x22d}, + 86: {From: 0x20f9, To: 0x256}, + 87: {From: 0x210f, To: 0x21eb}, + 88: {From: 0x2135, To: 0x27d}, + 89: {From: 0x2160, To: 0x913}, + 90: {From: 0x2199, To: 0x121}, + 91: {From: 0x21ce, To: 0x1561}, + 92: {From: 0x21e6, To: 0x504}, + 93: {From: 0x21f4, To: 0x49f}, + 94: {From: 0x21fb, To: 0x269}, + 95: {From: 0x222d, To: 0x121}, + 96: {From: 0x2237, To: 0x121}, + 97: {From: 0x2262, To: 0x92a}, + 98: {From: 0x2316, To: 0x3226}, + 99: {From: 0x236a, To: 0x2835}, + 100: {From: 0x2382, To: 0x3365}, + 101: {From: 0x2472, To: 0x2c7}, + 102: {From: 0x24e4, To: 0x2ff}, + 103: {From: 0x24f0, To: 0x2fa}, + 104: {From: 0x24fa, To: 0x31f}, + 105: {From: 0x2550, To: 0xb5b}, + 106: {From: 0x25a9, To: 0xe2}, + 107: {From: 0x263e, To: 0x2d0}, + 108: {From: 0x26c9, To: 0x26b4}, + 109: {From: 0x26f9, To: 0x3c8}, + 110: {From: 0x2727, To: 0x3caf}, + 111: {From: 0x2755, To: 0x6a4}, + 112: {From: 0x2765, To: 0x26b4}, + 113: {From: 0x2789, To: 0x4358}, + 114: {From: 0x27c9, To: 0x2001}, + 115: {From: 0x28ea, To: 0x27b1}, + 116: {From: 0x28ef, To: 0x2837}, + 117: {From: 0x2914, To: 0x351}, + 118: {From: 0x2986, To: 0x2da7}, + 119: {From: 0x29f0, To: 0x96b}, + 120: {From: 0x2b1a, To: 0x38d}, + 121: {From: 0x2bfc, To: 0x395}, + 122: {From: 0x2c3f, To: 0x3caf}, + 123: {From: 0x2cfc, To: 0x3be}, + 124: {From: 0x2d13, To: 0x597}, + 125: {From: 0x2d47, To: 0x148}, + 126: {From: 0x2d48, To: 0x148}, + 127: {From: 0x2dff, To: 0x2f1}, + 128: {From: 0x2e08, To: 0x19cc}, + 129: {From: 0x2e1a, To: 0x2d95}, + 130: {From: 0x2e21, To: 0x292}, + 131: {From: 0x2e54, To: 0x7d}, + 132: {From: 0x2e65, To: 0x2282}, + 133: {From: 0x2ea0, To: 0x2e9b}, + 134: {From: 0x2eef, To: 0x2ed7}, + 135: {From: 0x3193, To: 0x3c4}, + 136: {From: 0x3366, To: 0x338e}, + 137: {From: 0x342a, To: 0x3dc}, + 138: {From: 0x34ee, To: 0x18d0}, + 139: {From: 0x35c8, To: 0x2c9b}, + 140: {From: 0x35e6, To: 0x412}, + 141: {From: 0x3658, To: 0x246}, + 142: {From: 0x3676, To: 0x3f4}, + 143: {From: 0x36fd, To: 0x445}, + 144: {From: 0x37c0, To: 0x121}, + 145: {From: 0x3816, To: 0x38f2}, + 146: {From: 0x382a, To: 0x2b48}, + 147: {From: 0x382b, To: 0x2c9b}, + 148: {From: 0x382f, To: 0xa9}, + 149: {From: 0x3832, To: 0x3228}, + 150: {From: 0x386c, To: 0x39a6}, + 151: {From: 0x3892, To: 0x3fc0}, + 152: {From: 0x38a5, To: 0x39d7}, + 153: {From: 0x38b4, To: 0x1fa4}, + 154: {From: 0x38b5, To: 0x2e9a}, + 155: {From: 0x395c, To: 0x47e}, + 156: {From: 0x3b4e, To: 0xd91}, + 157: {From: 0x3b78, To: 0x137}, + 158: {From: 0x3c99, To: 0x4bc}, + 159: {From: 0x3fbd, To: 0x100}, + 160: {From: 0x4208, To: 0xa91}, + 161: {From: 0x42be, To: 0x573}, + 162: {From: 0x42f9, To: 0x3f60}, + 163: {From: 0x4378, To: 0x25a}, + 164: {From: 0x43b8, To: 0xe6c}, + 165: {From: 0x43cd, To: 0x10f}, + 166: {From: 0x44af, To: 0x3322}, + 167: {From: 0x44e3, To: 0x512}, + 168: {From: 0x45ca, To: 0x2409}, + 169: {From: 0x45dd, To: 0x26dc}, + 170: {From: 0x4610, To: 0x48ae}, + 171: {From: 0x46ae, To: 0x46a0}, + 172: {From: 0x473e, To: 0x4745}, + 173: {From: 0x4817, To: 0x3503}, + 174: {From: 0x4916, To: 0x31f}, + 175: {From: 0x49a7, To: 0x523}, } -// Size: 179 bytes, 179 elements -var AliasTypes = [179]AliasType{ +// Size: 176 bytes, 176 elements +var AliasTypes = [176]AliasType{ // Entry 0 - 3F 1, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 1, 0, 0, 1, 2, - 1, 1, 2, 0, 0, 1, 0, 1, 2, 1, 1, 0, 0, 0, 0, 2, - 1, 1, 0, 2, 0, 0, 1, 0, 1, 0, 0, 1, 2, 1, 1, 1, - 1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 1, 0, 1, 1, 2, + 1, 1, 2, 0, 0, 1, 0, 1, 2, 1, 1, 0, 0, 2, 1, 1, + 0, 2, 0, 0, 1, 0, 1, 0, 0, 1, 2, 1, 1, 1, 1, 0, + 0, 0, 0, 2, 1, 1, 1, 1, 2, 1, 0, 1, 1, 2, 2, 0, // Entry 40 - 7F - 2, 0, 0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 0, 0, 2, 1, - 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 0, 1, 1, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, + 0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 0, 0, 2, 1, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 1, 2, 2, 2, 0, 1, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 2, 1, 1, // Entry 80 - BF - 2, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 2, 0, 0, 2, - 1, 1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 1, 2, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, - 0, 1, 1, + 0, 0, 1, 0, 0, 0, 0, 1, 1, 2, 0, 0, 2, 1, 1, 1, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, + 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, } const ( @@ -790,17 +785,17 @@ const ( _Hani = 57 _Hans = 59 _Hant = 60 - _Qaaa = 147 - _Qaai = 155 - _Qabx = 196 - _Zinh = 252 - _Zyyy = 257 - _Zzzz = 258 + _Qaaa = 143 + _Qaai = 151 + _Qabx = 192 + _Zinh = 245 + _Zyyy = 250 + _Zzzz = 251 ) // script is an alphabetically sorted list of ISO 15924 codes. The index // of the script in the string, divided by 4, is the internal scriptID. -const script tag.Index = "" + // Size: 1040 bytes +const script tag.Index = "" + // Size: 1012 bytes "----AdlmAfakAghbAhomArabAranArmiArmnAvstBaliBamuBassBatkBengBhksBlisBopo" + "BrahBraiBugiBuhdCakmCansCariChamCherChrsCirtCoptCpmnCprtCyrlCyrsDevaDiak" + "DogrDsrtDuplEgydEgyhEgypElbaElymEthiGeokGeorGlagGongGonmGothGranGrekGujr" + @@ -808,14 +803,14 @@ const script tag.Index = "" + // Size: 1040 bytes "JavaJpanJurcKaliKanaKharKhmrKhojKitlKitsKndaKoreKpelKthiLanaLaooLatfLatg" + "LatnLekeLepcLimbLinaLinbLisuLomaLyciLydiMahjMakaMandManiMarcMayaMedfMend" + "MercMeroMlymModiMongMoonMrooMteiMultMymrNandNarbNbatNewaNkdbNkgbNkooNshu" + - "OgamOlckOrkhOryaOsgeOsmaOugrPalmPaucPcunPelmPermPhagPhliPhlpPhlvPhnxPiqd" + - "PlrdPrtiPsinQaaaQaabQaacQaadQaaeQaafQaagQaahQaaiQaajQaakQaalQaamQaanQaao" + - "QaapQaaqQaarQaasQaatQaauQaavQaawQaaxQaayQaazQabaQabbQabcQabdQabeQabfQabg" + - "QabhQabiQabjQabkQablQabmQabnQaboQabpQabqQabrQabsQabtQabuQabvQabwQabxRanj" + - "RjngRohgRoroRunrSamrSaraSarbSaurSgnwShawShrdShuiSiddSindSinhSogdSogoSora" + - "SoyoSundSyloSyrcSyreSyrjSyrnTagbTakrTaleTaluTamlTangTavtTeluTengTfngTglg" + - "ThaaThaiTibtTirhTnsaTotoUgarVaiiVispVithWaraWchoWoleXpeoXsuxYeziYiiiZanb" + - "ZinhZmthZsyeZsymZxxxZyyyZzzz\xff\xff\xff\xff" + "OgamOlckOrkhOryaOsgeOsmaPalmPaucPermPhagPhliPhlpPhlvPhnxPiqdPlrdPrtiQaaa" + + "QaabQaacQaadQaaeQaafQaagQaahQaaiQaajQaakQaalQaamQaanQaaoQaapQaaqQaarQaas" + + "QaatQaauQaavQaawQaaxQaayQaazQabaQabbQabcQabdQabeQabfQabgQabhQabiQabjQabk" + + "QablQabmQabnQaboQabpQabqQabrQabsQabtQabuQabvQabwQabxRjngRohgRoroRunrSamr" + + "SaraSarbSaurSgnwShawShrdShuiSiddSindSinhSogdSogoSoraSoyoSundSyloSyrcSyre" + + "SyrjSyrnTagbTakrTaleTaluTamlTangTavtTeluTengTfngTglgThaaThaiTibtTirhToto" + + "UgarVaiiVispWaraWchoWoleXpeoXsuxYeziYiiiZanbZinhZmthZsyeZsymZxxxZyyyZzzz" + + "\xff\xff\xff\xff" // suppressScript is an index from langID to the dominant script for that language, // if it exists. If a script is given, it should be suppressed from the language tag. @@ -863,7 +858,7 @@ var suppressScript = [1330]uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xea, 0x00, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, + 0xe5, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x5a, 0x00, 0x5a, 0x00, // Entry 140 - 17F @@ -967,7 +962,7 @@ var suppressScript = [1330]uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Entry 400 - 43F 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -977,10 +972,10 @@ var suppressScript = [1330]uint8{ // Entry 440 - 47F 0x00, 0x00, 0x00, 0x00, 0x5a, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe6, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, 0x2c, + 0x00, 0xe1, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5a, 0x00, // Entry 480 - 4BF @@ -1091,9 +1086,9 @@ var regionTypes = [358]uint8{ // regionISO holds a list of alphabetically sorted 2-letter ISO region codes. // Each 2-letter codes is followed by two bytes with the following meaning: -// - [A-Z}{2}: the first letter of the 2-letter code plus these two -// letters form the 3-letter ISO code. -// - 0, n: index into altRegionISO3. +// - [A-Z}{2}: the first letter of the 2-letter code plus these two +// letters form the 3-letter ISO code. +// - 0, n: index into altRegionISO3. const regionISO tag.Index = "" + // Size: 1308 bytes "AAAAACSCADNDAEREAFFGAGTGAIIAALLBAMRMANNTAOGOAQTAARRGASSMATUTAUUSAWBWAXLA" + "AZZEBAIHBBRBBDGDBEELBFFABGGRBHHRBIDIBJENBLLMBMMUBNRNBOOLBQESBRRABSHSBTTN" + @@ -1211,9 +1206,7 @@ var m49 = [358]int16{ // m49Index gives indexes into fromM49 based on the three most significant bits // of a 10-bit UN.M49 code. To search an UN.M49 code in fromM49, search in -// -// fromM49[m49Index[msb39(code)]:m49Index[msb3(code)+1]] -// +// fromM49[m49Index[msb39(code)]:m49Index[msb3(code)+1]] // for an entry where the first 7 bits match the 7 lsb of the UN.M49 code. // The region code is stored in the 9 lsb of the indexed value. // Size: 18 bytes, 9 elements @@ -1275,118 +1268,117 @@ var fromM49 = [333]uint16{ 0xc759, 0xc95a, 0xcb5b, 0xcd5c, 0xcf65, } -// Size: 2014 bytes +// Size: 1995 bytes var variantIndex = map[string]uint8{ "1606nict": 0x0, "1694acad": 0x1, "1901": 0x2, "1959acad": 0x3, - "1994": 0x61, + "1994": 0x60, "1996": 0x4, "abl1943": 0x5, "akuapem": 0x6, - "alalc97": 0x63, + "alalc97": 0x62, "aluku": 0x7, "ao1990": 0x8, "aranes": 0x9, "arevela": 0xa, "arevmda": 0xb, - "arkaika": 0xc, - "asante": 0xd, - "auvern": 0xe, - "baku1926": 0xf, - "balanka": 0x10, - "barla": 0x11, - "basiceng": 0x12, - "bauddha": 0x13, - "biscayan": 0x14, - "biske": 0x5c, - "bohoric": 0x15, - "boont": 0x16, - "bornholm": 0x17, - "cisaup": 0x18, - "colb1945": 0x19, - "cornu": 0x1a, - "creiss": 0x1b, - "dajnko": 0x1c, - "ekavsk": 0x1d, - "emodeng": 0x1e, - "fonipa": 0x64, - "fonkirsh": 0x65, - "fonnapa": 0x66, - "fonupa": 0x67, - "fonxsamp": 0x68, - "gascon": 0x1f, - "grclass": 0x20, - "grital": 0x21, - "grmistr": 0x22, - "hepburn": 0x23, - "heploc": 0x62, - "hognorsk": 0x24, - "hsistemo": 0x25, - "ijekavsk": 0x26, - "itihasa": 0x27, - "ivanchov": 0x28, - "jauer": 0x29, - "jyutping": 0x2a, - "kkcor": 0x2b, - "kociewie": 0x2c, - "kscor": 0x2d, - "laukika": 0x2e, - "lemosin": 0x2f, - "lengadoc": 0x30, - "lipaw": 0x5d, - "luna1918": 0x31, - "metelko": 0x32, - "monoton": 0x33, - "ndyuka": 0x34, - "nedis": 0x35, - "newfound": 0x36, - "nicard": 0x37, - "njiva": 0x5e, - "nulik": 0x38, - "osojs": 0x5f, - "oxendict": 0x39, - "pahawh2": 0x3a, - "pahawh3": 0x3b, - "pahawh4": 0x3c, - "pamaka": 0x3d, - "peano": 0x3e, - "petr1708": 0x3f, - "pinyin": 0x40, - "polyton": 0x41, - "provenc": 0x42, - "puter": 0x43, - "rigik": 0x44, - "rozaj": 0x45, - "rumgr": 0x46, - "scotland": 0x47, - "scouse": 0x48, - "simple": 0x69, - "solba": 0x60, - "sotav": 0x49, - "spanglis": 0x4a, - "surmiran": 0x4b, - "sursilv": 0x4c, - "sutsilv": 0x4d, - "tarask": 0x4e, - "tongyong": 0x4f, - "tunumiit": 0x50, - "uccor": 0x51, - "ucrcor": 0x52, - "ulster": 0x53, - "unifon": 0x54, - "vaidika": 0x55, - "valencia": 0x56, - "vallader": 0x57, - "vecdruka": 0x58, - "vivaraup": 0x59, - "wadegile": 0x5a, - "xsistemo": 0x5b, + "asante": 0xc, + "auvern": 0xd, + "baku1926": 0xe, + "balanka": 0xf, + "barla": 0x10, + "basiceng": 0x11, + "bauddha": 0x12, + "biscayan": 0x13, + "biske": 0x5b, + "bohoric": 0x14, + "boont": 0x15, + "bornholm": 0x16, + "cisaup": 0x17, + "colb1945": 0x18, + "cornu": 0x19, + "creiss": 0x1a, + "dajnko": 0x1b, + "ekavsk": 0x1c, + "emodeng": 0x1d, + "fonipa": 0x63, + "fonkirsh": 0x64, + "fonnapa": 0x65, + "fonupa": 0x66, + "fonxsamp": 0x67, + "gascon": 0x1e, + "grclass": 0x1f, + "grital": 0x20, + "grmistr": 0x21, + "hepburn": 0x22, + "heploc": 0x61, + "hognorsk": 0x23, + "hsistemo": 0x24, + "ijekavsk": 0x25, + "itihasa": 0x26, + "ivanchov": 0x27, + "jauer": 0x28, + "jyutping": 0x29, + "kkcor": 0x2a, + "kociewie": 0x2b, + "kscor": 0x2c, + "laukika": 0x2d, + "lemosin": 0x2e, + "lengadoc": 0x2f, + "lipaw": 0x5c, + "luna1918": 0x30, + "metelko": 0x31, + "monoton": 0x32, + "ndyuka": 0x33, + "nedis": 0x34, + "newfound": 0x35, + "nicard": 0x36, + "njiva": 0x5d, + "nulik": 0x37, + "osojs": 0x5e, + "oxendict": 0x38, + "pahawh2": 0x39, + "pahawh3": 0x3a, + "pahawh4": 0x3b, + "pamaka": 0x3c, + "peano": 0x3d, + "petr1708": 0x3e, + "pinyin": 0x3f, + "polyton": 0x40, + "provenc": 0x41, + "puter": 0x42, + "rigik": 0x43, + "rozaj": 0x44, + "rumgr": 0x45, + "scotland": 0x46, + "scouse": 0x47, + "simple": 0x68, + "solba": 0x5f, + "sotav": 0x48, + "spanglis": 0x49, + "surmiran": 0x4a, + "sursilv": 0x4b, + "sutsilv": 0x4c, + "tarask": 0x4d, + "tongyong": 0x4e, + "tunumiit": 0x4f, + "uccor": 0x50, + "ucrcor": 0x51, + "ulster": 0x52, + "unifon": 0x53, + "vaidika": 0x54, + "valencia": 0x55, + "vallader": 0x56, + "vecdruka": 0x57, + "vivaraup": 0x58, + "wadegile": 0x59, + "xsistemo": 0x5a, } // variantNumSpecialized is the number of specialized variants in variants. -const variantNumSpecialized = 99 +const variantNumSpecialized = 98 // nRegionGroups is the number of region groups. const nRegionGroups = 33 @@ -1398,8 +1390,8 @@ type likelyLangRegion struct { // likelyScript is a lookup table, indexed by scriptID, for the most likely // languages and regions given a script. -// Size: 1040 bytes, 260 elements -var likelyScript = [260]likelyLangRegion{ +// Size: 1012 bytes, 253 elements +var likelyScript = [253]likelyLangRegion{ 1: {lang: 0x14e, region: 0x84}, 3: {lang: 0x2a2, region: 0x106}, 4: {lang: 0x1f, region: 0x99}, @@ -1497,57 +1489,57 @@ var likelyScript = [260]likelyLangRegion{ 129: {lang: 0x395, region: 0x99}, 130: {lang: 0x399, region: 0x135}, 131: {lang: 0x429, region: 0x115}, - 133: {lang: 0x3b, region: 0x11c}, - 134: {lang: 0xfd, region: 0xc4}, - 137: {lang: 0x27d, region: 0x106}, - 138: {lang: 0x2c9, region: 0x53}, - 139: {lang: 0x39f, region: 0x9c}, - 140: {lang: 0x39f, region: 0x53}, - 142: {lang: 0x3ad, region: 0xb0}, - 144: {lang: 0x1c6, region: 0x53}, - 145: {lang: 0x4fd, region: 0x9c}, - 198: {lang: 0x3cb, region: 0x95}, - 201: {lang: 0x372, region: 0x10c}, - 202: {lang: 0x420, region: 0x97}, - 204: {lang: 0x4ff, region: 0x15e}, - 205: {lang: 0x3f0, region: 0x99}, - 206: {lang: 0x45, region: 0x135}, - 207: {lang: 0x139, region: 0x7b}, - 208: {lang: 0x3e9, region: 0x99}, - 210: {lang: 0x3e9, region: 0x99}, - 211: {lang: 0x3fa, region: 0x99}, - 212: {lang: 0x40c, region: 0xb3}, - 215: {lang: 0x433, region: 0x99}, - 216: {lang: 0xef, region: 0xc5}, - 217: {lang: 0x43e, region: 0x95}, - 218: {lang: 0x44d, region: 0x35}, - 219: {lang: 0x44e, region: 0x9b}, - 223: {lang: 0x45a, region: 0xe7}, - 224: {lang: 0x11a, region: 0x99}, - 225: {lang: 0x45e, region: 0x53}, - 226: {lang: 0x232, region: 0x53}, - 227: {lang: 0x450, region: 0x99}, - 228: {lang: 0x4a5, region: 0x53}, - 229: {lang: 0x9f, region: 0x13e}, - 230: {lang: 0x461, region: 0x99}, - 232: {lang: 0x528, region: 0xba}, - 233: {lang: 0x153, region: 0xe7}, - 234: {lang: 0x128, region: 0xcd}, - 235: {lang: 0x46b, region: 0x123}, - 236: {lang: 0xa9, region: 0x53}, - 237: {lang: 0x2ce, region: 0x99}, - 240: {lang: 0x4ad, region: 0x11c}, - 241: {lang: 0x4be, region: 0xb4}, - 244: {lang: 0x1ce, region: 0x99}, - 247: {lang: 0x3a9, region: 0x9c}, - 248: {lang: 0x22, region: 0x9b}, - 250: {lang: 0x1ea, region: 0x53}, - 251: {lang: 0xef, region: 0xc5}, + 132: {lang: 0x3b, region: 0x11c}, + 133: {lang: 0xfd, region: 0xc4}, + 134: {lang: 0x27d, region: 0x106}, + 135: {lang: 0x2c9, region: 0x53}, + 136: {lang: 0x39f, region: 0x9c}, + 137: {lang: 0x39f, region: 0x53}, + 139: {lang: 0x3ad, region: 0xb0}, + 141: {lang: 0x1c6, region: 0x53}, + 142: {lang: 0x4fd, region: 0x9c}, + 193: {lang: 0x3cb, region: 0x95}, + 196: {lang: 0x372, region: 0x10c}, + 197: {lang: 0x420, region: 0x97}, + 199: {lang: 0x4ff, region: 0x15e}, + 200: {lang: 0x3f0, region: 0x99}, + 201: {lang: 0x45, region: 0x135}, + 202: {lang: 0x139, region: 0x7b}, + 203: {lang: 0x3e9, region: 0x99}, + 205: {lang: 0x3e9, region: 0x99}, + 206: {lang: 0x3fa, region: 0x99}, + 207: {lang: 0x40c, region: 0xb3}, + 210: {lang: 0x433, region: 0x99}, + 211: {lang: 0xef, region: 0xc5}, + 212: {lang: 0x43e, region: 0x95}, + 213: {lang: 0x44d, region: 0x35}, + 214: {lang: 0x44e, region: 0x9b}, + 218: {lang: 0x45a, region: 0xe7}, + 219: {lang: 0x11a, region: 0x99}, + 220: {lang: 0x45e, region: 0x53}, + 221: {lang: 0x232, region: 0x53}, + 222: {lang: 0x450, region: 0x99}, + 223: {lang: 0x4a5, region: 0x53}, + 224: {lang: 0x9f, region: 0x13e}, + 225: {lang: 0x461, region: 0x99}, + 227: {lang: 0x528, region: 0xba}, + 228: {lang: 0x153, region: 0xe7}, + 229: {lang: 0x128, region: 0xcd}, + 230: {lang: 0x46b, region: 0x123}, + 231: {lang: 0xa9, region: 0x53}, + 232: {lang: 0x2ce, region: 0x99}, + 234: {lang: 0x4ad, region: 0x11c}, + 235: {lang: 0x4be, region: 0xb4}, + 237: {lang: 0x1ce, region: 0x99}, + 240: {lang: 0x3a9, region: 0x9c}, + 241: {lang: 0x22, region: 0x9b}, + 243: {lang: 0x1ea, region: 0x53}, + 244: {lang: 0xef, region: 0xc5}, } type likelyScriptRegion struct { region uint16 - script uint16 + script uint8 flags uint8 } @@ -1555,7 +1547,7 @@ type likelyScriptRegion struct { // scripts and regions given incomplete information. If more entries exist for a // given language, region and script are the index and size respectively // of the list in likelyLangList. -// Size: 7980 bytes, 1330 elements +// Size: 5320 bytes, 1330 elements var likelyLang = [1330]likelyScriptRegion{ 0: {region: 0x135, script: 0x5a, flags: 0x0}, 1: {region: 0x6f, script: 0x5a, flags: 0x0}, @@ -1591,7 +1583,7 @@ var likelyLang = [1330]likelyScriptRegion{ 31: {region: 0x99, script: 0x4, flags: 0x0}, 32: {region: 0x165, script: 0x5a, flags: 0x0}, 33: {region: 0x80, script: 0x5a, flags: 0x0}, - 34: {region: 0x9b, script: 0xf8, flags: 0x0}, + 34: {region: 0x9b, script: 0xf1, flags: 0x0}, 35: {region: 0x165, script: 0x5a, flags: 0x0}, 36: {region: 0x165, script: 0x5a, flags: 0x0}, 37: {region: 0x14d, script: 0x5a, flags: 0x0}, @@ -1624,7 +1616,7 @@ var likelyLang = [1330]likelyScriptRegion{ 66: {region: 0x6b, script: 0x5, flags: 0x0}, 67: {region: 0x99, script: 0xe, flags: 0x0}, 68: {region: 0x12f, script: 0x5a, flags: 0x0}, - 69: {region: 0x135, script: 0xce, flags: 0x0}, + 69: {region: 0x135, script: 0xc9, flags: 0x0}, 70: {region: 0x165, script: 0x5a, flags: 0x0}, 71: {region: 0x165, script: 0x5a, flags: 0x0}, 72: {region: 0x6e, script: 0x5a, flags: 0x0}, @@ -1678,7 +1670,7 @@ var likelyLang = [1330]likelyScriptRegion{ 120: {region: 0x165, script: 0x5a, flags: 0x0}, 121: {region: 0x12f, script: 0x5a, flags: 0x0}, 122: {region: 0x52, script: 0x5a, flags: 0x0}, - 123: {region: 0x99, script: 0xe3, flags: 0x0}, + 123: {region: 0x99, script: 0xde, flags: 0x0}, 124: {region: 0xe8, script: 0x5, flags: 0x0}, 125: {region: 0x99, script: 0x22, flags: 0x0}, 126: {region: 0x38, script: 0x20, flags: 0x0}, @@ -1713,7 +1705,7 @@ var likelyLang = [1330]likelyScriptRegion{ 156: {region: 0x165, script: 0x5a, flags: 0x0}, 157: {region: 0xe7, script: 0x5a, flags: 0x0}, 158: {region: 0x165, script: 0x5a, flags: 0x0}, - 159: {region: 0x13e, script: 0xe5, flags: 0x0}, + 159: {region: 0x13e, script: 0xe0, flags: 0x0}, 160: {region: 0xc3, script: 0x5a, flags: 0x0}, 161: {region: 0x165, script: 0x5a, flags: 0x0}, 162: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -1723,7 +1715,7 @@ var likelyLang = [1330]likelyScriptRegion{ 166: {region: 0x165, script: 0x5a, flags: 0x0}, 167: {region: 0x165, script: 0x5a, flags: 0x0}, 168: {region: 0x165, script: 0x5a, flags: 0x0}, - 169: {region: 0x53, script: 0xec, flags: 0x0}, + 169: {region: 0x53, script: 0xe7, flags: 0x0}, 170: {region: 0x165, script: 0x5a, flags: 0x0}, 171: {region: 0x165, script: 0x5a, flags: 0x0}, 172: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -1793,7 +1785,7 @@ var likelyLang = [1330]likelyScriptRegion{ 236: {region: 0x165, script: 0x5a, flags: 0x0}, 237: {region: 0x165, script: 0x5a, flags: 0x0}, 238: {region: 0x165, script: 0x5a, flags: 0x0}, - 239: {region: 0xc5, script: 0xd8, flags: 0x0}, + 239: {region: 0xc5, script: 0xd3, flags: 0x0}, 240: {region: 0x78, script: 0x5a, flags: 0x0}, 241: {region: 0x6b, script: 0x1d, flags: 0x0}, 242: {region: 0xe7, script: 0x5a, flags: 0x0}, @@ -1807,7 +1799,7 @@ var likelyLang = [1330]likelyScriptRegion{ 250: {region: 0x5e, script: 0x5a, flags: 0x0}, 251: {region: 0xe9, script: 0x5a, flags: 0x0}, 252: {region: 0x49, script: 0x17, flags: 0x0}, - 253: {region: 0xc4, script: 0x86, flags: 0x0}, + 253: {region: 0xc4, script: 0x85, flags: 0x0}, 254: {region: 0x8, script: 0x2, flags: 0x1}, 255: {region: 0x106, script: 0x20, flags: 0x0}, 256: {region: 0x7b, script: 0x5a, flags: 0x0}, @@ -1850,12 +1842,12 @@ var likelyLang = [1330]likelyScriptRegion{ 293: {region: 0x165, script: 0x5a, flags: 0x0}, 294: {region: 0x165, script: 0x5a, flags: 0x0}, 295: {region: 0x165, script: 0x5a, flags: 0x0}, - 296: {region: 0xcd, script: 0xea, flags: 0x0}, + 296: {region: 0xcd, script: 0xe5, flags: 0x0}, 297: {region: 0x165, script: 0x5a, flags: 0x0}, 298: {region: 0x165, script: 0x5a, flags: 0x0}, 299: {region: 0x114, script: 0x5a, flags: 0x0}, 300: {region: 0x37, script: 0x5a, flags: 0x0}, - 301: {region: 0x43, script: 0xec, flags: 0x0}, + 301: {region: 0x43, script: 0xe7, flags: 0x0}, 302: {region: 0x165, script: 0x5a, flags: 0x0}, 303: {region: 0xa4, script: 0x5a, flags: 0x0}, 304: {region: 0x80, script: 0x5a, flags: 0x0}, @@ -1965,7 +1957,7 @@ var likelyLang = [1330]likelyScriptRegion{ 408: {region: 0x165, script: 0x2c, flags: 0x0}, 409: {region: 0x165, script: 0x5a, flags: 0x0}, 410: {region: 0x99, script: 0x22, flags: 0x0}, - 411: {region: 0x99, script: 0xe6, flags: 0x0}, + 411: {region: 0x99, script: 0xe1, flags: 0x0}, 412: {region: 0x95, script: 0x5a, flags: 0x0}, 413: {region: 0xd9, script: 0x5a, flags: 0x0}, 414: {region: 0x130, script: 0x32, flags: 0x0}, @@ -2008,7 +2000,7 @@ var likelyLang = [1330]likelyScriptRegion{ 451: {region: 0xe7, script: 0x5a, flags: 0x0}, 452: {region: 0x165, script: 0x5a, flags: 0x0}, 453: {region: 0x12b, script: 0x40, flags: 0x0}, - 454: {region: 0x53, script: 0x90, flags: 0x0}, + 454: {region: 0x53, script: 0x8d, flags: 0x0}, 455: {region: 0x165, script: 0x5a, flags: 0x0}, 456: {region: 0xe8, script: 0x5, flags: 0x0}, 457: {region: 0x99, script: 0x22, flags: 0x0}, @@ -2043,7 +2035,7 @@ var likelyLang = [1330]likelyScriptRegion{ 487: {region: 0xd6, script: 0x5a, flags: 0x0}, 488: {region: 0x165, script: 0x5a, flags: 0x0}, 489: {region: 0x165, script: 0x5a, flags: 0x0}, - 490: {region: 0x53, script: 0xfa, flags: 0x0}, + 490: {region: 0x53, script: 0xf3, flags: 0x0}, 491: {region: 0x165, script: 0x5a, flags: 0x0}, 492: {region: 0x135, script: 0x5a, flags: 0x0}, 493: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2103,7 +2095,7 @@ var likelyLang = [1330]likelyScriptRegion{ 547: {region: 0x12f, script: 0x5a, flags: 0x0}, 548: {region: 0x122, script: 0x5, flags: 0x0}, 549: {region: 0x165, script: 0x5a, flags: 0x0}, - 550: {region: 0x123, script: 0xeb, flags: 0x0}, + 550: {region: 0x123, script: 0xe6, flags: 0x0}, 551: {region: 0x5a, script: 0x5a, flags: 0x0}, 552: {region: 0x52, script: 0x5a, flags: 0x0}, 553: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2115,7 +2107,7 @@ var likelyLang = [1330]likelyScriptRegion{ 559: {region: 0x165, script: 0x5a, flags: 0x0}, 560: {region: 0x41, script: 0x5a, flags: 0x0}, 561: {region: 0x99, script: 0x5a, flags: 0x0}, - 562: {region: 0x53, script: 0xe2, flags: 0x0}, + 562: {region: 0x53, script: 0xdd, flags: 0x0}, 563: {region: 0x99, script: 0x22, flags: 0x0}, 564: {region: 0xc3, script: 0x5a, flags: 0x0}, 565: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2199,7 +2191,7 @@ var likelyLang = [1330]likelyScriptRegion{ 643: {region: 0x165, script: 0x5a, flags: 0x0}, 644: {region: 0x165, script: 0x5a, flags: 0x0}, 645: {region: 0x165, script: 0x2c, flags: 0x0}, - 646: {region: 0x123, script: 0xeb, flags: 0x0}, + 646: {region: 0x123, script: 0xe6, flags: 0x0}, 647: {region: 0xe8, script: 0x5, flags: 0x0}, 648: {region: 0x165, script: 0x5a, flags: 0x0}, 649: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2219,7 +2211,7 @@ var likelyLang = [1330]likelyScriptRegion{ 663: {region: 0x165, script: 0x5a, flags: 0x0}, 664: {region: 0x95, script: 0x5a, flags: 0x0}, 665: {region: 0x165, script: 0x5a, flags: 0x0}, - 666: {region: 0x53, script: 0xeb, flags: 0x0}, + 666: {region: 0x53, script: 0xe6, flags: 0x0}, 667: {region: 0x165, script: 0x5a, flags: 0x0}, 668: {region: 0x165, script: 0x5a, flags: 0x0}, 669: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2243,7 +2235,7 @@ var likelyLang = [1330]likelyScriptRegion{ 687: {region: 0x135, script: 0x5a, flags: 0x0}, 688: {region: 0x165, script: 0x5a, flags: 0x0}, 689: {region: 0x165, script: 0x5a, flags: 0x0}, - 690: {region: 0x99, script: 0xe6, flags: 0x0}, + 690: {region: 0x99, script: 0xe1, flags: 0x0}, 691: {region: 0x9e, script: 0x5a, flags: 0x0}, 692: {region: 0x165, script: 0x5a, flags: 0x0}, 693: {region: 0x4b, script: 0x5a, flags: 0x0}, @@ -2265,7 +2257,7 @@ var likelyLang = [1330]likelyScriptRegion{ 709: {region: 0xa4, script: 0x5a, flags: 0x0}, 710: {region: 0x9c, script: 0x5, flags: 0x0}, 711: {region: 0xb8, script: 0x5a, flags: 0x0}, - 712: {region: 0x123, script: 0xeb, flags: 0x0}, + 712: {region: 0x123, script: 0xe6, flags: 0x0}, 713: {region: 0x53, script: 0x3b, flags: 0x0}, 714: {region: 0x12b, script: 0x5a, flags: 0x0}, 715: {region: 0x95, script: 0x5a, flags: 0x0}, @@ -2432,7 +2424,7 @@ var likelyLang = [1330]likelyScriptRegion{ 879: {region: 0xda, script: 0x5a, flags: 0x0}, 880: {region: 0x123, script: 0x56, flags: 0x0}, 881: {region: 0x99, script: 0x22, flags: 0x0}, - 882: {region: 0x10c, script: 0xc9, flags: 0x0}, + 882: {region: 0x10c, script: 0xc4, flags: 0x0}, 883: {region: 0x165, script: 0x5a, flags: 0x0}, 884: {region: 0x165, script: 0x5a, flags: 0x0}, 885: {region: 0x84, script: 0x7c, flags: 0x0}, @@ -2486,11 +2478,11 @@ var likelyLang = [1330]likelyScriptRegion{ 934: {region: 0x135, script: 0x5a, flags: 0x0}, 935: {region: 0x49, script: 0x5a, flags: 0x0}, 936: {region: 0x165, script: 0x5a, flags: 0x0}, - 937: {region: 0x9c, script: 0xf7, flags: 0x0}, + 937: {region: 0x9c, script: 0xf0, flags: 0x0}, 938: {region: 0x165, script: 0x5a, flags: 0x0}, 939: {region: 0x60, script: 0x5a, flags: 0x0}, 940: {region: 0x165, script: 0x5, flags: 0x0}, - 941: {region: 0xb0, script: 0x8e, flags: 0x0}, + 941: {region: 0xb0, script: 0x8b, flags: 0x0}, 943: {region: 0x165, script: 0x5a, flags: 0x0}, 944: {region: 0x165, script: 0x5a, flags: 0x0}, 945: {region: 0x99, script: 0x12, flags: 0x0}, @@ -2556,7 +2548,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1005: {region: 0x95, script: 0x5a, flags: 0x0}, 1006: {region: 0x99, script: 0x5a, flags: 0x0}, 1007: {region: 0x114, script: 0x5a, flags: 0x0}, - 1008: {region: 0x99, script: 0xcd, flags: 0x0}, + 1008: {region: 0x99, script: 0xc8, flags: 0x0}, 1009: {region: 0x165, script: 0x5a, flags: 0x0}, 1010: {region: 0x165, script: 0x5a, flags: 0x0}, 1011: {region: 0x12f, script: 0x5a, flags: 0x0}, @@ -2579,11 +2571,11 @@ var likelyLang = [1330]likelyScriptRegion{ 1028: {region: 0xb6, script: 0x5a, flags: 0x0}, 1029: {region: 0x165, script: 0x2c, flags: 0x0}, 1030: {region: 0x165, script: 0x5a, flags: 0x0}, - 1032: {region: 0xba, script: 0xe8, flags: 0x0}, + 1032: {region: 0xba, script: 0xe3, flags: 0x0}, 1033: {region: 0x165, script: 0x5a, flags: 0x0}, 1034: {region: 0xc4, script: 0x75, flags: 0x0}, 1035: {region: 0x165, script: 0x5, flags: 0x0}, - 1036: {region: 0xb3, script: 0xd4, flags: 0x0}, + 1036: {region: 0xb3, script: 0xcf, flags: 0x0}, 1037: {region: 0x6f, script: 0x5a, flags: 0x0}, 1038: {region: 0x165, script: 0x5a, flags: 0x0}, 1039: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2602,7 +2594,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1052: {region: 0x10c, script: 0x5a, flags: 0x0}, 1054: {region: 0x10c, script: 0x5a, flags: 0x0}, 1055: {region: 0x72, script: 0x5a, flags: 0x0}, - 1056: {region: 0x97, script: 0xca, flags: 0x0}, + 1056: {region: 0x97, script: 0xc5, flags: 0x0}, 1057: {region: 0x165, script: 0x5a, flags: 0x0}, 1058: {region: 0x72, script: 0x5a, flags: 0x0}, 1059: {region: 0x164, script: 0x5a, flags: 0x0}, @@ -2614,14 +2606,14 @@ var likelyLang = [1330]likelyScriptRegion{ 1065: {region: 0x115, script: 0x5a, flags: 0x0}, 1066: {region: 0x165, script: 0x5a, flags: 0x0}, 1067: {region: 0x165, script: 0x5a, flags: 0x0}, - 1068: {region: 0x123, script: 0xeb, flags: 0x0}, + 1068: {region: 0x123, script: 0xe6, flags: 0x0}, 1069: {region: 0x165, script: 0x5a, flags: 0x0}, 1070: {region: 0x165, script: 0x5a, flags: 0x0}, 1071: {region: 0x165, script: 0x5a, flags: 0x0}, 1072: {region: 0x165, script: 0x5a, flags: 0x0}, 1073: {region: 0x27, script: 0x5a, flags: 0x0}, 1074: {region: 0x37, script: 0x5, flags: 0x1}, - 1075: {region: 0x99, script: 0xd7, flags: 0x0}, + 1075: {region: 0x99, script: 0xd2, flags: 0x0}, 1076: {region: 0x116, script: 0x5a, flags: 0x0}, 1077: {region: 0x114, script: 0x5a, flags: 0x0}, 1078: {region: 0x99, script: 0x22, flags: 0x0}, @@ -2648,9 +2640,9 @@ var likelyLang = [1330]likelyScriptRegion{ 1099: {region: 0x95, script: 0x5a, flags: 0x0}, 1100: {region: 0x165, script: 0x5a, flags: 0x0}, 1101: {region: 0x35, script: 0xe, flags: 0x0}, - 1102: {region: 0x9b, script: 0xdb, flags: 0x0}, + 1102: {region: 0x9b, script: 0xd6, flags: 0x0}, 1103: {region: 0xe9, script: 0x5a, flags: 0x0}, - 1104: {region: 0x99, script: 0xe3, flags: 0x0}, + 1104: {region: 0x99, script: 0xde, flags: 0x0}, 1105: {region: 0xdb, script: 0x22, flags: 0x0}, 1106: {region: 0x165, script: 0x5a, flags: 0x0}, 1107: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2664,10 +2656,10 @@ var likelyLang = [1330]likelyScriptRegion{ 1115: {region: 0x165, script: 0x5a, flags: 0x0}, 1116: {region: 0x165, script: 0x5a, flags: 0x0}, 1117: {region: 0x99, script: 0x52, flags: 0x0}, - 1118: {region: 0x53, script: 0xe1, flags: 0x0}, + 1118: {region: 0x53, script: 0xdc, flags: 0x0}, 1119: {region: 0xdb, script: 0x22, flags: 0x0}, 1120: {region: 0xdb, script: 0x22, flags: 0x0}, - 1121: {region: 0x99, script: 0xe6, flags: 0x0}, + 1121: {region: 0x99, script: 0xe1, flags: 0x0}, 1122: {region: 0x165, script: 0x5a, flags: 0x0}, 1123: {region: 0x112, script: 0x5a, flags: 0x0}, 1124: {region: 0x131, script: 0x5a, flags: 0x0}, @@ -2677,7 +2669,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1128: {region: 0x165, script: 0x5a, flags: 0x0}, 1129: {region: 0x165, script: 0x5a, flags: 0x0}, 1130: {region: 0x165, script: 0x5a, flags: 0x0}, - 1131: {region: 0x123, script: 0xeb, flags: 0x0}, + 1131: {region: 0x123, script: 0xe6, flags: 0x0}, 1132: {region: 0xdb, script: 0x22, flags: 0x0}, 1133: {region: 0xdb, script: 0x22, flags: 0x0}, 1134: {region: 0xdb, script: 0x22, flags: 0x0}, @@ -2716,14 +2708,14 @@ var likelyLang = [1330]likelyScriptRegion{ 1167: {region: 0x87, script: 0x34, flags: 0x0}, 1168: {region: 0xdb, script: 0x22, flags: 0x0}, 1169: {region: 0xe7, script: 0x5a, flags: 0x0}, - 1170: {region: 0x43, script: 0xec, flags: 0x0}, + 1170: {region: 0x43, script: 0xe7, flags: 0x0}, 1171: {region: 0x165, script: 0x5a, flags: 0x0}, 1172: {region: 0x106, script: 0x20, flags: 0x0}, 1173: {region: 0x165, script: 0x5a, flags: 0x0}, 1174: {region: 0x165, script: 0x5a, flags: 0x0}, 1175: {region: 0x131, script: 0x5a, flags: 0x0}, 1176: {region: 0x165, script: 0x5a, flags: 0x0}, - 1177: {region: 0x123, script: 0xeb, flags: 0x0}, + 1177: {region: 0x123, script: 0xe6, flags: 0x0}, 1178: {region: 0x32, script: 0x5a, flags: 0x0}, 1179: {region: 0x165, script: 0x5a, flags: 0x0}, 1180: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2734,7 +2726,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1185: {region: 0x165, script: 0x5a, flags: 0x0}, 1187: {region: 0x165, script: 0x5a, flags: 0x0}, 1188: {region: 0xd4, script: 0x5a, flags: 0x0}, - 1189: {region: 0x53, script: 0xe4, flags: 0x0}, + 1189: {region: 0x53, script: 0xdf, flags: 0x0}, 1190: {region: 0xe5, script: 0x5a, flags: 0x0}, 1191: {region: 0x165, script: 0x5a, flags: 0x0}, 1192: {region: 0x106, script: 0x20, flags: 0x0}, @@ -2742,7 +2734,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1194: {region: 0x165, script: 0x5a, flags: 0x0}, 1195: {region: 0x106, script: 0x20, flags: 0x0}, 1196: {region: 0x3f, script: 0x4, flags: 0x1}, - 1197: {region: 0x11c, script: 0xf0, flags: 0x0}, + 1197: {region: 0x11c, script: 0xea, flags: 0x0}, 1198: {region: 0x130, script: 0x20, flags: 0x0}, 1199: {region: 0x75, script: 0x5a, flags: 0x0}, 1200: {region: 0x2a, script: 0x5a, flags: 0x0}, @@ -2758,7 +2750,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1211: {region: 0x165, script: 0x5a, flags: 0x0}, 1212: {region: 0x46, script: 0x4, flags: 0x1}, 1213: {region: 0x165, script: 0x5a, flags: 0x0}, - 1214: {region: 0xb4, script: 0xf1, flags: 0x0}, + 1214: {region: 0xb4, script: 0xeb, flags: 0x0}, 1215: {region: 0x165, script: 0x5a, flags: 0x0}, 1216: {region: 0x161, script: 0x5a, flags: 0x0}, 1217: {region: 0x9e, script: 0x5a, flags: 0x0}, @@ -2781,7 +2773,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1234: {region: 0x165, script: 0x5a, flags: 0x0}, 1235: {region: 0xe7, script: 0x5a, flags: 0x0}, 1236: {region: 0x2f, script: 0x5a, flags: 0x0}, - 1237: {region: 0x99, script: 0xe6, flags: 0x0}, + 1237: {region: 0x99, script: 0xe1, flags: 0x0}, 1238: {region: 0x99, script: 0x22, flags: 0x0}, 1239: {region: 0x165, script: 0x5a, flags: 0x0}, 1240: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2821,9 +2813,9 @@ var likelyLang = [1330]likelyScriptRegion{ 1274: {region: 0x99, script: 0x22, flags: 0x0}, 1275: {region: 0x131, script: 0x5a, flags: 0x0}, 1276: {region: 0x165, script: 0x5a, flags: 0x0}, - 1277: {region: 0x9c, script: 0x91, flags: 0x0}, + 1277: {region: 0x9c, script: 0x8e, flags: 0x0}, 1278: {region: 0x165, script: 0x5a, flags: 0x0}, - 1279: {region: 0x15e, script: 0xcc, flags: 0x0}, + 1279: {region: 0x15e, script: 0xc7, flags: 0x0}, 1280: {region: 0x165, script: 0x5a, flags: 0x0}, 1281: {region: 0x165, script: 0x5a, flags: 0x0}, 1282: {region: 0xdb, script: 0x22, flags: 0x0}, @@ -2863,7 +2855,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1316: {region: 0x10b, script: 0x5a, flags: 0x0}, 1318: {region: 0xa8, script: 0x5, flags: 0x0}, 1319: {region: 0xd9, script: 0x5a, flags: 0x0}, - 1320: {region: 0xba, script: 0xe8, flags: 0x0}, + 1320: {region: 0xba, script: 0xe3, flags: 0x0}, 1321: {region: 0x4d, script: 0x14, flags: 0x1}, 1322: {region: 0x53, script: 0x7d, flags: 0x0}, 1323: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2875,11 +2867,11 @@ var likelyLang = [1330]likelyScriptRegion{ } // likelyLangList holds lists info associated with likelyLang. -// Size: 582 bytes, 97 elements +// Size: 388 bytes, 97 elements var likelyLangList = [97]likelyScriptRegion{ 0: {region: 0x9c, script: 0x7, flags: 0x0}, 1: {region: 0xa1, script: 0x78, flags: 0x2}, - 2: {region: 0x11c, script: 0x85, flags: 0x2}, + 2: {region: 0x11c, script: 0x84, flags: 0x2}, 3: {region: 0x32, script: 0x5a, flags: 0x0}, 4: {region: 0x9b, script: 0x5, flags: 0x4}, 5: {region: 0x9c, script: 0x5, flags: 0x4}, @@ -2888,7 +2880,7 @@ var likelyLangList = [97]likelyScriptRegion{ 8: {region: 0x106, script: 0x20, flags: 0x0}, 9: {region: 0x38, script: 0x2f, flags: 0x2}, 10: {region: 0x135, script: 0x5a, flags: 0x0}, - 11: {region: 0x7b, script: 0xcf, flags: 0x2}, + 11: {region: 0x7b, script: 0xca, flags: 0x2}, 12: {region: 0x114, script: 0x5a, flags: 0x0}, 13: {region: 0x84, script: 0x1, flags: 0x2}, 14: {region: 0x5d, script: 0x1f, flags: 0x0}, @@ -2924,14 +2916,14 @@ var likelyLangList = [97]likelyScriptRegion{ 44: {region: 0x99, script: 0x36, flags: 0x0}, 45: {region: 0xe8, script: 0x5, flags: 0x4}, 46: {region: 0xe8, script: 0x5, flags: 0x2}, - 47: {region: 0x9c, script: 0x8b, flags: 0x0}, - 48: {region: 0x53, script: 0x8c, flags: 0x2}, - 49: {region: 0xba, script: 0xe8, flags: 0x0}, + 47: {region: 0x9c, script: 0x88, flags: 0x0}, + 48: {region: 0x53, script: 0x89, flags: 0x2}, + 49: {region: 0xba, script: 0xe3, flags: 0x0}, 50: {region: 0xd9, script: 0x5a, flags: 0x4}, 51: {region: 0xe8, script: 0x5, flags: 0x0}, 52: {region: 0x99, script: 0x22, flags: 0x2}, 53: {region: 0x99, script: 0x4f, flags: 0x2}, - 54: {region: 0x99, script: 0xd3, flags: 0x2}, + 54: {region: 0x99, script: 0xce, flags: 0x2}, 55: {region: 0x105, script: 0x20, flags: 0x0}, 56: {region: 0xbd, script: 0x5a, flags: 0x4}, 57: {region: 0x104, script: 0x5a, flags: 0x4}, @@ -2978,7 +2970,7 @@ var likelyLangList = [97]likelyScriptRegion{ type likelyLangScript struct { lang uint16 - script uint16 + script uint8 flags uint8 } @@ -2987,7 +2979,7 @@ type likelyLangScript struct { // for a given regionID, lang and script are the index and size respectively // of the list in likelyRegionList. // TODO: exclude containers and user-definable regions from the list. -// Size: 2148 bytes, 358 elements +// Size: 1432 bytes, 358 elements var likelyRegion = [358]likelyLangScript{ 34: {lang: 0xd7, script: 0x5a, flags: 0x0}, 35: {lang: 0x3a, script: 0x5, flags: 0x0}, @@ -3094,7 +3086,7 @@ var likelyRegion = [358]likelyLangScript{ 175: {lang: 0x27, script: 0x2, flags: 0x1}, 176: {lang: 0x3a, script: 0x5, flags: 0x0}, 178: {lang: 0x10d, script: 0x5a, flags: 0x0}, - 179: {lang: 0x40c, script: 0xd4, flags: 0x0}, + 179: {lang: 0x40c, script: 0xcf, flags: 0x0}, 181: {lang: 0x43b, script: 0x5a, flags: 0x0}, 182: {lang: 0x2c0, script: 0x5a, flags: 0x0}, 183: {lang: 0x15e, script: 0x5a, flags: 0x0}, @@ -3115,7 +3107,7 @@ var likelyRegion = [358]likelyLangScript{ 201: {lang: 0x35, script: 0x2, flags: 0x1}, 203: {lang: 0x320, script: 0x5a, flags: 0x0}, 204: {lang: 0x37, script: 0x3, flags: 0x1}, - 205: {lang: 0x128, script: 0xea, flags: 0x0}, + 205: {lang: 0x128, script: 0xe5, flags: 0x0}, 207: {lang: 0x13e, script: 0x5a, flags: 0x0}, 208: {lang: 0x31f, script: 0x5a, flags: 0x0}, 209: {lang: 0x3c0, script: 0x5a, flags: 0x0}, @@ -3193,7 +3185,7 @@ var likelyRegion = [358]likelyLangScript{ } // likelyRegionList holds lists info associated with likelyRegion. -// Size: 558 bytes, 93 elements +// Size: 372 bytes, 93 elements var likelyRegionList = [93]likelyLangScript{ 0: {lang: 0x148, script: 0x5, flags: 0x0}, 1: {lang: 0x476, script: 0x5a, flags: 0x0}, @@ -3203,12 +3195,12 @@ var likelyRegionList = [93]likelyLangScript{ 5: {lang: 0x274, script: 0x5a, flags: 0x0}, 6: {lang: 0xb7, script: 0x5a, flags: 0x0}, 7: {lang: 0x432, script: 0x20, flags: 0x0}, - 8: {lang: 0x12d, script: 0xec, flags: 0x0}, + 8: {lang: 0x12d, script: 0xe7, flags: 0x0}, 9: {lang: 0x351, script: 0x22, flags: 0x0}, 10: {lang: 0x529, script: 0x3b, flags: 0x0}, 11: {lang: 0x4ac, script: 0x5, flags: 0x0}, 12: {lang: 0x523, script: 0x5a, flags: 0x0}, - 13: {lang: 0x29a, script: 0xeb, flags: 0x0}, + 13: {lang: 0x29a, script: 0xe6, flags: 0x0}, 14: {lang: 0x136, script: 0x34, flags: 0x0}, 15: {lang: 0x48a, script: 0x5a, flags: 0x0}, 16: {lang: 0x3a, script: 0x5, flags: 0x0}, @@ -3231,11 +3223,11 @@ var likelyRegionList = [93]likelyLangScript{ 33: {lang: 0x476, script: 0x5a, flags: 0x0}, 34: {lang: 0x24a, script: 0x4e, flags: 0x0}, 35: {lang: 0xe6, script: 0x5, flags: 0x0}, - 36: {lang: 0x226, script: 0xeb, flags: 0x0}, + 36: {lang: 0x226, script: 0xe6, flags: 0x0}, 37: {lang: 0x3a, script: 0x5, flags: 0x0}, 38: {lang: 0x15e, script: 0x5a, flags: 0x0}, 39: {lang: 0x2b8, script: 0x57, flags: 0x0}, - 40: {lang: 0x226, script: 0xeb, flags: 0x0}, + 40: {lang: 0x226, script: 0xe6, flags: 0x0}, 41: {lang: 0x3a, script: 0x5, flags: 0x0}, 42: {lang: 0x15e, script: 0x5a, flags: 0x0}, 43: {lang: 0x3dc, script: 0x5a, flags: 0x0}, @@ -3268,7 +3260,7 @@ var likelyRegionList = [93]likelyLangScript{ 70: {lang: 0x15e, script: 0x5a, flags: 0x0}, 71: {lang: 0x15e, script: 0x5a, flags: 0x0}, 72: {lang: 0x35, script: 0x5, flags: 0x0}, - 73: {lang: 0x46b, script: 0xeb, flags: 0x0}, + 73: {lang: 0x46b, script: 0xe6, flags: 0x0}, 74: {lang: 0x2ec, script: 0x5, flags: 0x0}, 75: {lang: 0x30f, script: 0x75, flags: 0x0}, 76: {lang: 0x467, script: 0x20, flags: 0x0}, @@ -3293,7 +3285,7 @@ var likelyRegionList = [93]likelyLangScript{ type likelyTag struct { lang uint16 region uint16 - script uint16 + script uint8 } // Size: 198 bytes, 33 elements @@ -3454,8 +3446,8 @@ var regionInclusionNext = [73]uint8{ type parentRel struct { lang uint16 - script uint16 - maxScript uint16 + script uint8 + maxScript uint8 toRegion uint16 fromRegion []uint16 } @@ -3469,4 +3461,4 @@ var parents = [5]parentRel{ 4: {lang: 0x529, script: 0x3c, maxScript: 0x3c, toRegion: 0x8d, fromRegion: []uint16{0xc6}}, } -// Total table size 30244 bytes (29KiB); checksum: B6B15F30 +// Total table size 26398 bytes (25KiB); checksum: 1C859EA7 diff --git a/vendor/golang.org/x/text/internal/utf8internal/utf8internal.go b/vendor/golang.org/x/text/internal/utf8internal/utf8internal.go index e5c53b1b..575cea87 100644 --- a/vendor/golang.org/x/text/internal/utf8internal/utf8internal.go +++ b/vendor/golang.org/x/text/internal/utf8internal/utf8internal.go @@ -74,7 +74,7 @@ type AcceptRange struct { // AcceptRanges is a slice of AcceptRange values. For a given byte sequence b // -// AcceptRanges[First[b[0]]>>AcceptShift] +// AcceptRanges[First[b[0]]>>AcceptShift] // // will give the value of AcceptRange for the multi-byte UTF-8 sequence starting // at b[0]. diff --git a/vendor/golang.org/x/text/language/doc.go b/vendor/golang.org/x/text/language/doc.go index 212b77c9..8afecd50 100644 --- a/vendor/golang.org/x/text/language/doc.go +++ b/vendor/golang.org/x/text/language/doc.go @@ -10,17 +10,18 @@ // and provides the user with the best experience // (see https://blog.golang.org/matchlang). // -// # Matching preferred against supported languages +// +// Matching preferred against supported languages // // A Matcher for an application that supports English, Australian English, // Danish, and standard Mandarin can be created as follows: // -// var matcher = language.NewMatcher([]language.Tag{ -// language.English, // The first language is used as fallback. -// language.MustParse("en-AU"), -// language.Danish, -// language.Chinese, -// }) +// var matcher = language.NewMatcher([]language.Tag{ +// language.English, // The first language is used as fallback. +// language.MustParse("en-AU"), +// language.Danish, +// language.Chinese, +// }) // // This list of supported languages is typically implied by the languages for // which there exists translations of the user interface. @@ -29,14 +30,14 @@ // language tags. // The MatchString finds best matches for such strings: // -// handler(w http.ResponseWriter, r *http.Request) { -// lang, _ := r.Cookie("lang") -// accept := r.Header.Get("Accept-Language") -// tag, _ := language.MatchStrings(matcher, lang.String(), accept) +// handler(w http.ResponseWriter, r *http.Request) { +// lang, _ := r.Cookie("lang") +// accept := r.Header.Get("Accept-Language") +// tag, _ := language.MatchStrings(matcher, lang.String(), accept) // -// // tag should now be used for the initialization of any -// // locale-specific service. -// } +// // tag should now be used for the initialization of any +// // locale-specific service. +// } // // The Matcher's Match method can be used to match Tags directly. // @@ -47,7 +48,8 @@ // For instance, it will know that a reader of Bokmål Danish can read Norwegian // and will know that Cantonese ("yue") is a good match for "zh-HK". // -// # Using match results +// +// Using match results // // To guarantee a consistent user experience to the user it is important to // use the same language tag for the selection of any locale-specific services. @@ -56,9 +58,9 @@ // More subtly confusing is using the wrong sorting order or casing // algorithm for a certain language. // -// All the packages in x/text that provide locale-specific services -// (e.g. collate, cases) should be initialized with the tag that was -// obtained at the start of an interaction with the user. +// All the packages in x/text that provide locale-specific services +// (e.g. collate, cases) should be initialized with the tag that was +// obtained at the start of an interaction with the user. // // Note that Tag that is returned by Match and MatchString may differ from any // of the supported languages, as it may contain carried over settings from @@ -68,7 +70,8 @@ // Match and MatchString both return the index of the matched supported tag // to simplify associating such data with the matched tag. // -// # Canonicalization +// +// Canonicalization // // If one uses the Matcher to compare languages one does not need to // worry about canonicalization. @@ -89,9 +92,10 @@ // equivalence relations. The CanonType type can be used to alter the // canonicalization form. // -// # References +// References // // BCP 47 - Tags for Identifying Languages http://tools.ietf.org/html/bcp47 +// package language // import "golang.org/x/text/language" // TODO: explanation on how to match languages for your own locale-specific diff --git a/vendor/golang.org/x/text/language/go1_1.go b/vendor/golang.org/x/text/language/go1_1.go new file mode 100644 index 00000000..c7435583 --- /dev/null +++ b/vendor/golang.org/x/text/language/go1_1.go @@ -0,0 +1,39 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.2 +// +build !go1.2 + +package language + +import "sort" + +func sortStable(s sort.Interface) { + ss := stableSort{ + s: s, + pos: make([]int, s.Len()), + } + for i := range ss.pos { + ss.pos[i] = i + } + sort.Sort(&ss) +} + +type stableSort struct { + s sort.Interface + pos []int +} + +func (s *stableSort) Len() int { + return len(s.pos) +} + +func (s *stableSort) Less(i, j int) bool { + return s.s.Less(i, j) || !s.s.Less(j, i) && s.pos[i] < s.pos[j] +} + +func (s *stableSort) Swap(i, j int) { + s.s.Swap(i, j) + s.pos[i], s.pos[j] = s.pos[j], s.pos[i] +} diff --git a/vendor/golang.org/x/text/language/go1_2.go b/vendor/golang.org/x/text/language/go1_2.go new file mode 100644 index 00000000..77aaaa29 --- /dev/null +++ b/vendor/golang.org/x/text/language/go1_2.go @@ -0,0 +1,12 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.2 +// +build go1.2 + +package language + +import "sort" + +var sortStable = sort.Stable diff --git a/vendor/golang.org/x/text/language/match.go b/vendor/golang.org/x/text/language/match.go index ee45f494..f7349213 100644 --- a/vendor/golang.org/x/text/language/match.go +++ b/vendor/golang.org/x/text/language/match.go @@ -545,7 +545,7 @@ type bestMatch struct { // match as the preferred match. // // If pin is true and have and tag are a strong match, it will henceforth only -// consider matches for this language. This corresponds to the idea that most +// consider matches for this language. This corresponds to the nothing that most // users have a strong preference for the first defined language. A user can // still prefer a second language over a dialect of the preferred language by // explicitly specifying dialects, e.g. "en, nl, en-GB". In this case pin should diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go index 4d57222e..59b04100 100644 --- a/vendor/golang.org/x/text/language/parse.go +++ b/vendor/golang.org/x/text/language/parse.go @@ -6,7 +6,6 @@ package language import ( "errors" - "sort" "strconv" "strings" @@ -148,7 +147,6 @@ func update(b *language.Builder, part ...interface{}) (err error) { } var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") -var errTagListTooLarge = errors.New("tag list exceeds max length") // ParseAcceptLanguage parses the contents of an Accept-Language header as // defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and @@ -166,10 +164,6 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { } }() - if strings.Count(s, "-") > 1000 { - return nil, nil, errTagListTooLarge - } - var entry string for s != "" { if entry, s = split(s, ','); entry == "" { @@ -207,7 +201,7 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { tag = append(tag, t) q = append(q, float32(w)) } - sort.Stable(&tagSort{tag, q}) + sortStable(&tagSort{tag, q}) return tag, q, nil } diff --git a/vendor/golang.org/x/text/language/tables.go b/vendor/golang.org/x/text/language/tables.go index 34a732b6..96b57f61 100644 --- a/vendor/golang.org/x/text/language/tables.go +++ b/vendor/golang.org/x/text/language/tables.go @@ -39,12 +39,12 @@ const ( _Hani = 57 _Hans = 59 _Hant = 60 - _Qaaa = 147 - _Qaai = 155 - _Qabx = 196 - _Zinh = 252 - _Zyyy = 257 - _Zzzz = 258 + _Qaaa = 143 + _Qaai = 151 + _Qabx = 192 + _Zinh = 245 + _Zyyy = 250 + _Zzzz = 251 ) var regionToGroups = []uint8{ // 358 elements @@ -265,9 +265,9 @@ var matchScript = []scriptIntelligibility{ // 26 elements 13: {wantLang: 0x39d, haveLang: 0x139, wantScript: 0x36, haveScript: 0x5a, distance: 0xa}, 14: {wantLang: 0x3be, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5a, distance: 0xa}, 15: {wantLang: 0x3fa, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5a, distance: 0xa}, - 16: {wantLang: 0x40c, haveLang: 0x139, wantScript: 0xd4, haveScript: 0x5a, distance: 0xa}, - 17: {wantLang: 0x450, haveLang: 0x139, wantScript: 0xe3, haveScript: 0x5a, distance: 0xa}, - 18: {wantLang: 0x461, haveLang: 0x139, wantScript: 0xe6, haveScript: 0x5a, distance: 0xa}, + 16: {wantLang: 0x40c, haveLang: 0x139, wantScript: 0xcf, haveScript: 0x5a, distance: 0xa}, + 17: {wantLang: 0x450, haveLang: 0x139, wantScript: 0xde, haveScript: 0x5a, distance: 0xa}, + 18: {wantLang: 0x461, haveLang: 0x139, wantScript: 0xe1, haveScript: 0x5a, distance: 0xa}, 19: {wantLang: 0x46f, haveLang: 0x139, wantScript: 0x2c, haveScript: 0x5a, distance: 0xa}, 20: {wantLang: 0x476, haveLang: 0x3e2, wantScript: 0x5a, haveScript: 0x20, distance: 0xa}, 21: {wantLang: 0x4b4, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5a, distance: 0xa}, diff --git a/vendor/golang.org/x/text/runes/runes.go b/vendor/golang.org/x/text/runes/runes.go index 930e87fe..71933696 100644 --- a/vendor/golang.org/x/text/runes/runes.go +++ b/vendor/golang.org/x/text/runes/runes.go @@ -33,7 +33,7 @@ func In(rt *unicode.RangeTable) Set { return setFunc(func(r rune) bool { return unicode.Is(rt, r) }) } -// NotIn creates a Set with a Contains method that returns true for all runes not +// In creates a Set with a Contains method that returns true for all runes not // in the given RangeTable. func NotIn(rt *unicode.RangeTable) Set { return setFunc(func(r rune) bool { return !unicode.Is(rt, r) }) diff --git a/vendor/golang.org/x/text/unicode/bidi/core.go b/vendor/golang.org/x/text/unicode/bidi/core.go index 9d2ae547..e4c08110 100644 --- a/vendor/golang.org/x/text/unicode/bidi/core.go +++ b/vendor/golang.org/x/text/unicode/bidi/core.go @@ -193,14 +193,14 @@ func (p *paragraph) run() { // // At the end of this function: // -// - The member variable matchingPDI is set to point to the index of the -// matching PDI character for each isolate initiator character. If there is -// no matching PDI, it is set to the length of the input text. For other -// characters, it is set to -1. -// - The member variable matchingIsolateInitiator is set to point to the -// index of the matching isolate initiator character for each PDI character. -// If there is no matching isolate initiator, or the character is not a PDI, -// it is set to -1. +// - The member variable matchingPDI is set to point to the index of the +// matching PDI character for each isolate initiator character. If there is +// no matching PDI, it is set to the length of the input text. For other +// characters, it is set to -1. +// - The member variable matchingIsolateInitiator is set to point to the +// index of the matching isolate initiator character for each PDI character. +// If there is no matching isolate initiator, or the character is not a PDI, +// it is set to -1. func (p *paragraph) determineMatchingIsolates() { p.matchingPDI = make([]int, p.Len()) p.matchingIsolateInitiator = make([]int, p.Len()) @@ -435,7 +435,7 @@ func maxLevel(a, b level) level { } // Rule X10, second bullet: Determine the start-of-sequence (sos) and end-of-sequence (eos) types, -// either L or R, for each isolating run sequence. +// either L or R, for each isolating run sequence. func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence { length := len(indexes) types := make([]Class, length) @@ -495,9 +495,9 @@ func (s *isolatingRunSequence) resolveWeakTypes() { if t == NSM { s.types[i] = precedingCharacterType } else { - // if t.in(LRI, RLI, FSI, PDI) { - // precedingCharacterType = ON - // } + if t.in(LRI, RLI, FSI, PDI) { + precedingCharacterType = ON + } precedingCharacterType = t } } @@ -905,7 +905,7 @@ func (p *paragraph) getLevels(linebreaks []int) []level { // Lines are concatenated from left to right. So for example, the fifth // character from the left on the third line is // -// getReordering(linebreaks)[linebreaks[1] + 4] +// getReordering(linebreaks)[linebreaks[1] + 4] // // (linebreaks[1] is the position after the last character of the second // line, which is also the index of the first character on the third line, diff --git a/vendor/golang.org/x/text/unicode/norm/forminfo.go b/vendor/golang.org/x/text/unicode/norm/forminfo.go index d69ccb4f..526c7033 100644 --- a/vendor/golang.org/x/text/unicode/norm/forminfo.go +++ b/vendor/golang.org/x/text/unicode/norm/forminfo.go @@ -110,11 +110,10 @@ func (p Properties) BoundaryAfter() bool { } // We pack quick check data in 4 bits: -// -// 5: Combines forward (0 == false, 1 == true) -// 4..3: NFC_QC Yes(00), No (10), or Maybe (11) -// 2: NFD_QC Yes (0) or No (1). No also means there is a decomposition. -// 1..0: Number of trailing non-starters. +// 5: Combines forward (0 == false, 1 == true) +// 4..3: NFC_QC Yes(00), No (10), or Maybe (11) +// 2: NFD_QC Yes (0) or No (1). No also means there is a decomposition. +// 1..0: Number of trailing non-starters. // // When all 4 bits are zero, the character is inert, meaning it is never // influenced by normalization. diff --git a/vendor/golang.org/x/text/unicode/norm/normalize.go b/vendor/golang.org/x/text/unicode/norm/normalize.go index 4747ad07..95efcf26 100644 --- a/vendor/golang.org/x/text/unicode/norm/normalize.go +++ b/vendor/golang.org/x/text/unicode/norm/normalize.go @@ -18,17 +18,16 @@ import ( // A Form denotes a canonical representation of Unicode code points. // The Unicode-defined normalization and equivalence forms are: // -// NFC Unicode Normalization Form C -// NFD Unicode Normalization Form D -// NFKC Unicode Normalization Form KC -// NFKD Unicode Normalization Form KD +// NFC Unicode Normalization Form C +// NFD Unicode Normalization Form D +// NFKC Unicode Normalization Form KC +// NFKD Unicode Normalization Form KD // // For a Form f, this documentation uses the notation f(x) to mean // the bytes or string x converted to the given form. // A position n in x is called a boundary if conversion to the form can // proceed independently on both sides: -// -// f(x) == append(f(x[0:n]), f(x[n:])...) +// f(x) == append(f(x[0:n]), f(x[n:])...) // // References: https://unicode.org/reports/tr15/ and // https://unicode.org/notes/tn5/. diff --git a/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go b/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go index 9115ef25..96a130d3 100644 --- a/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go +++ b/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go @@ -7315,7 +7315,7 @@ const recompMapPacked = "" + "\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C "\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D "\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E - "\x00v\x03#\x00\x00\x1e\x7f" + // 0x00760323: 0x00001E7F + "\x00v\x03#\x00\x00\x1e\u007f" + // 0x00760323: 0x00001E7F "\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80 "\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81 "\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82 @@ -7342,7 +7342,7 @@ const recompMapPacked = "" + "\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97 "\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98 "\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99 - "\x01\x7f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B + "\x01\u007f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B "\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0 "\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1 "\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2 diff --git a/vendor/golang.org/x/text/width/tables10.0.0.go b/vendor/golang.org/x/text/width/tables10.0.0.go index cd9d91ca..186b1d4e 100644 --- a/vendor/golang.org/x/text/width/tables10.0.0.go +++ b/vendor/golang.org/x/text/width/tables10.0.0.go @@ -1146,31 +1146,21 @@ var widthIndex = [1408]uint8{ } // inverseData contains 4-byte entries of the following format: -// -// <0 padding> -// +// <0 padding> // The last byte of the UTF-8-encoded rune is xor-ed with the last byte of the // UTF-8 encoding of the original rune. Mappings often have the following // pattern: -// -// A -> A (U+FF21 -> U+0041) -// B -> B (U+FF22 -> U+0042) -// ... -// +// A -> A (U+FF21 -> U+0041) +// B -> B (U+FF22 -> U+0042) +// ... // By xor-ing the last byte the same entry can be shared by many mappings. This // reduces the total number of distinct entries by about two thirds. // The resulting entry for the aforementioned mappings is -// -// { 0x01, 0xE0, 0x00, 0x00 } -// +// { 0x01, 0xE0, 0x00, 0x00 } // Using this entry to map U+FF21 (UTF-8 [EF BC A1]), we get -// -// E0 ^ A1 = 41. -// +// E0 ^ A1 = 41. // Similarly, for U+FF22 (UTF-8 [EF BC A2]), we get -// -// E0 ^ A2 = 42. -// +// E0 ^ A2 = 42. // Note that because of the xor-ing, the byte sequence stored in the entry is // not valid UTF-8. var inverseData = [150][4]byte{ diff --git a/vendor/golang.org/x/text/width/tables11.0.0.go b/vendor/golang.org/x/text/width/tables11.0.0.go index 327eaef9..990f7622 100644 --- a/vendor/golang.org/x/text/width/tables11.0.0.go +++ b/vendor/golang.org/x/text/width/tables11.0.0.go @@ -1158,31 +1158,21 @@ var widthIndex = [1408]uint8{ } // inverseData contains 4-byte entries of the following format: -// -// <0 padding> -// +// <0 padding> // The last byte of the UTF-8-encoded rune is xor-ed with the last byte of the // UTF-8 encoding of the original rune. Mappings often have the following // pattern: -// -// A -> A (U+FF21 -> U+0041) -// B -> B (U+FF22 -> U+0042) -// ... -// +// A -> A (U+FF21 -> U+0041) +// B -> B (U+FF22 -> U+0042) +// ... // By xor-ing the last byte the same entry can be shared by many mappings. This // reduces the total number of distinct entries by about two thirds. // The resulting entry for the aforementioned mappings is -// -// { 0x01, 0xE0, 0x00, 0x00 } -// +// { 0x01, 0xE0, 0x00, 0x00 } // Using this entry to map U+FF21 (UTF-8 [EF BC A1]), we get -// -// E0 ^ A1 = 41. -// +// E0 ^ A1 = 41. // Similarly, for U+FF22 (UTF-8 [EF BC A2]), we get -// -// E0 ^ A2 = 42. -// +// E0 ^ A2 = 42. // Note that because of the xor-ing, the byte sequence stored in the entry is // not valid UTF-8. var inverseData = [150][4]byte{ diff --git a/vendor/golang.org/x/text/width/tables12.0.0.go b/vendor/golang.org/x/text/width/tables12.0.0.go index 5c14ade6..85296297 100644 --- a/vendor/golang.org/x/text/width/tables12.0.0.go +++ b/vendor/golang.org/x/text/width/tables12.0.0.go @@ -1178,31 +1178,21 @@ var widthIndex = [1408]uint8{ } // inverseData contains 4-byte entries of the following format: -// -// <0 padding> -// +// <0 padding> // The last byte of the UTF-8-encoded rune is xor-ed with the last byte of the // UTF-8 encoding of the original rune. Mappings often have the following // pattern: -// -// A -> A (U+FF21 -> U+0041) -// B -> B (U+FF22 -> U+0042) -// ... -// +// A -> A (U+FF21 -> U+0041) +// B -> B (U+FF22 -> U+0042) +// ... // By xor-ing the last byte the same entry can be shared by many mappings. This // reduces the total number of distinct entries by about two thirds. // The resulting entry for the aforementioned mappings is -// -// { 0x01, 0xE0, 0x00, 0x00 } -// +// { 0x01, 0xE0, 0x00, 0x00 } // Using this entry to map U+FF21 (UTF-8 [EF BC A1]), we get -// -// E0 ^ A1 = 41. -// +// E0 ^ A1 = 41. // Similarly, for U+FF22 (UTF-8 [EF BC A2]), we get -// -// E0 ^ A2 = 42. -// +// E0 ^ A2 = 42. // Note that because of the xor-ing, the byte sequence stored in the entry is // not valid UTF-8. var inverseData = [150][4]byte{ diff --git a/vendor/golang.org/x/text/width/tables13.0.0.go b/vendor/golang.org/x/text/width/tables13.0.0.go index ab258e38..bac3f1ae 100644 --- a/vendor/golang.org/x/text/width/tables13.0.0.go +++ b/vendor/golang.org/x/text/width/tables13.0.0.go @@ -1179,31 +1179,21 @@ var widthIndex = [1408]uint8{ } // inverseData contains 4-byte entries of the following format: -// -// <0 padding> -// +// <0 padding> // The last byte of the UTF-8-encoded rune is xor-ed with the last byte of the // UTF-8 encoding of the original rune. Mappings often have the following // pattern: -// -// A -> A (U+FF21 -> U+0041) -// B -> B (U+FF22 -> U+0042) -// ... -// +// A -> A (U+FF21 -> U+0041) +// B -> B (U+FF22 -> U+0042) +// ... // By xor-ing the last byte the same entry can be shared by many mappings. This // reduces the total number of distinct entries by about two thirds. // The resulting entry for the aforementioned mappings is -// -// { 0x01, 0xE0, 0x00, 0x00 } -// +// { 0x01, 0xE0, 0x00, 0x00 } // Using this entry to map U+FF21 (UTF-8 [EF BC A1]), we get -// -// E0 ^ A1 = 41. -// +// E0 ^ A1 = 41. // Similarly, for U+FF22 (UTF-8 [EF BC A2]), we get -// -// E0 ^ A2 = 42. -// +// E0 ^ A2 = 42. // Note that because of the xor-ing, the byte sequence stored in the entry is // not valid UTF-8. var inverseData = [150][4]byte{ diff --git a/vendor/golang.org/x/text/width/tables9.0.0.go b/vendor/golang.org/x/text/width/tables9.0.0.go index 6781f3d9..b3db84f6 100644 --- a/vendor/golang.org/x/text/width/tables9.0.0.go +++ b/vendor/golang.org/x/text/width/tables9.0.0.go @@ -1114,31 +1114,21 @@ var widthIndex = [1408]uint8{ } // inverseData contains 4-byte entries of the following format: -// -// <0 padding> -// +// <0 padding> // The last byte of the UTF-8-encoded rune is xor-ed with the last byte of the // UTF-8 encoding of the original rune. Mappings often have the following // pattern: -// -// A -> A (U+FF21 -> U+0041) -// B -> B (U+FF22 -> U+0042) -// ... -// +// A -> A (U+FF21 -> U+0041) +// B -> B (U+FF22 -> U+0042) +// ... // By xor-ing the last byte the same entry can be shared by many mappings. This // reduces the total number of distinct entries by about two thirds. // The resulting entry for the aforementioned mappings is -// -// { 0x01, 0xE0, 0x00, 0x00 } -// +// { 0x01, 0xE0, 0x00, 0x00 } // Using this entry to map U+FF21 (UTF-8 [EF BC A1]), we get -// -// E0 ^ A1 = 41. -// +// E0 ^ A1 = 41. // Similarly, for U+FF22 (UTF-8 [EF BC A2]), we get -// -// E0 ^ A2 = 42. -// +// E0 ^ A2 = 42. // Note that because of the xor-ing, the byte sequence stored in the entry is // not valid UTF-8. var inverseData = [150][4]byte{ diff --git a/vendor/google.golang.org/grpc/attributes/attributes.go b/vendor/google.golang.org/grpc/attributes/attributes.go index 02f5dc53..ae13ddac 100644 --- a/vendor/google.golang.org/grpc/attributes/attributes.go +++ b/vendor/google.golang.org/grpc/attributes/attributes.go @@ -19,7 +19,7 @@ // Package attributes defines a generic key/value store used in various gRPC // components. // -// # Experimental +// Experimental // // Notice: This package is EXPERIMENTAL and may be changed or removed in a // later release. diff --git a/vendor/google.golang.org/grpc/backoff.go b/vendor/google.golang.org/grpc/backoff.go index 29475e31..542594f5 100644 --- a/vendor/google.golang.org/grpc/backoff.go +++ b/vendor/google.golang.org/grpc/backoff.go @@ -48,7 +48,7 @@ type BackoffConfig struct { // here for more details: // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. diff --git a/vendor/google.golang.org/grpc/balancer/balancer.go b/vendor/google.golang.org/grpc/balancer/balancer.go index 392b21fb..f4f9408f 100644 --- a/vendor/google.golang.org/grpc/balancer/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/balancer.go @@ -110,11 +110,6 @@ type SubConn interface { UpdateAddresses([]resolver.Address) // Connect starts the connecting for this SubConn. Connect() - // GetOrBuildProducer returns a reference to the existing Producer for this - // ProducerBuilder in this SubConn, or, if one does not currently exist, - // creates a new one and returns it. Returns a close function which must - // be called when the Producer is no longer needed. - GetOrBuildProducer(ProducerBuilder) (p Producer, close func()) } // NewSubConnOptions contains options to create new SubConn. @@ -376,21 +371,3 @@ type ClientConnState struct { // ErrBadResolverState may be returned by UpdateClientConnState to indicate a // problem with the provided name resolver data. var ErrBadResolverState = errors.New("bad resolver state") - -// A ProducerBuilder is a simple constructor for a Producer. It is used by the -// SubConn to create producers when needed. -type ProducerBuilder interface { - // Build creates a Producer. The first parameter is always a - // grpc.ClientConnInterface (a type to allow creating RPCs/streams on the - // associated SubConn), but is declared as interface{} to avoid a - // dependency cycle. Should also return a close function that will be - // called when all references to the Producer have been given up. - Build(grpcClientConnInterface interface{}) (p Producer, close func()) -} - -// A Producer is a type shared among potentially many consumers. It is -// associated with a SubConn, and an implementation will typically contain -// other methods to provide additional functionality, e.g. configuration or -// subscription registration. -type Producer interface { -} diff --git a/vendor/google.golang.org/grpc/balancer/base/balancer.go b/vendor/google.golang.org/grpc/balancer/base/balancer.go index 3929c26d..e8dfc828 100644 --- a/vendor/google.golang.org/grpc/balancer/base/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/base/balancer.go @@ -157,8 +157,8 @@ func (b *baseBalancer) mergeErrors() error { // regeneratePicker takes a snapshot of the balancer, and generates a picker // from it. The picker is -// - errPicker if the balancer is in TransientFailure, -// - built by the pickerBuilder with all READY SubConns otherwise. +// - errPicker if the balancer is in TransientFailure, +// - built by the pickerBuilder with all READY SubConns otherwise. func (b *baseBalancer) regeneratePicker() { if b.state == connectivity.TransientFailure { b.picker = NewErrPicker(b.mergeErrors()) diff --git a/vendor/google.golang.org/grpc/balancer/conn_state_evaluator.go b/vendor/google.golang.org/grpc/balancer/conn_state_evaluator.go index c3341358..a87b6809 100644 --- a/vendor/google.golang.org/grpc/balancer/conn_state_evaluator.go +++ b/vendor/google.golang.org/grpc/balancer/conn_state_evaluator.go @@ -34,10 +34,10 @@ type ConnectivityStateEvaluator struct { // RecordTransition records state change happening in subConn and based on that // it evaluates what aggregated state should be. // -// - If at least one SubConn in Ready, the aggregated state is Ready; -// - Else if at least one SubConn in Connecting, the aggregated state is Connecting; -// - Else if at least one SubConn is Idle, the aggregated state is Idle; -// - Else if at least one SubConn is TransientFailure (or there are no SubConns), the aggregated state is Transient Failure. +// - If at least one SubConn in Ready, the aggregated state is Ready; +// - Else if at least one SubConn in Connecting, the aggregated state is Connecting; +// - Else if at least one SubConn is Idle, the aggregated state is Idle; +// - Else if at least one SubConn is TransientFailure (or there are no SubConns), the aggregated state is Transient Failure. // // Shutdown is not considered. func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState connectivity.State) connectivity.State { @@ -55,11 +55,7 @@ func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState conne cse.numIdle += updateVal } } - return cse.CurrentState() -} -// CurrentState returns the current aggregate conn state by evaluating the counters -func (cse *ConnectivityStateEvaluator) CurrentState() connectivity.State { // Evaluate. if cse.numReady > 0 { return connectivity.Ready diff --git a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go b/vendor/google.golang.org/grpc/balancer_conn_wrappers.go index 0359956d..b1c23eaa 100644 --- a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go +++ b/vendor/google.golang.org/grpc/balancer_conn_wrappers.go @@ -19,20 +19,17 @@ package grpc import ( - "context" "fmt" "strings" "sync" "google.golang.org/grpc/balancer" - "google.golang.org/grpc/codes" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/internal/balancer/gracefulswitch" "google.golang.org/grpc/internal/buffer" "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/resolver" - "google.golang.org/grpc/status" ) // ccBalancerWrapper sits between the ClientConn and the Balancer. @@ -308,7 +305,7 @@ func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer channelz.Warningf(logger, ccb.cc.channelzID, "acBalancerWrapper: NewSubConn: failed to newAddrConn: %v", err) return nil, err } - acbw := &acBalancerWrapper{ac: ac, producers: make(map[balancer.ProducerBuilder]*refCountedProducer)} + acbw := &acBalancerWrapper{ac: ac} acbw.ac.mu.Lock() ac.acbw = acbw acbw.ac.mu.Unlock() @@ -362,9 +359,8 @@ func (ccb *ccBalancerWrapper) Target() string { // acBalancerWrapper is a wrapper on top of ac for balancers. // It implements balancer.SubConn interface. type acBalancerWrapper struct { - mu sync.Mutex - ac *addrConn - producers map[balancer.ProducerBuilder]*refCountedProducer + mu sync.Mutex + ac *addrConn } func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { @@ -418,64 +414,3 @@ func (acbw *acBalancerWrapper) getAddrConn() *addrConn { defer acbw.mu.Unlock() return acbw.ac } - -var errSubConnNotReady = status.Error(codes.Unavailable, "SubConn not currently connected") - -// NewStream begins a streaming RPC on the addrConn. If the addrConn is not -// ready, returns errSubConnNotReady. -func (acbw *acBalancerWrapper) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) { - transport := acbw.ac.getReadyTransport() - if transport == nil { - return nil, errSubConnNotReady - } - return newNonRetryClientStream(ctx, desc, method, transport, acbw.ac, opts...) -} - -// Invoke performs a unary RPC. If the addrConn is not ready, returns -// errSubConnNotReady. -func (acbw *acBalancerWrapper) Invoke(ctx context.Context, method string, args interface{}, reply interface{}, opts ...CallOption) error { - cs, err := acbw.NewStream(ctx, unaryStreamDesc, method, opts...) - if err != nil { - return err - } - if err := cs.SendMsg(args); err != nil { - return err - } - return cs.RecvMsg(reply) -} - -type refCountedProducer struct { - producer balancer.Producer - refs int // number of current refs to the producer - close func() // underlying producer's close function -} - -func (acbw *acBalancerWrapper) GetOrBuildProducer(pb balancer.ProducerBuilder) (balancer.Producer, func()) { - acbw.mu.Lock() - defer acbw.mu.Unlock() - - // Look up existing producer from this builder. - pData := acbw.producers[pb] - if pData == nil { - // Not found; create a new one and add it to the producers map. - p, close := pb.Build(acbw) - pData = &refCountedProducer{producer: p, close: close} - acbw.producers[pb] = pData - } - // Account for this new reference. - pData.refs++ - - // Return a cleanup function wrapped in a OnceFunc to remove this reference - // and delete the refCountedProducer from the map if the total reference - // count goes to zero. - unref := func() { - acbw.mu.Lock() - pData.refs-- - if pData.refs == 0 { - defer pData.close() // Run outside the acbw mutex - delete(acbw.producers, pb) - } - acbw.mu.Unlock() - } - return pData.producer, grpcsync.OnceFunc(unref) -} diff --git a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go index 64a232f2..ed75290c 100644 --- a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go +++ b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go @@ -261,7 +261,6 @@ type GrpcLogEntry struct { // according to the type of the log entry. // // Types that are assignable to Payload: - // // *GrpcLogEntry_ClientHeader // *GrpcLogEntry_ServerHeader // *GrpcLogEntry_Message @@ -695,12 +694,12 @@ func (x *Message) GetData() []byte { // Header keys added by gRPC are omitted. To be more specific, // implementations will not log the following entries, and this is // not to be treated as a truncation: -// - entries handled by grpc that are not user visible, such as those -// that begin with 'grpc-' (with exception of grpc-trace-bin) -// or keys like 'lb-token' -// - transport specific entries, including but not limited to: -// ':path', ':authority', 'content-encoding', 'user-agent', 'te', etc -// - entries added for call credentials +// - entries handled by grpc that are not user visible, such as those +// that begin with 'grpc-' (with exception of grpc-trace-bin) +// or keys like 'lb-token' +// - transport specific entries, including but not limited to: +// ':path', ':authority', 'content-encoding', 'user-agent', 'te', etc +// - entries added for call credentials // // Implementations must always log grpc-trace-bin if it is present. // Practically speaking it will only be visible on server side because diff --git a/vendor/google.golang.org/grpc/channelz/channelz.go b/vendor/google.golang.org/grpc/channelz/channelz.go index 32b7fa57..a220c47c 100644 --- a/vendor/google.golang.org/grpc/channelz/channelz.go +++ b/vendor/google.golang.org/grpc/channelz/channelz.go @@ -23,7 +23,7 @@ // https://github.com/grpc/proposal/blob/master/A14-channelz.md, is provided by // the `internal/channelz` package. // -// # Experimental +// Experimental // // Notice: All APIs in this package are experimental and may be removed in a // later release. diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index 422639c7..779b03bc 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -503,7 +503,7 @@ type ClientConn struct { // WaitForStateChange waits until the connectivity.State of ClientConn changes from sourceState or // ctx expires. A true value is returned in former case and false in latter. // -// # Experimental +// Experimental // // Notice: This API is EXPERIMENTAL and may be changed or removed in a // later release. @@ -522,7 +522,7 @@ func (cc *ClientConn) WaitForStateChange(ctx context.Context, sourceState connec // GetState returns the connectivity.State of ClientConn. // -// # Experimental +// Experimental // // Notice: This API is EXPERIMENTAL and may be changed or removed in a later // release. @@ -534,7 +534,7 @@ func (cc *ClientConn) GetState() connectivity.State { // the channel is idle. Does not wait for the connection attempts to begin // before returning. // -// # Experimental +// Experimental // // Notice: This API is EXPERIMENTAL and may be changed or removed in a later // release. @@ -761,7 +761,7 @@ func (cc *ClientConn) channelzMetric() *channelz.ChannelInternalMetric { // Target returns the target string of the ClientConn. // -// # Experimental +// Experimental // // Notice: This API is EXPERIMENTAL and may be changed or removed in a // later release. @@ -831,9 +831,9 @@ func equalAddresses(a, b []resolver.Address) bool { // // If ac is Ready, it checks whether current connected address of ac is in the // new addrs list. -// - If true, it updates ac.addrs and returns true. The ac will keep using -// the existing connection. -// - If false, it does nothing and returns false. +// - If true, it updates ac.addrs and returns true. The ac will keep using +// the existing connection. +// - If false, it does nothing and returns false. func (ac *addrConn) tryUpdateAddrs(addrs []resolver.Address) bool { ac.mu.Lock() defer ac.mu.Unlock() @@ -998,7 +998,7 @@ func (cc *ClientConn) resolveNow(o resolver.ResolveNowOptions) { // However, if a previously unavailable network becomes available, this may be // used to trigger an immediate reconnect. // -// # Experimental +// Experimental // // Notice: This API is EXPERIMENTAL and may be changed or removed in a // later release. @@ -1228,33 +1228,38 @@ func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.T // address was not successfully connected, or updates ac appropriately with the // new transport. func (ac *addrConn) createTransport(addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time) error { + // TODO: Delete prefaceReceived and move the logic to wait for it into the + // transport. + prefaceReceived := grpcsync.NewEvent() + connClosed := grpcsync.NewEvent() + addr.ServerName = ac.cc.getServerName(addr) hctx, hcancel := context.WithCancel(ac.ctx) + hcStarted := false // protected by ac.mu - onClose := grpcsync.OnceFunc(func() { + onClose := func() { ac.mu.Lock() defer ac.mu.Unlock() - if ac.state == connectivity.Shutdown { - // Already shut down. tearDown() already cleared the transport and - // canceled hctx via ac.ctx, and we expected this connection to be - // closed, so do nothing here. - return - } - hcancel() - if ac.transport == nil { - // We're still connecting to this address, which could error. Do - // not update the connectivity state or resolve; these will happen - // at the end of the tryAllAddrs connection loop in the event of an - // error. + defer connClosed.Fire() + defer hcancel() + if !hcStarted || hctx.Err() != nil { + // We didn't start the health check or set the state to READY, so + // no need to do anything else here. + // + // OR, we have already cancelled the health check context, meaning + // we have already called onClose once for this transport. In this + // case it would be dangerous to clear the transport and update the + // state, since there may be a new transport in this addrConn. return } ac.transport = nil - // Refresh the name resolver on any connection loss. + // Refresh the name resolver ac.cc.resolveNow(resolver.ResolveNowOptions{}) - // Always go idle and wait for the LB policy to initiate a new - // connection attempt. - ac.updateConnectivityState(connectivity.Idle, nil) - }) + if ac.state != connectivity.Shutdown { + ac.updateConnectivityState(connectivity.Idle, nil) + } + } + onGoAway := func(r transport.GoAwayReason) { ac.mu.Lock() ac.adjustParams(r) @@ -1266,7 +1271,7 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne defer cancel() copts.ChannelzParentID = ac.channelzID - newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, onGoAway, onClose) + newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, func() { prefaceReceived.Fire() }, onGoAway, onClose) if err != nil { // newTr is either nil, or closed. hcancel() @@ -1274,34 +1279,60 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne return err } - ac.mu.Lock() - defer ac.mu.Unlock() - if ac.state == connectivity.Shutdown { - // This can happen if the subConn was removed while in `Connecting` - // state. tearDown() would have set the state to `Shutdown`, but - // would not have closed the transport since ac.transport would not - // have been set at that point. - // - // We run this in a goroutine because newTr.Close() calls onClose() - // inline, which requires locking ac.mu. - // + select { + case <-connectCtx.Done(): + // We didn't get the preface in time. // The error we pass to Close() is immaterial since there are no open // streams at this point, so no trailers with error details will be sent // out. We just need to pass a non-nil error. - go newTr.Close(transport.ErrConnClosing) + newTr.Close(transport.ErrConnClosing) + if connectCtx.Err() == context.DeadlineExceeded { + err := errors.New("failed to receive server preface within timeout") + channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %s: %v", addr, err) + return err + } return nil - } - if hctx.Err() != nil { - // onClose was already called for this connection, but the connection - // was successfully established first. Consider it a success and set - // the new state to Idle. - ac.updateConnectivityState(connectivity.Idle, nil) + case <-prefaceReceived.Done(): + // We got the preface - huzzah! things are good. + ac.mu.Lock() + defer ac.mu.Unlock() + if connClosed.HasFired() { + // onClose called first; go idle but do nothing else. + if ac.state != connectivity.Shutdown { + ac.updateConnectivityState(connectivity.Idle, nil) + } + return nil + } + if ac.state == connectivity.Shutdown { + // This can happen if the subConn was removed while in `Connecting` + // state. tearDown() would have set the state to `Shutdown`, but + // would not have closed the transport since ac.transport would not + // been set at that point. + // + // We run this in a goroutine because newTr.Close() calls onClose() + // inline, which requires locking ac.mu. + // + // The error we pass to Close() is immaterial since there are no open + // streams at this point, so no trailers with error details will be sent + // out. We just need to pass a non-nil error. + go newTr.Close(transport.ErrConnClosing) + return nil + } + ac.curAddr = addr + ac.transport = newTr + hcStarted = true + ac.startHealthCheck(hctx) // Will set state to READY if appropriate. return nil + case <-connClosed.Done(): + // The transport has already closed. If we received the preface, too, + // this is not an error. + select { + case <-prefaceReceived.Done(): + return nil + default: + return errors.New("connection closed before server preface received") + } } - ac.curAddr = addr - ac.transport = newTr - ac.startHealthCheck(hctx) // Will set state to READY if appropriate. - return nil } // startHealthCheck starts the health checking stream (RPC) to watch the health @@ -1552,7 +1583,7 @@ func (cc *ClientConn) parseTargetAndFindResolver() (resolver.Builder, error) { channelz.Infof(logger, cc.channelzID, "dial target %q parse failed: %v", cc.target, err) } else { channelz.Infof(logger, cc.channelzID, "parsed dial target is: %+v", parsedTarget) - rb = cc.getResolver(parsedTarget.URL.Scheme) + rb = cc.getResolver(parsedTarget.Scheme) if rb != nil { cc.parsedTarget = parsedTarget return rb, nil @@ -1573,9 +1604,9 @@ func (cc *ClientConn) parseTargetAndFindResolver() (resolver.Builder, error) { return nil, err } channelz.Infof(logger, cc.channelzID, "parsed dial target is: %+v", parsedTarget) - rb = cc.getResolver(parsedTarget.URL.Scheme) + rb = cc.getResolver(parsedTarget.Scheme) if rb == nil { - return nil, fmt.Errorf("could not get resolver for default scheme: %q", parsedTarget.URL.Scheme) + return nil, fmt.Errorf("could not get resolver for default scheme: %q", parsedTarget.Scheme) } cc.parsedTarget = parsedTarget return rb, nil diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go index 5feac3aa..96ff1877 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/credentials/credentials.go @@ -36,16 +36,16 @@ import ( // PerRPCCredentials defines the common interface for the credentials which need to // attach security information to every RPC (e.g., oauth2). type PerRPCCredentials interface { - // GetRequestMetadata gets the current request metadata, refreshing tokens - // if required. This should be called by the transport layer on each - // request, and the data should be populated in headers or other - // context. If a status code is returned, it will be used as the status for - // the RPC (restricted to an allowable set of codes as defined by gRFC - // A54). uri is the URI of the entry point for the request. When supported - // by the underlying implementation, ctx can be used for timeout and - // cancellation. Additionally, RequestInfo data will be available via ctx - // to this call. TODO(zhaoq): Define the set of the qualified keys instead - // of leaving it as an arbitrary string. + // GetRequestMetadata gets the current request metadata, refreshing + // tokens if required. This should be called by the transport layer on + // each request, and the data should be populated in headers or other + // context. If a status code is returned, it will be used as the status + // for the RPC. uri is the URI of the entry point for the request. + // When supported by the underlying implementation, ctx can be used for + // timeout and cancellation. Additionally, RequestInfo data will be + // available via ctx to this call. + // TODO(zhaoq): Define the set of the qualified keys instead of leaving + // it as an arbitrary string. GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) // RequireTransportSecurity indicates whether the credentials requires // transport security. diff --git a/vendor/google.golang.org/grpc/credentials/tls.go b/vendor/google.golang.org/grpc/credentials/tls.go index ce2bbc10..784822d0 100644 --- a/vendor/google.golang.org/grpc/credentials/tls.go +++ b/vendor/google.golang.org/grpc/credentials/tls.go @@ -195,7 +195,7 @@ func NewServerTLSFromFile(certFile, keyFile string) (TransportCredentials, error // TLSChannelzSecurityValue defines the struct that TLS protocol should return // from GetSecurityValue(), containing security info like cipher and certificate used. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go index 9372dc32..60403bc1 100644 --- a/vendor/google.golang.org/grpc/dialoptions.go +++ b/vendor/google.golang.org/grpc/dialoptions.go @@ -29,7 +29,6 @@ import ( "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/internal" internalbackoff "google.golang.org/grpc/internal/backoff" - "google.golang.org/grpc/internal/binarylog" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/resolver" @@ -37,13 +36,12 @@ import ( ) func init() { - internal.AddGlobalDialOptions = func(opt ...DialOption) { + internal.AddExtraDialOptions = func(opt ...DialOption) { extraDialOptions = append(extraDialOptions, opt...) } - internal.ClearGlobalDialOptions = func() { + internal.ClearExtraDialOptions = func() { extraDialOptions = nil } - internal.WithBinaryLogger = withBinaryLogger } // dialOptions configure a Dial call. dialOptions are set by the DialOption @@ -63,7 +61,6 @@ type dialOptions struct { timeout time.Duration scChan <-chan ServiceConfig authority string - binaryLogger binarylog.Logger copts transport.ConnectOptions callOptions []CallOption channelzParentID *channelz.Identifier @@ -404,14 +401,6 @@ func WithStatsHandler(h stats.Handler) DialOption { }) } -// withBinaryLogger returns a DialOption that specifies the binary logger for -// this ClientConn. -func withBinaryLogger(bl binarylog.Logger) DialOption { - return newFuncDialOption(func(o *dialOptions) { - o.binaryLogger = bl - }) -} - // FailOnNonTempDialError returns a DialOption that specifies if gRPC fails on // non-temporary dial errors. If f is true, and dialer returns a non-temporary // error, gRPC will fail the connection to the network address and won't try to diff --git a/vendor/google.golang.org/grpc/encoding/encoding.go b/vendor/google.golang.org/grpc/encoding/encoding.go index 711763d5..18e530fc 100644 --- a/vendor/google.golang.org/grpc/encoding/encoding.go +++ b/vendor/google.golang.org/grpc/encoding/encoding.go @@ -19,7 +19,7 @@ // Package encoding defines the interface for the compressor and codec, and // functions to register and retrieve compressors and codecs. // -// # Experimental +// Experimental // // Notice: This package is EXPERIMENTAL and may be changed or removed in a // later release. @@ -28,8 +28,6 @@ package encoding import ( "io" "strings" - - "google.golang.org/grpc/internal/grpcutil" ) // Identity specifies the optional encoding for uncompressed streams. @@ -75,7 +73,6 @@ var registeredCompressor = make(map[string]Compressor) // registered with the same name, the one registered last will take effect. func RegisterCompressor(c Compressor) { registeredCompressor[c.Name()] = c - grpcutil.RegisteredCompressorNames = append(grpcutil.RegisteredCompressorNames, c.Name()) } // GetCompressor returns Compressor for the given compressor name. diff --git a/vendor/google.golang.org/grpc/grpclog/loggerv2.go b/vendor/google.golang.org/grpc/grpclog/loggerv2.go index b5560b47..7c1f6640 100644 --- a/vendor/google.golang.org/grpc/grpclog/loggerv2.go +++ b/vendor/google.golang.org/grpc/grpclog/loggerv2.go @@ -242,7 +242,7 @@ func (g *loggerT) V(l int) bool { // DepthLoggerV2, the below functions will be called with the appropriate stack // depth set for trivial functions the logger may ignore. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. diff --git a/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go b/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go index 809d73cc..e3dfe204 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go @@ -37,7 +37,7 @@ type Logger interface { // binLogger is the global binary logger for the binary. One of this should be // built at init time from the configuration (environment variable or flags). // -// It is used to get a MethodLogger for each individual method. +// It is used to get a methodLogger for each individual method. var binLogger Logger var grpclogLogger = grpclog.Component("binarylog") @@ -56,11 +56,11 @@ func GetLogger() Logger { return binLogger } -// GetMethodLogger returns the MethodLogger for the given methodName. +// GetMethodLogger returns the methodLogger for the given methodName. // // methodName should be in the format of "/service/method". // -// Each MethodLogger returned by this method is a new instance. This is to +// Each methodLogger returned by this method is a new instance. This is to // generate sequence id within the call. func GetMethodLogger(methodName string) MethodLogger { if binLogger == nil { @@ -117,7 +117,7 @@ func (l *logger) setDefaultMethodLogger(ml *MethodLoggerConfig) error { // Set method logger for "service/*". // -// New MethodLogger with same service overrides the old one. +// New methodLogger with same service overrides the old one. func (l *logger) setServiceMethodLogger(service string, ml *MethodLoggerConfig) error { if _, ok := l.config.Services[service]; ok { return fmt.Errorf("conflicting service rules for service %v found", service) @@ -131,7 +131,7 @@ func (l *logger) setServiceMethodLogger(service string, ml *MethodLoggerConfig) // Set method logger for "service/method". // -// New MethodLogger with same method overrides the old one. +// New methodLogger with same method overrides the old one. func (l *logger) setMethodMethodLogger(method string, ml *MethodLoggerConfig) error { if _, ok := l.config.Blacklist[method]; ok { return fmt.Errorf("conflicting blacklist rules for method %v found", method) @@ -161,11 +161,11 @@ func (l *logger) setBlacklist(method string) error { return nil } -// getMethodLogger returns the MethodLogger for the given methodName. +// getMethodLogger returns the methodLogger for the given methodName. // // methodName should be in the format of "/service/method". // -// Each MethodLogger returned by this method is a new instance. This is to +// Each methodLogger returned by this method is a new instance. This is to // generate sequence id within the call. func (l *logger) GetMethodLogger(methodName string) MethodLogger { s, m, err := grpcutil.ParseMethod(methodName) @@ -174,16 +174,16 @@ func (l *logger) GetMethodLogger(methodName string) MethodLogger { return nil } if ml, ok := l.config.Methods[s+"/"+m]; ok { - return NewTruncatingMethodLogger(ml.Header, ml.Message) + return newMethodLogger(ml.Header, ml.Message) } if _, ok := l.config.Blacklist[s+"/"+m]; ok { return nil } if ml, ok := l.config.Services[s]; ok { - return NewTruncatingMethodLogger(ml.Header, ml.Message) + return newMethodLogger(ml.Header, ml.Message) } if l.config.All == nil { return nil } - return NewTruncatingMethodLogger(l.config.All.Header, l.config.All.Message) + return newMethodLogger(l.config.All.Header, l.config.All.Message) } diff --git a/vendor/google.golang.org/grpc/internal/binarylog/env_config.go b/vendor/google.golang.org/grpc/internal/binarylog/env_config.go index f9e80e27..ab589a76 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/env_config.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/env_config.go @@ -30,15 +30,15 @@ import ( // to build a new logger and assign it to binarylog.Logger. // // Example filter config strings: -// - "" Nothing will be logged -// - "*" All headers and messages will be fully logged. -// - "*{h}" Only headers will be logged. -// - "*{m:256}" Only the first 256 bytes of each message will be logged. -// - "Foo/*" Logs every method in service Foo -// - "Foo/*,-Foo/Bar" Logs every method in service Foo except method /Foo/Bar -// - "Foo/*,Foo/Bar{m:256}" Logs the first 256 bytes of each message in method -// /Foo/Bar, logs all headers and messages in every other method in service -// Foo. +// - "" Nothing will be logged +// - "*" All headers and messages will be fully logged. +// - "*{h}" Only headers will be logged. +// - "*{m:256}" Only the first 256 bytes of each message will be logged. +// - "Foo/*" Logs every method in service Foo +// - "Foo/*,-Foo/Bar" Logs every method in service Foo except method /Foo/Bar +// - "Foo/*,Foo/Bar{m:256}" Logs the first 256 bytes of each message in method +// /Foo/Bar, logs all headers and messages in every other method in service +// Foo. // // If two configs exist for one certain method or service, the one specified // later overrides the previous config. @@ -57,7 +57,7 @@ func NewLoggerFromConfigString(s string) Logger { return l } -// fillMethodLoggerWithConfigString parses config, creates TruncatingMethodLogger and adds +// fillMethodLoggerWithConfigString parses config, creates methodLogger and adds // it to the right map in the logger. func (l *logger) fillMethodLoggerWithConfigString(config string) error { // "" is invalid. diff --git a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go index 179f4a26..24df0a1a 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go @@ -52,9 +52,7 @@ type MethodLogger interface { Log(LogEntryConfig) } -// TruncatingMethodLogger is a method logger that truncates headers and messages -// based on configured fields. -type TruncatingMethodLogger struct { +type methodLogger struct { headerMaxLen, messageMaxLen uint64 callID uint64 @@ -63,9 +61,8 @@ type TruncatingMethodLogger struct { sink Sink // TODO(blog): make this plugable. } -// NewTruncatingMethodLogger returns a new truncating method logger. -func NewTruncatingMethodLogger(h, m uint64) *TruncatingMethodLogger { - return &TruncatingMethodLogger{ +func newMethodLogger(h, m uint64) *methodLogger { + return &methodLogger{ headerMaxLen: h, messageMaxLen: m, @@ -78,8 +75,8 @@ func NewTruncatingMethodLogger(h, m uint64) *TruncatingMethodLogger { // Build is an internal only method for building the proto message out of the // input event. It's made public to enable other library to reuse as much logic -// in TruncatingMethodLogger as possible. -func (ml *TruncatingMethodLogger) Build(c LogEntryConfig) *pb.GrpcLogEntry { +// in methodLogger as possible. +func (ml *methodLogger) Build(c LogEntryConfig) *pb.GrpcLogEntry { m := c.toProto() timestamp, _ := ptypes.TimestampProto(time.Now()) m.Timestamp = timestamp @@ -98,11 +95,11 @@ func (ml *TruncatingMethodLogger) Build(c LogEntryConfig) *pb.GrpcLogEntry { } // Log creates a proto binary log entry, and logs it to the sink. -func (ml *TruncatingMethodLogger) Log(c LogEntryConfig) { +func (ml *methodLogger) Log(c LogEntryConfig) { ml.sink.Write(ml.Build(c)) } -func (ml *TruncatingMethodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated bool) { +func (ml *methodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated bool) { if ml.headerMaxLen == maxUInt { return false } @@ -132,7 +129,7 @@ func (ml *TruncatingMethodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated return truncated } -func (ml *TruncatingMethodLogger) truncateMessage(msgPb *pb.Message) (truncated bool) { +func (ml *methodLogger) truncateMessage(msgPb *pb.Message) (truncated bool) { if ml.messageMaxLen == maxUInt { return false } diff --git a/vendor/google.golang.org/grpc/internal/channelz/types.go b/vendor/google.golang.org/grpc/internal/channelz/types.go index 7b2f350e..ad0ce4da 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/types.go +++ b/vendor/google.golang.org/grpc/internal/channelz/types.go @@ -273,10 +273,10 @@ func (c *channel) deleteSelfFromMap() (delete bool) { // deleteSelfIfReady tries to delete the channel itself from the channelz database. // The delete process includes two steps: -// 1. delete the channel from the entry relation tree, i.e. delete the channel reference from its -// parent's child list. -// 2. delete the channel from the map, i.e. delete the channel entirely from channelz. Lookup by id -// will return entry not found error. +// 1. delete the channel from the entry relation tree, i.e. delete the channel reference from its +// parent's child list. +// 2. delete the channel from the map, i.e. delete the channel entirely from channelz. Lookup by id +// will return entry not found error. func (c *channel) deleteSelfIfReady() { if !c.deleteSelfFromTree() { return @@ -381,10 +381,10 @@ func (sc *subChannel) deleteSelfFromMap() (delete bool) { // deleteSelfIfReady tries to delete the subchannel itself from the channelz database. // The delete process includes two steps: -// 1. delete the subchannel from the entry relation tree, i.e. delete the subchannel reference from -// its parent's child list. -// 2. delete the subchannel from the map, i.e. delete the subchannel entirely from channelz. Lookup -// by id will return entry not found error. +// 1. delete the subchannel from the entry relation tree, i.e. delete the subchannel reference from +// its parent's child list. +// 2. delete the subchannel from the map, i.e. delete the subchannel entirely from channelz. Lookup +// by id will return entry not found error. func (sc *subChannel) deleteSelfIfReady() { if !sc.deleteSelfFromTree() { return diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index 7edd196b..6f027254 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -25,15 +25,11 @@ import ( ) const ( - prefix = "GRPC_GO_" - txtErrIgnoreStr = prefix + "IGNORE_TXT_ERRORS" - advertiseCompressorsStr = prefix + "ADVERTISE_COMPRESSORS" + prefix = "GRPC_GO_" + txtErrIgnoreStr = prefix + "IGNORE_TXT_ERRORS" ) var ( // TXTErrIgnore is set if TXT errors should be ignored ("GRPC_GO_IGNORE_TXT_ERRORS" is not "false"). TXTErrIgnore = !strings.EqualFold(os.Getenv(txtErrIgnoreStr), "false") - // AdvertiseCompressors is set if registered compressor should be advertised - // ("GRPC_GO_ADVERTISE_COMPRESSORS" is not "false"). - AdvertiseCompressors = !strings.EqualFold(os.Getenv(advertiseCompressorsStr), "false") ) diff --git a/vendor/google.golang.org/grpc/internal/envconfig/observability.go b/vendor/google.golang.org/grpc/internal/envconfig/observability.go deleted file mode 100644 index 821dd0a7..00000000 --- a/vendor/google.golang.org/grpc/internal/envconfig/observability.go +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * Copyright 2022 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package envconfig - -import "os" - -const ( - envObservabilityConfig = "GRPC_GCP_OBSERVABILITY_CONFIG" - envObservabilityConfigFile = "GRPC_GCP_OBSERVABILITY_CONFIG_FILE" -) - -var ( - // ObservabilityConfig is the json configuration for the gcp/observability - // package specified directly in the envObservabilityConfig env var. - ObservabilityConfig = os.Getenv(envObservabilityConfig) - // ObservabilityConfigFile is the json configuration for the - // gcp/observability specified in a file with the location specified in - // envObservabilityConfigFile env var. - ObservabilityConfigFile = os.Getenv(envObservabilityConfigFile) -) diff --git a/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go b/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go index b68e26a3..30a3b425 100644 --- a/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go +++ b/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go @@ -110,7 +110,7 @@ type LoggerV2 interface { // This is a copy of the DepthLoggerV2 defined in the external grpclog package. // It is defined here to avoid a circular dependency. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. diff --git a/vendor/google.golang.org/grpc/internal/grpcsync/oncefunc.go b/vendor/google.golang.org/grpc/internal/grpcsync/oncefunc.go deleted file mode 100644 index 6635f7bc..00000000 --- a/vendor/google.golang.org/grpc/internal/grpcsync/oncefunc.go +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * Copyright 2022 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package grpcsync - -import ( - "sync" -) - -// OnceFunc returns a function wrapping f which ensures f is only executed -// once even if the returned function is executed multiple times. -func OnceFunc(f func()) func() { - var once sync.Once - return func() { - once.Do(f) - } -} diff --git a/vendor/google.golang.org/grpc/internal/grpcutil/compressor.go b/vendor/google.golang.org/grpc/internal/grpcutil/compressor.go deleted file mode 100644 index 9f409096..00000000 --- a/vendor/google.golang.org/grpc/internal/grpcutil/compressor.go +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright 2022 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package grpcutil - -import ( - "strings" - - "google.golang.org/grpc/internal/envconfig" -) - -// RegisteredCompressorNames holds names of the registered compressors. -var RegisteredCompressorNames []string - -// IsCompressorNameRegistered returns true when name is available in registry. -func IsCompressorNameRegistered(name string) bool { - for _, compressor := range RegisteredCompressorNames { - if compressor == name { - return true - } - } - return false -} - -// RegisteredCompressors returns a string of registered compressor names -// separated by comma. -func RegisteredCompressors() string { - if !envconfig.AdvertiseCompressors { - return "" - } - return strings.Join(RegisteredCompressorNames, ",") -} diff --git a/vendor/google.golang.org/grpc/internal/grpcutil/method.go b/vendor/google.golang.org/grpc/internal/grpcutil/method.go index ec62b477..e9c4af64 100644 --- a/vendor/google.golang.org/grpc/internal/grpcutil/method.go +++ b/vendor/google.golang.org/grpc/internal/grpcutil/method.go @@ -25,6 +25,7 @@ import ( // ParseMethod splits service and method from the input. It expects format // "/service/method". +// func ParseMethod(methodName string) (service, method string, _ error) { if !strings.HasPrefix(methodName, "/") { return "", "", errors.New("invalid method name: should start with /") diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go index fd0ee3dc..87cacb5b 100644 --- a/vendor/google.golang.org/grpc/internal/internal.go +++ b/vendor/google.golang.org/grpc/internal/internal.go @@ -63,31 +63,24 @@ var ( // xDS-enabled server invokes this method on a grpc.Server when a particular // listener moves to "not-serving" mode. DrainServerTransports interface{} // func(*grpc.Server, string) - // AddGlobalServerOptions adds an array of ServerOption that will be + // AddExtraServerOptions adds an array of ServerOption that will be // effective globally for newly created servers. The priority will be: 1. // user-provided; 2. this method; 3. default values. - AddGlobalServerOptions interface{} // func(opt ...ServerOption) - // ClearGlobalServerOptions clears the array of extra ServerOption. This + AddExtraServerOptions interface{} // func(opt ...ServerOption) + // ClearExtraServerOptions clears the array of extra ServerOption. This // method is useful in testing and benchmarking. - ClearGlobalServerOptions func() - // AddGlobalDialOptions adds an array of DialOption that will be effective + ClearExtraServerOptions func() + // AddExtraDialOptions adds an array of DialOption that will be effective // globally for newly created client channels. The priority will be: 1. // user-provided; 2. this method; 3. default values. - AddGlobalDialOptions interface{} // func(opt ...DialOption) - // ClearGlobalDialOptions clears the array of extra DialOption. This + AddExtraDialOptions interface{} // func(opt ...DialOption) + // ClearExtraDialOptions clears the array of extra DialOption. This // method is useful in testing and benchmarking. - ClearGlobalDialOptions func() + ClearExtraDialOptions func() // JoinServerOptions combines the server options passed as arguments into a // single server option. JoinServerOptions interface{} // func(...grpc.ServerOption) grpc.ServerOption - // WithBinaryLogger returns a DialOption that specifies the binary logger - // for a ClientConn. - WithBinaryLogger interface{} // func(binarylog.Logger) grpc.DialOption - // BinaryLogger returns a ServerOption that can set the binary logger for a - // server. - BinaryLogger interface{} // func(binarylog.Logger) grpc.ServerOption - // NewXDSResolverWithConfigForTesting creates a new xds resolver builder using // the provided xds bootstrap config instead of the global configuration from // the supported environment variables. The resolver.Builder is meant to be diff --git a/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go b/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go index 51e733e4..badbdbf5 100644 --- a/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go +++ b/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go @@ -67,10 +67,10 @@ func (bc *BalancerConfig) MarshalJSON() ([]byte, error) { // ServiceConfig contains a list of loadBalancingConfigs, each with a name and // config. This method iterates through that list in order, and stops at the // first policy that is supported. -// - If the config for the first supported policy is invalid, the whole service -// config is invalid. -// - If the list doesn't contain any supported policy, the whole service config -// is invalid. +// - If the config for the first supported policy is invalid, the whole service +// config is invalid. +// - If the list doesn't contain any supported policy, the whole service config +// is invalid. func (bc *BalancerConfig) UnmarshalJSON(b []byte) error { var ir intermediateBalancerConfig err := json.Unmarshal(b, &ir) diff --git a/vendor/google.golang.org/grpc/internal/status/status.go b/vendor/google.golang.org/grpc/internal/status/status.go index b0ead4f5..e5c6513e 100644 --- a/vendor/google.golang.org/grpc/internal/status/status.go +++ b/vendor/google.golang.org/grpc/internal/status/status.go @@ -164,13 +164,3 @@ func (e *Error) Is(target error) bool { } return proto.Equal(e.s.s, tse.s.s) } - -// IsRestrictedControlPlaneCode returns whether the status includes a code -// restricted for control plane usage as defined by gRFC A54. -func IsRestrictedControlPlaneCode(s *Status) bool { - switch s.Code() { - case codes.InvalidArgument, codes.NotFound, codes.AlreadyExists, codes.FailedPrecondition, codes.Aborted, codes.OutOfRange, codes.DataLoss: - return true - } - return false -} diff --git a/vendor/google.golang.org/grpc/internal/transport/handler_server.go b/vendor/google.golang.org/grpc/internal/transport/handler_server.go index fb272235..09012092 100644 --- a/vendor/google.golang.org/grpc/internal/transport/handler_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/handler_server.go @@ -442,10 +442,10 @@ func (ht *serverHandlerTransport) Drain() { // mapRecvMsgError returns the non-nil err into the appropriate // error value as expected by callers of *grpc.parser.recvMsg. // In particular, in can only be: -// - io.EOF -// - io.ErrUnexpectedEOF -// - of type transport.ConnectionError -// - an error from the status package +// * io.EOF +// * io.ErrUnexpectedEOF +// * of type transport.ConnectionError +// * an error from the status package func mapRecvMsgError(err error) error { if err == io.EOF || err == io.ErrUnexpectedEOF { return err diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index d518b07e..5c2f35b2 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -38,10 +38,8 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/internal/channelz" icredentials "google.golang.org/grpc/internal/credentials" - "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/internal/grpcutil" imetadata "google.golang.org/grpc/internal/metadata" - istatus "google.golang.org/grpc/internal/status" "google.golang.org/grpc/internal/syscall" "google.golang.org/grpc/internal/transport/networktype" "google.golang.org/grpc/keepalive" @@ -101,13 +99,16 @@ type http2Client struct { maxSendHeaderListSize *uint32 bdpEst *bdpEstimator + // onPrefaceReceipt is a callback that client transport calls upon + // receiving server preface to signal that a succefull HTTP2 + // connection was established. + onPrefaceReceipt func() maxConcurrentStreams uint32 streamQuota int64 streamsQuotaAvailable chan struct{} waitingStreams uint32 nextID uint32 - registeredCompressors string // Do not access controlBuf with mu held. mu sync.Mutex // guard the following variables @@ -193,7 +194,7 @@ func isTemporary(err error) bool { // newHTTP2Client constructs a connected ClientTransport to addr based on HTTP2 // and starts to receive messages on it. Non-nil error returns if construction // fails. -func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onGoAway func(GoAwayReason), onClose func()) (_ *http2Client, err error) { +func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onPrefaceReceipt func(), onGoAway func(GoAwayReason), onClose func()) (_ *http2Client, err error) { scheme := "http" ctx, cancel := context.WithCancel(ctx) defer func() { @@ -215,35 +216,12 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts } return nil, connectionErrorf(true, err, "transport: Error while dialing %v", err) } - // Any further errors will close the underlying connection defer func(conn net.Conn) { if err != nil { conn.Close() } }(conn) - - // The following defer and goroutine monitor the connectCtx for cancelation - // and deadline. On context expiration, the connection is hard closed and - // this function will naturally fail as a result. Otherwise, the defer - // waits for the goroutine to exit to prevent the context from being - // monitored (and to prevent the connection from ever being closed) after - // returning from this function. - ctxMonitorDone := grpcsync.NewEvent() - newClientCtx, newClientDone := context.WithCancel(connectCtx) - defer func() { - newClientDone() // Awaken the goroutine below if connectCtx hasn't expired. - <-ctxMonitorDone.Done() // Wait for the goroutine below to exit. - }() - go func(conn net.Conn) { - defer ctxMonitorDone.Fire() // Signal this goroutine has exited. - <-newClientCtx.Done() // Block until connectCtx expires or the defer above executes. - if connectCtx.Err() != nil { - // connectCtx expired before exiting the function. Hard close the connection. - conn.Close() - } - }(conn) - kp := opts.KeepaliveParams // Validate keepalive parameters. if kp.Time == 0 { @@ -275,7 +253,15 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts } } if transportCreds != nil { - conn, authInfo, err = transportCreds.ClientHandshake(connectCtx, addr.ServerName, conn) + rawConn := conn + // Pull the deadline from the connectCtx, which will be used for + // timeouts in the authentication protocol handshake. Can ignore the + // boolean as the deadline will return the zero value, which will make + // the conn not timeout on I/O operations. + deadline, _ := connectCtx.Deadline() + rawConn.SetDeadline(deadline) + conn, authInfo, err = transportCreds.ClientHandshake(connectCtx, addr.ServerName, rawConn) + rawConn.SetDeadline(time.Time{}) if err != nil { return nil, connectionErrorf(isTemporary(err), err, "transport: authentication handshake failed: %v", err) } @@ -313,7 +299,6 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts ctxDone: ctx.Done(), // Cache Done chan. cancel: cancel, userAgent: opts.UserAgent, - registeredCompressors: grpcutil.RegisteredCompressors(), conn: conn, remoteAddr: conn.RemoteAddr(), localAddr: conn.LocalAddr(), @@ -330,15 +315,16 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts kp: kp, statsHandlers: opts.StatsHandlers, initialWindowSize: initialWindowSize, + onPrefaceReceipt: onPrefaceReceipt, nextID: 1, maxConcurrentStreams: defaultMaxStreamsClient, streamQuota: defaultMaxStreamsClient, streamsQuotaAvailable: make(chan struct{}, 1), czData: new(channelzData), onGoAway: onGoAway, + onClose: onClose, keepaliveEnabled: keepaliveEnabled, bufferPool: newBufferPool(), - onClose: onClose, } // Add peer information to the http2client context. t.ctx = peer.NewContext(t.ctx, t.getPeer()) @@ -377,32 +363,21 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts t.kpDormancyCond = sync.NewCond(&t.mu) go t.keepalive() } - - // Start the reader goroutine for incoming messages. Each transport has a - // dedicated goroutine which reads HTTP2 frames from the network. Then it - // dispatches the frame to the corresponding stream entity. When the - // server preface is received, readerErrCh is closed. If an error occurs - // first, an error is pushed to the channel. This must be checked before - // returning from this function. - readerErrCh := make(chan error, 1) - go t.reader(readerErrCh) - defer func() { - if err == nil { - err = <-readerErrCh - } - if err != nil { - t.Close(err) - } - }() + // Start the reader goroutine for incoming message. Each transport has + // a dedicated goroutine which reads HTTP2 frame from network. Then it + // dispatches the frame to the corresponding stream entity. + go t.reader() // Send connection preface to server. n, err := t.conn.Write(clientPreface) if err != nil { err = connectionErrorf(true, err, "transport: failed to write client preface: %v", err) + t.Close(err) return nil, err } if n != len(clientPreface) { err = connectionErrorf(true, nil, "transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface)) + t.Close(err) return nil, err } var ss []http2.Setting @@ -422,12 +397,14 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts err = t.framer.fr.WriteSettings(ss...) if err != nil { err = connectionErrorf(true, err, "transport: failed to write initial settings frame: %v", err) + t.Close(err) return nil, err } // Adjust the connection flow control window if needed. if delta := uint32(icwz - defaultWindowSize); delta > 0 { if err := t.framer.fr.WriteWindowUpdate(0, delta); err != nil { err = connectionErrorf(true, err, "transport: failed to write window update: %v", err) + t.Close(err) return nil, err } } @@ -530,22 +507,9 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr) headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-previous-rpc-attempts", Value: strconv.Itoa(callHdr.PreviousAttempts)}) } - registeredCompressors := t.registeredCompressors if callHdr.SendCompress != "" { headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-encoding", Value: callHdr.SendCompress}) - // Include the outgoing compressor name when compressor is not registered - // via encoding.RegisterCompressor. This is possible when client uses - // WithCompressor dial option. - if !grpcutil.IsCompressorNameRegistered(callHdr.SendCompress) { - if registeredCompressors != "" { - registeredCompressors += "," - } - registeredCompressors += callHdr.SendCompress - } - } - - if registeredCompressors != "" { - headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-accept-encoding", Value: registeredCompressors}) + headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-accept-encoding", Value: callHdr.SendCompress}) } if dl, ok := ctx.Deadline(); ok { // Send out timeout regardless its value. The server can detect timeout context by itself. @@ -625,11 +589,7 @@ func (t *http2Client) getTrAuthData(ctx context.Context, audience string) (map[s for _, c := range t.perRPCCreds { data, err := c.GetRequestMetadata(ctx, audience) if err != nil { - if st, ok := status.FromError(err); ok { - // Restrict the code to the list allowed by gRFC A54. - if istatus.IsRestrictedControlPlaneCode(st) { - err = status.Errorf(codes.Internal, "transport: received per-RPC creds error with illegal status: %v", err) - } + if _, ok := status.FromError(err); ok { return nil, err } @@ -658,14 +618,7 @@ func (t *http2Client) getCallAuthData(ctx context.Context, audience string, call } data, err := callCreds.GetRequestMetadata(ctx, audience) if err != nil { - if st, ok := status.FromError(err); ok { - // Restrict the code to the list allowed by gRFC A54. - if istatus.IsRestrictedControlPlaneCode(st) { - err = status.Errorf(codes.Internal, "transport: received per-RPC creds error with illegal status: %v", err) - } - return nil, err - } - return nil, status.Errorf(codes.Internal, "transport: per-RPC creds failed due to error: %v", err) + return nil, status.Errorf(codes.Internal, "transport: %v", err) } callAuthData = make(map[string]string, len(data)) for k, v := range data { @@ -681,13 +634,13 @@ func (t *http2Client) getCallAuthData(ctx context.Context, audience string, call // NewStream errors result in transparent retry, as they mean nothing went onto // the wire. However, there are two notable exceptions: // -// 1. If the stream headers violate the max header list size allowed by the -// server. It's possible this could succeed on another transport, even if -// it's unlikely, but do not transparently retry. -// 2. If the credentials errored when requesting their headers. In this case, -// it's possible a retry can fix the problem, but indefinitely transparently -// retrying is not appropriate as it is likely the credentials, if they can -// eventually succeed, would need I/O to do so. +// 1. If the stream headers violate the max header list size allowed by the +// server. It's possible this could succeed on another transport, even if +// it's unlikely, but do not transparently retry. +// 2. If the credentials errored when requesting their headers. In this case, +// it's possible a retry can fix the problem, but indefinitely transparently +// retrying is not appropriate as it is likely the credentials, if they can +// eventually succeed, would need I/O to do so. type NewStreamError struct { Err error @@ -927,15 +880,19 @@ func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2. // Close kicks off the shutdown process of the transport. This should be called // only once on a transport. Once it is called, the transport should not be // accessed any more. +// +// This method blocks until the addrConn that initiated this transport is +// re-connected. This happens because t.onClose() begins reconnect logic at the +// addrConn level and blocks until the addrConn is successfully connected. func (t *http2Client) Close(err error) { t.mu.Lock() - // Make sure we only close once. + // Make sure we only Close once. if t.state == closing { t.mu.Unlock() return } - // Call t.onClose ASAP to prevent the client from attempting to create new - // streams. + // Call t.onClose before setting the state to closing to prevent the client + // from attempting to create new streams ASAP. t.onClose() t.state = closing streams := t.activeStreams @@ -1525,35 +1482,33 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { t.closeStream(s, io.EOF, rst, http2.ErrCodeNo, statusGen, mdata, true) } -// readServerPreface reads and handles the initial settings frame from the -// server. -func (t *http2Client) readServerPreface() error { +// reader runs as a separate goroutine in charge of reading data from network +// connection. +// +// TODO(zhaoq): currently one reader per transport. Investigate whether this is +// optimal. +// TODO(zhaoq): Check the validity of the incoming frame sequence. +func (t *http2Client) reader() { + defer close(t.readerDone) + // Check the validity of server preface. frame, err := t.framer.fr.ReadFrame() if err != nil { - return connectionErrorf(true, err, "error reading server preface: %v", err) - } - sf, ok := frame.(*http2.SettingsFrame) - if !ok { - return connectionErrorf(true, nil, "initial http2 frame from server is not a settings frame: %T", frame) - } - t.handleSettings(sf, true) - return nil -} - -// reader verifies the server preface and reads all subsequent data from -// network connection. If the server preface is not read successfully, an -// error is pushed to errCh; otherwise errCh is closed with no error. -func (t *http2Client) reader(errCh chan<- error) { - defer close(t.readerDone) - - if err := t.readServerPreface(); err != nil { - errCh <- err + err = connectionErrorf(true, err, "error reading server preface: %v", err) + t.Close(err) // this kicks off resetTransport, so must be last before return return } - close(errCh) + t.conn.SetReadDeadline(time.Time{}) // reset deadline once we get the settings frame (we didn't time out, yay!) if t.keepaliveEnabled { atomic.StoreInt64(&t.lastRead, time.Now().UnixNano()) } + sf, ok := frame.(*http2.SettingsFrame) + if !ok { + // this kicks off resetTransport, so must be last before return + t.Close(connectionErrorf(true, nil, "initial http2 frame from server is not a settings frame: %T", frame)) + return + } + t.onPrefaceReceipt() + t.handleSettings(sf, true) // loop to keep reading incoming messages on this transport. for { diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index 2e615ee2..6c3ba851 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -43,10 +43,6 @@ import ( "google.golang.org/grpc/tap" ) -// ErrNoHeaders is used as a signal that a trailers only response was received, -// and is not a real error. -var ErrNoHeaders = errors.New("stream has no headers") - const logLevel = 2 type bufferPool struct { @@ -370,15 +366,9 @@ func (s *Stream) Header() (metadata.MD, error) { return s.header.Copy(), nil } s.waitOnHeader() - if !s.headerValid { return nil, s.status.Err() } - - if s.noHeaders { - return nil, ErrNoHeaders - } - return s.header.Copy(), nil } @@ -583,8 +573,8 @@ type ConnectOptions struct { // NewClientTransport establishes the transport with the required ConnectOptions // and returns it to the caller. -func NewClientTransport(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onGoAway func(GoAwayReason), onClose func()) (ClientTransport, error) { - return newHTTP2Client(connectCtx, ctx, addr, opts, onGoAway, onClose) +func NewClientTransport(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onPrefaceReceipt func(), onGoAway func(GoAwayReason), onClose func()) (ClientTransport, error) { + return newHTTP2Client(connectCtx, ctx, addr, opts, onPrefaceReceipt, onGoAway, onClose) } // Options provides additional hints and information for message diff --git a/vendor/google.golang.org/grpc/metadata/metadata.go b/vendor/google.golang.org/grpc/metadata/metadata.go index fb4a88f5..98d62e06 100644 --- a/vendor/google.golang.org/grpc/metadata/metadata.go +++ b/vendor/google.golang.org/grpc/metadata/metadata.go @@ -41,11 +41,10 @@ type MD map[string][]string // New creates an MD from a given key-value map. // // Only the following ASCII characters are allowed in keys: -// - digits: 0-9 -// - uppercase letters: A-Z (normalized to lower) -// - lowercase letters: a-z -// - special characters: -_. -// +// - digits: 0-9 +// - uppercase letters: A-Z (normalized to lower) +// - lowercase letters: a-z +// - special characters: -_. // Uppercase letters are automatically converted to lowercase. // // Keys beginning with "grpc-" are reserved for grpc-internal use only and may @@ -63,11 +62,10 @@ func New(m map[string]string) MD { // Pairs panics if len(kv) is odd. // // Only the following ASCII characters are allowed in keys: -// - digits: 0-9 -// - uppercase letters: A-Z (normalized to lower) -// - lowercase letters: a-z -// - special characters: -_. -// +// - digits: 0-9 +// - uppercase letters: A-Z (normalized to lower) +// - lowercase letters: a-z +// - special characters: -_. // Uppercase letters are automatically converted to lowercase. // // Keys beginning with "grpc-" are reserved for grpc-internal use only and may @@ -198,7 +196,7 @@ func FromIncomingContext(ctx context.Context) (MD, bool) { // ValueFromIncomingContext returns the metadata value corresponding to the metadata // key from the incoming metadata if it exists. Key must be lower-case. // -// # Experimental +// Experimental // // Notice: This API is EXPERIMENTAL and may be changed or removed in a // later release. diff --git a/vendor/google.golang.org/grpc/picker_wrapper.go b/vendor/google.golang.org/grpc/picker_wrapper.go index a5d5516e..843633c9 100644 --- a/vendor/google.golang.org/grpc/picker_wrapper.go +++ b/vendor/google.golang.org/grpc/picker_wrapper.go @@ -26,7 +26,6 @@ import ( "google.golang.org/grpc/balancer" "google.golang.org/grpc/codes" "google.golang.org/grpc/internal/channelz" - istatus "google.golang.org/grpc/internal/status" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/status" ) @@ -130,12 +129,8 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer. if err == balancer.ErrNoSubConnAvailable { continue } - if st, ok := status.FromError(err); ok { + if _, ok := status.FromError(err); ok { // Status error: end the RPC unconditionally with this status. - // First restrict the code to the list allowed by gRFC A54. - if istatus.IsRestrictedControlPlaneCode(st) { - err = status.Errorf(codes.Internal, "received picker error with illegal status: %v", err) - } return nil, nil, dropError{error: err} } // For all other errors, wait for ready RPCs should block and other diff --git a/vendor/google.golang.org/grpc/preloader.go b/vendor/google.golang.org/grpc/preloader.go index cd455478..0a1e975a 100644 --- a/vendor/google.golang.org/grpc/preloader.go +++ b/vendor/google.golang.org/grpc/preloader.go @@ -25,7 +25,7 @@ import ( // PreparedMsg is responsible for creating a Marshalled and Compressed object. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. diff --git a/vendor/google.golang.org/grpc/resolver/resolver.go b/vendor/google.golang.org/grpc/resolver/resolver.go index 967cbc73..ca2e35a3 100644 --- a/vendor/google.golang.org/grpc/resolver/resolver.go +++ b/vendor/google.golang.org/grpc/resolver/resolver.go @@ -96,7 +96,7 @@ const ( // Address represents a server the client connects to. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. @@ -236,12 +236,12 @@ type ClientConn interface { // // Examples: // -// - "dns://some_authority/foo.bar" -// Target{Scheme: "dns", Authority: "some_authority", Endpoint: "foo.bar"} -// - "foo.bar" -// Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "foo.bar"} -// - "unknown_scheme://authority/endpoint" -// Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "unknown_scheme://authority/endpoint"} +// - "dns://some_authority/foo.bar" +// Target{Scheme: "dns", Authority: "some_authority", Endpoint: "foo.bar"} +// - "foo.bar" +// Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "foo.bar"} +// - "unknown_scheme://authority/endpoint" +// Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "unknown_scheme://authority/endpoint"} type Target struct { // Deprecated: use URL.Scheme instead. Scheme string diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index 934fc1aa..5d407b00 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -198,7 +198,7 @@ func Header(md *metadata.MD) CallOption { // HeaderCallOption is a CallOption for collecting response header metadata. // The metadata field will be populated *after* the RPC completes. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. @@ -220,7 +220,7 @@ func Trailer(md *metadata.MD) CallOption { // TrailerCallOption is a CallOption for collecting response trailer metadata. // The metadata field will be populated *after* the RPC completes. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. @@ -242,7 +242,7 @@ func Peer(p *peer.Peer) CallOption { // PeerCallOption is a CallOption for collecting the identity of the remote // peer. The peer field will be populated *after* the RPC completes. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. @@ -282,7 +282,7 @@ func FailFast(failFast bool) CallOption { // FailFastCallOption is a CallOption for indicating whether an RPC should fail // fast or not. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. @@ -305,7 +305,7 @@ func MaxCallRecvMsgSize(bytes int) CallOption { // MaxRecvMsgSizeCallOption is a CallOption that indicates the maximum message // size in bytes the client can receive. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. @@ -328,7 +328,7 @@ func MaxCallSendMsgSize(bytes int) CallOption { // MaxSendMsgSizeCallOption is a CallOption that indicates the maximum message // size in bytes the client can send. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. @@ -351,7 +351,7 @@ func PerRPCCredentials(creds credentials.PerRPCCredentials) CallOption { // PerRPCCredsCallOption is a CallOption that indicates the per-RPC // credentials to use for the call. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. @@ -369,7 +369,7 @@ func (o PerRPCCredsCallOption) after(c *callInfo, attempt *csAttempt) {} // sending the request. If WithCompressor is also set, UseCompressor has // higher priority. // -// # Experimental +// Experimental // // Notice: This API is EXPERIMENTAL and may be changed or removed in a // later release. @@ -379,7 +379,7 @@ func UseCompressor(name string) CallOption { // CompressorCallOption is a CallOption that indicates the compressor to use. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. @@ -416,7 +416,7 @@ func CallContentSubtype(contentSubtype string) CallOption { // ContentSubtypeCallOption is a CallOption that indicates the content-subtype // used for marshaling messages. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. @@ -444,7 +444,7 @@ func (o ContentSubtypeCallOption) after(c *callInfo, attempt *csAttempt) {} // This function is provided for advanced users; prefer to use only // CallContentSubtype to select a registered codec instead. // -// # Experimental +// Experimental // // Notice: This API is EXPERIMENTAL and may be changed or removed in a // later release. @@ -455,7 +455,7 @@ func ForceCodec(codec encoding.Codec) CallOption { // ForceCodecCallOption is a CallOption that indicates the codec used for // marshaling messages. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. @@ -480,7 +480,7 @@ func CallCustomCodec(codec Codec) CallOption { // CustomCodecCallOption is a CallOption that indicates the codec used for // marshaling messages. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. @@ -497,7 +497,7 @@ func (o CustomCodecCallOption) after(c *callInfo, attempt *csAttempt) {} // MaxRetryRPCBufferSize returns a CallOption that limits the amount of memory // used for buffering this RPC's requests for retry purposes. // -// # Experimental +// Experimental // // Notice: This API is EXPERIMENTAL and may be changed or removed in a // later release. @@ -508,7 +508,7 @@ func MaxRetryRPCBufferSize(bytes int) CallOption { // MaxRetryRPCBufferSizeCallOption is a CallOption indicating the amount of // memory to be used for caching this RPC for retry purposes. // -// # Experimental +// Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. @@ -548,11 +548,10 @@ type parser struct { // format. The caller owns the returned msg memory. // // If there is an error, possible values are: -// - io.EOF, when no messages remain -// - io.ErrUnexpectedEOF -// - of type transport.ConnectionError -// - an error from the status package -// +// * io.EOF, when no messages remain +// * io.ErrUnexpectedEOF +// * of type transport.ConnectionError +// * an error from the status package // No other error values or types must be returned, which also means // that the underlying io.Reader must not return an incompatible // error. diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index f4dde72b..6ef3df67 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -73,13 +73,12 @@ func init() { internal.DrainServerTransports = func(srv *Server, addr string) { srv.drainServerTransports(addr) } - internal.AddGlobalServerOptions = func(opt ...ServerOption) { - extraServerOptions = append(extraServerOptions, opt...) + internal.AddExtraServerOptions = func(opt ...ServerOption) { + extraServerOptions = opt } - internal.ClearGlobalServerOptions = func() { + internal.ClearExtraServerOptions = func() { extraServerOptions = nil } - internal.BinaryLogger = binaryLogger internal.JoinServerOptions = newJoinServerOption } @@ -157,7 +156,6 @@ type serverOptions struct { streamInt StreamServerInterceptor chainUnaryInts []UnaryServerInterceptor chainStreamInts []StreamServerInterceptor - binaryLogger binarylog.Logger inTapHandle tap.ServerInHandle statsHandlers []stats.Handler maxConcurrentStreams uint32 @@ -471,14 +469,6 @@ func StatsHandler(h stats.Handler) ServerOption { }) } -// binaryLogger returns a ServerOption that can set the binary logger for the -// server. -func binaryLogger(bl binarylog.Logger) ServerOption { - return newFuncServerOption(func(o *serverOptions) { - o.binaryLogger = bl - }) -} - // UnknownServiceHandler returns a ServerOption that allows for adding a custom // unknown service handler. The provided method is a bidi-streaming RPC service // handler that will be invoked instead of returning the "unimplemented" gRPC @@ -1226,16 +1216,9 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. } }() } - var binlogs []binarylog.MethodLogger - if ml := binarylog.GetMethodLogger(stream.Method()); ml != nil { - binlogs = append(binlogs, ml) - } - if s.opts.binaryLogger != nil { - if ml := s.opts.binaryLogger.GetMethodLogger(stream.Method()); ml != nil { - binlogs = append(binlogs, ml) - } - } - if len(binlogs) != 0 { + + binlog := binarylog.GetMethodLogger(stream.Method()) + if binlog != nil { ctx := stream.Context() md, _ := metadata.FromIncomingContext(ctx) logEntry := &binarylog.ClientHeader{ @@ -1255,9 +1238,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if peer, ok := peer.FromContext(ctx); ok { logEntry.PeerAddr = peer.Addr } - for _, binlog := range binlogs { - binlog.Log(logEntry) - } + binlog.Log(logEntry) } // comp and cp are used for compression. decomp and dc are used for @@ -1297,7 +1278,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. } var payInfo *payloadInfo - if len(shs) != 0 || len(binlogs) != 0 { + if len(shs) != 0 || binlog != nil { payInfo = &payloadInfo{} } d, err := recvAndDecompress(&parser{r: stream}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp) @@ -1323,13 +1304,10 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Length: len(d), }) } - if len(binlogs) != 0 { - cm := &binarylog.ClientMessage{ + if binlog != nil { + binlog.Log(&binarylog.ClientMessage{ Message: d, - } - for _, binlog := range binlogs { - binlog.Log(cm) - } + }) } if trInfo != nil { trInfo.tr.LazyLog(&payload{sent: false, msg: v}, true) @@ -1353,24 +1331,18 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if e := t.WriteStatus(stream, appStatus); e != nil { channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e) } - if len(binlogs) != 0 { + if binlog != nil { if h, _ := stream.Header(); h.Len() > 0 { // Only log serverHeader if there was header. Otherwise it can // be trailer only. - sh := &binarylog.ServerHeader{ + binlog.Log(&binarylog.ServerHeader{ Header: h, - } - for _, binlog := range binlogs { - binlog.Log(sh) - } + }) } - st := &binarylog.ServerTrailer{ + binlog.Log(&binarylog.ServerTrailer{ Trailer: stream.Trailer(), Err: appErr, - } - for _, binlog := range binlogs { - binlog.Log(st) - } + }) } return appErr } @@ -1396,34 +1368,26 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. panic(fmt.Sprintf("grpc: Unexpected error (%T) from sendResponse: %v", st, st)) } } - if len(binlogs) != 0 { + if binlog != nil { h, _ := stream.Header() - sh := &binarylog.ServerHeader{ + binlog.Log(&binarylog.ServerHeader{ Header: h, - } - st := &binarylog.ServerTrailer{ + }) + binlog.Log(&binarylog.ServerTrailer{ Trailer: stream.Trailer(), Err: appErr, - } - for _, binlog := range binlogs { - binlog.Log(sh) - binlog.Log(st) - } + }) } return err } - if len(binlogs) != 0 { + if binlog != nil { h, _ := stream.Header() - sh := &binarylog.ServerHeader{ + binlog.Log(&binarylog.ServerHeader{ Header: h, - } - sm := &binarylog.ServerMessage{ + }) + binlog.Log(&binarylog.ServerMessage{ Message: reply, - } - for _, binlog := range binlogs { - binlog.Log(sh) - binlog.Log(sm) - } + }) } if channelz.IsOn() { t.IncrMsgSent() @@ -1435,14 +1399,11 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. // Should the logging be in WriteStatus? Should we ignore the WriteStatus // error or allow the stats handler to see it? err = t.WriteStatus(stream, statusOK) - if len(binlogs) != 0 { - st := &binarylog.ServerTrailer{ + if binlog != nil { + binlog.Log(&binarylog.ServerTrailer{ Trailer: stream.Trailer(), Err: appErr, - } - for _, binlog := range binlogs { - binlog.Log(st) - } + }) } return err } @@ -1555,15 +1516,8 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp }() } - if ml := binarylog.GetMethodLogger(stream.Method()); ml != nil { - ss.binlogs = append(ss.binlogs, ml) - } - if s.opts.binaryLogger != nil { - if ml := s.opts.binaryLogger.GetMethodLogger(stream.Method()); ml != nil { - ss.binlogs = append(ss.binlogs, ml) - } - } - if len(ss.binlogs) != 0 { + ss.binlog = binarylog.GetMethodLogger(stream.Method()) + if ss.binlog != nil { md, _ := metadata.FromIncomingContext(ctx) logEntry := &binarylog.ClientHeader{ Header: md, @@ -1582,9 +1536,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp if peer, ok := peer.FromContext(ss.Context()); ok { logEntry.PeerAddr = peer.Addr } - for _, binlog := range ss.binlogs { - binlog.Log(logEntry) - } + ss.binlog.Log(logEntry) } // If dc is set and matches the stream's compression, use it. Otherwise, try @@ -1650,14 +1602,11 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp ss.mu.Unlock() } t.WriteStatus(ss.s, appStatus) - if len(ss.binlogs) != 0 { - st := &binarylog.ServerTrailer{ + if ss.binlog != nil { + ss.binlog.Log(&binarylog.ServerTrailer{ Trailer: ss.s.Trailer(), Err: appErr, - } - for _, binlog := range ss.binlogs { - binlog.Log(st) - } + }) } // TODO: Should we log an error from WriteStatus here and below? return appErr @@ -1668,14 +1617,11 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp ss.mu.Unlock() } err = t.WriteStatus(ss.s, statusOK) - if len(ss.binlogs) != 0 { - st := &binarylog.ServerTrailer{ + if ss.binlog != nil { + ss.binlog.Log(&binarylog.ServerTrailer{ Trailer: ss.s.Trailer(), Err: appErr, - } - for _, binlog := range ss.binlogs { - binlog.Log(st) - } + }) } return err } diff --git a/vendor/google.golang.org/grpc/serviceconfig/serviceconfig.go b/vendor/google.golang.org/grpc/serviceconfig/serviceconfig.go index 35e7a20a..73a2f926 100644 --- a/vendor/google.golang.org/grpc/serviceconfig/serviceconfig.go +++ b/vendor/google.golang.org/grpc/serviceconfig/serviceconfig.go @@ -19,7 +19,7 @@ // Package serviceconfig defines types and methods for operating on gRPC // service configs. // -// # Experimental +// Experimental // // Notice: This package is EXPERIMENTAL and may be changed or removed in a // later release. diff --git a/vendor/google.golang.org/grpc/status/status.go b/vendor/google.golang.org/grpc/status/status.go index 623be39f..6d163b6e 100644 --- a/vendor/google.golang.org/grpc/status/status.go +++ b/vendor/google.golang.org/grpc/status/status.go @@ -76,14 +76,14 @@ func FromProto(s *spb.Status) *Status { // FromError returns a Status representation of err. // -// - If err was produced by this package or implements the method `GRPCStatus() -// *Status`, the appropriate Status is returned. +// - If err was produced by this package or implements the method `GRPCStatus() +// *Status`, the appropriate Status is returned. // -// - If err is nil, a Status is returned with codes.OK and no message. +// - If err is nil, a Status is returned with codes.OK and no message. // -// - Otherwise, err is an error not compatible with this package. In this -// case, a Status is returned with codes.Unknown and err's Error() message, -// and ok is false. +// - Otherwise, err is an error not compatible with this package. In this +// case, a Status is returned with codes.Unknown and err's Error() message, +// and ok is false. func FromError(err error) (s *Status, ok bool) { if err == nil { return nil, true diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index 960c3e33..446a91e3 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -39,7 +39,6 @@ import ( imetadata "google.golang.org/grpc/internal/metadata" iresolver "google.golang.org/grpc/internal/resolver" "google.golang.org/grpc/internal/serviceconfig" - istatus "google.golang.org/grpc/internal/status" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" @@ -196,13 +195,6 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth rpcInfo := iresolver.RPCInfo{Context: ctx, Method: method} rpcConfig, err := cc.safeConfigSelector.SelectConfig(rpcInfo) if err != nil { - if st, ok := status.FromError(err); ok { - // Restrict the code to the list allowed by gRFC A54. - if istatus.IsRestrictedControlPlaneCode(st) { - err = status.Errorf(codes.Internal, "config selector returned illegal status: %v", err) - } - return nil, err - } return nil, toRPCErr(err) } @@ -309,14 +301,7 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client if !cc.dopts.disableRetry { cs.retryThrottler = cc.retryThrottler.Load().(*retryThrottler) } - if ml := binarylog.GetMethodLogger(method); ml != nil { - cs.binlogs = append(cs.binlogs, ml) - } - if cc.dopts.binaryLogger != nil { - if ml := cc.dopts.binaryLogger.GetMethodLogger(method); ml != nil { - cs.binlogs = append(cs.binlogs, ml) - } - } + cs.binlog = binarylog.GetMethodLogger(method) // Pick the transport to use and create a new stream on the transport. // Assign cs.attempt upon success. @@ -337,7 +322,7 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client return nil, err } - if len(cs.binlogs) != 0 { + if cs.binlog != nil { md, _ := metadata.FromOutgoingContext(ctx) logEntry := &binarylog.ClientHeader{ OnClientSide: true, @@ -351,9 +336,7 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client logEntry.Timeout = 0 } } - for _, binlog := range cs.binlogs { - binlog.Log(logEntry) - } + cs.binlog.Log(logEntry) } if desc != unaryStreamDesc { @@ -497,7 +480,7 @@ type clientStream struct { retryThrottler *retryThrottler // The throttler active when the RPC began. - binlogs []binarylog.MethodLogger + binlog binarylog.MethodLogger // Binary logger, can be nil. // serverHeaderBinlogged is a boolean for whether server header has been // logged. Server header will be logged when the first time one of those // happens: stream.Header(), stream.Recv(). @@ -752,25 +735,17 @@ func (cs *clientStream) withRetry(op func(a *csAttempt) error, onSuccess func()) func (cs *clientStream) Header() (metadata.MD, error) { var m metadata.MD - noHeader := false err := cs.withRetry(func(a *csAttempt) error { var err error m, err = a.s.Header() - if err == transport.ErrNoHeaders { - noHeader = true - return nil - } return toRPCErr(err) }, cs.commitAttemptLocked) - if err != nil { cs.finish(err) return nil, err } - - if len(cs.binlogs) != 0 && !cs.serverHeaderBinlogged && !noHeader { - // Only log if binary log is on and header has not been logged, and - // there is actually headers to log. + if cs.binlog != nil && !cs.serverHeaderBinlogged { + // Only log if binary log is on and header has not been logged. logEntry := &binarylog.ServerHeader{ OnClientSide: true, Header: m, @@ -779,10 +754,8 @@ func (cs *clientStream) Header() (metadata.MD, error) { if peer, ok := peer.FromContext(cs.Context()); ok { logEntry.PeerAddr = peer.Addr } + cs.binlog.Log(logEntry) cs.serverHeaderBinlogged = true - for _, binlog := range cs.binlogs { - binlog.Log(logEntry) - } } return m, nil } @@ -856,44 +829,38 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { return a.sendMsg(m, hdr, payload, data) } err = cs.withRetry(op, func() { cs.bufferForRetryLocked(len(hdr)+len(payload), op) }) - if len(cs.binlogs) != 0 && err == nil { - cm := &binarylog.ClientMessage{ + if cs.binlog != nil && err == nil { + cs.binlog.Log(&binarylog.ClientMessage{ OnClientSide: true, Message: data, - } - for _, binlog := range cs.binlogs { - binlog.Log(cm) - } + }) } return err } func (cs *clientStream) RecvMsg(m interface{}) error { - if len(cs.binlogs) != 0 && !cs.serverHeaderBinlogged { + if cs.binlog != nil && !cs.serverHeaderBinlogged { // Call Header() to binary log header if it's not already logged. cs.Header() } var recvInfo *payloadInfo - if len(cs.binlogs) != 0 { + if cs.binlog != nil { recvInfo = &payloadInfo{} } err := cs.withRetry(func(a *csAttempt) error { return a.recvMsg(m, recvInfo) }, cs.commitAttemptLocked) - if len(cs.binlogs) != 0 && err == nil { - sm := &binarylog.ServerMessage{ + if cs.binlog != nil && err == nil { + cs.binlog.Log(&binarylog.ServerMessage{ OnClientSide: true, Message: recvInfo.uncompressedBytes, - } - for _, binlog := range cs.binlogs { - binlog.Log(sm) - } + }) } if err != nil || !cs.desc.ServerStreams { // err != nil or non-server-streaming indicates end of stream. cs.finish(err) - if len(cs.binlogs) != 0 { + if cs.binlog != nil { // finish will not log Trailer. Log Trailer here. logEntry := &binarylog.ServerTrailer{ OnClientSide: true, @@ -906,9 +873,7 @@ func (cs *clientStream) RecvMsg(m interface{}) error { if peer, ok := peer.FromContext(cs.Context()); ok { logEntry.PeerAddr = peer.Addr } - for _, binlog := range cs.binlogs { - binlog.Log(logEntry) - } + cs.binlog.Log(logEntry) } } return err @@ -929,13 +894,10 @@ func (cs *clientStream) CloseSend() error { return nil } cs.withRetry(op, func() { cs.bufferForRetryLocked(0, op) }) - if len(cs.binlogs) != 0 { - chc := &binarylog.ClientHalfClose{ + if cs.binlog != nil { + cs.binlog.Log(&binarylog.ClientHalfClose{ OnClientSide: true, - } - for _, binlog := range cs.binlogs { - binlog.Log(chc) - } + }) } // We never returned an error here for reasons. return nil @@ -968,13 +930,10 @@ func (cs *clientStream) finish(err error) { // // Only one of cancel or trailer needs to be logged. In the cases where // users don't call RecvMsg, users must have already canceled the RPC. - if len(cs.binlogs) != 0 && status.Code(err) == codes.Canceled { - c := &binarylog.Cancel{ + if cs.binlog != nil && status.Code(err) == codes.Canceled { + cs.binlog.Log(&binarylog.Cancel{ OnClientSide: true, - } - for _, binlog := range cs.binlogs { - binlog.Log(c) - } + }) } if err == nil { cs.retryThrottler.successfulRPC() @@ -1046,7 +1005,6 @@ func (a *csAttempt) recvMsg(m interface{}, payInfo *payloadInfo) (err error) { } return io.EOF // indicates successful end of stream. } - return toRPCErr(err) } if a.trInfo != nil { @@ -1495,7 +1453,7 @@ type serverStream struct { statsHandler []stats.Handler - binlogs []binarylog.MethodLogger + binlog binarylog.MethodLogger // serverHeaderBinlogged indicates whether server header has been logged. It // will happen when one of the following two happens: stream.SendHeader(), // stream.Send(). @@ -1529,15 +1487,12 @@ func (ss *serverStream) SendHeader(md metadata.MD) error { } err = ss.t.WriteHeader(ss.s, md) - if len(ss.binlogs) != 0 && !ss.serverHeaderBinlogged { + if ss.binlog != nil && !ss.serverHeaderBinlogged { h, _ := ss.s.Header() - sh := &binarylog.ServerHeader{ + ss.binlog.Log(&binarylog.ServerHeader{ Header: h, - } + }) ss.serverHeaderBinlogged = true - for _, binlog := range ss.binlogs { - binlog.Log(sh) - } } return err } @@ -1594,23 +1549,17 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { if err := ss.t.Write(ss.s, hdr, payload, &transport.Options{Last: false}); err != nil { return toRPCErr(err) } - if len(ss.binlogs) != 0 { + if ss.binlog != nil { if !ss.serverHeaderBinlogged { h, _ := ss.s.Header() - sh := &binarylog.ServerHeader{ + ss.binlog.Log(&binarylog.ServerHeader{ Header: h, - } + }) ss.serverHeaderBinlogged = true - for _, binlog := range ss.binlogs { - binlog.Log(sh) - } } - sm := &binarylog.ServerMessage{ + ss.binlog.Log(&binarylog.ServerMessage{ Message: data, - } - for _, binlog := range ss.binlogs { - binlog.Log(sm) - } + }) } if len(ss.statsHandler) != 0 { for _, sh := range ss.statsHandler { @@ -1649,16 +1598,13 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { } }() var payInfo *payloadInfo - if len(ss.statsHandler) != 0 || len(ss.binlogs) != 0 { + if len(ss.statsHandler) != 0 || ss.binlog != nil { payInfo = &payloadInfo{} } if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxReceiveMessageSize, payInfo, ss.decomp); err != nil { if err == io.EOF { - if len(ss.binlogs) != 0 { - chc := &binarylog.ClientHalfClose{} - for _, binlog := range ss.binlogs { - binlog.Log(chc) - } + if ss.binlog != nil { + ss.binlog.Log(&binarylog.ClientHalfClose{}) } return err } @@ -1679,13 +1625,10 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { }) } } - if len(ss.binlogs) != 0 { - cm := &binarylog.ClientMessage{ + if ss.binlog != nil { + ss.binlog.Log(&binarylog.ClientMessage{ Message: payInfo.uncompressedBytes, - } - for _, binlog := range ss.binlogs { - binlog.Log(cm) - } + }) } return nil } diff --git a/vendor/google.golang.org/grpc/tap/tap.go b/vendor/google.golang.org/grpc/tap/tap.go index bfa5dfa4..dbf34e6b 100644 --- a/vendor/google.golang.org/grpc/tap/tap.go +++ b/vendor/google.golang.org/grpc/tap/tap.go @@ -19,7 +19,7 @@ // Package tap defines the function handles which are executed on the transport // layer of gRPC-Go and related information. // -// # Experimental +// Experimental // // Notice: This API is EXPERIMENTAL and may be changed or removed in a // later release. diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 2198e709..4a717069 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.51.0" +const Version = "1.51.0-dev" diff --git a/vendor/google.golang.org/grpc/vet.sh b/vendor/google.golang.org/grpc/vet.sh index bd8e0cdb..c3fc8253 100644 --- a/vendor/google.golang.org/grpc/vet.sh +++ b/vendor/google.golang.org/grpc/vet.sh @@ -67,9 +67,7 @@ elif [[ "$#" -ne 0 ]]; then fi # - Ensure all source files contain a copyright message. -# (Done in two parts because Darwin "git grep" has broken support for compound -# exclusion matches.) -(grep -L "DO NOT EDIT" $(git grep -L "\(Copyright [0-9]\{4,\} gRPC authors\)" -- '*.go') || true) | fail_on_output +not git grep -L "\(Copyright [0-9]\{4,\} gRPC authors\)\|DO NOT EDIT" -- '*.go' # - Make sure all tests in grpc and grpc/test use leakcheck via Teardown. not grep 'func Test[^(]' *_test.go @@ -83,7 +81,7 @@ not git grep -l 'x/net/context' -- "*.go" git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^stress\|grpcrand\|^benchmark\|wrr_test' # - Do not call grpclog directly. Use grpclog.Component instead. -git grep -l -e 'grpclog.I' --or -e 'grpclog.W' --or -e 'grpclog.E' --or -e 'grpclog.F' --or -e 'grpclog.V' -- "*.go" | not grep -v '^grpclog/component.go\|^internal/grpctest/tlogger_test.go' +git grep -l 'grpclog.I\|grpclog.W\|grpclog.E\|grpclog.F\|grpclog.V' -- "*.go" | not grep -v '^grpclog/component.go\|^internal/grpctest/tlogger_test.go' # - Ensure all ptypes proto packages are renamed when importing. not git grep "\(import \|^\s*\)\"github.com/golang/protobuf/ptypes/" -- "*.go" diff --git a/vendor/modules.txt b/vendor/modules.txt index 9402c003..249b9504 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -144,7 +144,6 @@ github.com/fsnotify/fsnotify # github.com/go-logr/logr v1.2.3 ## explicit; go 1.16 github.com/go-logr/logr -github.com/go-logr/logr/funcr # github.com/go-openapi/jsonpointer v0.19.5 ## explicit; go 1.13 github.com/go-openapi/jsonpointer @@ -205,7 +204,7 @@ github.com/josharian/intern # github.com/json-iterator/go v1.1.12 ## explicit; go 1.12 github.com/json-iterator/go -# github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.3.0 +# github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0 ## explicit; go 1.17 github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1 @@ -279,7 +278,7 @@ github.com/onsi/ginkgo/reporters/stenographer github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty github.com/onsi/ginkgo/types -# github.com/onsi/ginkgo/v2 v2.5.1 +# github.com/onsi/ginkgo/v2 v2.1.4 ## explicit; go 1.18 github.com/onsi/ginkgo/v2 github.com/onsi/ginkgo/v2/config @@ -291,7 +290,7 @@ github.com/onsi/ginkgo/v2/internal/parallel_support github.com/onsi/ginkgo/v2/internal/testingtproxy github.com/onsi/ginkgo/v2/reporters github.com/onsi/ginkgo/v2/types -# github.com/onsi/gomega v1.24.1 +# github.com/onsi/gomega v1.20.1 ## explicit; go 1.18 github.com/onsi/gomega github.com/onsi/gomega/format @@ -339,7 +338,7 @@ go.opencensus.io/internal go.opencensus.io/trace go.opencensus.io/trace/internal go.opencensus.io/trace/tracestate -# golang.org/x/net v0.2.0 +# golang.org/x/net v0.0.0-20220722155237-a158d28d115b ## explicit; go 1.17 golang.org/x/net/context golang.org/x/net/context/ctxhttp @@ -370,7 +369,7 @@ golang.org/x/sys/windows # golang.org/x/term v0.2.0 ## explicit; go 1.17 golang.org/x/term -# golang.org/x/text v0.4.0 +# golang.org/x/text v0.3.7 ## explicit; go 1.17 golang.org/x/text/encoding golang.org/x/text/encoding/charmap @@ -408,7 +407,7 @@ google.golang.org/appengine/urlfetch # google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 ## explicit; go 1.15 google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.51.0 +# google.golang.org/grpc v1.51.0-dev ## explicit; go 1.17 google.golang.org/grpc google.golang.org/grpc/attributes