Présentation de l'outil de génération de jeux de données Benerator

Antonio Gomes-Rodrigues

Afin qu'une campagne de tirs de charges soit la plus utile possible, il est souvent nécessaire d'avoir un jeu de données conséquent 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.

- Titre : Présentation de l'outil de génération de jeux de données Benerator

- Auteur : Antonio Gomes-Rodrigues

- Parution : 12 février 2012

- Licence : 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.

Sommaire

- I. Un peu de théorie

- II. Passons à la pratique

- II-A. Présentation du cas de test

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

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

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é 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.

On remarque que :

- les produits sont divisés en 4 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.

Et son code SQL.

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

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

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.

<!--?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 2 scripts SQL.

Drop des tables avant leurs créations

- Créons deux générateurs de nombre auto incrémenté 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 test 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
)

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 3 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
Person
et
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 a 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ées :

- 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 fichier 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.