Skip to content

Commit 34db298

Browse files
authored
k8 deploy test (#40)
1 parent d531f73 commit 34db298

7 files changed

Lines changed: 224 additions & 166 deletions

File tree

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: K8S Deploy Test
2+
3+
on:
4+
pull_request:
5+
branches: '*'
6+
push:
7+
branches: '*'
8+
9+
jobs:
10+
test:
11+
name: "Run k8s deploy test suite"
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: "Clone project repository"
15+
uses: actions/checkout@v3
16+
- name: "Install Python"
17+
uses: actions/setup-python@v4
18+
with:
19+
python-version: '3.10'
20+
- name: "Print Python version"
21+
run: python3 --version
22+
- name: "Install shiv"
23+
run: pip install shiv
24+
- name: "Generate build version file"
25+
run: ./scripts/create_build_tag_file.sh
26+
- name: "Build local shiv package"
27+
run: ./scripts/build_shiv_package.sh
28+
- name: "Run k8s deploy tests"
29+
run: ./tests/k8s-deploy/run-deploy-test.sh

src/stack/data/build_tag.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# This file should be re-generated running: scripts/create_build_tag_file.sh script
2+
2.0.0-d531f73-202505011750

src/stack/deploy/deployment_create.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,14 +281,14 @@ def init_operation( # noqa: C901
281281
):
282282
default_spec_file_content = call_stack_deploy_init(deploy_command_context)
283283
spec_file_content = {"stack": stack, constants.deploy_to_key: deployer_type}
284-
if deployer_type == "k8s":
284+
if deployer_type in ["k8s", "k8s-kind"]:
285285
if kube_config:
286286
spec_file_content.update({constants.kube_config_key: kube_config})
287-
else:
287+
elif deployer_type == "k8s":
288288
error_exit("--kube-config must be supplied with --deploy-to k8s")
289289
if image_registry:
290290
spec_file_content.update({constants.image_registry_key: image_registry})
291-
else:
291+
elif deployer_type == "k8s":
292292
print("WARNING: --image-registry not specified, only default container registries (eg, Docker Hub) will be available")
293293
if k8s_http_proxy:
294294
proxy_hosts = {host for _, host, _, _ in map(_parse_http_proxy, k8s_http_proxy)}
@@ -343,7 +343,7 @@ def init_operation( # noqa: C901
343343
spec_file_content.update({"config": merged_config})
344344

345345
if not map_ports_to_host:
346-
if deployer_type == "k8s":
346+
if deployer_type in ["k8s", "k8s-kind"]:
347347
map_ports_to_host = "k8s-clusterip-same"
348348
elif deployer_type == "compose":
349349
map_ports_to_host = "any-variable-random"
@@ -364,6 +364,7 @@ def init_operation( # noqa: C901
364364
matched = False
365365
for svc in ports:
366366
for svc_port in ports[svc]:
367+
svc_port = svc_port.split(":")[-1].replace("/udp", "")
367368
if f"{svc}:{svc_port}" == target:
368369
matched = True
369370
break

src/stack/deploy/k8s/cluster_info.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,8 @@ def get_services(self):
178178
for service_name in services:
179179
service_info = services[service_name]
180180
if "ports" in service_info:
181-
svc_ports = [
182-
client.V1ServicePort(port=int(p), target_port=int(p), name=f"{service_name}-{p}")
183-
for p in service_info["ports"]
184-
]
181+
int_ports = [int(p.split(":")[-1].replace("/udp", "")) for p in service_info["ports"]]
182+
svc_ports = [client.V1ServicePort(port=p, target_port=p, name=f"{service_name}-{p}") for p in int_ports]
185183
service = client.V1Service(
186184
metadata=client.V1ObjectMeta(
187185
name=f"{self.app_name}-svc-{service_name}",

src/stack/deploy/k8s/helpers.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@
2424
from ruamel.yaml.comments import CommentedSeq
2525
from typing import Set, Mapping, List
2626

27-
from stack.util import get_k8s_dir, error_exit
28-
from stack.opts import opts
27+
from stack.build.build_util import container_exists_locally
2928
from stack.deploy.deploy_util import parsed_pod_files_map_from_file_names
3029
from stack.deploy.deployer import DeployerException
30+
from stack.opts import opts
31+
from stack.util import get_k8s_dir, error_exit
3132

3233

3334
DEFAULT_K8S_NAMESPACE = "default"
@@ -83,6 +84,10 @@ def install_ingress_for_kind():
8384

8485
def load_images_into_kind(kind_cluster_name: str, image_set: Set[str]):
8586
for image in image_set:
87+
if not container_exists_locally(image):
88+
result = _shell_command(f"docker pull {image}")
89+
if result.returncode != 0:
90+
raise DeployerException(f"kind create cluster failed: {result}")
8691
result = _shell_command(f"kind load docker-image {image} --name {kind_cluster_name}")
8792
if result.returncode != 0:
8893
raise DeployerException(f"kind create cluster failed: {result}")

tests/deploy/run-deploy-test.sh

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,73 @@ env
99

1010
delete_cluster_exit () {
1111
$TEST_TARGET_SO manage --dir $test_deployment_dir stop --delete-volumes
12-
exit 1
1312
}
1413

14+
trap delete_cluster_exit EXIT
15+
16+
add_todo() {
17+
set +e
18+
19+
local running=0
20+
local check=0
21+
local check_limit=10
22+
23+
url=$1
24+
title=$2
25+
26+
try=0
27+
rc=1
28+
29+
while [ $rc -ne 0 ] && [ $try -lt 10 ]; do
30+
try=$((try + 1))
31+
curl "$url" \
32+
--fail-with-body \
33+
-H 'Accept: application/json, text/plain, */*' \
34+
-H 'Accept-Language: en-US,en;q=0.9' \
35+
-H 'Connection: keep-alive' \
36+
-H 'Content-Type: application/json' \
37+
-H 'Origin: http://localhost' \
38+
-H 'Referer: http://localhost/' \
39+
-H 'Sec-Fetch-Dest: empty' \
40+
-H 'Sec-Fetch-Mode: cors' \
41+
-H 'Sec-Fetch-Site: same-site' \
42+
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0' \
43+
-H 'sec-ch-ua: "Microsoft Edge";v="135", "Not-A.Brand";v="8", "Chromium";v="135"' \
44+
-H 'sec-ch-ua-mobile: ?0' \
45+
-H 'sec-ch-ua-platform: "Windows"' \
46+
--data-raw "{\"title\":\"$title\",\"completed\":false}"
47+
rc=$?
48+
49+
if [ $rc -ne 0 ]; then
50+
echo "Error adding todo, retrying..."
51+
sleep 5
52+
fi
53+
done
54+
55+
set -e
56+
57+
return $rc
58+
}
59+
60+
1561
wait_for_running () {
1662
# Check that all services are running
63+
local how_many=$1
1764
local running=0
1865
local check=0
1966
local check_limit=10
20-
while [ $running -lt 3 ] && [ $check -lt $check_limit ]; do
67+
while [ $running -lt $how_many ] && [ $check -lt $check_limit ]; do
2168
check=$((check + 1))
22-
running=$($TEST_TARGET_SO manage --dir $test_deployment_dir status | grep -c "running")
23-
if [ $running -lt 3 ]; then
69+
running=$($TEST_TARGET_SO manage --dir $test_deployment_dir status | grep -ic "running")
70+
if [ $running -lt $how_many ]; then
2471
echo "deploy manage start: Waiting for services to start..."
2572
sleep 5
2673
fi
2774
done
2875

29-
if [ $running -lt 3 ]; then
76+
if [ $running -lt $how_many ]; then
3077
echo "deploy manage start: failed - not all services started"
31-
delete_cluster_exit
78+
exit 1
3279
fi
3380
}
3481

@@ -79,34 +126,16 @@ echo "deploy create test: passed"
79126

80127
# Start
81128
$TEST_TARGET_SO manage --dir $test_deployment_dir start
82-
wait_for_running
129+
wait_for_running 3
83130

84131
# Add a todo
85132
todo_title="79b06705-b402-431a-83a3-a634392d2754"
86-
curl 'http://localhost:5000/api/todos' \
87-
-H 'Accept: application/json, text/plain, */*' \
88-
-H 'Accept-Language: en-US,en;q=0.9' \
89-
-H 'Connection: keep-alive' \
90-
-H 'Content-Type: application/json' \
91-
-H 'Origin: http://localhost:3000' \
92-
-H 'Referer: http://localhost:3000/' \
93-
-H 'Sec-Fetch-Dest: empty' \
94-
-H 'Sec-Fetch-Mode: cors' \
95-
-H 'Sec-Fetch-Site: same-site' \
96-
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0' \
97-
-H 'sec-ch-ua: "Microsoft Edge";v="135", "Not-A.Brand";v="8", "Chromium";v="135"' \
98-
-H 'sec-ch-ua-mobile: ?0' \
99-
-H 'sec-ch-ua-platform: "Windows"' \
100-
--data-raw "{\"title\":\"$todo_title\",\"completed\":false}"
101-
if [ $? -ne 0 ]; then
102-
echo "deploy storage: failed - todo $todo_title not added"
103-
delete_cluster_exit
104-
fi
133+
add_todo http://localhost:5000/api/todos "$todo_title"
105134

106135
# Check that it exists
107136
if [ "$todo_title" != "$(curl -s http://localhost:5000/api/todos | jq -r '.[] | select(.id == 1) | .title')" ]; then
108137
echo "deploy storage: failed - todo $todo_title not found"
109-
delete_cluster_exit
138+
exit 1
110139
fi
111140

112141
# Stop the stack (don't delete volumes)
@@ -116,18 +145,19 @@ $TEST_TARGET_SO manage --dir $test_deployment_dir stop
116145
$TEST_TARGET_SO manage --dir $test_deployment_dir start
117146

118147
# Check that all services are running
119-
wait_for_running
148+
wait_for_running 3
120149

121150
# Check that it is still viewable
122151
if [ "$todo_title" != "$(curl -s http://localhost:5000/api/todos | jq -r '.[] | select(.id == 1) | .title')" ]; then
123152
echo "deploy storage: failed - todo $todo_title not found after restart"
124-
delete_cluster_exit
153+
exit 1
125154
fi
126155
echo "deploy storage: passed"
127156

128157
# TODO: Do we need to add a check for deleting the volumes?
129158
# Docker doesn't remove the files for a bound volume so nothing much really changes.
130159

131-
# Stop and clean up
132-
$TEST_TARGET_SO manage --dir $test_deployment_dir stop --delete-volumes
160+
wget -q -O - http://localhost:3000 | grep 'bundle.js'
161+
echo "deploy http: passed"
162+
133163
echo "Test passed"

0 commit comments

Comments
 (0)