Tutoriel sur la présentation de Benerator : un outil de génération de jeux de données

Afin qu'une campagne de tests de charge soit la plus utile possible, il est souvent nécessaire d'avoir un jeu de données volumineux et réaliste. Pour cela plusieurs solutions existent :

  • importation des données de la base de données de production ;
  • création du jeu de données à l'aide d'outils maison ;
  • utilisation d'ETL ;
  • utilisation de l'outil de test de charge et/ou de test fonctionnel afin d'exécuter des scripts qui vont remplir la base ;
  • utilisation d'outil de création de données.

Nous allons nous focaliser sur la dernière solution avec l'utilisation de l'outil Benerator qui couvre largement ce besoin.

Un espace de dialogue vous est proposé sur le forum : Commentez Donner une note à l'article (5) pour vous permettre de réagir sur ce tutoriel.

Article lu   fois.

L'auteur

Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Un peu de théorie

Pour la partie théorique et quelques exemples, je vous laisse aller sur le site officiel et sur mon précédent article sur developpez.com.

II. Passons à la pratique

II-A. Présentation du cas de test

Dans cet article nous allons nous pencher sur la création de plusieurs jeux de données pour l'application démo PlantsByWebSphere livrée avec IBM WebSphere 8. Nous utiliserons une base de données MySQL en remplacement de Derby.

PlantsByWebSphere est une démonstration de boutique en ligne comme vous pouvez le voir sur cette capture d'écran.

Image non disponible

On remarque que :

  • les produits sont divisés en quatre catégories (Flowers, Fruits & Vegetables, Trees et Accessories) ;
  • l'application gère des comptes clients ;
  • l'application gère un panier d'achats.

Regardons d'un peu plus près le schéma de la base de données.

Image non disponible

Et son code SQL.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.

CREATE TABLE CUSTOMER(
	CUSTOMERID VARCHAR(250) NOT NULL,
	PASSWORD VARCHAR(250),
	FIRSTNAME VARCHAR(250),
	LASTNAME VARCHAR(250),
	ADDR1 VARCHAR(250),
	ADDR2 VARCHAR(250),
	ADDRCITY VARCHAR(250),
	ADDRSTATE VARCHAR(250),
	ADDRZIP VARCHAR(250),
	PHONE VARCHAR(250)
);

ALTER TABLE CUSTOMER
	ADD CONSTRAINT PK_CUSTOMER PRIMARY KEY (CUSTOMERID);

CREATE TABLE INVENTORY(
	INVENTORYID VARCHAR(250) NOT NULL,
	NAME VARCHAR(250),
	HEADING VARCHAR(250),
	DESCRIPTION VARCHAR(250),
	PKGINFO VARCHAR(250),
	IMAGE VARCHAR(250),
	IMGBYTES LONG BIT VARYING,
	PRICE REAL,
	COST REAL,
	CATEGORY INTEGER,
	QUANTITY INTEGER,
	NOTES VARCHAR(250),
	ISPUBLIC INTEGER,
	MINTHRESHOLD INTEGER NOT NULL,
	MAXTHRESHOLD INTEGER NOT NULL
);

ALTER TABLE INVENTORY
	ADD CONSTRAINT PK_INVENTORY PRIMARY KEY (INVENTORYID);

CREATE TABLE ORDER1(
	ORDERID VARCHAR(250) NOT NULL,
	SELLDATE VARCHAR(250),
	BILLNAME VARCHAR(250),
	BILLADDR1 VARCHAR(250),
	BILLADDR2 VARCHAR(250),
	BILLCITY VARCHAR(250),
	BILLSTATE VARCHAR(250),
	BILLZIP VARCHAR(250),
	BILLPHONE VARCHAR(250),
	SHIPNAME VARCHAR(250),
	SHIPADDR1 VARCHAR(250),
	SHIPADDR2 VARCHAR(250),
	SHIPCITY VARCHAR(250),
	SHIPSTATE VARCHAR(250),
	SHIPZIP VARCHAR(250),
	SHIPPHONE VARCHAR(250),
	CREDITCARD VARCHAR(250),
	CCNUM VARCHAR(250),
	CCEXPIREMONTH VARCHAR(250),
	CCEXPIREYEAR VARCHAR(250),
	CARDHOLDER VARCHAR(250),
	SHIPPINGMETHOD INTEGER NOT NULL,
	PROFIT REAL NOT NULL,
	CUSTOMERID VARCHAR(250)
);

ALTER TABLE ORDER1
	ADD CONSTRAINT PK_ORDER1 PRIMARY KEY (ORDERID);

CREATE TABLE ORDERITEM(
	INVENTORYID VARCHAR(250) NOT NULL,
	NAME VARCHAR(250),
	PKGINFO VARCHAR(250),
	PRICE REAL NOT NULL,
	COST REAL NOT NULL,
	CATEGORY INTEGER NOT NULL,
	QUANTITY INTEGER NOT NULL,
	SELLDATE VARCHAR(250),
	ORDER_ORDERID VARCHAR(250) NOT NULL
);

ALTER TABLE ORDERITEM
	ADD CONSTRAINT PK_ORDERITEM PRIMARY KEY (INVENTORYID, ORDER_ORDERID);

CREATE TABLE IDGENERATOR(
	IDNAME VARCHAR(250) NOT NULL,
	IDVALUE INTEGER NOT NULL
);

ALTER TABLE IDGENERATOR
	ADD CONSTRAINT PK_IDGENERATOR PRIMARY KEY (IDNAME);

CREATE TABLE BACKORDER(
	BACKORDERID VARCHAR(250) NOT NULL,
	INVENTORYID VARCHAR(250),
	QUANTITY INTEGER NOT NULL,
	STATUS VARCHAR(250),
	LOWDATE BIGINT NOT NULL,
	ORDERDATE BIGINT NOT NULL,
	SUPPLIERORDERID VARCHAR(250) NULL
);

ALTER TABLE BACKORDER
	ADD CONSTRAINT PK_BACKORDER PRIMARY KEY (BACKORDERID);

CREATE TABLE SUPPLIER(
	SUPPLIERID VARCHAR(250) NOT NULL,
    NAME VARCHAR(250),
	STREET VARCHAR(250),
	CITY VARCHAR(250),
	USSTATE VARCHAR(250),
	ZIP VARCHAR(250),
	PHONE VARCHAR(250),
	URL VARCHAR(250)
);

ALTER TABLE SUPPLIER
	ADD CONSTRAINT PK_SUPPLIER PRIMARY KEY (SUPPLIERID);

Comme on peut le voir, le schéma de la base de données n'est pas ce qui se fait de mieux, mais nous permettra d'avoir une bonne vision de l'utilisation de Benerator.

Après la découverte du schéma de la base de données et du fonctionnement Benerator, regardons comment créer le fichier XML de description du projet.

II-B. Paramétrage de la base de données cible et de la volumétrie du jeu de données

Mais avant cela, nous allons créer deux fichiers properties afin de regrouper les informations sur :

  • la base de données ;
  • la volumétrie cible.

Les informations sur la base de données seront dans le fichier mysql\PlantsByWebSphere.mysql.properties

 
Sélectionnez
1.
2.
3.
4.
5.
bddUrl=jdbc:mysql://localhost:3306/test
bddDriver=com.mysql.jdbc.Driver
bddCatalog=test
bddUser=root
bddPassword=mysql

Les informations sur les volumétries cibles seront dans les fichiers de type PlantsByWebSphere.{volumetrie}.properties

Par exemple pour un poste de développement, le fichier se nommera PlantsByWebSphere.development.properties

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
taillePaquet=10
customer_count=10
inventory_cat0_count=10
inventory_cat1_count=3
inventory_cat2_count=2
inventory_cat3_count=5
supplier_count=1
order_count=60
items_per_order=3

II-C. Création du fichier de description de Benerator

  • Commençons par l'entête du fichier.
 
Sélectionnez
1.
<!--?xml version="1.0" encoding="iso-8859-1"?-->
  • Importons les domaines nécessaires et la bonne plate-forme.

Définissons des valeurs par défaut pour le type de volumétrie et le type de base de données cible.

 Valeur par défaut

  • Chargeons les deux fichiers properties que l'on a créés.

Récupération des valeurs pour la volumétrie et la base de données cible

  • Définissons l'URL de la base de données (ne pas oublier d'ajouter les drivers dans le classpath si nécessaire).

Afin d'éviter les mauvaises surprises, partons d'une base vide (drop + create) à l'aide de deux scripts SQL.

Drop des tables avant leurs créations

  • Créons deux générateurs de nombres auto-incrémentés pour les utiliser comme clé primaire. Maintenant, en fonction de ce que l'on veut tester, il nous reste plusieurs choix possibles comme :
  • simuler des tests avec un catalogue de produits plus grand que celui défini par défaut ;
  • simuler des tests à l'ouverture de la boutique en ligne ;
  • simuler des tests après plusieurs jours de fonctionnement (ce qui correspond à avoir déjà des clients et des commandes en base de données) ;
  • simuler plusieurs combinaisons des cas précédents.

Ces choix impacteront le volume et la répartition des données en base et donc les résultats des tests.

Dans notre cas, nous allons regarder comment créer des données pour chaque table.

  • Commençons par ajouter des articles en base (table INVENTORY).

Chargeons les images des articles en mémoire afin de pouvoir remplir le champ IMGBYTES. L'objectif du jeu de données étant une campagne de tests de charge, nous ne nous soucierons pas de la correspondance entre l'image et le produit.

Afin de contrôler le plus finement possible la répartition des articles, nous les traiterons catégorie par catégorie (champ CATEGORY).

Chaque catégorie sera générée de cette façon (ici pour la catégorie des Flowers)

 
Sélectionnez
1.
generate type="INVENTORY" count="{inventory_cat0_count}" consumer="db" pageSize="{taillePaquet}" >

En fonction de la catégorie et de l'objectif du test, on pourra modifier les paramètres suivants :

  • count ;
  • QUANTITY ;
  • ISPUBLIC.

Je vous laisse créer les autres articles pour les trois catégories restantes (CATEGORY aura pour valeurs : 1, 2 et 3).

  • Créons à l'identique de l'original la table SUPPLIER.
  • Créons des comptes clients (table CUSTOMER). Comme on peut le voir, on utilise les domaines Personet Address afin d'avoir des données réalistes.

Il nous reste à créer des commandes clients (tables ORDER1, ORDERITEM et IDGENERATOR).

  • Remplissons la table ORDER1.
  • Puis la table ORDERITEM.

Mettons à jour le prix de chaque commande (champ PROFIT de la table ORDER1).

On utilise la fonction SQL IFNULL de MySQL afin d'être sûr de mettre une valeur non null dans le champ PROFIT.

Une autre solution est d'utiliser un subSelector à la place de la combinaison de selector et cyclic="true".

Pour la dernière table IDGENERATOR, on va utiliser les capacités de Benerator à importer des fichiers CSV.

Importons le fichier CSV idgenerator.import.csv.

Puis mettons à jour la valeur du champ IDVALUE.

Une autre solution est de tout faire lors de l'importation du fichier CSV à l'aide du mot clé condition.

Il ne reste plus qu'à exécuter Benerator pour générer notre jeu de données.

Notre fichier XML de description est prêt et je vous laisse le paramétrer au mieux pour l'objectif de vos tests.

Ma conclusion sur cet outil est toujours la même :

  • il est pratique ;
  • pilotable en ligne de commande et donc très flexible pour son intégration dans un processus ;
  • larges possibilités :

    • générer un jeu de données à partir de rien ;
    • anonymiser un jeu de données ;
    • traitement de données existantes comme pour un ETL ;
    • création de fichiers d'entrée pour un test de charge (création de login/password…) ;
  • possibilité d'utiliser le même fichier XML de configuration de Benerator pour divers environnements (test, développement,préproduction …) à l'aide de fichiers properties ;
  • documentation complète ;
  • développement actif ;
  • gratuit ;
  • open source ;
  • support par le développeur ;
  • extensible.

III. Conclusion

Dans ce tutoriel, nous avons présenté l'outil Benerator. C'est un outil de génération de données open source, dont le but premier est de générer d'importants lots de données pour des tests.

Benerator génère des entités abstraites sur la base d'un fichier de configuration. Les formats suivants sont supportés comme sources de données pour la génération : Comma Separated Values (CSV), XML, flat file, database et Excel sheet.

IV. Remerciements

Nous tenons à remercier Claude Leloup pour sa relecture de cet article et Laethy pour la mise au gabarit.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2015 Antonio Gomes-Rodrigues. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.