Skip to content

Commit

Permalink
Add simple smoke test
Browse files Browse the repository at this point in the history
  • Loading branch information
foriequal0 committed Aug 2, 2024
1 parent b6ce9c8 commit 2c56e59
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 2 deletions.
20 changes: 18 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
kind_image:
- "v1.30.0"
Expand Down Expand Up @@ -71,13 +72,26 @@ jobs:

smoke-test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
kind_image:
- "v1.30.0"
- "v1.29.4"
- "v1.28.9"
- "v1.27.13"
env:
KIND_IMAGE: kindest/node:${{matrix.kind_image}}
needs:
- build-image
steps:
- uses: actions/checkout@v4
- uses: helm/[email protected]
- name: Setup kind
run: |
kind create cluster --image="$KIND_IMAGE"
- uses: eifinger/setup-rye@v4
with:
cluster_name: kind
version: '0.37.0'
- uses: actions/download-artifact@v4
with:
name: pod-graceful-drain.tar
Expand All @@ -91,6 +105,8 @@ jobs:
--set experimentalGeneralIngress=true \
--set logLevel=info\\,pod_graceful_drain=trace \
--wait=true --timeout=1m
- run: rye sync
- run: rye test
- name: Dump
if: always()
run: |
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
.venv/
*.egg-info/
__pycache__/

target/

.idea/
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.12.3
16 changes: 16 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[project]
name = "pod-graceful-drain-integ-test"
version = "0.1.0"
description = "Integration test for pod-graceful-drain"
authors = [
{ name = "SeongChan Lee", email = "[email protected]" }
]
dependencies = []
readme = "README.md"
requires-python = ">= 3.8"

[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.3.1",
]
20 changes: 20 additions & 0 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# generated by rye
# use `rye lock` or `rye sync` to update this lockfile
#
# last locked with the following flags:
# pre: false
# features: []
# all-features: false
# with-sources: false
# generate-hashes: false

-e file:.
colorama==0.4.6
# via pytest
iniconfig==2.0.0
# via pytest
packaging==24.1
# via pytest
pluggy==1.5.0
# via pytest
pytest==8.3.1
11 changes: 11 additions & 0 deletions requirements.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# generated by rye
# use `rye lock` or `rye sync` to update this lockfile
#
# last locked with the following flags:
# pre: false
# features: []
# all-features: false
# with-sources: false
# generate-hashes: false

-e file:.
119 changes: 119 additions & 0 deletions tests/test_smoke.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import subprocess
import sys
from datetime import datetime, timedelta
import random
import time

namespace = ""


def setup_module():
global namespace
namespace = f"pgd-test-{random.randrange(10000, 99999)}"
kubectl("create", "namespace", namespace)
kubectl("label", "namespace", namespace, "test=true")
print("testing on namespace: ", namespace)


def teardown_module():
global namespace
kubectl("delete", "namespace", namespace)


def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)


def kubectl(*args):
global namespace

result = subprocess.run(
["kubectl", "--namespace", namespace, *args],
capture_output=True)

if result.returncode != 0:
eprint("stdout:")
eprint(result.stdout)
eprint("stderr:")
eprint(result.stderr)
raise Exception(f"'kubectl {" ".join(args)}' failed with exit code '{result.returncode}'")


def kubectl_stdin(args, /, input):
global namespace

result = subprocess.run(
["kubectl", "--namespace", namespace, *args],
capture_output=True,
input=input, encoding="utf-8")

if result.returncode != 0:
eprint("stdout:")
eprint(result.stdout)
eprint("stderr:")
eprint(result.stderr)
raise Exception(f"'kubectl {" ".join(args)}' failed with exit code '{result.returncode}'")


def kubectl_nowait(args):
global namespace

child = subprocess.Popen(
["kubectl", "--namespace", namespace, *args])

return child


def pod_is_alive(name):
global namespace

result = subprocess.run(
["kubectl", "--namespace", namespace, "get", name, "-o", "jsonpath={.metadata.deletionTimestamp}"],
capture_output=True, encoding="utf-8")

if result.returncode != 0:
return False

stdout = result.stdout.strip()
return not stdout


def test_can_delete_pod_without_delay_if_no_ingress():
kubectl("run", "busybox-sleep", "--image=public.ecr.aws/docker/library/busybox", "--", "sleep", "1000")
kubectl("wait", "pod/busybox-sleep", "--for=condition=Ready")
start = datetime.now()
kubectl("delete", "pod/busybox-sleep", "--wait=false")
diff = datetime.now() - start
assert diff < timedelta(seconds=10), "it should be quick"
assert not pod_is_alive("pod/busybox-sleep")


def test_delete_is_delayed_with_ingress():
kubectl("run", "nginx", "--image=nginx")
kubectl("expose", "pod", "nginx", "--port=80", "--target-port=8000")
kubectl_stdin(["apply", "-f", "-"], input="""
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
""")
kubectl("wait", "pod/nginx", "--for=condition=Ready")

time.sleep(1) # give some time to settle down

kubectl_nowait(["delete", "pod/nginx", "--wait=false"])

for _ in range(0, 20 - 5):
assert pod_is_alive("pod/nginx"), "pod should be alive for approx. 20s"
time.sleep(1)

0 comments on commit 2c56e59

Please sign in to comment.