Ejemplo n.º 1
0
func TestDeleteNamespaceWithCompleteFinalizers(t *testing.T) {
	now := util.Now()
	fakeEtcdClient, helper := newHelper(t)
	fakeEtcdClient.ChangeIndex = 1
	key := etcdtest.AddPrefix("/namespaces/foo")
	fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
		R: &etcd.Response{
			Node: &etcd.Node{
				Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{
					ObjectMeta: api.ObjectMeta{
						Name:              "foo",
						DeletionTimestamp: &now,
					},
					Spec: api.NamespaceSpec{
						Finalizers: []api.FinalizerName{},
					},
					Status: api.NamespaceStatus{Phase: api.NamespaceActive},
				}),
				ModifiedIndex: 1,
				CreatedIndex:  1,
			},
		},
	}
	storage, _, _ := NewStorage(helper)
	_, err := storage.Delete(api.NewContext(), "foo", nil)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
}
Ejemplo n.º 2
0
func TestGetEventExisting(t *testing.T) {
	// Arrange
	eventTime := util.Now()
	event := api.Event{
		Reason:  "do I exist",
		Message: "I do, oh my",
		InvolvedObject: api.ObjectReference{
			Kind:       "Pod",
			Name:       "clever.name.here",
			Namespace:  "spaceOfName",
			UID:        "D933D32AFB2A238",
			APIVersion: "version",
		},
		Source: api.EventSource{
			Component: "qinglet",
			Host:      "kublet.node4",
		},
		Count:          1,
		FirstTimestamp: eventTime,
		LastTimestamp:  eventTime,
	}
	addOrUpdateEvent(&event)

	// Act
	existingEvent := getEvent(&event)

	// Assert
	compareEventWithHistoryEntry(&event, &existingEvent, t)
}
Ejemplo n.º 3
0
func TestAddOrUpdateEventNoExisting(t *testing.T) {
	// Arrange
	eventTime := util.Now()
	event := api.Event{
		Reason:  "my reasons are many",
		Message: "my message is love",
		InvolvedObject: api.ObjectReference{
			Kind:       "Pod",
			Name:       "awesome.name",
			Namespace:  "betterNamespace",
			UID:        "C934D34AFB20242",
			APIVersion: "version",
		},
		Source: api.EventSource{
			Component: "qinglet",
			Host:      "kublet.node1",
		},
		Count:          1,
		FirstTimestamp: eventTime,
		LastTimestamp:  eventTime,
	}

	// Act
	result := addOrUpdateEvent(&event)

	// Assert
	compareEventWithHistoryEntry(&event, &result, t)
}
Ejemplo n.º 4
0
func TestNamespaceStatusStrategy(t *testing.T) {
	ctx := api.NewDefaultContext()
	if StatusStrategy.NamespaceScoped() {
		t.Errorf("Namespaces should not be namespace scoped")
	}
	if StatusStrategy.AllowCreateOnUpdate() {
		t.Errorf("Namespaces should not allow create on update")
	}
	now := util.Now()
	oldNamespace := &api.Namespace{
		ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"},
		Spec:       api.NamespaceSpec{Finalizers: []api.FinalizerName{"qingyuan"}},
		Status:     api.NamespaceStatus{Phase: api.NamespaceActive},
	}
	namespace := &api.Namespace{
		ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "9", DeletionTimestamp: &now},
		Status:     api.NamespaceStatus{Phase: api.NamespaceTerminating},
	}
	StatusStrategy.PrepareForUpdate(namespace, oldNamespace)
	if namespace.Status.Phase != api.NamespaceTerminating {
		t.Errorf("Namespace status updates should allow change of phase: %v", namespace.Status.Phase)
	}
	if len(namespace.Spec.Finalizers) != 1 || namespace.Spec.Finalizers[0] != api.FinalizerQingYuan {
		t.Errorf("PrepareForUpdate should have preserved old finalizers")
	}
	errs := StatusStrategy.ValidateUpdate(ctx, namespace, oldNamespace)
	if len(errs) != 0 {
		t.Errorf("Unexpected error %v", errs)
	}
	if namespace.ResourceVersion != "9" {
		t.Errorf("Incoming resource version on update should not be mutated")
	}
}
Ejemplo n.º 5
0
func TestAddOrUpdateEventExisting(t *testing.T) {
	// Arrange
	event1Time := util.Unix(2324, 2342)
	event2Time := util.Now()
	event1 := api.Event{
		Reason:  "something happened",
		Message: "can you believe it?",
		ObjectMeta: api.ObjectMeta{
			ResourceVersion: "rs1",
		},
		InvolvedObject: api.ObjectReference{
			Kind:       "Scheduler",
			Name:       "anOkName",
			Namespace:  "someNamespace",
			UID:        "C934D3234CD0242",
			APIVersion: "version",
		},
		Source: api.EventSource{
			Component: "qinglet",
			Host:      "kublet.node2",
		},
		Count:          1,
		FirstTimestamp: event1Time,
		LastTimestamp:  event1Time,
	}
	event2 := api.Event{
		Reason:  "something happened",
		Message: "can you believe it?",
		ObjectMeta: api.ObjectMeta{
			ResourceVersion: "rs2",
		},
		InvolvedObject: api.ObjectReference{
			Kind:       "Scheduler",
			Name:       "anOkName",
			Namespace:  "someNamespace",
			UID:        "C934D3234CD0242",
			APIVersion: "version",
		},
		Source: api.EventSource{
			Component: "qinglet",
			Host:      "kublet.node2",
		},
		Count:          3,
		FirstTimestamp: event1Time,
		LastTimestamp:  event2Time,
	}

	// Act
	addOrUpdateEvent(&event1)
	result1 := addOrUpdateEvent(&event2)
	result2 := getEvent(&event1)

	// Assert
	compareEventWithHistoryEntry(&event2, &result1, t)
	compareEventWithHistoryEntry(&event2, &result2, t)
}
Ejemplo n.º 6
0
func TestChangedStatusKeepsStartTime(t *testing.T) {
	syncer := newTestStatusManager()
	now := util.Now()
	firstStatus := getRandomPodStatus()
	firstStatus.StartTime = &now
	syncer.SetPodStatus(testPod, firstStatus)
	syncer.SetPodStatus(testPod, getRandomPodStatus())
	verifyUpdates(t, syncer, 2)
	finalStatus, _ := syncer.GetPodStatus(qingcontainer.GetPodFullName(testPod))
	if finalStatus.StartTime.IsZero() {
		t.Errorf("StartTime should not be zero")
	}
	if !finalStatus.StartTime.Time.Equal(now.Time) {
		t.Errorf("Expected %v, but got %v", now.Time, finalStatus.StartTime.Time)
	}
}
Ejemplo n.º 7
0
func TestEventList(t *testing.T) {
	ns := api.NamespaceDefault
	objReference := &api.ObjectReference{
		Kind:            "foo",
		Namespace:       ns,
		Name:            "objref1",
		UID:             "uid",
		APIVersion:      "apiv1",
		ResourceVersion: "1",
	}
	timeStamp := util.Now()
	eventList := &api.EventList{
		Items: []api.Event{
			{
				InvolvedObject: *objReference,
				FirstTimestamp: timeStamp,
				LastTimestamp:  timeStamp,
				Count:          1,
			},
		},
	}
	c := &testClient{
		Request: testRequest{
			Method: "GET",
			Path:   testapi.ResourcePath("events", ns, ""),
			Body:   nil,
		},
		Response: Response{StatusCode: 200, Body: eventList},
	}
	response, err := c.Setup().Events(ns).List(labels.Everything(),
		fields.Everything())

	if err != nil {
		t.Errorf("%#v should be nil.", err)
	}

	if len(response.Items) != 1 {
		t.Errorf("%#v response.Items should have len 1.", response.Items)
	}

	responseEvent := response.Items[0]
	if e, r := eventList.Items[0].InvolvedObject,
		responseEvent.InvolvedObject; !reflect.DeepEqual(e, r) {
		t.Errorf("%#v != %#v.", e, r)
	}
}
Ejemplo n.º 8
0
func makeEvent(ref *api.ObjectReference, reason, message string) *api.Event {
	t := util.Now()
	namespace := ref.Namespace
	if namespace == "" {
		namespace = api.NamespaceDefault
	}
	return &api.Event{
		ObjectMeta: api.ObjectMeta{
			Name:      fmt.Sprintf("%v.%x", ref.Name, t.UnixNano()),
			Namespace: namespace,
		},
		InvolvedObject: *ref,
		Reason:         reason,
		Message:        message,
		FirstTimestamp: t,
		LastTimestamp:  t,
		Count:          1,
	}
}
Ejemplo n.º 9
0
func TestNewStatusPreservesPodStartTime(t *testing.T) {
	syncer := newTestStatusManager()
	pod := &api.Pod{
		ObjectMeta: api.ObjectMeta{
			UID:       "12345678",
			Name:      "foo",
			Namespace: "new",
		},
		Status: api.PodStatus{},
	}
	now := util.Now()
	startTime := util.NewTime(now.Time.Add(-1 * time.Minute))
	pod.Status.StartTime = &startTime
	syncer.SetPodStatus(pod, getRandomPodStatus())

	status, _ := syncer.GetPodStatus(qingcontainer.GetPodFullName(pod))
	if !status.StartTime.Time.Equal(startTime.Time) {
		t.Errorf("Unexpected start time, expected %v, actual %v", startTime, status.StartTime)
	}
}
Ejemplo n.º 10
0
func (t *Tester) TestCreateResetsUserData(valid runtime.Object) {
	objectMeta, err := api.ObjectMetaFor(valid)
	if err != nil {
		t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, valid)
	}

	now := util.Now()
	objectMeta.UID = "bad-uid"
	objectMeta.CreationTimestamp = now

	obj, err := t.storage.(rest.Creater).Create(t.TestContext(), valid)
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}
	if obj == nil {
		t.Fatalf("Unexpected object from result: %#v", obj)
	}
	if objectMeta.UID == "bad-uid" || objectMeta.CreationTimestamp == now {
		t.Errorf("ObjectMeta did not reset basic fields: %#v", objectMeta)
	}
}
Ejemplo n.º 11
0
func (s *statusManager) SetPodStatus(pod *api.Pod, status api.PodStatus) {
	podFullName := qingcontainer.GetPodFullName(pod)
	s.podStatusesLock.Lock()
	defer s.podStatusesLock.Unlock()
	oldStatus, found := s.podStatuses[podFullName]

	// ensure that the start time does not change across updates.
	if found && oldStatus.StartTime != nil {
		status.StartTime = oldStatus.StartTime
	}

	// if the status has no start time, we need to set an initial time
	// TODO(yujuhong): Consider setting StartTime when generating the pod
	// status instead, which would allow statusManager to become a simple cache
	// again.
	if status.StartTime.IsZero() {
		if pod.Status.StartTime.IsZero() {
			// the pod did not have a previously recorded value so set to now
			now := util.Now()
			status.StartTime = &now
		} else {
			// the pod had a recorded value, but the qinglet restarted so we need to rebuild cache
			// based on last observed value
			status.StartTime = pod.Status.StartTime
		}
	}

	// TODO: Holding a lock during blocking operations is dangerous. Refactor so this isn't necessary.
	// The intent here is to prevent concurrent updates to a pod's status from
	// clobbering each other so the phase of a pod progresses monotonically.
	// Currently this routine is not called for the same pod from multiple
	// workers and/or the qinglet but dropping the lock before sending the
	// status down the channel feels like an easy way to get a bullet in foot.
	if !found || !isStatusEqual(&oldStatus, &status) {
		s.podStatuses[podFullName] = status
		s.podStatusChannel <- podStatusSyncRequest{pod, status}
	} else {
		glog.V(3).Infof("Ignoring same pod status for %q - old: %+v new: %+v", podFullName, oldStatus, status)
	}
}
func TestSyncNamespaceThatIsTerminating(t *testing.T) {
	mockClient := &testclient.Fake{}
	now := util.Now()
	testNamespace := api.Namespace{
		ObjectMeta: api.ObjectMeta{
			Name:              "test",
			ResourceVersion:   "1",
			DeletionTimestamp: &now,
		},
		Spec: api.NamespaceSpec{
			Finalizers: []api.FinalizerName{"qingyuan"},
		},
		Status: api.NamespaceStatus{
			Phase: api.NamespaceTerminating,
		},
	}
	err := syncNamespace(mockClient, testNamespace)
	if err != nil {
		t.Errorf("Unexpected error when synching namespace %v", err)
	}
	// TODO: Reuse the constants for all these strings from testclient
	expectedActionSet := util.NewStringSet(
		testclient.ListControllerAction,
		"list-services",
		"list-pods",
		"list-resourceQuotas",
		"list-secrets",
		"list-limitRanges",
		"list-events",
		"finalize-namespace",
		"delete-namespace")
	actionSet := util.NewStringSet()
	for i := range mockClient.Actions {
		actionSet.Insert(mockClient.Actions[i].Action)
	}
	if !actionSet.HasAll(expectedActionSet.List()...) {
		t.Errorf("Expected actions: %v, but got: %v", expectedActionSet, actionSet)
	}
}
Ejemplo n.º 13
0
func TestEventGet(t *testing.T) {
	objReference := &api.ObjectReference{
		Kind:            "foo",
		Namespace:       "nm",
		Name:            "objref1",
		UID:             "uid",
		APIVersion:      "apiv1",
		ResourceVersion: "1",
	}
	timeStamp := util.Now()
	event := &api.Event{
		ObjectMeta: api.ObjectMeta{
			Namespace: "other",
		},
		InvolvedObject: *objReference,
		FirstTimestamp: timeStamp,
		LastTimestamp:  timeStamp,
		Count:          1,
	}
	c := &testClient{
		Request: testRequest{
			Method: "GET",
			Path:   testapi.ResourcePath("events", "other", "1"),
			Body:   nil,
		},
		Response: Response{StatusCode: 200, Body: event},
	}

	response, err := c.Setup().Events("other").Get("1")

	if err != nil {
		t.Fatalf("%v should be nil.", err)
	}

	if e, r := event.InvolvedObject, response.InvolvedObject; !reflect.DeepEqual(e, r) {
		t.Errorf("%#v != %#v.", e, r)
	}
}
Ejemplo n.º 14
0
// Delete enforces life-cycle rules for namespace termination
func (r *REST) Delete(ctx api.Context, name string, options *api.DeleteOptions) (runtime.Object, error) {
	nsObj, err := r.Get(ctx, name)
	if err != nil {
		return nil, err
	}

	namespace := nsObj.(*api.Namespace)

	// upon first request to delete, we switch the phase to start namespace termination
	if namespace.DeletionTimestamp.IsZero() {
		now := util.Now()
		namespace.DeletionTimestamp = &now
		namespace.Status.Phase = api.NamespaceTerminating
		result, _, err := r.status.Update(ctx, namespace)
		return result, err
	}

	// prior to final deletion, we must ensure that finalizers is empty
	if len(namespace.Spec.Finalizers) != 0 {
		err = apierrors.NewConflict("Namespace", namespace.Name, fmt.Errorf("The system is ensuring all content is removed from this namespace.  Upon completion, this namespace will automatically be purged by the system."))
		return nil, err
	}
	return r.Etcd.Delete(ctx, name, nil)
}
Ejemplo n.º 15
0
// FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta.
func FillObjectMetaSystemFields(ctx Context, meta *ObjectMeta) {
	meta.CreationTimestamp = util.Now()
	meta.UID = util.NewUUID()
	meta.SelfLink = ""
}
Ejemplo n.º 16
0
				createTimes := make(map[string]util.Time, 0)
				nodes := make(map[string]string, 0)
				scheduleTimes := make(map[string]util.Time, 0)
				runTimes := make(map[string]util.Time, 0)
				watchTimes := make(map[string]util.Time, 0)

				var mutex sync.Mutex
				checkPod := func(p *api.Pod) {
					mutex.Lock()
					defer mutex.Unlock()
					defer GinkgoRecover()

					if p.Status.Phase == api.PodRunning {
						if _, found := watchTimes[p.Name]; !found {
							watchTimes[p.Name] = util.Now()
							createTimes[p.Name] = p.CreationTimestamp
							nodes[p.Name] = p.Spec.NodeName
							var startTime util.Time
							for _, cs := range p.Status.ContainerStatuses {
								if cs.State.Running != nil {
									if startTime.Before(cs.State.Running.StartedAt) {
										startTime = cs.State.Running.StartedAt
									}
								}
							}
							if startTime != util.NewTime(time.Time{}) {
								runTimes[p.Name] = startTime
							} else {
								Failf("Pod %v is reported to be running, but none of its containers is", p.Name)
							}
Ejemplo n.º 17
0
func (f fakeRecorder) Event(object runtime.Object, reason, message string) {
	f.events = append(f.events, fakeEvent{object, util.Now(), reason, message})
}
Ejemplo n.º 18
0
func (f fakeRecorder) Eventf(object runtime.Object, reason, messageFmt string, args ...interface{}) {
	f.events = append(f.events, fakeEvent{object, util.Now(), reason, fmt.Sprintf(messageFmt, args...)})
}
Ejemplo n.º 19
0
func (recorder *recorderImpl) Event(object runtime.Object, reason, message string) {
	recorder.generateEvent(object, util.Now(), reason, message)
}