Sunday, September 03, 2017

Games on Linux

One of the major disadvantage of Linux is luck of games. Most of PC games are only run on Windows. However, as a casual game player, I can see there is a lot of improvement in recent years.

First of all, there are more and more games officially support Linux. Steam, a popular game distribution platform, can run on Linux. Steam also maintains a Linux distribution, called SteamOS, which is specialized for using Steam. In Steam, I can search the games supporting Linux. Recently, I have bought two games, Civilization V and Cities: Skyline, from Steam. Both are running smoothly on my Ubuntu box.

If the game only support Windows, there is still a hope that it can run on WINE. WINE is similar to a Windows virtual machine (VM), but it simulates Windows on OS level instead of hardware level. The performance of WINE is much better than traditional VM, especially on 3D graphics. However, WINE is not prefect. The community of WINE is keep improving it. You can get a list of Windows software which can run in WINE here. In my past experience, with some tricks mentioned in the WINE page, I can run Windows version of Steam. In the Steam, I can run AOE II, AOE III, and Simcity 4 Deluxe. Recently, I follow the guide to install League of Legends (LoL). It is also running fine on my Ubuntu box.

Last but not the least, the open source community also developed a lot of open source games for Linux. I found the most impressive one is SuperTuxKart.

Happy gaming on Linux!


Saturday, July 29, 2017

JUnit Test for Singletons/Static Variables

JUnit runs all tests in one instance of JVM. Therefore, it assumes individual test cases are independent and should not interfere each other. However, this is not true for singletons or static variables. The status of singletons and static variables carry over across test cases. This causes troubles for JUnit tests.
Let me show you an example. Assume we have a MyService class: MyService class is a typical implementation of singleton. In addition, it has two methods:
init(String config)
to initialize MyService with a config parameter. This method can only call once.
doSomeService(FileWriter)
ask MyService to do something. In this example, it writes the value of someConfig via FileWriter parameter.
Now, we want to implement some JUnit test classes to verify the implementation. The first test class initializes MyService with "Hello!" and verifies whether doSomeService(...) really tries to write "Hello!". The second test class initializes MyService with "Hi!" and verifies whether doSomeService(...) really tries to write "Hi!". If you run the above test cases one-by-one in your IDE, it works fine. However, if you run both test cases in one go, one of the test cases fails:
As mentioned at the beginning, JUnit tests are run in one instance of JVM. If you run both test cases, because of singleton design pattern, the MyService instance of first test case is carried over to the second test case. When the second test case calls the init(...) method, it throws exception. This is actually one of the infamous disadvantages of singleton design pattern. However, you may not be able to re-design your system. Then, how can we fix the unit tests?

Actually, there is a workaround to force reloading of classes for each test using class loader trick. For each JUnit test class, we use a customized test runner which enforce a separated instance of class loader for each test class. Then, the classes we want to test will be reloaded for each JUnit test class Here is the implementation of the test runner (SeparateClassloaderTestRunner):
To use the SeparateClassloaderTestRunner, you need to replace the "@RunWith(MockitoJUnitRunner.class)" to "@RunWith(SeparateClassloaderTestRunner.class)" in the test classes. Then, if you run both test cases in one go, both test cases will pass.
You can get the demo source code at github - https://github.com/loklam/reloadclassdemo.

Thursday, July 27, 2017

Working Copy - a good Git Client for iPad

Recently, I want to read some source code located in GitHub. I found there is a handy tool - Working Copy. It's a Git Client for iPad. It has a nice code browser and code viewer/editor with syntax highlight. You can even edit the code and commit the changes. Now, I can read code during travelling.

Sunday, May 14, 2017

a lightweight code generator - cog


Recently, I need to write a library to read and write JSON messages for C++. The library should be able to serialize/deserialize an message object to/from a JSON message. However, the messages schema can be changed from time to time for new requirements. So, I need to think a way to adapt the schema change easily.

In Java world, there are many mature JSON libraries support this, e.g. JSON-B, Gson, .... However, C++ doesn't have reflection. We cannot have C++ version of libraries like JSON-B and Gson. For C++, the only option is code generation. There are number of ways to do code generation. After some search on the web, I found a Python based code generator -- Cog, and here is a success story about using Cog. The tool works very good and it's lightweight. With the code generation, it saved me a lot of time when there is any schema change.

Sunday, February 05, 2017

Recovery Ubuntu boot entry in UEFI after upgraded motherboard firmware

Nowadays, UEFI is commonly used to replace the BIOS. UEFI doesn't use boot sector in disks. Instead, UEFI comes with a boot manager. During installation of an OS, e.g. Ubuntu Linux, the OS installer usually setup the boot loader (e.g. GRUB) in EFI partition and update the boot config. The boot config provides information for boot manager to locate the boot loader. The tricky part is the boot config is stored in NVRAM on the motherboard. During firmware upgrade, NVRAM can be reset. This means the boot config will also be reset and lost the boot loader information.
I encountered this issue when I upgrade the firmware of my Xubuntu box. Now, I would like to show you how to recovery the boot config. This demo is using Ubuntu 16.04 on Virtual Box.

  1.  Get an installation CD or a flash drive with installer of Ubuntu 16.04 (You should have it when you install the Ubuntu first time). If you don't have it, get it from here.
  2.  Boot up the system using the CD or flash drive. In GRUB, select "Try Ubuntu without installation"
  3. Then, you should be able to boot into a fresh Ubuntu, like
  4. Open a terminal and run "sudo su" to switch to root user.
  5. Now, we need to know where the EFI partition located. We can use "fdisk -l /dev/xxx" command to list out the paration, like:
    Refer to the above screen, we know that the EFI partition is on the first partition of device "sda" (i.e. /dev/sda1). (Note: the actual location of the EFI partition on your box can be different from this demo.)
  6. Then, we mount the EFI partition to verify if the Ubuntu GRUB loader is installed. To do this, mount the drive using command "udiskctrl mount -b /dev/xxx" and check if the EFI partition contains "EFI/ubuntu/shimx64.efi" file. E.g.:
  7. After the above verification, we have enough information to create the add the boot entry using the command:
    efibootmgr -c -d /dev/xxx -p n -l '\EFI\ubuntu\shimx64.efi'
    where "xxx" is the disk device contains the EFI partition, and "n" is the partition number. E.g.:

  • shutdown the box, remove the CD or flash drive and reboot. Then, we should be able to see the GRUB again.
  • Monday, January 02, 2017

    jq - a powerful unix command line tool for handling JSON data

    Nowadays, JSON is a popular data format, especially in web services domain. However, traditionally, Unix command line tools, e.g. sed, awk, grep, etc., are not capable to handle JSON data format. So, it is hard to write shell scripts to reading JSON data.
    Fortunately, I found a handy and powerful tool - jq. In this page, I want to show you an example of using jq to extract weather forecast in JSON format to CSV. First of all, I get the data from weather forecast serveice of api.openweathermap.org and save it to "forcecast.json" file:
    Here is the raw data, hard to read by human,
    jq can print the JSON in pretty format, with color:
    Now, I show you how to extract the dt_txt(forecast time), temp (forecast temperature) and humidity (forecast humidity) from the JSON data to CSV:
    Just a  single command can covert JSON to CSV. How powerful is it! For the usage details of jq, you can refer to the manual

    Friday, December 23, 2016

    Log TCP Connections to WAN in OpenWrt

    I have a router running OpenWrt 15.05. I would like to log all the TCP connections. To achieve this, I just need to add a line in the firewall custom rule like:
    iptables -A forwarding_lan_rule -p tcp -m state --state NEW -m limit --limit 30/sec -j LOG --log-prefix "NEW Conn "
    
    
    Then, login the router as root, and restart the firewall with the following command:
    /etc/init.d/firewall restart
    

    The following shows how the System Log looks like after enable the custom rule: