Beispiel #1
0
func NewTestGenericEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, *Etcd) {
	f := tools.NewFakeEtcdClient(t)
	f.TestIndex = true
	s := etcdstorage.NewEtcdStorage(f, testapi.Default.Codec(), etcdtest.PathPrefix())
	strategy := &testRESTStrategy{api.Scheme, api.SimpleNameGenerator, true, false, true}
	podPrefix := "/pods"
	return f, &Etcd{
		NewFunc:        func() runtime.Object { return &api.Pod{} },
		NewListFunc:    func() runtime.Object { return &api.PodList{} },
		EndpointName:   "pods",
		CreateStrategy: strategy,
		UpdateStrategy: strategy,
		KeyRootFunc: func(ctx api.Context) string {
			return podPrefix
		},
		KeyFunc: func(ctx api.Context, id string) (string, error) {
			if _, ok := api.NamespaceFrom(ctx); !ok {
				return "", fmt.Errorf("namespace is required")
			}
			return path.Join(podPrefix, id), nil
		},
		ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.Pod).Name, nil },
		Storage:        s,
	}
}
Beispiel #2
0
func initThirdParty(t *testing.T, version string) (*Master, *tools.FakeEtcdClient, *httptest.Server, *assert.Assertions) {
	master, _, assert := setUp(t)
	master.thirdPartyResources = map[string]*thirdpartyresourcedatastorage.REST{}
	api := &extensions.ThirdPartyResource{
		ObjectMeta: api.ObjectMeta{
			Name: "foo.company.com",
		},
		Versions: []extensions.APIVersion{
			{
				APIGroup: "group",
				Name:     version,
			},
		},
	}
	master.handlerContainer = restful.NewContainer()

	fakeClient := tools.NewFakeEtcdClient(t)
	fakeClient.Machines = []string{"http://machine1:4001", "http://machine2", "http://machine3:4003"}
	master.thirdPartyStorage = etcdstorage.NewEtcdStorage(fakeClient, testapi.Extensions.Codec(), etcdtest.PathPrefix())

	if !assert.NoError(master.InstallThirdPartyResource(api)) {
		t.FailNow()
	}

	server := httptest.NewServer(master.handlerContainer.ServeMux)
	return &master, fakeClient, server, assert
}
Beispiel #3
0
// NewEtcdStorage returns a storage.Interface for the provided arguments or an error if the version
// is incorrect.
func NewEtcdStorage(client tools.EtcdClient, interfacesFunc meta.VersionInterfacesFunc, version, prefix string) (etcdStorage storage.Interface, err error) {
	versionInterfaces, err := interfacesFunc(version)
	if err != nil {
		return etcdStorage, err
	}
	return etcdstorage.NewEtcdStorage(client, versionInterfaces.Codec, prefix), nil
}
Beispiel #4
0
// setUp is a convience function for setting up for (most) tests.
func setUp(t *testing.T) (Master, Config, *assert.Assertions) {
	master := Master{}
	config := Config{}
	fakeClient := tools.NewFakeEtcdClient(t)
	fakeClient.Machines = []string{"http://machine1:4001", "http://machine2", "http://machine3:4003"}
	storageVersions := make(map[string]string)
	storageDestinations := NewStorageDestinations()
	storageDestinations.AddAPIGroup("", etcdstorage.NewEtcdStorage(fakeClient, testapi.Default.Codec(), etcdtest.PathPrefix()))
	storageDestinations.AddAPIGroup("extensions", etcdstorage.NewEtcdStorage(fakeClient, testapi.Extensions.Codec(), etcdtest.PathPrefix()))
	config.StorageDestinations = storageDestinations
	storageVersions[""] = testapi.Default.Version()
	storageVersions["extensions"] = testapi.Extensions.GroupAndVersion()
	config.StorageVersions = storageVersions
	master.nodeRegistry = registrytest.NewNodeRegistry([]string{"node1", "node2"}, api.NodeResources{})

	return master, config, assert.New(t)
}
Beispiel #5
0
func TestWatch(t *testing.T) {
	client := framework.NewEtcdClient()
	etcdStorage := etcd.NewEtcdStorage(client, testapi.Default.Codec(), etcdtest.PathPrefix())
	framework.WithEtcdKey(func(key string) {
		key = etcdtest.AddPrefix(key)
		resp, err := client.Set(key, runtime.EncodeOrDie(testapi.Default.Codec(), &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		expectedVersion := resp.Node.ModifiedIndex

		// watch should load the object at the current index
		w, err := etcdStorage.Watch(key, 0, storage.Everything)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}

		event := <-w.ResultChan()
		if event.Type != watch.Added || event.Object == nil {
			t.Fatalf("expected first value to be set to ADDED, got %#v", event)
		}

		// version should match what we set
		pod := event.Object.(*api.Pod)
		if pod.ResourceVersion != strconv.FormatUint(expectedVersion, 10) {
			t.Errorf("expected version %d, got %#v", expectedVersion, pod)
		}

		// should be no events in the stream
		select {
		case event, ok := <-w.ResultChan():
			if !ok {
				t.Fatalf("channel closed unexpectedly")
			}
			t.Fatalf("unexpected object in channel: %#v", event)
		default:
		}

		// should return the previously deleted item in the watch, but with the latest index
		resp, err = client.Delete(key, false)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		expectedVersion = resp.Node.ModifiedIndex
		event = <-w.ResultChan()
		if event.Type != watch.Deleted {
			t.Errorf("expected deleted event %#v", event)
		}
		pod = event.Object.(*api.Pod)
		if pod.ResourceVersion != strconv.FormatUint(expectedVersion, 10) {
			t.Errorf("expected version %d, got %#v", expectedVersion, pod)
		}
	})
}
Beispiel #6
0
func TestWriteTTL(t *testing.T) {
	client := framework.NewEtcdClient()
	etcdStorage := etcd.NewEtcdStorage(client, testapi.Default.Codec(), "")
	framework.WithEtcdKey(func(key string) {
		testObject := api.ServiceAccount{ObjectMeta: api.ObjectMeta{Name: "foo"}}
		if err := etcdStorage.Set(key, &testObject, nil, 0); err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		result := &api.ServiceAccount{}
		err := etcdStorage.GuaranteedUpdate(key, result, false, func(obj runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) {
			if in, ok := obj.(*api.ServiceAccount); !ok || in.Name != "foo" {
				t.Fatalf("unexpected existing object: %v", obj)
			}
			if res.TTL != 0 {
				t.Fatalf("unexpected TTL: %#v", res)
			}
			ttl := uint64(10)
			out := &api.ServiceAccount{ObjectMeta: api.ObjectMeta{Name: "out"}}
			return out, &ttl, nil
		})
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		if result.Name != "out" {
			t.Errorf("unexpected response: %#v", result)
		}
		if res, err := client.Get(key, false, false); err != nil || res == nil || res.Node.TTL != 10 {
			t.Fatalf("unexpected get: %v %#v", err, res)
		}

		result = &api.ServiceAccount{}
		err = etcdStorage.GuaranteedUpdate(key, result, false, func(obj runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) {
			if in, ok := obj.(*api.ServiceAccount); !ok || in.Name != "out" {
				t.Fatalf("unexpected existing object: %v", obj)
			}
			if res.TTL <= 1 {
				t.Fatalf("unexpected TTL: %#v", res)
			}
			out := &api.ServiceAccount{ObjectMeta: api.ObjectMeta{Name: "out2"}}
			return out, nil, nil
		})
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		if result.Name != "out2" {
			t.Errorf("unexpected response: %#v", result)
		}
		if res, err := client.Get(key, false, false); err != nil || res == nil || res.Node.TTL <= 1 {
			t.Fatalf("unexpected get: %v %#v", err, res)
		}
	})
}
Beispiel #7
0
func newTestCacher(client tools.EtcdClient) *storage.Cacher {
	prefix := "pods"
	config := storage.CacherConfig{
		CacheCapacity:  10,
		Versioner:      etcdstorage.APIObjectVersioner{},
		Storage:        etcdstorage.NewEtcdStorage(client, testapi.Default.Codec(), etcdtest.PathPrefix()),
		Type:           &api.Pod{},
		ResourcePrefix: prefix,
		KeyFunc:        func(obj runtime.Object) (string, error) { return storage.NamespaceKeyFunc(prefix, obj) },
		NewListFunc:    func() runtime.Object { return &api.PodList{} },
		StopChannel:    util.NeverStop,
	}
	return storage.NewCacher(config)
}
Beispiel #8
0
func TestSet(t *testing.T) {
	client := framework.NewEtcdClient()
	etcdStorage := etcd.NewEtcdStorage(client, testapi.Default.Codec(), "")
	framework.WithEtcdKey(func(key string) {
		testObject := api.ServiceAccount{ObjectMeta: api.ObjectMeta{Name: "foo"}}
		if err := etcdStorage.Set(key, &testObject, nil, 0); err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		resp, err := client.Get(key, false, false)
		if err != nil || resp.Node == nil {
			t.Fatalf("unexpected error: %v %v", err, resp)
		}
		decoded, err := testapi.Default.Codec().Decode([]byte(resp.Node.Value))
		if err != nil {
			t.Fatalf("unexpected response: %#v", resp.Node)
		}
		result := *decoded.(*api.ServiceAccount)
		if !api.Semantic.DeepEqual(testObject, result) {
			t.Errorf("expected: %#v got: %#v", testObject, result)
		}
	})
}
Beispiel #9
0
func TestGet(t *testing.T) {
	client := framework.NewEtcdClient()
	etcdStorage := etcd.NewEtcdStorage(client, testapi.Default.Codec(), "")
	framework.WithEtcdKey(func(key string) {
		testObject := api.ServiceAccount{ObjectMeta: api.ObjectMeta{Name: "foo"}}
		coded, err := testapi.Default.Codec().Encode(&testObject)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		_, err = client.Set(key, string(coded), 0)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		result := api.ServiceAccount{}
		if err := etcdStorage.Get(key, &result, false); err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		// Propagate ResourceVersion (it is set automatically).
		testObject.ObjectMeta.ResourceVersion = result.ObjectMeta.ResourceVersion
		if !api.Semantic.DeepEqual(testObject, result) {
			t.Errorf("expected: %#v got: %#v", testObject, result)
		}
	})
}
Beispiel #10
0
func NewEtcdStorage(t *testing.T, group string) (storage.Interface, *tools.FakeEtcdClient) {
	fakeClient := tools.NewFakeEtcdClient(t)
	fakeClient.TestIndex = true
	etcdStorage := etcdstorage.NewEtcdStorage(fakeClient, testapi.Groups[group].Codec(), etcdtest.PathPrefix())
	return etcdStorage, fakeClient
}