Bumping k8s dependencies to 1.13
This commit is contained in:
6
vendor/k8s.io/apimachinery/pkg/util/httpstream/httpstream.go
generated
vendored
6
vendor/k8s.io/apimachinery/pkg/util/httpstream/httpstream.go
generated
vendored
@@ -136,12 +136,12 @@ func Handshake(req *http.Request, w http.ResponseWriter, serverProtocols []strin
|
||||
|
||||
negotiatedProtocol := negotiateProtocol(clientProtocols, serverProtocols)
|
||||
if len(negotiatedProtocol) == 0 {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
for i := range serverProtocols {
|
||||
w.Header().Add(HeaderAcceptedProtocolVersions, serverProtocols[i])
|
||||
}
|
||||
fmt.Fprintf(w, "unable to upgrade: unable to negotiate protocol: client supports %v, server accepts %v", clientProtocols, serverProtocols)
|
||||
return "", fmt.Errorf("unable to upgrade: unable to negotiate protocol: client supports %v, server supports %v", clientProtocols, serverProtocols)
|
||||
err := fmt.Errorf("unable to upgrade: unable to negotiate protocol: client supports %v, server accepts %v", clientProtocols, serverProtocols)
|
||||
http.Error(w, err.Error(), http.StatusForbidden)
|
||||
return "", err
|
||||
}
|
||||
|
||||
w.Header().Add(HeaderProtocolVersion, negotiatedProtocol)
|
||||
|
17
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper.go
generated
vendored
17
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper.go
generated
vendored
@@ -67,6 +67,9 @@ type SpdyRoundTripper struct {
|
||||
// followRedirects indicates if the round tripper should examine responses for redirects and
|
||||
// follow them.
|
||||
followRedirects bool
|
||||
// requireSameHostRedirects restricts redirect following to only follow redirects to the same host
|
||||
// as the original request.
|
||||
requireSameHostRedirects bool
|
||||
}
|
||||
|
||||
var _ utilnet.TLSClientConfigHolder = &SpdyRoundTripper{}
|
||||
@@ -75,14 +78,18 @@ var _ utilnet.Dialer = &SpdyRoundTripper{}
|
||||
|
||||
// NewRoundTripper creates a new SpdyRoundTripper that will use
|
||||
// the specified tlsConfig.
|
||||
func NewRoundTripper(tlsConfig *tls.Config, followRedirects bool) httpstream.UpgradeRoundTripper {
|
||||
return NewSpdyRoundTripper(tlsConfig, followRedirects)
|
||||
func NewRoundTripper(tlsConfig *tls.Config, followRedirects, requireSameHostRedirects bool) httpstream.UpgradeRoundTripper {
|
||||
return NewSpdyRoundTripper(tlsConfig, followRedirects, requireSameHostRedirects)
|
||||
}
|
||||
|
||||
// NewSpdyRoundTripper creates a new SpdyRoundTripper that will use
|
||||
// the specified tlsConfig. This function is mostly meant for unit tests.
|
||||
func NewSpdyRoundTripper(tlsConfig *tls.Config, followRedirects bool) *SpdyRoundTripper {
|
||||
return &SpdyRoundTripper{tlsConfig: tlsConfig, followRedirects: followRedirects}
|
||||
func NewSpdyRoundTripper(tlsConfig *tls.Config, followRedirects, requireSameHostRedirects bool) *SpdyRoundTripper {
|
||||
return &SpdyRoundTripper{
|
||||
tlsConfig: tlsConfig,
|
||||
followRedirects: followRedirects,
|
||||
requireSameHostRedirects: requireSameHostRedirects,
|
||||
}
|
||||
}
|
||||
|
||||
// TLSClientConfig implements pkg/util/net.TLSClientConfigHolder for proper TLS checking during
|
||||
@@ -257,7 +264,7 @@ func (s *SpdyRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
|
||||
)
|
||||
|
||||
if s.followRedirects {
|
||||
conn, rawResponse, err = utilnet.ConnectWithRedirects(req.Method, req.URL, header, req.Body, s)
|
||||
conn, rawResponse, err = utilnet.ConnectWithRedirects(req.Method, req.URL, header, req.Body, s, s.requireSameHostRedirects)
|
||||
} else {
|
||||
clone := utilnet.CloneRequest(req)
|
||||
clone.Header = header
|
||||
|
8
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper_test.go
generated
vendored
8
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper_test.go
generated
vendored
@@ -282,7 +282,7 @@ func TestRoundTripAndNewConnection(t *testing.T) {
|
||||
t.Fatalf("%s: Error creating request: %s", k, err)
|
||||
}
|
||||
|
||||
spdyTransport := NewSpdyRoundTripper(testCase.clientTLS, redirect)
|
||||
spdyTransport := NewSpdyRoundTripper(testCase.clientTLS, redirect, redirect)
|
||||
|
||||
var proxierCalled bool
|
||||
var proxyCalledWithHost string
|
||||
@@ -391,8 +391,8 @@ func TestRoundTripRedirects(t *testing.T) {
|
||||
}{
|
||||
{0, true},
|
||||
{1, true},
|
||||
{10, true},
|
||||
{11, false},
|
||||
{9, true},
|
||||
{10, false},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(fmt.Sprintf("with %d redirects", test.redirects), func(t *testing.T) {
|
||||
@@ -425,7 +425,7 @@ func TestRoundTripRedirects(t *testing.T) {
|
||||
t.Fatalf("Error creating request: %s", err)
|
||||
}
|
||||
|
||||
spdyTransport := NewSpdyRoundTripper(nil, true)
|
||||
spdyTransport := NewSpdyRoundTripper(nil, true, true)
|
||||
client := &http.Client{Transport: spdyTransport}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
|
8
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/upgrade.go
generated
vendored
8
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/upgrade.go
generated
vendored
@@ -74,15 +74,15 @@ func (u responseUpgrader) UpgradeResponse(w http.ResponseWriter, req *http.Reque
|
||||
connectionHeader := strings.ToLower(req.Header.Get(httpstream.HeaderConnection))
|
||||
upgradeHeader := strings.ToLower(req.Header.Get(httpstream.HeaderUpgrade))
|
||||
if !strings.Contains(connectionHeader, strings.ToLower(httpstream.HeaderUpgrade)) || !strings.Contains(upgradeHeader, strings.ToLower(HeaderSpdy31)) {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprintf(w, "unable to upgrade: missing upgrade headers in request: %#v", req.Header)
|
||||
errorMsg := fmt.Sprintf("unable to upgrade: missing upgrade headers in request: %#v", req.Header)
|
||||
http.Error(w, errorMsg, http.StatusBadRequest)
|
||||
return nil
|
||||
}
|
||||
|
||||
hijacker, ok := w.(http.Hijacker)
|
||||
if !ok {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
fmt.Fprintf(w, "unable to upgrade: unable to hijack response")
|
||||
errorMsg := fmt.Sprintf("unable to upgrade: unable to hijack response")
|
||||
http.Error(w, errorMsg, http.StatusInternalServerError)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
21
vendor/k8s.io/apimachinery/pkg/util/intstr/generated.pb.go
generated
vendored
21
vendor/k8s.io/apimachinery/pkg/util/intstr/generated.pb.go
generated
vendored
@@ -14,9 +14,8 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by protoc-gen-gogo.
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package intstr is a generated protocol buffer package.
|
||||
@@ -81,24 +80,6 @@ func (m *IntOrString) MarshalTo(dAtA []byte) (int, error) {
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func encodeFixed64Generated(dAtA []byte, offset int, v uint64) int {
|
||||
dAtA[offset] = uint8(v)
|
||||
dAtA[offset+1] = uint8(v >> 8)
|
||||
dAtA[offset+2] = uint8(v >> 16)
|
||||
dAtA[offset+3] = uint8(v >> 24)
|
||||
dAtA[offset+4] = uint8(v >> 32)
|
||||
dAtA[offset+5] = uint8(v >> 40)
|
||||
dAtA[offset+6] = uint8(v >> 48)
|
||||
dAtA[offset+7] = uint8(v >> 56)
|
||||
return offset + 8
|
||||
}
|
||||
func encodeFixed32Generated(dAtA []byte, offset int, v uint32) int {
|
||||
dAtA[offset] = uint8(v)
|
||||
dAtA[offset+1] = uint8(v >> 8)
|
||||
dAtA[offset+2] = uint8(v >> 16)
|
||||
dAtA[offset+3] = uint8(v >> 24)
|
||||
return offset + 4
|
||||
}
|
||||
func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int {
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
|
2
vendor/k8s.io/apimachinery/pkg/util/intstr/generated.proto
generated
vendored
2
vendor/k8s.io/apimachinery/pkg/util/intstr/generated.proto
generated
vendored
@@ -29,7 +29,7 @@ option go_package = "intstr";
|
||||
// inner type. This allows you to have, for example, a JSON field that can
|
||||
// accept a name or number.
|
||||
// TODO: Rename to Int32OrString
|
||||
//
|
||||
//
|
||||
// +protobuf=true
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
// +k8s:openapi-gen=true
|
||||
|
4
vendor/k8s.io/apimachinery/pkg/util/naming/from_stack_test.go
generated
vendored
4
vendor/k8s.io/apimachinery/pkg/util/naming/from_stack_test.go
generated
vendored
@@ -31,12 +31,12 @@ func TestGetNameFromCallsite(t *testing.T) {
|
||||
{
|
||||
name: "ignore-package",
|
||||
ignoredPackages: []string{"k8s.io/apimachinery/pkg/util/naming"},
|
||||
expected: "testing/testing.go:777",
|
||||
expected: "testing/testing.go:827",
|
||||
},
|
||||
{
|
||||
name: "ignore-file",
|
||||
ignoredPackages: []string{"k8s.io/apimachinery/pkg/util/naming/from_stack_test.go"},
|
||||
expected: "testing/testing.go:777",
|
||||
expected: "testing/testing.go:827",
|
||||
},
|
||||
{
|
||||
name: "ignore-multiple",
|
||||
|
18
vendor/k8s.io/apimachinery/pkg/util/net/http.go
generated
vendored
18
vendor/k8s.io/apimachinery/pkg/util/net/http.go
generated
vendored
@@ -321,9 +321,10 @@ type Dialer interface {
|
||||
|
||||
// ConnectWithRedirects uses dialer to send req, following up to 10 redirects (relative to
|
||||
// originalLocation). It returns the opened net.Conn and the raw response bytes.
|
||||
func ConnectWithRedirects(originalMethod string, originalLocation *url.URL, header http.Header, originalBody io.Reader, dialer Dialer) (net.Conn, []byte, error) {
|
||||
// If requireSameHostRedirects is true, only redirects to the same host are permitted.
|
||||
func ConnectWithRedirects(originalMethod string, originalLocation *url.URL, header http.Header, originalBody io.Reader, dialer Dialer, requireSameHostRedirects bool) (net.Conn, []byte, error) {
|
||||
const (
|
||||
maxRedirects = 10
|
||||
maxRedirects = 9 // Fail on the 10th redirect
|
||||
maxResponseSize = 16384 // play it safe to allow the potential for lots of / large headers
|
||||
)
|
||||
|
||||
@@ -387,10 +388,6 @@ redirectLoop:
|
||||
|
||||
resp.Body.Close() // not used
|
||||
|
||||
// Reset the connection.
|
||||
intermediateConn.Close()
|
||||
intermediateConn = nil
|
||||
|
||||
// Prepare to follow the redirect.
|
||||
redirectStr := resp.Header.Get("Location")
|
||||
if redirectStr == "" {
|
||||
@@ -404,6 +401,15 @@ redirectLoop:
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("malformed Location header: %v", err)
|
||||
}
|
||||
|
||||
// Only follow redirects to the same host. Otherwise, propagate the redirect response back.
|
||||
if requireSameHostRedirects && location.Hostname() != originalLocation.Hostname() {
|
||||
break redirectLoop
|
||||
}
|
||||
|
||||
// Reset the connection.
|
||||
intermediateConn.Close()
|
||||
intermediateConn = nil
|
||||
}
|
||||
|
||||
connToReturn := intermediateConn
|
||||
|
159
vendor/k8s.io/apimachinery/pkg/util/net/http_test.go
generated
vendored
159
vendor/k8s.io/apimachinery/pkg/util/net/http_test.go
generated
vendored
@@ -19,14 +19,23 @@ limitations under the License.
|
||||
package net
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
)
|
||||
|
||||
func TestGetClientIP(t *testing.T) {
|
||||
@@ -280,3 +289,153 @@ func TestJoinPreservingTrailingSlash(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConnectWithRedirects(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
redirects []string
|
||||
method string // initial request method, empty == GET
|
||||
expectError bool
|
||||
expectedRedirects int
|
||||
newPort bool // special case different port test
|
||||
}{{
|
||||
desc: "relative redirects allowed",
|
||||
redirects: []string{"/ok"},
|
||||
expectedRedirects: 1,
|
||||
}, {
|
||||
desc: "redirects to the same host are allowed",
|
||||
redirects: []string{"http://HOST/ok"}, // HOST replaced with server address in test
|
||||
expectedRedirects: 1,
|
||||
}, {
|
||||
desc: "POST redirects to GET",
|
||||
method: http.MethodPost,
|
||||
redirects: []string{"/ok"},
|
||||
expectedRedirects: 1,
|
||||
}, {
|
||||
desc: "PUT redirects to GET",
|
||||
method: http.MethodPut,
|
||||
redirects: []string{"/ok"},
|
||||
expectedRedirects: 1,
|
||||
}, {
|
||||
desc: "DELETE redirects to GET",
|
||||
method: http.MethodDelete,
|
||||
redirects: []string{"/ok"},
|
||||
expectedRedirects: 1,
|
||||
}, {
|
||||
desc: "9 redirects are allowed",
|
||||
redirects: []string{"/1", "/2", "/3", "/4", "/5", "/6", "/7", "/8", "/9"},
|
||||
expectedRedirects: 9,
|
||||
}, {
|
||||
desc: "10 redirects are forbidden",
|
||||
redirects: []string{"/1", "/2", "/3", "/4", "/5", "/6", "/7", "/8", "/9", "/10"},
|
||||
expectError: true,
|
||||
}, {
|
||||
desc: "redirect to different host are prevented",
|
||||
redirects: []string{"http://example.com/foo"},
|
||||
expectedRedirects: 0,
|
||||
}, {
|
||||
desc: "multiple redirect to different host forbidden",
|
||||
redirects: []string{"/1", "/2", "/3", "http://example.com/foo"},
|
||||
expectedRedirects: 3,
|
||||
}, {
|
||||
desc: "redirect to different port is allowed",
|
||||
redirects: []string{"http://HOST/foo"},
|
||||
expectedRedirects: 1,
|
||||
newPort: true,
|
||||
}}
|
||||
|
||||
const resultString = "Test output"
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
redirectCount := 0
|
||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
// Verify redirect request.
|
||||
if redirectCount > 0 {
|
||||
expectedURL, err := url.Parse(test.redirects[redirectCount-1])
|
||||
require.NoError(t, err, "test URL error")
|
||||
assert.Equal(t, req.URL.Path, expectedURL.Path, "unknown redirect path")
|
||||
assert.Equal(t, http.MethodGet, req.Method, "redirects must always be GET")
|
||||
}
|
||||
if redirectCount < len(test.redirects) {
|
||||
http.Redirect(w, req, test.redirects[redirectCount], http.StatusFound)
|
||||
redirectCount++
|
||||
} else if redirectCount == len(test.redirects) {
|
||||
w.Write([]byte(resultString))
|
||||
} else {
|
||||
t.Errorf("unexpected number of redirects %d to %s", redirectCount, req.URL.String())
|
||||
}
|
||||
}))
|
||||
defer s.Close()
|
||||
|
||||
u, err := url.Parse(s.URL)
|
||||
require.NoError(t, err, "Error parsing server URL")
|
||||
host := u.Host
|
||||
|
||||
// Special case new-port test with a secondary server.
|
||||
if test.newPort {
|
||||
s2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
w.Write([]byte(resultString))
|
||||
}))
|
||||
defer s2.Close()
|
||||
u2, err := url.Parse(s2.URL)
|
||||
require.NoError(t, err, "Error parsing secondary server URL")
|
||||
|
||||
// Sanity check: secondary server uses same hostname, different port.
|
||||
require.Equal(t, u.Hostname(), u2.Hostname(), "sanity check: same hostname")
|
||||
require.NotEqual(t, u.Port(), u2.Port(), "sanity check: different port")
|
||||
|
||||
// Redirect to the secondary server.
|
||||
host = u2.Host
|
||||
|
||||
}
|
||||
|
||||
// Update redirect URLs with actual host.
|
||||
for i := range test.redirects {
|
||||
test.redirects[i] = strings.Replace(test.redirects[i], "HOST", host, 1)
|
||||
}
|
||||
|
||||
method := test.method
|
||||
if method == "" {
|
||||
method = http.MethodGet
|
||||
}
|
||||
|
||||
netdialer := &net.Dialer{
|
||||
Timeout: wait.ForeverTestTimeout,
|
||||
KeepAlive: wait.ForeverTestTimeout,
|
||||
}
|
||||
dialer := DialerFunc(func(req *http.Request) (net.Conn, error) {
|
||||
conn, err := netdialer.Dial("tcp", req.URL.Host)
|
||||
if err != nil {
|
||||
return conn, err
|
||||
}
|
||||
if err = req.Write(conn); err != nil {
|
||||
require.NoError(t, conn.Close())
|
||||
return nil, fmt.Errorf("error sending request: %v", err)
|
||||
}
|
||||
return conn, err
|
||||
})
|
||||
conn, rawResponse, err := ConnectWithRedirects(method, u, http.Header{} /*body*/, nil, dialer, true)
|
||||
if test.expectError {
|
||||
require.Error(t, err, "expected request error")
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, err, "unexpected request error")
|
||||
assert.NoError(t, conn.Close(), "error closing connection")
|
||||
|
||||
resp, err := http.ReadResponse(bufio.NewReader(bytes.NewReader(rawResponse)), nil)
|
||||
require.NoError(t, err, "unexpected request error")
|
||||
|
||||
result, err := ioutil.ReadAll(resp.Body)
|
||||
require.NoError(t, resp.Body.Close())
|
||||
if test.expectedRedirects < len(test.redirects) {
|
||||
// Expect the last redirect to be returned.
|
||||
assert.Equal(t, http.StatusFound, resp.StatusCode, "Final response is not a redirect")
|
||||
assert.Equal(t, test.redirects[len(test.redirects)-1], resp.Header.Get("Location"))
|
||||
assert.NotEqual(t, resultString, string(result), "wrong content")
|
||||
} else {
|
||||
assert.Equal(t, resultString, string(result), "stream content does not match")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
4
vendor/k8s.io/apimachinery/pkg/util/proxy/upgradeaware.go
generated
vendored
4
vendor/k8s.io/apimachinery/pkg/util/proxy/upgradeaware.go
generated
vendored
@@ -68,6 +68,8 @@ type UpgradeAwareHandler struct {
|
||||
// InterceptRedirects determines whether the proxy should sniff backend responses for redirects,
|
||||
// following them as necessary.
|
||||
InterceptRedirects bool
|
||||
// RequireSameHostRedirects only allows redirects to the same host. It is only used if InterceptRedirects=true.
|
||||
RequireSameHostRedirects bool
|
||||
// UseRequestLocation will use the incoming request URL when talking to the backend server.
|
||||
UseRequestLocation bool
|
||||
// FlushInterval controls how often the standard HTTP proxy will flush content from the upstream.
|
||||
@@ -256,7 +258,7 @@ func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Reques
|
||||
utilnet.AppendForwardedForHeader(clone)
|
||||
if h.InterceptRedirects {
|
||||
glog.V(6).Infof("Connecting to backend proxy (intercepting redirects) %s\n Headers: %v", &location, clone.Header)
|
||||
backendConn, rawResponse, err = utilnet.ConnectWithRedirects(req.Method, &location, clone.Header, req.Body, utilnet.DialerFunc(h.DialForUpgrade))
|
||||
backendConn, rawResponse, err = utilnet.ConnectWithRedirects(req.Method, &location, clone.Header, req.Body, utilnet.DialerFunc(h.DialForUpgrade), h.RequireSameHostRedirects)
|
||||
} else {
|
||||
glog.V(6).Infof("Connecting to backend proxy (direct dial) %s\n Headers: %v", &location, clone.Header)
|
||||
clone.URL = &location
|
||||
|
9
vendor/k8s.io/apimachinery/pkg/util/rand/rand.go
generated
vendored
9
vendor/k8s.io/apimachinery/pkg/util/rand/rand.go
generated
vendored
@@ -27,7 +27,14 @@ var rng = struct {
|
||||
sync.Mutex
|
||||
rand *rand.Rand
|
||||
}{
|
||||
rand: rand.New(rand.NewSource(time.Now().UTC().UnixNano())),
|
||||
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||
}
|
||||
|
||||
// Int returns a non-negative pseudo-random int.
|
||||
func Int() int {
|
||||
rng.Lock()
|
||||
defer rng.Unlock()
|
||||
return rng.rand.Int()
|
||||
}
|
||||
|
||||
// Intn generates an integer in range [0,max).
|
||||
|
2
vendor/k8s.io/apimachinery/pkg/util/strategicpatch/testing/openapi.go
generated
vendored
2
vendor/k8s.io/apimachinery/pkg/util/strategicpatch/testing/openapi.go
generated
vendored
@@ -74,7 +74,7 @@ func getSchema(f Fake, model string) (openapi.Schema, error) {
|
||||
return m.LookupModel(model), nil
|
||||
}
|
||||
|
||||
// GetSchemaOrDie returns returns the openapi schema.
|
||||
// GetSchemaOrDie returns the openapi schema.
|
||||
func GetSchemaOrDie(f Fake, model string) openapi.Schema {
|
||||
s, err := getSchema(f, model)
|
||||
if err != nil {
|
||||
|
2
vendor/k8s.io/apimachinery/pkg/util/validation/validation_test.go
generated
vendored
2
vendor/k8s.io/apimachinery/pkg/util/validation/validation_test.go
generated
vendored
@@ -297,7 +297,7 @@ func TestIsValidLabelValue(t *testing.T) {
|
||||
"end-with-num-1",
|
||||
"1234", // only num
|
||||
strings.Repeat("a", 63), // to the limit
|
||||
"", // empty value
|
||||
"", // empty value
|
||||
}
|
||||
for i := range successCases {
|
||||
if errs := IsValidLabelValue(successCases[i]); len(errs) != 0 {
|
||||
|
18
vendor/k8s.io/apimachinery/pkg/util/version/doc.go
generated
vendored
Normal file
18
vendor/k8s.io/apimachinery/pkg/util/version/doc.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 version provides utilities for version number comparisons
|
||||
package version // import "k8s.io/apimachinery/pkg/util/version"
|
285
vendor/k8s.io/apimachinery/pkg/util/version/version.go
generated
vendored
Normal file
285
vendor/k8s.io/apimachinery/pkg/util/version/version.go
generated
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 version
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Version is an opqaue representation of a version number
|
||||
type Version struct {
|
||||
components []uint
|
||||
semver bool
|
||||
preRelease string
|
||||
buildMetadata string
|
||||
}
|
||||
|
||||
var (
|
||||
// versionMatchRE splits a version string into numeric and "extra" parts
|
||||
versionMatchRE = regexp.MustCompile(`^\s*v?([0-9]+(?:\.[0-9]+)*)(.*)*$`)
|
||||
// extraMatchRE splits the "extra" part of versionMatchRE into semver pre-release and build metadata; it does not validate the "no leading zeroes" constraint for pre-release
|
||||
extraMatchRE = regexp.MustCompile(`^(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?\s*$`)
|
||||
)
|
||||
|
||||
func parse(str string, semver bool) (*Version, error) {
|
||||
parts := versionMatchRE.FindStringSubmatch(str)
|
||||
if parts == nil {
|
||||
return nil, fmt.Errorf("could not parse %q as version", str)
|
||||
}
|
||||
numbers, extra := parts[1], parts[2]
|
||||
|
||||
components := strings.Split(numbers, ".")
|
||||
if (semver && len(components) != 3) || (!semver && len(components) < 2) {
|
||||
return nil, fmt.Errorf("illegal version string %q", str)
|
||||
}
|
||||
|
||||
v := &Version{
|
||||
components: make([]uint, len(components)),
|
||||
semver: semver,
|
||||
}
|
||||
for i, comp := range components {
|
||||
if (i == 0 || semver) && strings.HasPrefix(comp, "0") && comp != "0" {
|
||||
return nil, fmt.Errorf("illegal zero-prefixed version component %q in %q", comp, str)
|
||||
}
|
||||
num, err := strconv.ParseUint(comp, 10, 0)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("illegal non-numeric version component %q in %q: %v", comp, str, err)
|
||||
}
|
||||
v.components[i] = uint(num)
|
||||
}
|
||||
|
||||
if semver && extra != "" {
|
||||
extraParts := extraMatchRE.FindStringSubmatch(extra)
|
||||
if extraParts == nil {
|
||||
return nil, fmt.Errorf("could not parse pre-release/metadata (%s) in version %q", extra, str)
|
||||
}
|
||||
v.preRelease, v.buildMetadata = extraParts[1], extraParts[2]
|
||||
|
||||
for _, comp := range strings.Split(v.preRelease, ".") {
|
||||
if _, err := strconv.ParseUint(comp, 10, 0); err == nil {
|
||||
if strings.HasPrefix(comp, "0") && comp != "0" {
|
||||
return nil, fmt.Errorf("illegal zero-prefixed version component %q in %q", comp, str)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// ParseGeneric parses a "generic" version string. The version string must consist of two
|
||||
// or more dot-separated numeric fields (the first of which can't have leading zeroes),
|
||||
// followed by arbitrary uninterpreted data (which need not be separated from the final
|
||||
// numeric field by punctuation). For convenience, leading and trailing whitespace is
|
||||
// ignored, and the version can be preceded by the letter "v". See also ParseSemantic.
|
||||
func ParseGeneric(str string) (*Version, error) {
|
||||
return parse(str, false)
|
||||
}
|
||||
|
||||
// MustParseGeneric is like ParseGeneric except that it panics on error
|
||||
func MustParseGeneric(str string) *Version {
|
||||
v, err := ParseGeneric(str)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// ParseSemantic parses a version string that exactly obeys the syntax and semantics of
|
||||
// the "Semantic Versioning" specification (http://semver.org/) (although it ignores
|
||||
// leading and trailing whitespace, and allows the version to be preceded by "v"). For
|
||||
// version strings that are not guaranteed to obey the Semantic Versioning syntax, use
|
||||
// ParseGeneric.
|
||||
func ParseSemantic(str string) (*Version, error) {
|
||||
return parse(str, true)
|
||||
}
|
||||
|
||||
// MustParseSemantic is like ParseSemantic except that it panics on error
|
||||
func MustParseSemantic(str string) *Version {
|
||||
v, err := ParseSemantic(str)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Major returns the major release number
|
||||
func (v *Version) Major() uint {
|
||||
return v.components[0]
|
||||
}
|
||||
|
||||
// Minor returns the minor release number
|
||||
func (v *Version) Minor() uint {
|
||||
return v.components[1]
|
||||
}
|
||||
|
||||
// Patch returns the patch release number if v is a Semantic Version, or 0
|
||||
func (v *Version) Patch() uint {
|
||||
if len(v.components) < 3 {
|
||||
return 0
|
||||
}
|
||||
return v.components[2]
|
||||
}
|
||||
|
||||
// BuildMetadata returns the build metadata, if v is a Semantic Version, or ""
|
||||
func (v *Version) BuildMetadata() string {
|
||||
return v.buildMetadata
|
||||
}
|
||||
|
||||
// PreRelease returns the prerelease metadata, if v is a Semantic Version, or ""
|
||||
func (v *Version) PreRelease() string {
|
||||
return v.preRelease
|
||||
}
|
||||
|
||||
// Components returns the version number components
|
||||
func (v *Version) Components() []uint {
|
||||
return v.components
|
||||
}
|
||||
|
||||
// String converts a Version back to a string; note that for versions parsed with
|
||||
// ParseGeneric, this will not include the trailing uninterpreted portion of the version
|
||||
// number.
|
||||
func (v *Version) String() string {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
for i, comp := range v.components {
|
||||
if i > 0 {
|
||||
buffer.WriteString(".")
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf("%d", comp))
|
||||
}
|
||||
if v.preRelease != "" {
|
||||
buffer.WriteString("-")
|
||||
buffer.WriteString(v.preRelease)
|
||||
}
|
||||
if v.buildMetadata != "" {
|
||||
buffer.WriteString("+")
|
||||
buffer.WriteString(v.buildMetadata)
|
||||
}
|
||||
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// compareInternal returns -1 if v is less than other, 1 if it is greater than other, or 0
|
||||
// if they are equal
|
||||
func (v *Version) compareInternal(other *Version) int {
|
||||
|
||||
vLen := len(v.components)
|
||||
oLen := len(other.components)
|
||||
for i := 0; i < vLen && i < oLen; i++ {
|
||||
switch {
|
||||
case other.components[i] < v.components[i]:
|
||||
return 1
|
||||
case other.components[i] > v.components[i]:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
// If components are common but one has more items and they are not zeros, it is bigger
|
||||
switch {
|
||||
case oLen < vLen && !onlyZeros(v.components[oLen:]):
|
||||
return 1
|
||||
case oLen > vLen && !onlyZeros(other.components[vLen:]):
|
||||
return -1
|
||||
}
|
||||
|
||||
if !v.semver || !other.semver {
|
||||
return 0
|
||||
}
|
||||
|
||||
switch {
|
||||
case v.preRelease == "" && other.preRelease != "":
|
||||
return 1
|
||||
case v.preRelease != "" && other.preRelease == "":
|
||||
return -1
|
||||
case v.preRelease == other.preRelease: // includes case where both are ""
|
||||
return 0
|
||||
}
|
||||
|
||||
vPR := strings.Split(v.preRelease, ".")
|
||||
oPR := strings.Split(other.preRelease, ".")
|
||||
for i := 0; i < len(vPR) && i < len(oPR); i++ {
|
||||
vNum, err := strconv.ParseUint(vPR[i], 10, 0)
|
||||
if err == nil {
|
||||
oNum, err := strconv.ParseUint(oPR[i], 10, 0)
|
||||
if err == nil {
|
||||
switch {
|
||||
case oNum < vNum:
|
||||
return 1
|
||||
case oNum > vNum:
|
||||
return -1
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if oPR[i] < vPR[i] {
|
||||
return 1
|
||||
} else if oPR[i] > vPR[i] {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case len(oPR) < len(vPR):
|
||||
return 1
|
||||
case len(oPR) > len(vPR):
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// returns false if array contain any non-zero element
|
||||
func onlyZeros(array []uint) bool {
|
||||
for _, num := range array {
|
||||
if num != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// AtLeast tests if a version is at least equal to a given minimum version. If both
|
||||
// Versions are Semantic Versions, this will use the Semantic Version comparison
|
||||
// algorithm. Otherwise, it will compare only the numeric components, with non-present
|
||||
// components being considered "0" (ie, "1.4" is equal to "1.4.0").
|
||||
func (v *Version) AtLeast(min *Version) bool {
|
||||
return v.compareInternal(min) != -1
|
||||
}
|
||||
|
||||
// LessThan tests if a version is less than a given version. (It is exactly the opposite
|
||||
// of AtLeast, for situations where asking "is v too old?" makes more sense than asking
|
||||
// "is v new enough?".)
|
||||
func (v *Version) LessThan(other *Version) bool {
|
||||
return v.compareInternal(other) == -1
|
||||
}
|
||||
|
||||
// Compare compares v against a version string (which will be parsed as either Semantic
|
||||
// or non-Semantic depending on v). On success it returns -1 if v is less than other, 1 if
|
||||
// it is greater than other, or 0 if they are equal.
|
||||
func (v *Version) Compare(other string) (int, error) {
|
||||
ov, err := parse(other, v.semver)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return v.compareInternal(ov), nil
|
||||
}
|
348
vendor/k8s.io/apimachinery/pkg/util/version/version_test.go
generated
vendored
Normal file
348
vendor/k8s.io/apimachinery/pkg/util/version/version_test.go
generated
vendored
Normal file
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 version
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testItem struct {
|
||||
version string
|
||||
unparsed string
|
||||
equalsPrev bool
|
||||
}
|
||||
|
||||
func testOne(v *Version, item, prev testItem) error {
|
||||
str := v.String()
|
||||
if item.unparsed == "" {
|
||||
if str != item.version {
|
||||
return fmt.Errorf("bad round-trip: %q -> %q", item.version, str)
|
||||
}
|
||||
} else {
|
||||
if str != item.unparsed {
|
||||
return fmt.Errorf("bad unparse: %q -> %q, expected %q", item.version, str, item.unparsed)
|
||||
}
|
||||
}
|
||||
|
||||
if prev.version != "" {
|
||||
cmp, err := v.Compare(prev.version)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unexpected parse error: %v", err)
|
||||
}
|
||||
rv, err := parse(prev.version, v.semver)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unexpected parse error: %v", err)
|
||||
}
|
||||
rcmp, err := rv.Compare(item.version)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unexpected parse error: %v", err)
|
||||
}
|
||||
|
||||
switch {
|
||||
case cmp == -1:
|
||||
return fmt.Errorf("unexpected ordering %q < %q", item.version, prev.version)
|
||||
case cmp == 0 && !item.equalsPrev:
|
||||
return fmt.Errorf("unexpected comparison %q == %q", item.version, prev.version)
|
||||
case cmp == 1 && item.equalsPrev:
|
||||
return fmt.Errorf("unexpected comparison %q != %q", item.version, prev.version)
|
||||
case cmp != -rcmp:
|
||||
return fmt.Errorf("unexpected reverse comparison %q <=> %q %v %v %v %v", item.version, prev.version, cmp, rcmp, v.Components(), rv.Components())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestSemanticVersions(t *testing.T) {
|
||||
tests := []testItem{
|
||||
// This is every version string that appears in the 2.0 semver spec,
|
||||
// sorted in strictly increasing order except as noted.
|
||||
{version: "0.1.0"},
|
||||
{version: "1.0.0-0.3.7"},
|
||||
{version: "1.0.0-alpha"},
|
||||
{version: "1.0.0-alpha+001", equalsPrev: true},
|
||||
{version: "1.0.0-alpha.1"},
|
||||
{version: "1.0.0-alpha.beta"},
|
||||
{version: "1.0.0-beta"},
|
||||
{version: "1.0.0-beta+exp.sha.5114f85", equalsPrev: true},
|
||||
{version: "1.0.0-beta.2"},
|
||||
{version: "1.0.0-beta.11"},
|
||||
{version: "1.0.0-rc.1"},
|
||||
{version: "1.0.0-x.7.z.92"},
|
||||
{version: "1.0.0"},
|
||||
{version: "1.0.0+20130313144700", equalsPrev: true},
|
||||
{version: "1.8.0-alpha.3"},
|
||||
{version: "1.8.0-alpha.3.673+73326ef01d2d7c"},
|
||||
{version: "1.9.0"},
|
||||
{version: "1.10.0"},
|
||||
{version: "1.11.0"},
|
||||
{version: "2.0.0"},
|
||||
{version: "2.1.0"},
|
||||
{version: "2.1.1"},
|
||||
{version: "42.0.0"},
|
||||
|
||||
// We also allow whitespace and "v" prefix
|
||||
{version: " 42.0.0", unparsed: "42.0.0", equalsPrev: true},
|
||||
{version: "\t42.0.0 ", unparsed: "42.0.0", equalsPrev: true},
|
||||
{version: "43.0.0-1", unparsed: "43.0.0-1"},
|
||||
{version: "43.0.0-1 ", unparsed: "43.0.0-1", equalsPrev: true},
|
||||
{version: "v43.0.0-1", unparsed: "43.0.0-1", equalsPrev: true},
|
||||
{version: " v43.0.0", unparsed: "43.0.0"},
|
||||
{version: " 43.0.0 ", unparsed: "43.0.0", equalsPrev: true},
|
||||
}
|
||||
|
||||
var prev testItem
|
||||
for _, item := range tests {
|
||||
v, err := ParseSemantic(item.version)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected parse error: %v", err)
|
||||
continue
|
||||
}
|
||||
err = testOne(v, item, prev)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
prev = item
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadSemanticVersions(t *testing.T) {
|
||||
tests := []string{
|
||||
// "MUST take the form X.Y.Z"
|
||||
"1",
|
||||
"1.2",
|
||||
"1.2.3.4",
|
||||
".2.3",
|
||||
"1..3",
|
||||
"1.2.",
|
||||
"",
|
||||
"..",
|
||||
// "where X, Y, and Z are non-negative integers"
|
||||
"-1.2.3",
|
||||
"1.-2.3",
|
||||
"1.2.-3",
|
||||
"1a.2.3",
|
||||
"1.2a.3",
|
||||
"1.2.3a",
|
||||
"a1.2.3",
|
||||
"a.b.c",
|
||||
"1 .2.3",
|
||||
"1. 2.3",
|
||||
// "and MUST NOT contain leading zeroes."
|
||||
"01.2.3",
|
||||
"1.02.3",
|
||||
"1.2.03",
|
||||
// "[pre-release] identifiers MUST comprise only ASCII alphanumerics and hyphen"
|
||||
"1.2.3-/",
|
||||
// "[pre-release] identifiers MUST NOT be empty"
|
||||
"1.2.3-",
|
||||
"1.2.3-.",
|
||||
"1.2.3-foo.",
|
||||
"1.2.3-.foo",
|
||||
// "Numeric [pre-release] identifiers MUST NOT include leading zeroes"
|
||||
"1.2.3-01",
|
||||
// "[build metadata] identifiers MUST comprise only ASCII alphanumerics and hyphen"
|
||||
"1.2.3+/",
|
||||
// "[build metadata] identifiers MUST NOT be empty"
|
||||
"1.2.3+",
|
||||
"1.2.3+.",
|
||||
"1.2.3+foo.",
|
||||
"1.2.3+.foo",
|
||||
|
||||
// whitespace/"v"-prefix checks
|
||||
"v 1.2.3",
|
||||
"vv1.2.3",
|
||||
}
|
||||
|
||||
for i := range tests {
|
||||
_, err := ParseSemantic(tests[i])
|
||||
if err == nil {
|
||||
t.Errorf("unexpected success parsing invalid semver %q", tests[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenericVersions(t *testing.T) {
|
||||
tests := []testItem{
|
||||
// This is all of the strings from TestSemanticVersions, plus some strings
|
||||
// from TestBadSemanticVersions that should parse as generic versions,
|
||||
// plus some additional strings.
|
||||
{version: "0.1.0", unparsed: "0.1.0"},
|
||||
{version: "1.0.0-0.3.7", unparsed: "1.0.0"},
|
||||
{version: "1.0.0-alpha", unparsed: "1.0.0", equalsPrev: true},
|
||||
{version: "1.0.0-alpha+001", unparsed: "1.0.0", equalsPrev: true},
|
||||
{version: "1.0.0-alpha.1", unparsed: "1.0.0", equalsPrev: true},
|
||||
{version: "1.0.0-alpha.beta", unparsed: "1.0.0", equalsPrev: true},
|
||||
{version: "1.0.0.beta", unparsed: "1.0.0", equalsPrev: true},
|
||||
{version: "1.0.0-beta+exp.sha.5114f85", unparsed: "1.0.0", equalsPrev: true},
|
||||
{version: "1.0.0.beta.2", unparsed: "1.0.0", equalsPrev: true},
|
||||
{version: "1.0.0.beta.11", unparsed: "1.0.0", equalsPrev: true},
|
||||
{version: "1.0.0.rc.1", unparsed: "1.0.0", equalsPrev: true},
|
||||
{version: "1.0.0-x.7.z.92", unparsed: "1.0.0", equalsPrev: true},
|
||||
{version: "1.0.0", unparsed: "1.0.0", equalsPrev: true},
|
||||
{version: "1.0.0+20130313144700", unparsed: "1.0.0", equalsPrev: true},
|
||||
{version: "1.2", unparsed: "1.2"},
|
||||
{version: "1.2a.3", unparsed: "1.2", equalsPrev: true},
|
||||
{version: "1.2.3", unparsed: "1.2.3"},
|
||||
{version: "1.2.3.0", unparsed: "1.2.3.0", equalsPrev: true},
|
||||
{version: "1.2.3a", unparsed: "1.2.3", equalsPrev: true},
|
||||
{version: "1.2.3-foo.", unparsed: "1.2.3", equalsPrev: true},
|
||||
{version: "1.2.3-.foo", unparsed: "1.2.3", equalsPrev: true},
|
||||
{version: "1.2.3-01", unparsed: "1.2.3", equalsPrev: true},
|
||||
{version: "1.2.3+", unparsed: "1.2.3", equalsPrev: true},
|
||||
{version: "1.2.3+foo.", unparsed: "1.2.3", equalsPrev: true},
|
||||
{version: "1.2.3+.foo", unparsed: "1.2.3", equalsPrev: true},
|
||||
{version: "1.02.3", unparsed: "1.2.3", equalsPrev: true},
|
||||
{version: "1.2.03", unparsed: "1.2.3", equalsPrev: true},
|
||||
{version: "1.2.003", unparsed: "1.2.3", equalsPrev: true},
|
||||
{version: "1.2.3.4", unparsed: "1.2.3.4"},
|
||||
{version: "1.2.3.4b3", unparsed: "1.2.3.4", equalsPrev: true},
|
||||
{version: "1.2.3.4.5", unparsed: "1.2.3.4.5"},
|
||||
{version: "1.9.0", unparsed: "1.9.0"},
|
||||
{version: "1.9.0.0.0.0.0.0", unparsed: "1.9.0.0.0.0.0.0", equalsPrev: true},
|
||||
{version: "1.10.0", unparsed: "1.10.0"},
|
||||
{version: "1.11.0", unparsed: "1.11.0"},
|
||||
{version: "1.11.0.0.5", unparsed: "1.11.0.0.5"},
|
||||
{version: "2.0.0", unparsed: "2.0.0"},
|
||||
{version: "2.1.0", unparsed: "2.1.0"},
|
||||
{version: "2.1.1", unparsed: "2.1.1"},
|
||||
{version: "42.0.0", unparsed: "42.0.0"},
|
||||
{version: " 42.0.0", unparsed: "42.0.0", equalsPrev: true},
|
||||
{version: "\t42.0.0 ", unparsed: "42.0.0", equalsPrev: true},
|
||||
{version: "42.0.0-1", unparsed: "42.0.0", equalsPrev: true},
|
||||
{version: "42.0.0-1 ", unparsed: "42.0.0", equalsPrev: true},
|
||||
{version: "v42.0.0-1", unparsed: "42.0.0", equalsPrev: true},
|
||||
{version: " v43.0.0", unparsed: "43.0.0"},
|
||||
{version: " 43.0.0 ", unparsed: "43.0.0", equalsPrev: true},
|
||||
}
|
||||
|
||||
var prev testItem
|
||||
for _, item := range tests {
|
||||
v, err := ParseGeneric(item.version)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected parse error: %v", err)
|
||||
continue
|
||||
}
|
||||
err = testOne(v, item, prev)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
prev = item
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadGenericVersions(t *testing.T) {
|
||||
tests := []string{
|
||||
"1",
|
||||
"01.2.3",
|
||||
"-1.2.3",
|
||||
"1.-2.3",
|
||||
".2.3",
|
||||
"1..3",
|
||||
"1a.2.3",
|
||||
"a1.2.3",
|
||||
"1 .2.3",
|
||||
"1. 2.3",
|
||||
"1.bob",
|
||||
"bob",
|
||||
"v 1.2.3",
|
||||
"vv1.2.3",
|
||||
"",
|
||||
".",
|
||||
}
|
||||
|
||||
for i := range tests {
|
||||
_, err := ParseGeneric(tests[i])
|
||||
if err == nil {
|
||||
t.Errorf("unexpected success parsing invalid version %q", tests[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestComponents(t *testing.T) {
|
||||
|
||||
var tests = []struct {
|
||||
version string
|
||||
semver bool
|
||||
expectedComponents []uint
|
||||
expectedMajor uint
|
||||
expectedMinor uint
|
||||
expectedPatch uint
|
||||
expectedPreRelease string
|
||||
expectedBuildMetadata string
|
||||
}{
|
||||
{
|
||||
version: "1.0.2",
|
||||
semver: true,
|
||||
expectedComponents: []uint{1, 0, 2},
|
||||
expectedMajor: 1,
|
||||
expectedMinor: 0,
|
||||
expectedPatch: 2,
|
||||
},
|
||||
{
|
||||
version: "1.0.2-alpha+001",
|
||||
semver: true,
|
||||
expectedComponents: []uint{1, 0, 2},
|
||||
expectedMajor: 1,
|
||||
expectedMinor: 0,
|
||||
expectedPatch: 2,
|
||||
expectedPreRelease: "alpha",
|
||||
expectedBuildMetadata: "001",
|
||||
},
|
||||
{
|
||||
version: "1.2",
|
||||
semver: false,
|
||||
expectedComponents: []uint{1, 2},
|
||||
expectedMajor: 1,
|
||||
expectedMinor: 2,
|
||||
},
|
||||
{
|
||||
version: "1.0.2-beta+exp.sha.5114f85",
|
||||
semver: true,
|
||||
expectedComponents: []uint{1, 0, 2},
|
||||
expectedMajor: 1,
|
||||
expectedMinor: 0,
|
||||
expectedPatch: 2,
|
||||
expectedPreRelease: "beta",
|
||||
expectedBuildMetadata: "exp.sha.5114f85",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
version, _ := parse(test.version, test.semver)
|
||||
if !reflect.DeepEqual(test.expectedComponents, version.Components()) {
|
||||
t.Error("parse returned un'expected components")
|
||||
}
|
||||
if test.expectedMajor != version.Major() {
|
||||
t.Errorf("parse returned version.Major %d, expected %d", test.expectedMajor, version.Major())
|
||||
}
|
||||
if test.expectedMinor != version.Minor() {
|
||||
t.Errorf("parse returned version.Minor %d, expected %d", test.expectedMinor, version.Minor())
|
||||
}
|
||||
if test.expectedPatch != version.Patch() {
|
||||
t.Errorf("parse returned version.Patch %d, expected %d", test.expectedPatch, version.Patch())
|
||||
}
|
||||
if test.expectedPreRelease != version.PreRelease() {
|
||||
t.Errorf("parse returned version.PreRelease %s, expected %s", test.expectedPreRelease, version.PreRelease())
|
||||
}
|
||||
if test.expectedBuildMetadata != version.BuildMetadata() {
|
||||
t.Errorf("parse returned version.BuildMetadata %s, expected %s", test.expectedBuildMetadata, version.BuildMetadata())
|
||||
}
|
||||
}
|
||||
}
|
4
vendor/k8s.io/apimachinery/pkg/util/yaml/decoder_test.go
generated
vendored
4
vendor/k8s.io/apimachinery/pkg/util/yaml/decoder_test.go
generated
vendored
@@ -197,8 +197,8 @@ stuff: 1
|
||||
t.Fatal("expected error with yaml: violate, got no error")
|
||||
}
|
||||
fmt.Printf("err: %s\n", err.Error())
|
||||
if !strings.Contains(err.Error(), "yaml: line 2:") {
|
||||
t.Fatalf("expected %q to have 'yaml: line 2:' found a tab character", err.Error())
|
||||
if !strings.Contains(err.Error(), "yaml: line 3:") {
|
||||
t.Fatalf("expected %q to have 'yaml: line 3:' found a tab character", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user