Java EE 6 Testing with Arquillian Persistence Extension

Posted by admin | Posted in General Programming, Learning Materials, Tools | Posted on 22-12-2011

2

Today I will describe my newly discovered library which is an extension to the great JBoss Arquillian project.

The mission of the Arquillian project is to provide a simple test harness that abstracts away all container lifecycle and deployment from the test logic so developers can easily produce a broad range of integration tests for their enterprise Java applications.

Arquillian persistence extension allows you to test JPA related code without filling up the database with test data. All you have to do is to populate .yml file with your data specified. That will be best described with an example.

First of all add arquillian persistence dependencies to your project:

<dependency>
            <groupId>org.jboss.arquillian.extension</groupId>
            <artifactId>arquillian-persistence-api</artifactId>
            <version>${version.arquillian_persistence}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.arquillian.extension</groupId>
            <artifactId>arquillian-persistence-impl</artifactId>
            <version>${version.arquillian_persistence}</version>
            <scope>test</scope>
        </dependency>

where ‘${version.arquillian_persistence}’ is equal to ’1.0.0.Alpha2′. I assume that you have the basic arquillian tests (for EJB’s and CDI) working, If not read on.

I have found myself setting up arquillian enabled project quite cumbersome, always ending up with some classpath dependency problems while trying to remote test my classes. For those of you new to Arquillian I would strongly recommend starting up with working example provided by Bartosz Majsak and available on github as a ‘Beer-Advisor‘ project.

The ‘Beer-Advisor’ project can be quickly refactored to suit your needs, it lack comments but its so clearly written that it shouldn’t be a problem to grasp the idea.

Ok then, lets get going with the arquillian persistence extension, we are going to use two nice annotations to help us testing our JPA layer: @UsingDataSet and @ShouldMatchDataSet.

We start off with doing some setup, I will copy part of the example from the Beer-Advisor project which you can easily clone and try for yourself:

Having an entity class Beer:

@Entity
public class Beer implements Serializable
{
   private static final long serialVersionUID = 5892013208071126314L;

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Long id;

   @Basic
   private String name;

   @Basic
   private BigDecimal price;

   @Basic
   private BigDecimal alcohol;

   @Basic
   private String code;

   @Enumerated(EnumType.STRING)
   private Type type;

   // If lazy then Glassfish Embedded is facing this problem: https://bugs.eclipse.org/bugs/show_bug.cgi?id=323403
   @ManyToOne(optional = false, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
   private Brewery brewery;

   Beer()
   {
      // to satisfy JPA
   }

   public Beer(Brewery brewery, Type type, String name, BigDecimal price, BigDecimal alcohol)
   {
      this.name = name;
      this.price = price;
      this.alcohol = alcohol;
      this.type = type;
      this.brewery = brewery;
      this.brewery.addBeer(this);
   }
........ Getters and Setters ...............

and simple DAO for managing Beer objects on the persistence layer:

@RequestScoped
public class JpaBeerRepository implements BeerRepository
{
   @PersistenceContext
   private EntityManager em;

   @Override
   public Beer getById(Long id)
   {
      return em.find(Beer.class, id);
   }
..........

@Override
   public Set<Beer> fetchAll()
   {
      CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
      CriteriaQuery<Beer> query = criteriaBuilder.createQuery(Beer.class);
      Root<Beer> from = query.from(Beer.class);
      CriteriaQuery<Beer> select = query.select(from);

      Set<Beer> result = new HashSet<Beer>();
      result.addAll(em.createQuery(select).getResultList());

      return result;
   }

   @Override
   public void save(Beer beer)
   {
      if (beer.getId() == null)
      {
         em.persist(beer);
      }
      else
      {
         em.merge(beer);
      }
   }
..................

We can easily test our DAO by creating datasets in yml format and test our logic against it:

Beer:
  - id: 1
    alcohol: 4.5
    name: "Mocny Full"
    price: 1.0
    type: LAGER
    brewery_id: 1
  - id: 2
    alcohol: 55.0
    name: "End of history"
    price: 765
    type: BLOND_ALE
    brewery_id: 2
  - id: 3
    alcohol: 41.0
    name: "Sink The Bismarck!"
    price: 64.0
    type: QUADRUPEL_IPA
    brewery_id: 2
  - id: 4
    alcohol: 8.5
    name: "Delirium Tremens"
    price: 10.0
    type: PALE_ALE
    brewery_id: 3
  - id: 5
    alcohol: 8.4
    name: "Pauwel Kwak"
    price: 4.0
    type: AMBER
    brewery_id: 4

You should put your .yml file into test/resources/datasets folder in you maven project

@UsingDataSet annotation will populate our database with the data specified in beers.yml file

   @Test
   @UsingDataSet("beers.yml")
   public void shouldReturnBeerByItsId() throws Exception
   {
      // given
      Long beerId = 1L;
      String expectedName = "Mocny Full";

      // when
      Beer beers = beerRepository.getById(beerId);

      // then
      assertThat(beers.getName()).isEqualTo(expectedName);
   }

Now, lets say we want to add new Beer and see if the database will have a specific data in it, for this purpose we are going to use @ShouldMatchDataSet(..)

@Test
    @ShouldMatchDataSet("expected-insert-beer.yml")
    public void shouldSaveNewBeer() throws Exception{
        //when
        Beer b = new Beer();
                //set the necessary fields on the beer object
        beerRepository.save(b);
        assertThat(beerRepository).isNotNull();
    }

after inserting our Beer object to the database through the EntityManager we should end up with a single beer record in our database, exactly like the one specified in ‘expected-insert-beer.yml’.

Eclipse Code Recommenders

Posted by admin | Posted in Tools | Posted on 28-09-2011

0

Thanks to @Vogella I have found out lately about Eclipse Code Recommenders.
For anyone using Eclipse or considering a switch from other IDE check out this: Eclipse Code Recommenders

This is in my opinion the way to go for the IDE but I wonder how good this can actually get, anyway looks interesting though.

What you get with code recommenders:

1. Intelligent Call Completion
2. Dynamic and Example-driven Template Completion
3. Java Chain Completion

So far it covers quite a short list of classes/functionality but anyway still impressive.
There is no stable release yet. More details on the mentioned website above.
Check out the website for more details.

Improving your Eclipse productivity

Posted by admin | Posted in Tools | Posted on 02-03-2011

0

One of the quickest ways to improve your productivity as a programmer is to learn your tools. The easiest way to master your tools is to learn its shortcuts and one of the easiest ways to learn shortcuts is to use a flash card based learning software :) .
As I have moved recently from Netbeans to Eclipse I have decided to upgrade my eclipse skills by learning its shortcuts extensively.
If you are a linux user you can try to install small program just for that called Anki, this is a very simple and intuitive software which allows you to quickly and easily create new sets of flash cards as well as import some already created by the community.
Based on the post here I have quickly created a set of flash cards for learning Eclispe shortcuts.
You can download the .anki file contained in a zip from here:
eclipse_shortcuts.anki
This is an example screen from the Anki software displaying random flash card:

Installing Artifactory on Ubuntu box

Posted by admin | Posted in General Programming, Tools | Posted on 25-02-2011

2

This is a simple and straightforward guide on how to install Artifactory and import exisiting maven repository into it.

1. Download Artifactory from JFrog website
2. Unzip downloaded file in your home directory
3. Change to root user (su -)
4. Set your JAVA_HOME in /etc/environment

JAVA_HOME=/usr/lib/jvm/java-6-sun/
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"

5. Set your JAVA_HOME in /etc/profile

# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
export JAVA_HOME=/usr/lib/jvm/java-6-sun/
if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
   .............. rest of the file.....

6. Go to /home/kris/artifactory-2.3.2/bin (of course replace ‘kris’ with your home folder name)
7. Run

$: ./install.sh

8. Check if your installation was successful, run:

$: service artifactory check

9. If you get error saying something like: “Cannot find a JRE or JDK. Please set JAVA_HOME to a >=1.5 JRE” , edit /etc/artifactory/default and add JAVA_HOME export:

10. Run the check again (service artifactory check) and if all goes fine run

[cc lang="bash"]
$: service artifactory start

11. In your browser to into: http://localhost:8081/artifactory and log in as administrator (default user/pass is admin/password)

12. After logging in, click on the ‘Admin’ tab, then ‘Import & Export’ and ‘Repositories’

13. Inside the ‘Import’ section select ‘ext-release-local’ as your ‘Target Local Repo’ and find your maven .m2 repository

14. Click import and your are all set!

Oracle SQL Developer on Ubuntu 10.04 – No brainer instalation guide

Posted by admin | Posted in Tools | Posted on 29-09-2010

3

This is a short tutorial on how to install ‘Oracle SQL Developer’ on Ubuntu 10.04 (Lucid) platform.
1. Instal sqldeveloper-package package

sudo apt-get install sqldeveloper-package

2. Download ‘SqlDeveloper’ itself from Oracle website (you have to be registered prior to download)

3. Install tofrodos package

sudo apt-get install tofrodos

4. Create symlinks for dos2unix and unix2dos (execute the following inside your /usr/bin folder)

username@linuxbox:/usr/bin# sudo ln -s fromdos dos2unix

username@linuxbox:/usr/bin# sudo ln -s todos unix2dos

5. Install debhelper package

sudo apt-get install debhelper

6. Go to the folder where you have downloaded the SQL Developer in step 2 and run the following command:

make-sqldeveloper-package sqldeveloper-2.1.1.64.45-no-jre.zip

7. Install the newly created deb package

sudo dpkg --install sqldeveloper_2.1.1.64.45+0.2.3-1_all.deb

8. Run Sql Developer and when asked provide JDK home eg.

/usr/lib/jvm/java-6-openjdk

And thats it! Enjoy!

Getting started with Apache Click and Eclipse Galileo

Posted by admin | Posted in Code Snippets, General Programming, Tools | Posted on 18-02-2010

6

Last couple of days I read here and there about Apache Click, which is now in version 2.1.0. It looks preety cool and easy to learn, so I decided to give it a try and see for myself.
I understand that its cool to learn things using vi and shell only, but when you tried many frameworks before, you know how things works, you just want to see how or how not, productive you can be with the new framework, thats why I jump straight to the IDE.
And here, first surprise, with apache click its’ not that easy, well, I’m mean its still easy but I have encountered a few problems, and right now I would like to share the solution.
First of all, I did not tried all the examples in the apache click user guide yet, haven’t build anything usefull and definietly I’m not an Apache Click expert, I think I have figured out how to plug it to Eclipse and I think this is good start :) .


Here you have a few points to build your Apache Click IDE:
1. First of all download latest and greatest Eclipse Galileo from here – choose Eclipse for Java EE developers
2. Download Apache Click libraries from here – choose version 2.1.0
3. Download Apache Click IDE from here – note that it contains Click version 1.5 and it was last updated in November 2008 – maybe I’m missing something here?
4. Unzip your ClickIDE and copy the ‘features’ and ‘plugins’ folders into your Eclipse home directory
5. Unzip your latest click libraries and keep it for later :)
6. Start your Eclipse IDE and create new ‘Dynamic Web Project’

Choose target name, in this case ‘ClickDemo2′, select your target runtime as Tomcat 6+ etc.
7. Under configuration combo box, select custom and click ‘Modify’

8. Select ‘Click’ in Project Facet List and save the configuration as click config

9. Once you have your configuration created, dynamic web project screen should look like in the following screenshot:

10. The rest of the settings you can leave as it is, just click ‘Next’ up to the point when you finish creating new dynamic web project.
11. After your project is created it will have the structure like in the following screen:



Notice that there are click libraries from version 1.5, which is no good, we want to use the latest version which is 2.1.0.
12. Copy the files ‘click-2.1.0.jar’ and ‘click-extras-2.1.0.jar’ into the same lib folder where the old libraries are found.
13. Delete old libraries and refresh the project tree under eclipse (right click on the project node and select ‘Refresh’), now you will see the new libraries come up in the lib folder.
14. Open your web.xml file under ‘WebContent/WEB-INF/’ folder and change the class name of the main Click Servlet, from ‘net.sf.click.ClickServlet’ to ‘org.apache.click.ClickServlet’ in ‘servlet-class’ declaration.
15. With Eclipse, select the project node and click ‘New’ -> ‘Other’, choose ‘Click Page’ under ‘click’ directory.

16. Fill out the necessary fields for your new click page as below:

17. Name the file ‘index.htm’ and click ‘Finish’
18. Under the page java source file, fix the Page class by using the page from the: org.apache.click.Page instead of the old path.

package com.softwarepassion;

import java.util.Date;

import org.apache.click.Page;


public class Index extends Page {
   
    private Date time = new Date();
   
    public Index(){
        addModel("time", time);
    }

}

Modify your ‘index.htm’ using html editor to look something like this:

<html>
  <head>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=UTF-8">
    <title>Blank</title>
    $imports
  </head>
  <body>
  $time
  </body>
</html>

19. Start up your project in tomcat. The page should display current time!


Additional Comments:
I know that this is just a quickfix, and I just cannot belive that there is no proper eclipse plugin using the latest click framework, which would be up to date, if you know any, than please comment and save me and my readers precious time.

Thank you.

Jasperberry – the most dynamic reports ever.

Posted by admin | Posted in Code Snippets, General Programming, Tools | Posted on 17-02-2010

10

Today I will describe in short my latest and simplest quick and dirty trick, generating jasper report dynamically. Jasperberry is a component written very quickly to help me
generate pdf report in a situation where I don’t know the number of columns I will have, I don’t know their widths, the data they contain etc, all is generated at runtime dynamically.
I know that there is DynamicJasper project but it seems to be dead, and its dead in a very strange way, I mean, I see that the authors commit new code but there is no chance to get any support unless, I guess, you pay for it.
With dynamic jasper I couldn’t generate report with polish fonts displayed properly, tried many different tricks, no support on the forum, no support on stack overflow, no nothing. After 2 days I have realized that I will write my own library quicker to solve my problem than get an answer from the dynamic jasper community (if there is any).
So here we have: jasperberry!


Don’t expect too much from it but if you want to display simple table with data, dynamic columns, adjustable fonts and colors than this is it.

In fact you don’t have to even know object properties to generate the report, we will use Apache DynaBeans for that:

This is a simple example code snipped showing you how to get started with the simplest and most dynamic reporting library ever (as well as lacking features probably but we hope its enough for simple projects)

This example assumes the following:

1. You want simple report
2. You dont have to know the object which properties you want to display in advance, by this I mean you can create report columns dynamically, and by using apache dyna beans your objects don’t have to even exists. You just dynamically create them and inject them into the report.

Here is an example test class showing you how to use jasperberry, for more info please contact us directly at softberries.com
Code:

public class JRXMLBuilderTest {

    private static List<JBColumnBean> columns;

    public JRXMLBuilderTest() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
        columns = new ArrayList<JBColumnBean>();
        JBColumnBean col1 = new JBColumnBean();
        JBColumnBean col2 = new JBColumnBean();
        JBColumnBean col3 = new JBColumnBean();
        JBColumnBean col4 = new JBColumnBean();
        JBColumnBean col5 = new JBColumnBean();
        JBColumnBean col6 = new JBColumnBean();
        JBColumnBean col7 = new JBColumnBean();
        col1.setPreferredWidth(60);
        col1.setProperty("name");
        col1.setTitle("ImiÄ™");
        col2.setPreferredWidth(60);
        col2.setProperty("surname");
        col2.setTitle("Nazwisko");
        col3.setPreferredWidth(160);
        col3.setProperty("comment");
        col3.setTitle("Komentarz");
        col4.setPreferredWidth(100);
        col4.setProperty("comment2");
        col4.setTitle("Komentarz");
        col5.setPreferredWidth(100);
        col5.setProperty("comment3");
        col5.setTitle("Komentarz");
        col6.setPreferredWidth(100);
        col6.setProperty("comment4");
        col6.setTitle("Komentarz");
        col7.setPreferredWidth(100);
        col7.setProperty("comment5");
        col7.setTitle("Komentarz");
        columns.add(col1);
        columns.add(col2);
        columns.add(col3);
        columns.add(col4);
        columns.add(col5);
        columns.add(col6);
        columns.add(col7);
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
    }

    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }

    /** * Test of build method, of class JRXMLBuilder. */
    @Test
    public void testBuild() {
        try {
            System.out.println("build");
            List<JBReportElement> elements = new ArrayList<JBReportElement>();
            //col header font
            JBFont colHeaderFont = new JBFont();
            colHeaderFont.setBold(true);
            colHeaderFont.setSize(10);
            colHeaderFont.setForegroundColor("#555555");
            //detail font
            JBFont detailFont = new JBFont();
            detailFont.setSize(6);
            detailFont.setForegroundColor("#000000");
            detailFont.setPdfEncoding("Cp1257");
            JBPage page = new JBPage();
            JBReport report = new JBReport(page, colHeaderFont, detailFont, "#CCCCFF", "#DEDEDE", "#FFFFFF");
            JBFont titleFont = new JBFont();
            titleFont.setBold(true);
            titleFont.setSize(20);
            titleFont.setForegroundColor("#FF0000");
            titleFont.setPdfEncoding("Cp1257");
            //add title elements
            elements.add(new JBStaticTextElement("Hello World!", 450, 10, 300, titleFont));
            elements.add(new JBImageElement("C:\\\\Documents and Settings\\\\admin\\\\Moje dokumenty\\\\NetBeansProjects\\\\JASPER_BERRY\\\\test.jpg", 0, 0, 350, 242));
            report.setTitleElements(elements);
            JRXMLBuilder instance = new JRXMLBuilder(columns, report);
            boolean expResult = true;
            boolean result = instance.build();
            JasperReport jr = JasperCompileManager.compileReport("jasperberry_by_softberries.jrxml");
            //PREPARE SOME DATA
            DynaProperty[] props = new DynaProperty[columns.size()];
            for (int i = 0; i < columns.size(); i++) {
                props[i] = new DynaProperty(columns.get(i).getProperty(), String.class);
            }
            BasicDynaClass dynaClass = new BasicDynaClass("tester", null, props);
            List<DynaBean> beans = new ArrayList<DynaBean>();
            for (int i = 0; i < 100; i++) {
                DynaBean db = dynaClass.newInstance();
                db.set("name", "Krzysztof " + i);
                db.set("surname", "Grajek " + i);
                db.set("comment", "Komentarz ");
                db.set("comment2", "Komentarz ");
                db.set("comment3", "Komentarz ");
                db.set("comment4", "Komentarz ");
                //
                db.set("comment5", "Komentarz ");
                beans.add(db);
            }
            JasperPrint jp = JasperFillManager.fillReport(jr, null, new JRBeanCollectionDataSource(beans));
            JasperExportManager.exportReportToPdfFile(jp, "jasperberry.pdf");
            assertEquals(expResult, result);
        } catch (Exception ex) {
            Logger.getLogger(JRXMLBuilderTest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

You should find similar snippet in a test suite of the project.
The project itself is licensed under LGPL and its available from sourceforge here

Free file sharing service based on Amazon S3

Posted by admin | Posted in Tools | Posted on 26-04-2009

3

storage
A short note about a brand new rapidshare competition based on Amazon S3 called Storage For Free (www.storage43.com). Without registration you can share here your project files or basically anything you want to share quickly (up to 200 MB no registration required and the file is alive on the server for 30 days), if you are still unhappy you can register for free and get 500MB for a single upload. This is another service that proves growing popularity of Amazon Web Services which in my opinion are great!

Enjoy!

Continuous Integration with CruiseControll.NET

Posted by admin | Posted in Tools | Posted on 09-04-2009

4

Today I will try to bite quite a big topic which is continuous integration setup for .NET application build using Visual Studio 2008, Vistual Studio Unit Tests and Cruise Control.NET.
Continuous integration, in a few simple words works the following way: there are a number of developers working on a project, developers use subversion or other code versioning system to manage their source code. When they work on the project they commit changes to the subversion repo and from the other side another part of the process called ‘continuous integration server’ checks this code out every few minutes, and tries to build it and run unit tests on it, to see if it is so far all ok.
That was probably the shortest description of continuous integration process you would ever be able to find on the internet ;) .

So, how do you set up your own? Well, actually its not that difficult but looks scary at the frist sight. First of all of course, you would have to download and install all software needed, and this is:

That should be it on the server side! While installing just follow the defaults and you should be fine. I do install Cruise Control directly on the C: drive which ends up as C:CruiseControl.NET but you can install it wherever you want, I do it this way as its easier for me to write scripts if neccessary (short pathes instead of long ones).

Once CC.NET is installed you should be able to run it. You have two options, first one run it as a console app or run it as a service. For the setup, I would recommend running it as a console, make sure that CC.NET service is not running and double click ccnet.exe file inside C:CruiseControl.NETserver directory or any other ‘server’ directory depending on your installation path.
If all went fine you can see the CC.NET dashboard in your browser. Just browse to the url ‘http://localhost/ccnet’ where ‘ccnet’ is a virtual directory created by Cruise Control application setup.
capture1

Ok then, once all is runnning and installed we can start configuring our CC server. To do that you would need to open ccnet.config file in your favourite text editor. Inside ccnet.config you will be able to set your project which should be build and tested by Cruise Control. The ccnet.config file consist of a number of project sections. You can have as many ‘project sections as you wish, all contained inside the root element of the document.

<cruisecontrol xmlns:cb="urn:ccnet.config.builder">

  <project name="Project One">
  </project>

  <project name="Project Two">
  </project>

</cruisecontrol>

Lets configure one of the projects, all elements described above would be a subnodes of the project element. First of all we need to specify a working directory for our project. Simply create a dir on your drive somewhere and add a path to it between ‘workingDirectory’ elements. This directory will be used to download the subversion sources.

    <workingDirectory>c:projectone</workingDirectory>

After we specify ‘workingDirectory’ we have to specify a trigger which will call updates on our source code, checked out form the subversion. Right here we specify that CC.NET should check the subversion repo every 60 seconds and if it finds any modifications it should run the whole continuous integration process.

     <triggers>
         <intervalTrigger seconds="60"/>
     </triggers>

To allow cruise controll download/update your sources, we need to specify the adress of the subversion repository as well as username and password

    <!--set the sourcecontrol type to subversion and point to the subversion exe-->
    <sourcecontrol type="svn">
      <executable>C:Program FilesSubversionbinsvn.exe</executable>
      <workingDirectory>C:projectone</workingDirectory>
      <trunkUrl>http://svn_server.com/projectone</trunkUrl>
      <autoGetSource>true</autoGetSource>
      <username>your_username</username>
      <password>your_password</password>
    </sourcecontrol>

This section was pretty easy, after we specify working directory, trigger and subversion settings we are ready to add sections responsible for building, testing and publishing our results.
All of the mentioned should happen inside the ‘tasks’ section so, just after the ‘sourcecontrol’ element add the following:

      <tasks>
      </tasks>

Inside the ‘tasks’ we will add the elements for building the project/solution (msbuild element), unit testing (2 times ‘exec’ element), publishing our work to a separate directory (‘buildpublisher’ element) as well as publish our test results to CC.NET dashboard (‘publishers’ element).

To do all that, we need to first build our project. We are going to use MSBuild.exe which you should be able to find in C:WINDOWSMicrosoft.NETFrameworkv3.5 if you are using .NET 3.5 version. Instead of building single project we are going to build a whole solution. To build a solution you need to specify the place where the solution file exists as well as the name of the solution file itself. Depending on the project size and characteristics you have to set the timeout option to suit your needs and to prevent CC.NET to timeout before the project have a chance to actually build.

      <!-- Configure MSBuild to compile the updated files -->c:
      <msbuild>
        <executable>C:WINDOWSMicrosoft.NETFrameworkv3.5MSBuild.exe</executable>
        <workingDirectory>C:projectonetrunk</workingDirectory>
        <projectFile>projectOne.sln</projectFile>
        <buildArgs>/noconsolelogger /p:Configuration=Debug</buildArgs>
        <targets></targets>
        <timeout>300</timeout>
        <logger>C:CruiseControl.NETwebdashboardbinThoughtWorks.CruiseControl.MsBuild.dll</logger>
      </msbuild>

Ok, so we are already able to automatically build our project and this is really cool but what would be continuous integration without executing unit tests :) . As it makes development easier, for my projects, wherever possible I use built in Unit Test functionality in Visual Studio 2008.In my opinion, VS Unit Tests are a bit more tricky to set up than NUnit on CC.NET, especially publishing results part of it) but the developmnet on the other hand is easier and I will stick to it.
We need to do the following three things to properly execute tests. First of all we need to run tests using MSTest.exe, this part is pretty easy but before doing that we need to delete previous test results or otherwise our MSTest would complain. Therefore you have to add into your tasks the two following ‘exec’ sections.
First one to delete any previouse test results using bat file (deleteTestLog.bat) with single command:

    DEL C:projectoneresults.trx
        <exec>
            <executable>deleteTestLog.bat</executable>
            <baseDirectory>C:CruiseControl.NETserver</baseDirectory>
            <buildArgs></buildArgs>
            <buildTimeoutSeconds>30</buildTimeoutSeconds>
        </exec>

Second ‘exec’ section running the actual unit tests:

        <exec>
            <!--Call mstest to run the tests contained in the TestProject -->
            <executable>mstest.exe</executable>
            <baseDirectory>C:projectonetrunkprojectOneTests</baseDirectory>
            <!--testcontainer: points to the DLL that contains the tests -->
            <!--runconfig: points to solutions testrunconfig that is created by vs.net, list what test to run -->
            <!--resultsfile: normally the test run log is written to the uniquely named testresults directory  -->
            <!--                   this option causes a fixed name copy of the file to be written as well -->
            <buildArgs>/testcontainer:C:projectonetrunkprojectOneTestsBinDebugprojectOneTests.dll /resultsfile:C:projectoneresults.trx</buildArgs>
            <buildTimeoutSeconds>90</buildTimeoutSeconds>
         </exec>

Right now our server builds and tests our solution automatically. If we want to publish the build results somewhere else, lets say to another virtual directory or web site we can copy the files using ‘buildPublisher’. This way, if its a web application, after each build you can browse to the web site url and see the latest changes in place, all freshly build and tested.

      <buildpublisher>
        <sourceDir>C:projectonetrunkprojectOne</sourceDir>
        <publishDir>D:projectOnePublished</publishDir>
        <useLabelSubDirectory>false</useLabelSubDirectory>
      </buildpublisher>

At this point we have a continuous integration server running which automatically update our solution if it detects any changes on subversion server, builds the sources, runs unit tests and publish the build results. This is great, one problem though, MSTest is not well integrated into CC.NET so we won’t be able to see our tests results, if any fails for e.g. on our CC dashboard.
To publish your test results into cruise control dashboard you would need to add the following section inside your ‘project’, just after ‘exec’ or ‘buildPublisher’ sections:

    <!--Publishers will be done after the build has completed-->
    <publishers>
         <merge>
               <files>
                     <file>results.trx</file>
               </files>
         </merge>
         <xmllogger logDir="C:CruiseControl.NETserverProjectOneArtifactsbuildlogs" />
    </publishers>

This will merge your test results into the dashboard.

I hope you will enjoy having continuous integration as part of your project building flow. Have fun.

Affirma S3 library for C#

Posted by admin | Posted in Cloud Computing, General Programming, Tools | Posted on 06-04-2009

0

Finally I have found S3 library that works in C#. The library was written by Joel Wetzel from Affirma Consulting and I just wanted to spread the word about it.
Once downloaded you are presented with the whole C# Visual Studio solution which contains the library project as well as some example on how to use it.
There is even a simple wrapper written which greatly simplyfies the use of the affirma’s library.
As an example:
1. Create wrapper object (constructor listed)

        public ThreeSharpWrapper(String awsAccessKeyId, String awsSecretAccessKey)
        {
            this.config = new ThreeSharpConfig();
            this.config.AwsAccessKeyID = awsAccessKeyId;
            this.config.AwsSecretAccessKey = awsSecretAccessKey;

            this.service = new ThreeSharpQuery(this.config);
        }

and then use it having the following methods:

/// Adds a bucket to an S3 account
public void AddBucket(String bucketName);

 /// Returns a string of XML, describing the contents of a bucket
public String ListBucket(String bucketName);

/// Adds a string to a bucket, as an object
public void AddStringObject(String bucketName, String keyName, String data);

/// Streams a file to a bucket as an object
public void AddFileObject(String bucketName, String keyName, String localfile);

/// Streams a file to a bucket as an object, with encryption
public void AddEncryptFileObject(String bucketName, String keyName, String localfile, String encryptionKey, String encryptionIV);

/// Gets a string object from a bucket, and returns it as a String
public String GetStringObject(String bucketName, String keyName);

/// Gets a file object from a bucket, and streams it to disk
public void GetFileObject(String bucketName, String keyName, String localfile);

/// Gets a file object from a bucket, streaming it to disk, with decryption
public void GetDecryptFileObject(String bucketName, String keyName, String localfile, String encryptionKey, String encryptionIV);

/// Copies an object from a source location to a destination location
public void CopyObject(String sourceBucketName, String sourceKey, String destinationBucketName, String destinationKey);

/// Generates a URL to access an S3 object in a bucket
public String GetUrl(String bucketName, String keyName);

/// Deletes an object from a bucket
public void DeleteObject(String bucketName, String keyName);

/// Deletes a bucket from an S3 account
public void DeleteBucket(String bucketName);

/// Changes the request payer value for the specified bucket
public String PaymentChange(String bucketName, PaymentChangeRequest.Payer payer);

/// Gets the request payer value for the specified bucket
public String PaymentGet(String bucketName);

The library is dead easy to use and most importantly it works (comparing to other S3 libraries I’ve found). Great work Joel!
You can download the solution zip from here or directly from the codeplex hosting the project here