Updating integration tests to test both API versions - v1beta1 and 3

This commit is contained in:
nikhiljindal 2015-03-18 01:21:10 -07:00
parent c966ae8953
commit 7e36bbab3c
13 changed files with 175 additions and 158 deletions

View File

@ -37,7 +37,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
apierrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" apierrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
nodeControllerPkg "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller" nodeControllerPkg "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller"
@ -59,10 +58,13 @@ import (
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/spf13/pflag"
) )
var ( var (
fakeDocker1, fakeDocker2 dockertools.FakeDockerClient fakeDocker1, fakeDocker2 dockertools.FakeDockerClient
// API version that should be used by the client to talk to the server.
apiVersion string
) )
type fakeKubeletClient struct{} type fakeKubeletClient struct{}
@ -120,7 +122,7 @@ func (h *delegateHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
} }
func startComponents(manifestURL string) (string, string) { func startComponents(manifestURL, apiVersion string) (string, string) {
// Setup // Setup
servers := []string{} servers := []string{}
glog.Infof("Creating etcd client pointing to %v", servers) glog.Infof("Creating etcd client pointing to %v", servers)
@ -154,7 +156,7 @@ func startComponents(manifestURL string) (string, string) {
glog.Fatalf("Failed to connect to etcd") glog.Fatalf("Failed to connect to etcd")
} }
cl := client.NewOrDie(&client.Config{Host: apiServer.URL, Version: testapi.Version()}) cl := client.NewOrDie(&client.Config{Host: apiServer.URL, Version: apiVersion})
helper, err := master.NewEtcdHelper(etcdClient, "") helper, err := master.NewEtcdHelper(etcdClient, "")
if err != nil { if err != nil {
@ -178,7 +180,6 @@ func startComponents(manifestURL string) (string, string) {
// Create a master and install handlers into mux. // Create a master and install handlers into mux.
m := master.New(&master.Config{ m := master.New(&master.Config{
Client: cl,
EtcdHelper: helper, EtcdHelper: helper,
KubeletClient: fakeKubeletClient{}, KubeletClient: fakeKubeletClient{},
EnableLogsSupport: false, EnableLogsSupport: false,
@ -191,6 +192,7 @@ func startComponents(manifestURL string) (string, string) {
PublicAddress: publicAddress, PublicAddress: publicAddress,
CacheTimeout: 2 * time.Second, CacheTimeout: 2 * time.Second,
SyncPodStatus: true, SyncPodStatus: true,
EnableV1Beta3: true,
}) })
handler.delegate = m.Handler handler.delegate = m.Handler
@ -338,7 +340,8 @@ containers:
} }
func runReplicationControllerTest(c *client.Client) { func runReplicationControllerTest(c *client.Client) {
data, err := ioutil.ReadFile("cmd/integration/controller.json") clientAPIVersion := c.APIVersion()
data, err := ioutil.ReadFile("cmd/integration/" + clientAPIVersion + "-controller.json")
if err != nil { if err != nil {
glog.Fatalf("Unexpected error: %v", err) glog.Fatalf("Unexpected error: %v", err)
} }
@ -373,55 +376,55 @@ func runReplicationControllerTest(c *client.Client) {
func runAPIVersionsTest(c *client.Client) { func runAPIVersionsTest(c *client.Client) {
v, err := c.ServerAPIVersions() v, err := c.ServerAPIVersions()
clientVersion := c.APIVersion()
if err != nil { if err != nil {
glog.Fatalf("failed to get api versions: %v", err) glog.Fatalf("failed to get api versions: %v", err)
} }
if e, a := []string{"v1beta1", "v1beta2"}, v.Versions; !reflect.DeepEqual(e, a) { // Verify that the server supports the API version used by the client.
glog.Fatalf("Expected version list '%v', got '%v'", e, a) for _, version := range v.Versions {
if version == clientVersion {
glog.Infof("Version test passed")
return
}
} }
glog.Infof("Version test passed") glog.Fatalf("Server does not support APIVersion used by client. Server supported APIVersions: '%v', client APIVersion: '%v'", v.Versions, clientVersion)
} }
func runSelfLinkTestOnNamespace(c *client.Client, namespace string) { func runSelfLinkTestOnNamespace(c *client.Client, namespace string) {
var svc api.Service svcBody := api.Service{
err := c.Post(). ObjectMeta: api.ObjectMeta{
NamespaceIfScoped(namespace, len(namespace) > 0). Name: "selflinktest",
Resource("services").Body( Namespace: namespace,
&api.Service{ Labels: map[string]string{
ObjectMeta: api.ObjectMeta{ "name": "selflinktest",
Name: "selflinktest",
Namespace: namespace,
Labels: map[string]string{
"name": "selflinktest",
},
},
Spec: api.ServiceSpec{
Port: 12345,
// This is here because validation requires it.
Selector: map[string]string{
"foo": "bar",
},
Protocol: "TCP",
SessionAffinity: "None",
}, },
}, },
).Do().Into(&svc) Spec: api.ServiceSpec{
Port: 12345,
// This is here because validation requires it.
Selector: map[string]string{
"foo": "bar",
},
Protocol: "TCP",
SessionAffinity: "None",
},
}
services := c.Services(namespace)
svc, err := services.Create(&svcBody)
if err != nil { if err != nil {
glog.Fatalf("Failed creating selflinktest service: %v", err) glog.Fatalf("Failed creating selflinktest service: %v", err)
} }
// TODO: this is not namespace aware err = c.Get().RequestURI(svc.SelfLink).Do().Into(svc)
err = c.Get().RequestURI(svc.SelfLink).Do().Into(&svc)
if err != nil { if err != nil {
glog.Fatalf("Failed listing service with supplied self link '%v': %v", svc.SelfLink, err) glog.Fatalf("Failed listing service with supplied self link '%v': %v", svc.SelfLink, err)
} }
var svcList api.ServiceList svcList, err := services.List(labels.Everything())
err = c.Get().NamespaceIfScoped(namespace, len(namespace) > 0).Resource("services").Do().Into(&svcList)
if err != nil { if err != nil {
glog.Fatalf("Failed listing services: %v", err) glog.Fatalf("Failed listing services: %v", err)
} }
err = c.Get().RequestURI(svcList.SelfLink).Do().Into(&svcList) err = c.Get().RequestURI(svcList.SelfLink).Do().Into(svcList)
if err != nil { if err != nil {
glog.Fatalf("Failed listing services with supplied self link '%v': %v", svcList.SelfLink, err) glog.Fatalf("Failed listing services with supplied self link '%v': %v", svcList.SelfLink, err)
} }
@ -433,7 +436,7 @@ func runSelfLinkTestOnNamespace(c *client.Client, namespace string) {
continue continue
} }
found = true found = true
err = c.Get().RequestURI(item.SelfLink).Do().Into(&svc) err = c.Get().RequestURI(item.SelfLink).Do().Into(svc)
if err != nil { if err != nil {
glog.Fatalf("Failed listing service with supplied self link '%v': %v", item.SelfLink, err) glog.Fatalf("Failed listing service with supplied self link '%v': %v", item.SelfLink, err)
} }
@ -448,29 +451,28 @@ func runSelfLinkTestOnNamespace(c *client.Client, namespace string) {
} }
func runAtomicPutTest(c *client.Client) { func runAtomicPutTest(c *client.Client) {
var svc api.Service svcBody := api.Service{
err := c.Post().Resource("services").Body( TypeMeta: api.TypeMeta{
&api.Service{ APIVersion: c.APIVersion(),
TypeMeta: api.TypeMeta{ },
APIVersion: latest.Version, ObjectMeta: api.ObjectMeta{
}, Name: "atomicservice",
ObjectMeta: api.ObjectMeta{ Labels: map[string]string{
Name: "atomicservice", "name": "atomicService",
Labels: map[string]string{
"name": "atomicService",
},
},
Spec: api.ServiceSpec{
Port: 12345,
// This is here because validation requires it.
Selector: map[string]string{
"foo": "bar",
},
Protocol: "TCP",
SessionAffinity: "None",
}, },
}, },
).Do().Into(&svc) Spec: api.ServiceSpec{
Port: 12345,
// This is here because validation requires it.
Selector: map[string]string{
"foo": "bar",
},
Protocol: "TCP",
SessionAffinity: "None",
},
}
services := c.Services(api.NamespaceDefault)
svc, err := services.Create(&svcBody)
if err != nil { if err != nil {
glog.Fatalf("Failed creating atomicService: %v", err) glog.Fatalf("Failed creating atomicService: %v", err)
} }
@ -488,12 +490,7 @@ func runAtomicPutTest(c *client.Client) {
go func(l, v string) { go func(l, v string) {
for { for {
glog.Infof("Starting to update (%s, %s)", l, v) glog.Infof("Starting to update (%s, %s)", l, v)
var tmpSvc api.Service tmpSvc, err := services.Get(svc.Name)
err := c.Get().
Resource("services").
Name(svc.Name).
Do().
Into(&tmpSvc)
if err != nil { if err != nil {
glog.Errorf("Error getting atomicService: %v", err) glog.Errorf("Error getting atomicService: %v", err)
continue continue
@ -504,7 +501,7 @@ func runAtomicPutTest(c *client.Client) {
tmpSvc.Spec.Selector[l] = v tmpSvc.Spec.Selector[l] = v
} }
glog.Infof("Posting update (%s, %s)", l, v) glog.Infof("Posting update (%s, %s)", l, v)
err = c.Put().Resource("services").Name(svc.Name).Body(&tmpSvc).Do().Error() tmpSvc, err = services.Update(tmpSvc)
if err != nil { if err != nil {
if apierrors.IsConflict(err) { if apierrors.IsConflict(err) {
glog.Infof("Conflict: (%s, %s)", l, v) glog.Infof("Conflict: (%s, %s)", l, v)
@ -521,7 +518,8 @@ func runAtomicPutTest(c *client.Client) {
}(label, value) }(label, value)
} }
wg.Wait() wg.Wait()
if err := c.Get().Resource("services").Name(svc.Name).Do().Into(&svc); err != nil { svc, err = services.Get(svc.Name)
if err != nil {
glog.Fatalf("Failed getting atomicService after writers are complete: %v", err) glog.Fatalf("Failed getting atomicService after writers are complete: %v", err)
} }
if !reflect.DeepEqual(testLabels, labels.Set(svc.Spec.Selector)) { if !reflect.DeepEqual(testLabels, labels.Set(svc.Spec.Selector)) {
@ -532,30 +530,28 @@ func runAtomicPutTest(c *client.Client) {
func runPatchTest(c *client.Client) { func runPatchTest(c *client.Client) {
name := "patchservice" name := "patchservice"
resource := "services" svcBody := api.Service{
var svc api.Service TypeMeta: api.TypeMeta{
err := c.Post().Resource(resource).Body( APIVersion: c.APIVersion(),
&api.Service{ },
TypeMeta: api.TypeMeta{ ObjectMeta: api.ObjectMeta{
APIVersion: latest.Version, Name: name,
}, Labels: map[string]string{
ObjectMeta: api.ObjectMeta{ "name": name,
Name: name,
Labels: map[string]string{
"name": name,
},
},
Spec: api.ServiceSpec{
Port: 12345,
// This is here because validation requires it.
Selector: map[string]string{
"foo": "bar",
},
Protocol: "TCP",
SessionAffinity: "None",
}, },
}, },
).Do().Into(&svc) Spec: api.ServiceSpec{
Port: 12345,
// This is here because validation requires it.
Selector: map[string]string{
"foo": "bar",
},
Protocol: "TCP",
SessionAffinity: "None",
},
}
services := c.Services(api.NamespaceDefault)
svc, err := services.Create(&svcBody)
if err != nil { if err != nil {
glog.Fatalf("Failed creating patchservice: %v", err) glog.Fatalf("Failed creating patchservice: %v", err)
} }
@ -564,12 +560,11 @@ func runPatchTest(c *client.Client) {
} }
// add label // add label
_, err = c.Patch().Resource(resource).Name(name).Body([]byte("{\"labels\":{\"foo\":\"bar\"}}")).Do().Get() svc.Labels["foo"] = "bar"
if err != nil { if _, err = services.Update(svc); err != nil {
glog.Fatalf("Failed updating patchservice: %v", err) glog.Fatalf("Failed updating patchservice: %v", err)
} }
err = c.Get().Resource(resource).Name(name).Do().Into(&svc) if svc, err = services.Get(name); err != nil {
if err != nil {
glog.Fatalf("Failed getting patchservice: %v", err) glog.Fatalf("Failed getting patchservice: %v", err)
} }
if len(svc.Labels) != 2 || svc.Labels["foo"] != "bar" { if len(svc.Labels) != 2 || svc.Labels["foo"] != "bar" {
@ -577,12 +572,11 @@ func runPatchTest(c *client.Client) {
} }
// remove one label // remove one label
_, err = c.Patch().Resource(resource).Name(name).Body([]byte("{\"labels\":{\"name\":null}}")).Do().Get() delete(svc.Labels, "name")
if err != nil { if _, err = services.Update(svc); err != nil {
glog.Fatalf("Failed updating patchservice: %v", err) glog.Fatalf("Failed updating patchservice: %v", err)
} }
err = c.Get().Resource(resource).Name(name).Do().Into(&svc) if svc, err = services.Get(name); err != nil {
if err != nil {
glog.Fatalf("Failed getting patchservice: %v", err) glog.Fatalf("Failed getting patchservice: %v", err)
} }
if len(svc.Labels) != 1 || svc.Labels["foo"] != "bar" { if len(svc.Labels) != 1 || svc.Labels["foo"] != "bar" {
@ -590,12 +584,11 @@ func runPatchTest(c *client.Client) {
} }
// remove all labels // remove all labels
_, err = c.Patch().Resource(resource).Name(name).Body([]byte("{\"labels\":null}")).Do().Get() svc.Labels = nil
if err != nil { if _, err = services.Update(svc); err != nil {
glog.Fatalf("Failed updating patchservice: %v", err) glog.Fatalf("Failed updating patchservice: %v", err)
} }
err = c.Get().Resource(resource).Name(name).Do().Into(&svc) if svc, err = services.Get(name); err != nil {
if err != nil {
glog.Fatalf("Failed getting patchservice: %v", err) glog.Fatalf("Failed getting patchservice: %v", err)
} }
if svc.Labels != nil { if svc.Labels != nil {
@ -607,12 +600,7 @@ func runPatchTest(c *client.Client) {
func runMasterServiceTest(client *client.Client) { func runMasterServiceTest(client *client.Client) {
time.Sleep(12 * time.Second) time.Sleep(12 * time.Second)
var svcList api.ServiceList svcList, err := client.Services(api.NamespaceDefault).List(labels.Everything())
err := client.Get().
Namespace("default").
Resource("services").
Do().
Into(&svcList)
if err != nil { if err != nil {
glog.Fatalf("unexpected error listing services: %v", err) glog.Fatalf("unexpected error listing services: %v", err)
} }
@ -628,13 +616,7 @@ func runMasterServiceTest(client *client.Client) {
} }
} }
if foundRW { if foundRW {
var ep api.Endpoints ep, err := client.Endpoints(api.NamespaceDefault).Get("kubernetes")
err := client.Get().
Namespace("default").
Resource("endpoints").
Name("kubernetes").
Do().
Into(&ep)
if err != nil { if err != nil {
glog.Fatalf("unexpected error listing endpoints for kubernetes service: %v", err) glog.Fatalf("unexpected error listing endpoints for kubernetes service: %v", err)
} }
@ -645,13 +627,7 @@ func runMasterServiceTest(client *client.Client) {
glog.Errorf("no RW service found: %v", found) glog.Errorf("no RW service found: %v", found)
} }
if foundRO { if foundRO {
var ep api.Endpoints ep, err := client.Endpoints(api.NamespaceDefault).Get("kubernetes-ro")
err := client.Get().
Namespace("default").
Resource("endpoints").
Name("kubernetes-ro").
Do().
Into(&ep)
if err != nil { if err != nil {
glog.Fatalf("unexpected error listing endpoints for kubernetes service: %v", err) glog.Fatalf("unexpected error listing endpoints for kubernetes service: %v", err)
} }
@ -683,7 +659,7 @@ func runServiceTest(client *client.Client) {
Ports: []api.ContainerPort{ Ports: []api.ContainerPort{
{ContainerPort: 1234}, {ContainerPort: 1234},
}, },
ImagePullPolicy: "PullIfNotPresent", ImagePullPolicy: api.PullIfNotPresent,
}, },
}, },
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
@ -777,9 +753,15 @@ func runServiceTest(client *client.Client) {
type testFunc func(*client.Client) type testFunc func(*client.Client)
func addFlags(fs *pflag.FlagSet) {
fs.StringVar(&apiVersion, "apiVersion", latest.Version, "API version that should be used by the client for communicating with the server")
}
func main() { func main() {
util.InitFlags()
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())
addFlags(pflag.CommandLine)
util.InitFlags()
util.ReallyCrash = true util.ReallyCrash = true
util.InitLogs() util.InitLogs()
defer util.FlushLogs() defer util.FlushLogs()
@ -790,16 +772,17 @@ func main() {
glog.Fatalf("This test has timed out.") glog.Fatalf("This test has timed out.")
}() }()
manifestURL := ServeCachedManifestFile() glog.Infof("Running tests for APIVersion: %s", apiVersion)
apiServerURL, configFilePath := startComponents(manifestURL) manifestURL := ServeCachedManifestFile()
apiServerURL, configFilePath := startComponents(manifestURL, apiVersion)
// Ok. we're good to go. // Ok. we're good to go.
glog.Infof("API Server started on %s", apiServerURL) glog.Infof("API Server started on %s", apiServerURL)
// Wait for the synchronization threads to come up. // Wait for the synchronization threads to come up.
time.Sleep(time.Second * 10) time.Sleep(time.Second * 10)
kubeClient := client.NewOrDie(&client.Config{Host: apiServerURL, Version: testapi.Version()}) kubeClient := client.NewOrDie(&client.Config{Host: apiServerURL, Version: apiVersion})
// Run tests in parallel // Run tests in parallel
testFuncs := []testFunc{ testFuncs := []testFunc{
@ -810,13 +793,14 @@ func main() {
runAPIVersionsTest, runAPIVersionsTest,
runMasterServiceTest, runMasterServiceTest,
func(c *client.Client) { func(c *client.Client) {
runSelfLinkTestOnNamespace(c, "") runSelfLinkTestOnNamespace(c, api.NamespaceDefault)
runSelfLinkTestOnNamespace(c, "other") runSelfLinkTestOnNamespace(c, "other")
}, },
func(c *client.Client) { func(c *client.Client) {
runStaticPodTest(c, configFilePath) runStaticPodTest(c, configFilePath)
}, },
} }
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(len(testFuncs)) wg.Add(len(testFuncs))
for i := range testFuncs { for i := range testFuncs {

View File

@ -0,0 +1,24 @@
{
"kind": "ReplicationController",
"apiVersion": "v1beta3",
"metadata": {
"name": "nginx-controller",
"labels": {"name": "nginx"}
},
"spec": {
"replicas": 2,
"selector": {"name": "nginx"},
"template": {
"metadata": {
"labels": {"name": "nginx"}
},
"spec": {
"containers": [{
"name": "nginx",
"image": "dockerfile/nginx",
"ports": [{"containerPort": 80}]
}]
}
}
}
}

View File

@ -229,7 +229,6 @@ func (s *APIServer) Run(_ []string) error {
admissionController := admission.NewFromPlugins(client, admissionControlPluginNames, s.AdmissionControlConfigFile) admissionController := admission.NewFromPlugins(client, admissionControlPluginNames, s.AdmissionControlConfigFile)
config := &master.Config{ config := &master.Config{
Client: client,
Cloud: cloud, Cloud: cloud,
EtcdHelper: helper, EtcdHelper: helper,
EventTTL: s.EventTTL, EventTTL: s.EventTTL,

View File

@ -76,7 +76,7 @@ func (h *delegateHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
} }
// RunApiServer starts an API server in a go routine. // RunApiServer starts an API server in a go routine.
func runApiServer(cl *client.Client, etcdClient tools.EtcdClient, addr net.IP, port int, masterServiceNamespace string) { func runApiServer(etcdClient tools.EtcdClient, addr net.IP, port int, masterServiceNamespace string) {
handler := delegateHandler{} handler := delegateHandler{}
helper, err := master.NewEtcdHelper(etcdClient, "") helper, err := master.NewEtcdHelper(etcdClient, "")
@ -86,7 +86,6 @@ func runApiServer(cl *client.Client, etcdClient tools.EtcdClient, addr net.IP, p
// Create a master and install handlers into mux. // Create a master and install handlers into mux.
m := master.New(&master.Config{ m := master.New(&master.Config{
Client: cl,
EtcdHelper: helper, EtcdHelper: helper,
KubeletClient: &client.HTTPKubeletClient{ KubeletClient: &client.HTTPKubeletClient{
Client: http.DefaultClient, Client: http.DefaultClient,
@ -142,7 +141,7 @@ func runControllerManager(machineList []string, cl *client.Client, nodeMilliCPU,
func startComponents(etcdClient tools.EtcdClient, cl *client.Client, addr net.IP, port int) { func startComponents(etcdClient tools.EtcdClient, cl *client.Client, addr net.IP, port int) {
machineList := []string{"localhost"} machineList := []string{"localhost"}
runApiServer(cl, etcdClient, addr, port, *masterServiceNamespace) runApiServer(etcdClient, addr, port, *masterServiceNamespace)
runScheduler(cl) runScheduler(cl)
runControllerManager(machineList, cl, *nodeMilliCPU, *nodeMemory) runControllerManager(machineList, cl, *nodeMilliCPU, *nodeMemory)

View File

@ -100,7 +100,8 @@ func TestExampleObjectSchemas(t *testing.T) {
"pod": &api.Pod{}, "pod": &api.Pod{},
}, },
"../cmd/integration": { "../cmd/integration": {
"controller": &api.ReplicationController{}, "v1beta1-controller": &api.ReplicationController{},
"v1beta3-controller": &api.ReplicationController{},
}, },
"../examples/guestbook": { "../examples/guestbook": {
"frontend-controller": &api.ReplicationController{}, "frontend-controller": &api.ReplicationController{},

View File

@ -30,20 +30,25 @@ cleanup() {
kube::log::status "Integration test cleanup complete" kube::log::status "Integration test cleanup complete"
} }
runTests() {
kube::etcd::start
kube::log::status "Running integration test cases"
KUBE_GOFLAGS="-tags 'integration no-docker' " \
KUBE_RACE="-race" \
"${KUBE_ROOT}/hack/test-go.sh" test/integration
kube::log::status "Running integration test scenario"
"${KUBE_OUTPUT_HOSTBIN}/integration" --v=2 --apiVersion="$1"
cleanup
}
"${KUBE_ROOT}/hack/build-go.sh" "$@" cmd/integration "${KUBE_ROOT}/hack/build-go.sh" "$@" cmd/integration
# Run cleanup to stop etcd on interrupt or other kill signal. # Run cleanup to stop etcd on interrupt or other kill signal.
trap cleanup EXIT trap cleanup EXIT
kube::etcd::start runTests "v1beta1"
runTests "v1beta3"
kube::log::status "Running integration test cases"
KUBE_GOFLAGS="-tags 'integration no-docker' " \
KUBE_RACE="-race" \
"${KUBE_ROOT}/hack/test-go.sh" test/integration
kube::log::status "Running integration test scenario"
"${KUBE_OUTPUT_HOSTBIN}/integration" --v=2
cleanup

View File

@ -89,7 +89,7 @@ type Request struct {
baseURL *url.URL baseURL *url.URL
codec runtime.Codec codec runtime.Codec
// If true, add "?namespace=<namespace>" as a query parameter, if false put ns/<namespace> in path // If true, add "?namespace=<namespace>" as a query parameter, if false put namespaces/<namespace> in path
// Query parameter is considered legacy behavior // Query parameter is considered legacy behavior
namespaceInQuery bool namespaceInQuery bool
// If true, lowercase resource prior to inserting into a path, if false, leave it as is. Preserving // If true, lowercase resource prior to inserting into a path, if false, leave it as is. Preserving

View File

@ -77,7 +77,13 @@ func (c *services) Get(name string) (result *api.Service, err error) {
// Create creates a new service. // Create creates a new service.
func (c *services) Create(svc *api.Service) (result *api.Service, err error) { func (c *services) Create(svc *api.Service) (result *api.Service, err error) {
result = &api.Service{} result = &api.Service{}
err = c.r.Post().Namespace(c.ns).Resource("services").Body(svc).Do().Into(result) // v1beta3 does not allow POST without a namespace.
needNamespace := !api.PreV1Beta3(c.r.APIVersion())
namespace := c.ns
if needNamespace && len(namespace) == 0 {
namespace = api.NamespaceDefault
}
err = c.r.Post().Namespace(namespace).Resource("services").Body(svc).Do().Into(result)
return return
} }
@ -88,12 +94,24 @@ func (c *services) Update(svc *api.Service) (result *api.Service, err error) {
err = fmt.Errorf("invalid update object, missing resource version: %v", svc) err = fmt.Errorf("invalid update object, missing resource version: %v", svc)
return return
} }
err = c.r.Put().Namespace(c.ns).Resource("services").Name(svc.Name).Body(svc).Do().Into(result) // v1beta3 does not allow PUT without a namespace.
needNamespace := !api.PreV1Beta3(c.r.APIVersion())
namespace := c.ns
if needNamespace && len(namespace) == 0 {
namespace = api.NamespaceDefault
}
err = c.r.Put().Namespace(namespace).Resource("services").Name(svc.Name).Body(svc).Do().Into(result)
return return
} }
// Delete deletes an existing service. // Delete deletes an existing service.
func (c *services) Delete(name string) error { func (c *services) Delete(name string) error {
// v1beta3 does not allow DELETE without a namespace.
needNamespace := !api.PreV1Beta3(c.r.APIVersion())
namespace := c.ns
if needNamespace && len(namespace) == 0 {
namespace = api.NamespaceDefault
}
return c.r.Delete().Namespace(c.ns).Resource("services").Name(name).Do().Error() return c.r.Delete().Namespace(c.ns).Resource("services").Name(name).Do().Error()
} }

View File

@ -65,7 +65,6 @@ import (
// Config is a structure used to configure a Master. // Config is a structure used to configure a Master.
type Config struct { type Config struct {
Client *client.Client
Cloud cloudprovider.Interface Cloud cloudprovider.Interface
EtcdHelper tools.EtcdHelper EtcdHelper tools.EtcdHelper
EventTTL time.Duration EventTTL time.Duration
@ -122,7 +121,6 @@ type Config struct {
// Master contains state for a Kubernetes cluster master/api server. // Master contains state for a Kubernetes cluster master/api server.
type Master struct { type Master struct {
// "Inputs", Copied from Config // "Inputs", Copied from Config
client *client.Client
portalNet *net.IPNet portalNet *net.IPNet
cacheTimeout time.Duration cacheTimeout time.Duration
@ -262,7 +260,6 @@ func New(c *Config) *Master {
glog.V(4).Infof("Setting master service IPs based on PortalNet subnet to %q (read-only) and %q (read-write).", serviceReadOnlyIP, serviceReadWriteIP) glog.V(4).Infof("Setting master service IPs based on PortalNet subnet to %q (read-only) and %q (read-write).", serviceReadOnlyIP, serviceReadWriteIP)
m := &Master{ m := &Master{
client: c.Client,
portalNet: c.PortalNet, portalNet: c.PortalNet,
rootWebService: new(restful.WebService), rootWebService: new(restful.WebService),
enableLogsSupport: c.EnableLogsSupport, enableLogsSupport: c.EnableLogsSupport,

View File

@ -201,8 +201,7 @@ func (factory *ConfigFactory) createMinionLW() *cache.ListWatch {
// Lists all minions and filter out unhealthy ones, then returns // Lists all minions and filter out unhealthy ones, then returns
// an enumerator for cache.Poller. // an enumerator for cache.Poller.
func (factory *ConfigFactory) pollMinions() (cache.Enumerator, error) { func (factory *ConfigFactory) pollMinions() (cache.Enumerator, error) {
allNodes := &api.NodeList{} allNodes, err := factory.Client.Nodes().List()
err := factory.Client.Get().Resource("minions").Do().Into(allNodes)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -312,7 +312,6 @@ func TestAuthModeAlwaysAllow(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper, EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false, EnableLogsSupport: false,
@ -415,7 +414,6 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper, EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false, EnableLogsSupport: false,
@ -483,7 +481,6 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper, EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false, EnableLogsSupport: false,
@ -569,7 +566,6 @@ func TestBobIsForbidden(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper, EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false, EnableLogsSupport: false,
@ -631,7 +627,6 @@ func TestUnknownUserIsUnauthorized(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper, EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false, EnableLogsSupport: false,
@ -712,7 +707,6 @@ func TestNamespaceAuthorization(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper, EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false, EnableLogsSupport: false,
@ -827,7 +821,6 @@ func TestKindAuthorization(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper, EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false, EnableLogsSupport: false,
@ -930,7 +923,6 @@ func TestReadOnlyAuthorization(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper, EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false, EnableLogsSupport: false,

View File

@ -50,7 +50,6 @@ func TestClient(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper, EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false, EnableLogsSupport: false,