Posted on 25 Apr 2012
QUICKLINK: I don’t care about your stupid life story, just show me how to make it work
We’ve been using the Play framework lately at KonciergeMD to build our application. One thing that’s always good to have on your application is good test coverage, and there’s no shortage of tools to measure that.
To get the reports on code coverage, we decided to give JaCoCo a shot, and specifically try to use the sbt-jacoco plugin to do it.
Trying to use it right out of the box, however, proved useless. Running jacoco:cover from sbt or play would not work, and instead run no tests while not giving any error messages, and making you feel like a fool for trying.
After staring at the problem for a while, @seantbrady and I finally came across the solution. The main and simple issue with it is that sbt runs tests in parallel by default, and this is what the sbt-jacoco plugin inherits. You can see this by doing the following in the play console:
[webapp] $ jacoco:parallel-execution
[info] true
Play, however, has this set to false. The simple solution, then, is to set this to false for jacoco also.
How to make it work
UPDATE: We originally had the settings in a separate build.sbt file in the root directory to make this work. A quick email from Peter Hausel at Typesafe showed us how we can do it in the Build.scala file present in the project directory.
Some of this is covered in the sbt-jacoco wiki, but I’m going to put it all here for completeness.
- Add the following to the
plugins.sbt
1 libraryDependencies ++= Seq(
2 "org.jacoco" % "org.jacoco.core" % "0.5.7.201204190339" artifacts(Artifact("org.jacoco.core", "jar", "jar")),
3 "org.jacoco" % "org.jacoco.report" % "0.5.7.201204190339" artifacts(Artifact("org.jacoco.report", "jar", "jar")))
4
5 addSbtPlugin("de.johoop" % "jacoco4sbt" % "1.2.2")
- We also added the following to the
Build.scala file in the project directory:
1 import de.johoop.jacoco4sbt.JacocoPlugin._
2
3
4 object ApplicationBuild extends Build {
5
6 val appName = "webapp"
7 val appVersion = "1.0-SNAPSHOT"
8
9 lazy val s = Defaults.defaultSettings ++ Seq(jacoco.settings:_*)
10
11 val appDependencies = Seq(
12 // Add your project dependencies here,
13 )
14
15 val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA, settings = s).settings(
16 // Add your own project settings here
17 parallelExecution in jacoco.Config := false
18 )
19 }
You’ll notice you have to add the JaCoCo settings to the default settings, and set the settings in the Play Project, adding the parallelExecution to false in there.
Now you can run jacoco:cover to produce your beautiful coverage report! You can see your report at target/scala-2.9.1/jacoco/html.
Posted on 26 Jan 2012
I wanted to take a stab at doing some Ruby, so I whipped up this little utility delete all the files in one or all of your campfire rooms for a given URL.
You can get it on my github.
Running the program
To run, the command is as follows:
$ ./campfireremovefiles.rb -s server -t apitoken
where server is the name of your campfire server (in the form of name.campfirenow.com) and apitoken is the token given to you. You can get this token by going under the “My Info” link on your campfire page.
The script will print out a list of rooms, and give you a choice of which one to delete from (or all). You can ignore the “peer certificate” warning, it just means that you’re not verifying the cert from campfirenow. We’ll assume the server is correct.
Here’s what a sample run will look like:
warning: peer certificate won't be verified in this SSL session
Choose the room you want to delete the files from:
1: Test
2: Test 1
3: Test 2
4: All
? 2
This will delete all files in the room Test 1!! Are you sure? (y/n)
? y
Deleting test2.txt
Deleting test1.txt
Again, since this is my first ever Ruby program, it’s probably in pretty crappy shape. Deriding comments about the exact level of crappiness are always welcome.
Posted on 11 Dec 2011
I finally got around to releasing my silly little app for Android. It’s called “Sleepwords”, and it floats the name of random objects in front of you, to help you sleep, meditate, or give your conscience mind a distraction to help your subconscious mind flow free. Best of all, IT’S FREE. So you really have no excuse not to at least try it.
You can find it on the market here. I’m planning on making the source code available soon.
UPDATE
I’ve just released sleepwords as open source! You can get the code on github here.
Posted on 20 Nov 2011
When I was trying to get Google Music working on my Ubuntu install, I was getting the following error:
On my motherboard, I have two ethernet ports. Doing an ifconfig, I saw something weird with my MAC addresses.
I’m only using eth1, but you can see that both of the ethernet ports are reporting the same MAC address of aa:00:04:00:0a:04. I found this post detailing that the DECNet tools is what causes the MAC address to be the same. To remove them, run the following:
$ sudo apt-get remove dnet-common libdnet
Reboot, and running ifconfig will show your ethernet ports mapped to their correct MAC address. Now you should not have any problems running Google Music!
Posted on 05 Sep 2011
So, in my last blog, I said I was using Jekyll to blog now. I also got a new host in Webfaction. So I figured I’d blog about how squished these two together into some blogging without your hands leaving the keyboard. This post will assume you know the basics about Jekyll and git.
1. Upgrade RubyGems and install Jekyll
To install the latest Jekyll on Webfaction, you’ll need to upgrade the version of RubyGems to at least 1.3.7. There’s instructions here for doing that, but I’m going to include them here for you lazy lazers.
It basically involves setting up some Ruby variables, and downloading, extracting and installing the new RubyGems packages.
export GEM_HOME=$HOME/gems
export RUBYLIB=$HOME/lib
export PATH=$HOME/bin:$PATH
wget http://production.cf.rubygems.org/rubygems/rubygems-1.8.10.tgz
tar xvzf rubygems-1.8.10.tgz
ruby setup.rb install --prefix=$HOME
gem install jekyll
This will install the gem command in $HOME/bin, and then install the latest version of Jekyll.
2. Install Pygments (optional)
Pygments is a Liquid Extension for Jekyll that will highlight code blocks. If you don’t need code highlighting, it’s not something you need, but if you do it will give you some of the nice formatting you see on this website.
Installation is as follows:
mkdir $HOME/lib/python
easy_install --always-unzip --install-dir=$HOME/lib/python --script-dir=$HOME/bin Pygments
3. Create static application in Webfaction
In your Webfaction control panel, setup a static web application, as shown below. Remember the name of the application, as that folder is where you’ll output your blog.
4. Set up git on Webfaction and your computer
On your webserver, create two directories. One will contain a bare git repository, and the other will contain the actual source of your blog (some info on a bare repository can be found here. I used ~/gitwebsite/git and ~/gitwebsite/ronalleva.com respectively. The rest of these instructions will assume those directories.
Inside ~/gitwebsite/git run:
Now on your own computer, in your git repo for your Jekyll website, run
git remote add web ssh://username@username.webfactional.com/home/username/gitwebsite/git
This will add the repo on your Webfactional server as a remote. Make sure you change username with your username, and the path /gitwebsite/git to whatever you happen to call it.
Now run:
and that will now push any of your committed changes to your webserver! Woohoo. Oh, and you’ll only need the master call the first time you do it, otherwise it won’t know what branch you’re trying to push. All subsequent calls won’t need the master.
5. Create a post-receive hook
Well, this is great. You’re pushing all your code to your webserver. But it’s sitting there, inert and useless like a sleeping kitten. You’re going to need to run the Jekyll command on your source to get it to show up right. There’s probably one million ways to do this (including doing it manually, using the at daemon, or setting up some type of Rube Goldberg device), but I like doing it with a post-receive hook.
Create a file called ~/gitwebsite/git/hooks/post-receive and place something like the following in there:
The first part basically sets up the necessary variables for working. The GIT_WORK_TREE variable is basically where your Jekyll files will end up. git checkout -f will checkout your Jekyll files into GIT_WORK_TREE. Then the Jekyll command is run, using the webapp you set up previously as the output directory. I put this in a gist, messing up the color style of my website, just so you could fork it! My kindness knows no bounds.
These instructions should be able to be adapted for any web host that allows for shell access (one of the great things about Webfaction). You can find the source of my blog at Github.
Posted on 04 Aug 2011
Welcome to my new blog. It’s a little rough around the edges at the moment, but hopefully not too bad. I was getting tired of my wordpress blog, so I decided to give Jekyll a try. It’s really fun to work with, and lets you get really fine grained with your control.
Unfortunately I don’t have everything over here yet, but that should hopefully come within the next few days. I’ll also post about the migration from Wordpress to Jekyll.
Enjoy.
Posted on 07 Oct 2010
Wow, I’ve gotten a lot of requests for the jmeter-maven-plugin, for enhancements and whatnot. I originally had the code on code.google.com, but from there I have to add contributors, blah blah blah. So I moved all the code over to github, so if anybody wants to update it, now they can do so directly, through github. The page for the jmeter plugin is still here.
Posted on 10 May 2010
Our group is starting to use Review Board more and more to conduct our code reviews. But using it with git-svn, or with anything you’ve already checked into svn can be a real hassle. You don’t want to have uncommitted code hanging around in your computer for extended periods of time for a number of reasons, so this rendered it difficult to use for code projects that take more than a week.
Since I like to eat, and hence get paid so that I can afford food, I have to work on things that take longer than a week. But luckily, git can help get a diff for review board based only on a string in the commit comments.
This came about when one of my co-workers posted a bash scripts someone had written that would take a git diff and make it into a svn-like diff. And that worked great. My first attempt was to modify it to do multiple files at once, but it ended up making a diff for each revision for each file (if you need that functionality, you can get that here).
So I pulled out python and worked on a new script, which is at the bottom of this post, or you can get it here.
Once you download the file, you run it like this from your git repository:
git-create-review.py (some grep string) > diff.output
The script will take the argument as a string to search for in the commit comments. This is thanks to the git log --grep=foo command available in git. It outputs directly to the terminal, which you can see I’m redirecting into diff.output. Once you have the file, you can upload to Review Board as you normally would. I did it by using a search string because we use JIRA to track our work in svn. We have pre-commit hooks to ensure that we put a JIRA number on each commit. This helps out git as it has something to search through to get the change list.
Known issues:
First: It will get all the changes between the first and last revision that had the search string.
Example:
I change File.java under JIRA-123 (now at r1).
Another change to File.java under JIRA-321 (now at r2).
I change the file again under JIRA-123 (now r3).
This script will take all changes between 1 and 3, even if I don’t want the JIRA-321 changes to show up.
Second: it doesn’t have any context around removed/moved files. It still should pick up a renamed file as just a completely new file, but it doesn’t have any context of renaming. But I believe that’s the case with svn anyway.
Third: I am by no means a good python programmer, and might not know all the conventions that people normally follow. The code below may cause eye hemorrhaging, face hemorrhaging…pretty much any of your organs could be hemorrhaged by looking at the code. CONSIDER THIS YOUR ONLY WARNING. But I did some testing with newly created files, and removed files, and binary files, but I’m sure I missed some crazy edge cases. Let me know if you hit any snags. The script follows:
Posted on 29 Mar 2010
If you go to the bottom of the page for git-svn, under the “Basic Examples” section, you’ll see in there a procedure to clone a git-svn repo that someone has painstakingly already cloned from svn. That’s great, because it will save you hours and hours of mind numbing time that would normally take someone to clone an svn repo.
That person may be tremendously happy…that is, until, you try to git svn fetch to get new revisions and branched and what have you, and you get an error message like this:
Last fetched revision of (some branch or tag) was r3421, but we are about to fetch: r3421!
In an attempt to fix it, you may find this blog post, saying to remove the .ref files from your svn directory, which also proves fruitless.
The fix: modify the .git/svn/.metadata file so that the branches-maxRev and tags-maxRev equals the latest commit revision in svn. So it should look like this after you are done:
; This file is used internally by git-svn
; You should not have to edit it
[svn-remote "svn"]
reposRoot = (svn server name)
uuid = c08781d2-f03e-0410-8c7c-e884ea3e41f3
branches-maxRev = 17224
tags-maxRev = 17224
Where 17224 was our latest revision.
I got the idea from git-svn’s webpage, where it states:
If the subset of branches or tags is changed after fetching, then .git/svn/.metadata must be manually edited to remove (or reset) branches-maxRev and/or tags-maxRev as appropriate.
I must caveat this with the fact that I have no idea why this works. Git svn is still black magic to me, and making this work is akin to me throwing muskrat bones onto a flaming pyre, and drawing conclusions from the charred remains. Maybe someone with more git knowledge could drop it off here?
Posted on 01 Mar 2010
So, you have a materialized view in your DB. That’s great. Give yourself a cookie.
You also have created a set of tests in your DAO layer, using the AbstractTransactionalSpringContextTests. Good for you, again.
But when you try to mix these two together, you may see tests failing and can’t immediately see why. This can happen if you try to get data from the materialized view after attempting to save data to a table that the view accesses.
Well, it’s very simple, and probably pretty obvious. It wasn’t immediately obvious to me why it was failing, and I didn’t really see anything online about it, so hopefully this will stop your search quickly.
First thing to realize is that running your DAO tests through the AbstractTransactionalSpringContextTests is that every test is run in a transaction. That’s great most of the time. Each test will run in a little isolated environment and the changes to the database will be rolled back at the end. You don’t have all kinds of test data strewn about afterwards as if it were the island in Cast Away.
The second thing to realize is that a materialized view will only be updated on commit. There’s a lot more to it than that, but I am not a DBA and that’s all you need to know in general.
So, with those two things in mind, you can see how it might be a problem if you try to write tests against code that uses the materialized view. All is not lost however. If you put an endTransaction() call somewhere in your test, all of the DB calls you’ve made up to that point will be committed. Also, any other calls made after that point will also be committed to the database. Since that happens, you will be on your own to clean up after the test as you see fit. Also, placing an endTransaction will only affect the test you place it in. Any other test will still continue to run and rollback in the normal fashion.
What we ended up doing was making the tests that need to commit to the database small as possible. We then wrapped the endTransaction() function in a function called setTestToCommit() (my co-worker James’ suggestion), so that it makes more sense to read it, and placed it at the beginning of the test.
There’s lots more information about how it works here.