diff --git a/docs/devel/coding-conventions.md b/docs/devel/coding-conventions.md index c3f7d628f17..dc2825b0cc9 100644 --- a/docs/devel/coding-conventions.md +++ b/docs/devel/coding-conventions.md @@ -109,7 +109,7 @@ following Go conventions - `stateLock`, `mapLock` etc. tests - Table-driven tests are preferred for testing multiple scenarios/inputs; for -example, see [TestNamespaceAuthorization](../../test/integration/auth_test.go) +example, see [TestNamespaceAuthorization](../../test/integration/auth/auth_test.go) - Significant features should come with integration (test/integration) and/or [end-to-end (test/e2e) tests](e2e-tests.md) diff --git a/docs/devel/testing.md b/docs/devel/testing.md index 4ae988595c5..4e41a1da31d 100644 --- a/docs/devel/testing.md +++ b/docs/devel/testing.md @@ -73,7 +73,7 @@ passing, so it is often a good idea to make sure the e2e tests work as well. * All packages and any significant files require unit tests. * The preferred method of testing multiple scenarios or input is [table driven testing](https://github.com/golang/go/wiki/TableDrivenTests) - - Example: [TestNamespaceAuthorization](../../test/integration/auth_test.go) + - Example: [TestNamespaceAuthorization](../../test/integration/auth/auth_test.go) * Unit tests must pass on OS X and Windows platforms. - Tests using linux-specific features must be skipped or compiled out. - Skipped is better, compiled out is required when it won't compile. @@ -189,9 +189,9 @@ See `go help test` and `go help testflag` for additional info. - This includes kubectl commands * The preferred method of testing multiple scenarios or inputs is [table driven testing](https://github.com/golang/go/wiki/TableDrivenTests) - - Example: [TestNamespaceAuthorization](../../test/integration/auth_test.go) + - Example: [TestNamespaceAuthorization](../../test/integration/auth/auth_test.go) * Each test should create its own master, httpserver and config. - - Example: [TestPodUpdateActiveDeadlineSeconds](../../test/integration/pods_test.go) + - Example: [TestPodUpdateActiveDeadlineSeconds](../../test/integration/pods/pods_test.go) * See [coding conventions](coding-conventions.md). ### Install etcd dependency diff --git a/hack/test-integration.sh b/hack/test-integration.sh index 19ad160382d..c35241fd7d6 100755 --- a/hack/test-integration.sh +++ b/hack/test-integration.sh @@ -41,6 +41,15 @@ KUBE_INTEGRATION_TEST_MAX_CONCURRENCY=${KUBE_INTEGRATION_TEST_MAX_CONCURRENCY:-" LOG_LEVEL=${LOG_LEVEL:-2} KUBE_TEST_ARGS=${KUBE_TEST_ARGS:-} +kube::test::find_integration_test_dirs() { + ( + cd ${KUBE_ROOT} + find test/integration -name '*_test.go' -print0 \ + | xargs -0n1 dirname \ + | sort -u + ) +} + cleanup() { kube::log::status "Cleaning up etcd" kube::etcd::cleanup @@ -58,7 +67,7 @@ runTests() { KUBE_RACE="" \ KUBE_TIMEOUT="${KUBE_TIMEOUT}" \ KUBE_TEST_API_VERSIONS="$1" \ - "${KUBE_ROOT}/hack/test-go.sh" test/integration + "${KUBE_ROOT}/hack/test-go.sh" $(kube::test::find_integration_test_dirs) # Run the watch cache tests # KUBE_TEST_ARGS doesn't mean anything to the watch cache test. diff --git a/test/integration/auth_test.go b/test/integration/auth/auth_test.go similarity index 85% rename from test/integration/auth_test.go rename to test/integration/auth/auth_test.go index c93731d3406..d75493aa058 100644 --- a/test/integration/auth_test.go +++ b/test/integration/auth/auth_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package auth // This file tests authentication and (soon) authorization of HTTP requests to a master object. // It does not use the client in pkg/client/... because authentication and authorization needs @@ -53,6 +53,7 @@ import ( "k8s.io/kubernetes/plugin/pkg/admission/admit" "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/tokentest" "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/webhook" + "k8s.io/kubernetes/test/integration" "k8s.io/kubernetes/test/integration/framework" ) @@ -267,19 +268,6 @@ var deleteNow string = ` } ` -// Requests to try. Each one should be forbidden or not forbidden -// depending on the authentication and authorization setup of the master. -var code200 = map[int]bool{200: true} -var code201 = map[int]bool{201: true} -var code400 = map[int]bool{400: true} -var code403 = map[int]bool{403: true} -var code404 = map[int]bool{404: true} -var code405 = map[int]bool{405: true} -var code409 = map[int]bool{409: true} -var code422 = map[int]bool{422: true} -var code500 = map[int]bool{500: true} -var code503 = map[int]bool{503: true} - // To ensure that a POST completes before a dependent GET, set a timeout. func addTimeoutFlag(URLString string) string { u, _ := url.Parse(URLString) @@ -302,107 +290,107 @@ func getTestRequests(namespace string) []struct { statusCodes map[int]bool // Set of expected resp.StatusCode if all goes well. }{ // Normal methods on pods - {"GET", path("pods", "", ""), "", code200}, - {"GET", path("pods", namespace, ""), "", code200}, - {"POST", timeoutPath("pods", namespace, ""), aPod, code201}, - {"PUT", timeoutPath("pods", namespace, "a"), aPod, code200}, - {"GET", path("pods", namespace, "a"), "", code200}, + {"GET", path("pods", "", ""), "", integration.Code200}, + {"GET", path("pods", namespace, ""), "", integration.Code200}, + {"POST", timeoutPath("pods", namespace, ""), aPod, integration.Code201}, + {"PUT", timeoutPath("pods", namespace, "a"), aPod, integration.Code200}, + {"GET", path("pods", namespace, "a"), "", integration.Code200}, // GET and POST for /exec should return Bad Request (400) since the pod has not been assigned a node yet. - {"GET", path("pods", namespace, "a") + "/exec", "", code400}, - {"POST", path("pods", namespace, "a") + "/exec", "", code400}, + {"GET", path("pods", namespace, "a") + "/exec", "", integration.Code400}, + {"POST", path("pods", namespace, "a") + "/exec", "", integration.Code400}, // PUT for /exec should return Method Not Allowed (405). - {"PUT", path("pods", namespace, "a") + "/exec", "", code405}, + {"PUT", path("pods", namespace, "a") + "/exec", "", integration.Code405}, // GET and POST for /portforward should return Bad Request (400) since the pod has not been assigned a node yet. - {"GET", path("pods", namespace, "a") + "/portforward", "", code400}, - {"POST", path("pods", namespace, "a") + "/portforward", "", code400}, + {"GET", path("pods", namespace, "a") + "/portforward", "", integration.Code400}, + {"POST", path("pods", namespace, "a") + "/portforward", "", integration.Code400}, // PUT for /portforward should return Method Not Allowed (405). - {"PUT", path("pods", namespace, "a") + "/portforward", "", code405}, - {"PATCH", path("pods", namespace, "a"), "{%v}", code200}, - {"DELETE", timeoutPath("pods", namespace, "a"), deleteNow, code200}, + {"PUT", path("pods", namespace, "a") + "/portforward", "", integration.Code405}, + {"PATCH", path("pods", namespace, "a"), "{%v}", integration.Code200}, + {"DELETE", timeoutPath("pods", namespace, "a"), deleteNow, integration.Code200}, // Non-standard methods (not expected to work, // but expected to pass/fail authorization prior to // failing validation. - {"OPTIONS", path("pods", namespace, ""), "", code405}, - {"OPTIONS", path("pods", namespace, "a"), "", code405}, - {"HEAD", path("pods", namespace, ""), "", code405}, - {"HEAD", path("pods", namespace, "a"), "", code405}, - {"TRACE", path("pods", namespace, ""), "", code405}, - {"TRACE", path("pods", namespace, "a"), "", code405}, - {"NOSUCHVERB", path("pods", namespace, ""), "", code405}, + {"OPTIONS", path("pods", namespace, ""), "", integration.Code405}, + {"OPTIONS", path("pods", namespace, "a"), "", integration.Code405}, + {"HEAD", path("pods", namespace, ""), "", integration.Code405}, + {"HEAD", path("pods", namespace, "a"), "", integration.Code405}, + {"TRACE", path("pods", namespace, ""), "", integration.Code405}, + {"TRACE", path("pods", namespace, "a"), "", integration.Code405}, + {"NOSUCHVERB", path("pods", namespace, ""), "", integration.Code405}, // Normal methods on services - {"GET", path("services", "", ""), "", code200}, - {"GET", path("services", namespace, ""), "", code200}, - {"POST", timeoutPath("services", namespace, ""), aService, code201}, + {"GET", path("services", "", ""), "", integration.Code200}, + {"GET", path("services", namespace, ""), "", integration.Code200}, + {"POST", timeoutPath("services", namespace, ""), aService, integration.Code201}, // Create an endpoint for the service (this is done automatically by endpoint controller // whenever a service is created, but this test does not run that controller) - {"POST", timeoutPath("endpoints", namespace, ""), emptyEndpoints, code201}, + {"POST", timeoutPath("endpoints", namespace, ""), emptyEndpoints, integration.Code201}, // Should return service unavailable when endpoint.subset is empty. - {"GET", pathWithPrefix("proxy", "services", namespace, "a") + "/", "", code503}, - {"PUT", timeoutPath("services", namespace, "a"), aService, code200}, - {"GET", path("services", namespace, "a"), "", code200}, - {"DELETE", timeoutPath("endpoints", namespace, "a"), "", code200}, - {"DELETE", timeoutPath("services", namespace, "a"), "", code200}, + {"GET", pathWithPrefix("proxy", "services", namespace, "a") + "/", "", integration.Code503}, + {"PUT", timeoutPath("services", namespace, "a"), aService, integration.Code200}, + {"GET", path("services", namespace, "a"), "", integration.Code200}, + {"DELETE", timeoutPath("endpoints", namespace, "a"), "", integration.Code200}, + {"DELETE", timeoutPath("services", namespace, "a"), "", integration.Code200}, // Normal methods on replicationControllers - {"GET", path("replicationControllers", "", ""), "", code200}, - {"GET", path("replicationControllers", namespace, ""), "", code200}, - {"POST", timeoutPath("replicationControllers", namespace, ""), aRC, code201}, - {"PUT", timeoutPath("replicationControllers", namespace, "a"), aRC, code200}, - {"GET", path("replicationControllers", namespace, "a"), "", code200}, - {"DELETE", timeoutPath("replicationControllers", namespace, "a"), "", code200}, + {"GET", path("replicationControllers", "", ""), "", integration.Code200}, + {"GET", path("replicationControllers", namespace, ""), "", integration.Code200}, + {"POST", timeoutPath("replicationControllers", namespace, ""), aRC, integration.Code201}, + {"PUT", timeoutPath("replicationControllers", namespace, "a"), aRC, integration.Code200}, + {"GET", path("replicationControllers", namespace, "a"), "", integration.Code200}, + {"DELETE", timeoutPath("replicationControllers", namespace, "a"), "", integration.Code200}, // Normal methods on endpoints - {"GET", path("endpoints", "", ""), "", code200}, - {"GET", path("endpoints", namespace, ""), "", code200}, - {"POST", timeoutPath("endpoints", namespace, ""), aEndpoints, code201}, - {"PUT", timeoutPath("endpoints", namespace, "a"), aEndpoints, code200}, - {"GET", path("endpoints", namespace, "a"), "", code200}, - {"DELETE", timeoutPath("endpoints", namespace, "a"), "", code200}, + {"GET", path("endpoints", "", ""), "", integration.Code200}, + {"GET", path("endpoints", namespace, ""), "", integration.Code200}, + {"POST", timeoutPath("endpoints", namespace, ""), aEndpoints, integration.Code201}, + {"PUT", timeoutPath("endpoints", namespace, "a"), aEndpoints, integration.Code200}, + {"GET", path("endpoints", namespace, "a"), "", integration.Code200}, + {"DELETE", timeoutPath("endpoints", namespace, "a"), "", integration.Code200}, // Normal methods on nodes - {"GET", path("nodes", "", ""), "", code200}, - {"POST", timeoutPath("nodes", "", ""), aNode, code201}, - {"PUT", timeoutPath("nodes", "", "a"), aNode, code200}, - {"GET", path("nodes", "", "a"), "", code200}, - {"DELETE", timeoutPath("nodes", "", "a"), "", code200}, + {"GET", path("nodes", "", ""), "", integration.Code200}, + {"POST", timeoutPath("nodes", "", ""), aNode, integration.Code201}, + {"PUT", timeoutPath("nodes", "", "a"), aNode, integration.Code200}, + {"GET", path("nodes", "", "a"), "", integration.Code200}, + {"DELETE", timeoutPath("nodes", "", "a"), "", integration.Code200}, // Normal methods on events - {"GET", path("events", "", ""), "", code200}, - {"GET", path("events", namespace, ""), "", code200}, - {"POST", timeoutPath("events", namespace, ""), aEvent(namespace), code201}, - {"PUT", timeoutPath("events", namespace, "a"), aEvent(namespace), code200}, - {"GET", path("events", namespace, "a"), "", code200}, - {"DELETE", timeoutPath("events", namespace, "a"), "", code200}, + {"GET", path("events", "", ""), "", integration.Code200}, + {"GET", path("events", namespace, ""), "", integration.Code200}, + {"POST", timeoutPath("events", namespace, ""), aEvent(namespace), integration.Code201}, + {"PUT", timeoutPath("events", namespace, "a"), aEvent(namespace), integration.Code200}, + {"GET", path("events", namespace, "a"), "", integration.Code200}, + {"DELETE", timeoutPath("events", namespace, "a"), "", integration.Code200}, // Normal methods on bindings - {"GET", path("bindings", namespace, ""), "", code405}, - {"POST", timeoutPath("pods", namespace, ""), aPod, code201}, // Need a pod to bind or you get a 404 - {"POST", timeoutPath("bindings", namespace, ""), aBinding, code201}, - {"PUT", timeoutPath("bindings", namespace, "a"), aBinding, code404}, - {"GET", path("bindings", namespace, "a"), "", code404}, // No bindings instances - {"DELETE", timeoutPath("bindings", namespace, "a"), "", code404}, + {"GET", path("bindings", namespace, ""), "", integration.Code405}, + {"POST", timeoutPath("pods", namespace, ""), aPod, integration.Code201}, // Need a pod to bind or you get a 404 + {"POST", timeoutPath("bindings", namespace, ""), aBinding, integration.Code201}, + {"PUT", timeoutPath("bindings", namespace, "a"), aBinding, integration.Code404}, + {"GET", path("bindings", namespace, "a"), "", integration.Code404}, // No bindings instances + {"DELETE", timeoutPath("bindings", namespace, "a"), "", integration.Code404}, // Non-existent object type. - {"GET", path("foo", "", ""), "", code404}, - {"POST", path("foo", namespace, ""), `{"foo": "foo"}`, code404}, - {"PUT", path("foo", namespace, "a"), `{"foo": "foo"}`, code404}, - {"GET", path("foo", namespace, "a"), "", code404}, - {"DELETE", timeoutPath("foo", namespace, ""), "", code404}, + {"GET", path("foo", "", ""), "", integration.Code404}, + {"POST", path("foo", namespace, ""), `{"foo": "foo"}`, integration.Code404}, + {"PUT", path("foo", namespace, "a"), `{"foo": "foo"}`, integration.Code404}, + {"GET", path("foo", namespace, "a"), "", integration.Code404}, + {"DELETE", timeoutPath("foo", namespace, ""), "", integration.Code404}, // Special verbs on nodes - {"GET", pathWithPrefix("proxy", "nodes", namespace, "a"), "", code404}, - {"GET", pathWithPrefix("redirect", "nodes", namespace, "a"), "", code404}, + {"GET", pathWithPrefix("proxy", "nodes", namespace, "a"), "", integration.Code404}, + {"GET", pathWithPrefix("redirect", "nodes", namespace, "a"), "", integration.Code404}, // TODO: test .../watch/..., which doesn't end before the test timeout. // TODO: figure out how to create a node so that it can successfully proxy/redirect. // Non-object endpoints - {"GET", "/", "", code200}, - {"GET", "/api", "", code200}, - {"GET", "/healthz", "", code200}, - {"GET", "/version", "", code200}, - {"GET", "/invalidURL", "", code404}, + {"GET", "/", "", integration.Code200}, + {"GET", "/api", "", integration.Code200}, + {"GET", "/healthz", "", integration.Code200}, + {"GET", "/version", "", integration.Code200}, + {"GET", "/invalidURL", "", integration.Code404}, } return requests } @@ -970,20 +958,20 @@ func TestNamespaceAuthorization(t *testing.T) { statusCodes map[int]bool // allowed status codes. }{ - {"POST", timeoutPath("pods", ns.Name, ""), "foo", aPod, code201}, - {"GET", path("pods", ns.Name, ""), "foo", "", code200}, - {"GET", path("pods", ns.Name, "a"), "foo", "", code200}, - {"DELETE", timeoutPath("pods", ns.Name, "a"), "foo", "", code200}, + {"POST", timeoutPath("pods", ns.Name, ""), "foo", aPod, integration.Code201}, + {"GET", path("pods", ns.Name, ""), "foo", "", integration.Code200}, + {"GET", path("pods", ns.Name, "a"), "foo", "", integration.Code200}, + {"DELETE", timeoutPath("pods", ns.Name, "a"), "foo", "", integration.Code200}, - {"POST", timeoutPath("pods", "foo", ""), "bar", aPod, code403}, - {"GET", path("pods", "foo", ""), "bar", "", code403}, - {"GET", path("pods", "foo", "a"), "bar", "", code403}, - {"DELETE", timeoutPath("pods", "foo", "a"), "bar", "", code403}, + {"POST", timeoutPath("pods", "foo", ""), "bar", aPod, integration.Code403}, + {"GET", path("pods", "foo", ""), "bar", "", integration.Code403}, + {"GET", path("pods", "foo", "a"), "bar", "", integration.Code403}, + {"DELETE", timeoutPath("pods", "foo", "a"), "bar", "", integration.Code403}, - {"POST", timeoutPath("pods", api.NamespaceDefault, ""), "", aPod, code403}, - {"GET", path("pods", "", ""), "", "", code403}, - {"GET", path("pods", api.NamespaceDefault, "a"), "", "", code403}, - {"DELETE", timeoutPath("pods", api.NamespaceDefault, "a"), "", "", code403}, + {"POST", timeoutPath("pods", api.NamespaceDefault, ""), "", aPod, integration.Code403}, + {"GET", path("pods", "", ""), "", "", integration.Code403}, + {"GET", path("pods", api.NamespaceDefault, "a"), "", "", integration.Code403}, + {"DELETE", timeoutPath("pods", api.NamespaceDefault, "a"), "", "", integration.Code403}, } for _, r := range requests { @@ -1066,15 +1054,15 @@ func TestKindAuthorization(t *testing.T) { body string statusCodes map[int]bool // allowed status codes. }{ - {"POST", timeoutPath("services", ns.Name, ""), aService, code201}, - {"GET", path("services", ns.Name, ""), "", code200}, - {"GET", path("services", ns.Name, "a"), "", code200}, - {"DELETE", timeoutPath("services", ns.Name, "a"), "", code200}, + {"POST", timeoutPath("services", ns.Name, ""), aService, integration.Code201}, + {"GET", path("services", ns.Name, ""), "", integration.Code200}, + {"GET", path("services", ns.Name, "a"), "", integration.Code200}, + {"DELETE", timeoutPath("services", ns.Name, "a"), "", integration.Code200}, - {"POST", timeoutPath("pods", ns.Name, ""), aPod, code403}, - {"GET", path("pods", "", ""), "", code403}, - {"GET", path("pods", ns.Name, "a"), "", code403}, - {"DELETE", timeoutPath("pods", ns.Name, "a"), "", code403}, + {"POST", timeoutPath("pods", ns.Name, ""), aPod, integration.Code403}, + {"GET", path("pods", "", ""), "", integration.Code403}, + {"GET", path("pods", ns.Name, "a"), "", integration.Code403}, + {"DELETE", timeoutPath("pods", ns.Name, "a"), "", integration.Code403}, } for _, r := range requests { @@ -1149,9 +1137,9 @@ func TestReadOnlyAuthorization(t *testing.T) { body string statusCodes map[int]bool // allowed status codes. }{ - {"POST", path("pods", ns.Name, ""), aPod, code403}, - {"GET", path("pods", ns.Name, ""), "", code200}, - {"GET", path("pods", api.NamespaceDefault, "a"), "", code404}, + {"POST", path("pods", ns.Name, ""), aPod, integration.Code403}, + {"GET", path("pods", ns.Name, ""), "", integration.Code200}, + {"GET", path("pods", api.NamespaceDefault, "a"), "", integration.Code404}, } for _, r := range requests { diff --git a/test/integration/rbac_test.go b/test/integration/auth/rbac_test.go similarity index 99% rename from test/integration/rbac_test.go rename to test/integration/auth/rbac_test.go index 0f52cd0cffa..60abc4ded91 100644 --- a/test/integration/rbac_test.go +++ b/test/integration/auth/rbac_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package auth import ( "bytes" diff --git a/test/integration/client_test.go b/test/integration/client/client_test.go similarity index 99% rename from test/integration/client_test.go rename to test/integration/client/client_test.go index 3ab606414b9..0c616841ced 100644 --- a/test/integration/client_test.go +++ b/test/integration/client/client_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package client import ( "fmt" diff --git a/test/integration/dynamic_client_test.go b/test/integration/client/dynamic_client_test.go similarity index 99% rename from test/integration/dynamic_client_test.go rename to test/integration/client/dynamic_client_test.go index aefd890935d..e65b87be2d3 100644 --- a/test/integration/dynamic_client_test.go +++ b/test/integration/client/dynamic_client_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package client import ( "reflect" diff --git a/test/integration/configmap_test.go b/test/integration/configmap/configmap_test.go similarity index 96% rename from test/integration/configmap_test.go rename to test/integration/configmap/configmap_test.go index 7e0433eb42c..e3b73a7ea30 100644 --- a/test/integration/configmap_test.go +++ b/test/integration/configmap/configmap_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package configmap // This file tests use of the configMap API resource. @@ -27,6 +27,7 @@ import ( "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/client/restclient" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/test/integration" "k8s.io/kubernetes/test/integration/framework" ) @@ -114,7 +115,7 @@ func DoTestConfigMap(t *testing.T, client *client.Client, ns *api.Namespace) { if _, err := client.Pods(ns.Name).Create(pod); err != nil { t.Errorf("Failed to create pod: %v", err) } - defer deletePodOrErrorf(t, client, ns.Name, pod.Name) + defer integration.DeletePodOrErrorf(t, client, ns.Name, pod.Name) } func deleteConfigMapOrErrorf(t *testing.T, c *client.Client, ns, name string) { diff --git a/test/integration/garbage_collector_test.go b/test/integration/garbagecollector/garbage_collector_test.go similarity index 99% rename from test/integration/garbage_collector_test.go rename to test/integration/garbagecollector/garbage_collector_test.go index 49b0acd87bf..282651eea06 100644 --- a/test/integration/garbage_collector_test.go +++ b/test/integration/garbagecollector/garbage_collector_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package garbagecollector import ( "fmt" diff --git a/test/integration/kubectl_test.go b/test/integration/kubectl/kubectl_test.go similarity index 99% rename from test/integration/kubectl_test.go rename to test/integration/kubectl/kubectl_test.go index 9d84ee93dd6..9cc05497387 100644 --- a/test/integration/kubectl_test.go +++ b/test/integration/kubectl/kubectl_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package kubectl import ( "testing" diff --git a/test/integration/etcd_tools_test.go b/test/integration/master/etcd_tools_test.go similarity index 99% rename from test/integration/etcd_tools_test.go rename to test/integration/master/etcd_tools_test.go index 2b07f810e61..c03814678bd 100644 --- a/test/integration/etcd_tools_test.go +++ b/test/integration/master/etcd_tools_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package master import ( "strconv" diff --git a/test/integration/master_benchmark_test.go b/test/integration/master/master_benchmark_test.go similarity index 99% rename from test/integration/master_benchmark_test.go rename to test/integration/master/master_benchmark_test.go index 75627dc15ff..7c42322cc2f 100644 --- a/test/integration/master_benchmark_test.go +++ b/test/integration/master/master_benchmark_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package master import ( "flag" diff --git a/test/integration/master_test.go b/test/integration/master/master_test.go similarity index 92% rename from test/integration/master_test.go rename to test/integration/master/master_test.go index ca5a59b7219..5334d9814a2 100644 --- a/test/integration/master_test.go +++ b/test/integration/master/master_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package master import ( "bytes" @@ -36,6 +36,7 @@ import ( "k8s.io/kubernetes/pkg/client/restclient" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/util/wait" + "k8s.io/kubernetes/test/integration" "k8s.io/kubernetes/test/integration/framework" ) @@ -127,9 +128,9 @@ func TestAutoscalingGroupBackwardCompatibility(t *testing.T) { expectedStatusCodes map[int]bool expectedVersion string }{ - {"POST", autoscalingPath("horizontalpodautoscalers", api.NamespaceDefault, ""), hpaV1, code201, ""}, - {"GET", autoscalingPath("horizontalpodautoscalers", api.NamespaceDefault, ""), "", code200, testapi.Autoscaling.GroupVersion().String()}, - {"GET", extensionsPath("horizontalpodautoscalers", api.NamespaceDefault, ""), "", code200, testapi.Extensions.GroupVersion().String()}, + {"POST", autoscalingPath("horizontalpodautoscalers", api.NamespaceDefault, ""), hpaV1, integration.Code201, ""}, + {"GET", autoscalingPath("horizontalpodautoscalers", api.NamespaceDefault, ""), "", integration.Code200, testapi.Autoscaling.GroupVersion().String()}, + {"GET", extensionsPath("horizontalpodautoscalers", api.NamespaceDefault, ""), "", integration.Code200, testapi.Extensions.GroupVersion().String()}, } for _, r := range requests { @@ -242,16 +243,6 @@ var jobV1 string = ` } ` -var deleteResp string = ` -{ - "kind": "Status", - "apiVersion": "v1", - "metadata":{}, - "status":"Success", - "code":200 -} -` - // TestBatchGroupBackwardCompatibility is testing that batch/v1 and ext/v1beta1 // Job share storage. This test can be deleted when Jobs is removed from ext/v1beta1, // (expected to happen in 1.4). @@ -271,15 +262,15 @@ func TestBatchGroupBackwardCompatibility(t *testing.T) { expectedVersion string }{ // Post a v1 and get back both as v1beta1 and as v1. - {"POST", batchPath("jobs", api.NamespaceDefault, ""), jobV1, code201, ""}, - {"GET", batchPath("jobs", api.NamespaceDefault, "pi"), "", code200, testapi.Batch.GroupVersion().String()}, - {"GET", extensionsPath("jobs", api.NamespaceDefault, "pi"), "", code200, testapi.Extensions.GroupVersion().String()}, - {"DELETE", batchPath("jobs", api.NamespaceDefault, "pi"), "", code200, testapi.Default.GroupVersion().String()}, // status response + {"POST", batchPath("jobs", api.NamespaceDefault, ""), jobV1, integration.Code201, ""}, + {"GET", batchPath("jobs", api.NamespaceDefault, "pi"), "", integration.Code200, testapi.Batch.GroupVersion().String()}, + {"GET", extensionsPath("jobs", api.NamespaceDefault, "pi"), "", integration.Code200, testapi.Extensions.GroupVersion().String()}, + {"DELETE", batchPath("jobs", api.NamespaceDefault, "pi"), "", integration.Code200, testapi.Default.GroupVersion().String()}, // status response // Post a v1beta1 and get back both as v1beta1 and as v1. - {"POST", extensionsPath("jobs", api.NamespaceDefault, ""), jobV1beta1, code201, ""}, - {"GET", batchPath("jobs", api.NamespaceDefault, "pi"), "", code200, testapi.Batch.GroupVersion().String()}, - {"GET", extensionsPath("jobs", api.NamespaceDefault, "pi"), "", code200, testapi.Extensions.GroupVersion().String()}, - {"DELETE", extensionsPath("jobs", api.NamespaceDefault, "pi"), "", code200, testapi.Default.GroupVersion().String()}, //status response + {"POST", extensionsPath("jobs", api.NamespaceDefault, ""), jobV1beta1, integration.Code201, ""}, + {"GET", batchPath("jobs", api.NamespaceDefault, "pi"), "", integration.Code200, testapi.Batch.GroupVersion().String()}, + {"GET", extensionsPath("jobs", api.NamespaceDefault, "pi"), "", integration.Code200, testapi.Extensions.GroupVersion().String()}, + {"DELETE", extensionsPath("jobs", api.NamespaceDefault, "pi"), "", integration.Code200, testapi.Default.GroupVersion().String()}, //status response } for _, r := range requests { diff --git a/test/integration/metrics_test.go b/test/integration/metrics/metrics_test.go similarity index 99% rename from test/integration/metrics_test.go rename to test/integration/metrics/metrics_test.go index 9d3f5149377..05899242a2b 100644 --- a/test/integration/metrics_test.go +++ b/test/integration/metrics/metrics_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package metrics import ( "bufio" diff --git a/test/integration/openshift_test.go b/test/integration/openshift/openshift_test.go similarity index 98% rename from test/integration/openshift_test.go rename to test/integration/openshift/openshift_test.go index bd552d44882..0703030a408 100644 --- a/test/integration/openshift_test.go +++ b/test/integration/openshift/openshift_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package openshift import ( "testing" diff --git a/test/integration/persistent_volumes_test.go b/test/integration/persistentvolumes/persistent_volumes_test.go similarity index 99% rename from test/integration/persistent_volumes_test.go rename to test/integration/persistentvolumes/persistent_volumes_test.go index 1def6df2771..5e0d048c3a4 100644 --- a/test/integration/persistent_volumes_test.go +++ b/test/integration/persistentvolumes/persistent_volumes_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package persistentvolumes import ( "fmt" @@ -27,8 +27,6 @@ import ( "testing" "time" - "github.com/golang/glog" - "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/testapi" @@ -41,11 +39,14 @@ import ( "k8s.io/kubernetes/pkg/volume" volumetest "k8s.io/kubernetes/pkg/volume/testing" "k8s.io/kubernetes/pkg/watch" + "k8s.io/kubernetes/test/integration" "k8s.io/kubernetes/test/integration/framework" + + "github.com/golang/glog" ) func init() { - requireEtcd() + integration.RequireEtcd() } // Several tests in this file are configurable by environment variables: diff --git a/test/integration/pods_test.go b/test/integration/pods/pods_test.go similarity index 95% rename from test/integration/pods_test.go rename to test/integration/pods/pods_test.go index 2d69a2a46b8..342093b4fac 100644 --- a/test/integration/pods_test.go +++ b/test/integration/pods/pods_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package pods import ( "fmt" @@ -26,6 +26,7 @@ import ( "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/client/restclient" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/test/integration" "k8s.io/kubernetes/test/integration/framework" ) @@ -142,7 +143,7 @@ func TestPodUpdateActiveDeadlineSeconds(t *testing.T) { t.Errorf("%v: unexpected allowed update to pod", tc.name) } - deletePodOrErrorf(t, client, ns.Name, pod.Name) + integration.DeletePodOrErrorf(t, client, ns.Name, pod.Name) } } @@ -177,5 +178,5 @@ func TestPodReadOnlyFilesystem(t *testing.T) { t.Errorf("Failed to create pod: %v", err) } - deletePodOrErrorf(t, client, ns.Name, pod.Name) + integration.DeletePodOrErrorf(t, client, ns.Name, pod.Name) } diff --git a/test/integration/quota_test.go b/test/integration/quota/quota_test.go similarity index 98% rename from test/integration/quota_test.go rename to test/integration/quota/quota_test.go index 8fd9a547e4b..27cd6959fc0 100644 --- a/test/integration/quota_test.go +++ b/test/integration/quota/quota_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package quota import ( "fmt" @@ -40,11 +40,12 @@ import ( quotainstall "k8s.io/kubernetes/pkg/quota/install" "k8s.io/kubernetes/pkg/watch" "k8s.io/kubernetes/plugin/pkg/admission/resourcequota" + "k8s.io/kubernetes/test/integration" "k8s.io/kubernetes/test/integration/framework" ) func init() { - requireEtcd() + integration.RequireEtcd() } // 1.2 code gets: diff --git a/test/integration/extender_test.go b/test/integration/scheduler/extender_test.go similarity index 99% rename from test/integration/extender_test.go rename to test/integration/scheduler/extender_test.go index 07e4745fac9..65a7abb3838 100644 --- a/test/integration/extender_test.go +++ b/test/integration/scheduler/extender_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package scheduler // This file tests scheduler extender. diff --git a/test/integration/scheduler_test.go b/test/integration/scheduler/scheduler_test.go similarity index 99% rename from test/integration/scheduler_test.go rename to test/integration/scheduler/scheduler_test.go index e81ae03d8cb..175222d8816 100644 --- a/test/integration/scheduler_test.go +++ b/test/integration/scheduler/scheduler_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package scheduler // This file tests the scheduler. diff --git a/test/integration/secret_test.go b/test/integration/secrets/secrets_test.go similarity index 94% rename from test/integration/secret_test.go rename to test/integration/secrets/secrets_test.go index e90e4858ffc..fe972c24d19 100644 --- a/test/integration/secret_test.go +++ b/test/integration/secrets/secrets_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package secrets // This file tests use of the secrets API resource. @@ -27,6 +27,7 @@ import ( "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/client/restclient" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/test/integration" "k8s.io/kubernetes/test/integration/framework" ) @@ -105,14 +106,14 @@ func DoTestSecrets(t *testing.T, client *client.Client, ns *api.Namespace) { if _, err := client.Pods(ns.Name).Create(pod); err != nil { t.Errorf("Failed to create pod: %v", err) } - defer deletePodOrErrorf(t, client, ns.Name, pod.Name) + defer integration.DeletePodOrErrorf(t, client, ns.Name, pod.Name) // Create a pod that consumes non-existent secret. pod.ObjectMeta.Name = "uses-non-existent-secret" if _, err := client.Pods(ns.Name).Create(pod); err != nil { t.Errorf("Failed to create pod: %v", err) } - defer deletePodOrErrorf(t, client, ns.Name, pod.Name) + defer integration.DeletePodOrErrorf(t, client, ns.Name, pod.Name) // This pod may fail to run, but we don't currently prevent this, and this // test can't check whether the kubelet actually pulls the secret. diff --git a/test/integration/service_account_test.go b/test/integration/serviceaccount/service_account_test.go similarity index 99% rename from test/integration/service_account_test.go rename to test/integration/serviceaccount/service_account_test.go index 9df0b0744ce..dcd7f5e2200 100644 --- a/test/integration/service_account_test.go +++ b/test/integration/serviceaccount/service_account_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package integration +package serviceaccount // This file tests authentication and (soon) authorization of HTTP requests to a master object. // It does not use the client in pkg/client/... because authentication and authorization needs @@ -47,6 +47,7 @@ import ( "k8s.io/kubernetes/pkg/util/wait" serviceaccountadmission "k8s.io/kubernetes/plugin/pkg/admission/serviceaccount" "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union" + "k8s.io/kubernetes/test/integration" "k8s.io/kubernetes/test/integration/framework" ) @@ -59,7 +60,7 @@ const ( ) func init() { - requireEtcd() + integration.RequireEtcd() } func TestServiceAccountAutoCreate(t *testing.T) { diff --git a/test/integration/utils.go b/test/integration/utils.go index 47c394beef2..d34cc64b97b 100644 --- a/test/integration/utils.go +++ b/test/integration/utils.go @@ -39,7 +39,7 @@ func newEtcdClient() etcd.Client { return client } -func requireEtcd() { +func RequireEtcd() { if _, err := etcd.NewKeysAPI(newEtcdClient()).Get(context.TODO(), "/", nil); err != nil { glog.Fatalf("unable to connect to etcd for integration testing: %v", err) } @@ -51,8 +51,21 @@ func withEtcdKey(f func(string)) { f(prefix) } -func deletePodOrErrorf(t *testing.T, c *client.Client, ns, name string) { +func DeletePodOrErrorf(t *testing.T, c *client.Client, ns, name string) { if err := c.Pods(ns).Delete(name, nil); err != nil { t.Errorf("unable to delete pod %v: %v", name, err) } } + +// Requests to try. Each one should be forbidden or not forbidden +// depending on the authentication and authorization setup of the master. +var Code200 = map[int]bool{200: true} +var Code201 = map[int]bool{201: true} +var Code400 = map[int]bool{400: true} +var Code403 = map[int]bool{403: true} +var Code404 = map[int]bool{404: true} +var Code405 = map[int]bool{405: true} +var Code409 = map[int]bool{409: true} +var Code422 = map[int]bool{422: true} +var Code500 = map[int]bool{500: true} +var Code503 = map[int]bool{503: true}