Victor Ryzhenkin | 14354ac | 2017-09-27 17:42:30 +0400 | [diff] [blame] | 1 | # Copyright 2017 Mirantis, Inc. |
| 2 | # |
| 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 4 | # not use this file except in compliance with the License. You may obtain |
| 5 | # a copy of the License at |
| 6 | # |
| 7 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | # |
| 9 | # Unless required by applicable law or agreed to in writing, software |
| 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 12 | # License for the specific language governing permissions and limitations |
| 13 | # under the License. |
| 14 | |
| 15 | import pytest |
Vladimir Jigulin | 34dfa94 | 2018-07-23 21:05:48 +0400 | [diff] [blame] | 16 | import netaddr |
| 17 | import os |
Victor Ryzhenkin | 14354ac | 2017-09-27 17:42:30 +0400 | [diff] [blame] | 18 | |
| 19 | from tcp_tests import logger |
| 20 | from tcp_tests import settings |
| 21 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 22 | from tcp_tests.managers.k8s import read_yaml_file |
| 23 | |
Victor Ryzhenkin | 14354ac | 2017-09-27 17:42:30 +0400 | [diff] [blame] | 24 | LOG = logger.logger |
| 25 | |
| 26 | |
| 27 | class TestMCPK8sActions(object): |
| 28 | """Test class for different k8s actions""" |
| 29 | |
Tatyana Leontovich | c411ec3 | 2017-10-09 14:48:00 +0300 | [diff] [blame] | 30 | @pytest.mark.grab_versions |
Victor Ryzhenkin | 14354ac | 2017-09-27 17:42:30 +0400 | [diff] [blame] | 31 | @pytest.mark.fail_snapshot |
Tatyana Leontovich | 071ce6a | 2017-10-24 18:08:10 +0300 | [diff] [blame] | 32 | @pytest.mark.cz8116 |
Dennis Dmitriev | 0f624a8 | 2018-06-11 12:57:13 +0300 | [diff] [blame] | 33 | @pytest.mark.k8s_calico |
Victor Ryzhenkin | 14354ac | 2017-09-27 17:42:30 +0400 | [diff] [blame] | 34 | def test_k8s_externaldns_coredns(self, show_step, config, k8s_deployed): |
| 35 | """Test externaldns integration with coredns |
| 36 | |
| 37 | Scenario: |
| 38 | 1. Install k8s with externaldns addon enabled(including etcd, coredns) |
| 39 | 2. Start simple service |
| 40 | 3. Expose deployment |
| 41 | 4. Annotate service with domain name |
| 42 | 5. Try to get service using nslookup |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 43 | 6. Delete service and deployment |
Victor Ryzhenkin | 14354ac | 2017-09-27 17:42:30 +0400 | [diff] [blame] | 44 | """ |
| 45 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 46 | show_step(1) |
Victor Ryzhenkin | 14354ac | 2017-09-27 17:42:30 +0400 | [diff] [blame] | 47 | if not (config.k8s_deploy.kubernetes_externaldns_enabled and |
| 48 | config.k8s_deploy.kubernetes_coredns_enabled): |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 49 | pytest.skip("Test requires externaldns and coredns addons enabled") |
Victor Ryzhenkin | 14354ac | 2017-09-27 17:42:30 +0400 | [diff] [blame] | 50 | |
| 51 | show_step(2) |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 52 | deployment = k8s_deployed.run_sample_deployment('test-dep') |
Victor Ryzhenkin | 14354ac | 2017-09-27 17:42:30 +0400 | [diff] [blame] | 53 | |
| 54 | show_step(3) |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 55 | svc = deployment.expose() |
Victor Ryzhenkin | 14354ac | 2017-09-27 17:42:30 +0400 | [diff] [blame] | 56 | |
Victor Ryzhenkin | 14354ac | 2017-09-27 17:42:30 +0400 | [diff] [blame] | 57 | show_step(4) |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 58 | hostname = "test.{0}.local.".format(settings.LAB_CONFIG_NAME) |
| 59 | svc.patch({ |
| 60 | "metadata": { |
| 61 | "annotations": { |
| 62 | "external-dns.alpha.kubernetes.io/hostname": hostname |
| 63 | } |
| 64 | } |
| 65 | }) |
Victor Ryzhenkin | 14354ac | 2017-09-27 17:42:30 +0400 | [diff] [blame] | 66 | |
| 67 | show_step(5) |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 68 | k8s_deployed.nslookup(hostname, svc.get_ip()) |
| 69 | |
| 70 | show_step(6) |
| 71 | deployment.delete() |
Victor Ryzhenkin | 87a3142 | 2018-03-16 22:25:27 +0400 | [diff] [blame] | 72 | |
| 73 | @pytest.mark.grab_versions |
| 74 | @pytest.mark.cncf_publisher(name=['e2e.log', 'junit_01.xml', 'version.txt', |
| 75 | 'cncf_results.tar.gz']) |
| 76 | @pytest.mark.fail_snapshot |
| 77 | def test_k8s_cncf_certification(self, show_step, config, k8s_deployed, |
Vladimir Jigulin | 0c8dd5a | 2018-08-28 05:08:35 +0400 | [diff] [blame^] | 78 | k8s_cncf_log_helper): |
Victor Ryzhenkin | 87a3142 | 2018-03-16 22:25:27 +0400 | [diff] [blame] | 79 | """Run cncf e2e suite and provide files needed for pull request |
| 80 | to the CNCF repo |
| 81 | |
| 82 | Scenario: |
| 83 | 1. Run cncf from https://github.com/cncf/k8s-conformance |
| 84 | """ |
| 85 | |
| 86 | show_step(1) |
| 87 | k8s_deployed.start_k8s_cncf_verification() |
Vladimir Jigulin | 62bcf46 | 2018-05-28 18:17:01 +0400 | [diff] [blame] | 88 | |
| 89 | @pytest.mark.grap_versions |
| 90 | @pytest.mark.fail_snapshot |
| 91 | def test_k8s_chain_update(self, show_step, underlay, config, k8s_deployed, |
| 92 | k8s_chain_update_log_helper): |
| 93 | """Test for chain-upgrading k8s hypercube pool and checking it |
| 94 | |
| 95 | Scenario: |
| 96 | 1. Prepare salt on hosts |
| 97 | 2. Setup controller nodes |
| 98 | 3. Setup compute nodes |
| 99 | 4. Setup Kubernetes cluster |
| 100 | 5. Run and expose sample test service |
| 101 | 6. Run conformance to check consistency |
| 102 | 7. For every version in update chain: |
| 103 | Update cluster to new version, check test sample service |
| 104 | availability, run conformance |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 105 | 8. Delete service and deployment |
Vladimir Jigulin | 62bcf46 | 2018-05-28 18:17:01 +0400 | [diff] [blame] | 106 | """ |
| 107 | |
Vladimir Jigulin | 62bcf46 | 2018-05-28 18:17:01 +0400 | [diff] [blame] | 108 | show_step(5) |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 109 | sample = k8s_deployed.run_sample_deployment('test-dep-chain-upgrade') |
Vladimir Jigulin | a6b018b | 2018-07-18 15:19:01 +0400 | [diff] [blame] | 110 | sample.expose() |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 111 | sample.wait_ready() |
Vladimir Jigulin | 62bcf46 | 2018-05-28 18:17:01 +0400 | [diff] [blame] | 112 | |
Vladimir Jigulin | a6b018b | 2018-07-18 15:19:01 +0400 | [diff] [blame] | 113 | assert sample.is_service_available() |
Vladimir Jigulin | 62bcf46 | 2018-05-28 18:17:01 +0400 | [diff] [blame] | 114 | |
| 115 | show_step(6) |
| 116 | k8s_deployed.run_conformance(log_out="k8s_conformance.log") |
| 117 | |
| 118 | show_step(7) |
| 119 | chain_versions = config.k8s.k8s_update_chain.split(" ") |
| 120 | for version in chain_versions: |
| 121 | LOG.info("Chain update to '{}' version".format(version)) |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 122 | k8s_deployed.update_k8s_version(version) |
Vladimir Jigulin | 62bcf46 | 2018-05-28 18:17:01 +0400 | [diff] [blame] | 123 | |
| 124 | LOG.info("Checking test service availability") |
Vladimir Jigulin | a6b018b | 2018-07-18 15:19:01 +0400 | [diff] [blame] | 125 | assert sample.is_service_available() |
Vladimir Jigulin | 62bcf46 | 2018-05-28 18:17:01 +0400 | [diff] [blame] | 126 | |
| 127 | LOG.info("Running conformance on {} version".format(version)) |
| 128 | log_name = "k8s_conformance_{}.log".format(version) |
| 129 | k8s_deployed.run_conformance(log_out=log_name, raise_on_err=False) |
Vladimir Jigulin | a6b018b | 2018-07-18 15:19:01 +0400 | [diff] [blame] | 130 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 131 | assert sample.is_service_available() |
| 132 | |
| 133 | show_step(8) |
| 134 | sample.delete() |
| 135 | |
Vladimir Jigulin | a6b018b | 2018-07-18 15:19:01 +0400 | [diff] [blame] | 136 | @pytest.mark.grap_versions |
| 137 | @pytest.mark.fail_snapshot |
| 138 | def test_k8s_metallb(self, show_step, config, k8s_deployed): |
| 139 | """Enable metallb in cluster and do basic tests |
| 140 | |
| 141 | Scenario: |
| 142 | 1. Setup Kubernetes cluster with enabled metallb |
| 143 | 2. Check that metallb pods created in metallb-system namespace |
| 144 | 3. Run 5 sample deployments |
| 145 | 4. Expose deployments with type=LoadBalancer |
| 146 | 5. Check services availability from outside of cluster |
| 147 | 6. Run conformance |
| 148 | 7. Check services availability from outside of cluster |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 149 | 8. Delete deployments |
Vladimir Jigulin | a6b018b | 2018-07-18 15:19:01 +0400 | [diff] [blame] | 150 | """ |
| 151 | show_step(1) |
| 152 | if not config.k8s_deploy.kubernetes_metallb_enabled: |
| 153 | pytest.skip("Test requires metallb addon enabled") |
| 154 | |
| 155 | show_step(2) |
Vladimir Jigulin | 34dfa94 | 2018-07-23 21:05:48 +0400 | [diff] [blame] | 156 | ns = "metallb-system" |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 157 | assert \ |
| 158 | len(k8s_deployed.api.pods.list(ns, name_prefix="controller")) > 0 |
| 159 | assert \ |
| 160 | len(k8s_deployed.api.pods.list(ns, name_prefix="speaker")) > 0 |
Vladimir Jigulin | a6b018b | 2018-07-18 15:19:01 +0400 | [diff] [blame] | 161 | |
| 162 | show_step(3) |
| 163 | samples = [] |
| 164 | for i in range(5): |
| 165 | name = 'test-dep-metallb-{}'.format(i) |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 166 | samples.append(k8s_deployed.run_sample_deployment(name)) |
Vladimir Jigulin | a6b018b | 2018-07-18 15:19:01 +0400 | [diff] [blame] | 167 | |
| 168 | show_step(4) |
| 169 | for sample in samples: |
| 170 | sample.expose('LoadBalancer') |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 171 | sample.wait_ready() |
Vladimir Jigulin | a6b018b | 2018-07-18 15:19:01 +0400 | [diff] [blame] | 172 | |
| 173 | show_step(5) |
| 174 | for sample in samples: |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 175 | assert sample.is_service_available(external=False) |
Vladimir Jigulin | a6b018b | 2018-07-18 15:19:01 +0400 | [diff] [blame] | 176 | assert sample.is_service_available(external=True) |
| 177 | |
| 178 | show_step(6) |
| 179 | k8s_deployed.run_conformance() |
| 180 | |
| 181 | show_step(7) |
| 182 | for sample in samples: |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 183 | assert sample.is_service_available(external=False) |
Vladimir Jigulin | a6b018b | 2018-07-18 15:19:01 +0400 | [diff] [blame] | 184 | assert sample.is_service_available(external=True) |
Vladimir Jigulin | 34dfa94 | 2018-07-23 21:05:48 +0400 | [diff] [blame] | 185 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 186 | show_step(8) |
| 187 | for sample in samples: |
| 188 | sample.delete() |
| 189 | |
Vladimir Jigulin | 34dfa94 | 2018-07-23 21:05:48 +0400 | [diff] [blame] | 190 | @pytest.mark.grap_versions |
| 191 | @pytest.mark.fail_snapshot |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 192 | def test_k8s_genie_flannel(self, show_step, config, |
| 193 | salt_deployed, k8s_deployed): |
Vladimir Jigulin | 34dfa94 | 2018-07-23 21:05:48 +0400 | [diff] [blame] | 194 | """Test genie-cni+flannel cni setup |
| 195 | |
| 196 | Scenario: |
| 197 | 1. Setup Kubernetes cluster with genie cni and flannel |
| 198 | 2. Check that flannel pods created in kube-system namespace |
| 199 | 3. Create sample deployment with flannel cni annotation |
| 200 | 4. Check that the deployment have 1 ip addresses from cni provider |
| 201 | 5. Create sample deployment with calico cni annotation |
| 202 | 6. Check that the deployment have 1 ip addresses from cni provider |
| 203 | 7. Create sample deployment with multi-cni annotation |
| 204 | 8. Check that the deployment have 2 ip addresses from different |
| 205 | cni providers |
| 206 | 9. Create sample deployment without cni annotation |
| 207 | 10. Check that the deployment have 1 ip address |
| 208 | 11. Check pods availability |
| 209 | 12. Run conformance |
| 210 | 13. Check pods availability |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 211 | 14. Delete pods |
Vladimir Jigulin | 34dfa94 | 2018-07-23 21:05:48 +0400 | [diff] [blame] | 212 | """ |
| 213 | show_step(1) |
| 214 | |
| 215 | # Find out calico and flannel networks |
| 216 | tgt_k8s_control = "I@kubernetes:control:enabled:True" |
| 217 | |
| 218 | flannel_pillar = salt_deployed.get_pillar( |
| 219 | tgt=tgt_k8s_control, |
| 220 | pillar="kubernetes:master:network:flannel:private_ip_range")[0] |
| 221 | flannel_network = netaddr.IPNetwork(flannel_pillar.values()[0]) |
| 222 | LOG.info("Flannel network: {}".format(flannel_network)) |
| 223 | |
| 224 | calico_network_pillar = salt_deployed.get_pillar( |
| 225 | tgt=tgt_k8s_control, pillar="_param:calico_private_network")[0] |
| 226 | calico_netmask_pillar = salt_deployed.get_pillar( |
| 227 | tgt=tgt_k8s_control, pillar="_param:calico_private_netmask")[0] |
| 228 | calico_network = netaddr.IPNetwork( |
| 229 | "{0}/{1}".format(calico_network_pillar.values()[0], |
| 230 | calico_netmask_pillar.values()[0])) |
| 231 | LOG.info("Calico network: {}".format(calico_network)) |
| 232 | |
| 233 | show_step(2) |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 234 | assert k8s_deployed.api.pods.list( |
| 235 | namespace="kube-system", name_prefix="kube-flannel-") > 0 |
Vladimir Jigulin | 34dfa94 | 2018-07-23 21:05:48 +0400 | [diff] [blame] | 236 | |
Vladimir Jigulin | 34dfa94 | 2018-07-23 21:05:48 +0400 | [diff] [blame] | 237 | show_step(3) |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 238 | data_dir = os.path.join(os.path.dirname(__file__), 'testdata/k8s') |
| 239 | flannel_pod = k8s_deployed.api.pods.create( |
| 240 | body=read_yaml_file(data_dir, 'pod-sample-flannel.yaml')) |
| 241 | flannel_pod.wait_running() |
Vladimir Jigulin | 34dfa94 | 2018-07-23 21:05:48 +0400 | [diff] [blame] | 242 | |
| 243 | show_step(4) |
| 244 | flannel_ips = k8s_deployed.get_pod_ips_from_container(flannel_pod.name) |
| 245 | assert len(flannel_ips) == 1 |
| 246 | assert netaddr.IPAddress(flannel_ips[0]) in flannel_network |
| 247 | |
| 248 | show_step(5) |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 249 | calico_pod = k8s_deployed.api.pods.create( |
| 250 | body=read_yaml_file(data_dir, 'pod-sample-calico.yaml')) |
| 251 | calico_pod.wait_running() |
Vladimir Jigulin | 34dfa94 | 2018-07-23 21:05:48 +0400 | [diff] [blame] | 252 | |
| 253 | show_step(6) |
| 254 | calico_ips = k8s_deployed.get_pod_ips_from_container(calico_pod.name) |
| 255 | assert len(calico_ips) == 1 |
| 256 | assert netaddr.IPAddress(calico_ips[0]) in calico_network |
| 257 | |
| 258 | show_step(7) |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 259 | multicni_pod = k8s_deployed.api.pods.create( |
| 260 | body=read_yaml_file(data_dir, 'pod-sample-multicni.yaml')) |
| 261 | multicni_pod.wait_running() |
Vladimir Jigulin | 34dfa94 | 2018-07-23 21:05:48 +0400 | [diff] [blame] | 262 | |
| 263 | show_step(8) |
| 264 | multicni_ips = \ |
| 265 | k8s_deployed.get_pod_ips_from_container(multicni_pod.name) |
| 266 | assert len(multicni_ips) == 2 |
| 267 | for net in [calico_network, flannel_network]: |
| 268 | assert netaddr.IPAddress(multicni_ips[0]) in net or \ |
| 269 | netaddr.IPAddress(multicni_ips[1]) in net |
| 270 | |
| 271 | show_step(9) |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 272 | nocni_pod = k8s_deployed.api.pods.create( |
| 273 | body=read_yaml_file(data_dir, 'pod-sample.yaml')) |
| 274 | nocni_pod.wait_running() |
Vladimir Jigulin | 34dfa94 | 2018-07-23 21:05:48 +0400 | [diff] [blame] | 275 | |
| 276 | show_step(10) |
| 277 | nocni_ips = k8s_deployed.get_pod_ips_from_container(nocni_pod.name) |
| 278 | assert len(nocni_ips) == 1 |
| 279 | assert (netaddr.IPAddress(nocni_ips[0]) in calico_network or |
| 280 | netaddr.IPAddress(nocni_ips[0]) in flannel_network) |
| 281 | |
| 282 | show_step(11) |
| 283 | |
| 284 | def check_pod_availability(ip): |
| 285 | assert "Hello Kubernetes!" in k8s_deployed.curl( |
| 286 | "http://{}:8080".format(ip)) |
| 287 | |
| 288 | def check_pods_availability(): |
| 289 | check_pod_availability(flannel_ips[0]) |
| 290 | check_pod_availability(calico_ips[0]) |
| 291 | check_pod_availability(multicni_ips[0]) |
| 292 | check_pod_availability(multicni_ips[1]) |
| 293 | check_pod_availability(nocni_ips[0]) |
| 294 | |
| 295 | check_pods_availability() |
| 296 | |
| 297 | show_step(12) |
| 298 | k8s_deployed.run_conformance() |
| 299 | |
| 300 | show_step(13) |
| 301 | check_pods_availability() |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 302 | |
| 303 | show_step(14) |
| 304 | flannel_pod.delete() |
| 305 | calico_pod.delete() |
| 306 | multicni_pod.delete() |
| 307 | nocni_pod.delete() |