mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			205 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
Copyright 2019 The Kubernetes Authors.
 | 
						|
 | 
						|
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 endpoint
 | 
						|
 | 
						|
import (
 | 
						|
	"runtime"
 | 
						|
	"testing"
 | 
						|
	"time"
 | 
						|
 | 
						|
	v1 "k8s.io/api/core/v1"
 | 
						|
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						|
	"k8s.io/apimachinery/pkg/util/intstr"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	t0 = time.Date(2019, 01, 01, 0, 0, 0, 0, time.UTC)
 | 
						|
	t1 = t0.Add(time.Second)
 | 
						|
	t2 = t1.Add(time.Second)
 | 
						|
	t3 = t2.Add(time.Second)
 | 
						|
	t4 = t3.Add(time.Second)
 | 
						|
	t5 = t4.Add(time.Second)
 | 
						|
 | 
						|
	ttNamespace   = "ttNamespace1"
 | 
						|
	ttServiceName = "my-service"
 | 
						|
)
 | 
						|
 | 
						|
func TestNewServiceNoPods(t *testing.T) {
 | 
						|
	tester := newTester(t)
 | 
						|
 | 
						|
	service := createService(ttNamespace, ttServiceName, t2)
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service).expect(t2)
 | 
						|
}
 | 
						|
 | 
						|
func TestNewServiceExistingPods(t *testing.T) {
 | 
						|
	tester := newTester(t)
 | 
						|
 | 
						|
	service := createService(ttNamespace, ttServiceName, t3)
 | 
						|
	pod1 := createPod(ttNamespace, "pod1", t0)
 | 
						|
	pod2 := createPod(ttNamespace, "pod2", t1)
 | 
						|
	pod3 := createPod(ttNamespace, "pod3", t5)
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service, pod1, pod2, pod3).
 | 
						|
		// Pods were created before service, but trigger time is the time when service was created.
 | 
						|
		expect(t3)
 | 
						|
}
 | 
						|
 | 
						|
func TestPodsAdded(t *testing.T) {
 | 
						|
	tester := newTester(t)
 | 
						|
 | 
						|
	service := createService(ttNamespace, ttServiceName, t0)
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service).expect(t0)
 | 
						|
 | 
						|
	pod1 := createPod(ttNamespace, "pod1", t2)
 | 
						|
	pod2 := createPod(ttNamespace, "pod2", t1)
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service, pod1, pod2).expect(t1)
 | 
						|
}
 | 
						|
 | 
						|
func TestPodsUpdated(t *testing.T) {
 | 
						|
	tester := newTester(t)
 | 
						|
 | 
						|
	service := createService(ttNamespace, ttServiceName, t0)
 | 
						|
	pod1 := createPod(ttNamespace, "pod1", t1)
 | 
						|
	pod2 := createPod(ttNamespace, "pod2", t2)
 | 
						|
	pod3 := createPod(ttNamespace, "pod3", t3)
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service, pod1, pod2, pod3).expect(t0)
 | 
						|
 | 
						|
	pod1 = createPod(ttNamespace, "pod1", t5)
 | 
						|
	pod2 = createPod(ttNamespace, "pod2", t4)
 | 
						|
	// pod3 doesn't change.
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service, pod1, pod2, pod3).expect(t4)
 | 
						|
}
 | 
						|
 | 
						|
func TestPodsUpdatedNoOp(t *testing.T) {
 | 
						|
	tester := newTester(t)
 | 
						|
 | 
						|
	service := createService(ttNamespace, ttServiceName, t0)
 | 
						|
	pod1 := createPod(ttNamespace, "pod1", t1)
 | 
						|
	pod2 := createPod(ttNamespace, "pod2", t2)
 | 
						|
	pod3 := createPod(ttNamespace, "pod3", t3)
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service, pod1, pod2, pod3).expect(t0)
 | 
						|
 | 
						|
	// Nothing has changed.
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service, pod1, pod2, pod3).expectNil()
 | 
						|
}
 | 
						|
 | 
						|
func TestPodDeletedThenAdded(t *testing.T) {
 | 
						|
	tester := newTester(t)
 | 
						|
 | 
						|
	service := createService(ttNamespace, ttServiceName, t0)
 | 
						|
	pod1 := createPod(ttNamespace, "pod1", t1)
 | 
						|
	pod2 := createPod(ttNamespace, "pod2", t2)
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service, pod1, pod2).expect(t0)
 | 
						|
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service, pod1).expectNil()
 | 
						|
 | 
						|
	pod2 = createPod(ttNamespace, "pod2", t4)
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service, pod1, pod2).expect(t4)
 | 
						|
}
 | 
						|
 | 
						|
func TestServiceDeletedThenAdded(t *testing.T) {
 | 
						|
	tester := newTester(t)
 | 
						|
 | 
						|
	service := createService(ttNamespace, ttServiceName, t0)
 | 
						|
	pod1 := createPod(ttNamespace, "pod1", t1)
 | 
						|
	pod2 := createPod(ttNamespace, "pod2", t2)
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service, pod1, pod2).expect(t0)
 | 
						|
 | 
						|
	tester.DeleteService(ttNamespace, ttServiceName)
 | 
						|
 | 
						|
	service = createService(ttNamespace, ttServiceName, t3)
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service, pod1, pod2).expect(t3)
 | 
						|
}
 | 
						|
 | 
						|
func TestServiceUpdatedNoPodChange(t *testing.T) {
 | 
						|
	tester := newTester(t)
 | 
						|
 | 
						|
	service := createService(ttNamespace, ttServiceName, t0)
 | 
						|
	pod1 := createPod(ttNamespace, "pod1", t1)
 | 
						|
	pod2 := createPod(ttNamespace, "pod2", t2)
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service, pod1, pod2).expect(t0)
 | 
						|
 | 
						|
	// service's ports have changed.
 | 
						|
	service.Spec = v1.ServiceSpec{
 | 
						|
		Selector: map[string]string{},
 | 
						|
		Ports:    []v1.ServicePort{{Port: 80, TargetPort: intstr.FromInt(8080), Protocol: "TCP"}},
 | 
						|
	}
 | 
						|
 | 
						|
	// Currently we're not able to calculate trigger time for service updates, hence the returned
 | 
						|
	// value is a nil time.
 | 
						|
	tester.whenComputeEndpointLastChangeTriggerTime(ttNamespace, service, pod1, pod2).expectNil()
 | 
						|
}
 | 
						|
 | 
						|
// ------- Test Utils -------
 | 
						|
 | 
						|
type tester struct {
 | 
						|
	*TriggerTimeTracker
 | 
						|
	t *testing.T
 | 
						|
}
 | 
						|
 | 
						|
func newTester(t *testing.T) *tester {
 | 
						|
	return &tester{NewTriggerTimeTracker(), t}
 | 
						|
}
 | 
						|
 | 
						|
func (t *tester) whenComputeEndpointLastChangeTriggerTime(
 | 
						|
	namespace string, service *v1.Service, pods ...*v1.Pod) subject {
 | 
						|
	return subject{t.ComputeEndpointLastChangeTriggerTime(namespace, service, pods), t.t}
 | 
						|
}
 | 
						|
 | 
						|
type subject struct {
 | 
						|
	got time.Time
 | 
						|
	t   *testing.T
 | 
						|
}
 | 
						|
 | 
						|
func (s subject) expect(expected time.Time) {
 | 
						|
	s.doExpect(expected)
 | 
						|
}
 | 
						|
 | 
						|
func (s subject) expectNil() {
 | 
						|
	s.doExpect(time.Time{})
 | 
						|
}
 | 
						|
 | 
						|
func (s subject) doExpect(expected time.Time) {
 | 
						|
	if s.got != expected {
 | 
						|
		_, fn, line, _ := runtime.Caller(2)
 | 
						|
		s.t.Errorf("Wrong trigger time in %s:%d expected %s, got %s", fn, line, expected, s.got)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func createPod(namespace, ttServiceName string, readyTime time.Time) *v1.Pod {
 | 
						|
	return &v1.Pod{
 | 
						|
		ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: ttServiceName},
 | 
						|
		Status: v1.PodStatus{Conditions: []v1.PodCondition{
 | 
						|
			{
 | 
						|
				Type:               v1.PodReady,
 | 
						|
				Status:             v1.ConditionTrue,
 | 
						|
				LastTransitionTime: metav1.NewTime(readyTime),
 | 
						|
			},
 | 
						|
		},
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func createService(namespace, ttServiceName string, creationTime time.Time) *v1.Service {
 | 
						|
	return &v1.Service{
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Namespace:         namespace,
 | 
						|
			Name:              ttServiceName,
 | 
						|
			CreationTimestamp: metav1.NewTime(creationTime),
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 |