tag:blogger.com,1999:blog-86281967720952305982024-03-16T11:52:22.025-07:00Maria MarcanoSomething about softwareMariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.comBlogger21125tag:blogger.com,1999:blog-8628196772095230598.post-6251125835221526402019-10-05T15:40:00.002-07:002019-10-05T15:40:27.611-07:00Moved to githubI'm moving to github and starting a new coding repo blog here <a href="https://mariangemarcano.github.io/">https://mariangemarcano.github.io/</a>. see you there!<div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com5tag:blogger.com,1999:blog-8628196772095230598.post-89531269571622809862015-03-17T15:21:00.000-07:002019-09-16T12:12:10.606-07:00Running Katana<span id="docs-internal-guid-22a843a5-286a-9ce6-0970-bbbc95156051"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">I have been developing features on top of buildbot on a project that we internally called Katana, which is a custom version based on 0.8.7.p1. </span></span><span style="font-family: "arial"; font-size: 15px; line-height: 1.38; white-space: pre-wrap;"><a href="https://blogs.unity3d.com/2014/06/02/katana-leveraging-open-source-tools-for-continuous-integration/">Here</a> Na’tosha gives a very good explanation about the </span><span style="font-family: arial;"><span style="font-size: 15px; line-height: 1.38; white-space: pre-wrap;"><a href="https://www.blogger.com/goog_296134570">project</a></span></span><span style="font-family: "arial"; font-size: 15px; line-height: 1.38; white-space: pre-wrap;"><a href="http://./">.</a> </span><br />
<div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt;">
<div style="line-height: 1.38;">
<span style="font-family: "arial"; font-size: 15px; line-height: 1.38; white-space: pre-wrap;"><br /></span></div>
<div style="line-height: 1.38;">
<span style="font-family: "arial"; font-size: 15px; line-height: 1.38; white-space: pre-wrap;">Now, I’m going to quickly go over some of the features and provide a more detailed explanation on how to get started running katana.</span></div>
<div style="line-height: 1.38;">
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div style="line-height: 1.38;">
<span id="docs-internal-guid-22a843a5-286c-664b-94e3-3d3089939619"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Overall features</b></span></span></div>
<div style="line-height: 1.38;">
<span id="docs-internal-guid-22a843a5-286c-9802-7f49-cff8484f949f"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Some of the features and customizations we have developed for katana:</span></span></div>
<ul>
<li><span style="font-family: "arial";"><span style="font-size: 15px; line-height: 20.7000007629395px; white-space: pre-wrap;">Multiple project support</span></span></li>
<li><span style="font-family: "arial";"><span style="font-size: 15px; line-height: 20.7000007629395px; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-286d-766a-40cf-55e1347e82f1">Build status page filters the information by project / branches</span></span></span></li>
<li><span style="font-family: "arial";"><span style="font-size: 15px; line-height: 20.7000007629395px; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-286d-95d5-ff7c-d215e7494fe6">Trigger builds and upload / download artifact dependencies</span></span></span></li>
<li><span style="font-family: "arial";"><span style="font-size: 15px; line-height: 20.7000007629395px; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-286d-bbb0-53bf-03cf2053fcae">New UI design</span></span></span></li>
<li><span style="font-family: "arial";"><span style="font-size: 15px; line-height: 20.7000007629395px; white-space: pre-wrap;">Real-time data </span></span></li>
<li><span style="font-family: "arial";"><span style="font-size: 15px; line-height: 20.7000007629395px; white-space: pre-wrap;">Authentication AD/LDAP, etc</span></span></li>
</ul>
<br />
<span id="docs-internal-guid-22a843a5-286e-43c1-ff54-c532deadba5d"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Get the code</b></span></span><br />
<span style="font-family: "arial"; font-size: 15px; line-height: 1.38; white-space: pre-wrap;">git clone https://github.com/Unity-Technologies/buildbot.git src</span><br />
<div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span id="docs-internal-guid-22a843a5-286f-054d-8cfb-f78f5ea03a11"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">git checkout katana (this is our stable branch)</span></span></div>
</div>
<div>
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<span id="docs-internal-guid-22a843a5-286f-d1f0-f907-17166233f7d0"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Development environmen</b>t</span></span><br />
<div>
<span id="docs-internal-guid-22a843a5-2870-d17d-e47d-239330ba0699"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">You can run katana in the same way as you do with buildbot (with a few differences):</span></span></div>
<div>
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<span id="docs-internal-guid-22a843a5-2871-287f-9c5d-d123969a0ee1"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Setup python virtual environment</b></span></span><br />
<span style="font-family: "arial"; font-size: 15px; white-space: pre-wrap;">virtualenv --no-site-packages katana-venv/</span><br />
<span style="font-family: "arial"; font-size: 15px; white-space: pre-wrap;">source katana-venv/bin/activate</span><br />
<div>
<span id="docs-internal-guid-22a843a5-2872-9c47-7dc0-7f531b8a42a5"></span><br />
<div style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span id="docs-internal-guid-22a843a5-2872-9c47-7dc0-7f531b8a42a5"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Python modules</b></span></span><br />
<span style="background-color: white; font-family: "arial"; font-size: 15px; line-height: 1.38; white-space: pre-wrap;">We are using the following modules</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; font-family: "arial"; font-size: 15px; line-height: 1.38; white-space: pre-wrap;">pip install -Iv SQLAlchemy-migrate==0.7.2</span><br />
<span style="background-color: white; font-family: "arial"; font-size: 15px; line-height: 1.38; white-space: pre-wrap;">pip install -Iv SQLAlchemy==0.7.9</span><br />
<span style="background-color: white; font-family: "arial"; font-size: 15px; line-height: 1.38; white-space: pre-wrap;">pip install python-ldap</span><br />
<span style="background-color: white; font-family: "arial"; font-size: 15px; line-height: 1.38; white-space: pre-wrap;">pip install mock</span><br />
<span style="background-color: white; font-family: "arial"; font-size: 15px; white-space: pre-wrap;">pip install mysql-python</span><br />
<b style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"><br /></b>
<b style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">Setup the master and slave</b></div>
</div>
<div>
<span id="docs-internal-guid-22a843a5-2875-2169-ee07-6ec920d1da94"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">pip install -e master</span></span></div>
<div>
<span id="docs-internal-guid-22a843a5-2875-46ea-e627-820f2e3bc346"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">pip install -e slave</span></span></div>
<div>
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<span id="docs-internal-guid-22a843a5-2875-951f-2393-452dce111ff0"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Check the running version</b></span></span><br />
<div>
<span id="docs-internal-guid-22a843a5-2875-f3b1-e85a-77616b119a74"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">buildbot --version</span></span></div>
<div>
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">buildslave --version</span></div>
<div>
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<span id="docs-internal-guid-22a843a5-2876-90e3-03b4-c8b35f2fee2e"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Run the tests</b></span></span><br />
<div>
<span id="docs-internal-guid-22a843a5-2876-ca59-e37b-6e0918fc734f"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">trial buildbot.test</span></span></div>
<div>
<span id="docs-internal-guid-22a843a5-2876-ec93-09af-48a6889dfe11"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">trial buildslave.test</span></span></div>
<div>
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<span id="docs-internal-guid-22a843a5-2877-1dda-6b21-f337fea91a01"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Create the buildmaster</b></span></span><br />
<div>
<span id="docs-internal-guid-22a843a5-2877-720f-0816-658c22ec614f"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">buildbot create-master buildmaster</span></span></div>
<div>
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<span id="docs-internal-guid-22a843a5-2877-9342-339d-5c7e53405723"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Change configuration file</b></span></span><br />
<div>
<span id="docs-internal-guid-22a843a5-2878-5c1a-88d4-d4cb4e16de87"><span style="background-color: white; font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">mv master.cfg.sample master.cfg</span></span></div>
<div>
<span style="background-color: white; color: #333333; font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div>
<span style="font-family: "arial";"><span style="background-color: white; font-size: 15px; white-space: pre-wrap;"><b>Change html folder</b></span></span></div>
<div>
<span id="docs-internal-guid-22a843a5-2879-4da5-7167-dbe739c67482"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Set the public_html folder to the one matching the resources (src)</span></span><br />
<span id="docs-internal-guid-22a843a5-2879-89e7-3a58-11fbc26be758"><span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg,</span></span></div>
<div>
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"> public_html="../src/www"))</span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><br /></span>
<br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Running the master</b></span></div>
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287a-45c9-4baf-20f0d0dbf204"><span style="background-color: white; vertical-align: baseline;">You should be able to see katana at </span><a href="http://localhost:8010/" style="text-decoration: none;"><span style="background-color: white; text-decoration: underline; vertical-align: baseline;">http://localhost:8010/</span></a><span style="background-color: white; vertical-align: baseline;"> after running:</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287a-6d77-b70c-e53c931a23d0"><span style="background-color: white; vertical-align: baseline;">buildbot start</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span style="background-color: white; color: #333333; vertical-align: baseline;"><br /></span></span>
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287a-b747-0c1c-9ccb77e48e85"><span style="background-color: white; color: #333333; vertical-align: baseline;"><img height="285px;" src="https://lh6.googleusercontent.com/3yVhF3ljMIqTyxrGR5XGevsHPCRXBkuSIs29k4Hr7tbLgCkcsoxJImMYB-Sq9D7AZfm_ckyWi4zV60ExqE_jBpfLIXUmC0mYsDjd1zvk3Tz045-gtmaPwIQ_I3nBkJwjwuLdaj0" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="446px;" /></span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span style="background-color: white; color: #333333; vertical-align: baseline;"><br /></span></span>
<br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287b-4f7c-8067-6fe0267593c8"><span style="background-color: white; vertical-align: baseline;">You should be able to login to katana using pyflakes user and password, the default example configuration</span></span></span><span style="background-color: white; font-family: "arial"; font-size: 15px; white-space: pre-wrap;"> should look this:</span><br />
<br />
<span style="background-color: white; color: #333333; font-family: "arial"; font-size: 15px; white-space: pre-wrap;"><br /></span>
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287b-a86b-d5f2-f3e6e3ebafea"><span style="background-color: white; color: #333333; vertical-align: baseline;">authz_cfg=authz.Authz(</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287b-cc4b-624c-ff11b55a5897"><span style="background-color: white; color: #333333; vertical-align: baseline;"> # change any of these to True to enable; see the manual for more</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287b-edab-27fd-2f23dbde0aa2"><span style="background-color: white; color: #333333; vertical-align: baseline;"> # options</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287c-11f3-3143-b9e0612bcdfa"><span style="background-color: white; color: #333333; vertical-align: baseline;"> auth=auth.BasicAuth([("pyflakes","pyflakes")]),</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287c-6d9f-133a-e48bca3b03c6"><span style="background-color: white; color: #333333; vertical-align: baseline;"> gracefulShutdown = False,</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287c-9421-6c2a-0648b080b2c3"><span style="background-color: white; color: #333333; vertical-align: baseline;"> forceBuild = 'auth', # use this to test your slave once it is set up</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287c-b94b-fa37-6a9baa757002"><span style="background-color: white; color: #333333; vertical-align: baseline;"> forceAllBuilds = False,</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287c-d43b-3374-f4277ca0e92d"><span style="background-color: white; color: #333333; vertical-align: baseline;"> pingBuilder = False,</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287c-f087-1d49-b7a38f8218c8"><span style="background-color: white; color: #333333; vertical-align: baseline;"> stopBuild = False,</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287d-0d51-a8d6-ed505706d23d"><span style="background-color: white; color: #333333; vertical-align: baseline;"> stopAllBuilds = False,</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287d-28df-9b87-79740a12a102"><span style="background-color: white; color: #333333; vertical-align: baseline;"> cancelPendingBuild = False,</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-22a843a5-287d-5f9e-2898-0670826f4b27"><span style="background-color: white; color: #333333; vertical-align: baseline;">)</span></span></span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><span style="background-color: white; color: #333333; vertical-align: baseline;"><br /></span></span>
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">If you sign in using pyflakes usr/password you will see Katana running</span><br />
<span style="font-family: "arial"; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><img height="360px;" src="https://lh5.googleusercontent.com/Xf6Lr4Ddw24ues6wrLPZAAcDrMRZBhTI4LrmEXmaGxEPvZTHLnHMf6d82QBfZCPYo2aDMKWmU6xBgSc0mL9GJabNrzfEgkP8N1WBUgPwqqHHXNza3Cg85pargMNWJN1hk4Dc7QM" style="-webkit-transform: rotate(0rad); border: none; transform: rotate(0rad);" width="624px;" /></span><br />
<span style="font-family: "arial"; font-size: 15px; white-space: pre-wrap;">That's all, next time will bring more examples of using Katana.</span></div>
<div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com43tag:blogger.com,1999:blog-8628196772095230598.post-16439568587473419202012-09-17T10:23:00.001-07:002012-09-18T03:35:00.570-07:00Speech Recognition – Setting up sclite word alignmentWord alignment is used to measure the accuracy of a decoder. <a href="http://www.speech.cs.cmu.edu/sphinx/tutorial.html">Sphinx tutorial</a> references sclite from National Institute of Standards and Technology (NIST). This time I’m going to share some notes on how to run and setup sclite.<br />
<br />
<h3>
Running sclite </h3>
Sclite is a tool for scoring and evaluating the output of speech recognition by comparing the hypothesized text (HYP) output by the speech recognizer to the correct, or reference (REF) text. After comparing REF to HYP, (a process called alignment), statistics are gathered during the scoring process and a variety of reports can be produced to summarize the performance of the recognition system.<br />
<br />
This is an example output using the files located src\sclite\testdata\tests.hyp and sclite\testdata\tests.ref: <br />
<br />
Parameters:<br />
<ul>
<li>The '-h' option is a required argument which specifies the input hypothesis file.</li>
<li>The '-r' option, a required argument, specifies the input reference file which the hypothesis file(s) are compared to.</li>
</ul>
<br />
<ul>
</ul>
<div>
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">sclite -h C:\Project\SpeechRecognition\CMUSphinx\3rdPartyLibs\sctk-2.4.3\src\sclite\testdata\tests.hyp -r C:\Project\SpeechRecognition\CMUSphinx\3rdPartyLibs\sctk-2.4.3\src\sclite\testdata\tests.ref</pre>
</div>
<br />
<a href="http://lh5.ggpht.com/-0gao-aBQ3s4/UFdccUo4fgI/AAAAAAAAANc/pF3m1wEwbvo/s1600-h/New%252520Picture%252520%2525281%252529%25255B2%25255D.png"><img alt="New Picture (1)" border="0" src="http://lh3.ggpht.com/-hdbAtMjAVPs/UFdcdQeCTYI/AAAAAAAAANk/jBLcYcRBA-8/New%252520Picture%252520%2525281%252529_thumb%25255B2%25255D.png?imgmax=800" style="background-image: none; border: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="New Picture (1)" /></a><br />
<br />
<br />
<h3>
Setup <a href="http://www.itl.nist.gov/iad/mig//tools/">sctk-2.4.0-20091110-0958.tar.bz2</a> on Windows 7</h3>
I downloaded Speech Recognition Scoring Toolkit (SCTK) which includes the SCLITE, ASCLITE, tranfilt, hubscr, SLATreport and utf_filt scoring tools.<br />
<br />
I could compile it with gcc version 3.4.4, found in the following MinGW setup package mingw-get-inst-20101030.exe.<br />
<br />
It was also necessary to modify 'src/rfilter1/makefile.in' and change the value of OPTIONS to be blank (as specified in the instructions)<br />
<br />
The following compilation error is thrown when compiling using gcc version 4.6.2:<br />
<br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">recording.h:122:29: error: 'Filter::Filter' cannot appear in a constant-expression
recording.h:122:36: error: template argument 2 is invalid
recording.h:122:36: error: template argument 4 is invalid
make[3]: *** [main.o] Error 1</pre>
</div>
<br />
<h3>
Setup <a href="http://www.nist.gov/itl/iad/mig/tools.cfm">sctk-2.4.2-20120810-0938.tar.bz2</a> on Windows 7</h3>
Something similar happened with this version, I could compile it with gcc version 3.4.4.<br />
<br />
The following compilation error is thrown when using gcc version 4.6.2: <br />
<br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">In file included from asctools.h:23:0,
from asctools.cpp:22:
timeval.h:33:8: error: redefinition of 'struct timeval'
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/../../../../include/winsock2.h:109:8: error: previous definition of 'struct timeval'
make[2]: *** [asctools.o] Error 1
make[2]: Leaving directory `/c/Project/SpeechRecognition/CMUSphinx/3rdPartyLibs/
sctk-2.4.2/src/asclite/test'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/c/Project/SpeechRecognition/CMUSphinx/3rdPartyLibs/
sctk-2.4.2/src/asclite'
make: *** [all] Error 2</pre>
<br /></div>
This is thrown when compiling <strong>rfilter1</strong><br />
<br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">gcc -o rfilter1 rfilter1.c
C:\Users\MANGEL~1\AppData\Local\Temp\ccuj1MU6.o:rfilter1.c:(.text+0x760): undefined reference to `strncmpi'
C:\Users\MANGEL~1\AppData\Local\Temp\ccuj1MU6.o:rfilter1.c:(.text+0x7c4): undefined reference to `strncmpi'
C:\Users\MANGEL~1\AppData\Local\Temp\ccuj1MU6.o:rfilter1.c:(.text+0x827): undefined reference to `strncmpi'
C:\Users\MANGEL~1\AppData\Local\Temp\ccuj1MU6.o:rfilter1.c:(.text+0x935): undefined reference to `strncmpi'
collect2: ld returned 1 exit status
make[1]: *** [rfilter1] Error 1
make[1]: Leaving directory `/c/Project/SpeechRecognition/CMUSphinx/3rdPartyLibs/sctk-2.4.2/src/rfilter1'
make: *** [all] Error 2</pre>
<br /></div>
It is also possible to compile this with gcc version 4.6.2 after removing asclite tests and rfilter1 from make file. <br />
<br />
After finishing the setup you are able to run sclite as described initially.<br />
<br />
<strong>Resources:</strong><br />
<ul>
<li><a href="http://www.speech.cs.cmu.edu/sphinx/tutorial.html" title="http://www.speech.cs.cmu.edu/sphinx/tutorial.html">http://www.speech.cs.cmu.edu/sphinx/tutorial.html</a></li>
<li><a href="http://www.itl.nist.gov/iad/mig//tools/">http://www.itl.nist.gov/iad/mig//tools/</a></li>
<li><a href="http://www.nist.gov/itl/iad/mig/tools.cfm" title="http://www.nist.gov/itl/iad/mig/tools.cfm">http://www.nist.gov/itl/iad/mig/tools.cfm</a></li>
<li>sclite documentation ctk-2.4.3/doc/sclite.htm</li>
<li>http://www.voxforge.org/home/forums/message-boards/speech-recognition-engines/can-nists-sclite-be-used-on-windows</li>
</ul>
<div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com24tag:blogger.com,1999:blog-8628196772095230598.post-3082107460643651182012-09-09T23:28:00.000-07:002012-09-12T05:27:53.175-07:00Speech Recognition with PocketSphinxThe following post puts together information from different sources about speech recognition and gives a brief overview of the CMUSphinx project and how to get started with PocketSphinx on Windows.<br />
<br />
<a href="http://cmusphinx.sourceforge.net/">CMUSphinx</a> project is an open source speech recognition project developed at <a href="http://en.wikipedia.org/wiki/Carnegie_Mellon_University">Carnegie Mellon University</a>, which consists of various tools use to build speech applications:<br />
<ul>
<li>CMUclmtk — language model tools </li>
<li>Sphinxtrain — acoustic model training tools</li>
</ul>
<br />
The following recognizers (decoders)<br />
<ul>
<li>Pocketsphinx: Designed to be fast and for real time speed written in C, supports desktop applications and mobile devices. It needs the library Sphinxbase. </li>
<li>Sphinx3: Speed recognizer intended for researchers . </li>
<li>Sphinx4: Speech recognition written in the Java.</li>
</ul>
<br />
Let’s learn how <a href="http://www.speech.cs.cmu.edu/sphinx/tutorial.html#prelimdecode">HMM based speech</a> recognition is handled: it functions by first learning the characteristics (or parameters) of a set of sound units, and then using what it has learned about the units to find the most probable sequence of sound units for a given speech signal. The process of learning about the sound units is called training. The process of using the knowledge acquired to deduce the most probable sequence of units in a given signal is called decoding, or simply recognition.<br />
<br />
<h4>
</h4>
<h4>
Setup Pocketsphinx on windows </h4>
Environment: Windows 7 and Visual Studio 2012, <a href="http://sourceforge.net/projects/cmusphinx/files/sphinxbase/0.7">sphinxbase-0.7</a>, <a href="http://sourceforge.net/projects/cmusphinx/files/pocketsphinx/0.7">pocketsphinx-0.7</a><br />
<br />
Name the folders (sphinxbase / pocketsphinx ), the project pocketsphinx has external dependencies that use the relative paths like the following “..\..\..\sphinxbase\include\sphinxbase\ad.h”.<br />
<br />
To test the installation let's run pocketsphinx_continuous.exe, this tool runs speech recognition both continuous listening from microphone and continuous file transcription. To run it requires:<br />
<ul>
<li>Copy sphinxbase.dll to the build folder, for example C:\Project\SpeechRecognition\CMUSphinx\pocketsphinx\bin\Debug. </li>
<li>The parameter –hmm, the directory containing acoustic model files. </li>
<li>The parameter –lm, word trigram language model input file. </li>
<li>The parameter –dict, main pronunciation dictionary (lexicon) input file.</li>
</ul>
<br />
This is running the command with the information contained in the project.<br />
<br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">pocketsphinx_continuous.exe -hmm C:\Project\SpeechRecognition\CMUSphinx\pocketsphinx\model\hmm\en_US\hub4wsj_sc_8k
-dict C:\Project\SpeechRecognition\CMUSphinx\pocketsphinx\model\lm\en_US\cmu07a.dic
-lm C:\Project\SpeechRecognition\CMUSphinx\pocketsphinx\model\lm\en_US\wsj0vp.5000.DMP</pre>
<br /></div>
<br />
<div id="codeSnippetWrapper">
this is the output of me saying “no no no” </div>
<br />
<a href="http://lh4.ggpht.com/-SnguC9dmPzs/UE41kUlA00I/AAAAAAAAANE/woeyW-l4tcs/s1600-h/New-Picture-22.png"><img alt="New Picture (2)" border="0" height="403" src="http://lh3.ggpht.com/-MFaKs5tBS1U/UE2In9tGJ_I/AAAAAAAAANM/jR61FHY6jIc/New-Picture-2_thumb2.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="New Picture (2)" width="984" /></a><br />
<br />
I will take a closer look at the project to check more the accuracy of the recognition.<br />
<br />
<h4>
Terminology<b></b></h4>
<b><a href="http://en.wikipedia.org/wiki/Language_model">language model</a></b> assigns a <a href="http://en.wikipedia.org/wiki/Probability">probability</a> to a sequence of <i>m</i> words P(w1, .., w1) by means of a <a href="http://en.wikipedia.org/wiki/Probability_distribution">probability distribution</a>. Language modeling is used in many <a href="http://en.wikipedia.org/wiki/Natural_language_processing">natural language processing</a> applications such as <a href="http://en.wikipedia.org/wiki/Speech_recognition">speech recognition</a>, <a href="http://en.wikipedia.org/wiki/Machine_translation">machine translation</a>, <a href="http://en.wikipedia.org/wiki/Part-of-speech_tagging">part-of-speech tagging</a>, <a href="http://en.wikipedia.org/wiki/Parsing">parsing</a> and <a href="http://en.wikipedia.org/wiki/Information_retrieval">information retrieval</a>. In <a href="http://en.wikipedia.org/wiki/Speech_recognition">speech recognition</a> and in <a href="http://en.wikipedia.org/wiki/Data_compression">data compression</a>, such a model tries to capture the properties of a language, and to predict the next word in a speech sequence.<br />
<br />
<strong><a href="http://en.wikipedia.org/wiki/Hidden_Markov_model">HMM</a>:</strong> (Hidden_Markov_model) is a <a href="http://en.wikipedia.org/wiki/Statistical_model">statistical</a> <a href="http://en.wikipedia.org/wiki/Markov_model">Markov model</a> in which the system being modeled is assumed to be a <a href="http://en.wikipedia.org/wiki/Markov_process">Markov process</a> with unobserved (<i>hidden</i>) states.<br />
<br />
<h4>
Resources:</h4>
<ul>
<li><a href="http://cmusphinx.sourceforge.net/">http://cmusphinx.sourceforge.net</a> </li>
<li>Recognizer/Decoder versions: <a href="http://cmusphinx.sourceforge.net/wiki/versions">http://cmusphinx.sourceforge.net/wiki/versions</a> </li>
<li>Toolkit overview: <a href="http://cmusphinx.sourceforge.net/wiki/tutorialoverview">http://cmusphinx.sourceforge.net/wiki/tutorialoverview</a> </li>
<li><a href="http://en.wikipedia.org/wiki/CMU_Sphinx">http://en.wikipedia.org/wiki/CMU_Sphinx</a> </li>
<li><a href="http://en.wikipedia.org/wiki/Language_model">http://en.wikipedia.org/wiki/Language_model</a> </li>
<li><a href="http://cmusphinx.sourceforge.net/wiki/tutorialpocketsphinx">http://cmusphinx.sourceforge.net/wiki/tutorialpocketsphinx</a> </li>
<li><a href="http://cmusphinx.sourceforge.net/wiki/tutorialpocketsphinx#windows">http://cmusphinx.sourceforge.net/wiki/tutorialpocketsphinx#windows</a> </li>
<li><a href="http://www.digipedia.pl/man/doc/view/pocketsphinx_continuous.1/">http://www.digipedia.pl/man/doc/view/pocketsphinx_continuous.1/</a></li>
</ul>
<div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com41tag:blogger.com,1999:blog-8628196772095230598.post-88726027415664340152012-08-28T23:36:00.000-07:002012-08-28T23:36:31.900-07:00Buildbot Part IV: Customize the schedulerMy previous post was about customizing buildbot to display more information on the waterfall page. Now let’s customize the scheduler to trigger the knightly build only if the continuous one hasn’t failed.
<br />
<br />
One way to accomplish this is by adding a new scheduler called <em>DependentNightly</em>, this scheduler receives a new parameter called <em>relatedBuilderNames</em> containing a set of builders that the scheduler should watch. The <em>startbuild</em> method will now check, for every related builder, the last finished build status and start the knightly build if no failures are found. Bellow master.cfg changes.<br />
<br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span style="color: navy; font-weight: bold;">from</span> buildbot.schedulers.basic <span style="color: navy; font-weight: bold;">import</span> SingleBranchScheduler
<span style="color: navy; font-weight: bold;">from</span> buildbot.schedulers.timed <span style="color: navy; font-weight: bold;">import</span> Nightly
<span style="color: navy; font-weight: bold;">from</span> buildbot.changes <span style="color: navy; font-weight: bold;">import</span> filter
<span style="color: navy; font-weight: bold;">from</span> buildbot.status.builder import SUCCESS, WARNINGS, FAILURE
<span style="color: navy; font-weight: bold;">from</span> twisted.python <span style="color: navy; font-weight: bold;">import</span> log
<span style="color: navy; font-weight: bold;">from</span> twisted.internet <span style="color: navy; font-weight: bold;">import</span> defer
<span style="color: navy; font-weight: bold;">class</span> <span style="color: blue; font-weight: bold;">DependentNightly</span>(Nightly):
relatedBuilderNames = []
<span style="color: navy; font-weight: bold;">def</span> <span style="color: teal; font-weight: bold;">__init__</span>(self, relatedBuilderNames = [], **kwargs):
Nightly.__init__(self, **kwargs)
self.relatedBuilderNames = relatedBuilderNames
<span style="color: navy; font-weight: bold;">def</span> <span style="color: teal; font-weight: bold;">startBuild</span>(self):
startBuild = True
<span style="color: navy; font-weight: bold;">for</span> builderName <span style="color: navy; font-weight: bold;">in</span> self.relatedBuilderNames:
builder_status = self.master.status.getBuilder(builderName)
lastBuild = builder_status.getLastFinishedBuild()
<span style="color: navy; font-weight: bold;">if</span> lastBuild != None:
startBuild = startBuild <span style="color: navy; font-weight: bold;">and</span> (lastBuild.getResults() != FAILURE)
<span style="color: navy; font-weight: bold;">if</span> (startBuild):
<span style="color: navy; font-weight: bold;">return</span> Nightly.startBuild(self)
<span style="color: navy; font-weight: bold;">else</span>:
log.msg((<span style="color: olive;">"Nightly Scheduler <%s>: skipping build. "</span> +
<span style="color: olive;">"- Related builder <%s> failed last build"</span>)
% (self.name, <span style="color: olive;">", "</span>.join(self.relatedBuilderNames)))
<span style="color: navy; font-weight: bold;">return</span> defer.succeed(None)
c[<span style="color: olive;">'schedulers'</span>] = []
c[<span style="color: olive;">'schedulers'</span>].append(SingleBranchScheduler(
name=<span style="color: olive;">"Continuous"</span>,
change_filter=filter.ChangeFilter(branch=<span style="color: olive;">'master'</span>),
treeStableTimer=<span style="color: teal;">3*60</span>,
builderNames=[<span style="color: olive;">"Continuous"</span>]))
c[<span style="color: olive;">'schedulers'</span>].append(DependentNightly(
name=<span style="color: olive;">"Ninghtly"</span>,
branch=<span style="color: olive;">'master'</span>,
hour=<span style="color: teal;">13</span>,
minute=<span style="color: teal;">24</span>,
onlyIfChanged=False,
builderNames=[<span style="color: olive;">"Ninghtly"</span>],
relatedBuilderNames=[<span style="color: olive;">"Continuous"</span>] ))</pre>
<br /></div>
<br />
When the scheduler finds out that the build won’t run, a message will be log to twistd.log file as shown bellow.<br />
<br />
<a href="http://lh3.ggpht.com/-bMq1DTf8YAI/UAU0IlY_KiI/AAAAAAAAAMI/9KpFhb_kVVg/s1600-h/skippingknightly%25255B1%25255D.png"><img alt="skippingknightly" border="0" height="208" src="http://lh5.ggpht.com/-DRdxrJ29y_8/UAU0J4rcrkI/AAAAAAAAAMQ/1DPeR8JeIhk/skippingknightly_thumb%25255B1%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="skippingknightly" width="981" /></a><br />
<br />
I hope this series of blog posts were helpful to give you an overall idea about using buildbot for CI. <div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com0tag:blogger.com,1999:blog-8628196772095230598.post-89497319697229285072012-08-23T02:50:00.000-07:002012-08-23T02:50:08.918-07:00Buildbot Part III: CustomizationsOn my previous post we configured buildbot to run automated build and tests. Now, let’s add <a href="http://buildbot.net/buildbot/docs/latest/manual/customization.html">customizations</a>, usually this configurations consists of subclasses set up for use in a regular buildbot configuration file (master.cfg).<br />
<br />
<h3>
Display more information in the waterfall</h3>
The first customization will be adding detail information in the waterfall page. One way to do this is writing a new <a href="http://buildbot.net/buildbot/docs/latest/manual/customization.html#writing-new-buildsteps">custom buildstep.</a> Most shell commands emit messages to stdout/stderr as they run, we will get output information from xunit.console.exe and use the functions provided by buildbot to perform summarization of the step base on the content of the stdio <a href="http://buildbot.net/buildbot/docs/current/manual/customization.html?highlight=getlog#reading-logfiles">logfile</a>. Bellow changes done to display details about the tests executed in a dll: total, failed, skipped and the time it took to perform the tests. <br />
<br />
<div>
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span style="color: navy; font-weight: bold;">class</span> <span style="color: blue; font-weight: bold;">xUnitConsole</span>(ShellCommand):
<span style="color: navy; font-weight: bold;">def</span> <span style="color: teal; font-weight: bold;">__init__</span>(self, **kwargs):
ShellCommand.__init__(self, **kwargs)
<span style="color: navy; font-weight: bold;">def</span> <span style="color: teal; font-weight: bold;">describe</span>(self, done=False):
description = ShellCommand.describe(self,done)
<span style="color: navy; font-weight: bold;">if</span> done:
description.append(<span style="color: olive;">'total: %d '</span> % self.step_status.getStatistic(<span style="color: olive;">'total'</span>, <span style="color: teal;">0</span>))
failed = self.step_status.getStatistic(<span style="color: olive;">'failed'</span>, <span style="color: teal;">0</span>)
<span style="color: navy; font-weight: bold;">if</span> failed > <span style="color: teal;">0</span>:
description.append(<span style="color: olive;">'failed: %d'</span> % failed)
skipped = self.step_status.getStatistic(<span style="color: olive;">'skipped'</span>, <span style="color: teal;">0</span>)
<span style="color: navy; font-weight: bold;">if</span> skipped > <span style="color: teal;">0</span>:
description.append(<span style="color: olive;">'skipped: %d'</span> % skipped)
description.append(<span style="color: olive;">'took: %s seconds'</span> % self.step_status.getStatistic(<span style="color: olive;">'time'</span>, <span style="color: teal;">0</span>))
<span style="color: navy; font-weight: bold;">return</span> description
<span style="color: navy; font-weight: bold;">def</span> <span style="color: teal; font-weight: bold;">createSummary</span>(self,log):
_re_result = re.compile(r<span style="color: olive;">'(\d*) total, (\d*) failed, (\d*) skipped, took (.*) seconds'</span>)
total = <span style="color: teal;">0</span>
failed = <span style="color: teal;">0</span>
skipped = <span style="color: teal;">0</span>
time = <span style="color: teal;">0</span>
lines = self.getLog(<span style="color: olive;">'stdio'</span>).readlines()
<span style="color: navy; font-weight: bold;">for</span> l <span style="color: navy; font-weight: bold;">in</span> lines:
m = _re_result.search(l)
<span style="color: navy; font-weight: bold;">if</span> m:
total = int(m.group(<span style="color: teal;">1</span>))
failed = int(m.group(<span style="color: teal;">2</span>))
skipped = int(m.group(<span style="color: teal;">3</span>))
time = m.group(<span style="color: teal;">4</span>)
self.step_status.setStatistic(<span style="color: olive;">'total'</span>, total)
self.step_status.setStatistic(<span style="color: olive;">'failed'</span>, failed)
self.step_status.setStatistic(<span style="color: olive;">'skipped'</span>, skipped)
self.step_status.setStatistic(<span style="color: olive;">'time'</span>, time)
<span style="color: navy; font-weight: bold;">def</span> <span style="color: teal; font-weight: bold;">RunTests</span>(factory, testproject, configuration, testdirectory):
factory.addStep(xUnitConsole(command=[<span style="color: olive;">'src\\xunit.console\\bin\\%s\\xunit.console.exe'</span> % configuration,
<span style="color: olive;">'%s\\%s'</span> % (testdirectory, testproject), <span style="color: olive;">"/html"</span>, <span style="color: olive;">"%s\\testresults.html"</span> % testdirectory],
workdir='build\\', name=<span style="color: olive;">"Run %s"</span> % testproject,
description=<span style="color: olive;">"Running %s"</span> % testproject ,
descriptionDone=<span style="color: olive;">"Run %s done"</span> % testproject,
flunkOnFailure=False, warnOnFailure=True))</pre>
</div>
<br />
<br />
We switched from using <em>ShellCommand</em> to use the new one <em>xUnitConsole</em>, bellow an image with the new information displayed in the waterfall page. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtfMXc23nRkyNEZj_kJYN5vK9G7DxK6JDQ60Qf6deaM5bG2QozHjgzCDGOj6u7k9hjynrDAO5EFBg0MeR4q69QK85FnQecQkRnzoq_4cc7BCI31gfQHfZhezihBh6LEM6ICa1n8GmFuTpX/s1600-h/buildbot-moreinfo2.png"><img alt="buildbot-moreinfo" border="0" height="575" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinM0zbi7QbV-YrxPlSjGWSOUfFKf0oP7_IkSusq75xh-BGX0YP1RYhXqCw1rchE_5JTZ-BnMPQnOFLo2pB-PFO3Lhy-Kz2saKY7aLnc3P5tMtVgaYlvCJRxVP9MbtAKhWE8J-G5sWOrn63/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="buildbot-moreinfo" width="670" /></a><br />
<br />
you can follow a similar approach to display more information in compiling buildstep, check the visual studio buildstep in <a href="https://github.com/buildbot/buildbot/blob/master/master/buildbot/steps/vstudio.py">vstudio.py</a>.<br />
<br />
<h3>
xunit.net report</h3>
Next customization will be adding a link to the report generated by xunit.console. The <a href="http://buildbot.net/buildbot/docs/0.8.5/manual/cfg-buildsteps.html#shellcommand">ShellCommand</a> has the parameter logfiles that is useful in this case, when a command logs information in a local file rather than emitting everything to stdout/stderr. By setting lazylogfiles=True, logfiles will be tracked lazily, meaning they will only be added when and if something is written to them. Finally, the <a href="http://buildbot.net/buildbot/docs/0.8.5/developer/cls-buildsteps.html#buildbot.process.buildstep.BuildStep.addLog">addHtmllog</a> adds a logfile containing pre-formatted HTML. Bellow the changes done in master.cfg.<br />
<br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span style="color: navy; font-weight: bold;">class</span> <span style="color: blue; font-weight: bold;">xUnitConsole</span>(ShellCommand):
<span style="color: navy; font-weight: bold;">def</span> <span style="color: teal; font-weight: bold;">__init__</span>(self, xunitreport=None, **kwargs):
ShellCommand.__init__(self, **kwargs)
<span style="color: navy; font-weight: bold;">def</span> <span style="color: teal; font-weight: bold;">describe</span>(self, done=False):
description = ShellCommand.describe(self,done)
<span style="color: navy; font-weight: bold;">if</span> done:
description.append(<span style="color: olive;">'total: %d '</span> % self.step_status.getStatistic(<span style="color: olive;">'total'</span>, <span style="color: teal;">0</span>))
failed = self.step_status.getStatistic(<span style="color: olive;">'failed'</span>, <span style="color: teal;">0</span>)
<span style="color: navy; font-weight: bold;">if</span> failed > <span style="color: teal;">0</span>:
description.append(<span style="color: olive;">'failed: %d'</span> % failed)
skipped = self.step_status.getStatistic(<span style="color: olive;">'skipped'</span>, <span style="color: teal;">0</span>)
<span style="color: navy; font-weight: bold;">if</span> skipped > <span style="color: teal;">0</span>:
description.append(<span style="color: olive;">'skipped: %d'</span> % skipped)
description.append(<span style="color: olive;">'took: %s seconds'</span> % self.step_status.getStatistic(<span style="color: olive;">'time'</span>, <span style="color: teal;">0</span>))
<span style="color: navy; font-weight: bold;">return</span> description
<span style="color: navy; font-weight: bold;">def</span> <span style="color: teal; font-weight: bold;">createSummary</span>(self,log):
html = self.getLog(<span style="color: olive;">"xunit-report"</span>)
text = html.getText()
self.addHTMLLog(<span style="color: olive;">"xunit-report.html"</span>, text)
_re_result = re.compile(r<span style="color: olive;">'(\d*) total, (\d*) failed, (\d*) skipped, took (.*) seconds'</span>)
total = <span style="color: teal;">0</span>
failed = <span style="color: teal;">0</span>
skipped = <span style="color: teal;">0</span>
time = <span style="color: teal;">0</span>
lines = self.getLog(<span style="color: olive;">'stdio'</span>).readlines()
<span style="color: navy; font-weight: bold;">for</span> l <span style="color: navy; font-weight: bold;">in</span> lines:
m = _re_result.search(l)
<span style="color: navy; font-weight: bold;">if</span> m:
total = int(m.group(<span style="color: teal;">1</span>))
failed = int(m.group(<span style="color: teal;">2</span>))
skipped = int(m.group(<span style="color: teal;">3</span>))
time = m.group(<span style="color: teal;">4</span>)
self.step_status.setStatistic(<span style="color: olive;">'total'</span>, total)
self.step_status.setStatistic(<span style="color: olive;">'failed'</span>, failed)
self.step_status.setStatistic(<span style="color: olive;">'skipped'</span>, skipped)
self.step_status.setStatistic(<span style="color: olive;">'time'</span>, time)
<span style="color: navy; font-weight: bold;">def</span> RunTests(factory, testproject, configuration, testdirectory):
factory.addStep(xUnitConsole(command=[<span style="color: olive;">'src\\xunit.console\\bin\\%s\\xunit.console.exe'</span> % configuration,
<span style="color: olive;">'%s\\%s'</span> % (testdirectory, testproject), <span style="color: olive;">"/html"</span>, <span style="color: olive;">"%s\\testresults.html"</span> % testdirectory],
workdir='build\\', name=<span style="color: olive;">"Run %s"</span> % testproject,
description=<span style="color: olive;">"Running %s"</span> % testproject ,
descriptionDone=<span style="color: olive;">"Run %s done"</span> % testproject,
flunkOnFailure=False, warnOnFailure=True,
logfiles = {<span style="color: olive;">"xunit-report"</span> : <span style="color: olive;">"%s\\testresults.html"</span> % testdirectory }, lazylogfiles=True))</pre>
</div>
<br />
<br />
The waterfall page now has a link to xunit.net report, as you can see bellow:<br />
<br />
<table border="0" cellpadding="2" cellspacing="0"><tbody>
<tr><td valign="top"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMPbwRxIU5D_1fdTEmDVON143f1rzeGy1bOgrmQS1fZLi9OG8pb2IBofitFGjsCr5uHjHS8ZTBF3Anxna-KV6X4lwVBeqQYVJFrMAoQkH7W8TUjSp9_2abNmld18Xmaaf0yK3MI56QJwmJ/s1600-h/Buildbot-report4.png"><img alt="Buildbot-report" border="0" height="425" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_AdR_X4SZrp7gYqH_FDafU1OHKh1pNR8wddBdbowVYMZsoQFW6vlR_u6XVdBk3v9IJ1CF3VeBLSFr_YCNJJLCRJQinRFVWnk0EYiyUpRfPQW78wMvJt83h22LAZCMRo9XRPdXkKYk35XG/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Buildbot-report" width="423" /></a></td><td valign="top"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfQM6bOloan0076sUhvPmQxT67HggTYs1_Dpp8NdoBBoMlL0W26IeZBOAdJJSTpxdAOjBGzF88wReWnPT3VyVA1JBdBhOvpk0fnNI8cCc6M2bmz7VeEUsmtKgQSBpBT_9ndhnF0jXqnSod/s1600-h/xunitreport1.png"><img alt="xunitreport" border="0" height="344" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibiUS7BOdwrOcdCX5xtzCZGaRx1hUIUr4Q1WODJyEc6o0Ncu4GbRkoQ32N0zhAbiJpTKqhfceyUeqzS3BDMVqdZjpJDksajvkC3EShTyDg1DLeVRmfbID9SqeG6dSA2MWXjrk1UCP8Nthu/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="xunitreport" width="595" /></a></td></tr>
</tbody></table>
<br />
On my next post I’ll show you how to customize the scheduler. <div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com0tag:blogger.com,1999:blog-8628196772095230598.post-90981245623189639892012-08-09T00:51:00.000-07:002012-08-09T00:51:35.978-07:00Buildbot Part II – Running automated build and testsOn my previous post we setup buildbot. Now, let’s configure it to run automated builds and tests. To do this, I’ll be using my xUnit.Net fork hosted on git/codeplex.<br />
Make the following changes to <a href="http://buildbot.net/buildbot/docs/current/manual/configuration.html#configuration">master.cfg</a>:<br />
<br />
<h3>
Connect to the buildslave</h3>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">c[<span style="color: olive;">'slaves'</span>] = [BuildSlave(<span style="color: olive;">"BuildSlave01"</span>, <span style="color: olive;">"mysecretpwd"</span>)]</pre>
</div>
<br />
<h3>
Track repository – GitPoller</h3>
The <a href="http://buildbot.net/buildbot/docs/latest/manual/cfg-changesources.html?highlight=gitpoller#chsrc-GitPoller">gitpoller</a> periodically fetches from a remote git repository and process any changes. <br />
<br />
<div>
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span style="color: navy; font-weight: bold;">from</span> buildbot.changes.gitpoller <span style="color: navy; font-weight: bold;">import</span> GitPoller
c[<span style="color: olive;">'change_source'</span>] = []
c[<span style="color: olive;">'change_source'</span>].append(GitPoller(
<span style="color: olive;">'https://git01.codeplex.com/forks/mariangemarcano/xunit'</span>,
gitbin=<span style="color: olive;">'C:\\Program Files (x86)\\Git\\bin\\git.exe'</span>,
workdir=<span style="color: olive;">'gitpoller_work'</span>,
pollinterval=<span style="color: teal;">300</span>))</pre>
</div>
<br />
<h3>
Add scheduler</h3>
There are different types of <a href="http://buildbot.net/buildbot/docs/current/manual/cfg-schedulers.html">schedulers</a> supported by buildbot and you can customize it. Let’s add a single branch scheduler to run the build whenever a change is committed to the repository and knightly schedulers to run the build once a day. <br />
<br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span style="color: navy; font-weight: bold;">from</span> buildbot.schedulers.basic <span style="color: navy; font-weight: bold;">import</span> SingleBranchScheduler
<span style="color: navy; font-weight: bold;">from</span> buildbot.schedulers.timed <span style="color: navy; font-weight: bold;">import</span> Nightly
<span style="color: navy; font-weight: bold;">from</span> buildbot.changes <span style="color: navy; font-weight: bold;">import</span> filter
c[<span style="color: olive;">'schedulers'</span>] = []
c[<span style="color: olive;">'schedulers'</span>].append(SingleBranchScheduler(
name=<span style="color: olive;">"Continuous"</span>,
change_filter=filter.ChangeFilter(branch=<span style="color: olive;">'master'</span>),
treeStableTimer=<span style="color: teal;">3*60</span>,
builderNames=[<span style="color: olive;">"Continuous"</span>]))
c[<span style="color: olive;">'schedulers'</span>].append(Nightly(
name=<span style="color: olive;">"Ninghtly"</span>,
branch=<span style="color: olive;">'master'</span>,
hour=<span style="color: teal;">3</span>,
minute=<span style="color: teal;">30</span>,
onlyIfChanged=True,
builderNames=[<span style="color: olive;">"Ninghtly"</span>]))</pre>
</div>
<br />
<h3>
Define a Build Factory</h3>
It contains the steps that a build will follow. In our case, we need to get source from repository, compile xunit.net projects and run the tests. <br />
<br />
<strong>Get source from repository</strong>: Let’s do an incremental update for continuous build and compile debug; the full build will do a full repository checkout and compile using release configuration. The git factory needs to access git binaries, set the environment path to where you install it for example: C:\Program Files (x86)\Git\bin\.<br />
<br />
<strong>Compile xunit.net and run tests</strong>: Let’s compile using <a href="http://msdn.microsoft.com/en-us/library/ms164311.aspx">MSbuild.exe</a> and run the tests with xunit.console.exe. By setting flunkOnFailure=False/warnOnFailure=True, test failures will mark the overall build as having warnings.<br />
<br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span style="color: navy; font-weight: bold;">from</span> buildbot.process.factory <span style="color: navy; font-weight: bold;">import</span> BuildFactory
<span style="color: navy; font-weight: bold;">from</span> buildbot.steps.source.git <span style="color: navy; font-weight: bold;">import</span> Git
<span style="color: navy; font-weight: bold;">from</span> buildbot.steps.shell <span style="color: navy; font-weight: bold;">import</span> ShellCommand
<span style="color: navy; font-weight: bold;">def</span> <span style="color: teal; font-weight: bold;">MSBuildFramework4</span>(factory, configuration, projectdir):
factory.addStep(ShellCommand(command=[<span style="color: olive;">'%windir%\\Microsoft.NET\\Framework\\v4.0.30319\\MSbuild.exe'</span>,
<span style="color: olive;">'xunit.msbuild'</span>, <span style="color: olive;">'/t:Build'</span>, <span style="color: olive;">'/p:Configuration=%s'</span> % configuration],
workdir=projectdir, name=<span style="color: olive;">"Compile xunit.net projects"</span>,
description=<span style="color: olive;">"Compiling xunit.net projects"</span>,
descriptionDone=<span style="color: olive;">"Copile xunit.net projects done"</span>))
<span style="color: navy; font-weight: bold;">def</span> <span style="color: teal; font-weight: bold;">RunTests</span>(factory, testproject, configuration, testdirectory):
factory.addStep(ShellCommand(command=[<span style="color: olive;">'src\\xunit.console\\bin\\%s\\xunit.console.exe'</span> % configuration,
<span style="color: olive;">'%s\\%s'</span> % (testdirectory, testproject), <span style="color: olive;">"/html"</span>, <span style="color: olive;">"%s\\testresults.html"</span> % testdirectory],
workdir=<span style="color: olive;">'build\\'</span>, name=<span style="color: olive;">"Run %s"</span> % testproject,
description=<span style="color: olive;">"Running %s"</span> % testproject ,
descriptionDone=<span style="color: olive;">"Run %s done"</span> % testproject,
flunkOnFailure=False, warnOnFailure=True))
factory_continuous = BuildFactory()
factory_continuous.addStep(Git(repourl='<span style="color: olive;">https://git01.codeplex.com/forks/mariangemarcano/xunit'</span>, mode=<span style="color: olive;">'incremental'</span>))
MSBuildFramework4(factory_continuous, <span style="color: olive;">'Debug'</span>, <span style="color: olive;">'build\\'</span>)
RunTests(factory_continuous, <span style="color: olive;">'test.xunit.dll'</span>, <span style="color: olive;">'Debug'</span>, <span style="color: olive;">'test\\test.xunit\\bin\\Debug'</span>)
RunTests(factory_continuous, <span style="color: olive;">'test.xunit.gui.dll</span>', <span style="color: olive;">'Debug'</span>, <span style="color: olive;">'test\\test.xunit.gui\\bin\\Debug'</span>)
factory_ninghtly = BuildFactory()
factory_ninghtly.addStep(Git(repourl=<span style="color: olive;">'https://git01.codeplex.com/forks/mariangemarcano/xunit'</span>, mode=<span style="color: olive;">'full'</span>, method=<span style="color: olive;">'clobber'</span>))
MSBuildFramework4(factory_ninghtly, <span style="color: olive;">'Release'</span>, <span style="color: olive;">'build\\'</span>)
RunTests(factory_ninghtly, <span style="color: olive;">'test.xunit.dll'</span>, <span style="color: olive;">'Release'</span>, <span style="color: olive;">'test\\test.xunit\\bin\\Release'</span>)
RunTests(factory_ninghtly, <span style="color: olive;">'test.xunit.gui.dll'</span>, <span style="color: olive;">'Release'</span>, <span style="color: olive;">'test\\test.xunit.gui\\bin\\Release'</span>)</pre>
</div>
<br />
<h3>
Builder Configuration</h3>
<br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span style="color: navy; font-weight: bold;">from</span> buildbot.config <span style="color: navy; font-weight: bold;">import</span> BuilderConfig
c[<span style="color: olive;">'builders'</span>] = []
c[<span style="color: olive;">'builders'</span>].append(
BuilderConfig(name=<span style="color: olive;">"Continuous"</span>,
slavenames=[<span style="color: olive;">"BuildSlave01"</span>],
factory=factory_continuous))
c[<span style="color: olive;">'builders'</span>].append(
BuilderConfig(name=<span style="color: olive;">"Ninghtly"</span>,
slavenames=[<span style="color: olive;">"BuildSlave01"</span>],
factory=factory_ninghtly))</pre>
</div>
<br />
<h3>
Status notifications</h3>
You could also add MailNotifier to configure mail notifications. <br />
<br />
<div>
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">c[<span style="color: olive;">'status'</span>] = []
<span style="color: navy; font-weight: bold;">from</span> buildbot.status <span style="color: navy; font-weight: bold;">import</span> html
<span style="color: navy; font-weight: bold;">from</span> buildbot.status.web <span style="color: navy; font-weight: bold;">import</span> authz, auth
authz_cfg=authz.Authz(
<span style="color: green;"># change any of these to True to enable; see the manual for more</span>
<span style="color: green;"># options</span>
gracefulShutdown = False,
forceBuild = True, <span style="color: green;"># use this to test your slave once it is set up</span>
forceAllBuilds = False,
pingBuilder = True,
stopBuild = True,
stopAllBuilds = False,
cancelPendingBuild = True,
)
c[<span style="color: olive;">'status'</span>].append(html.WebStatus(http_port=<span style="color: teal;">8010</span>, authz=authz_cfg))</pre>
</div>
<br />
Every commit done will trigger a continuous build that automatically compiles and runs tests. In the waterfall page you can see the people who has committed changes to the branch (view image bellow).<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0a-RqiOmg_mkh3HWykPshGfbJDWhpUor-ukAnrWG6O19_GyeKnkw3WLPFGEWqzNBa1NKWSd_ANW5Vn3kDzFnv1lXTaEM8-pdKq5jtH3Qghi0A0_mOG0832C1Y30-s16dMspoTb8PIVjzq/s1600-h/Buildbot-waterfall%25255B2%25255D.png"><img alt="Buildbot-waterfall" border="0" height="537" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiecf9CMsc3nZ1RNVef8l_f1KlauofIvrNiA_38kMe4OKwwxSF6lZFC5XKDImxHD6STgYO52xvodQW1AAPwRVLpXkDZZZbfG_nIluMXeftUjuDtUR5KkxEc7vO6npbDUXmN0mI0EtuUVIzz/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Buildbot-waterfall" width="637" /></a><br />
<br />
Click on the person’s name to view commit’s detail information like repository, branch and revision. At the bottom there is a list of changed files. This is very helpful to track down any failures (view image bellow).<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiupACUAZp_D2s3yxSXmXMuWW6cRuO-2ZcV44t1XhnB5rS_JCYXhEteL5JhXI8xNRThV-b_T8n36tZ0KFkgjKX5VXVMaerraDB4f1mVU9KpzNs6CjjFdGRUrNLrH6hFQ_WHt3-UgQbDxtBE/s1600-h/change-detail%25255B1%25255D.png"><img alt="change-detail" border="0" height="380" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMP5GV9NyNzVxi-fymJUyuWGx1ppBjpNxy4Jc4qRcAGaru3ym19SuHm5NCtlkp1jqM_Y5wyhxmQorxL9m9DNIJlfYgqmdtGE7JrY8z30WnVz1HjmyQGTFpiQmnOUkL7Nj4YMnpi6WQBanM/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="change-detail" width="653" /></a><br />
<br />
On my next blog post I’ll show you how to add customizations.<div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com1tag:blogger.com,1999:blog-8628196772095230598.post-41307670657789858592012-07-31T22:48:00.000-07:002012-07-31T22:48:29.534-07:00Buildbot Part I - Setting Up<a href="http://trac.buildbot.net/">Buildbot</a> is a Python-based continuous integration system that <a href="http://buildbot.net/buildbot/docs/current/manual/introduction.html">consists</a> of a buildmaster and one or more buildslaves, you can check it out on <a href="https://github.com/buildbot/buildbot">github</a>.
<br />
<br />
<div align="justify">
The buildmaster decides what, when and how the system is build, it has a configuration file called <a href="http://buildbot.net/buildbot/docs/current/manual/configuration.html#configuration">master.cfg</a> where the build process is defined. On the other hand, the buildslaves handle the execution of the commands and return results to the master.</div>
<div align="justify">
<br />
The following is a graph (from <a href="http://buildbot.net/buildbot/docs/current/manual/introduction.html">buildbot’s wiki</a>) shows buildbot architecture supported repositories and notifiers.<br />
<br /></div>
<a href="http://buildbot.net/buildbot/docs/current/manual/introduction.html"><img alt="buildbot" border="0" height="282" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRY4xpppIEbRAP6L8-45aRchcrOPGy7_VczzsMe4qpMRNAOMqzNmZ6FY6zSEnjvMDM3X7eH7Qq4LItKiRBxCDPTFTFV0peJaICpoFjG8mqanErkZmo2mF9e6axHjjVTpCUhp4RbR5X3fWj/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="buildbot" width="586" /></a>
<br />
<h3>
</h3>
<h3>
Setting up</h3>
<br />
To <a href="http://buildbot.net/buildbot/docs/current/manual/installation.html">setup</a> on windows, the master and slaves require: <br />
<ul>
<li>Python 2.7 <a href="http://www.python.org/download/">http://www.python.org/download/</a> and setuptools <a href="http://pypi.python.org/pypi/setuptools/0.6c11">http://pypi.python.org/pypi/setuptools/0.6c11</a>. </li>
<li>Twisted <a href="http://twistedmatrix.com/">http://twistedmatrix.com</a> (I’m using 12.1.0 for Python 2.7 64 bits). </li>
<li>Twisted requires PyWin32 in order to spawn processes on Windows <a href="http://sourceforge.net/projects/pywin32/">http://sourceforge.net/projects/pywin32/</a> (downloaded pywin32-217.win-amd64-py2.7).</li>
</ul>
Additionally, master requires:<br />
<ul>
<li>sqlite3: <a href="http://www.sqlite.org/">http://www.sqlite.org</a> (sqlite-dll-win32-x64-3071300). </li>
<li>Jinja2: <a href="http://jinja.pocoo.org/">http://jinja.pocoo.org/</a> (<a href="http://pypi.python.org/pypi/Jinja2/2.6">http://pypi.python.org/pypi/Jinja2/2.6</a>). </li>
<li>SQLAlchemy <a href="http://www.sqlalchemy.org/">http://www.sqlalchemy.org/</a> (SQLAlchemy-0.7.8). </li>
<li>SQLAlchemy-Migrate <a href="http://code.google.com/p/sqlalchemy-migrate/" title="http://code.google.com/p/sqlalchemy-migrate/">http://code.google.com/p/sqlalchemy-migrate/</a> (sqlalchemy-migrate-0.7.1.tar)</li>
</ul>
Install buildbotmaster (<a href="http://buildbot.googlecode.com/files/buildbot-0.8.6p1.tar.gz" title="http://buildbot.googlecode.com/files/buildbot-0.8.6p1.tar.gz">http://buildbot.googlecode.com/files/buildbot-0.8.6p1.tar.gz</a>) and buildbotslave (<a href="http://buildbot.googlecode.com/files/buildbot-slave-0.8.6p1.tar.gz" title="http://buildbot.googlecode.com/files/buildbot-slave-0.8.6p1.tar.gz">http://buildbot.googlecode.com/files/buildbot-slave-0.8.6p1.tar.gz</a>)<br />
<br />
For this example, I installed both on same machine, if the installation went ok you should be able to check their versions:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUzZnjtGkDGdZxrrn2-EaRXZKSQDWJCM39t6-31-COxlxnH1Oonn4yF4WSJa6KDWL4R1L53W1h6s1QPuGrZj-8aI-fUsPRLmRyIuaQ5BBuX0jTx_BPrn82ikJ8Q5IVjmT4PeZzL0qsqYEc/s1600-h/buildbotsetup4.png"><img alt="buildbotsetup" border="0" height="172" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRV8MSkMUQ2ORirMz_DDm7euy751DUR5xBri8mDYRtSHrJjrv8azYEKw1so5A5eRyvUtmP1DLN0XST2feXbmQ9w_1CFeFGeYBYT5BTfkL7fE3aaCNgBwTkQPDZsbb3RaEEB7tHvM2ij1zI/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="buildbotsetup" width="448" /></a><br />
<br />
The following steps creates and starts the master and slave:<br />
<br />
<h3>
Create BuildbotMaster</h3>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">C:\Python27\Scripts>buildbot create-master -r C:\BuildMaster</pre>
</div>
<br />
<h3>
Create BuildbotSlave</h3>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">C:\Python27\Scripts>buildslave create-slave C:\BuildSlave localhost:9989 BuildSlave01 mysecretpwd</pre>
</div>
<br />
<h3>
Start BuildbotMaster</h3>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">C:\Python27\Scripts>buildbot start c:\BuildMaster</pre>
</div>
<br />
<h3>
Start BuildbotSlave</h3>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">C:\Python27\Scripts>buildslave start c:\BuildSlave</pre>
</div>
<br />
if everything went fine you should see a page like the following:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlZVIdO4VpTu4nWtVfsOunstdF2E9zh6nMsSg2U6XLOQ_cMSVS6IwXuWA7bXSEtxFQ1Os9K2GEu6N7vzz-1X1d3EQYJVcb8sM_w_AQMCQG-3aJqilPN-M4b8LvaM0jRa5hob36DoZD-TlX/s1600-h/buildbotpage7.png"><img alt="buildbotpage" border="0" height="394" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEEz4n1Ss7HBCbhyWDO3BZAzvvG7KAtfYXsZVPyYIat5PEyyP_8KvPIwE2Epa_nhfMW7xqcgC-tlyaExeUaRjnaFjXiTjyaex2Wz4KWGeh9AkCcuxE0WSFYJfHNWJEUDvQVyrYRbF7BNGk/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="buildbotpage" width="697" /></a><br />
<br />
You can check for errors on C:\BuildMaster\twistd.log and C:\BuildSlave\twistd.log.<br />
<br />
Who is using <a href="http://trac.buildbot.net/wiki/SuccessStories">buildbot</a>: Python, Mozilla, Google Chromium and others. The following shows Python 2.7 waterfall page:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgucuj-td92ZsgDw40syCUCuqeewceF1-Oa4fB0sLCaetlN0PP4zwMTn-ERvwesQPplIw3kmeFu6aOQpzm0Nw1MBsEX8w1-siMrmFbqa-gchN4FZCsapkEL_sFa0GW6lRobC5A58BcWUG1W/s1600-h/PythonBuildbot%25255B12%25255D.png"><img alt="PythonBuildbot" border="0" height="490" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSc-KWVCB_i-PiKOg9lxeeESyYirmohyztonnHb7DHm4Yb91_9_yntU7MrHrh78oUlADK6dkfklp9vIkWYSN5Z7xhLUXydKlUgQeG8wvK1t2F1fRkmxmLfWVNaGKoCqxG55d2indqFFbwc/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="PythonBuildbot" width="820" /></a><br />
<br />
On my next post I’ll show you how to run automated builds and tests for a .net application hosted on git/codeplex using buildbot.<div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com0Copenhagen, Denmark55.6760968 12.568337155.604617800000007 12.4104086 55.7475758 12.726265600000001tag:blogger.com,1999:blog-8628196772095230598.post-3838905282805789702012-06-27T09:30:00.000-07:002012-06-27T00:52:27.215-07:00Virtualization using Proxmox VE<p><a href="http://pve.proxmox.com/wiki/Main_Page"> <div id="codeSnippetWrapper">Proxmox Virtual Environment</a> is an open source virtualization platform for running virtual machines with a web UI to manage the VMs and view resource usage. It allows 32/64 bit Windows, Linux and more. </div> <div> </div> <div>I would like to share some information about Proxmox and a few common actions I learned on a previous project. Although I used an earlier version, I just installed version 2.1, here is an <a href="http://pve.proxmox.com/wiki/Proxmox_VE_installation_(Video)">installation video</a>. I found that the UI completely changed and more features were added, below a sample screen of the management UI showing the services of the host and another one with the VM guest console.</div> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ13Ncoo7_LKgv_LkvIaSsdjHJpIPz_ajlcH2Wxfif75nYSr8IZS0DjIhYZkTlTGU5IHsVSC5zvt7Dx_t-7IHqvupmOGdepVuY9xB-Z8Pj62icEnv0T_OWbr8T-fHYbnGVBgIGRRM8wzV8/s1600-h/HostServices1.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="HostServices" border="0" alt="HostServices" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvSu7kpEA7qGS-OTzZXbmSItbtXJ3mud61D228TlUNfGrFeoTbu1q6HMLgty-Ysy-dD_UBgO9nMfoEI6QlddlIck4h2Q22uiawcYaJR_XxH2l6anVIi_op0dalC9NpXGetFuFLoZ1vSd-P/?imgmax=800" width="781" height="574"></a> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyu8rYbBvqyvxYvj9IadWH6IkEJkiRkXVeYtgJ9lUWblxHobCctO0TfdqYuWzFM0o3VPTcgEn6ruIAjqrqQ8ZB9rq-xJY83dcZhiQ-_owplWNrM37jUj-YZnypUqdjW22amnzRLmNuw0WI/s1600-h/proxmoxconsole1.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="proxmoxconsole" border="0" alt="proxmoxconsole" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1S9qG_q7u7VjE2nTtiIaxjJsbIhxPzhCDvtHbJcBBfFliJoyIpWvzNXZVtRnYdhVoBhNGw-GAz4M5QQTHHFY0KdyUaT20dAwx3YX2kh1IOA80v-9ENLE4w3XsZQHFJgpbJ__MmTXVLyZn/?imgmax=800" width="786" height="460"></a> <br><br> <h4>Location of VM and config files</h4>VM images: <div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">proxmox:/var/lib/vz/images# ls<br>101 102</pre></div><br>VM configurations: <br /><div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">proxmox:/etc/pve/openvz# ls<br>100.conf</pre></div><br>or <br /><div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">proxmox:/etc/pve/qemu-server# ls<br>101.config</pre></div><br>Previous version: <br /><div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">proxmox:/etc/qemu-server#</pre></div><br /><br /><h4>Backup</h4>The backup tool used for <a href="http://pve.proxmox.com/wiki/Container_and_Full_Virtualization">OpenVZ containers and KVM</a> is called <a href="http://pve.proxmox.com/wiki/Vzdump_manual">vzdump</a>; if you are using the UI, first create a backup directory on Datacenter->Storage (using the new UI), and select 'Backup' as content for that storage. If you don’t have a storage created, you will get “Can’t use storage for backups – wrong content type” error.<br><br /><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8hv_mTypSbFFtatz0kGmS4q6ztDFm7Pl7p3EuVH24KnXYt5Ck9BQdLDe_dl0Bu89hyUx6LR3fCo7nPzKGSQep85qrWDYelD-ntq8Hmx2thslauJJMvj2eL_Aj1k3AnL_c8fZUEq7QiuSL/s1600-h/backup1.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="backup" border="0" alt="backup" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKlSfDI4QV1IL4W7tAVKtiiOWddd6TIR3SmZXEKurt00BlE2xT_bT8GgBoaPNc66HeAOnYrwcuHkPLx4XESC-5RT05TgxzdkcwDevi0tvDWhpe0KJci_M_HQ5dnJ2y96ITEP7Fhxj61U2J/?imgmax=800" width="629" height="314"></a><br>There are other options to backup an image with no downtime for example using the <a href="http://pve.proxmox.com/wiki/Backup_-_Restore_-_Live_Migration#Backup_with_VZDump">snapshot</a> mode. </p><br /><h4>Create a vm image</h4>You can create a vm via command line or using the web UI. <br /><p>The following example creates windows 2003 vm with 3G of ram and using 1 core/socket CPU. <br /><div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">qm create 101 --name BuildSlave01 --vlan0 virtio=DA:28:61:58:71:5B --ide2 none,media=cdrom --bootdisk ide0<br>--ostype w2k3 --memory 3072 --sockets 1 --onboot no --cores 1 --virtio0 local:100,format=qcow2<br></pre></div><br /><p>Make sure to assign a new mac address every time a vm is created. </p><br /><h4>Restore from a backup</h4>To <a href="http://pve.proxmox.com/wiki/Backup_-_Restore_-_Live_Migration">restore</a> use vzrestore for OpenVZ containers or qmrestore for KVM machines. <br /><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnYExLoZTPZ7OEnjEo3_E6585o3co6YeteRaQi7Kxj9mTvNJ31hJNwjBLSephV5eR_siZrLLES2U4hFiD0jZyyG1fppEeTpsX1Hw2hD2m2w8nVPt_cLFf_m-mhN_0vlO4pCTvfcpUE799Y/s1600-h/restorevm%25255B3%25255D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="restorevm" border="0" alt="restorevm" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic5mYPxR0UxceSVsEhkzobi7iYSwL-BgRJxbqPEendmwAEdz7yKyvvwkLWhASpgMJW8BLooIGb1Iq-LYlYAR4S5agHsfkQYEyyDrwwgINpw6niWMOaDTf3QiYAiZD8SA6g8wnK3TVARPiH/?imgmax=800" width="651" height="403"></a></p><br /><h4>Copy VM image</h4>It is also possible to copy the vm disk image from one virtual machine to another, doing this will keep each vm configuration separate. <br /><div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">proxmox:/var/lib/vz/images# cp 101/vm-101-disk-1.qcow2 106/vm-106-disk-1.qcow2 <br></pre><br></div><br /><h4>Extend vm disk size </h4>The following example will add 20G to the vm. <br /><div><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">qemu-img resize vm-101-disk-1.qcow2 +20G</pre></div><br /><div><br>You can use <a href="http://sourceforge.net/projects/gparted/files/gparted-live-stable/">gparted</a> to make this space available on windows server 2003 c:\ drive. First, upload the iso image on proxmox and then boot the vm from cd using uploaded gparted iso image. </div><br /><div><br>Using gparted to extend disk space is explained in more details here <a href="http://es.scribd.com/doc/39059599/How-to-Resize-Proxmox-Qcow2-Raw-Images-and-Windows-Partitions-Using-Qemu-0-13-and-Linux-Gparted">http://es.scribd.com/doc/39059599/How-to-Resize-Proxmox-Qcow2-Raw-Images-and-Windows-Partitions-Using-Qemu-0-13-and-Linux-Gparted</a>.</div><br><br /><h4>Converting image formats</h4>The <code><a href="http://en.wikibooks.org/wiki/QEMU/Images">qemu-img</a></code> program can be used to convert images from one format to another. For example: <br /><div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">qemu-img convert -O qcow2 MyVmwareImage.vmdk MyProxmoxImage.qcow2</pre></div><div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com0Copenhagen, Denmark55.6760968 12.568337155.604469300000005 12.4104086 55.7477243 12.726265600000001tag:blogger.com,1999:blog-8628196772095230598.post-10255814577045961552011-11-09T22:43:00.000-08:002011-11-09T22:43:00.607-08:00Getting your App Continuously Tested<p>Being able to identify issues quickly and having an automated system that tells us whether or not the application is broken, sounds like a must have practice for software development companies nowadays. Nevertheless, we are still facing many challenges specially on large and complex systems.</p> <h4>So where do we start?</h4> <p>In my opinion, the first step in getting automated is having a <a href="http://en.wikipedia.org/wiki/Continuous_integration">CI</a> (Continuous Integration) system in place and making sure the builds cover major branches. </p> <p>The CI system needs to be able to deploy and run the application in isolation per branches, for example using different virtual machines / databases. This way we can make sure we have a known state of all resources and that we are able to roll back to that state after the tests run. Having the hardware/software resources needed for this is key to success.</p> <p>In many cases, we may require changing the way the application is built and deployed, using tools and creating scripts that runs steps automatically in CI.</p> <h4>Being able to run tests automatically in CI </h4> <p>Select the tools that allows you to run automated tests unattended and getting tests results reports in CI. This way we make sure all the tests are executed after every code change, and that we also are able to run many tests on different environments/configurations. </p> <h4>Creating the tests</h4> <p>Get the whole team involved and make the creation of different levels of automated tests a part of development activities. Consider the team may need to improve their code design skills, which leads to testable code. Most of us have heard high cohesion and low coupling, for a long time; unfortunately it is common not seeing these applied.</p> <h4>Automated tests general guidelines </h4> <ol> <li>The test should communicate intent: it should be clear and simple what the test is verifying, and how the functionality is used by the application.</li> <li>The test must have an assert.</li> <li>The test must pass and fail reliably. The test should not have code branches i.e. if/else statements that cause it to not give a reliable pass/fail.</li> <li>If for some reason, the test has code branches, there must not be one that doesn’t have an assert.</li> <li>Keep tests independent: As tests grow, running the tests sequentially may be unpractical, so we need to make sure we can run tests in parallel and get quick feedback. </li> <li>There must be a way to run separately unit, integration and end to end tests. The distinction between these must be clearly understood.</li> <li>Unit tests must run fast.</li> <li>Do not comment tests when they start failing, fix them.</li></ol> <p>This list can grow very long but at least this can be a good start =)</p> <p>Hope this summary helps you and your team getting automated.</p><div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com0tag:blogger.com,1999:blog-8628196772095230598.post-66459169972473009532011-11-02T11:40:00.001-07:002012-05-16T01:52:43.658-07:00Visual Studio Debugging and Remote DebuggingThis time I would like to share some notes gathered from different sources about debugging: how visual studio handles different builds (Debug and Release) and how we can debug code that has been deployed to a remote machine.<br />
<br />
<h4>
Debug, Release Build </h4>
Like most of you know visual studio projects has some predefined build configurations: Debug and Release. Using <a href="http://msdn.microsoft.com/en-us/library/wx0123s5(v=VS.90).aspx">Debug</a>, the program is compiled with full symbolic debug information and no optimizations. <br />
<br />
With Release the program is compiled using Optimize code and pdb-only options. The <a href="http://msdn.microsoft.com/en-us/library/ms241903(v=VS.90).aspx">pdb-only</a> option does not generate the <tt><a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.debuggableattribute.aspx">DebuggableAttribute</a></tt> that tells the JIT compiler that debug information is available, but generates a <a href="http://blogs.msdn.com/b/jimgries/archive/2004/08/26/221027.aspx">.pdb</a> (program database) file to allow viewing information such as source filenames and line numbers in the application’s stacktrace.<br />
<br />
<a href="http://msdn.microsoft.com/en-us/library/ms164714(VS.80).aspx">Optimized</a> code is harder to debug since the compiler repositions and reorganizes instructions to get a more efficient compiled code, so generated instructions may not correspond directly to the source code. Some optimizations are always performed by the compiler and others only performed when the Optimized code option is set; <a href="http://blogs.msdn.com/b/ericlippert/archive/2009/06/11/what-does-the-optimize-switch-do.aspx">optimization</a> may include things like: constant propagation,<strong> </strong>dead code elimination. .Net runs optimizations in 2 steps: one optimization run by the compiler when generating the IL code and other when running the application and transforming IL to machine code, most optimizations are left to the JIT compiler. <br />
<br />
While reviewing more about it, it seems that <a href="http://stackoverflow.com/questions/41842/pdb-files-for-production-app-and-the-optimize-code-flag">optimization</a> is separate from pdb generation so pdb-only generation shouldn’t affect <a href="http://msdn.microsoft.com/en-us/library/ee416588(v=vs.85).aspx">performance</a> in most scenarios and it is recommended to produce PDB files, even if you don't want to ship them with the executable.<br />
<br />
In order to debug an application with visual studio, we require the <a href="http://msdn.microsoft.com/en-us/library/ee416588(v=vs.85).aspx">matching pdb file</a>: The debugger <a href="http://www.wintellect.com/CS/blogs/jrobbins/archive/2009/05/11/pdb-files-what-every-developer-must-know.aspx">looks for the PDB</a> files using the dll or executable name and looks for [applicationname].pdb. When .dll, executable, and PDB files are generated it creates and stores identical GUIDs in each file. The GUID is used to determine if a given PDB file matches a DLL or an executable file.<br />
<br />
You can use <a href="http://msdn.microsoft.com/en-us/library/c1h23y6c.aspx">DUMPBIN</a> to see if pdb files are found for a given dll, for example:<br />
<br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">e:\Program Files (x86)\Microsoft Visual Studio 9.0\VC>dumpbin /pdbpath:verbose
<span style="color: #006080;">"e:\Projects\VS 2008\RemoteDebugging\WpfApplication1\bin\Release\WpfApplication1.exe"</span>
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file e:\Projects\VS 2008\RemoteDebugging\WpfApplication1\bin\Release\WpfApplication1.exe
File Type: EXECUTABLE IMAGE
PDB file found at <span style="color: green;">'e:\Projects\VS 2008\RemoteDebugging\WpfApplication1\bin\Release\WpfApplication1.pdb'</span>
Summary
2000 .reloc
2000 .rsrc
2000 .text
e:\Program Files (x86)\Microsoft Visual Studio 9.0\VC></pre>
<br /></div>
and GUID information can be inspected using DUMPBIN as well:
<br />
<br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">e:\Program Files (x86)\Microsoft Visual Studio 9.0\VC><span style="color: green;">dumpbin /headers </span>
<span style="color: #006080;">"e:\Projects\VS 2008\RemoteDebugging\WpfApplication1\bin\Release\WpfApplication1.exe"</span>
.....
Dump of file e:\Projects\VS 2008\RemoteDebugging\WpfApplication1\bin\Release\WpfApplication1.exe
.....
Debug Directories
Time Type Size RVA Pointer
-------- ------ -------- -------- --------
4D97EE82 cv 6C 00003708 1908 Format: RSDS,
{9873ECF8-BA29-4C84-9AF5-BC54B1E6FFD4}, 1, E:\Projects\VS 2008\RemoteDebugging\WpfApplication1\obj\Release\WpfApplication1.pdb</pre>
<br /></div>
Another interesting feature around .net debugging is <a href="http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx">configuring an executable image for debugging</a>, if you want to debug [application].exe, create a text file named [application].ini, in the same folder having this information:<br />
<br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0</pre>
<br />
This tells JIT compiler to generate tracking information and not run optimizations, making it possible for the debugger to match up MSIL and not optimizing resulting machine code.</div>
<br />
<h4>
Remote debugging </h4>
To remote debug a .net application you can use the visual studio remote debugger (msvsmon.exe), <br />
Both machines should have access/permissions to connect to each other. Start visual studio remote debugger on the machine running the application, this will start visual studio remote debugging monitor displaying the following information.<br />
<div id="codeSnippetWrapper">
<br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">Msvsmon started a new server named 'Domain\user@machinename'. Waiting for new connections.
machine\user connected. </pre>
<br /></div>
</div>
On the machine you want to debug, start visual studio and on the attach to process windows, set Qualifier to the remote debugger server name. In this example 'Domain\user@machinename' use the mane as it appears.<div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com1tag:blogger.com,1999:blog-8628196772095230598.post-65738721360653783032011-03-02T20:43:00.000-08:002012-05-16T01:58:35.747-07:00xUnit.Net – Running the tests (RunAfterTestFailed Custom Attribute)<p>On my last post I created a Custom TestCategory Attribute and custom xUnit.Net TestClassCommand to run test by category. Now I want to create a Custom RunAfterTestFailed attribute to run a method whenever a test fails. We have the following test class</p><div><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">using</span> Xunit;
<span style="color: #0000ff">using</span> Xunit.Extensions;
<span style="color: #0000ff">namespace</span> xUnitCustomizations
{
[CustomTestClassCommand]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> TestClass
{
[Fact, TestCategory(<span style="color: #006080">"Unit"</span>)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> FailedTest1()
{
Assert.True(<span style="color: #0000ff">false</span>);
}
[Fact, TestCategory(<span style="color: #006080">"Unit"</span>)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> FailedTest2()
{
<span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> InvalidOperationException();
}
[RunAfterTestFailed]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestFailed()
{
Debug.WriteLine(<span style="color: #006080">"Run this whenever a test fails"</span>);
}
}
}</pre></div><div><br />
We will use CustomTestClassCommandAttribute and CustomTestClassCommand previously created, and made the following changes to EnumerateTestCommands method, since we need a custom command to be able to handle errors when executing test methods:</div><br />
<div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> CustomTestClassCommand : ITestClassCommand
{
.....
<span style="color: #cc6633">#region</span> ITestClassCommand Members
.....
<span style="color: #0000ff">public</span> IEnumerable<ITestCommand> EnumerateTestCommands(IMethodInfo testMethod)
{
<span style="color: #0000ff">string</span> skipReason = MethodUtility.GetSkipReason(testMethod);
<span style="color: #0000ff">if</span> (skipReason != <span style="color: #0000ff">null</span>)
<span style="color: #0000ff">yield</span> <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> SkipCommand(testMethod, MethodUtility.GetDisplayName(testMethod), skipReason);
<span style="color: #0000ff">else</span>
<span style="color: #0000ff">foreach</span> (var testCommand <span style="color: #0000ff">in</span> cmd.EnumerateTestCommands(testMethod))
<span style="color: #0000ff">yield</span> <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> AfterTestFailedCommand(testCommand);
}
....
<span style="color: #cc6633">#endregion</span>
}</pre></div><div><br />
AfterTestFailedCommand will handle calling the execution of the test method and calling the proper method whenever a test fails</div><br />
<div id="codeSnippetWrapper"><div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> AfterTestFailedCommand : DelegatingTestCommand
{
<span style="color: #0000ff">public</span> AfterTestFailedCommand(ITestCommand innerCommand)
: <span style="color: #0000ff">base</span>(innerCommand)
{}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> MethodResult Execute(<span style="color: #0000ff">object</span> testClass)
{
MethodResult result = <span style="color: #0000ff">null</span>;
Type testClassType = testClass.GetType();
<span style="color: #0000ff">try</span>
{
result = InnerCommand.Execute(testClass);
}
<span style="color: #0000ff">finally</span>
{
<span style="color: #0000ff">if</span> (!(result <span style="color: #0000ff">is</span> PassedResult))
{
<span style="color: #0000ff">foreach</span> (MethodInfo method <span style="color: #0000ff">in</span> testClassType.GetMethods())
<span style="color: #0000ff">foreach</span> (var attr <span style="color: #0000ff">in</span> method.GetCustomAttributes(<span style="color: #0000ff">typeof</span>(RunAfterTestFailedAttribute), <span style="color: #0000ff">true</span>))
method.Invoke(testClass, <span style="color: #0000ff">null</span>);
}
}
<span style="color: #0000ff">return</span> result;
}
}</pre></div></div><br />
<p>I liked the extensibility that xUnit.Net provides, even when there isn’t a built in solution for TestCategory and RunAfterTestFailed attributes, I was able to build it by looking at the source code, the unit tests and examples available in CodePlex (the framework has unit tests!). Hope this series of posts was helpful to get you started in migrating from MSTest to xUnit.Net and writing custom extensions for this framework.</p><div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com0tag:blogger.com,1999:blog-8628196772095230598.post-50932946901775003172011-01-28T23:05:00.000-08:002012-05-16T02:01:10.266-07:00xUnit.Net – Running the tests (TestCategory)<p>In my previous post I showed an example about converting a MSTest class to xUnit.Net, and now I want to provide a solution for converting MSTest TestCategory attribute to an equivalent implementation in xUnit.Net.</p><p>MSTest allowed us to run the test that belongs to an specific category, let’s see a solution on how this can be accomplished in xUnit.Net.</p><div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">using</span> Xunit;
<span style="color: #0000ff">using</span> Xunit.Extensions;
<span style="color: #0000ff">namespace</span> xUnitCustomizations
{
[CustomTestClassCommand]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> TestClass
{
[Fact, TestCategory(<span style="color: #006080">"Unit"</span>)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> FastTest()
{
Debug.WriteLine(<span style="color: #006080">"fast test executed"</span>);
Assert.True(<span style="color: #0000ff">true</span>);
}
[Fact, TestCategory(<span style="color: #006080">"Integration"</span>)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> SlowTest()
{
Thread.Sleep(5000);
Debug.WriteLine(<span style="color: #006080">"slow test executed"</span>);
Assert.True(<span style="color: #0000ff">true</span>);
}
}
}</pre></div><p><div>Create <strong>TestCategory</strong> attribute</div><div> </div><div><div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none;color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">namespace</span> Xunit.Extensions
{
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> TestCategoryAttribute : TraitAttribute
{
<span style="color: #0000ff">public</span> TestCategoryAttribute(<span style="color: #0000ff">string</span> category)
: <span style="color: #0000ff">base</span>(<span style="color: #006080">"TestCategory"</span>, category) { }
}
...
}</pre></div></div></p><p><strong>CustomTestClassCommandAttribute</strong> attribute is used to indicate that a custom test runner will be used</p><div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> CustomTestClassCommandAttribute : RunWithAttribute
{
<span style="color: #0000ff">public</span> CustomTestClassCommandAttribute() : <span style="color: #0000ff">base</span>(<span style="color: #0000ff">typeof</span>(CustomTestClassCommand)) { }
}</pre></div><p><strong>CustomTestClassCommand</strong> is the class that implements ITestClassCommand and acts as the runner for the test fixture</p><div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><p><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> CustomTestClassCommand : ITestClassCommand
{
<span style="color: #008000">// Delegate most of the work to the existing TestClassCommand class so that we</span>
<span style="color: #008000">// can preserve any existing behavior (like supporting IUseFixture<T>).</span>
<span style="color: #0000ff">readonly</span> TestClassCommand cmd = <span style="color: #0000ff">new</span> TestClassCommand();
<span style="color: #cc6633">#region</span> ITestClassCommand Members
<span style="color: #0000ff">public</span> <span style="color: #0000ff">object</span> ObjectUnderTest
{
get { <span style="color: #0000ff">return</span> cmd.ObjectUnderTest; }
}
<span style="color: #0000ff">public</span> ITypeInfo TypeUnderTest
{
get { <span style="color: #0000ff">return</span> cmd.TypeUnderTest; }
set { cmd.TypeUnderTest = <span style="color: #0000ff">value</span>; }
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span> ChooseNextTest(ICollection<IMethodInfo> testsLeftToRun)
{
<span style="color: #0000ff">return</span> cmd.ChooseNextTest(testsLeftToRun);
}
<span style="color: #0000ff">public</span> Exception ClassFinish()
{
<span style="color: #0000ff">return</span> cmd.ClassFinish();
}
<span style="color: #0000ff">public</span> Exception ClassStart()
{
<span style="color: #0000ff">return</span> cmd.ClassStart();
}
<span style="color: #0000ff">public</span> IEnumerable<ITestCommand> EnumerateTestCommands(IMethodInfo testMethod)
{
<span style="color: #0000ff">return</span> cmd.EnumerateTestCommands(testMethod);
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">bool</span> IsTestMethod(IMethodInfo testMethod)
{
<span style="color: #0000ff">return</span> cmd.IsTestMethod(testMethod);
}
<span style="color: #0000ff">public</span> IEnumerable<IMethodInfo> EnumerateTestMethods()
{
<span style="color: #0000ff">string</span> category;
<span style="color: #0000ff">foreach</span> (IMethodInfo method <span style="color: #0000ff">in</span> cmd.EnumerateTestMethods())
{
category = <span style="color: #0000ff">string</span>.Empty;
<span style="color: #0000ff">foreach</span> (IAttributeInfo attr <span style="color: #0000ff">in</span> method.GetCustomAttributes(<span style="color: #0000ff">typeof</span>(TestCategoryAttribute)))
category = attr.GetPropertyValue<<span style="color: #0000ff">string</span>>(<span style="color: #006080">"Value"</span>);
<span style="color: #0000ff">if</span> (category.ToLower().Contains(<span style="color: #006080">"unit"</span>)) <span style="color: #008000">// We can make this configurable</span>
<span style="color: #0000ff">yield</span> <span style="color: #0000ff">return</span> method;
}
}
<span style="color: #cc6633">#endregion</span>
}</p></pre><br />
The Method <span style="color: #0000ff">public</span> IEnumerable<IMethodInfo> EnumerateTestMethods() filters the tests methods by TestCategory's attribute Value, note that we can make this configurable so we can configure our CI server to run unit test as soon as there are changes in the repository to provide quick feedback and schedule (e.g. once a day) the execution slower test like integration or Web UI test.<br />
</div><div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com4tag:blogger.com,1999:blog-8628196772095230598.post-73960543225043026432011-01-03T18:34:00.000-08:002012-05-16T02:09:50.465-07:00xUnit.Net – Running the tests (ClassInitialize – ClassCleanup)<p>I started using <a href="http://xunit.codeplex.com/">xUnit.Net</a> few weeks ago. My first question was how to do the things I was used to do in <a href="http://xunit.codeplex.com/wikipage?title=Comparisons&referringTitle=Home">other testing frameworks</a> like MSTest or NUnit, specially when using these frameworks not only for unit testing but for higher level tests like <a href="http://seleniumhq.org/projects/remote-control/">Selenium RC</a> web tests. So far, the framework seems to be very good and extensible.<p>I am going to show some scenarios I have run into converting MSTest to xUnit.Net, having the following class</p><div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><p>using Microsoft.VisualStudio.TestTools.UnitTesting;</p><p>[TestClass]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> AdminPageTest
{
<span style="color: #0000ff">static</span> SeleniumWebTestContext test = <span style="color: #0000ff">new</span> SeleniumWebTestContext();
[ClassInitialize()]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> ClassInitialize()
{
<span style="color: #0000ff">new</span> LoginPage(test).LoginUser(“maria”, “******”);
}
[ClassCleanup()]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> ClassCleanup()
{
<span style="color: #0000ff">new</span> AdminPage(test.Driver).Logout();
test.StopWebTestContext();
}
[TestCategory(<span style="color: #006080">"WebTest"</span>), TestMethod]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestViewMyProfile()
{
var profileWindow = <span style="color: #0000ff">new</span> AdminPage(test.Driver).SelectMyProfile();
Assert.IsTrue(profileWindow.CheckFirstName(“Maria”));
profileWindow.Close();
}
[TestCategory(<span style="color: #006080">"WebTest"</span>), TestMethod]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestAdminSearchUser()
{
var userWindow = <span style="color: #0000ff">new</span> AdminPage(test.Driver).SelectUserManagement();
userWindow.Search(<span style="color: #006080">"Marcano Maria"</span>);
Assert.IsTrue(adminTab.VerifyEmail(<span style="color: #006080">"my-email@domain.com"</span>));
}
}</p></pre></div><p>Note that SeleniumWebTestContext is holding information about Selenium RC and starts the server. </p><h3>ClassInitialize – ClassCleanup / IUseFixture<T></h3><p>Sometimes we require sharing information among the methods defined in a class, for example in web tests we want to share the logged in the user information, execute different actions and validations and log out at the end: </p><div><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; height: 278px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><p>using Xunit;</p><p><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> AdminPageTest : IUseFixture<LoggedUserContext>
{
SeleniumWebTestContext test;
<span style="color: #0000ff">public</span> AdminPageTest()
{
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> SetFixture(LoggedUserContext usrContext)
{
test = usrContext.Test;
}
...
}</p></pre></div><br />
<div>and the LoggedUserContext class will look like this:</div><div id="codeSnippetWrapper"><div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> LoggedUserContext : IDisposable
{
<span style="color: #0000ff">public</span> SeleniumWebTestContext Test;
<span style="color: #0000ff">public</span> LoggedUserContext()
{
Test = <span style="color: #0000ff">new</span> SeleniumWebTestContext();
<span style="color: #0000ff">new</span> LoginPage(Test).LoginUser(“maria”, “******”);
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Dispose()
{
<span style="color: #0000ff">new</span> AdminPage(Test.Driver).Logout();
Test.StopWebTestContext();
}
}</pre></div></div><div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com0tag:blogger.com,1999:blog-8628196772095230598.post-13696891356619842642010-11-27T11:36:00.000-08:002010-11-27T18:18:05.723-08:00Selenium’s How-To<p>Recently I ran into a couple of issues that started affecting some selenium automated tests I was developing, below the issues and solutions implemented:</p><h3>XHR ERROR: Response_Code = –1 Request Error</h3><p>When executing the open command the tests started failing with the following error</p><p>XHR ERROR: URL = https:// Response_Code = -1 Error_Message = Request Error. on Firefox version 3.6.12 and Selenium RC version 1.0.3</p><p>I found that the issue was reported by other users (issue <a href="http://code.google.com/p/selenium/issues/detail?id=408">408</a> on selenium project page). The open command started working again after making the suggested workaround on comment <a href="http://code.google.com/p/selenium/issues/detail?id=408#c4">4</a>, calling the open command and passing the second parameter true:</p><div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> CustomOpen(<span style="color: #0000ff">string</span> url)
{
commandProcessor.DoCommand(<span style="color: #006080">"open"</span>, <span style="color: #0000ff">new</span> String[] { url, <span style="color: #006080">"true"</span> });
}</pre></div><p>According to comment <a href="http://code.google.com/p/selenium/issues/detail?id=408#c4">4</a>, the issue was caused by a feature that was supposed to be disabled. </p><p>The issue seems to be related to that second parameter (ignoreResponseCode) on the open command and the default value assigned when it is null or empty, there is more details about the fix on commend <a href="http://code.google.com/p/selenium/issues/detail?id=408#c14">14</a>. The fix hasn't been released yet, so if you run into this issue you can use this workaround. </p><h3>Https pages</h3><p>When running selenium on development / test environment, usually there is a need to deal with the <a href="http://saucelabs.com/blog/index.php/2010/01/selenium-totw-https-and-self-signed-certificate-exeptions/">certificate exceptions</a> thrown by the browser.</p><p>I was experiencing the following behavior when running the tests using *firefoxproxy mode, this mode will remember the certificate exception added but if the site is redirected automatically to other location, Selenium throws permission denied exception (I supposed this is related to <a href="http://seleniumhq.org/docs/05_selenium_rc.html#the-same-origin-policy">Same Origin Policy</a> restriction). </p><p>Reading a little <a href="http://seleniumhq.org/docs/05_selenium_rc.html#handling-https-and-security-popups">further</a>, *firefoxproxy mode is supported only for backward compatibility and *firefox mode should be use in Selenium-RC 1.0 beta 2 and later. </p><p>I tried the following solutions mentioned <a href="http://saucelabs.com/blog/index.php/2010/01/selenium-totw-https-and-self-signed-certificate-exeptions/">here</a> running selenium using *firefox mode: <br />
<ul><li>Creating a <a href="http://seleniumhq.org/docs/05_selenium_rc.html#specifying-the-firefox-profile">firefox profile</a> and run selenium with that profile<br />
<li>Use RCE - <a href="https://addons.mozilla.org/en-US/firefox/addon/10246/">Remember Certificate Exception</a> firefox add-on<br />
</li><br />
</ul>Both approaches worked, but the test execution experiences a small delay when using RCE. <div class="blogger-post-footer"><a style="display: none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag">CodeProject</a></div><div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com1tag:blogger.com,1999:blog-8628196772095230598.post-69230493891973572362010-10-23T11:43:00.001-07:002012-05-16T02:12:54.556-07:00Automating MyAppInFlex.swf – Useful FlexPilot commandsI continue automating my Flex application with FlexPilot. One clear advantage I found when using FlexPilot is that I was able to access more of the UI elements of a complex Flex interface. The other tools I tried weren’t picking all those elements, but I must admit that I didn’t investigate further. <p>An interesting feature is FlexPilot’s chain syntax, that allows to access flex UI elements by different properties, like id, label or text. Another feature I liked is easier integration to work with selenium RC and selenium IDE. </p> <p>Below some usage examples to create automated tests for MyAppInFlex.swf, and also serve as a quick reference on how to interact/access the flex UI.</p> <h3>Click on a Button</h3>The easiest way to access an element is using the element’s id, for example click on a button: <br> <div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 16px; background-color: #f4f4f4; text-align: left; border-bottom-style: none">selenium.flexClick(<span style="color: #006080">"id=MyAppInFlex"</span>, <span style="color: #006080">"chain=id:okButton"</span>);</pre><br></div>If the button you are trying to access doesn't have an id, you are able to find it using the label property: <br><br /><div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 21px; background-color: #f4f4f4; text-align: left; border-bottom-style: none">selenium.flexClick(<span style="color: #006080">"id=MyAppInFlex"</span>, <span style="color: #006080">"chain="</span>id:buttonBar/label:Search");</pre></div><br /><h3>Access an element on a Grid</h3>Click an element that has an specific value on a Grid <br /><div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 100%; cursor: text; direction: ltr; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: 'Courier New', courier, monospace; height: 30px; background-color: #f4f4f4; text-align: left"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none">selenium.flexClick(<span style="color: #006080">"id=MyAppInFlex"</span>, <span style="color: #006080">"chain="</span>id:userGrid/name:AdvancedListBaseContentHolder*/name:AdvancedListBaseContentHolder*/text:Maria Marcano");</pre><br></div><br /><h3>Check the value on a TextInput</h3>Check a textbox has a specific value <br /><div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 21px; background-color: #f4f4f4; text-align: left; border-bottom-style: none">selenium.flexAssertProperty(<span style="color: #006080">"id=MyAppInFlex"</span>, <span style="color: #006080">"chain="</span>id:emailTextBox, validator=text|emailvalue@domain.com", );</pre></div><br>To improve the application testability, add id’s to the objects you want to access. This also applies for web application in general (accessing elements by id’s is faster than processing xpath expressions). <br><br /><h3>Some limitations</h3>Elements on a grid can’t be accessed by position, for example click on the first/second element on a grid. <br /><p>I’ve been experiencing some issues with some application builds that prevent the use of the flex explorer and recorder (reported the bug, hopefully it gets fixed soon). You can still run the tests, just not using those tools to capture the elements.</p><div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com4tag:blogger.com,1999:blog-8628196772095230598.post-90395578013138046772010-10-09T01:11:00.001-07:002012-05-16T02:17:21.673-07:00CruiseControl.Net and MSTest<p>I wanted to put together some notes about CruiseControl.Net and MSTest to have it as reference:</p> <p>First, to be able to generate reports the following element is required on ccnet.config file.</p> <div><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 16px; background-color: #f4f4f4; text-align: left; border-bottom-style: none"><span style="color: #0000ff"><</span><span style="color: #800000">xmllogger</span> <span style="color: #0000ff">/></span> </pre></div><br /><div>this element is used to create the log files read by the CruiseControl.NET web page, if it isn't defined the web page will throw the following error:</div><br /><div><strong>Exception Message</strong><br>Request processing has failed on the remote server: Unable to find Log Publisher for project so can't find log file.</div><br /><div>To view the MSTest report, we need to add the result file in ccnet.config to merge the content in the build report, for example : </div><br /><div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 302px; background-color: #f4f4f4; text-align: left; border-bottom-style: none">..................<br><span style="color: #0000ff"><</span><span style="color: #800000">exec</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">executable</span><span style="color: #0000ff">></span>C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\MSTest.exe<span style="color: #0000ff"></</span><span style="color: #800000">executable</span><span style="color: #0000ff">></span> <br> <span style="color: #0000ff"><</span><span style="color: #800000">baseDirectory</span><span style="color: #0000ff">></span>.\<span style="color: #0000ff"></</span><span style="color: #800000">baseDirectory</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">buildArgs</span><span style="color: #0000ff">></span> /testcontainer:SeleniumSearch\bin\Debug\SeleniumSearch.dll /resultsfile:Results\results1.trx<span style="color: #0000ff"></</span><span style="color: #800000">buildArgs</span><span style="color: #0000ff">></span><br><span style="color: #0000ff"></</span><span style="color: #800000">exec</span><span style="color: #0000ff">></span> <br>tasks<span style="color: #0000ff">></span><br><span style="color: #0000ff"><</span><span style="color: #800000">publishers</span><span style="color: #0000ff">></span><br><span style="color: #0000ff"><</span><span style="color: #800000">merge</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">files</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">file</span><span style="color: #0000ff">></span>.\Results\results1.trx<span style="color: #0000ff"></</span><span style="color: #800000">file</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">files</span><span style="color: #0000ff">></span><br><span style="color: #0000ff"></</span><span style="color: #800000">merge</span><span style="color: #0000ff">></span> <br><span style="color: #0000ff"><</span><span style="color: #800000">xmllogger</span> <span style="color: #0000ff">/></span><br><span style="color: #0000ff"></</span><span style="color: #800000">publishers</span><span style="color: #0000ff">></span><br>..................</pre>Include the MSTest plugin to generate the report on the web page, for example dashboard.config file</div><br /><div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 227px; background-color: #f4f4f4; text-align: left; border-bottom-style: none">..................<br><span style="color: #0000ff"><</span><span style="color: #800000">buildPlugins</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">buildReportBuildPlugin</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">xslFileNames</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">xslFile</span><span style="color: #0000ff">></span>xsl\header.xsl<span style="color: #0000ff"></</span><span style="color: #800000">xslFile</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">xslFile</span><span style="color: #0000ff">></span>xsl\modifications.xsl<span style="color: #0000ff"></</span><span style="color: #800000">xslFile</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">xslFile</span><span style="color: #0000ff">></span>xsl\MsTestSummary2008.xsl<span style="color: #0000ff"></</span><span style="color: #800000">xslFile</span><span style="color: #0000ff">></span> <br> <span style="color: #0000ff"></</span><span style="color: #800000">xslFileNames</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">buildReportBuildPlugin</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">buildLogBuildPlugin</span> <span style="color: #0000ff">/></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">xslReportBuildPlugin</span> <span style="color: #ff0000">description</span><span style="color: #0000ff">="MSTest2008 Report"</span> <span style="color: #ff0000">actionName</span><span style="color: #0000ff">="MSTESTReport"</span> <span style="color: #ff0000">xslFileName</span><span style="color: #0000ff">="xsl\MsTestReport2008.xsl"</span><span style="color: #0000ff">/></span> <br><span style="color: #0000ff"></</span><span style="color: #800000">buildPlugins</span><span style="color: #0000ff">></span><br>..................</pre>And include the xls file for MSTest report on ccservice.exe.config/ccnet.exe.config</div><br /><div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 212px; background-color: #f4f4f4; text-align: left; border-bottom-style: none">..................<br><span style="color: #008000"><!-- Specifies the stylesheets that are used to transform the build results when using the EmailPublisher --></span><br><span style="color: #0000ff"><</span><span style="color: #800000">xslFiles</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">file</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="xsl\header.xsl"</span><span style="color: #0000ff">/></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">file</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="xsl\compile.xsl"</span><span style="color: #0000ff">/></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">file</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="xsl\unittests.xsl"</span><span style="color: #0000ff">/></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">file</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="xsl\MsTestSummary2008.xsl"</span><span style="color: #0000ff">/></span> <br> <span style="color: #0000ff"><</span><span style="color: #800000">file</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="xsl\fit.xsl"</span><span style="color: #0000ff">/></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">file</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="xsl\modifications.xsl"</span><span style="color: #0000ff">/></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">file</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="xsl\fxcop-summary_1_36.xsl"</span><span style="color: #0000ff">/></span><br><span style="color: #0000ff"></</span><span style="color: #800000">xslFiles</span><span style="color: #0000ff">></span><br>..................</pre>The xls used on the above example is the one included in ccnet installation. I tested the report generation running tests on VS 2010 and VS 2008 and both reports are generated correctly. The only thing that caused issues was having MSTest on the path windows environment variables on a computer that has both VS 2010 an VS 2008</div><br /><div>Also, if MSTest needs to connect to external resources, like accessing remote files or connecting to SQL Server, make sure the account that runs CruiseControl.Net Server windows service (by default is Local System Account) has access to those resources.</div><div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com0tag:blogger.com,1999:blog-8628196772095230598.post-25845537383510495742010-10-01T22:49:00.001-07:002012-05-16T02:18:55.042-07:00CruiseControl.Net driving Selenium Tests<p>This is how you can quickly get CruiseControl.Net running and driving your selenium test – in 6 steps:</p> <ol> <li>Donwload & Install <a href="https://sourceforge.net/projects/ccnet/files/CruiseControl.NET%20Releases/CruiseControl.NET%201.5/CruiseControl.NET-1.5.7256.1-Setup.exe/download" target="_blank">CruiseControl.Net</a> <li>Start “CruiseControl.NET Server“ Windows Service <li>Download <a href="http://github.com/downloads/mariangemarcano/seleniumtest/SeleniumTest-Code.zip" target="_blank">SeleniumTest</a> sample project and extract it on a folder C:\Projects\. <li>Edit CruiseControl.NET configuration file (C:\Program Files (x86)\CruiseControl.NET\server\ccnet.config) and replace it with the information in C:\Projects\SeleniumTest\CruiseControl.Net\ccnet.config. Modify it with proper locations of MSBuild.exe, MsBuild.dll and MSTest.exe <li>Start selenium server by running C:\Projects\SeleniumTest\SeleniumServerPort4441.bat. <li>Open <a title="http://localhost/ccnet" href="http://localhost/ccnet">http://localhost/ccnet</a> and you will se the project SeleniumSearchTest1 click on Force. It should build the project and start the tests.</li></ol> <p>The tests will run using chrome, you can change this parameter in C:\Projects\SeleniumTest\SeleniumSearch\SeleniumSearchTest.cs and use "*iehta" for Internet Explorer or "*firefoxproxy" for Firefox.</p> <div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 35px; background-color: #f4f4f4; text-align: left; border-bottom-style: none"><span style="color: #008000">// "*iehta" IE - "*firefoxproxy" FF - *googlechrome</span><br>selenium = <span style="color: #0000ff">new</span> DefaultSelenium(<span style="color: #006080">"localhost"</span>, 4441, <span style="color: #006080">"*googlechrome"</span>, <span style="color: #006080">"http://seleniumhq.org/"</span>); </pre></div><br /><div>This is how the ccnet.config file looks</div><br /><div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 782px; background-color: #f4f4f4; text-align: left; border-bottom-style: none"><span style="color: #0000ff"><</span><span style="color: #800000">cruisecontrol</span> <span style="color: #ff0000">xmlns:cb</span><span style="color: #0000ff">="urn:ccnet.config.builder"</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">project</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">name</span><span style="color: #0000ff">></span>SeleniumSearchTest1<span style="color: #0000ff"></</span><span style="color: #800000">name</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">triggers</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">scheduleTrigger</span> <span style="color: #ff0000">time</span><span style="color: #0000ff">="23:30"</span> <span style="color: #ff0000">buildCondition</span><span style="color: #0000ff">="ForceBuild"</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">weekDays</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">weekDay</span><span style="color: #0000ff">></span>Monday<span style="color: #0000ff"></</span><span style="color: #800000">weekDay</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">weekDay</span><span style="color: #0000ff">></span>Tuesday<span style="color: #0000ff"></</span><span style="color: #800000">weekDay</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">weekDay</span><span style="color: #0000ff">></span>Wednesday<span style="color: #0000ff"></</span><span style="color: #800000">weekDay</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">weekDay</span><span style="color: #0000ff">></span>Thursday<span style="color: #0000ff"></</span><span style="color: #800000">weekDay</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">weekDay</span><span style="color: #0000ff">></span>Friday<span style="color: #0000ff"></</span><span style="color: #800000">weekDay</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">weekDays</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">scheduleTrigger</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">triggers</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">workingDirectory</span><span style="color: #0000ff">></span>C:\Projects\SeleniumTest<span style="color: #0000ff"></</span><span style="color: #800000">workingDirectory</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">tasks</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">msbuild</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">executable</span><span style="color: #0000ff">></span>C:\Windows\Microsoft.NET\Framework\v3.5\MSBuild.exe<span style="color: #0000ff"></</span><span style="color: #800000">executable</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">workingDirectory</span><span style="color: #0000ff">></span>C:\Projects\SeleniumTest<span style="color: #0000ff"></</span><span style="color: #800000">workingDirectory</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">projectFile</span><span style="color: #0000ff">></span>SeleniumTest.sln<span style="color: #0000ff"></</span><span style="color: #800000">projectFile</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">buildArgs</span><span style="color: #0000ff">></span>/noconsolelogger /p:Configuration=Debug /v:diag<span style="color: #0000ff"></</span><span style="color: #800000">buildArgs</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">targets</span><span style="color: #0000ff">></span>Build<span style="color: #0000ff"></</span><span style="color: #800000">targets</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">timeout</span><span style="color: #0000ff">></span>900<span style="color: #0000ff"></</span><span style="color: #800000">timeout</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">logger</span><span style="color: #0000ff">></span>C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll<span style="color: #0000ff"></</span><span style="color: #800000">logger</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">msbuild</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">exec</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">executable</span><span style="color: #0000ff">></span>DelResults.bat<span style="color: #0000ff"></</span><span style="color: #800000">executable</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">baseDirectory</span><span style="color: #0000ff">></span>.\<span style="color: #0000ff"></</span><span style="color: #800000">baseDirectory</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">exec</span><span style="color: #0000ff">></span> <br> <span style="color: #0000ff"><</span><span style="color: #800000">exec</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">executable</span><span style="color: #0000ff">></span>C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\MSTest.exe<span style="color: #0000ff"></</span><span style="color: #800000">executable</span><span style="color: #0000ff">></span> <br> <span style="color: #0000ff"><</span><span style="color: #800000">baseDirectory</span><span style="color: #0000ff">></span>.\<span style="color: #0000ff"></</span><span style="color: #800000">baseDirectory</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">buildArgs</span><span style="color: #0000ff">></span> /testcontainer:SeleniumSearch\bin\Debug\SeleniumSearch.dll /resultsfile:Results\results1.xml<span style="color: #0000ff"></</span><span style="color: #800000">buildArgs</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">exec</span><span style="color: #0000ff">></span> <br> <span style="color: #0000ff"></</span><span style="color: #800000">tasks</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">publishers</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">merge</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">files</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">file</span><span style="color: #0000ff">></span>.\Results\results1.xml<span style="color: #0000ff"></</span><span style="color: #800000">file</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">files</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">merge</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">xmllogger</span> <span style="color: #0000ff">/></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">publishers</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">project</span><span style="color: #0000ff">></span><br><span style="color: #0000ff"></</span><span style="color: #800000">cruisecontrol</span><span style="color: #0000ff">></span></pre></div><br /><div id="codeSnippetWrapper">This example applies for VS 2008 Professional, ccnet 1.5.7256.1 and Selenium RC 1.0.3</div><br /><div>Links:</div><br /><div><a title="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET" href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET">http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET</a></div><br /><div><a title="http://github.com/downloads/mariangemarcano/seleniumtest/SeleniumTest.zip" href="http://github.com/downloads/mariangemarcano/seleniumtest/SeleniumTest-Code.zip">http://github.com/downloads/mariangemarcano/seleniumtest/SeleniumTest-Code.zip</a></div><div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com4tag:blogger.com,1999:blog-8628196772095230598.post-11327358306630371352010-09-15T21:14:00.001-07:002010-10-16T11:46:24.850-07:00Looking at Git and GitHub<p>Recently I decided to take a look at Git and start checking what are the things that makes it different from other version control systems.</p> <p>First <a href="http://en.wikipedia.org/wiki/Git_(software)" target="_blank">Git</a> was initially designed and developed by <a href="http://en.wikipedia.org/wiki/Linus_Torvalds">Linus Torvalds</a> for <a href="http://en.wikipedia.org/wiki/Linux_kernel">Linux kernel</a> development. It is a distributed version control system, usually used from the command line console. <p>Git was designed based on the experience with Linux in maintaining a large distributed development project. The focus was on speed, distribution, fidelity and no corruption of files. <p>In Git you get the project doing a clone instead of checkout, this command gets a full copy of the database, getting every version of every files of the project and no the last version like you do on subversion, this allows you to execute commands like diff offline, as a result commands runs faster because it doesn’t have to go over the network. </p> <p>According to <a href="http://learn.github.com/p/intro.html" target="_blank">GitHub intro to Git</a> the size of the projects are smaller compared to svn, even when the git version is storing all version information of files. </p> <p>One option to start experimenting with Git is using <a href="http://github.com/" target="_blank">GitHub</a> which is a social code hosting - community oriented. You can create a free account for open source projects.</p> <p>To get started in GitHub, you must have a SSH public key to push your git repo. <p>For windows <ul> <li>Install <a href="http://code.google.com/p/msysgit/" target="_blank">Msysgit</a> run it C:\msysgit\msysgit\msys.bat <li>Generate <a href="http://help.github.com/msysgit-key-setup/" target="_blank">ssh-keys</a> in win/msysgit <ul> <li>execute ssh-keygen cmd on Git Bash console <li>you need the public key located in the .ssh directory for example C:\Users\mmarcano\.ssh\ id_rsa.pub </li></ul></li></ul> <p>Once you have setup the github account you can create new repositories, import existing git repo or importing an existing public svn repository like googlecode. <p>Here some links for additional info: <a href="http://help.github.com/" target="_blank">GitHup Help</a>, <a href="http://progit.org/book/ch1-1.html" target="_blank">Pro Git</a>, <a href="http://gitref.org/" target="_blank">Git Reference</a> <p>Enjoy! =)</p> <div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com0tag:blogger.com,1999:blog-8628196772095230598.post-60068187882694640022010-08-18T23:24:00.001-07:002012-05-16T02:20:37.216-07:00Selenium Testing with FlexPilot<p>I <a href="http://mariangemarcano.blogspot.com/2010/08/setting-up-flex-testing-with-selenium.html" target="_blank">continued</a> my quest for a solution to create automated tests using seleniumRC and C# and this time I took a look at this new project called Flex Pilot. </p> <p><a href="http://wiki.github.com/mde/flex-pilot/" target="_blank">FlexPilot</a> is a open source testing tool that integrates with selenium, it has a bootstrapper to make the application testable, it is able to use a selenium IDE recorder, and you can access elements using chain syntax (like accessing with xpath).</p> <p>Here is what I did to start building tests with flex pilot:</p> <ul> <li>Rebuilded flexpilot: source is <a href="http://github.com/mde/flex-pilot/archives/master">http://github.com/mde/flex-pilot/archives/master</a> and excecuted build.py this will update FlexPilot.swf and FPBootstrap.swf located under org/flex_pilot folder (place this file where the app is located) <li>Copied the content from src/org/flex_pilot folder to the flex's app libs folder example C:\source\MyAppInFlex\libs <li>Imported Bootstrap in the flex app <div id="codeSnippetWrapper"> <div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 16px; background-color: #f4f4f4; text-align: left; border-bottom-style: none"><span style="color: #0000ff">import</span> org.flex_pilot.FPBootstrap;</pre></div></div><br /><li>Set FPBootstrap.flex_pilotLibPath the path on the server where FPBootstrap can find FlexPilot.swf. The Loader fetches FlexPilot.swf via a Loader class. <br><br /><div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 20px; background-color: #f4f4f4; text-align: left; border-bottom-style: none">FPBootstrap.flex_pilotLibPath = <span style="color: #006080">'/flash/org/flex_pilot/FlexPilot.swf'</span>;<br></pre></div><br /><li>Initialize FPBootstrap this fetch and load FlexPilot.swf, and gives FlexPilot Flash a context to use for testing. This context is usually a reference to app’s Stage. <br><br /><div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 257px; background-color: #f4f4f4; text-align: left; border-bottom-style: none"><mx:Application xmlns:mx=<span style="color: #006080">"http://www.adobe.com/2006/mxml"</span> layout=<span style="color: #006080">"absolute"</span> xmlns:local=<span style="color: #006080">"*"</span> creationComplete=<span style="color: #006080">"init() <br>applicationComplete="</span>initFlexPilot()"><br>......<br><mx:Script><br> <![CDATA[<br> ...............<br> import mx.utils.ObjectUtil; <br> import org.flex_pilot.FPBootstrap;<br><br> ...............<br> <span style="color: #0000ff">private</span> function initFlexPilot():<span style="color: #0000ff">void</span><br> {<br> FPBootstrap.flex_pilotLibPath = <span style="color: #006080">'FlexPilot.swf'</span>;<br> FPBootstrap.init(stage);<br> }<br>......</pre></div><br /><li>Compiled application: mxmlc -source-path=. -source-path+=../libs MyAppInFlex.mxml -o MyAppInFlex.swf <br /><li>If present, remove tags like <noscript> around the flex object in you html. <br /><li>If the configuration is working Firebug will return “function” when calling <code>document.getElementById('MyAppInFlex').fp_click</code> <li>This is the “hello world” example of a test method on c# <br><br /><div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 150px; background-color: #f4f4f4; text-align: left; border-bottom-style: none">[TestMethod]<br><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestMethodFlexPilot()<br>{<br> selenium.Open(<span style="color: #006080">"http://localhost/testapp.html"</span>);<br> selenium.RunScript(<span style="color: #006080">"document.getElementById('MyAppInFlex').fp_type({name:'usernameTextInput', text:'Flex Pilot'})"</span>);<br> selenium.RunScript(<span style="color: #006080">"document.getElementById('MyAppInFlex').fp_click({name:'secureCheckBox'})"</span>);<br>}</pre></div></li></ul><br /><div id="codeSnippetWrapper">FlexPilot has seleniumRC <a href="http://github.com/admc/flex-pilot-x/tree/master/client/ " target="_blank">client drivers</a> available for java, phyton and rubi (no c# client driver available yet)</div><div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com5tag:blogger.com,1999:blog-8628196772095230598.post-38065513798420076892010-08-05T23:21:00.001-07:002012-05-16T02:22:04.811-07:00Setting up flex testing with selenium<p>Recently I was looking for tools to support automated testing for flex applications. I have a test suite in SeleniumRC and C# I was looking for options to continue using this environment. Here’s what I found: <p> <h3><a href="http://code.google.com/p/flash-selenium/" target="_blank">FlashSelenium</a>, <a href="http://code.google.com/p/sfapi/" target="_blank">Selenium Flex API</a></h3> <p>These two projects provides capabilities to interact with Flex UI components and web pages through selenium RC.</p> <p><b>Selenium Flex API </b>automatically exposes Flex APP UI and <strong>FlashSelenium</strong> allowing us to call ActionScript methods to interact with Flex elements. Note that this approach requires us to compile our flex applications with Selenium Flex API library.</p> <p>To start coding your test:</p> <ul> <li>Rebuild your Flex application with <a href="http://code.google.com/p/sfapi/downloads/list" target="_blank">sfapi.swc</a> add the compiler argument: -include-libraries "..\libs\sfapi.swc" <li>Include FlashSelenium.dll library in the seleniumRC test project.</li></ul> <p>To be able to run test on firefox you need to specify the browserString *firefoxproxy instead of *firefox since firefox doesn't like javascript calling flash when javascript comes from another window (the way selenium calls flash objects).</p> <p>This a “hello world” example: </p> <p></p> <div id="codeSnippetWrapper"><pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; height: 468px; background-color: #f4f4f4; text-align: left; border-bottom-style: none"><p>[TestClass]<br><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> MyAppInFlexTest<br>{<br> <span style="color: #0000ff">private</span> ISelenium selenium;<br> <span style="color: #0000ff">private</span> FlashSelenium.FlashSelenium flashApp;<br><br> [TestInitialize()]<br> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> SetupTest()<br> {<br> selenium = <span style="color: #0000ff">new</span> DefaultSelenium(<span style="color: #006080">"localhost"</span>, 4444, <span style="color: #006080">@"*firefoxproxy"</span>, <span style="color: #006080">@"http://localhost/testapp.html"</span>);<br> <span style="color: #008000">//selenium = new DefaultSelenium("localhost", 4444, @"*iexplore", @"http://localhost/testapp.html");</span><br> <span style="color: #008000">//selenium = new DefaultSelenium("localhost", 4444, @"*googlechorme", @<a href="http://localhost/testapp.html">http://localhost/testapp.html</a>);</span><br> selenium.Start();<br> flashApp = <span style="color: #0000ff">new</span> FlashSelenium.FlashSelenium(selenium, <span style="color: #006080">"MyAppInFlex"</span>);<br> }<br><br> [TestCleanup()]<br> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TeardownTest()<br> {<br> selenium.Stop();<br> }<br><br> [TestMethod]<br> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestMethodFlashSelenium()<br> {<br> flashApp.Call(<span style="color: #006080">"doFlexType"</span>, <span style="color: #006080">"usernameTextInput"</span>, <span style="color: #006080">"from selenium flex"</span>);<br> flashApp.Call(<span style="color: #006080">"doFlexClick"</span>, <span style="color: #006080">"secureCheckBox"</span>, <span style="color: #006080">""</span>);<br> }<br>}</p></pre></div><div class="blogger-post-footer"><a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7484579" rel="tag" style="display:none">CodeProject</a></div>MariangeMarcanohttp://www.blogger.com/profile/00750543870024417559noreply@blogger.com3