This blog is about Java (advanced Java topics like Reflection, Byte Code transformation, Code Generation), Maven, Web technologies, Raspberry Pi and IT in general.

Freitag, 13. Juni 2014

Mock Framework vs Anonymous Class for Unit Tests



I recently discussed at work what to use for unit tests: a mock framework (e.g. Mockito) or anonymous classes. Surprisingly for my only one person choose anonymous classes and there where many votes for the mock framework. I prefer myself the mock framework. 

The benefits of a mock framework:
  • if you mock an interface within multiple tests with anonymous classes and then you change the interface you have to touch all of these test files. Even if the new added method doesn't break the old tests.
  • if the interface has many methods but you need only a few of them, the anonymous class still have to implement each method. So it's quite messy and doesn't help to read the code.
  • sure your IDE will generate the anonymous class with all methods with one keystroke. But if you want to make explicit which method is used in the test than you have to rewrite all unnecessary methods to something like this: throw new RuntimeException("not implemented"). Because otherwise you can't decide if the test relies on the method to return null or it's not used for the test.
  • the code navigation in the IDE (at least IntelliJ) gets messed up because of the anonymous test classes. If you want to jump to the method implementation of an interface and there is one class implementing the interface than IntelliJ will jump directly to the correct code (ctrl+shift+b). But if in the test classes the anonymous mock classes are defined than IntelliJ will show you all anonymous classes which are in this case completely uninteresting.
  • mocks are cleaner to write. if you want different return values by different parameters than you just define them in two lines. In an anonymous class you have to use if/else.
  • mocks are more powerful. You can verify if the methods got called with the right parameters and are called exactly x times.
There is just one downside of mock frameworks: you have to learn one of them. 
It pays off to learn a mock framework and to use it because of all the benefits you get from it (see above). I am currently using Mockito which has a very easy and clean API.

Dienstag, 14. Mai 2013

Tutorial: how to setup a torrent-box (torrent-tracker + seeding client) on a Raspberry Pi


Motivation

Most people use Dropbox and other cloud services to share their files. But if you want to be in control of your files - without any restrictions - than you need to setup your own share server. The simplest way to do so is to setup a FTP or HTTP server. I didn't want to use a FTP because the person you want to share your files with has first to setup the connection - too much work. Another problem with both options is that they don't handle a connection lost very well. So I decided to use a torrent network.
  • it can handles a connection lost very well
  • the peers will upload too (important if you share you files with many people)
  • easy to use: just send a magnet link or a torrent file

Setup a Torrent Tracker - opentracker

 At first we setup our own torrent tracker using opentracker.

sudo apt-get install cvs
cvs -d :pserver:cvs@cvs.fefe.de:/cvs -z9 co libowfat
cd libowfat
make
cd ..
cvs -d:pserver:anoncvs@cvs.erdgeist.org:/home/cvsroot co opentracker
cd opentracker
make
chmod a+x opentracker

That's it. Just start the torrent tracker

./opentracker


Setup a Torrent Client - rtorrent

The tracker connects the peers with each other but it doesn't seed (upload) anything. So we need a torrent client which will seed our shared files. Get the program

sudo apt-get install rtorrent

Configure rtorrent

wget http://libtorrent.rakshasa.no/export/1303/trunk/rtorrent/doc/rtorrent.rc
mv rtorrent.rc ~/.rtorrent.rc
nano ~/.rtorrent.rc

The most important configuration settings

# sure use udp
use_udp_trackers = yes
# encryption is always a good idea
encryption = require
# change it so it doesn't conflict with our torrent tracker which uses the port 6969
port_range = 6890-6960
# where the files are saved
directory = ~/downloads/torrents/
# load automatically all torrent files from the directory and start downloading or seeding
schedule = watch_directory,5,5,load_start=/var/www/torrents/*.torrent
# if the torrent files are removed stop downloading or seeding
schedule = untied_directory,5,5,stop_untied=

Now you could start rtorrent and start downloading torrents.


Create a Torrent File - mktorrent

Now we need to create a torrent for the files we want to share.

sudo apt-get install mktorrent
mktorrent -p -a http://${YOUR_IP_OR_DOMAIN}:6969/announce -a udp://${YOUR_IP_OR_DOMAIN}:6969/announce FILE_OR_DIRECTORY -o OUTPUT_FILE.torrent

That's it. Put the torrent file in you torrent watch directory and start rtorrent. Rtorrent will read the file and start seeding. Don't forget the source file must be in the right directory (see the rtorrent setting directory=).


Setup your router and start sharing

You probably need to setup a port forwarding to your Raspberry Pi for the necessary ports.
Then you can start sharing your files in your own private torrent network :)




Further reading

How to automatically start opentracker and rtorrent
How to generate a magnetic link form a torrent file (convert torrent file to magnetic link)

Tutorial: How to automatically start opentracker and rtorrent on a Raspberry Pi


Motivation

In my last post I explained how to setup a torrent-box on a Raspberry Pi. But there is still one important thing to do: automatically start opentracker and rtorrent so you needn't to do it yourself after each reboot. It's not that easy because rtorrent can't be started as deamon and you probably want to be able to get the background rtorrent process so you can change the setting (e.g. limit the upload speed). To solve this problem I used tmux.

Setup the autostart


The first thing is to put the opentracker executable into the /usr/bin
Then install tmux

sudo apt-get install tmux

Now we have to write our init.d script which will be called at the startup

sudo nano /etc/init.d/torrent

With this content

# !/bin/sh
# /etc/init.d/torrent

BIN="/usr/bin"

case "$1" in
  start)
    echo "Starting torrent"
    start-stop-daemon --start --background --chuid=pi --exec $BIN/opentracker
    start-stop-daemon --start --background --chuid=pi --exec $BIN/tmux -- new-session -d -n rtorrent -s rtorrent rtorrent
    ;;
  stop)
    echo "Stopping torrent"
    killall opentracker
    killall rtorrent
    ;;
  *)
    echo "Usage: /etc/init.d/torrent {start|stop}:"
    exit 1
    ;;
esac

exit 0

Make the file executable and embed it into the starting process

sudo chmod 755 /etc/init.d/torrent.sh
sudo update-rc.d torrent.sh defaults

Basically that's it.

tmux

To get your running rtorrent process write

tmux attach

To put it back into the background press ctrl+b and then press d (for deattch).

tmux cheat cheet.

Tutorial: How to generate a magnet link form a torrent file (convert torrent file to magnetic link)

Motivation

It's easier to send just a link instead of a file if you want to share a torrent file.

Create the magic link

To create the magic link I used the bencode library (python). To easily install it we need first easy_install. The first thing to to is to install easy_install

wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg#md5=fe1f997bc722265116870bc7919059ea
sudo chmod 755 setuptools-0.6c11-py2.7.egg
sudo ./setuptools-0.6c11-py2.7.egg

Now it's very simple to install bencode

easy_install http://pypi.python.org/packages/2.7/b/bencode/bencode-1.0-py2.7.egg#md5=fa08025585d4cd7700bed503b6baf018

That's your preconditions. Now we can write our python script which will generate the magnic link.

nano createMagnetLink.py

Put following content into it

!/usr/bin/python

import sys
import urllib
import bencode
import hashlib
import base64

if len(sys.argv) == 0:
print("Usage: file")
exit()

torrent = open(sys.argv[1], 'r').read()
metadata = bencode.bdecode(torrent)

hashcontents = bencode.bencode(metadata['info'])
digest = hashlib.sha1(hashcontents).digest()
b32hash = base64.b32encode(digest)

params = {'xt': 'urn:btih:%s' % b32hash,
'dn': metadata['info']['name']}

announcestr = ''
for announce in metadata['announce-list']:
announcestr += '&' + urllib.urlencode({'tr':announce[0]})

paramstr = urllib.urlencode(params) + announcestr
magneturi = 'magnet:?%s' % paramstr

print(magneturi)

Make the file executable

sudo nano 755 createMagnetLink.py

And the just call it with a torrent file

./createMagnetLink.py file.torrent

Samstag, 11. Mai 2013

Tutorial: How to install a Tiny Tiny RSS (tt-rss) server on a Raspberry Pi (nginx, php, mysql)


Motivation

I love the Google Reader (RSS reader) very much and I used it heavily. But sadly Google decided to shutdown this great service. So it was time to look for an alternative and I found Tiny Tiny RSS (tt-rss). It's an open source RSS reader written in PHP. It's quite nice but there is one big issue: the website (JavaScript) is slow. It's impossible to use it on a smartphone. But there are Android apps for tt-rss which are quite nice.

Install & configure nginx, php & mysql-server

  • get all the packages
sudo apt-get update
sudo apt-get install nginx php5-fpm php5-cli php5-curl php5-gd php5-mcrypt php5-mysql php5-cgi mysql-server
  •  create the web directory
sudo mkdir /var/www
sudo chown www-data:www-data /var/www/
  •  configure nginx
    • open the config file
sudo nano /etc/nginx/sites-enabled/default 
    • modify it so it looks like this
server {
  listen   80;
  root /var/www;
  index index.html index.htm index.php;

  server_name localhost;

  location / {
    try_files $uri $uri/ /index.html;
  }

  location ~ \.php$ {
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
  }
}
  •  configure php-fpm
    • open the php.ini
sudo nano /etc/php5/fpm/php.ini
      • set: cgi.fix_pathinfo = 0;
    • open the www.conf
sudo nano /etc/php5/fpm/pool.d/www.conf
      •  set: listen = /var/run/php5-fpm.sock
  • restart nginx and php-fpm
sudo service php5-fpm restart
sudo service nginx restart
  • create the mysql database for tt-rss
mysql -u root -p
    • insert the password and execute those two commands
create database ttrss;
exit

 

Install Tiny Tiny RSS (tt-rss)

It's quite simple. Just grab the .tar.gz file, unpack it move it to the web directory and set the permissions. It's done like this. But you probably want to check if there is a newer version.

wget https://github.com/gothfox/Tiny-Tiny-RSS/archive/1.7.8.tar.gz
tar zxfv 1.7.8.tar.gz
mv Tiny-Tiny-RSS-1.7.8/ ttrss
sudo mv ttrss /var/www
cd /var/www/ttrss
chmod -R 777 cache/images && chmod -R 777 cache/export && chmod -R 777 cache/js && chmod -R 777 feed-icons && chmod -R 777 lock


Perform the tt-rss installation

http://localhost/ttrss/install

Setup the crontab

  • Open the crontab
crontab -e
    • Insert following line
*/15 * * * * cd /var/www/ttrss && /usr/bin/php update.php --feeds --quiet > /dev/null

With this setup the Raspberry Pi will load every 15 minutes the RSS feeds and update them so you can read them.

Enjoy your Tiny Tiny RSS (tt-rss) installation

That's it. Now you can open your installation, configure it and read your feeds. Have fun! :)

Samstag, 22. September 2012

Truecrypt benchmark for Raspberry Pi with Turbo

Introducing turbo mode: up to 50% more performance for free. This benchmark was run on raspbian/wheezy with the overclock setting "Turbo". The buffer size was was 5MB. With turbo truecrypt is about 60% faster than without.


Algorithm Encrypt Decrypt Mean
Twofish 14 12 13
Serpent 10 10 10
AES 7 5.3 6.1
Twofish-Serpent 5.9 5.5 5.7
Serpant-AES 4.1 4.0 4.1
AES-Twofish 4.6 4.2 4.4
Serpant-Twofish-AES 3.2 3.0 3.1
AES-Twofish-Serpent 3.2 3.0 3.1

Mittwoch, 12. September 2012

Java SimpleArchive with RandomAccessFile

 I had a quite simple problem. I want to read several hundred thumbnail images (movie posters) to display them in a Java program.

File system
The simplest approach is to save the images directly in the file system. It's working fine if all images are cached from the OS. But if not it takes several seconds to load all images. Another downside is that most of the files have a size of 6kb - 7kb (in a range of 3kb - 10kb). So you loose some space because the block size is usually 4kb. In my case it was about 25%.

Zip
The next idea was to save all images in a Zip archive. The standard Java library supports Zip archives directly. It looked very promising. It was quite easy to use and it worked fine. But there is one big problem. It's not possible to add files to an existing archive. You had always to recreate the complete file. It's no problem if the archive is small but if it gets bigger than this could consume quite a long time. I looked for other libraries and archive formats. But it seemed that there is no easy to use archive library which supported to add files to an existing archive. So I wrote my own very simple archive library with the RandomAccessFile API.

SimpleArchive (github)
It's very simple and very fast. It can add files to an existing archive without the need to recreate the file. It just adds the file(s) and rewrite the file index which is located at the end of the file. So it will be much faster by adding files to an archive than the Zip implementation. In a very basic test it read the files ~3 times faster than the the Zip implementation. If you want to know more about it just visit the github.