<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Fernando Ipar &#187; Testing</title>
	<atom:link href="http://fernandoipar.com/tag/testing/feed/" rel="self" type="application/rss+xml" />
	<link>http://fernandoipar.com</link>
	<description>I love mankind! Its people I can&#039;t stand!</description>
	<lastBuildDate>Tue, 06 Dec 2011 01:01:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Generating data with dbmonster</title>
		<link>http://fernandoipar.com/2009/08/14/generating-data-with-dbmonster/</link>
		<comments>http://fernandoipar.com/2009/08/14/generating-data-with-dbmonster/#comments</comments>
		<pubDate>Fri, 14 Aug 2009 20:02:56 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://fernandoipar.com/?p=182</guid>
		<description><![CDATA[In my last post I included some sample data which was useful for playing around with queries (once I published it, I realized it made my post look like some form of keyword stuffing, fortunately I don&#8217;t use adsense on my site so I hope I&#8217;m free of any suspicion ). That sample data was [...]


Related posts:<ol><li><a href='http://fernandoipar.com/2009/02/04/generating-random-salts-from-bash/' rel='bookmark' title='Permanent Link: Generating random salts from bash'>Generating random salts from bash</a> <small>From the &#8216;just because it can be done&#8217; column, here...</small></li><li><a href='http://fernandoipar.com/2009/03/09/using-the-enum-data-type-to-increase-performance/' rel='bookmark' title='Permanent Link: Using the ENUM data type to increase performance'>Using the ENUM data type to increase performance</a> <small>While going through the DATA TYPES section of the Certification...</small></li><li><a href='http://fernandoipar.com/2011/03/10/piping-data-to-multiple-processes/' rel='bookmark' title='Permanent Link: Piping data to multiple processes'>Piping data to multiple processes</a> <small>Here&#8217;s a simple shell script to stream data to multiple...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>
In my <a href="http://fernandoipar.com/2009/08/12/indexing-text-columns-in-mysql/">last post</a> I included some sample data which was useful for playing around with queries (once I published it,<br />
I realized it made my post look like some form of keyword stuffing, fortunately I don&#8217;t use adsense on my site so I hope I&#8217;m free of any suspicion <img src='http://fernandoipar.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> ).
</p>
<p>
That sample data was generated with dbmonster, a nice tool I discovered recently which comes in handy when you need to populate a database table to test your queries, the engine, schema, etc.
</p>
<p>
In a nutshell, here are the strengths I like about it:</p>
<ul>
<li>It&#8217;s written in Java, so it&#8217;ll feed any database with a JDBC driver, and AFAIK, that&#8217;s just about any RDBMS you might need to use</li>
<li>It&#8217;s not too slow (it&#8217;s actually pretty fast if you don&#8217;t go crazy on long text based datatypes)</li>
<li>It includes several data generators, and being written in Java, rolling out my own should be easy. </li>
</ul>
<p>As for the weaknesses:</p>
<ul>
<li>It can be unbearably slow with long text columns</li>
<li>The generated text data might not represent a very real installation (again, look at my previous post for a quick sample). Still, the fact that you can easily write and plug your own generator(s) is enough to give kudos to the developers for a good architecture. Even if a feature isn&#8217;t available now, it&#8217;s painless to add in the future</li>
<li><del>It has no way to manage relational integrity, hence, it doesn&#8217;t really feed RDBMS, just JDBC enabled databases</del> (yes it does, please see the comments)</li>
</ul>
<p>
<del>My last point means that, if you have table A and table B, both related through a foreign key constraint, dbmonster doesn&#8217;t provide a way for you to generate keys for table A and then reuse these keys<br />
while inserting the foreign keys in table B. Not that I&#8217;ve found so far, at least.</del>
</p>
<p>
Related with this limitation, tables are generated one at the time. Still, if you need a tool to populate tables, even very large ones, with random values, heck, up until a few days ago, I was doing this from<br />
bash or python, so it&#8217;s definitely an improvement. <del>I&#8217;ve discussed this with colleagues and some proprietary tools are either available or in the works that would handle referential integrity while<br />
generating data for database testing. If anyone knows an Open Source one that does, it&#8217;d be great. Otherwise, that would sure make one hell of a good project <img src='http://fernandoipar.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </del>
</p>
<p>
Ok, so enough rant, here&#8217;s some data: You get it from <a href="http://dbmonster.kernelpanic.pl/">here</a>.
</p>
<p>
Start off by creating a dbmonster.properties file. Here&#8217;s a sample:
</p>
<pre>
dbmonster.jdbc.driver=com.mysql.jdbc.Driver
dbmonster.jdbc.url=jdbc:mysql://localhost/sample_db
dbmonster.jdbc.username=mysql_user
dbmonster.jdbc.password=mysql_password

# for Oracle and other schema enabled databases
#dbmonster.jdbc.schema=schema_name

# maximal number of (re)tries
dbmonster.max-tries=50

# default rows number for SchemaGrabber
dbmonster.rows=1000

# progres monitor class
dbmonster.progress.monitor=pl.kernelpanic.dbmonster.ProgressMonitorAdapter
</pre>
<p>
Dbmonster is now ready to reach your database.<br />
Before it&#8217;s ready to feed it, though, you need to create an xml file (ah, yes, the plague of the Java world, and I&#8217;ve been a Java guy for most of my working years&#8230;). Call it what you want,<br />
being a consistent kind type of man, I&#8217;ve been using <schema-name>.xml. Here&#8217;s my sample_db.xml file:
</p>
<pre>
&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE dbmonster-schema PUBLIC "-//kernelpanic.pl//DBMonster Database Schema DTD 1.1//EN" "http://dbmonster.kernelpanic.pl/dtd/dbmonster-schema-1.1.dtd"&gt;
&lt;dbmonster-schema&gt;
  &lt;name&gt;Sample DB&lt;/name&gt;
  &lt;table name="jobs" rows="150000"&gt;
    &lt;key databaseDefault="true"&gt;
      &lt;generator type="pl.kernelpanic.dbmonster.generator.MaxKeyGenerator"&gt;
        &lt;property name="columnName" value="id"/&gt;
      &lt;/generator&gt;
    &lt;/key&gt;
    &lt;column name="title" databaseDefault="false"&gt;
      &lt;generator type="pl.kernelpanic.dbmonster.generator.StringGenerator"&gt;
        &lt;property name="allowSpaces" value="true"/&gt;
        &lt;property name="excludeChars" value=""/&gt;
        &lt;property name="maxLength" value="250"/&gt;
        &lt;property name="minLength" value="15"/&gt;
        &lt;property name="nulls" value="0"/&gt;
      &lt;/generator&gt;
    &lt;/column&gt;
    &lt;column name="link" databaseDefault="false"&gt;
      &lt;generator type="pl.kernelpanic.dbmonster.generator.StringGenerator"&gt;
        &lt;property name="allowSpaces" value="true"/&gt;
        &lt;property name="excludeChars" value=""/&gt;
        &lt;property name="maxLength" value="65500"/&gt;
        &lt;property name="minLength" value="150"/&gt;
        &lt;property name="nulls" value="0"/&gt;
      &lt;/generator&gt;
    &lt;/column&gt;
    &lt;column name="description" databaseDefault="false"&gt;
      &lt;generator type="pl.kernelpanic.dbmonster.generator.StringGenerator"&gt;
        &lt;property name="allowSpaces" value="true"/&gt;
        &lt;property name="excludeChars" value=""/&gt;
        &lt;property name="maxLength" value="65500"/&gt;
        &lt;property name="minLength" value="150"/&gt;
        &lt;property name="nulls" value="0"/&gt;
      &lt;/generator&gt;
    &lt;/column&gt;
    &lt;column name="city" databaseDefault="false"&gt;
      &lt;generator type="pl.kernelpanic.dbmonster.generator.StringGenerator"&gt;
        &lt;property name="allowSpaces" value="true"/&gt;
        &lt;property name="excludeChars" value=""/&gt;
        &lt;property name="maxLength" value="250"/&gt;
        &lt;property name="minLength" value="15"/&gt;
        &lt;property name="nulls" value="0"/&gt;
      &lt;/generator&gt;
    &lt;/column&gt;
    &lt;column name="postdate" databaseDefault="false"&gt;
      &lt;generator type="pl.kernelpanic.dbmonster.generator.DateTimeGenerator"&gt;
        &lt;property name="nulls" value="0"/&gt;
      &lt;/generator&gt;
    &lt;/column&gt;
    &lt;column name="company_id" databaseDefault="false"&gt;
      &lt;generator type="pl.kernelpanic.dbmonster.generator.NumberGenerator"&gt;
        &lt;property name="nulls" value="0"/&gt;
      &lt;/generator&gt;
    &lt;/column&gt;
    &lt;column name="country_id" databaseDefault="false"&gt;
      &lt;generator type="pl.kernelpanic.dbmonster.generator.NumberGenerator"&gt;
        &lt;property name="nulls" value="0"/&gt;
      &lt;/generator&gt;
    &lt;/column&gt;
  &lt;/table&gt;
&lt;/dbmonster-schema&gt;
</pre>
<p>
The file is pretty self explanatory. However, here are some pointers:</p>
<ul>
<li>You have a table tag for every generated table</li>
<li>A column tag for every column of every table (duh)</li>
<li>Column&#8217;s have generators. These are the Java classes that actually generate the value to insert into this column. Notice how you can specify the databasedefault=&#8221;true&#8221; attribute, which makes dbmonster omit generation for this column (good for auto increment columns / postgres sequences</li>
</ul>
<p>
Now let&#8217;s run it:
</p>
<pre>
export CLASSPATH=dbmonster*.jar:mysql*jar

java pl.kernelpanic.dbmonster.Launcher -s sample_db.xml

fipar@telecaster:~/soft/dbmonster-core-1.0.3$ java -classpath mysql-connector-java-5.1.6-bin.jar:dbmonster-core-1.0.3.jar pl.kernelpanic.dbmonster.Launcher -s sample_db.xml
2009-08-05 13:43:27,244 INFO  DBMonster - Let's feed this hungry database.
2009-08-05 13:43:27,697 INFO  DBCPConnectionProvider - Today we are feeding: MySQL 5.0.75-0ubuntu10.2-log
2009-08-05 13:43:27,783 INFO  Schema - Generating schema <Sample DB>.
2009-08-05 13:43:27,783 INFO  Table - Generating table <tasks>.
2009-08-05 13:44:18,749 INFO  Table - Generation of table <tasks> finished.
2009-08-05 13:44:18,750 INFO  Schema - Generation of schema <Sample DB> finished.
2009-08-05 13:44:18,750 INFO  DBMonster - Finished in 51 sec. 507 ms.
fipar@telecaster:~/soft/dbmonster-core-1.0.3$ mysql -p -e 'select count(*) from tasks' sample_db
Enter password:
+----------+
| count(*) |
+----------+
|    80000 |
+----------+

fipar@telecaster:~/soft/dbmonster-core-1.0.3$ java -cp dbmonster-core-1.0.3.jar:mysql-connector-java-5.1.6-bin.jar pl.kernelpanic.dbmonster.Launcher -s sample_db.xml
2009-08-06 10:27:24,747 INFO  DBMonster - Let's feed this hungry database.
2009-08-06 10:27:25,336 INFO  DBCPConnectionProvider - Today we are feeding: MySQL 5.0.75-0ubuntu10.2-log
2009-08-06 10:27:25,490 INFO  Schema - Generating schema <Sample DB>.
2009-08-06 10:27:25,490 INFO  Table - Generating table <tasks>.
2009-08-06 10:37:14,284 INFO  Table - Generation of table <tasks> finished.
2009-08-06 10:37:14,284 INFO  Schema - Generation of schema <Sample DB> finished.
2009-08-06 10:37:14,285 INFO  DBMonster - Finished in 9 min. 49 sec. 539 ms.
fipar@telecaster:~/soft/dbmonster-core-1.0.3$ mysql -p -e 'select count(*) from tasks' sample_db
Enter password:
+----------+
| count(*) |
+----------+
|   150000 |
+----------+
</pre>
<p>
Besides the obvious difference in the number of rows, the second generation had larger text values (char(250) vs char(40)). You can see how that affected generation time. It should have finished  (proportionally) in<br />
about 1:50, yet it took dbmonser almost 10 minutes to generate this data.
</p>
<p>
In conclusion, depending on the size of the database you need to generate, and the use you intend for it (forget testing a huge schema with referential constraints), dbmonster can certainly aid<br />
you in stress testing any database engine.</p>


<p>Related posts:<ol><li><a href='http://fernandoipar.com/2009/02/04/generating-random-salts-from-bash/' rel='bookmark' title='Permanent Link: Generating random salts from bash'>Generating random salts from bash</a> <small>From the &#8216;just because it can be done&#8217; column, here...</small></li><li><a href='http://fernandoipar.com/2009/03/09/using-the-enum-data-type-to-increase-performance/' rel='bookmark' title='Permanent Link: Using the ENUM data type to increase performance'>Using the ENUM data type to increase performance</a> <small>While going through the DATA TYPES section of the Certification...</small></li><li><a href='http://fernandoipar.com/2011/03/10/piping-data-to-multiple-processes/' rel='bookmark' title='Permanent Link: Piping data to multiple processes'>Piping data to multiple processes</a> <small>Here&#8217;s a simple shell script to stream data to multiple...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://fernandoipar.com/2009/08/14/generating-data-with-dbmonster/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Using MySQL sandbox for testing</title>
		<link>http://fernandoipar.com/2009/04/02/using-mysql-sandbox-for-testing/</link>
		<comments>http://fernandoipar.com/2009/04/02/using-mysql-sandbox-for-testing/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 23:28:05 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Sandbox]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://fernandoipar.com/?p=136</guid>
		<description><![CDATA[MySQL Sandbox is a great tool for quickly deploying test MySQL instances, particularly if your daily work involves diagnosing problems across multiple MySQL versions. Once you&#8217;ve downloaded it, it needs no installation. Just have a few MySQL binary releases at hand, and begin creating sandboxes in just a few seconds: ./make_sandbox mysql-5.0.77-linux-x86_64-glibc23.tar.gz or ./make_sandbox mysql-5.1.32-linux-x86_64-glibc23.tar.gz [...]


Related posts:<ol><li><a href='http://fernandoipar.com/2009/04/06/using-mysql-proxy-to-benchmark-query-performance/' rel='bookmark' title='Permanent Link: Using MySQL Proxy to benchmark query performance'>Using MySQL Proxy to benchmark query performance</a> <small>By transparently sitting between client and server on each request,...</small></li><li><a href='http://fernandoipar.com/2009/08/12/indexing-text-columns-in-mysql/' rel='bookmark' title='Permanent Link: Indexing text columns in MySQL'>Indexing text columns in MySQL</a> <small>This time, I&#8217;m talking about indexes for string typed columns....</small></li><li><a href='http://fernandoipar.com/2009/04/15/updated-mysql-proxy-benchmarking-script-for-proxy-07/' rel='bookmark' title='Permanent Link: Updated mysql-proxy benchmarking script (for proxy 0.7)'>Updated mysql-proxy benchmarking script (for proxy 0.7)</a> <small>My previous post contained a lua script for MySQL proxy...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><a title="MySQL Sandbox" href="https://launchpad.net/mysql-sandbox">MySQL Sandbox</a> is a great tool for quickly deploying test MySQL instances, particularly if your daily work involves diagnosing problems across multiple MySQL versions.</p>
<p>Once you&#8217;ve downloaded it, it needs no installation. Just have a few MySQL binary releases at hand, and begin creating sandboxes in just a few seconds:</p>
<blockquote><p>./make_sandbox mysql-5.0.77-linux-x86_64-glibc23.tar.gz</p></blockquote>
<p>or</p>
<blockquote><p>./make_sandbox mysql-5.1.32-linux-x86_64-glibc23.tar.gz</p></blockquote>
<p>Pretty simple, huh?</p>
<p>Suppose you have a parallel build around, say, 5.0.77-percona-highperf. The default syntax won&#8217;t work if you&#8217;ve already created a 5.0.77 sandbox, since Sandbox will use &#8217;5.0.77&#8242; as the sandbox dir. In this case, you&#8217;ll need to manually specify a directory name:</p>
<blockquote><p>./make_sandbox mysql-5.0.77-percona-highperf-b13.tar.gz -d msb_percona_5_0_77</p></blockquote>
<p>Fortunately, all Sandbox commands have a &#8211;help option that provide helpful screens to let you know how you can modify their default behavior. In this particular case, you&#8217;ll actually need to access the help for low_level_make_sandbox, since that&#8217;s the script that&#8217;s eventually called.</p>
<p>Once a sandbox is created, using it is real simple. Just cd to it&#8217;s directory (by default, $HOME/sandboxes/$SANDBOXDIR) and issue one of the following commands:</p>
<ul>
<li>./start</li>
<li>./stop</li>
<li>./restart</li>
<li>./use (this invokes the sandbox&#8217;s mysql client with appropriate parameters. you can append your own parameters too, i.e., a database name)</li>
<li>./clear (stops the server and removes everything from the data directory, leaving you ready to start from scratch)</li>
</ul>
<p>It even includes an option to create replication sandboxes, with a master node and two slaves. This is by default, but you can also create multiple sandboxes of the same version and configure replication yourself.</p>
<p>Here&#8217;s an example:</p>
<blockquote><p>./make_replication_sandbox mysql-5.0.77-linux-x86_64-glibc23.tar.gz</p></blockquote>
<p>So there it is, once again, <a title="MySQL Sandbox" href="https://launchpad.net/mysql-sandbox">download it</a> and start having fun!</p>


<p>Related posts:<ol><li><a href='http://fernandoipar.com/2009/04/06/using-mysql-proxy-to-benchmark-query-performance/' rel='bookmark' title='Permanent Link: Using MySQL Proxy to benchmark query performance'>Using MySQL Proxy to benchmark query performance</a> <small>By transparently sitting between client and server on each request,...</small></li><li><a href='http://fernandoipar.com/2009/08/12/indexing-text-columns-in-mysql/' rel='bookmark' title='Permanent Link: Indexing text columns in MySQL'>Indexing text columns in MySQL</a> <small>This time, I&#8217;m talking about indexes for string typed columns....</small></li><li><a href='http://fernandoipar.com/2009/04/15/updated-mysql-proxy-benchmarking-script-for-proxy-07/' rel='bookmark' title='Permanent Link: Updated mysql-proxy benchmarking script (for proxy 0.7)'>Updated mysql-proxy benchmarking script (for proxy 0.7)</a> <small>My previous post contained a lua script for MySQL proxy...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://fernandoipar.com/2009/04/02/using-mysql-sandbox-for-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

