Article écrit par Nicolas Desombre
Squash est une suite d’outils pour concevoir, automatiser, exécuter et industrialiser vos tests. Basée sur un socle open source, la solution est modulable et facilement intégrable.
Contexte
Étant déjà utilisateur de Squash TM pour la gestion de nos tests manuels, nous souhaitions désormais passer à la vitesse supérieure avec le test automatisé.
Nous souhaitions également profiter de cette occasion, pour migrer notre instance de Squash sur une infrastructure plus moderne. En effet, cette instance avait été historiquement déployée, de façon traditionnelle, sur une VM avec une base de donnée MySQL.
Place à présent à un déploiement sur Kubernetes et à une base de donnée PostgreSQL. Nous ne nous attarderons pas sur la transition MySQL → PostgreSQL, ce type de migration étant déjà largement documenté sur internet.
Le déploiement de la stack complète Squash TM / Squash Orchestrator / OpenTestFactory sur Kubernetes mérite en revanche ces quelques lignes, qui, je pense, pourront sans doute être utiles à d’autre.
Anatomie de la stack
Squash TM
Squash TM est une application full web de gestion de patrimoine de test qui permet notamment de :
- Organiser, planifier et exécuter vos tests manuels avec une traçabilité complète, des exigences aux anomalies*.
- Piloter l’ensemble des phases de votre processus de test.
- Simplifier votre flux de travail en interfaçant Squash TM et Jira et/ou GitLab.
Pour faire plus simple, il s’agit de l’interface web qui est utilisée de A à Z par les utilisateurs de la solution.
D’un point de vue technique, c’est une application en Java.
Squash Orchestrator
Squash AUTOM est un ensemble d’outils et de micro-services, pilotés depuis Squash TM, permettant de coordonner l’exécution des tests automatisés sur le(s) environnement(s) d’exécution(s). Il s’appuie pour cela sur le projet OpenTestFactory.
Squash Orchestrator est fourni sous forme d’une image Docker “all-in-one” et disponible en version gratuite ou Premium.
Environnement d’exécution Robot Framework
Il s’agit d’un environnement Linux/Python dans lequel sont exécutés les tests automatisés à l’aide des outils suivants :
- Robot Framework
- Les navigateurs Google Chrome/Mozilla Firefox ainsi que les drivers associés.
- Agent OpenTestFactory
Déploiement
Squash TM
Ce service est proposé sous forme d‘un tarball installable sur une VM Windows/Linux, d’une image Docker prête à l’emploi sur le Dockerhub et d’un Dockerfile.
C’est vers la dernière option que nous allons nous diriger, nous ne pouvons utiliser l’image Docker prête à l’emploi, car nous avons besoin d’y ajouter quelques plugins, pour pouvoir faire du test automatisé :
- Result publisher
- Git connector
- Squash AUTOM
- Test plan retriever
Nous allons donc récupérer le DockerFile ainsi que les plugins puis le tarball qui sera nécessaire pour builder l’image.
La cible est alors une arborescence de ce type :
➜ squash-tm git:(v0.1.1) ls -hl
total 301112
-rw-r--r-- 1 nicolas staff 2,5K 12 jui 15:02 Dockerfile
-rw-r--r--@ 1 nicolas staff 1,4K 12 jui 15:20 README.md
-rwxr-xr-x 1 nicolas staff 18K 12 jui 15:02 install-script.sh
drwxr-xr-x 7 nicolas staff 224B 12 jui 15:02 plugins
-rw-r--r-- 1 nicolas staff 147M 12 jui 15:02 squash-tm.tar.gz
Il faudra ensuite ajouter la directive suivante ADD plugins/* /opt/squash-tm/plugins/
au Dockerfile afin de copier les plugins dans l’image, ensuite suivre les instructions dans le README.md
.
Squash ne fournit pas de chart Helm ou de manifeste prêt à l’emploi pour ce composant de la stack. En revanche, un fichier docker-compose.yml est disponible avec le kit de build. Il est assez simple et reproduire sa configuration pour Kubernetes ne pose pas de grosse difficulté :
apiVersion: v1
kind: Secret
metadata:
name: squash-tm-secrets
namespace: squash
type: Opaque
stringData:
SQTM_DB_USERNAME: "DB_USERNAME"
SQTM_DB_PASSWORD: "DB_PASSWORD"
SQTM_DB_NAME: "DB_NAME"
SQTM_DB_HOST: "DB_HOST"
SQTM_DB_SCHEMA: "DB_SCHEMA"
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: squash-tm
name: squash-tm
spec:
replicas: 1
selector:
matchLabels:
app: squash-tm
template:
metadata:
labels:
app: squash-tm
spec:
imagePullSecrets:
- name: registry-secret
containers:
- name: squash-tm
image: your.registry.com/squash-tm:5.0.0.RELEASE
imagePullPolicy: IfNotPresent
env:
- name: SQTM_DB_TYPE
value: postgresql
envFrom:
- secretRef:
name: squash-tm-secrets
optional: false
ports:
- name: http
containerPort: 8080
protocol: TCP
livenessProbe:
httpGet:
path: /squash/isSquashAlive
port: http
initialDelaySeconds: 120
periodSeconds: 60
readinessProbe:
httpGet:
path: /squash/isSquashAlive
port: http
initialDelaySeconds: 120
periodSeconds: 60
---
apiVersion: v1
kind: Service
metadata:
name: squash-tm
spec:
selector:
app: squash-tm
ports:
- name: http
port: 8080
protocol: TCP
targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: squash
spec:
ingressClassName: nginx
tls:
- hosts:
- "squash.yourdomain.com"
secretName: squash-tls
rules:
- host: "squash.yourdomain.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: squash-tm
port:
number: 8080
Aucun stockage persistant n’est nécessaire, les logs sont renvoyés directement à Kubernetes et les plugins intégrés dans l’image.
Squash Orchestrator
Token Open JWT
Afin de s’authentifier de façon sécurisée auprès des micro-services inclus dans Squash Orchestrator, Squash TM ainsi que les agents OpenTestFactory utilisent un token Open JWT.
Celui-ci peut-être de 2 types :
- Généré de façon aléatoire au démarrage du micro-service automator et valable uniquement pour la durée de vie du conteneur (déconseillé en environnement de production)
- Statique et signé par un certificat de sécurité
C’est bien évidement vers la 2ᵉ possibilité que nous allons nous orienter.
Nous allons donc générer un couple clef public/privé :
openssl genrsa -out trusted_key.pem 4096
openssl rsa -pubout -in trusted_key.pem -out trusted_key.pub
La clef publique devra ensuite être stockée dans un secret, qui sera utilisé pour monter celle-ci dans le répertoire /etc/squashtf
du conteneur de Squash Orchestrator.
kubectl create secret generic squash-trusted-keys --from-file=trusted_key.pub=trusted_key.pub --namespace squash
On peut ensuite générer le token Open JWT à l’aide la commande suivante :
pip3 install opentf-tools
opentf-ctl generate token using trusted_key.pem
Déploiement
Concernant Squash Orchestrator, il faudra utiliser l’image docker “all-in-one” du DockerHub, car aucune autre option n’est disponible.
Un manifest Kubernetes prêt à l’emploi est disponible dans la procédure d’installation, il est normalement pensé pour la version Premium, mais son adaptation pour la version Freemium est assez simple :
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: squash-autom
name: squash-autom
spec:
replicas: 1
selector:
matchLabels:
app: squash-autom
template:
metadata:
labels:
app: squash-autom
spec:
containers:
- name: orchestrator
image: squashtest/squash-orchestrator:4.3.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 7774
protocol: TCP
- containerPort: 7775
protocol: TCP
- containerPort: 7776
protocol: TCP
- containerPort: 38368
protocol: TCP
- containerPort: 24368
protocol: TCP
- containerPort: 12312
protocol: TCP
volumeMounts:
- mountPath: /tmp/
name: attachment-storage
- mountPath: /etc/squashtf
name: squash-orchestrator-trusted-key
volumes:
- name: attachment-storage
emptyDir: {}
- name: squash-orchestrator-trusted-key
secret:
defaultMode: 420
secretName: squash-trusted-keys
---
apiVersion: v1
kind: Service
metadata:
name: squash-autom
spec:
selector:
app: squash-autom
ports:
- name: receptionist
port: 7774
protocol: TCP
targetPort: 7774
- name: eventbus
port: 38368
protocol: TCP
targetPort: 38368
- name: observer
port: 7775
protocol: TCP
targetPort: 7775
- name: killswitch
port: 7776
protocol: TCP
targetPort: 7776
- name: agentchannel
port: 24368
protocol: TCP
targetPort: 24368
- name: qualitygate
port: 12312
protocol: TCP
targetPort: 12312
Dans notre contexte, nous avons choisi de ne pas rendre accessible ce micro-service en dehors du cluster, donc aucun ingress n’est nécessaire.
Configuration
Il faudra ensuite déclarer le serveur automation depuis le panneau d’administration de Squash TM en suivant la procédure d’installation et en utilisant le token Open JWT.
Attention à spécifier les bons ports pour les différents micro-services si comme nous, vous avez décidé de ne pas les exposer via un ingress :
Environnement d’exécution Robot Framework
A l’image d’un runner Gitlab/Github, il est nécessaire de disposer d’un environnement dans lequel l’agent OpenTestFactory pourra exécuter les différents tests via Robot Framework.
Afin de rester sur une installation “full container”, nous allons créer une image Docker ayant comme base Ubuntu 22.04, dans lequel nous installerons tous les outils nécessaires.
L’agent OpenTestFactory y sera ensuite lancé puis s’inscrira auprès des micro-services Orchestrator.
On partira donc sur le DockerFile suivant :
FROM ubuntu:22.04
# Définir la timezone :
RUN ln -snf /usr/share/zoneinfo/$CONTAINER_TIMEZONE /etc/localtime && echo $CONTAINER_TIMEZONE > /etc/timezone && apt update && apt install -y tzdata
# Installer les utilitaires / python / python-pip :
RUN apt -y install wget unzip git python3 python3-pip software-properties-common
# Installer Robotframework et la librairie de mots-clés Selenium :
RUN pip3 install robotframework selenium==4.9.1 && \
pip3 install allure_robotframework pyyaml robotframework-seleniumlibrary robotframework-selenium2library robotframework-requests robotframework-jsonlibrary
# Installer Firefox via les dépots PPA (voir https://doc.ubuntu-fr.org/firefox#installer_firefox_en_deb_classique_au_lieu_de_snap) :
COPY mozillateamppa /etc/apt/preferences.d/mozillateamppa
RUN add-apt-repository ppa:mozillateam/ppa && apt update && apt -y install firefox
# Installer Chrome (browser) :
RUN sh -c 'echo "deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list' && \
wget -O- https://dl-ssl.google.com/linux/linux_signing_key.pub | tee /etc/apt/trusted.gpg.d/linux_signing_key.pub && \
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 78BD65473CB3BD13 && \
apt update && \
apt -y install google-chrome-stable
# Installer le webdriver pour Firefox (geckodriver) :
RUN cd /usr/local/bin; \
wget https://github.com/mozilla/geckodriver/releases/download/v0.33.0/geckodriver-v0.33.0-linux64.tar.gz; \
tar xzvf geckodriver-v0.33.0-linux64.tar.gz; \
rm -r geckodriver-v0.33.0-linux64.tar.gz;
# Installer le webdriver pour Chrome (chromedriver) :
RUN cd /usr/local/bin; \
wget https://chromedriver.storage.googleapis.com/97.0.4692.20/chromedriver_linux64.zip; \
unzip chromedriver_linux64.zip;\
rm -r chromedriver_linux64.zip;
# Installer l'agent OpenTestFactory (contactera l'orchestrator toutes les 5 secondes et exécutera les commandes receptionnées)
RUN pip3 install --upgrade opentf-agent
# Commande par défaut pour un Dockerfile Ubuntu
CMD ["/bin/bash"]
Attention, sur Ubuntu 22.04 l’installation de Firefox par défaut se fait via Snap, ce qui pose problème avec geckodriver
.
Il est donc nécessaire de l’installer via les paquets .deb comme ci-dessus.
On pourra ensuite déployer ce conteneur en lançant l’agent OpenTestFactory :
apiVersion: v1
kind: Secret
metadata:
name: squash-robot-env-secrets
namespace: squash
type: Opaque
stringData:
OPENTF_TOKEN: "OPENT_JWT_TOKEN"
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: squash-robot-env
name: squash-robot-env
spec:
replicas: 1
selector:
matchLabels:
app: squash-robot-env
template:
metadata:
labels:
app: squash-robot-env
spec:
imagePullSecrets:
- name: registry-secret
containers:
- name: robot-env
image: your.registry.com/squash-robot-env:latest
imagePullPolicy: IfNotPresent
envFrom:
- secretRef:
name: squash-robot-env-secrets
optional: false
command: ["/usr/local/bin/opentf-agent"]
args: ["--tags", "linux,robotframework", "--host", "http://squash-autom", "--token", "$(OPENTF_TOKEN)"]
livenessProbe:
exec:
command:
- /bin/bash
- -c
- ps -ef | grep opentf-agent | grep -v grep
initialDelaySeconds: 10
periodSeconds: 10
L’inscription de l’agent a Squash Automator étant automatique, vous devriez le voir remonter dans l’interface d’administration de Squash TM :
C’est tout, côté configuration/déploiement, votre stack de test automatisés est maintenant prête à être utilisé par vos automaticiens.