Merge pull request #131704 from karlkfi/karl-watch-subtests
test: Use sub-tests in watch tests Kubernetes-commit: 4e80b05087cf26188208f1c80d133566be4eae18
This commit is contained in:
commit
df39bcd7dd
|
@ -808,9 +808,10 @@ func TestNotFound(t *testing.T) {
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
client := http.Client{}
|
client := http.Client{}
|
||||||
for k, v := range cases {
|
for testName, test := range cases {
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
request, err := http.NewRequestWithContext(ctx, v.Method, server.URL+v.Path, nil)
|
request, err := http.NewRequestWithContext(ctx, test.Method, server.URL+test.Path, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -820,9 +821,10 @@ func TestNotFound(t *testing.T) {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
defer apitesting.Close(t, response.Body)
|
defer apitesting.Close(t, response.Body)
|
||||||
if response.StatusCode != v.Status {
|
if response.StatusCode != test.Status {
|
||||||
t.Errorf("Expected %d for %s (%s), Got %#v", v.Status, v.Method, k, response)
|
t.Errorf("Expected %d for %s, Got %#v", test.Status, test.Method, response)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -879,9 +881,10 @@ func TestUnimplementedRESTStorage(t *testing.T) {
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
client := http.Client{}
|
client := http.Client{}
|
||||||
for k, v := range cases {
|
for testName, test := range cases {
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
request, err := http.NewRequestWithContext(ctx, v.Method, server.URL+v.Path, bytes.NewReader([]byte(`{"kind":"Simple","apiVersion":"version"}`)))
|
request, err := http.NewRequestWithContext(ctx, test.Method, server.URL+test.Path, bytes.NewReader([]byte(`{"kind":"Simple","apiVersion":"version"}`)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -895,10 +898,10 @@ func TestUnimplementedRESTStorage(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if response.StatusCode != v.ErrCode {
|
if response.StatusCode != test.ErrCode {
|
||||||
t.Errorf("%s: expected %d for %s, Got %s", k, v.ErrCode, v.Method, string(data))
|
t.Fatalf("expected %d for %s, Got %s", test.ErrCode, test.Method, string(data))
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -949,9 +952,10 @@ func TestSomeUnimplementedRESTStorage(t *testing.T) {
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
client := http.Client{}
|
client := http.Client{}
|
||||||
for k, v := range cases {
|
for testName, test := range cases {
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
request, err := http.NewRequestWithContext(ctx, v.Method, server.URL+v.Path, bytes.NewReader([]byte(`{"kind":"Simple","apiVersion":"version"}`)))
|
request, err := http.NewRequestWithContext(ctx, test.Method, server.URL+test.Path, bytes.NewReader([]byte(`{"kind":"Simple","apiVersion":"version"}`)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -965,15 +969,15 @@ func TestSomeUnimplementedRESTStorage(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if response.StatusCode != v.ErrCode {
|
if response.StatusCode != test.ErrCode {
|
||||||
t.Errorf("%s: expected %d for %s, Got %s", k, v.ErrCode, v.Method, string(data))
|
t.Fatalf("expected %d for %s, Got %s", test.ErrCode, test.Method, string(data))
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestList(t *testing.T) {
|
func TestList(t *testing.T) {
|
||||||
testCases := []struct {
|
cases := []struct {
|
||||||
url string
|
url string
|
||||||
namespace string
|
namespace string
|
||||||
legacy bool
|
legacy bool
|
||||||
|
@ -1110,45 +1114,46 @@ func TestList(t *testing.T) {
|
||||||
namespace: "",
|
namespace: "",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i, testCase := range testCases {
|
for testIndex, test := range cases {
|
||||||
|
testName := fmt.Sprintf("%d", testIndex)
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
||||||
simpleStorage := SimpleRESTStorage{expectedResourceNamespace: testCase.namespace}
|
simpleStorage := SimpleRESTStorage{expectedResourceNamespace: test.namespace}
|
||||||
storage["simple"] = &simpleStorage
|
storage["simple"] = &simpleStorage
|
||||||
var handler = handleInternal(storage, admissionControl, nil)
|
var handler = handleInternal(storage, admissionControl, nil)
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
url := server.URL + testCase.url
|
url := server.URL + test.url
|
||||||
req, err := http.NewRequestWithContext(ctx, request.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, request.MethodGet, url, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%d: unexpected error: %v", i, err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
defer apitesting.Close(t, resp.Body)
|
defer apitesting.Close(t, resp.Body)
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
t.Errorf("%d: unexpected status: %d from url %s, Expected: %d, %#v", i, resp.StatusCode, testCase.url, http.StatusOK, resp)
|
t.Errorf("unexpected status: %d from url %s, Expected: %d, %#v", resp.StatusCode, test.url, http.StatusOK, resp)
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%d: unexpected error: %v", i, err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
t.Logf("%d: body: %s", i, string(body))
|
t.Logf("body: %s", string(body))
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
if !simpleStorage.namespacePresent {
|
if !simpleStorage.namespacePresent {
|
||||||
t.Errorf("%d: namespace not set", i)
|
t.Error("namespace not set")
|
||||||
} else if simpleStorage.actualNamespace != testCase.namespace {
|
} else if simpleStorage.actualNamespace != test.namespace {
|
||||||
t.Errorf("%d: %q unexpected resource namespace: %s", i, testCase.url, simpleStorage.actualNamespace)
|
t.Errorf("%q unexpected resource namespace: %s", test.url, simpleStorage.actualNamespace)
|
||||||
}
|
}
|
||||||
if simpleStorage.requestedLabelSelector == nil || simpleStorage.requestedLabelSelector.String() != testCase.label {
|
if simpleStorage.requestedLabelSelector == nil || simpleStorage.requestedLabelSelector.String() != test.label {
|
||||||
t.Errorf("%d: unexpected label selector: expected=%v got=%v", i, testCase.label, simpleStorage.requestedLabelSelector)
|
t.Errorf("unexpected label selector: expected=%v got=%v", test.label, simpleStorage.requestedLabelSelector)
|
||||||
}
|
}
|
||||||
if simpleStorage.requestedFieldSelector == nil || simpleStorage.requestedFieldSelector.String() != testCase.field {
|
if simpleStorage.requestedFieldSelector == nil || simpleStorage.requestedFieldSelector.String() != test.field {
|
||||||
t.Errorf("%d: unexpected field selector: expected=%v got=%v", i, testCase.field, simpleStorage.requestedFieldSelector)
|
t.Errorf("unexpected field selector: expected=%v got=%v", test.field, simpleStorage.requestedFieldSelector)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1162,7 +1167,7 @@ func TestRequestsWithInvalidQuery(t *testing.T) {
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
for i, test := range []struct {
|
for _, test := range []struct {
|
||||||
postfix string
|
postfix string
|
||||||
method string
|
method string
|
||||||
}{
|
}{
|
||||||
|
@ -1173,34 +1178,34 @@ func TestRequestsWithInvalidQuery(t *testing.T) {
|
||||||
// {"/simple/foo?resourceVersion=<invalid>", request.MethodGet}, TODO: there is no invalid resourceVersion. Should we be more strict?
|
// {"/simple/foo?resourceVersion=<invalid>", request.MethodGet}, TODO: there is no invalid resourceVersion. Should we be more strict?
|
||||||
// {"/withoptions?labelSelector=<invalid>", request.MethodGet}, TODO: SimpleGetOptions is always valid. Add more validation that can fail.
|
// {"/withoptions?labelSelector=<invalid>", request.MethodGet}, TODO: SimpleGetOptions is always valid. Add more validation that can fail.
|
||||||
} {
|
} {
|
||||||
|
testName := fmt.Sprintf("%s:%s", test.method, test.postfix)
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
baseURL := server.URL + "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default"
|
baseURL := server.URL + "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default"
|
||||||
url := baseURL + test.postfix
|
url := baseURL + test.postfix
|
||||||
r, err := http.NewRequestWithContext(ctx, test.method, url, nil)
|
r, err := http.NewRequestWithContext(ctx, test.method, url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%d: unexpected error: %v", i, err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
resp, err := http.DefaultClient.Do(r)
|
resp, err := http.DefaultClient.Do(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%d: unexpected error: %v", i, err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
defer apitesting.Close(t, resp.Body)
|
defer apitesting.Close(t, resp.Body)
|
||||||
if resp.StatusCode != http.StatusBadRequest {
|
if resp.StatusCode != http.StatusBadRequest {
|
||||||
t.Errorf("%d: unexpected status: %d from url %s, Expected: %d, %#v", i, resp.StatusCode, url, http.StatusBadRequest, resp)
|
t.Errorf("unexpected status: %d from url %s, Expected: %d, %#v", resp.StatusCode, url, http.StatusBadRequest, resp)
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%d: unexpected error: %v", i, err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
t.Logf("%d: body: %s", i, string(body))
|
t.Logf("body: %s", string(body))
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListCompression(t *testing.T) {
|
func TestListCompression(t *testing.T) {
|
||||||
testCases := []struct {
|
cases := []struct {
|
||||||
url string
|
url string
|
||||||
namespace string
|
namespace string
|
||||||
legacy bool
|
legacy bool
|
||||||
|
@ -1220,11 +1225,12 @@ func TestListCompression(t *testing.T) {
|
||||||
acceptEncoding: "gzip",
|
acceptEncoding: "gzip",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i, testCase := range testCases {
|
for testIndex, test := range cases {
|
||||||
|
t.Run(test.acceptEncoding, func(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
||||||
simpleStorage := SimpleRESTStorage{
|
simpleStorage := SimpleRESTStorage{
|
||||||
expectedResourceNamespace: testCase.namespace,
|
expectedResourceNamespace: test.namespace,
|
||||||
list: []genericapitesting.Simple{
|
list: []genericapitesting.Simple{
|
||||||
{Other: strings.Repeat("0123456789abcdef", (128*1024/16)+1)},
|
{Other: strings.Repeat("0123456789abcdef", (128*1024/16)+1)},
|
||||||
},
|
},
|
||||||
|
@ -1238,45 +1244,42 @@ func TestListCompression(t *testing.T) {
|
||||||
|
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, request.MethodGet, server.URL+testCase.url, nil)
|
req, err := http.NewRequestWithContext(ctx, request.MethodGet, server.URL+test.url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%d: unexpected error: %v", i, err)
|
t.Fatalf("%d: unexpected error: %v", testIndex, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
// It's necessary to manually set Accept-Encoding here
|
// It's necessary to manually set Accept-Encoding here
|
||||||
// to prevent http.DefaultClient from automatically
|
// to prevent http.DefaultClient from automatically
|
||||||
// decoding responses
|
// decoding responses
|
||||||
req.Header.Set("Accept-Encoding", testCase.acceptEncoding)
|
req.Header.Set("Accept-Encoding", test.acceptEncoding)
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%d: unexpected error: %v", i, err)
|
t.Fatalf("%d: unexpected error: %v", testIndex, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
defer apitesting.Close(t, resp.Body)
|
defer apitesting.Close(t, resp.Body)
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
t.Errorf("%d: unexpected status: %d from url %s, Expected: %d, %#v", i, resp.StatusCode, testCase.url, http.StatusOK, resp)
|
t.Errorf("unexpected status: %d from url %s, Expected: %d, %#v", resp.StatusCode, test.url, http.StatusOK, resp)
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%d: unexpected error: %v", i, err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
t.Logf("%d: body: %s", i, string(body))
|
t.Logf("body: %s", string(body))
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
if !simpleStorage.namespacePresent {
|
if !simpleStorage.namespacePresent {
|
||||||
t.Errorf("%d: namespace not set", i)
|
t.Error("namespace not set")
|
||||||
} else if simpleStorage.actualNamespace != testCase.namespace {
|
} else if simpleStorage.actualNamespace != test.namespace {
|
||||||
t.Errorf("%d: %q unexpected resource namespace: %s", i, testCase.url, simpleStorage.actualNamespace)
|
t.Errorf("%q unexpected resource namespace: %s", test.url, simpleStorage.actualNamespace)
|
||||||
}
|
}
|
||||||
if simpleStorage.requestedLabelSelector == nil || simpleStorage.requestedLabelSelector.String() != testCase.label {
|
if simpleStorage.requestedLabelSelector == nil || simpleStorage.requestedLabelSelector.String() != test.label {
|
||||||
t.Errorf("%d: unexpected label selector: %v", i, simpleStorage.requestedLabelSelector)
|
t.Errorf("unexpected label selector: %v", simpleStorage.requestedLabelSelector)
|
||||||
}
|
}
|
||||||
if simpleStorage.requestedFieldSelector == nil || simpleStorage.requestedFieldSelector.String() != testCase.field {
|
if simpleStorage.requestedFieldSelector == nil || simpleStorage.requestedFieldSelector.String() != test.field {
|
||||||
t.Errorf("%d: unexpected field selector: %v", i, simpleStorage.requestedFieldSelector)
|
t.Errorf("unexpected field selector: %v", simpleStorage.requestedFieldSelector)
|
||||||
}
|
}
|
||||||
|
|
||||||
var decoder *json.Decoder
|
var decoder *json.Decoder
|
||||||
if testCase.acceptEncoding == "gzip" {
|
if test.acceptEncoding == "gzip" {
|
||||||
gzipReader, err := gzip.NewReader(resp.Body)
|
gzipReader, err := gzip.NewReader(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error creating gzip reader: %v", err)
|
t.Fatalf("unexpected error creating gzip reader: %v", err)
|
||||||
|
@ -1290,6 +1293,7 @@ func TestListCompression(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to read response body as SimpleList: %v", err)
|
t.Errorf("failed to read response body as SimpleList: %v", err)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1482,6 +1486,8 @@ func BenchmarkGet(b *testing.B) {
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
|
// Use a closure to execute defers before continuing
|
||||||
|
func() {
|
||||||
req, err := http.NewRequestWithContext(ctx, request.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, request.MethodGet, url, nil)
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
@ -1495,11 +1501,13 @@ func BenchmarkGet(b *testing.B) {
|
||||||
if _, err := io.Copy(io.Discard, resp.Body); err != nil {
|
if _, err := io.Copy(io.Discard, resp.Body); err != nil {
|
||||||
b.Fatalf("unable to read body")
|
b.Fatalf("unable to read body")
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkGetNoCompression(b *testing.B) {
|
func BenchmarkGetNoCompression(b *testing.B) {
|
||||||
|
ctx := b.Context()
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
||||||
simpleStorage := SimpleRESTStorage{
|
simpleStorage := SimpleRESTStorage{
|
||||||
item: genericapitesting.Simple{
|
item: genericapitesting.Simple{
|
||||||
|
@ -1517,11 +1525,19 @@ func BenchmarkGetNoCompression(b *testing.B) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
u := server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id"
|
url := server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id"
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
resp, err := client.Get(u)
|
// Use a closure to execute defers before continuing
|
||||||
|
func() {
|
||||||
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
defer cancel()
|
||||||
|
req, err := http.NewRequestWithContext(ctx, request.MethodGet, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("unexpected error: %v", err)
|
b.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -1532,6 +1548,7 @@ func BenchmarkGetNoCompression(b *testing.B) {
|
||||||
if _, err := io.Copy(io.Discard, resp.Body); err != nil {
|
if _, err := io.Copy(io.Discard, resp.Body); err != nil {
|
||||||
b.Fatalf("unable to read body")
|
b.Fatalf("unable to read body")
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
}
|
}
|
||||||
|
@ -1550,14 +1567,16 @@ func TestGetCompression(t *testing.T) {
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
tests := []struct {
|
cases := []struct {
|
||||||
acceptEncoding string
|
acceptEncoding string
|
||||||
}{
|
}{
|
||||||
{acceptEncoding: ""},
|
{acceptEncoding: ""},
|
||||||
{acceptEncoding: "gzip"},
|
{acceptEncoding: "gzip"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range cases {
|
||||||
|
testName := fmt.Sprintf("Accept-Encoding:%s", test.acceptEncoding)
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
req, err := http.NewRequestWithContext(ctx, request.MethodGet, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/id", nil)
|
req, err := http.NewRequestWithContext(ctx, request.MethodGet, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/id", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1598,6 +1617,7 @@ func TestGetCompression(t *testing.T) {
|
||||||
if itemOut.Name != simpleStorage.item.Name {
|
if itemOut.Name != simpleStorage.item.Name {
|
||||||
t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simpleStorage.item, string(body))
|
t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simpleStorage.item, string(body))
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1613,7 +1633,7 @@ func TestGetPretty(t *testing.T) {
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
tests := []struct {
|
cases := []struct {
|
||||||
accept string
|
accept string
|
||||||
userAgent string
|
userAgent string
|
||||||
params url.Values
|
params url.Values
|
||||||
|
@ -1631,7 +1651,15 @@ func TestGetPretty(t *testing.T) {
|
||||||
{pretty: true, accept: runtime.ContentTypeJSON, params: url.Values{"pretty": {"1"}}},
|
{pretty: true, accept: runtime.ContentTypeJSON, params: url.Values{"pretty": {"1"}}},
|
||||||
{pretty: true, accept: runtime.ContentTypeJSON, params: url.Values{"pretty": {"true"}}},
|
{pretty: true, accept: runtime.ContentTypeJSON, params: url.Values{"pretty": {"true"}}},
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for _, test := range cases {
|
||||||
|
testName := fmt.Sprintf("Accept:%s", test.accept)
|
||||||
|
if test.userAgent != "" {
|
||||||
|
testName += fmt.Sprintf(" User-Agent:%s", test.userAgent)
|
||||||
|
}
|
||||||
|
if len(test.params) > 0 {
|
||||||
|
testName += fmt.Sprintf(" Params:%s", test.params.Encode())
|
||||||
|
}
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
u, err := url.Parse(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id")
|
u, err := url.Parse(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -1673,8 +1701,9 @@ func TestGetPretty(t *testing.T) {
|
||||||
expect = string(out) + "\n"
|
expect = string(out) + "\n"
|
||||||
}
|
}
|
||||||
if expect != body {
|
if expect != body {
|
||||||
t.Errorf("%d: body did not match expected:\n%s\n%s", i, body, expect)
|
t.Errorf("body did not match expected:\n%s\n%s", body, expect)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1714,7 +1743,7 @@ func TestGetTable(t *testing.T) {
|
||||||
|
|
||||||
metaDoc := metav1.ObjectMeta{}.SwaggerDoc()
|
metaDoc := metav1.ObjectMeta{}.SwaggerDoc()
|
||||||
|
|
||||||
tests := []struct {
|
cases := []struct {
|
||||||
accept string
|
accept string
|
||||||
params url.Values
|
params url.Values
|
||||||
pretty bool
|
pretty bool
|
||||||
|
@ -1815,8 +1844,9 @@ func TestGetTable(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for testIndex, test := range cases {
|
||||||
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
testName := fmt.Sprintf("%d", testIndex)
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
||||||
simpleStorage := SimpleRESTStorage{
|
simpleStorage := SimpleRESTStorage{
|
||||||
item: obj,
|
item: obj,
|
||||||
|
@ -1845,20 +1875,20 @@ func TestGetTable(t *testing.T) {
|
||||||
}
|
}
|
||||||
if test.statusCode != 0 {
|
if test.statusCode != 0 {
|
||||||
if resp.StatusCode != test.statusCode {
|
if resp.StatusCode != test.statusCode {
|
||||||
t.Errorf("%d: unexpected response: %#v", i, resp)
|
t.Errorf("unexpected response: %#v", resp)
|
||||||
}
|
}
|
||||||
obj, _, err := extractBodyObject(resp, unstructured.UnstructuredJSONScheme)
|
obj, _, err := extractBodyObject(resp, unstructured.UnstructuredJSONScheme)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("%d: unexpected body read error: %v", i, err)
|
t.Fatalf("unexpected body read error: %v", err)
|
||||||
}
|
}
|
||||||
gvk := schema.GroupVersionKind{Version: "v1", Kind: "Status"}
|
gvk := schema.GroupVersionKind{Version: "v1", Kind: "Status"}
|
||||||
if obj.GetObjectKind().GroupVersionKind() != gvk {
|
if obj.GetObjectKind().GroupVersionKind() != gvk {
|
||||||
t.Fatalf("%d: unexpected error body: %#v", i, obj)
|
t.Fatalf("unexpected error body: %#v", obj)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
t.Errorf("%d: unexpected response: %#v", i, resp)
|
t.Errorf("unexpected response: %#v", resp)
|
||||||
}
|
}
|
||||||
var itemOut metav1.Table
|
var itemOut metav1.Table
|
||||||
body, err := extractBody(resp, &itemOut)
|
body, err := extractBody(resp, &itemOut)
|
||||||
|
@ -1867,7 +1897,7 @@ func TestGetTable(t *testing.T) {
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(test.expected, &itemOut) {
|
if !reflect.DeepEqual(test.expected, &itemOut) {
|
||||||
t.Log(body)
|
t.Log(body)
|
||||||
t.Errorf("%d: did not match: %s", i, cmp.Diff(test.expected, &itemOut))
|
t.Errorf("did not match: %s", cmp.Diff(test.expected, &itemOut))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1903,7 +1933,7 @@ func TestWatchTable(t *testing.T) {
|
||||||
|
|
||||||
s := metainternalversionscheme.Codecs.SupportedMediaTypes()[0].Serializer
|
s := metainternalversionscheme.Codecs.SupportedMediaTypes()[0].Serializer
|
||||||
|
|
||||||
tests := []struct {
|
cases := []struct {
|
||||||
accept string
|
accept string
|
||||||
params url.Values
|
params url.Values
|
||||||
send func(w *watch.FakeWatcher)
|
send func(w *watch.FakeWatcher)
|
||||||
|
@ -2016,8 +2046,9 @@ func TestWatchTable(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for testIndex, test := range cases {
|
||||||
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
testName := fmt.Sprintf("%d", testIndex)
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
||||||
simpleStorage := SimpleRESTStorage{
|
simpleStorage := SimpleRESTStorage{
|
||||||
item: obj,
|
item: obj,
|
||||||
|
@ -2056,20 +2087,20 @@ func TestWatchTable(t *testing.T) {
|
||||||
defer apitesting.Close(t, resp.Body)
|
defer apitesting.Close(t, resp.Body)
|
||||||
if test.statusCode != 0 {
|
if test.statusCode != 0 {
|
||||||
if resp.StatusCode != test.statusCode {
|
if resp.StatusCode != test.statusCode {
|
||||||
t.Fatalf("%d: unexpected response: %#v", i, resp)
|
t.Fatalf("unexpected response: %#v", resp)
|
||||||
}
|
}
|
||||||
obj, _, err := extractBodyObject(resp, unstructured.UnstructuredJSONScheme)
|
obj, _, err := extractBodyObject(resp, unstructured.UnstructuredJSONScheme)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("%d: unexpected body read error: %v", i, err)
|
t.Fatalf("unexpected body read error: %v", err)
|
||||||
}
|
}
|
||||||
gvk := schema.GroupVersionKind{Version: "v1", Kind: "Status"}
|
gvk := schema.GroupVersionKind{Version: "v1", Kind: "Status"}
|
||||||
if obj.GetObjectKind().GroupVersionKind() != gvk {
|
if obj.GetObjectKind().GroupVersionKind() != gvk {
|
||||||
t.Fatalf("%d: unexpected error body: %#v", i, obj)
|
t.Fatalf("unexpected error body: %#v", obj)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
t.Fatalf("%d: unexpected response: %#v", i, resp)
|
t.Fatalf("unexpected response: %#v", resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -2137,7 +2168,7 @@ func TestGetPartialObjectMetadata(t *testing.T) {
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
tests := []struct {
|
cases := []struct {
|
||||||
accept string
|
accept string
|
||||||
params url.Values
|
params url.Values
|
||||||
pretty bool
|
pretty bool
|
||||||
|
@ -2231,7 +2262,9 @@ func TestGetPartialObjectMetadata(t *testing.T) {
|
||||||
expectKind: schema.GroupVersionKind{Kind: "PartialObjectMetadataList", Group: "meta.k8s.io", Version: "v1beta1"},
|
expectKind: schema.GroupVersionKind{Kind: "PartialObjectMetadataList", Group: "meta.k8s.io", Version: "v1beta1"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for testIndex, test := range cases {
|
||||||
|
testName := fmt.Sprintf("%d", testIndex)
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
suffix := "/namespaces/default/simple/id"
|
suffix := "/namespaces/default/simple/id"
|
||||||
if test.list {
|
if test.list {
|
||||||
suffix = "/namespaces/default/simple"
|
suffix = "/namespaces/default/simple"
|
||||||
|
@ -2251,22 +2284,20 @@ func TestGetPartialObjectMetadata(t *testing.T) {
|
||||||
defer apitesting.Close(t, resp.Body)
|
defer apitesting.Close(t, resp.Body)
|
||||||
if test.statusCode != 0 {
|
if test.statusCode != 0 {
|
||||||
if resp.StatusCode != test.statusCode {
|
if resp.StatusCode != test.statusCode {
|
||||||
t.Errorf("%d: unexpected response: %#v", i, resp)
|
t.Errorf("unexpected response: %#v", resp)
|
||||||
}
|
}
|
||||||
obj, _, err := extractBodyObject(resp, unstructured.UnstructuredJSONScheme)
|
obj, _, err := extractBodyObject(resp, unstructured.UnstructuredJSONScheme)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%d: unexpected body read error: %v", i, err)
|
t.Fatalf("unexpected body read error: %v", err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
gvk := schema.GroupVersionKind{Version: "v1", Kind: "Status"}
|
gvk := schema.GroupVersionKind{Version: "v1", Kind: "Status"}
|
||||||
if obj.GetObjectKind().GroupVersionKind() != gvk {
|
if obj.GetObjectKind().GroupVersionKind() != gvk {
|
||||||
t.Errorf("%d: unexpected error body: %#v", i, obj)
|
t.Errorf("unexpected error body: %#v", obj)
|
||||||
}
|
}
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
t.Errorf("%d: invalid status: %#v\n%s", i, resp, bodyOrDie(resp))
|
t.Fatalf("invalid status: %#v\n%s", resp, bodyOrDie(resp))
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
body := ""
|
body := ""
|
||||||
if test.expected != nil {
|
if test.expected != nil {
|
||||||
|
@ -2275,7 +2306,7 @@ func TestGetPartialObjectMetadata(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(test.expected, itemOut) {
|
if !reflect.DeepEqual(test.expected, itemOut) {
|
||||||
t.Errorf("%d: did not match: %s", i, cmp.Diff(test.expected, itemOut))
|
t.Errorf("did not match: %s", cmp.Diff(test.expected, itemOut))
|
||||||
}
|
}
|
||||||
body = d
|
body = d
|
||||||
} else {
|
} else {
|
||||||
|
@ -2290,8 +2321,9 @@ func TestGetPartialObjectMetadata(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if obj.GetObjectKind().GroupVersionKind() != test.expectKind {
|
if obj.GetObjectKind().GroupVersionKind() != test.expectKind {
|
||||||
t.Errorf("%d: unexpected kind: %#v", i, obj.GetObjectKind().GroupVersionKind())
|
t.Errorf("unexpected kind: %#v", obj.GetObjectKind().GroupVersionKind())
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2373,7 +2405,7 @@ func TestGetWithOptionsRouteParams(t *testing.T) {
|
||||||
|
|
||||||
func TestGetWithOptions(t *testing.T) {
|
func TestGetWithOptions(t *testing.T) {
|
||||||
|
|
||||||
tests := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
rootScoped bool
|
rootScoped bool
|
||||||
requestURL string
|
requestURL string
|
||||||
|
@ -2424,7 +2456,8 @@ func TestGetWithOptions(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range cases {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
simpleStorage := GetWithOptionsRESTStorage{
|
simpleStorage := GetWithOptionsRESTStorage{
|
||||||
SimpleRESTStorage: &SimpleRESTStorage{
|
SimpleRESTStorage: &SimpleRESTStorage{
|
||||||
|
@ -2461,13 +2494,11 @@ func TestGetWithOptions(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%s: %v", test.name, err)
|
t.Fatalf("%s: %v", test.name, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
defer apitesting.Close(t, resp.Body)
|
defer apitesting.Close(t, resp.Body)
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
t.Errorf("%s: unexpected response: %#v", test.name, resp)
|
t.Fatalf("%s: unexpected response: %#v", test.name, resp)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var itemOut runtime.Object
|
var itemOut runtime.Object
|
||||||
|
@ -2478,16 +2509,14 @@ func TestGetWithOptions(t *testing.T) {
|
||||||
}
|
}
|
||||||
body, err := extractBody(resp, itemOut)
|
body, err := extractBody(resp, itemOut)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%s: %v", test.name, err)
|
t.Fatalf("%s: %v", test.name, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
if metadata, err := meta.Accessor(itemOut); err == nil {
|
if metadata, err := meta.Accessor(itemOut); err == nil {
|
||||||
if metadata.GetName() != simpleStorage.item.Name {
|
if metadata.GetName() != simpleStorage.item.Name {
|
||||||
t.Errorf("%s: Unexpected data: %#v, expected %#v (%s)", test.name, itemOut, simpleStorage.item, string(body))
|
t.Fatalf("%s: Unexpected data: %#v, expected %#v (%s)", test.name, itemOut, simpleStorage.item, string(body))
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
t.Errorf("%s: Couldn't get name from %#v: %v", test.name, itemOut, err)
|
t.Errorf("Couldn't get name from %#v: %v", itemOut, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var opts *genericapitesting.SimpleGetOptions
|
var opts *genericapitesting.SimpleGetOptions
|
||||||
|
@ -2499,17 +2528,15 @@ func TestGetWithOptions(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Errorf("%s: Unexpected options object received: %#v", test.name, simpleStorage.optionsReceived)
|
t.Fatalf("Unexpected options object received: %#v", simpleStorage.optionsReceived)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
if opts.Param1 != "test1" || opts.Param2 != "test2" {
|
if opts.Param1 != "test1" || opts.Param2 != "test2" {
|
||||||
t.Errorf("%s: Did not receive expected options: %#v", test.name, opts)
|
t.Fatalf("Did not receive expected options: %#v", opts)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
if opts.Path != test.expectedPath {
|
if opts.Path != test.expectedPath {
|
||||||
t.Errorf("%s: Unexpected path value. Expected: %s. Actual: %s.", test.name, test.expectedPath, opts.Path)
|
t.Fatalf("Unexpected path value. Expected: %s. Actual: %s.", test.expectedPath, opts.Path)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2988,9 +3015,9 @@ func TestDeleteWithOptionsQueryAndBody(t *testing.T) {
|
||||||
func TestDeleteInvokesAdmissionControl(t *testing.T) {
|
func TestDeleteInvokesAdmissionControl(t *testing.T) {
|
||||||
// TODO: remove mutating deny when we removed it from the endpoint implementation and ported all plugins
|
// TODO: remove mutating deny when we removed it from the endpoint implementation and ported all plugins
|
||||||
for _, admit := range []admission.Interface{alwaysMutatingDeny{}, alwaysValidatingDeny{}} {
|
for _, admit := range []admission.Interface{alwaysMutatingDeny{}, alwaysValidatingDeny{}} {
|
||||||
t.Logf("Testing %T", admit)
|
testName := fmt.Sprintf("%T", admit)
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
|
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
||||||
simpleStorage := SimpleRESTStorage{}
|
simpleStorage := SimpleRESTStorage{}
|
||||||
ID := "id"
|
ID := "id"
|
||||||
|
@ -3012,6 +3039,7 @@ func TestDeleteInvokesAdmissionControl(t *testing.T) {
|
||||||
if response.StatusCode != http.StatusForbidden {
|
if response.StatusCode != http.StatusForbidden {
|
||||||
t.Errorf("Unexpected response %#v", response)
|
t.Errorf("Unexpected response %#v", response)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3085,7 +3113,8 @@ func TestUpdate(t *testing.T) {
|
||||||
|
|
||||||
func TestUpdateInvokesAdmissionControl(t *testing.T) {
|
func TestUpdateInvokesAdmissionControl(t *testing.T) {
|
||||||
for _, admit := range []admission.Interface{alwaysMutatingDeny{}, alwaysValidatingDeny{}} {
|
for _, admit := range []admission.Interface{alwaysMutatingDeny{}, alwaysValidatingDeny{}} {
|
||||||
t.Logf("Testing %T", admit)
|
testName := fmt.Sprintf("%T", admit)
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
|
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
||||||
|
@ -3125,6 +3154,7 @@ func TestUpdateInvokesAdmissionControl(t *testing.T) {
|
||||||
if response.StatusCode != http.StatusForbidden {
|
if response.StatusCode != http.StatusForbidden {
|
||||||
t.Errorf("Unexpected response %#v", response)
|
t.Errorf("Unexpected response %#v", response)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3855,9 +3885,9 @@ func TestCreateInNamespace(t *testing.T) {
|
||||||
|
|
||||||
func TestCreateInvokeAdmissionControl(t *testing.T) {
|
func TestCreateInvokeAdmissionControl(t *testing.T) {
|
||||||
for _, admit := range []admission.Interface{alwaysMutatingDeny{}, alwaysValidatingDeny{}} {
|
for _, admit := range []admission.Interface{alwaysMutatingDeny{}, alwaysValidatingDeny{}} {
|
||||||
t.Logf("Testing %T", admit)
|
testName := fmt.Sprintf("%T", admit)
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
|
|
||||||
storage := SimpleRESTStorage{
|
storage := SimpleRESTStorage{
|
||||||
injectedFunction: func(obj runtime.Object) (runtime.Object, error) {
|
injectedFunction: func(obj runtime.Object) (runtime.Object, error) {
|
||||||
time.Sleep(5 * time.Millisecond)
|
time.Sleep(5 * time.Millisecond)
|
||||||
|
@ -3890,6 +3920,7 @@ func TestCreateInvokeAdmissionControl(t *testing.T) {
|
||||||
if response.StatusCode != http.StatusForbidden {
|
if response.StatusCode != http.StatusForbidden {
|
||||||
t.Errorf("Unexpected status: %d, Expected: %d, %#v", response.StatusCode, http.StatusForbidden, response)
|
t.Errorf("Unexpected status: %d, Expected: %d, %#v", response.StatusCode, http.StatusForbidden, response)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4201,7 +4232,7 @@ unknown: baz`)
|
||||||
|
|
||||||
invalidSMP = []byte(`{"unknown": "foo", "other":"foo", "other": "bar"}`)
|
invalidSMP = []byte(`{"unknown": "foo", "other":"foo", "other": "bar"}`)
|
||||||
|
|
||||||
fieldValidationTests = []struct {
|
cases = []struct {
|
||||||
name string
|
name string
|
||||||
path string
|
path string
|
||||||
verb string
|
verb string
|
||||||
|
@ -4268,7 +4299,7 @@ unknown: baz`)
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
for _, test := range fieldValidationTests {
|
for _, test := range cases {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
baseURL := server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version
|
baseURL := server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version
|
||||||
response := runRequest(t, baseURL+test.path+test.queryParams, test.verb, test.data, test.contentType)
|
response := runRequest(t, baseURL+test.path+test.queryParams, test.verb, test.data, test.contentType)
|
||||||
|
@ -4548,6 +4579,8 @@ func BenchmarkUpdateProtobuf(b *testing.B) {
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
|
// Use a closure to execute defers before continuing
|
||||||
|
func() {
|
||||||
request, err := http.NewRequestWithContext(ctx, request.MethodPut, dest.String(), bytes.NewReader(data))
|
request, err := http.NewRequestWithContext(ctx, request.MethodPut, dest.String(), bytes.NewReader(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("unexpected error: %v", err)
|
b.Fatalf("unexpected error: %v", err)
|
||||||
|
@ -4564,7 +4597,7 @@ func BenchmarkUpdateProtobuf(b *testing.B) {
|
||||||
b.Fatalf("Unexpected response %#v\n%s", response, body)
|
b.Fatalf("Unexpected response %#v\n%s", response, body)
|
||||||
}
|
}
|
||||||
_, _ = io.ReadAll(response.Body)
|
_, _ = io.ReadAll(response.Body)
|
||||||
response.Body.Close()
|
}()
|
||||||
}
|
}
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package endpoints
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -268,7 +269,6 @@ func TestWatchClientClose(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWatchRead(t *testing.T) {
|
func TestWatchRead(t *testing.T) {
|
||||||
ctx := t.Context()
|
|
||||||
simpleStorage := &SimpleRESTStorage{}
|
simpleStorage := &SimpleRESTStorage{}
|
||||||
_ = rest.Watcher(simpleStorage) // Give compile error if this doesn't work.
|
_ = rest.Watcher(simpleStorage) // Give compile error if this doesn't work.
|
||||||
handler := handle(map[string]rest.Storage{"simples": simpleStorage})
|
handler := handle(map[string]rest.Storage{"simples": simpleStorage})
|
||||||
|
@ -279,7 +279,7 @@ func TestWatchRead(t *testing.T) {
|
||||||
dest.Path = "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simples"
|
dest.Path = "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simples"
|
||||||
dest.RawQuery = "watch=1"
|
dest.RawQuery = "watch=1"
|
||||||
|
|
||||||
connectHTTP := func(accept string) (io.ReadCloser, string) {
|
connectHTTP := func(ctx context.Context, accept string) (io.ReadCloser, string) {
|
||||||
client := http.Client{}
|
client := http.Client{}
|
||||||
request, err := http.NewRequestWithContext(ctx, request.MethodGet, dest.String(), nil)
|
request, err := http.NewRequestWithContext(ctx, request.MethodGet, dest.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -299,7 +299,7 @@ func TestWatchRead(t *testing.T) {
|
||||||
return response.Body, response.Header.Get("Content-Type")
|
return response.Body, response.Header.Get("Content-Type")
|
||||||
}
|
}
|
||||||
|
|
||||||
connectWebSocket := func(accept string) (io.ReadCloser, string) {
|
connectWebSocket := func(ctx context.Context, accept string) (io.ReadCloser, string) {
|
||||||
dest := *dest
|
dest := *dest
|
||||||
dest.Scheme = "ws" // Required by websocket, though the server never sees it.
|
dest.Scheme = "ws" // Required by websocket, though the server never sees it.
|
||||||
config, err := websocket.NewConfig(dest.String(), "http://localhost")
|
config, err := websocket.NewConfig(dest.String(), "http://localhost")
|
||||||
|
@ -307,14 +307,14 @@ func TestWatchRead(t *testing.T) {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
config.Header.Add("Accept", accept)
|
config.Header.Add("Accept", accept)
|
||||||
ws, err := websocket.DialConfig(config)
|
ws, err := config.DialContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
return ws, "__default__"
|
return ws, "__default__"
|
||||||
}
|
}
|
||||||
|
|
||||||
testCases := []struct {
|
cases := []struct {
|
||||||
Accept string
|
Accept string
|
||||||
ExpectedContentType string
|
ExpectedContentType string
|
||||||
MediaType string
|
MediaType string
|
||||||
|
@ -351,22 +351,24 @@ func TestWatchRead(t *testing.T) {
|
||||||
protocols := []struct {
|
protocols := []struct {
|
||||||
name string
|
name string
|
||||||
selfFraming bool
|
selfFraming bool
|
||||||
fn func(string) (io.ReadCloser, string)
|
fn func(context.Context, string) (io.ReadCloser, string)
|
||||||
}{
|
}{
|
||||||
{name: "http", fn: connectHTTP},
|
{name: "http", fn: connectHTTP},
|
||||||
{name: "websocket", selfFraming: true, fn: connectWebSocket},
|
{name: "websocket", selfFraming: true, fn: connectWebSocket},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, protocol := range protocols {
|
for _, protocol := range protocols {
|
||||||
for _, test := range testCases {
|
for textIndex, test := range cases {
|
||||||
func() {
|
testName := fmt.Sprintf("%s-%d", protocol.name, textIndex)
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
|
ctx := t.Context()
|
||||||
info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), test.MediaType)
|
info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), test.MediaType)
|
||||||
if !ok || info.StreamSerializer == nil {
|
if !ok || info.StreamSerializer == nil {
|
||||||
t.Fatal(info)
|
t.Fatal(info)
|
||||||
}
|
}
|
||||||
streamSerializer := info.StreamSerializer
|
streamSerializer := info.StreamSerializer
|
||||||
|
|
||||||
r, contentType := protocol.fn(test.Accept)
|
r, contentType := protocol.fn(ctx, test.Accept)
|
||||||
closeBody := apitesting.Close
|
closeBody := apitesting.Close
|
||||||
defer func() {
|
defer func() {
|
||||||
closeBody(t, r)
|
closeBody(t, r)
|
||||||
|
@ -424,7 +426,7 @@ func TestWatchRead(t *testing.T) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Unexpected non-error")
|
t.Errorf("Unexpected non-error")
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -472,7 +474,7 @@ func TestWatchParamParsing(t *testing.T) {
|
||||||
rootPath := "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/simples"
|
rootPath := "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/simples"
|
||||||
namespacedPath := "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/namespaces/other/simpleroots"
|
namespacedPath := "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/namespaces/other/simpleroots"
|
||||||
|
|
||||||
table := []struct {
|
cases := []struct {
|
||||||
path string
|
path string
|
||||||
rawQuery string
|
rawQuery string
|
||||||
resourceVersion string
|
resourceVersion string
|
||||||
|
@ -540,35 +542,37 @@ func TestWatchParamParsing(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range table {
|
for testIndex, test := range cases {
|
||||||
|
testName := fmt.Sprintf("%d", testIndex)
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
simpleStorage.requestedLabelSelector = labels.Everything()
|
simpleStorage.requestedLabelSelector = labels.Everything()
|
||||||
simpleStorage.requestedFieldSelector = fields.Everything()
|
simpleStorage.requestedFieldSelector = fields.Everything()
|
||||||
simpleStorage.requestedResourceVersion = "5" // Prove this is set in all cases
|
simpleStorage.requestedResourceVersion = "5" // Prove this is set in all cases
|
||||||
simpleStorage.requestedResourceNamespace = ""
|
simpleStorage.requestedResourceNamespace = ""
|
||||||
dest.Path = item.path
|
dest.Path = test.path
|
||||||
dest.RawQuery = item.rawQuery
|
dest.RawQuery = test.rawQuery
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, request.MethodGet, dest.String(), nil)
|
req, err := http.NewRequestWithContext(ctx, request.MethodGet, dest.String(), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%v: unexpected error: %v", item.rawQuery, err)
|
t.Fatalf("%v: unexpected error: %v", test.rawQuery, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
defer apitesting.Close(t, resp.Body)
|
defer apitesting.Close(t, resp.Body)
|
||||||
if e, a := item.namespace, simpleStorage.requestedResourceNamespace; e != a {
|
if e, a := test.namespace, simpleStorage.requestedResourceNamespace; e != a {
|
||||||
t.Errorf("%v: expected %v, got %v", item.rawQuery, e, a)
|
t.Errorf("%v: expected %v, got %v", test.rawQuery, e, a)
|
||||||
}
|
}
|
||||||
if e, a := item.resourceVersion, simpleStorage.requestedResourceVersion; e != a {
|
if e, a := test.resourceVersion, simpleStorage.requestedResourceVersion; e != a {
|
||||||
t.Errorf("%v: expected %v, got %v", item.rawQuery, e, a)
|
t.Errorf("%v: expected %v, got %v", test.rawQuery, e, a)
|
||||||
}
|
}
|
||||||
if e, a := item.labelSelector, simpleStorage.requestedLabelSelector.String(); e != a {
|
if e, a := test.labelSelector, simpleStorage.requestedLabelSelector.String(); e != a {
|
||||||
t.Errorf("%v: expected %v, got %v", item.rawQuery, e, a)
|
t.Errorf("%v: expected %v, got %v", test.rawQuery, e, a)
|
||||||
}
|
}
|
||||||
if e, a := item.fieldSelector, simpleStorage.requestedFieldSelector.String(); e != a {
|
if e, a := test.fieldSelector, simpleStorage.requestedFieldSelector.String(); e != a {
|
||||||
t.Errorf("%v: expected %v, got %v", item.rawQuery, e, a)
|
t.Errorf("%v: expected %v, got %v", test.rawQuery, e, a)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,7 +588,7 @@ func TestWatchProtocolSelection(t *testing.T) {
|
||||||
dest.Path = "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/simples"
|
dest.Path = "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/simples"
|
||||||
dest.RawQuery = ""
|
dest.RawQuery = ""
|
||||||
|
|
||||||
table := []struct {
|
cases := []struct {
|
||||||
isWebsocket bool
|
isWebsocket bool
|
||||||
connHeader string
|
connHeader string
|
||||||
}{
|
}{
|
||||||
|
@ -594,13 +598,15 @@ func TestWatchProtocolSelection(t *testing.T) {
|
||||||
{false, "keep-alive"},
|
{false, "keep-alive"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range table {
|
for _, test := range cases {
|
||||||
|
testName := fmt.Sprintf("websocket:%v header:%s", test.isWebsocket, test.connHeader)
|
||||||
|
t.Run(testName, func(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
request, err := http.NewRequestWithContext(ctx, request.MethodGet, dest.String(), nil)
|
request, err := http.NewRequestWithContext(ctx, request.MethodGet, dest.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
request.Header.Set("Connection", item.connHeader)
|
request.Header.Set("Connection", test.connHeader)
|
||||||
request.Header.Set("Upgrade", "websocket")
|
request.Header.Set("Upgrade", "websocket")
|
||||||
|
|
||||||
response, err := client.Do(request)
|
response, err := client.Do(request)
|
||||||
|
@ -611,13 +617,14 @@ func TestWatchProtocolSelection(t *testing.T) {
|
||||||
// The requests recognized as websocket requests based on connection
|
// The requests recognized as websocket requests based on connection
|
||||||
// and upgrade headers will not also have the necessary Sec-Websocket-*
|
// and upgrade headers will not also have the necessary Sec-Websocket-*
|
||||||
// headers so it is expected to throw a 400
|
// headers so it is expected to throw a 400
|
||||||
if item.isWebsocket && response.StatusCode != http.StatusBadRequest {
|
if test.isWebsocket && response.StatusCode != http.StatusBadRequest {
|
||||||
t.Errorf("Unexpected response %#v", response)
|
t.Errorf("Unexpected response %#v", response)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !item.isWebsocket && response.StatusCode != http.StatusOK {
|
if !test.isWebsocket && response.StatusCode != http.StatusOK {
|
||||||
t.Errorf("Unexpected response %#v", response)
|
t.Errorf("Unexpected response %#v", response)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue