Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE Antonio García Domínguez SE Universidad de Cádiz, España 19 noviembre 2012 Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 1 / 18 Contenidos 1 Motivación 2 Inferencia de requisitos de rendimiento 3 Generación de artefactos de prueba 4 Estado actual y trabajo futuro Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 2 / 18 Motivación Rendimiento como requisito En algunos contextos, puede ser clave para tener éxito Se firman Acuerdos de Nivel de Servicio en partes críticas Es difícil garantizar el cumplimiento de un acuerdo en una composición de Servicios Web Principal reto: dependencia en otros servicios ¿Cuánto rendimiento debemos pedir? Insuficiente: no cumpliremos nuestro acuerdo Excesivo: pagaremos más de la cuenta Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 3 / 18 Enfoques existentes para obtener el rendimiento deseado ¿Desde acuerdos o desde código? ¿Ascendente o descendente? Ingeniería de rendimiento tradicional: acuerdos, ascendente Tenemos acuerdos para todos los componentes Estimamos el rendimiento global y comparamos ¿Y si no tenemos esa información para algún servicio? Perfilado o monitorización: código, ascendente Hemos implementado todos los servicios Medimos tiempos reales y corregimos cuellos de botella ¿Y si tenemos que firmar un acuerdo antes de implementar? Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 4 / 18 Nuestro enfoque: inferencia de rendimiento Características Desde acuerdos, descendente Tenemos requisitos para la composición y anotaciones locales con nuestros conocimientos parciales sobre los servicios usados Inferimos el rendimiento mínimo a exigir a los servicios Ventajas Puede usar la información incompleta que haya disponible sobre los servicios Puede ayudar a definir el acuerdo antes de implementar Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 5 / 18 Ejemplo de modelo: motor de búsqueda de viajes Consultar Aerolínea A Recibir Consulta Consultar Aerolínea B c Consultar Hotel C Reservar !c Consultar Hotel D Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 6 / 18 Inferencia de peticiones por segundo «gastep» {throughput = ?} «gastep» {throughput = ?} CAA RC «gastep» {throughput = ?} «gascenario» {throughput = (10Hz, req)} CAB «gastep» {prob = 0.8} c «gastep» {throughput = ?} CHC «gastep» {throughput = ?} «gastep» {prob = 0.2} «gastep» {throughput = ?} R !c CHD Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 7 / 18 Inferencia de peticiones por segundo «gastep» {throughput = 10} «gastep» {throughput = 10} CAA RC «gastep» {throughput = 10} «gascenario» {throughput = (10Hz, req)} CAB «gastep» {prob = 0.8} c «gastep» {throughput = 8} CHC «gastep» {throughput = 10} «gastep» {prob = 0.2} «gastep» {throughput = 2} R !c CHD Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 7 / 18 Inferencia de tiempos límite «gastep» {hostDemand = {(5, req)}} «gastep» {hostDemand = {(sRP, req)}} CAA RC «gastep» {hostDemand = {(sAB, req)},rep=3} «gascenario» {respT = (10s, req)} «gaanalysiscontext» {contextParams = { sRP = ?, sAB = ?, sHC = ?, sHD = ?, sR = ?}} CAB «gastep» {hostDemand = {(sHC, req)}} CHC «gastep» {hostDemand = {(3 × sR, req)}} «gastep» {hostDemand = {(2 + sHD, req)}} R CHD Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 8 / 18 Inferencia de tiempos límite «gastep» {hostDemand = {(5, req)}} «gastep» {hostDemand = {(sRP, req)}} CAA RC «gastep» {hostDemand = {(sAB, req)},rep=3} «gascenario» {respT = (10s, req)} «gaanalysiscontext» {contextParams = { sRP = ?, sAB = ?, sHC = ?, sHD = ?, sR = ?}} CAB «gastep» {hostDemand = {(sHC, req)}} CHC «gastep» {hostDemand = {(3 × sR, req)}} «gastep» {hostDemand = {(2 + sHD, req)}} R CHD Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 8 / 18 Inferencia de tiempos límite «gastep» {hostDemand = {(5, req)}} «gastep» {hostDemand = {(sRP, req)}} CAA RC «gastep» {hostDemand = {(sAB, req)},rep=3} «gascenario» {respT = (10s, req)} «gaanalysiscontext» {contextParams = { sRP = 0,6, sAB = 1,66, sHC = 2,6, sHD = 0,6, sR = 0,6}} CAB «gastep» {hostDemand = {(sHC, req)}} CHC «gastep» {hostDemand = {(3 × sR, req)}} «gastep» {hostDemand = {(2 + sHD, req)}} R CHD Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 8 / 18 Enfoque general para generación de pruebas Código Modelo de rendimiento Modelo diseño/impl. Extracción de modelos Modelo de entrelazado Transformación M2T Artefactos de pruebas Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 9 / 18 Implementaciones hechas Java Código: pruebas unitarias JUnit. Extractor de modelos existente: MoDisco. Se generan nuevas pruebas JUnit que envuelven a las anteriores usando la biblioteca ContiPerf. WSDL Código: interfaz WSDL de un servicio Web. Extractor de modelos propio: ServiceAnalyzer. Se generan plantillas de mensajes y un conjunto aleatorio de entradas mediante SpecGenerator y TestGenerator (propios). Se genera código Jython para realizar pruebas de rendimiento mediante la herramienta The Grinder. Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 10 / 18 Estado actual y trabajo futuro ¿Qué está hecho? Modelos de rendimiento basados en OMG MARTE Algoritmos para tiempos límite y peticiones por segundo Generación de pruebas de rendimiento para código Java y servicios Web descritos mediante WSDL ¿Qué está por hacer? Añadir más opciones para generar entradas a las pruebas de rendimiento desde documentos WSDL Validar el enfoque con casos de estudio mayores Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 11 / 18 Fin de la presentación ¡Gracias por su atención! Código y descargas: https://neptuno.uca.es/redmine/projects/sodmt E-mail: [email protected] Twitter: @antoniogado Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 12 / 18 Generación desde pruebas unitarias en Java Muchos SW se hacen en Java (Apache Axis, Apache CXF) y se prueban con JUnit Código Desc. modelos Modelo entrel. Artefactos de prueba public class MisPruebasUnitarias { @Test public void rechazado() { // ... test code ... } @Test public void aceptado() { // ... test code ... } } Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 13 / 18 Generación desde pruebas unitarias en Java Muchos SW se hacen en Java (Apache Axis, Apache CXF) y se prueban con JUnit Código Desc. modelos Modelo entrel. Artefactos de prueba Casos de prueba Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 13 / 18 Generación desde pruebas unitarias en Java Muchos SW se hacen en Java (Apache Axis, Apache CXF) y se prueban con JUnit Código Desc. modelos Modelo entrel. Artefactos de prueba Requisito de rendimiento Caso de prueba Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 13 / 18 Generación desde pruebas unitarias en Java Muchos SW se hacen en Java (Apache Axis, Apache CXF) y se prueban con JUnit Código Desc. modelos Modelo entrel. Artefactos de prueba @RunWith(ContiPerfSuiteRunner.class) @SuiteClasses(MyUnitTests.class) @PerfTest( invocations = 100, threads = 10) @Required(max=1000) public class PruebaCargaInferida {} Se usa la biblioteca ContiPerf para generar menos código Se pueden convertir conjuntos completos o pruebas sueltas Se pueden expresar tiempos límite como máximos, promedios, percentiles (90 %, 95 % , 99 %) o medianas Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 13 / 18 Desde WSDL: extracción y entrelazado (1/2) Enfoque independiente del lenguaje, pero WSDL es complejo Diferencias Descripción WSDL no depende del lenguaje Herramienta especializada: The Grinder Se necesita generar entradas Implementación actual Se extrae un “catálogo” de los documentos WSDL Se usa un metamodelo de entrelazado especializado: Enlaza nodos ejecutables UML con operaciones del catálogo Opciones de generación (Maven, Eclipse, The Grinder) Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 14 / 18 Desde WSDL: extracción y entrelazado (2/2) Simplificamos los WSDL y añadimos plantillas de mensajes TypeVariable name : String type : String variable 0..* «enumeration» TypeGA - string - int - float - list - tuple - date - dateTime - time - duration ServicesType TypeTypedef element : String fractionDigits : NonNegativeInteger max : String min : String name : String pattern : String totalDigits : PositiveInteger type : TypeGA values : String TypeService name : String 1..* uri : String service typedef decls 1 TypeFault name : String TypePort address : String 1..* name : String port TypeTemplate value : String TypeDecls 0..* fault 0..* operation template 1 TypeInput input 0..1 TypeOutput output 0..1 TypeOperation name : String 0..* Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 15 / 18 Desde WSDL: generación (1/3) Actualmente: aleatoria uniforme, servicios sin estado Las variables definen tipos, rangos y restricciones Se generan valores aleatorios y se pasan a las plantillas Plantillas, declaraciones y valores son personalizables Ejemplo de declaraciones typedef int (min=0, max=100) TArtID; typedef float (min=0.01, max=2000) TPrice; typedef list (element=TPrice, min=1, max=1) TL_float; typedef tuple (element={TArtID, TL_float}) TArticleQtys; typedef list (element=TArticleQtys, min=0) TOrder; typedef list (element=TOrder, min=1, max=1) TEvaluate; TEvaluate evaluate; Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 16 / 18 Desde WSDL: generación (2/3) Ejemplo de plantilla Apache Velocity <w:evaluate xmlns:w="http://ws.sodmt.uca.es/"> #foreach($V1 in $evaluate) <newOrder> #foreach($V2 in $V1) <articleQtys> <id>$V2.get(0)</id> #foreach($V3 in $V2.get(1))<qty>$V3</qty>#end </articleQtys> #end </newOrder> #end </w:evaluate> Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 17 / 18 Desde WSDL: generación (3/3) Código de pruebas Se generan guiones Jython para The Grinder Regeneran las pruebas si el usuario ha retocado las declaraciones Infraestructura Se genera un módulo Maven: desde una terminal, mvn post-integration-test lanza las pruebas y genera los informes Se genera un proyecto Eclipse (aún básico) Antonio García Domínguez Generación Dirigida por Modelos de Pruebas de Rendimiento desde UML y MARTE UCASE (Universidad de Cádiz) 18 / 18