github.com/AliyunContainerService/cli@v0.0.0-20181009023821-814ced4b30d0/cli/command/stack/kubernetes/conversion_test.go (about) 1 package kubernetes 2 3 import ( 4 "testing" 5 6 "github.com/docker/cli/cli/command/formatter" 7 "github.com/docker/cli/kubernetes/labels" 8 "github.com/docker/docker/api/types/swarm" 9 "gotest.tools/assert" 10 appsv1beta2 "k8s.io/api/apps/v1beta2" 11 apiv1 "k8s.io/api/core/v1" 12 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 13 apimachineryTypes "k8s.io/apimachinery/pkg/types" 14 apimachineryUtil "k8s.io/apimachinery/pkg/util/intstr" 15 ) 16 17 func TestReplicasConversionNeedsAService(t *testing.T) { 18 replicas := appsv1beta2.ReplicaSetList{ 19 Items: []appsv1beta2.ReplicaSet{makeReplicaSet("unknown", 0, 0)}, 20 } 21 services := apiv1.ServiceList{} 22 _, _, err := convertToServices(&replicas, &appsv1beta2.DaemonSetList{}, &services) 23 assert.ErrorContains(t, err, "could not find service") 24 } 25 26 func TestKubernetesServiceToSwarmServiceConversion(t *testing.T) { 27 testCases := []struct { 28 replicas *appsv1beta2.ReplicaSetList 29 services *apiv1.ServiceList 30 expectedServices []swarm.Service 31 expectedListInfo map[string]formatter.ServiceListInfo 32 }{ 33 // Match replicas with headless stack services 34 { 35 &appsv1beta2.ReplicaSetList{ 36 Items: []appsv1beta2.ReplicaSet{ 37 makeReplicaSet("service1", 2, 5), 38 makeReplicaSet("service2", 3, 3), 39 }, 40 }, 41 &apiv1.ServiceList{ 42 Items: []apiv1.Service{ 43 makeKubeService("service1", "stack", "uid1", apiv1.ServiceTypeClusterIP, nil), 44 makeKubeService("service2", "stack", "uid2", apiv1.ServiceTypeClusterIP, nil), 45 makeKubeService("service3", "other-stack", "uid2", apiv1.ServiceTypeClusterIP, nil), 46 }, 47 }, 48 []swarm.Service{ 49 makeSwarmService("stack_service1", "uid1", nil), 50 makeSwarmService("stack_service2", "uid2", nil), 51 }, 52 map[string]formatter.ServiceListInfo{ 53 "uid1": {Mode: "replicated", Replicas: "2/5"}, 54 "uid2": {Mode: "replicated", Replicas: "3/3"}, 55 }, 56 }, 57 // Headless service and LoadBalancer Service are tied to the same Swarm service 58 { 59 &appsv1beta2.ReplicaSetList{ 60 Items: []appsv1beta2.ReplicaSet{ 61 makeReplicaSet("service", 1, 1), 62 }, 63 }, 64 &apiv1.ServiceList{ 65 Items: []apiv1.Service{ 66 makeKubeService("service", "stack", "uid1", apiv1.ServiceTypeClusterIP, nil), 67 makeKubeService("service-published", "stack", "uid2", apiv1.ServiceTypeLoadBalancer, []apiv1.ServicePort{ 68 { 69 Port: 80, 70 TargetPort: apimachineryUtil.FromInt(80), 71 Protocol: apiv1.ProtocolTCP, 72 }, 73 }), 74 }, 75 }, 76 []swarm.Service{ 77 makeSwarmService("stack_service", "uid1", []swarm.PortConfig{ 78 { 79 PublishMode: swarm.PortConfigPublishModeIngress, 80 PublishedPort: 80, 81 TargetPort: 80, 82 Protocol: swarm.PortConfigProtocolTCP, 83 }, 84 }), 85 }, 86 map[string]formatter.ServiceListInfo{ 87 "uid1": {Mode: "replicated", Replicas: "1/1"}, 88 }, 89 }, 90 // Headless service and NodePort Service are tied to the same Swarm service 91 92 { 93 &appsv1beta2.ReplicaSetList{ 94 Items: []appsv1beta2.ReplicaSet{ 95 makeReplicaSet("service", 1, 1), 96 }, 97 }, 98 &apiv1.ServiceList{ 99 Items: []apiv1.Service{ 100 makeKubeService("service", "stack", "uid1", apiv1.ServiceTypeClusterIP, nil), 101 makeKubeService("service-random-ports", "stack", "uid2", apiv1.ServiceTypeNodePort, []apiv1.ServicePort{ 102 { 103 Port: 35666, 104 TargetPort: apimachineryUtil.FromInt(80), 105 Protocol: apiv1.ProtocolTCP, 106 }, 107 }), 108 }, 109 }, 110 []swarm.Service{ 111 makeSwarmService("stack_service", "uid1", []swarm.PortConfig{ 112 { 113 PublishMode: swarm.PortConfigPublishModeHost, 114 PublishedPort: 35666, 115 TargetPort: 80, 116 Protocol: swarm.PortConfigProtocolTCP, 117 }, 118 }), 119 }, 120 map[string]formatter.ServiceListInfo{ 121 "uid1": {Mode: "replicated", Replicas: "1/1"}, 122 }, 123 }, 124 } 125 126 for _, tc := range testCases { 127 swarmServices, listInfo, err := convertToServices(tc.replicas, &appsv1beta2.DaemonSetList{}, tc.services) 128 assert.NilError(t, err) 129 assert.DeepEqual(t, tc.expectedServices, swarmServices) 130 assert.DeepEqual(t, tc.expectedListInfo, listInfo) 131 } 132 } 133 134 func makeReplicaSet(service string, available, replicas int32) appsv1beta2.ReplicaSet { 135 return appsv1beta2.ReplicaSet{ 136 ObjectMeta: metav1.ObjectMeta{ 137 Labels: map[string]string{ 138 labels.ForServiceName: service, 139 }, 140 }, 141 Spec: appsv1beta2.ReplicaSetSpec{ 142 Template: apiv1.PodTemplateSpec{ 143 Spec: apiv1.PodSpec{ 144 Containers: []apiv1.Container{ 145 { 146 Image: "image", 147 }, 148 }, 149 }, 150 }, 151 }, 152 Status: appsv1beta2.ReplicaSetStatus{ 153 AvailableReplicas: available, 154 Replicas: replicas, 155 }, 156 } 157 } 158 159 func makeKubeService(service, stack, uid string, serviceType apiv1.ServiceType, ports []apiv1.ServicePort) apiv1.Service { 160 return apiv1.Service{ 161 ObjectMeta: metav1.ObjectMeta{ 162 Labels: map[string]string{ 163 labels.ForStackName: stack, 164 }, 165 Name: service, 166 UID: apimachineryTypes.UID(uid), 167 }, 168 Spec: apiv1.ServiceSpec{ 169 Type: serviceType, 170 Ports: ports, 171 }, 172 } 173 } 174 175 func makeSwarmService(service, id string, ports []swarm.PortConfig) swarm.Service { 176 return swarm.Service{ 177 ID: id, 178 Spec: swarm.ServiceSpec{ 179 Annotations: swarm.Annotations{ 180 Name: service, 181 }, 182 TaskTemplate: swarm.TaskSpec{ 183 ContainerSpec: &swarm.ContainerSpec{ 184 Image: "image", 185 }, 186 }, 187 }, 188 Endpoint: swarm.Endpoint{ 189 Ports: ports, 190 }, 191 } 192 }