2018-03-04

This blog is @deprecated

All entries have been moved to my site, so this blog will be shut down somewhere in the future. If you're interested, please visit the site dhiller.de.

Thanks for reading :)

2017-08-07

Update all git repos via cmd line in a subdir

This one is just for me so I don't forget this "one-liner". Updates all git repositories in direct subdirectories. Works on OS X :)

cwd=$(pwd); for dir in $(find . -type d -not -name '\.*' -maxdepth 1 -print); (current_dir="$cwd/${dir##./}"; echo "Updating $current_dir"; cd $current_dir; git pull --all;)

2016-11-18

Run multiple Intellij version installations on linux

I love Intellij very much. I like the jetbrains EAP program for trying out new features of the IDE. After being screwed a couple of times replacing a working installation by a faulty one, I elaborated a way of keeping several versions of Intellij in parallel.

As a side note: I'm reporting about a Linux Mint 18 install but I guess most other linux distributions will have minor adjustments to get this approach working.

First of all I like to keep all versions and needed files in a dedicated folder in /opt/IDEA. I have them symlinked so I can more easily switch versions:

/opt/IDEA ‹›
╰─$ ls -la    
insgesamt 24
drwxr-xr-x  6 dhiller dhiller 4096 Nov 17 11:17 .
drwxr-xr-x 13 root    root    4096 Nov 16 15:59 ..
lrwxrwxrwx  1 dhiller dhiller   13 Nov 14 17:20 current -> idea-2016.2.5
lrwxrwxrwx  1 dhiller dhiller   11 Nov  9 09:29 eap -> idea-2016.3
lrwxrwxrwx  1 dhiller dhiller   19 Okt 20 08:18 idea-2016.2.5 -> idea-IU-162.2228.15
lrwxrwxrwx  1 dhiller dhiller   19 Nov 17 11:09 idea-2016.3 -> idea-IU-163.7743.37
drwxr-xr-x  9 dhiller dhiller 4096 Okt 20 08:17 idea-IU-162.2228.15
drwxr-xr-x  9 dhiller dhiller 4096 Nov  9 09:29 idea-IU-163.7342.3
drwxr-xr-x  9 dhiller dhiller 4096 Nov 14 08:50 idea-IU-163.7743.17
drwxr-xr-x  9 dhiller dhiller 4096 Nov 17 11:09 idea-IU-163.7743.37
lrwxrwxrwx  1 root    root      37 Sep  7 11:56 idea.vmoptions -> /home/dhiller/bin/IDEA/idea.vmoptions
lrwxrwxrwx  1 root    root      43 Sep  7 11:56 run_idea_with_env.sh -> /home/dhiller/bin/IDEA/run_idea_with_env.sh

First of all I have a file where my Intellij options are stored:

File: /opt/IDEA/idea.vmoptions

-Xms1G
-Xmx2G
-XX:MaxPermSize=512m
-XX:ReservedCodeCacheSize=512m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-Dawt.useSystemAAFontSettings=on
-Dswing.aatext=true
-Dsun.java2d.xrender=true

Then I have a shell script:

File: run_idea_with_env.sh

#!/bin/bash

if [ ! -d "/opt/IDEA/$1" ]; then
        echo "Usage: $0 "
        exit 1
fi

# set environment variables
export JAVA_HOME="/usr/lib/jvm/default-java/"
export IDEA_VM_OPTIONS="/opt/IDEA/idea.vmoptions"

/opt/IDEA/$1/bin/idea.sh

Last but not least I have two or three desktop definitions to be able to start the IDE from the Menu in ~/.local/share/applications:

File: jetbrains-idea.desktop

#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Type=Application
Name=IntelliJ IDEA
Icon=/opt/IDEA/current/bin/idea.png
Exec="/opt/IDEA/run_idea_with_env.sh" current
Comment=The Drive to Develop
Categories=Development;IDE;
Terminal=false
StartupWMClass=jetbrains-idea

File: jetbrains-idea-eap.desktop

#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Type=Application
Name=IntelliJ IDEA EAP
Icon=/opt/IDEA/eap/bin/idea.png
Exec="/opt/IDEA/run_idea_with_env.sh" eap
Comment=The Drive to Develop
Categories=Development;IDE;EAP
Terminal=false
StartupWMClass=jetbrains-idea

The key point is the line starting with Exec that points to the version to start:

Exec="/opt/IDEA/run_idea_with_env.sh" current

But you just could start the IDE from a terminal with:

$ /opt/IDEA/run_idea_with_env.sh current

for starting the latest stable or




$ /opt/IDEA/run_idea_with_env.sh eap


for starting the latest EAP version,

When installing a new version I just download it, untar it into /opt/IDEA, change the symlink to point to the new version, and that's it.

2016-05-12

Don't forget that thenThrow returns an OngoingStubbing instance *sigh*

I've often had the problem that when checking for a working retry mechanism (btw. spring-retry works great) I wanted to first throw an exception and then return a value or whatever else is necessary.

Easy peasy, I thought. Just create an Answer and hold state within the answer i.e. a boolean that gets set to true after it has been called:

    @Test
    public void queryIsRetried() {
        final Answer objectAnswer = new Answer() {

            boolean called;

            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                if(called) {
                    return null;
                }

                called = true;
                throw new RuntimeException();
            }
        };
        when(lexdbJdbcTemplate.query(anyString(), any(RowMapper.class)))
                .then(objectAnswer);
        underTest.query("SELECT 1;");
    }


And of course there is a much easier way, stupid me:


    @Test
    public void queryIsRetried() {
        when(lexdbJdbcTemplate.query(anyString(), any(RowMapper.class)))
                .thenThrow(new RuntimeException())
                .thenReturn(null);
        underTest.query("SELECT 1;");
    }

2015-12-14

Git aliases, the easy way

After wrestling with the global .gitconfig file for installing aliases like a shortcut for status using vi, I thought there must be an easier way, and there is (as always when using git):

Create an alias for a compressed log with decorations and graph:

git config --global alias.l 'log --format=oneline --graph --decorate'

So instead of typing 

git log --format=oneline --graph --decorate

then you can just enter 

git l

and you will get a onelined history output complete with ascii visual graph and annotations for where every branch pointer is ATM :)

> git l
* 87e02884a6d45e0d003ffcdccf41098716ca876e (HEAD -> master) Moved files to folder
* 9d1c1dee120e5a189f562c2fc5d12709ae35102d (origin/master) Latest version
* 7b34163291fda0b82bf4777d7b9c24a22df9338e Corrected special characters
* 838ccffe24c7356f52063fc0b6e6c638dcccbd5a Removed lock file
* 74fff37b8ee77113b0702baeb0f9b85f17e5f7e9 Added gitignore
* 4b87667f117412034e977f61de8839b251b5ff81 Added conversion script
* 291eed8a5f44520e8ca706bc6fc7286978fc821c Initial commit

2015-06-18

Useful git aliases when working with Maven and Jira

Put these into your .gitconfig below the alias section:

# Return all jira issue keys from commit messages
issues = !sh -c 'git log --oneline $@ | egrep -o [A-Z]+-[0-9]+ | sort -V | uniq' -
# Fetch id of latest commit from maven release plugin
release-commit = !sh -c 'git log --all --grep=maven-release-plugin.*prepare.release --format=%H| head -1'
# Return all jira issue keys since last usage of maven release plugin
issues-since-release = !sh -c 'git issues $(git release-commit)..'


2012-06-04

Using Infinitest for real

Making your Test driven development faster in real projects

When you are practicing TDD like I do you may blindly know your keyboard shortcut to start your test runs after you've changed something. Or do you still use your mouse? :-)

Infinitest is a great tool to get rid of those shortcuts. Whenever a change occurs in a class it runs the tests that accompany it. Well, that's already awesome but fasten your seatbelt: Infinitest also runs tests of classes that are affected by your change.

How they do this magic I haven't elaborated but I can assure you of the effect: When using Infinitest you will notice net effects of your changes much faster.

But...

I always loved Infinitest for it's incredibly short feedback loop, yet disabled it in my current maven multi module project for seemingly obvious reasons: "No, I am too lazy don't have time to figure out how to properly set it up" (That of course I would not confess to myself.)

This meant I didn't figure out how to configure it so it wouldn't always mess up my own dev environment or, being quite more of an impact, the integration test environment.

As you might guess I have successfully set up Infinitest for this monster of a project.

The project

The Project is a maven multi module project with a dozen modules and specifically a module containing most of the integration tests. It is completely stored in a remote git repository. I have set up a local virtual machine containing a database for testing and a local memcached. The project is configured via a set of -D properties that specify which of these to use during integration tests, so that these can be run locally or on the dedicated test instances running on the integration server during the Jenkins CI build. The CI build runs on every push to the server repository.

And here comes the problem: Whenever a local integration test fails to run on the local database engine, but uses the integration instance instead, it may interfere with a running CI build. 

For a thing like Infinitest, which runs a couple of tests on each change, the test runs (including the integration tests) may happen quite often. So I have to make sure Infinitest propagates the properties of i.e. where to find the database to the test cases.

The easiest solution (read: solution of the lazy one) is of course: switch it off.

Beware: configuring Infinitest for such a project requires a bit of work if you don't have it enabled directly after you started. But it can be done and is well worth the effort.

There are a couple of constraints you have to consider when using Infinitest:

  1. When you are working in Eclipse you can not switch it on or off on a per project basis
  2. Settings are configured using files
  3. You have to have a set of files for each project
  4. Test cases may be filtered by
    1. Using regular expressions and/or
    2. Using TestNG groups
  5. Arguments are passed as -D properties in a files
See the Infinitest user guide for more information.

Preparations

The best way is: Have your integration tests in a single module. If you're using TestNG, use a group attribute in the test annotation. If you can't do that, move them into a separate package. If you can't do that and are not using TestNG, use a naming convention for your integration tests so you can easily filter them out. If you can't do that, you're screwed (well, I'm open for suggestions :-).

Setting it up

At first create a file called infinitest.args that contains all properties that have to be propagated to the test cases. Then create a file infinitest.filters that contains all filters for your integration tests (i.e. TestNG group or package regular expression or regular expression for the test case name. These files I'll call the master files for reference later on.

Put these two files into the top level maven project folder. Then make soft links in each module to these files. You can't do that? Well, you are on your own now ;-)

Hint: A very nice property of git is that it stores symbolic links in the repository. So you will share the links with the other project participants.

Don't put your master files into version control, or others will share the settings, which you probably don't want. But maybe you don't care whether they're using your database, do you? So you just put them into the .gitignore file.

Remember to not ignore the links in the module directories, of course.

So you should be fine right now. Just check the "Continuously test" option and enjoy the short feedback cycle from now on :-)

Hint: A slight modification which you may consider: For each project where you don't want to execute any tests just put an infinitest.filters with content .* instead of the symbolic link into the module directory.

So I hope this short guide helps you to get faster in test driven development and getting rid of manually executing tests via the mouse or a keyboard shortcut or whatever else you use. Please let me know if you have any corrections or suggestions.

My final notice: if you want to get really fast, just start using Infinitest whenever you start a new project. It's worth it!

Thanks for reading, anyway :-)

Followers