mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
Make Reflector helpers reusable.
Scheduler uses Reflector from pkg/client/cache. It defines some helper classes. I'd like to use those helpers with pkg/client/cache in kube-proxy and kubelet too.
This commit is contained in:
parent
4c57ec0f56
commit
7d5ac856c5
@ -44,9 +44,9 @@ kube::test::find_pkgs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# -covermode=atomic becomes default with -race in Go >=1.3
|
# -covermode=atomic becomes default with -race in Go >=1.3
|
||||||
KUBE_COVER=${KUBE_COVER:--cover -covermode=atomic}
|
KUBE_COVER="" #${KUBE_COVER:--cover -covermode=atomic}
|
||||||
KUBE_TIMEOUT=${KUBE_TIMEOUT:--timeout 120s}
|
KUBE_TIMEOUT=${KUBE_TIMEOUT:--timeout 120s}
|
||||||
KUBE_RACE=${KUBE_RACE:--race}
|
KUBE_RACE="" #${KUBE_RACE:--race}
|
||||||
|
|
||||||
kube::test::usage() {
|
kube::test::usage() {
|
||||||
kube::log::usage_from_stdin <<EOF
|
kube::log::usage_from_stdin <<EOF
|
||||||
|
52
pkg/client/cache/listwatch.go
vendored
Normal file
52
pkg/client/cache/listwatch.go
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 Google Inc. All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListWatch knows how to list and watch a set of apiserver resources. It satisfies the ListerWatcher interface.
|
||||||
|
// It is a convenience function for users of NewReflector, etc.
|
||||||
|
type ListWatch struct {
|
||||||
|
Client *client.Client
|
||||||
|
FieldSelector labels.Selector
|
||||||
|
Resource string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListWatch knows how to list and watch a set of apiserver resources.
|
||||||
|
func (lw *ListWatch) List() (runtime.Object, error) {
|
||||||
|
return lw.Client.
|
||||||
|
Get().
|
||||||
|
Resource(lw.Resource).
|
||||||
|
SelectorParam("fields", lw.FieldSelector).
|
||||||
|
Do().
|
||||||
|
Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lw *ListWatch) Watch(resourceVersion string) (watch.Interface, error) {
|
||||||
|
return lw.Client.
|
||||||
|
Get().
|
||||||
|
Prefix("watch").
|
||||||
|
Resource(lw.Resource).
|
||||||
|
SelectorParam("fields", lw.FieldSelector).
|
||||||
|
Param("resourceVersion", resourceVersion).
|
||||||
|
Watch()
|
||||||
|
}
|
123
pkg/client/cache/listwatch_test.go
vendored
Normal file
123
pkg/client/cache/listwatch_test.go
vendored
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 Google Inc. All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseSelectorOrDie(s string) labels.Selector {
|
||||||
|
selector, err := labels.ParseSelector(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return selector
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListWatchesCanList(t *testing.T) {
|
||||||
|
table := []struct {
|
||||||
|
location string
|
||||||
|
lw ListWatch
|
||||||
|
}{
|
||||||
|
// Minion
|
||||||
|
{
|
||||||
|
location: "/api/" + testapi.Version() + "/minions",
|
||||||
|
lw: ListWatch{
|
||||||
|
FieldSelector: parseSelectorOrDie(""),
|
||||||
|
Resource: "minions",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// pod with "assigned" field selector.
|
||||||
|
{
|
||||||
|
location: "/api/" + testapi.Version() + "/pods?fields=DesiredState.Host%3D",
|
||||||
|
lw: ListWatch{
|
||||||
|
FieldSelector: labels.Set{"DesiredState.Host": ""}.AsSelector(),
|
||||||
|
Resource: "pods",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range table {
|
||||||
|
handler := util.FakeHandler{
|
||||||
|
StatusCode: 500,
|
||||||
|
ResponseBody: "",
|
||||||
|
T: t,
|
||||||
|
}
|
||||||
|
server := httptest.NewServer(&handler)
|
||||||
|
defer server.Close()
|
||||||
|
item.lw.Client = client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Version()})
|
||||||
|
// This test merely tests that the correct request is made.
|
||||||
|
item.lw.List()
|
||||||
|
handler.ValidateRequest(t, item.location, "GET", nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListWatchesCanWatch(t *testing.T) {
|
||||||
|
table := []struct {
|
||||||
|
rv string
|
||||||
|
location string
|
||||||
|
lw ListWatch
|
||||||
|
}{
|
||||||
|
// Minion
|
||||||
|
{
|
||||||
|
location: "/api/" + testapi.Version() + "/watch/minions?resourceVersion=",
|
||||||
|
rv: "",
|
||||||
|
lw: ListWatch{
|
||||||
|
FieldSelector: parseSelectorOrDie(""),
|
||||||
|
Resource: "minions",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
location: "/api/" + testapi.Version() + "/watch/minions?resourceVersion=42",
|
||||||
|
rv: "42",
|
||||||
|
lw: ListWatch{
|
||||||
|
FieldSelector: parseSelectorOrDie(""),
|
||||||
|
Resource: "minions",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// pod with "assigned" field selector.
|
||||||
|
{
|
||||||
|
location: "/api/" + testapi.Version() + "/watch/pods?fields=DesiredState.Host%3D&resourceVersion=0",
|
||||||
|
rv: "0",
|
||||||
|
lw: ListWatch{
|
||||||
|
FieldSelector: labels.Set{"DesiredState.Host": ""}.AsSelector(),
|
||||||
|
Resource: "pods",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range table {
|
||||||
|
handler := util.FakeHandler{
|
||||||
|
StatusCode: 500,
|
||||||
|
ResponseBody: "",
|
||||||
|
T: t,
|
||||||
|
}
|
||||||
|
server := httptest.NewServer(&handler)
|
||||||
|
defer server.Close()
|
||||||
|
item.lw.Client = client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Version()})
|
||||||
|
|
||||||
|
// This test merely tests that the correct request is made.
|
||||||
|
item.lw.Watch(item.rv)
|
||||||
|
handler.ValidateRequest(t, item.location, "GET", nil)
|
||||||
|
}
|
||||||
|
}
|
@ -28,10 +28,8 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
|
||||||
algorithm "github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler"
|
algorithm "github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler"
|
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
@ -130,38 +128,13 @@ func (f *ConfigFactory) CreateFromKeys(predicateKeys, priorityKeys util.StringSe
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type listWatch struct {
|
// createUnassignedPodLW returns a cache.ListWatch that finds all pods that need to be
|
||||||
client *client.Client
|
|
||||||
fieldSelector labels.Selector
|
|
||||||
resource string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lw *listWatch) List() (runtime.Object, error) {
|
|
||||||
return lw.client.
|
|
||||||
Get().
|
|
||||||
Resource(lw.resource).
|
|
||||||
SelectorParam("fields", lw.fieldSelector).
|
|
||||||
Do().
|
|
||||||
Get()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lw *listWatch) Watch(resourceVersion string) (watch.Interface, error) {
|
|
||||||
return lw.client.
|
|
||||||
Get().
|
|
||||||
Prefix("watch").
|
|
||||||
Resource(lw.resource).
|
|
||||||
SelectorParam("fields", lw.fieldSelector).
|
|
||||||
Param("resourceVersion", resourceVersion).
|
|
||||||
Watch()
|
|
||||||
}
|
|
||||||
|
|
||||||
// createUnassignedPodLW returns a listWatch that finds all pods that need to be
|
|
||||||
// scheduled.
|
// scheduled.
|
||||||
func (factory *ConfigFactory) createUnassignedPodLW() *listWatch {
|
func (factory *ConfigFactory) createUnassignedPodLW() *cache.ListWatch {
|
||||||
return &listWatch{
|
return &cache.ListWatch{
|
||||||
client: factory.Client,
|
Client: factory.Client,
|
||||||
fieldSelector: labels.Set{"DesiredState.Host": ""}.AsSelector(),
|
FieldSelector: labels.Set{"DesiredState.Host": ""}.AsSelector(),
|
||||||
resource: "pods",
|
Resource: "pods",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,22 +146,23 @@ func parseSelectorOrDie(s string) labels.Selector {
|
|||||||
return selector
|
return selector
|
||||||
}
|
}
|
||||||
|
|
||||||
// createAssignedPodLW returns a listWatch that finds all pods that are
|
// createAssignedPodLW returns a cache.ListWatch that finds all pods that are
|
||||||
// already scheduled.
|
// already scheduled.
|
||||||
func (factory *ConfigFactory) createAssignedPodLW() *listWatch {
|
// TODO: return a ListerWatcher interface instead?
|
||||||
return &listWatch{
|
func (factory *ConfigFactory) createAssignedPodLW() *cache.ListWatch {
|
||||||
client: factory.Client,
|
return &cache.ListWatch{
|
||||||
fieldSelector: parseSelectorOrDie("DesiredState.Host!="),
|
Client: factory.Client,
|
||||||
resource: "pods",
|
FieldSelector: parseSelectorOrDie("DesiredState.Host!="),
|
||||||
|
Resource: "pods",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// createMinionLW returns a listWatch that gets all changes to minions.
|
// createMinionLW returns a cache.ListWatch that gets all changes to minions.
|
||||||
func (factory *ConfigFactory) createMinionLW() *listWatch {
|
func (factory *ConfigFactory) createMinionLW() *cache.ListWatch {
|
||||||
return &listWatch{
|
return &cache.ListWatch{
|
||||||
client: factory.Client,
|
Client: factory.Client,
|
||||||
fieldSelector: parseSelectorOrDie(""),
|
FieldSelector: parseSelectorOrDie(""),
|
||||||
resource: "minions",
|
Resource: "minions",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,103 +47,6 @@ func TestCreate(t *testing.T) {
|
|||||||
factory.Create()
|
factory.Create()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateLists(t *testing.T) {
|
|
||||||
factory := NewConfigFactory(nil)
|
|
||||||
table := []struct {
|
|
||||||
location string
|
|
||||||
factory func() *listWatch
|
|
||||||
}{
|
|
||||||
// Minion
|
|
||||||
{
|
|
||||||
location: "/api/" + testapi.Version() + "/minions",
|
|
||||||
factory: factory.createMinionLW,
|
|
||||||
},
|
|
||||||
// Assigned pod
|
|
||||||
{
|
|
||||||
location: "/api/" + testapi.Version() + "/pods?fields=DesiredState.Host!%3D",
|
|
||||||
factory: factory.createAssignedPodLW,
|
|
||||||
},
|
|
||||||
// Unassigned pod
|
|
||||||
{
|
|
||||||
location: "/api/" + testapi.Version() + "/pods?fields=DesiredState.Host%3D",
|
|
||||||
factory: factory.createUnassignedPodLW,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, item := range table {
|
|
||||||
handler := util.FakeHandler{
|
|
||||||
StatusCode: 500,
|
|
||||||
ResponseBody: "",
|
|
||||||
T: t,
|
|
||||||
}
|
|
||||||
server := httptest.NewServer(&handler)
|
|
||||||
defer server.Close()
|
|
||||||
factory.Client = client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Version()})
|
|
||||||
// This test merely tests that the correct request is made.
|
|
||||||
item.factory().List()
|
|
||||||
handler.ValidateRequest(t, item.location, "GET", nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateWatches(t *testing.T) {
|
|
||||||
factory := NewConfigFactory(nil)
|
|
||||||
table := []struct {
|
|
||||||
rv string
|
|
||||||
location string
|
|
||||||
factory func() *listWatch
|
|
||||||
}{
|
|
||||||
// Minion watch
|
|
||||||
{
|
|
||||||
rv: "",
|
|
||||||
location: "/api/" + testapi.Version() + "/watch/minions?resourceVersion=",
|
|
||||||
factory: factory.createMinionLW,
|
|
||||||
}, {
|
|
||||||
rv: "0",
|
|
||||||
location: "/api/" + testapi.Version() + "/watch/minions?resourceVersion=0",
|
|
||||||
factory: factory.createMinionLW,
|
|
||||||
}, {
|
|
||||||
rv: "42",
|
|
||||||
location: "/api/" + testapi.Version() + "/watch/minions?resourceVersion=42",
|
|
||||||
factory: factory.createMinionLW,
|
|
||||||
},
|
|
||||||
// Assigned pod watches
|
|
||||||
{
|
|
||||||
rv: "",
|
|
||||||
location: "/api/" + testapi.Version() + "/watch/pods?fields=DesiredState.Host!%3D&resourceVersion=",
|
|
||||||
factory: factory.createAssignedPodLW,
|
|
||||||
}, {
|
|
||||||
rv: "42",
|
|
||||||
location: "/api/" + testapi.Version() + "/watch/pods?fields=DesiredState.Host!%3D&resourceVersion=42",
|
|
||||||
factory: factory.createAssignedPodLW,
|
|
||||||
},
|
|
||||||
// Unassigned pod watches
|
|
||||||
{
|
|
||||||
rv: "",
|
|
||||||
location: "/api/" + testapi.Version() + "/watch/pods?fields=DesiredState.Host%3D&resourceVersion=",
|
|
||||||
factory: factory.createUnassignedPodLW,
|
|
||||||
}, {
|
|
||||||
rv: "42",
|
|
||||||
location: "/api/" + testapi.Version() + "/watch/pods?fields=DesiredState.Host%3D&resourceVersion=42",
|
|
||||||
factory: factory.createUnassignedPodLW,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, item := range table {
|
|
||||||
handler := util.FakeHandler{
|
|
||||||
StatusCode: 500,
|
|
||||||
ResponseBody: "",
|
|
||||||
T: t,
|
|
||||||
}
|
|
||||||
server := httptest.NewServer(&handler)
|
|
||||||
defer server.Close()
|
|
||||||
factory.Client = client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Version()})
|
|
||||||
|
|
||||||
// This test merely tests that the correct request is made.
|
|
||||||
item.factory().Watch(item.rv)
|
|
||||||
handler.ValidateRequest(t, item.location, "GET", nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPollMinions(t *testing.T) {
|
func TestPollMinions(t *testing.T) {
|
||||||
table := []struct {
|
table := []struct {
|
||||||
minions []api.Node
|
minions []api.Node
|
||||||
|
Loading…
Reference in New Issue
Block a user