DaedTech

Stories about Software

By

Setting up MongoDB on Fedora

This is one of those posts as much for my own reference as anything else, and if it helps others, then bonus.

I installed MongoDB on my old Fedora server just now, and while it was actually pretty straightforward to do, I figured I’d document the steps. The first thing to remember is that there are two separate installs: the client and the server (this is what tripped me up on the MongoDB site’s documentation). There isn’t some deal where running server install also gives you a client.

So, to set up a smooth, easy install with yum, the first thing you need to do is create the file “/etc/yum.repos.d/10gen.repo”. Once you’ve created that file, open it and add the following:

[10gen]
name=10gen Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/i686
gpgcheck=0

Now, once you’ve got that in place, run the command, “yum install mongo-10gen mongo-10gen-server”. This will install both the client and the server. When the client and the server are in place, you can start the server by running “/etc/init.d/mongod start”. Finally, if you’re like me, you probably want the server to run automatically. If that’s the case, execute the command “chkconfig mongod on”.

And, you’re set. MongoDB server is installed and running and will also run on your next reboot.

By

JUnit for C# Developers 6 – Cart Before the Horse

In this post, I’d like to point out something I learned while working following yesterday’s post. In my haste to find the JUnit equivalent of MS Moles, I didn’t stop to think about what I was doing.

So, as I expanded on yesterday’s effort, I realized that my mocking of Runtime.getRuntime() didn’t seem to be working properly. As I set about trying to fix this, something dawned on me. Runtime.getRuntime() returns a Runtime object, and it’s that object’s exec(string) method that I’m interested in. So, in the code that I was trying to test, I was engaging in a double whammy of a Law of Demeter violation and inlining a static dependency.

I believe I was distracted, as I mentioned, by my desire to find C# equivalents in Java and by the general newness of what I was doing. But, this is a “teachable moment” for me. It’s easy to slip into bad habits when things are unfamiliar. It’s also easy to justify doing so. When I realized what I was doing, my first thought was “well, give yourself a break, Erik — just go with it this way until you’re more comfortable.” I then shook off that silly thought and resolved to do things right.

It’s easy to follow good design principles when you’re following a tutorial or being taught. But, it’s imperative to do it all the time so that it becomes a reflex. This includes when you’re tired late at night and just wanting to turn off your downstairs light without going downstairs (my situation now). It includes when you’re behind schedule and under the gun on a project. It includes when people are giving you a hard time. It’s always. If you practice doing it right — make it rote to do it right — then that’s what you’ll do by default.

So, humbled, here is my updated code:

Tests


@RunWith(Enclosed.class)
public class LightManipulationServiceHeyuImplTest {

	private static LightManipulationServiceHeyuImpl BuildTarget() {
		return BuildTarget(Mockito.mock(Runtime.class));
	}
	
	private static LightManipulationServiceHeyuImpl BuildTarget(Runtime runtime) {
		return new LightManipulationServiceHeyuImpl(runtime);
	}
	
	public static class constructor {
		
		/**
		 * This class makes no sense without a runtime, so don't let that happen
		 */
		@Test(expected=IllegalArgumentException.class)
		public void throws_IllegalArgumentException_when_runtime_is_null() {
			new LightManipulationServiceHeyuImpl(null);
		}
	}
	
	public static class toggleLight {
		
		/**
		 * Make sure the service is invoking the runtime's exec() to invoke heyu
		 * @throws IOException
		 */
		@Test
		public void invokes_getRuntimes_exec() throws IOException {
			
			Runtime myMock = PowerMockito.mock(Runtime.class);
			Process myProcessMock = PowerMockito.mock(Process.class);
            Mockito.when(myMock.exec(Mockito.anyString())).thenReturn(myProcessMock);
            
			LightManipulationServiceHeyuImpl myService = BuildTarget(myMock);
			myService.toggleLight(new Light("asdf", "Fdsa"), true);
			
			Mockito.verify(myMock).exec(Mockito.anyString());
		}
		
		/**
		 * If the exec works fine, then return true for successful command
		 * @throws IOException
		 */
		@Test
		public void returns_true_when_exec_does_not_throw() throws IOException {
			Runtime myMock = PowerMockito.mock(Runtime.class);
			Process myProcessMock = PowerMockito.mock(Process.class);
            Mockito.when(myMock.exec(Mockito.anyString())).thenReturn(myProcessMock);
            
			LightManipulationServiceHeyuImpl myService = BuildTarget(myMock);
			assertEquals(true, myService.toggleLight(new Light("asdf", "Fdsa"), true));
		}
		
		/**
		 * If the runtime's exec throws an exception, then this was not a successful op
		 * @throws IOException 
		 */
		@Test
		public void returns_false_When_exec_throws_exception() throws IOException {
			Runtime myMock = PowerMockito.mock(Runtime.class);
            Mockito.when(myMock.exec(Mockito.anyString())).thenThrow(new IOException());
            
			LightManipulationServiceHeyuImpl myService = BuildTarget(myMock);
			assertEquals(false, myService.toggleLight(new Light("asdf", "Fdsa"), true));
		}
		
		/**
		 * If we get a null process back, something went wrong
		 * @throws IOException
		 */
		@Test
		public void returns_false_when_exec_returns_null() throws IOException {
			Runtime myMock = PowerMockito.mock(Runtime.class);
            Mockito.when(myMock.exec(Mockito.anyString())).thenReturn(null);
            
			LightManipulationServiceHeyuImpl myService = BuildTarget(myMock);
			assertEquals(false, myService.toggleLight(new Light("asdf", "Fdsa"), true));
		}
	}
}

and class under test:

public class LightManipulationServiceHeyuImpl implements LightManipulationService {

	private Runtime _runtime;
	
	public LightManipulationServiceHeyuImpl(Runtime runtime) {
		if(runtime == null)
			throw new IllegalArgumentException("runtime");
		_runtime = runtime;
	}
	
	@Override
	public Boolean toggleLight(Light light, Boolean isOn) {
		try {
			return _runtime.exec("command") != null;
		} catch (IOException e) {
			return false;
		}
	}

	@Override
	public Boolean changeBrightness(Light light, int brightnessChange) {
		// TODO Auto-generated method stub
		return null;
	}
}

Obviously, I don’t want to execute the shell command “command”, but that’s tomorrow’s TDD. I’m happy for the evening, now that I’ve refactored an inline static Law of Demeter violation out of my design plans. 🙂

By

SVN Global Ignore

This morning, I was adding a playpen I’d created of an enormous project to subversion. In my playpen, I was only editing a handful of .cs files, but I wanted to add all .cs files to my little repository. What I didn’t want to add were, obviously, outputs of the project, but other stuff that is sourced controlled in that project, like various media files and other space-suckers.

My first thought was to impose ignores on the individual directories, manually adding things to the ignore list, but that’s incredibly cumbersome in a project of this size. At this point, I remembered the SVN global ignore settings where I can have the shell simply omit stuff in my add window and show it as ignored in explorer windows (MS Windows, here, obviously).

To access it, rick click anywhere and go to TortoiseSVN->Settings. You’ll see the following, and circled is what you want to edit:

You can put extensions here with wildcards and you can, as I did, put the names of directories in here (such as bin, debug, release, etc). Once you put these in, they will be ignored by default and they will not appear in the “add” window of tortoise. You can still add them — this does not supersede actual source control. You just have to do it manually.

By

Fixing the Crackle and Pop in Ubuntu Sound

So, as I blogged previously, I’ve been re-appropriating some old PCs and sticking Ubuntu 11.10 on them. I had one doing exactly what I wanted it to do in the context of my home automation network with one small but annoying exception. Whenever I would play music through headphones or speakers, there would be a crackling noise. A google search turned up a lot of stuff that I had to weed through, but ultimately, this is what did the trick:

I opened /etc/pulse/default.pa and found the line

load-module module-udev-detect

This was located in an “ifexists” clause. It should be replaced by this:

load-module module-udev-detect tsched=0

From there, reboot. I can’t speak to whether this will fix everyone’s crackle or just some people’s, and I can’t speak to why this setting isn’t enabled by default, but c’est la vie. This is what did the trick for me, and hopefully it fixes the problem for someone else as well.

By

Ubuntu and Belkin Dongles Revisited

Previously, I posted about odyssey to get belkin wireless dongles working with Ubuntu. Actually, the previous post was tame compared to what I’ve hacked together with these things over the years, including getting them to work on Damn Small Linux where I had to ferret out the text for the entire wpa_supplicant configuration using kernel messages from demsg. But, I digress.

I’m in the middle of creating an ad-hoc “music throughout the house” setup for my home automation, and this involves a client computer in most rooms in the house. Over the years, I’ve accepted donations of computers that range in manufacture date from 1995 to 2008, and these are perfect for my task. Reappropriated and freed from their Windows whatever, they run ably if not spectacularly with XUbunutu (and, in some cases DSL or Slackware when that’s too much for a machine that maxes out at 64 meg of RAM).

So, I have this setup in most rooms, and I just remodeled my basement, which was the last room to get the setup. I had one of these things working with the dongle and everything, but the sound card was this HP Pavilion special that was integrated with a fax card or something, and the sound just wasn’t happening. So, after sort of borking it while trying to configure, I scrapped the effort and reappropriated an old Dell.

Each time I do this, I grab the latest and greatest Ubuntu, and this time was no different. Each time, I check to see if maybe, just maybe, I won’t have to pull the Belkin drivers off of the CD and use ndiswrapper, and lo and behold, this was the breaking point – I finally didn’t.

I wish I could say it worked out of the box, but alas, not quite. I plugged in the dongle and the network manager popped up, and sure enough it was detecting wireless networks, but when I put in all of my credentials, it just kept prompting me for a password. I remembered that Network manager had difficulty with these cards and WPA-PSK security protocol, so I tried another network manager: wicd. Bam! Up and running.

So, for those keeping score at home, if you have Ubuntu 11.10 (Ocelot) and a belkin dongle, all you need to do is:

sudo apt-get install --reinstall wicd
sudo service network-manager stop
sudo apt-get remove --purge network-manager network-manager-gnome
sudo service wicd restart

And, that’s it. You should be twittering and facebooking and whatever else in no time.

Edit:

Since making this post, I set up another machine in this fashion, and realized that I made an important omission. The wicd wireless setup did not just work out of the box with WPA2. I had to modify my /etc/network/interfaces file to look like this:

auto lo
iface lo inet loopback

auto wlan0
iface wlan0 inet static
address {my local IP}
gateway 192.168.2.1
dns-namesevers 192.168.2.1
netmask 255.255.255.0
wpa-driver wext
wpa-ssid {my network SSID}
wpa-ap-scan 2
wpa-proto WPA RSN
wpa-pairwise TKIP CCMP
wpa-group TKIP CCMP
wpa-key-mgmt WPA-PSK
wpa-psk {my encrypted key}

For my network, I use static IPs and this setup was necessary to get that going as well as the encryption protocol. Without this step, the setup I mentioned above does not work out of the box — wicd continuously fails with a “bad password” message. Adding this in fixed it.

Cheers