Skip to content

Commit

Permalink
Merge pull request #6 from claudiubelu/adds-integration-test
Browse files Browse the repository at this point in the history
Adds integration test
  • Loading branch information
bschimke95 authored Jul 19, 2024
2 parents b4f3780 + b30f8bb commit 10ee462
Show file tree
Hide file tree
Showing 5 changed files with 308 additions and 1 deletion.
5 changes: 5 additions & 0 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#
# Copyright 2024 Canonical, Ltd.
#

pytest_plugins = ["k8s_test_harness.plugin"]
139 changes: 139 additions & 0 deletions tests/integration/test_velero.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#
# Copyright 2024 Canonical, Ltd.
#
import logging
import uuid
from pathlib import Path

from k8s_test_harness import harness
from k8s_test_harness.util import env_util, k8s_util

LOG = logging.getLogger(__name__)

DIR = Path(__file__).absolute().parent
MANIFESTS_DIR = DIR / ".." / "templates"


def _get_velero_helm_cmd():
velero_rock = env_util.get_build_meta_info_for_rock_version(
"velero", "1.13.2", "amd64"
)
kubectl_rock = env_util.get_build_meta_info_for_rock_version(
"kubectl", "1.30.2", "amd64"
)
images = [
k8s_util.HelmImage(velero_rock.image),
k8s_util.HelmImage(kubectl_rock.image, "kubectl"),
]

credentials = """
[default]
aws_access_key_id = minio
aws_secret_access_key = minio123
"""
minio_url = "http://minio.velero.svc:9000"

set_configs = [
f"credentials.secretContents.cloud={credentials}",
"configuration.backupStorageLocation[0].provider=aws",
"configuration.backupStorageLocation[0].bucket=velero",
"configuration.backupStorageLocation[0].config.region=minio",
"configuration.backupStorageLocation[0].config.s3ForcePathStyle=true",
f"configuration.backupStorageLocation[0].config.s3Url={minio_url}",
"snapshotsEnabled=false",
"initContainers[0].name=velero-plugin-for-aws",
"initContainers[0].image=velero/velero-plugin-for-aws:v1.2.1",
"initContainers[0].volumeMounts[0].mountPath=/target",
"initContainers[0].volumeMounts[0].name=plugins",
]

return k8s_util.get_helm_install_command(
"velero",
"velero",
namespace="velero",
repository="https://vmware-tanzu.github.io/helm-charts",
images=images,
set_configs=set_configs,
)


def _exec_velero_cmd(instance, deployment_name, namespace, *cmd):
instance.exec(
[
"k8s",
"kubectl",
"exec",
"-ti",
"--namespace",
namespace,
f"deployment.apps/{deployment_name}",
"--",
"/velero",
*cmd,
]
)


def test_integration_velero(module_instance: harness.Instance):
# Setup Minio first, which is an S3-compatible storage service. We'll use
# it to test out Velero's functionality with it.
manifest = MANIFESTS_DIR / "minio-deployment.yaml"
module_instance.exec(
["k8s", "kubectl", "apply", "-f", "-"],
input=Path(manifest).read_bytes(),
)

k8s_util.wait_for_deployment(module_instance, "minio", "velero")

# Deploy Velero rock.
module_instance.exec(_get_velero_helm_cmd())
k8s_util.wait_for_deployment(module_instance, "velero", "velero")

# Deploy an nginx app which we'll back up.
manifest = MANIFESTS_DIR / "nginx-deployment.yaml"
module_instance.exec(
["k8s", "kubectl", "apply", "-f", "-"],
input=Path(manifest).read_bytes(),
)

k8s_util.wait_for_deployment(module_instance, "nginx-deployment", "nginx-example")

# Back the nginx app.
backup_name = f"nginx-backup-{uuid.uuid4()}"
_exec_velero_cmd(
module_instance,
"velero",
"velero",
"backup",
"create",
backup_name,
"--selector",
"app=nginx",
)

# Delete the nginx app, we should be able to restore it.
module_instance.exec(
[
"k8s",
"kubectl",
"delete",
"--wait",
"namespace",
"nginx-example",
"--timeout",
"60s",
]
)

# Restore it, and expect it to become available.
_exec_velero_cmd(
module_instance,
"velero",
"velero",
"restore",
"create",
"--from-backup",
backup_name,
)

k8s_util.wait_for_deployment(module_instance, "nginx-deployment", "nginx-example")
104 changes: 104 additions & 0 deletions tests/templates/minio-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
##
## Copyright 2024 Canonical, Ltd.
## See LICENSE file for licensing details
##

---
apiVersion: v1
kind: Namespace
metadata:
name: velero

---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: velero
name: minio
labels:
component: minio
spec:
strategy:
type: Recreate
selector:
matchLabels:
component: minio
template:
metadata:
labels:
component: minio
spec:
volumes:
- name: storage
emptyDir: {}
- name: config
emptyDir: {}
containers:
- name: minio
image: minio/minio:latest
imagePullPolicy: IfNotPresent
args:
- server
- /storage
- --config-dir=/config
env:
- name: MINIO_ACCESS_KEY
value: "minio"
- name: MINIO_SECRET_KEY
value: "minio123"
ports:
- containerPort: 9000
volumeMounts:
- name: storage
mountPath: "/storage"
- name: config
mountPath: "/config"

---
apiVersion: v1
kind: Service
metadata:
namespace: velero
name: minio
labels:
component: minio
spec:
# ClusterIP is recommended for production environments.
# Change to NodePort if needed per documentation,
# but only if you run Minio in a test/trial environment, for example with Minikube.
type: ClusterIP
ports:
- port: 9000
targetPort: 9000
protocol: TCP
selector:
component: minio

---
apiVersion: batch/v1
kind: Job
metadata:
namespace: velero
name: minio-setup
labels:
component: minio
spec:
template:
metadata:
name: minio-setup
spec:
restartPolicy: OnFailure
volumes:
- name: config
emptyDir: {}
containers:
- name: mc
image: minio/mc:latest
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- "mc --config-dir=/config config host add velero http://minio:9000 minio minio123 && mc --config-dir=/config mb -p velero/velero"
volumeMounts:
- name: config
mountPath: "/config"
52 changes: 52 additions & 0 deletions tests/templates/nginx-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
##
## Copyright 2024 Canonical, Ltd.
## See LICENSE file for licensing details
##

---
apiVersion: v1
kind: Namespace
metadata:
name: nginx-example
labels:
app: nginx

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: nginx-example
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.17.6
name: nginx
ports:
- containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: my-nginx
namespace: nginx-example
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx
type: LoadBalancer
9 changes: 8 additions & 1 deletion tests/tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,17 @@ pass_env =
description = Run integration tests
deps = -r {tox_root}/requirements-test.txt
commands =
echo "WARNING: This is a placeholder test - no test is implemented here."
pytest -v \
--maxfail 1 \
--tb native \
--log-cli-level DEBUG \
--disable-warnings \
{posargs} \
{tox_root}/integration
pass_env =
TEST_*
ROCK_*
BUILT_ROCKS_METADATA

[flake8]
max-line-length = 120
Expand Down

0 comments on commit 10ee462

Please sign in to comment.