Skip to content

Wakamiti 3 #17

@mgalbis

Description

@mgalbis

Tras varios meses de uso de la herramienta, se ha ido detectando una serie de carencias y problemas
que se han intentado paliar con parches. Sin embargo, algunos de estos problemas son complejos de
abordar atendiendo al diseño actual de Wakamiti, y requieren cambios profundos en el mismo core.
Algunos ejemplos son:

  • Incompatibilidades entre dependencias de plugins a la hora de juntarlos en una misma instalación
  • Consumo excesivo de memoria con planes de test grandes
  • Imposibilidad de reutilizar funcionalidades de un plugin en otro
  • Dificultad de expresar la complejidad de algunas expresiones de pasos con solo expresiones regulares

Atendiendo a la complejidad que presentan, se plantea una reescritura desde cero del proyecto,
realizando los ajustes de diseño necesarios fruto de la experiencia recopilada durante estos meses de
uso.

Nuevo sistema de carga de plugins

El sistema actual de plugins consiste en juntar todas las librerías usadas por cada plugin
en un único directorio que es usado como 'module-path' por parte de Java. El problema
que presenta esto es que varios plugins pueden usar versiones distintas de la misma
librería, y hay que revisar la instalación con cada nuevo plugin para poner en concordancia
las versiones, ya que de no hacerlo pueden surgir errores inesperados en tiempo de ejecución
porque un plugin use una versión que no era la intencionada. El hecho de tener que hacer
esta revisión rompe por completo la filosofía de plugins independientes que puedan
ser desarrollados por terceros.

Se hace necesario un nuevo sistema de carga de plugins en el que cada plugin tenga
aislado su conjunto de librerías y no interfieran entre sí. Java permite esto mediante
el concepto de 'capas de modulos' ('module layers'), aunque es una característica poco
usada. Un ejemplo de su uso es la librería Layrry (https://github.com/moditect/layrry).

Además, sería interesante que el nuevo sistema de plugins tenga opciones avanzadas
como la inyección de otros plugins para su interoperabilidad, o la capacidad de
instalar y actualizar plugins en caliente a partir de un fichero JAR.

Persistencia de datos en una base de datos embebida y optimizaciones

La construcción y ejecución de planes de tests actualmente se realiza completamente en memoria.
Se ha comprobado que, para planes con cientos de casos de tests, esta aproximación
no funciona ya que dispara el consumo de memoria pudiendo incluso llegar a producir
errores al no tener disponible toda la necesaria.

Se plantea un cambio de enfoque y usar una base de datos NoSQL, con persistencia
en disco, en la que se persistan los datos de cada caso de test, recuperandolos sólo
cuando sea necesario y liberando memoria tras su uso. Una opción inicial que se ha considerado
es MongoDB, pero se ha descartado por el motivo de que requiere una instalación
externa, cuando lo preferible es un sistema Java embebido que se pueda distribuir
como libreria de Wakamiti. Un buen candidato es Nitrite (https://github.com/nitrite/nitrite-java).

Adicionalmente, se pueden aplicar otras técnicas de optimización, como evitar
la construcción de un plan de test si el conjunto de ficheros de entrada ya ha
sido usado previamente (calculando los hash de los ficheros y viendo si ya
existe guardado en la base de datos un plan de test para dicho hash).

Rediseño de algunos puntos de extensión

Se ha dado el caso de tener una funcionalidad implementada para un plugin
en concreto que luego es dificil de reaprovechar en otros plugins. Un ejemplo
claro es la comparación de textos JSON y XML, implementada para el plugin REST
pero que sería de utilidad para otros plugins.

Por ello, se plantea la creación de nuevos puntos de extensión que permitan
abstraer estas funcionalidades y estén disponibles para todos los plugins.
También se planteará la eliminación de algunos puntos de extensión existentes
que no están siendo usados realmente y que únicamente añaden complejidad
innecesaria al código.

Expresiones de pasos compuestas

Como herencia de Cucumber, las expresiones usadas para identificar los pasos
de los casos de test están implementadas mediante expresiones regulares. Esto,
aunque inicialmente parecía suficiente, se ha demostrado ser insuficiente
a la hora de definir construcciones más complejas, como sub-expresiones o
valores que pueden venir de otras variables y que no se conocen a priori.
La aproximación usada para resolver estos casos es generalizar partes de las
expresiones regulares para que acepten cualquier cadena y evaluarla después
en tiempo de ejecución, pero con esto se pierde parte del contexto que
necesita el servidor de lenguaje (usado por el editor) para ofrecer un
servicio completo de detección de errores y autocompletado.

Se debería estudiar la posibilidad de reemplazar el uso de expresiones
regulares por un mecanismo propio de pattern-matching que permita un
uso más fino y detallado de cada una de las posibles secciones de una
expresión.

Wakamiti como servicio

La herramienta actualmente se comporta como un simple proceso Java que
inicia desde cero cada vez que se invoca. Esto supone un proceso inicial
de descubrimiento y registro de los plugins existentes que se ha de realizar
cada vez y que supone un tiempo extra de computación.

Se propone cambiar este enfoque y hacer que Wakamiti corra en background
como un servicio del sistema en vez de un proceso ejecutable, de forma que
este tiempo dedicado a las operaciones de inicialización sólo se
tenga que realizar cuando arranque el servicio. Como funcionalidad extra,
esto permitiría usarlo como servicio remoto desde otras máquinas sin
necesidad de tener toda la aplicación instalada.

Herramienta CLI avanzada

Actualmente el comando ejecutable se limita a lanzar la ejecución
del plan de test del directorio en curso. Sería interesante dotar a
este intérprete de comandos de varias funcionalidades extra, recogiendo
algunos de los puntos tratados anteriormente, como pueden ser:

  • Instalación, actualización, eliminación, y consulta de plugins instalados
  • Consulta de ejecuciones previas, recuperándolas de base datos
  • Exportación de ejecuciones previas aplicando algún plugin de reporte
    sin necesidad de volver a ejecutar al plan
  • ...

Reestructuración del proyecto y cambio de herramienta de construcción

La estructura actual del proyecto es excesivamente compleja, con
varios niveles anidados y múltiples interdependencias que lo hacen
algo costoso de mantener. Se debería replantear dicha estructura
para simplificarla todo lo posible, considerando incluso sacar fuera del
proyecto algunos módulos satélite y publicarlos por separado.

Además, se podría considerar cambiar Maven por Gradle como herramienta
de construcción. Aunque tiene una curva de aprendizaje más compleja,
Gradle es mucho más flexible y menos farragoso de usar que Maven,
y dadas las características actuales del proyecto podría simplificar
el proceso de ensamblaje y publicación. También permite escribir
plugins Gradle locales al proyecto, un mecanismo que podría ser
de utilidad para algunas tareas.

Generación automática de documentación

Uno de los puntos en los que más tiempo se ha invertido es la
escritura manual de la documentación de los plugins, tanto los
pasos disponibles como las opciones de configuración de cada uno.
Todo esto se podría llegar a automatizar si se modificara la forma
en que dichos elementos se definen dentro de un plugin, por ejemplo
definiendolos en un fichero JSON que luego pueda ser usado como origen
para la generación de páginas HTML o documentos Markdown.

Metadata

Metadata

Assignees

Labels

Projects

Status

Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions