
Alejandro García
Product Tech Lead en Whitestack
El desafío de testearlo todo
En Whitestack, desarrollamos y mantenemos una amplia gama de productos innovadores, desde herramientas de monitoreo hasta automatización de redes. Esta diversidad de productos presenta un desafío significativo a la hora de asegurar la más altísima calidad. Con tantos productos de dominios tan variados, la creación de entornos de prueba y la ejecución de tests eran tareas complejas y, a menudo, propensas a errores.
Algo debíamos hacer: necesitábamos una manera uniforme y automatizable de garantizar la robustez de nuestras soluciones. Teníamos que resolver el desafío de “testearlo todo”, considerando muchos escenarios y configuraciones. Así nació Whitestack Lab Deployment: nuestro primer producto de uso interno, que nos ayudó a impulsar la transformación del testing en Whitestack. Combinándolo con pipelines y un framework común para el testing end-to-end, logramos automatizar la creación de infraestructura virtual para instalar y validar nuestros productos.
En este artículo, exploraremos cómo implementamos este proceso con mayor foco técnico. En las siguientes secciones, veremos cómo atacamos y resolvimos cada una de las diferentes etapas del ciclo del testing continuo de nuestros productos, de manera uniforme y consistente.
La virtualización de nuestra infraestructura
Como ya mencionamos, Whitestack Lab Deployment (al que, internamente, llamamos solo “Deployment”) fue el punto de partida de este proceso. Originalmente, fue pensado como una herramienta para ayudar a nuestros nuevos ingenieros en su onboarding, pero rápidamente ganó muchísima relevancia cuando vimos su potencial para la automatización.
En resumen, Deployment es una solución basada en Terraform que nos permite virtualizar y desplegar la infraestructura necesaria para cada uno de nuestros productos de manera programática y reproducible. Por ejemplo, si queremos desplegar una instancia de WhiteCloud (nuestro cloud privado basado en OpenStack) necesitaremos un grupo de máquinas virtuales con múltiples redes desplegadas de determinada manera. Notar que el desafío aquí no es únicamente desplegar las instancias: es crear y administrar todos los recursos necesarios (redes, interfaces, security groups, llaves y otros) para hacerlo, y adecuarlos de manera tal que la infraestructura presente quede lista para instalar el producto.
En Deployment, cada uno de nuestros productos es implementado como un módulo de Terraform, lo que nos permite parametrizarlos a través de variables. En la práctica, todo lo que el usuario de Deployment debe hacer es invocarlo con un archivo JSON como entrada para desplegar correctamente.
En el ejemplo que mencionamos de Whitecloud, dicho archivo JSON tiene un formato como el siguiente:
{
"deployment": "whitecloud",
"whitecloud": {
"prefix": "wc",
"enabled": true,
"nodes": {
"total": 6,
"control": 3
},
"target_os": "Ubuntu 22.04 LTS",
"flavors": ["m1.xlarge", "m1.xlarge", "m1.xlarge", "m1.large", "m1.large"]
}
}
Invocar a Deployment con este JSON como entrada permite, entonces, la creación de una infraestructura con 6 máquinas virtuales para WhiteCloud, junto con la configuración de sus redes, security groups y otros recursos asociados. Gráficamente, la infraestructura tendrá una topología como la siguiente. Las distintas subnets creadas obedecen a los requerimientos de despliegue de WhiteCloud (ya que es un producto que hace segmentación de redes). Además, una instancia auxiliar deployer es creada junto con la infraestructura: la misma se puede usar como bastion host, y será el punto usado por nuestros pipelines para ejecutar los tests E2E contra el producto instalado.

Una ventaja adicional que provee el uso de Whitestack Lab Deployment es la modularización: como la infraestructura de cada producto está implementada en su propio Terraform module, se vuelve fácil extender la solución para nuevos productos; y modificaciones en los modules ya existentes tendrán un impacto local y no afectarán a los demás. Además, se vuelve posible instalar e integrar más de un producto, pero eso lo retomaremos en unas secciones…
Conoce la solución ideal para tu empresa
Construyendo nuestros tests
Ahora que explicamos cómo se crea la infraestructura para instalar nuestros productos, debemos abarcar la dimensión del testing. En Whitestack construimos nuestros productos en base a proyectos open-source de muchísima tracción. Obviamente, estas tecnologías incluyen en su ciclo de desarrollo un enorme esfuerzo en el testing y la validación de lo construido, pero sus pruebas standalone no siempre son representativas de los productos multicomponentes que nosotros construimos.
Consideremos, por ejemplo, nuestro producto de monitoreo WhiteMon. Este producto incluye varios componentes abiertos integrados: Fluentd, Prometheus, Grafana, OpenSearch y otros. La manera en la que integramos estos componentes, además de otras extensiones que agregamos para los casos de uso que contemplamos en el producto, es única y por lo tanto requiere un tratamiento de pruebas especial.
En otras palabras, necesitamos efectuar un correcto testing end-to-end (E2E) de nuestros productos, interactuando con sus diversas partes y validando que sus respuestas y el resultado global sean los esperados.
Para ello, hemos estandarizado el uso de Robot Framework, un framework de automatización usado en Acceptance Test Driven Development (ATDD). Su sintaxis legible y su capacidad de extensión nos permiten construir tests E2E complejos que interactúan con nuestros productos como lo haría un usuario final, verificando funcionalidades desde la interfaz de usuario hasta la capa de infraestructura subyacente.
Retomando el ejemplo de WhiteMon, supongamos que queremos armar un test que cree un dashboard en Grafana y agregue un panel con una consulta a Prometheus. Todas esas acciones son propias a la interfaz gráfica de Grafana y pueden realizarse con Selenium. En Robot Framework, esto podría implementarse de la siguiente manera:
*** Settings ***
Library SeleniumLibrary
Resource grafana_utils.resource
Suite Setup Setup Environment
Suite Teardown Destroy Environment
*** Variables ***
${SIMPLE_PROMETHEUS_QUERY} up{job="whitemon-prometheus"}
*** Test Cases ***
Create Simple Prometheus Panel
[Tags] smoke daily
Go To New Dashboard Screen
Add Panel ${SIMPLE_PROMETHEUS_QUERY}
Page Should Not Contain No Data
*** Keywords ***
Setup Environment
Set Selenium Timeout 10 seconds
Login To Grafana As Admin
Destroy Environment
Close All Browsers
Aunque poderoso para abstraernos de Selenium, Robot Framework no se limita únicamente a las interfaces gráficas. En Whitestack, lo hemos usado ya para consumir APIs, ejecutar comandos Linux, inspeccionar contenedores y máquinas virtuales, y hasta interactuar con clústers de Kubernetes.
Por ejemplo, algo que todos nuestros productos basados en Kubernetes validan es que, luego de desplegarse, todos sus services estén activos y funcionales:
*** Settings ***
Library Collections
*** Variables ***
${NAMESPACE} %{WHITEMON_NAMESPACE}
*** Test Cases ***
Check services status
[Tags] smoke daily
@{whitemon_services}= List Namespaced Service ${NAMESPACE}
FOR ${service} IN @{whitemon_services}
Log ${service.metadata.name}
Kubernetes Service Should Be Active ${service.metadata.name}
END
*** Keywords ***
Kubernetes Service Should Be Active
[Arguments] ${service_name}
# Check the service has active endpoints
${service_endpoints}= Read Namespaced Endpoints ${service_name} ${NAMESPACE}
Should Be True ${service_endpoints.subsets}
... Service ${service_name} has no endpoints
# If the service is of type LoadBalancer, check it has an external IP
${service_details}= Read Namespaced Service ${service_name} ${NAMESPACE}
IF "${service_details.spec.type}" == "LoadBalancer"
Log Service ${service_name} is of type LoadBalancer
Should Be True ${service_details.status.load_balancer.ingress}
... Service ${service_name} has no external IP
END
El pipeline automatizado
Ahora que entendemos cómo se despliega la infraestructura y cómo se definen y corren las pruebas E2E, podemos unir las piezas de nuestra solución automatizada. Como tanto Whitestack Lab Deployment como Robot Framework se pueden ejecutar mediante línea de comandos, es posible emplearlos a ambos en un pipeline de despliegue.
Este pipeline actúa como un orquestador de las herramientas y de otros detallitos más. En resumen, su lógica es la siguiente:
- Despliegue del producto: Whitestack Lab Deployment aprovisiona un entorno de prueba limpio y aislado, donde se instala el producto a validar.
- Ejecución de tests: Robot Framework ejecuta la suite de tests E2E en el entorno recién desplegado.
- Recolección de resultados: Los resultados de los tests se reportan a nuestros sistemas de monitoreo.
- Liberación de recursos: El entorno de prueba se destruye, liberando recursos.
Este enfoque automatizado es independiente del producto a validar, lo que nos permite mantener una estructura uniforme y consistente para testear nuestros productos antes de llegar a producción.
Yendo más allá: Testing de integraciones
Los productos que construimos en Whitestack tienen una particularidad extra: además de presentar cada uno una respuesta a un problema por sí mismos, pueden integrarse a otros productos para presentar una solución más robusta e integrada. Por ejemplo, WhiteStorage es nuestra solución de software-defined storage que provee servicios de almacenamiento. Si este producto se integra con WhiteCloud, permitirá a las máquinas virtuales de esta nube acceder a almacenamiento remoto. De esta forma, combinando dos de nuestros productos logramos otorgar nuevas funcionalidades al usuario. Y, obviamente, estas funcionalidades también deben ser validadas.
Por fortuna, la versatilidad de Whitestack Lab Deployment no se limita al testing de productos individuales. Como Deployment fue diseñado con cada producto como un módulo, podemos usarlo para configurar un entorno donde múltiples productos coexisten y se comunican, permitiéndonos validar la integración de forma completa. Esto nos ayuda a garantizar que nuestras soluciones operen armónicamente en escenarios del mundo real.
En el caso de WhiteCloud y WhiteStorage, deberemos habilitar ambos módulos en el JSON de entrada para Deployment. Además, deberemos explicitar la integración whitecloud_cinder_to_whitestorage para que Deployment “entienda” que queremos integrar ambos productos y los configure de manera acorde:
{
"deployment": "integration",
"whitecloud": {
"enabled": true,
"prefix": "wc-",
"nodes": {
"total": 2,
"control": 1
},
"target_os": "Ubuntu 22.04 LTS",
"flavors": ["m1.xlarge", "m1.large"]
},
"whitestorage": {
"enabled": true,
"prefix": "ws-",
"nodes": {
"total": 3,
"control": 1
},
"target_os": "Ubuntu 20.04 LTS",
"flavors": ["m1.ceph.large"]
},
"integrations": ["whitecloud_cinder_to_whitestorage"]
}
Conclusión y Próximos Pasos
La unificación de nuestro testing E2E a través de pipelines empleando Whitestack Lab Deployment y Robot Framework refuerza nuestro compromiso con la calidad y la innovación. Después de varios años de implementación y refinamiento, esta solución madura nos ha permitido acelerar el desarrollo, mejorar la confiabilidad de nuestros productos y construir un ecosistema de componentes de software más robusto.
De cara al futuro, nuestra visión es continuar expandiendo las capacidades de nuestros pipelines de pruebas E2E. Estamos explorando activamente nuevas funcionalidades y metodologías que nos permitan validar escenarios cada vez más complejos y exigentes, asegurando que nuestras soluciones sigan siendo vanguardistas y resilientes frente a los desafíos tecnológicos emergentes.
Disclaimer: Algunas de las keywords mostradas como Go To New Dashboard Screen no forman parte de las librerías estándar de Robot. En el ejemplo, se importó un archivo grafana_utils.resource que funciona como “librería para interactuar con Grafana”.
Acerca de nosotros
Whitestack es una empresa líder en el despliegue productivo de soluciones basadas en tecnologías y código abierto, con un fuerte foco en la industria de telecomunicaciones.
¡Contáctanos para conocer más!