tag:blogger.com,1999:blog-80895677976759575272024-03-13T15:53:31.752+01:00cat brain | grep stuff > blog- Random stuff, maybe programming related, maybe crap not worth your timeAnonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.comBlogger33125tag:blogger.com,1999:blog-8089567797675957527.post-9176816415959106052016-08-03T23:47:00.000+02:002016-08-04T00:00:19.691+02:00<br />
<span style="font-size: large;">colored log(back) for unit tests in two steps</span><br />
<br />
<br />
<br />
<br />
<b>The goal</b><br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://4.bp.blogspot.com/-kjL8kibtkRU/V6Jk0A4cOFI/AAAAAAAAjy4/6AHiZeKoDiE_zE4ewf6kfwGgUoWdS_XlgCLcB/s1600/colored-log.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="385" src="https://4.bp.blogspot.com/-kjL8kibtkRU/V6Jk0A4cOFI/AAAAAAAAjy4/6AHiZeKoDiE_zE4ewf6kfwGgUoWdS_XlgCLcB/s640/colored-log.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Make my own stuff yellow, and keep the other stuff grey.</td></tr>
</tbody></table><br />
<br />
<br />
1. src/test/resources/<b>logback.groovy</b><br />
(modify the namespace you wanna highlight as your own)<br />
<br />
<script src="https://gist.github.com/finnjohnsen/87b14223aba07cf5f7c3c84c4f474e0f.js"></script><br />
<br />
<br />
2. Add this to your build.gradle (in addition to logback):<br />
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Source Code Pro'; font-size: 10.6pt;">testCompile <span style="color: #6a8759;">"org.fusesource.jansi:jansi:1.12"</span></pre><br />
<br />
Done.Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com1tag:blogger.com,1999:blog-8089567797675957527.post-50503221594318363392016-05-05T15:57:00.001+02:002016-05-05T15:57:33.422+02:00Windows 10 - United States International AltGr No Dead KeysI use US keyboard. However I loose my native æøå letters if I use standard US layout. AltGR No Dead Keys fixes this problem.<br />
AltGR + z makes the "æ"<br />
AltGr + l makes the "ø"<br />
AltGr + w makes the "å"<br />
<br />
Holding shift makes them uppercased.<br />
<br />
I couldn't figure out how to use the <a href="https://drive.google.com/open?id=0BwLOBwunelgTay1IZGlPYjBzTzg">.klc file</a> I've used in previous Windows versions. So I ended up having to make a .msi installer in "Microsoft Keyboard Layout Creator". Tedious stuff, so I decided to put it in my blog where I (and maybe you) can get it from in the future.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<a href="https://drive.google.com/open?id=0BwLOBwunelgTbnhMRzhuSVlPRlk">USIntNDK_amd64.msi </a><br />
<br />
<br />
PS. You shouldn't trust executables from random blogs, like here. So honoring that best practice I recommend you use the <a href="https://drive.google.com/open?id=0BwLOBwunelgTay1IZGlPYjBzTzg">.klc keyboard layout file</a> and create the .msi using <a href="https://msdn.microsoft.com/en-us/goglobal/bb964665.aspx?f=255&MSPPError=-2147217396">Microsoft Keyboard Layout Creator</a> yourself.Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-70568194506705364632015-01-01T19:20:00.005+01:002015-01-02T01:43:26.943+01:00Minecraft server in Docker<h2>
Minecraft server, in a docker container</h2>
<h2>
</h2>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: left; float: left; margin-bottom: 1em; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-V1CwI5HtPho/VKWS8_a7rAI/AAAAAAAAhIg/lCM3wrvF7Cs/s1600/docker.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://3.bp.blogspot.com/-V1CwI5HtPho/VKWS8_a7rAI/AAAAAAAAhIg/lCM3wrvF7Cs/s1600/docker.png" height="113" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
Feel free to use <a href="https://registry.hub.docker.com/u/finnjohnsen/minecraft-srv/">the docker image</a> uploaded to Docker Hub during this christmas holiday. <br />
<br />
Modify the <i>/home/finn/minecraft_data</i> -path to fit your server, and run this command: <br />
<br />
<br />
<br />
<br />
<b><i><span style="font-size: small;">docker run -d -v <span style="background-color: yellow;">/home/finn/minecraft_data</span>:/data -p 25565:25565 -p 25575:25575 --name minecraft -i finnjohnsen/minecraft-srv:1.8.1</span></i></b><br />
<br />
The Dockerfile <span style="font-size: small;"><a href="https://github.com/finnjohnsen/minecraft-srv">is on github</a></span><br />
<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-YUIlgWd4RGU/VKWS7D52bUI/AAAAAAAAhIY/d6fvAmMsPUE/s1600/minecraft.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-YUIlgWd4RGU/VKWS7D52bUI/AAAAAAAAhIY/d6fvAmMsPUE/s1600/minecraft.png" height="134" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Have fun gaming</td></tr>
</tbody></table>
Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-45943710687318623222013-11-21T15:20:00.001+01:002013-11-21T15:30:10.690+01:00Digging into EHCache (and TTL)Using a caching frameworks (like <a href="http://grails-plugins.github.io/grails-cache">Grails Cache</a> and <a href="http://grails.org/plugin/cache-ehcache">Grails EhCache</a>) instead of writing the caching mechanism yourself is comfortable. You find yourself smacking @<a href="http://grails-plugins.github.io/grails-cache/docs/manual/gapi/grails/plugin/cache/Cacheable.html">Cacheable</a> on listing operations and get methods - and <a href="http://grails-plugins.github.io/grails-cache/docs/manual/gapi/grails/plugin/cache/CacheEvict.html">CacheEvict</a> on the C<strike>R</strike>UD operations. Right?<br />
<br />
But this is extremely distant from the actual implementation - so I think it's a good idea to have a close look and confirm it works as you think.<br />
<br />
So let's investigate, using 2 techniques achieving 3 goals.<br />
<br />
Goals are: <br />
<b>1. Confirming Configuration run-time</b><br />
<b>2. Watching the Cache run-time</b><br />
<b>3. Confirming TTL timers in run-time</b><br />
<b><strike>4. Unit testing</strike></b><br />
<br />
Techniques described:<br />
<b>1. JMX</b><br />
<b>2. <a href="http://grails.org/plugin/console">Grails Console Plugin</a></b><br />
<br />
<h2>
</h2>
<div>
First you need to verify that EhCache is JMX exposed. I have this in Bootstrap.groovy.</div>
<br />
<div>
<script src="https://gist.github.com/finnjohnsen/7581657.js"></script></div>
<br />
Then, fire up jConsole<br />
<br />
<h3>
Confirming configuration</h3>
<div>
EhCache works "great" without any configuration at all - and then runs purely on defaults - which can trick you to believe your system works as you configured.</div>
<div>
<br /></div>
<div>
So let's see that the configuration you intended are correct. We do this by browsing in <b>jConsole</b> to <b>"net.sf.ehcache" -> "CacheConfiguration"</b> and click the cache name.<br />
<br />
<a href="http://4.bp.blogspot.com/-F2qoBZJmoRg/Uo4OMO5hpHI/AAAAAAAAddg/bPTm0sMi3ew/s1600/jconsole-ehcache-config.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="532" src="http://4.bp.blogspot.com/-F2qoBZJmoRg/Uo4OMO5hpHI/AAAAAAAAddg/bPTm0sMi3ew/s640/jconsole-ehcache-config.png" width="640" /></a><br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
I've now verified my cache TTL has the exact value 1800 seconds (aka 30 minutes), matches my config file. Meaning my config file works.<br />
<br />
<h3>
Watching the Cache run-time</h3>
</div>
<div>
Head over to CacheStatistics in <b>jConsole</b>, and watch for CacheHits and CacheMiss<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-7yH75u0AiEM/Uo4REzFH6GI/AAAAAAAAdd0/g2PswBY7DUg/s1600/jconsole-ehcache-statistics.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="622" src="http://3.bp.blogspot.com/-7yH75u0AiEM/Uo4REzFH6GI/AAAAAAAAdd0/g2PswBY7DUg/s640/jconsole-ehcache-statistics.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
CacheHit means the cache did its job and returned cached results instead of invoking the annotated method. CacheMiss means the method was invoked. A high number on CacheHits is probably a sign of a healthy set up.<br />
<br />
<b>Confirming TTL timers</b><br />
This may seem uneccesary, but I wanted to look at how this worked, so I dug into it. I couldn't find the TTL timers exposed in JMX, so I dug into the runtime using Grails Console Plugin.<br />
<br />
So grab the CacheManager, find your cache, and ask for ExpirationTime and Creation Time.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-k18w3mno9Jw/Uo4VeCsuneI/AAAAAAAAdeA/2ryW5_Cfzgo/s1600/console.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="348" src="http://1.bp.blogspot.com/-k18w3mno9Jw/Uo4VeCsuneI/AAAAAAAAdeA/2ryW5_Cfzgo/s640/console.png" width="640" /></a></div>
<br />
<br />
<br />
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><a href="https://gist.github.com/finnjohnsen/7582236">This code on Gist</a></b><br />
<b><br /></b>
As you see, there is a perfect 30 minutes between Expiration and Creation time. Perfect.<br />
<br />
Now sit back and wait until the ExpirationTime passes - and watch a new CacheMiss increasse in jConsole! If it does, everything is working as you intented.<br />
<b><br /></b>
<b><br /></b>
<b>Unit testing</b><br />
This kind of configurations doesn't feel like a good fit for unit testing in my book. But maybe I'm wrong.<br />
<br />
Cheers<br />
.finn<br />
<br />
<br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-66104320016260080592013-10-29T14:03:00.001+01:002013-10-31T19:14:22.251+01:00Easier Killing<h2>
Who are you?</h2>
<div>
<br /></div>
<h3>
"I take the long road" -guy <span style="font-size: xx-small;">(this has been me for years and years)</span></h3>
<div>
<br />
<ol>
<li>ps -ax | grep <something describing my process></li>
<li>look for the <pid></li>
<li>type kill -s 9 <pid></li>
</ol>
<div>
<br /></div>
<br />
<h3>
"I made a shortcut" -guy</h3>
</div>
<div>
Make a clever script which uses ps | grep output, cut, awk or whatever to get the pid for the kill.<br />
<br />
<h3>
"I use the existing shortcut" -guy</h3>
<i>pkill</i> -9 -f <something describing my process><br />
<br />
or <i>pgrep</i> first if I'm insecure about the regex</div>
Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-73238283945482911322013-10-16T12:32:00.002+02:002013-10-16T12:48:16.799+02:00Mocking grailsApplication<br />
You don't have to mock grailsApplication, unless you've put yourself in the same boat as me and like writing pure jUnit. Keep running <b>grails test-app</b> all the time is just annoying and slow. Note I havent tested Grails 2.3 yet, which is supposed to be faster than the predecessors.<br />
<br />
Anyway. This "pure" approach has one downside: your service/controller aren't getting its dependencies injected for free. You have to do everything yourself.<br />
<br />
Injecting services is easy, as you just <b>@grails.test.mixin.Mock</b> them in during <b>setUp</b>(). But there is that <i><span style="color: #444444;">def <b>grailsApplication</b></span></i> sitting at the top of your file. How to best mock it so you don't get NullPointerException in your test? I (mostly) use grailsApplication for configuration, so there lies my need for mocking.<br />
<br />
There are several ways of getting this done and I have two ways which I use. I can't decide on a favorite. Here they are, I'll let you decide what you like:<br />
<br />
<h3>
<u>nested maps</u></h3>
<div>
<blockquote class="tr_bq">
<i>@Before</i><br />
public void setUp() {<br />
service = MyService() //service is a global variable for the entire test.<br />
<b>service.grailsApplication = [config:[myApp:[jms:[firstQueue:"firstQueue"]]]]</b></blockquote>
</div>
<br />
This works best if you have really few properties. Maybe just one. But it's a one-liner, which I like.<br />
<br />
<h3>
<u>ConfigObject</u></h3>
<div>
<div>
<blockquote class="tr_bq">
<i>@Before</i><br />
public void setUp() {<br />
service = MyService()<br />
def mockConfig = new <b>ConfigObject</b>() <br />
mockConfig.myApp.jms.firstQueue="firstQueue"<br />
service.grailsApplication = [config: mockConfig]</blockquote>
</div>
</div>
<div>
<br /></div>
<div>
I know deep down that ConfigObject is the proper way of doing this - but it's more stuff to write.</div>
<div>
<br /></div>
<div>
Which do you like best?</div>
<div>
/Finn</div>
<div>
<br /></div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-16260696383020296202013-10-14T11:22:00.002+02:002013-10-15T09:44:04.481+02:00Groovy / Grails / GORM - File Name Too Long<h2>
<u>Yet another "File Name Too Long" workaround :-(</u></h2>
Normal day - was just gonna add one more check to my nice .where{} closure. But when I did, everything blew up in my face - and I'm sitting here with no eyebrows.<br />
<br />
The file will no longer compiles!<br />
<br />
#grails test-app<br />
<b>/home/finn/src/stratos/stratos/target/classes/no/nsb/stratos/MyService$_updateAllWithChanges_closure5_closure7_closure8_closure9_closure10_closure12_closure14_closure16.class (File name too long)</b><br />
<br />
When I commented back in the validTo everything went melt-down.<br />
<br />
<i>List<distributiontext> gsmList = DistributionText.where {</distributiontext></i><br />
<distributiontext><i> status.enabled==true &&<br /> status.ok==false &&<br /> status.validFrom <= new Date() && </i></distributiontext><br />
<distributiontext><i><b><span style="color: red;">//status.validTo >= new Date() && </span></b><br /> status.station != null &&<br /> channelCode=="FOO" &&<br /> language == "eng"<br />
}.list()</i><br />
<br />I can't figure out why this happens! The filename isn't over the Linux file length limit. </distributiontext><br />
<distributiontext><br /></distributiontext>
<distributiontext>I've seen this before when JSON marshalling really deep objects. (the workaroud then, was to create a map from intended object, and serialize the map instead)</distributiontext><br />
<distributiontext><br /></distributiontext>
<distributiontext>So, what to do when you really don't understand the error in front of you? Escape! So I that's what I did - I rewrote to </distributiontext>rewrote to <a href="http://grails.org/doc/latest/guide/GORM.html#criteria">Hibernate Criterion</a>.<br />
<br />
<i>List<DistributionText> gsmList = DistributionText.createCriteria().list {</i><br />
<i>status {</i><br />
<i> eq("enabled", true)</i><br />
<i> eq("ok", false)</i><br />
<i> le("validFrom", new Date())</i><br />
<i><b> ge("validTo", new Date())</b></i><br />
<i> isNotNull("station") </i><br />
<i>}</i><br />
<i>eq("channelCode", "FOO")</i><br />
<i>eq("language", "eng")</i><br />
<i><distributiontext></distributiontext></i><br />
<i>} </i><br />
<br />
I kinda like better the Groovy DSL/where to this Hibernate syntax, so if you find out how to get around the <i>File Name Too Long</i>, <b>please leave a comment.</b><br />
<br />Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com1tag:blogger.com,1999:blog-8089567797675957527.post-4839219019602660982013-04-16T23:40:00.004+02:002013-04-16T23:55:15.277+02:00Unit testing potential thread leakageSo you've bewildered yourself into the <strike>dark</strike> world of <strike>pain</strike> threads, and you wanna make sure your app doesn't leak threads.<br />
<br />
I found I had to calm my nerves by having tonnes of these Spock tests covering my Thread spawning.<br />
<br />
I took my actual code, pasted it into this blog, stripped and rewrote it to cut straight to the point.<br />
<br />
This silly service only illustrates the two methods for starting and stopping threads. This sample only spawns 1 thread but the point here are tests below.<br />
<script src="https://gist.github.com/finnjohnsen/5399767.js"></script><br />
<br />
To be sure your startJobs actually creates your thread(s), you should have a test confirming that first.<br />
<script src="https://gist.github.com/finnjohnsen/5399709.js"></script><br />
<br />
And here is the test looking for leakage:<br />
<script src="https://gist.github.com/finnjohnsen/5399654.js"></script><br />
<br />
<b>The whole idea is finding the threads by your given thread name.</b> And yes, i know Thread.sleep isn't ideal, and I may not need it, but it just feels reasonable to make sure the thread gets a little time to get going.<br />
<br />
Side note: I learned that you have to cancel both the Timer and the TimerTask. If you only cancel the Timer, you'll have to wait for the GC to clean up the thread, and your test will fail.Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-75289013388895275952013-03-26T11:52:00.002+01:002013-03-26T11:52:25.012+01:00grails run-app and tomcat jmxWant the standard Tomcat JMX exposed during development (<b><i>grails run-app)</i></b> ?<br />
<br />
Add this to your Config.groovy:<br />
<b>grails.tomcat.jvmArgs</b>=["-Dcom.sun.management.jmxremote", "-Dcom.sun.management.jmxremote.port=<b>8099</b>", "-Dcom.sun.management.jmxremote.ssl=false", "-Dcom.sun.management.jmxremote.authenticate=false"]<br />
<br />
Fire up jconsole and hit localhost:8099.<br />
<br />
</note to future self blog entry>Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-78951547478320191902013-03-25T14:12:00.001+01:002013-03-25T14:27:44.471+01:00Unit test your logging<span style="font-family: inherit;">I have a few log statements which are <u>really</u> important for me in production. Without them, I would be screwed when tracking whats actually going on.</span><span style="font-family: inherit;"> So I decided that this important code shouldn't be left out in the cold.</span><br />
<span style="font-family: inherit;"><br />
</span> <span style="font-family: inherit;">Here is a trivial example. Lets say the "Replacing address" log statement in the following code is really important when stuff hits the fan.</span><br />
<span style="font-family: inherit;"><br />
</span> <br />
<br />
<span style="font-family: inherit; font-size: x-small;"><span class="kt" style="color: #445588; font-weight: bold;">void</span> <span class="nf" style="color: #990000; font-weight: bold;">setAddress</span><span class="o" style="font-weight: bold;">(</span><span class="n" style="color: #333333;">Address</span> <span class="n" style="color: #333333;">adr</span><span class="o" style="font-weight: bold;">)</span> <span class="o" style="font-weight: bold;">{</span></span><br />
<span style="font-family: inherit; font-size: x-small;"><span class="n" style="color: #333333;"> log</span><span class="o" style="font-weight: bold;">.</span><span class="na" style="color: teal;">info</span> <span class="s2" style="color: #dd1144;">"Replacing address ${this.address} with ${adr} on ${this}"</span></span><br />
<span style="font-family: inherit; font-size: x-small;"><span class="k" style="font-weight: bold;"> this</span><span class="o" style="font-weight: bold;">.</span><span class="na" style="color: teal;">address</span> <span class="o" style="font-weight: bold;">=</span> <span class="n" style="color: #333333;">adr</span></span><br />
<span style="font-family: inherit; font-size: x-small;"><span class="n" style="color: #333333;"> log</span><span class="o" style="font-weight: bold;">.</span><span class="na" style="color: teal;">debug</span> <span class="s2" style="color: #dd1144;">"Updated{person} with new address"</span></span><br />
<span style="font-family: inherit; font-size: x-small;">
<span class="o" style="font-weight: bold;">}</span></span><br />
<span style="font-family: inherit; font-size: x-small;"><br /></span>
<blockquote class="tr_bq">
<span class="o" style="background-color: white; font-family: inherit; font-size: x-small; font-weight: bold; line-height: 16px;"></span></blockquote>
<blockquote class="tr_bq">
<span class="s2" style="color: #dd1144; font-family: inherit; font-size: x-small;"></span></blockquote>
<blockquote class="tr_bq">
<span class="n" style="color: #333333; font-family: inherit; font-size: x-small;"></span></blockquote>
<blockquote class="tr_bq">
<span class="s2" style="color: #dd1144; font-family: inherit; font-size: x-small;"></span></blockquote>
<br />
<br />
<pre class="line-pre" style="background-color: white; line-height: 16px; padding: 0px; width: 744px; word-wrap: break-word;"><span style="font-family: inherit; font-size: x-small;"><span class="nl"><span style="color: blue;"><b>setup:</b></span></span></span><br />
<span style="font-family: inherit; font-size: x-small;"> <span class="kt" style="color: #445588; font-weight: bold;">def</span> <span class="n" style="color: #333333;">log</span> <span class="o" style="font-weight: bold;">=</span> <span class="o" style="font-weight: bold;">[]</span></span><br />
<span style="font-family: inherit; font-size: x-small;"> <span class="kt" style="color: #445588; font-weight: bold;">def</span> <span class="n" style="color: #333333;">collectLog</span> <span class="o" style="font-weight: bold;">=</span> <span class="o" style="font-weight: bold;">{</span><span class="n" style="color: #333333;">String</span> <span class="n" style="color: #333333;">message</span> <span class="o" style="font-weight: bold;">-></span> <span class="n" style="color: #333333;">log</span> <span class="o" style="font-weight: bold;"><<</span> <span class="n" style="color: #333333;">message</span><span class="o" style="font-weight: bold;">}</span></span><br />
<span style="font-family: inherit; font-size: x-small;"> <span class="kt" style="color: #445588; font-weight: bold;">def</span> <span class="n" style="color: #333333;">finn</span> <span class="o" style="font-weight: bold;">=</span> <span class="k" style="font-weight: bold;">new</span> <span class="n" style="color: #333333;">Person</span><span class="o" style="font-weight: bold;">(</span><span class="nl">name:</span><span class="s1" style="color: #dd1144;">'finn'</span><span class="o" style="font-weight: bold;">,</span> <span class="k" style="font-weight: bold;">new</span> <span class="n" style="color: #333333;">Address</span><span class="o" style="font-weight: bold;">(</span><span class="nl">streetname:</span><span class="s1" style="color: #dd1144;">'homeless'</span><span class="o" style="font-weight: bold;">))</span></span><br />
<span style="font-family: inherit; font-size: x-small;"> <span class="n" style="color: #333333;">finn</span><span class="o" style="font-weight: bold;">.</span><span class="na" style="color: teal;">metaClass</span><span class="o" style="font-weight: bold;">.</span><span class="na" style="color: teal;">log</span> <span class="o" style="font-weight: bold;">=</span> <span class="o" style="font-weight: bold;">[</span><span class="nl">debug:</span><span class="n" style="color: #333333;">collectLog</span><span class="o" style="font-weight: bold;">,</span> <span class="nl">info:</span><span class="n" style="color: #333333;">collectLog</span><span class="o" style="font-weight: bold;">,</span> <span class="nl">error:</span> <span class="n" style="color: #333333;">collectLog</span><span class="o" style="font-weight: bold;">]</span></span><br />
<span style="font-family: inherit; font-size: x-small;"><span class="nl"><b><span style="color: blue;">when</span></b>:</span></span><br />
<span style="font-family: inherit; font-size: x-small;"> <span class="n" style="color: #333333;">finn</span><span class="o" style="font-weight: bold;">.</span><span class="na" style="color: teal;">address</span> <span class="o" style="font-weight: bold;">=</span> <span class="k" style="font-weight: bold;">new</span> <span class="n" style="color: #333333;">Address</span><span class="o" style="font-weight: bold;">(</span><span class="nl">streetname:</span><span class="s1" style="color: #dd1144;">'Slottsplassen 1'</span><span class="o" style="font-weight: bold;">)</span></span><br />
<span style="font-family: inherit; font-size: x-small;"><span class="nl"><b><span style="color: blue;">then</span></b>:</span></span><br />
<span style="font-family: inherit; font-size: x-small;"> <span class="k" style="font-weight: bold;">assert</span> <span class="n" style="color: #333333;">log</span><span class="o" style="font-weight: bold;">.</span><span class="na" style="color: teal;">find</span> <span class="o" style="font-weight: bold;">{</span><span class="n" style="color: #333333;">String</span> <span class="n" style="color: #333333;">msg</span> <span class="o" style="font-weight: bold;">-></span> <span class="n" style="color: #333333;">msg</span><span class="o" style="font-weight: bold;">.</span><span class="na" style="color: teal;">contains</span> <span class="s2" style="color: #dd1144;">"Replacing address homeless with Slottsplassen 1 on Finn"</span><span class="o" style="font-weight: bold;">}</span></span></pre>
<br />
<br />
The code turned out simpler than I feared when I initially decided I need to test my logging. Joy!Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-75730123952611963192013-02-25T14:57:00.002+01:002013-02-25T15:02:28.008+01:00When I say Jump, Jenkins asks how high<h2>
<span style="font-size: x-small;">... if you want even faster feedback than waiting for Jenkins to poll your stuff</span></h2>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">- In project config within Jenkins. Check: <b>"<span style="background-color: white;">Trigger builds remotely"</span></b><span style="background-color: white;">, add a token, like "<span style="color: red;">foobar</span>" into the textbox.</span></span><br />
<span style="font-family: inherit;"><span style="background-color: white;"><br /></span></span>
<span style="font-family: inherit;"><span style="background-color: white;">- SSH to your SVN-server and find the project home within svnroot.</span></span><br />
<span style="font-family: inherit;"><span style="background-color: white;"><br /></span></span>
<span style="background-color: white;"></span><br />
- Here is my post-commit hook:<br />
finn@subversionserver:/var/svnroot/myproject/hooks$ <b>cat post-commit</b><br />
<blockquote class="tr_bq">
#!/bin/sh<br />
/usr/bin/wget -O /dev/null --auth-no-challenge --http-user=finn --http-password=JENKINS_PASSWORD http://jenkinsserver:8080/view/Finn/job/myproject/build?token=<span style="color: red;">foobar</span></blockquote>
<br />
If you don't have authentication on Jenkins, remove <i>--http-user </i>and<i> --http-password</i>Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-71685770703435533482013-02-12T12:37:00.002+01:002013-02-12T12:38:59.738+01:00uhm, there is a ~/.ssh/config file?<h3>
How did I miss this for all these years I've used ssh?</h3>
<div>
<br /></div>
<div>
<i>~/.ssh/config</i><span style="font-family: inherit; font-size: xx-small; font-style: italic;"> </span><span style="font-family: inherit;">lets you type </span></div>
<b>#ssh home</b><br />
instead of<br />
<b>#finn@84.215.xxx.xxx -p 10001</b><br />
<br />
Here is the ~/.ssh/config<br />
<b><i>Host home</i></b><br />
<i><b>HostName 84.215.xxx.xxx<br />Port 10001<br />User finn</b></i><br />
<i><br /></i>Combine this passwordless ssh with<br />
<b>ssh-copy-id -i ~/.ssh/id_rsa.pub finn@84.215.xxx.xxx</b><br />
and phoning home is pretty effortless.<br />
<br />
... another one of those note-to-future-Finn (tm) posts which I'll copy and paste stuff from.<br />
<br />Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com2tag:blogger.com,1999:blog-8089567797675957527.post-491406021485732302013-01-29T14:43:00.001+01:002013-01-29T17:48:44.184+01:00HOWTO: Grails / GORM + Oracle Schema<div>
By simply adding schema to your domain classes, you won't be able to get it working in h2 afterwards. Here is how you fix that.</div>
<div>
<u><br /></u></div>
<h3>
1. Update all your domain classes</h3>
<div>
<u>grails-app/domain/Person.groovy</u></div>
<div>
class Person {</div>
<div>
String name</div>
<div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>static mapping = {</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>table name: 'PERSON', <b>schema:"MYSCHEMA"</b></div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>}</div>
</div>
<div>
}</div>
<div>
<br /></div>
<h3>
2. Update all your datasource</h3>
<div>
grails-app/conf/<b>DataSource.groovy</b>:</div>
<div>
environments {</div>
<div>
<div>
development {</div>
<div>
dataSource {</div>
<div>
dbCreate = "create-drop"</div>
<div>
url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000<b>;INIT=CREATE SCHEMA IF NOT EXISTS MYSCHEMA</b>"</div>
<div>
}</div>
</div>
<div>
<br />
<br />
repeat that for the <i>test</i> environment also.<br />
<br />
Putting this in writing because I wish I had this blog post a while ago.</div>
Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com1tag:blogger.com,1999:blog-8089567797675957527.post-82148395945814348772013-01-18T15:17:00.005+01:002013-01-18T16:00:28.507+01:00Cheat sheet: ssh + screen + irssi <h2>
Cheat Sheet: SSH + IRSSI + SCREEN </h2>
<div>
1. <b>ssh user@myserver</b></div>
<div>
2. <b>screen -r </b> resumes your screen. <b>screen </b>starts a new one, then type <b>irssi</b></div>
<div>
3. <b>/server irc.freenode.org</b> to connect to the server. <b>/join #channelName </b>to join a channel</div>
<div>
4.<b> /wc</b> leaves a channel.</div>
<div>
5.<b> <ctrl+a d></b> detaches screen, type <b>exit</b> to leave your ssh session</div>
<div>
<br /></div>
<h2>
<a name='more'></a>Other commands</h2>
<div>
<b>screen -rd</b> forcefully takes the screen session. In case it's attached elsewhere.</div>
<div>
<br /></div>
<div>
You may have started 2 screens by accident. You'll get an output like so.</div>
<div>
<div>
<i>finn@stubuntu:~$ screen -r</i></div>
<div>
<i>There are several suitable screens on:</i></div>
<div>
<i><span class="Apple-tab-span" style="white-space: pre;"> </span>8851.pts-0.stubuntu<span class="Apple-tab-span" style="white-space: pre;"> </span>(01/18/2013 03:14:32 PM)<span class="Apple-tab-span" style="white-space: pre;"> </span>(Detached)</i></div>
<div>
<i><span class="Apple-tab-span" style="white-space: pre;"> </span>2339.pts-2.stubuntu<span class="Apple-tab-span" style="white-space: pre;"> </span>(01/01/2013 05:00:24 PM)<span class="Apple-tab-span" style="white-space: pre;"> </span>(Detached)</i></div>
<div>
<i>Type "screen [-d] -r [pid.]tty.host" to resume one of them.</i></div>
</div>
<div>
<i><br /></i></div>
<div>
This is anoying, and you'll want to kill one. type <b>screen -r </b><b>2339 </b>to access that particular one and preferably kill it.</div>
<div>
<b><br /></b></div>
<b>irssi </b>channel switching<br />
<b><Alt + 1></b> The IRC console output.<br />
<b><Alt + 2> </b>The first channel<br />
<b><Alt + 3></b> The second channel<br />
etc.<br />
<br />
In irrsi, change nick by typing <b>/nick mynewnick</b><br />
<br />
Make an extra terminal session within screen, if you wanna do other stuff than irssi.<br />
<b><ctrl+a c></b><br />
<br />
Switch terminal session, in screen, if you have many<br />
<b><ctrl+a 0> </b>the first<br />
<b><ctrl+a 1></b> the second<br />
etc.<br />
<br />
You terminate an individual screen terminal session with <b>exit</b>. When all sessions are terminated, screen dies also.Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-44769726064173021772012-11-28T02:52:00.003+01:002012-12-05T16:27:17.700+01:00JavaScript Continous Testing SmackdownI'm pretty new to serious JavaScript coding. By <i>serious</i>, I mean writing lots of pure JavaScript, as a contrary to putting some JavaScript functions into your <script> block to fizz things up.<br />
<br />
I immediately sought out a way to get a smooth TDD development cycle running. I already had a theoretical idea on how to do this - from some of my colleagues who are JavaScript elitists in my book.<br />
<i><br /></i>
As far as I'm aware of, the technique described in this post is THE way to do test driven JavaScript development these days.<br />
<br />
<h3>
<b>So, what will I get from this stuff?</b></h3>
You'll get a terminal which <u>automatically</u> runs your JavaScript tests immediately as you change code. Like Spork in Ruby On Rails, or Infinitest in Eclipse.<br />
<br />
Consider the alternative. Having to refresh your browser on every change of JavaScript code. Sound familiar? It's no good; for your quality of life or your aging process (gray hair). Little less your productivity.<br />
<br />
Under the hood, these guys passes your JavaScript code to "browser slaves" and shoves the test-results back into your terminal window. I've tried both Buster.JS and JsTestDriver. So, which is the king of TDD JavaScript (in my opinion ofcourse)?<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-g2YRTMgYC2Y/ULVug8E6WRI/AAAAAAAAbWE/cotzsn7H_4Q/s1600/buster.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="332" src="http://1.bp.blogspot.com/-g2YRTMgYC2Y/ULVug8E6WRI/AAAAAAAAbWE/cotzsn7H_4Q/s640/buster.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Buster.JS</td></tr>
</tbody></table>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-aSNefIYXQY8/ULVuem9DyUI/AAAAAAAAbV8/QkE6uUcwWdU/s1600/jtds.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="334" src="http://2.bp.blogspot.com/-aSNefIYXQY8/ULVuem9DyUI/AAAAAAAAbV8/QkE6uUcwWdU/s640/jtds.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">jsTestDriver using watchr</td></tr>
</tbody></table>
<br />
<br />
<br />
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b><br />
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
<span style="font-size: small; font-weight: normal;"><br /></span></h3>
<h3>
<span style="font-size: small; font-weight: normal;"><br /></span></h3>
<h3>
<span style="font-size: small; font-weight: normal;"><br /></span></h3>
<h3>
<span style="font-size: small; font-weight: normal;"><br /></span></h3>
<h3>
<span style="font-size: small; font-weight: normal;"><br /></span></h3>
<h3>
<span style="font-size: small; font-weight: normal;"><br /></span></h3>
<h3>
<span style="font-size: small; font-weight: normal;"><br /></span></h3>
<h3>
<span style="font-size: small; font-weight: normal;"><br /></span></h3>
<h3>
<span style="font-size: small; font-weight: normal;"><br /></span></h3>
<h3>
<span style="font-size: small; font-weight: normal;">All the code from this blog entry can be found on github. Under a </span><b style="font-size: medium;">busterjs</b><span style="font-size: small; font-weight: normal;"> and </span><b style="font-size: medium;">jstd</b><span style="font-size: small; font-weight: normal;"> branch. </span><a href="https://github.com/finnjohnsen/jstesting" style="font-size: medium; font-weight: normal;">https://github.com/finnjohnsen/jstesting</a></h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
"But hey..? There are other ways to test JavaScript code"</h3>
<div>
I've noticed, and none I've found are attractive at all.</div>
<br />
<ul>
<li>You can refresh your browser and see if your stuff works. You'll have to do this anyway in addition to your unit testing. But you certainly don't want this to be the <u>only</u> way to test your code. It often involved clicking and typing to reach the code you know you want to test. Horrible and unfortunately probably the most common way to do JavaScript development in the world today (I made that up, it's just my guts talking).</li>
<li>I've seen set-ups which involves refreshing or triggering the tests from your browser. For example at the Jasmine -site, this is what they document. This is a lot better than the previous bullet point. But we can do better.</li>
<li>The Selenium approach: Automate and play back clicks and input-text into your browser. These kind of behavior tests are tightly coupled to html, slow and messy. But they have value as they ensure your site actually works! But it's not what I want for unit testing.</li>
<li>Pure Node.js testing. I've tossed this idea, admittedly without really digging into it. Because browsers are too important. Different browsers have different JavaScript implementations, so isolating my tests to the Node.js v8 runtime feels fundamentally wrong.</li>
</ul>
If you know of other ways, please comment.<br />
<b><br /></b>
<br />
<h3>
<b><br /></b></h3>
<h3>
<b>Buster.JS or JsTestDriver: My Conclusion</b></h3>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Both frameworks gives you a speedy feedback when working test driven development in JavaScript. However, either will help you all the way - as you may have wished.<br />
<br />
<ul>
<li><b>jsTestDriver requires more patching, hacking</b> <b>and scripting</b>, but works well once you've got it running. You'll probably polish and tune your scripts for quite some time after you've got it running, but you have something working pretty easily. JSTD has wide adaptation and you'll almost certainly find a solution to your problems just by searching around a little. You can have a look at <a href="http://cjohansen.no/en/javascript/jstdutil_a_ruby_wrapper_over_jstestdriver">this wrapper</a>, which is suppose to ease the scripting from JsTestDriver. Anyway, check out <a href="https://github.com/finnjohnsen/jstesting/tree/jstd">my sample set up</a>.</li>
</ul>
<ul>
<li><b>Buster.JS is a bigger creature</b>. It seems to aim to provide you with some of the pieces missing in JsTestDriver. It <b>provides contrinous/auto testing and an built-in assertion library</b>. These two critical components are what made the installation and set-up of jsTestDriver take a while longer than buster. So check out my <a href="https://github.com/finnjohnsen/jstesting/tree/busterjs">sample set up.</a></li>
</ul>
I spent about 45 minutes setting up this JSTD project, and 15 minutes on Buster.js. However I've done this before. I suspect I spent at least 2 or 3 times as much the first time.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-iAgOtcaTBRc/ULzVO8UzZNI/AAAAAAAAbWY/x7-BerV47h0/s1600/conclusion.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="http://4.bp.blogspot.com/-iAgOtcaTBRc/ULzVO8UzZNI/AAAAAAAAbWY/x7-BerV47h0/s320/conclusion.gif" width="320" /></a></div>
<br />
<br />
<span style="background-color: white;"><b>Buster.JS</b> states on it's website it is under <b>heavy development. </b>It even and uses the word 'unstable' to describe its current state. Leaving JSTD the choice if you can't live with that. Personally I like getting as much set up for me as possible, and I found nothing mentionable when setting up Buster.JS. So <b>I will use Buster.JS on my next green field</b>. I can however be considered <u>biased</u>, one of the authors of Buster.JS work in the same company as I.</span><br />
<br />
<br />
<br />
<a name='more'></a><br />
<br />
<br />
<h3>
<b>This is nice and all, but the real world is bigger than this</b></h3>
<div>
<i>... and nobody said it was going to be easy.</i></div>
<div>
<i><br /></i></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-TvM5IjwTXr4/ULzWvF_mquI/AAAAAAAAbWg/44V4uGGcQH8/s1600/challenge.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-TvM5IjwTXr4/ULzWvF_mquI/AAAAAAAAbWg/44V4uGGcQH8/s1600/challenge.jpg" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br />
I found nothing in these projects which mentions, or in any significant way help you on how you should incorporate these para dimes into your <b>real world web framework</b>. So if you're using Rails, .NET or Grails, you're on your own hacking and slashing this stuff into your source code. You'll have a system within your system.</div>
<br />
I also find it <b>immensely difficult</b> <b>to test UI code</b>. That is, code working with the DOM, utilizing templating like Handlebars.js or Mustache.js. And whenever I see jQuery I know I'm in trouble. It is unfair to blame these technologies for not helping you with this, so I won't. I'm just saying this is unsolved and up to you to mess about with on your own.<br />
<br />
Personaly, my pure GUI code is not covered by any tests in my projects. I'm still searching for a sensible way to organize so I can test as much as I should. I'm looking for good coding standards on how to organize my code and .js -files. At the moment, I'm inventing stuff as best I can as I go along. I've typically got *-view.js which are untested, and contains the messy CSS selectors and stuff. And I have typical *-model.js which are the ones I test.<br />
<br />
<b>Continous integration</b> is also something I've only tried for 15 minutes and given up. Maybe I'll blog about this when I solve it. You <b>won't get this for free</b> either.<br />
<br />
I plan making a follow up blog entry covering an example (how I do it) on how to get this into a Grails project.<br />
<br />
<h2>
<span style="font-size: x-large;">
Get your hands dirty already!</span></h2>
<div>
<div>
Head over to <a href="https://github.com/finnjohnsen/jstesting">https://github.com/finnjohnsen/jstesting</a> and look at the simple skeleton set-up I made for the sake of this post. The project has a <b>jstd</b> and <b>buster.js</b> branch for you to look at.</div>
<h3>
</h3>
<div>
<h2>
<span style="font-size: x-large;"><br /></span></h2>
<h2>
<span style="font-size: x-large;">Pros, Cons and anoyances</span></h2>
These are my raw notes when getting the simple skeleton set up.<br />
<div>
<div>
</div>
</div>
</div>
<h3>
JsTestDriver</h3>
</div>
<div>
Pros:</div>
<div>
<ul>
<li>Created by Google and seems widely adopted and easy to search for questions, answers and sample setups.</li>
<li>Has a nice set-up video on the official site. <a href="http://www.youtube.com/watch?v=V4wYrR6t5gE" rel="nofollow" style="background-color: white; color: #0000cc; font-family: arial, sans-serif; font-size: 13px; line-height: 16.399999618530273px;">http://www.youtube.com/watch?v=V4wYrR6t5gE</a></li>
<ul>
<li>This video is gets eclipse specific when it comes to the automated testing.</li>
</ul>
</ul>
Cons:<br />
<ul><ul>
</ul>
<li><a href="http://code.google.com/p/js-test-driver/">The web site</a> is ugly and messy. I don't find it intuitive where to find what I need. Also the wiki linking to source often don't work.</li>
<li>You'll spend an hour setting this up even though the video made it seem easy. You'll have to create scripts which you'll tweak quite a bit over time before you're happy.</li>
<li>The project provides no proper continuous testing. <a href="https://github.com/finnjohnsen/jstesting/blob/jstd/autotest.watchr">I created a watchr</a> script for this.</li>
<li>It was a little difficult finding the QUnit adapter or whatever assertion framework is supposed to be default. I blame the poor website for this.</li>
</ul>
</div>
<div>
</div>
<div>
<br /></div>
<div>
bumps in the road:</div>
<div>
<ul>
<li>new JavaScript files doesn't seem to be discovered. Maybe I'm doing it wrong? I always restart the server and watchr script. --reset flag?</li>
<li>Difficult to put the config file other places than in the root of the project. I gave up on this and ended up polluting my root with the config file.</li>
<li>The jsTestDriver.conf is case sensitive. Stole a few minutes to figure out I had incorrectly put it all in lower case.</li>
<li>Have to repeat the port number in the port file and the configuration file. I don't like having to remember stuff.</li>
<li>I had to create a dummy test.js to be able to start the server the first time.</li>
<li>The default assert library on the site directed me to a dead link, so I chose QUnit.</li>
<li>Can't figure out how to get colors in console. I miss the <span style="background-color: red;">Test(s) failed </span><span style="background-color: white;">or </span><span style="background-color: lime;">Test Successful</span><span style="background-color: white;"> which is convention everywhere you do TDD.</span></li>
<li><span style="background-color: white;">The projects provides an eclipse plugin. I couldn't get it working however. I gave up quickly though.</span></li>
</ul>
<div>
<br /></div>
</div>
<h3>
Buster.JS</h3>
<div>
Pros:</div>
<div>
<ul>
<li>I got automatic relaunch of tests when files were touched. <u>No need for watchr</u>.</li>
<li>Got coloring in the console. <span style="background-color: red;">Red</span> and <span style="background-color: lime;">Green</span> for failed and successful tests respectively.</li>
<li>The config file (buster.js) is easily put in test/ instead of root. Repeat after me: "I hate polluting root directory"</li>
<li>The web site is decent.</li>
</ul>
<div>
Cons:</div>
<div>
<ul>
<li>I don't like having to mess with Node.js in my OS. Wish it was stand alone or just in my home folder </li>
</ul>
</div>
</div>
<div>
Bumps in the road:</div>
<div>
<ul>
<li>I couldnt get the expression test/*Test.js working. I prefer calling tests e.x personTest.js, not person-test.js. No biggie.</li>
<li>I intially had test/*.js in buster.js, but buster.js was in test/ as well, and I was trying to run buster.js as a test, which it isn't. Got weird errors which wasn't pointing me in the right direction.</li>
<li>I don't like having to run run the npm command as sudo. Unknown stuff leaking into my OS.</li>
</ul>
<div>
<br />
<h3>
aaaaalright</h3>
This is a tight race, and there is no clear winner in my opinion. None will rescue you from the horrors of JavaScript web development, and none of them suck. I will prefer Buster.JS, strictly because I'm lazy and want everything out of the box. JsTestDriver has "Google" anchored into it's brand, making it a pretty safe bet also.<br />
<br />
Thanks, feel free to comment :)</div>
</div>
<div>
.finn<br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com3tag:blogger.com,1999:blog-8089567797675957527.post-41378334386819972182011-04-16T02:13:00.014+02:002014-01-04T05:15:39.752+01:00Android Sources in Eclipse<span class="Apple-style-span" style="font-family: inherit;">I've blogged about getting Eclipse to show Android sources before, but these techniques no longer work. So I'll toss a working how-to out there again.</span><br />
<span class="Apple-style-span" style="font-family: inherit;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: inherit;">I'm still </span>baffled<span class="Apple-style-span" style="font-family: inherit;"> that Google hasn't ensured this working from day #1 with this eclipse plugin. But enough crying :)</span><br />
<span class="Apple-style-span" style="font-family: inherit;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: inherit;">I should also mention there is an <a href="http://code.google.com/p/adt-addons/">eclipse plugin</a> made for this. I've never tried it. I don't like bloating eclipse with tons of plugins, unless I really have to. And this boils down to 8 pretty easy steps, so an eclipse plugin isn't something Id'e consider. (But I may change my mind later)</span><br />
<br />
Download the sources from github, and attach them:<br />
<ul>
<li>Head over to <strike><a href="http://android.git.kernel.org/?p=platform/frameworks/base.git;a=tags">the android source at github</a>.</strike> EDIT: <a href="https://github.com/android/platform_frameworks_base">new location</a></li>
<li><a href="http://android.git.kernel.org/?p=platform/frameworks/base.git;a=tags"></a>Click the android SDK you're working on. (*1) I'll choose <i><a class="list subject" href="http://android.git.kernel.org/?p=platform/frameworks/base.git;a=tag;h=4b37fbc6d31a7ccc53a71d34b8c411a6b1a10285" style="color: black; font-weight: normal;">Android 2.2 SDK release </a><u>2</u></i> </li>
<li>Click the tiny link which says <u><i>Tree</i></u></li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-pfylKiyF1jA/TajfkqhZVfI/AAAAAAAAOjQ/6jQvtt3kMGM/s1600/treeLink.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="232" src="http://4.bp.blogspot.com/-pfylKiyF1jA/TajfkqhZVfI/AAAAAAAAOjQ/6jQvtt3kMGM/s320/treeLink.png" width="320" /></a></div>
<ul>
<li><b>Click</b> the <b>Snapshot</b> link which just appeared by the Tree -link</li>
</ul>
<br />
You'll start downloading a file which is about 130mb. This is the android source file. It's filename starts with <i>base</i>, for me it's called <i><b>base-08d9d9a.tar.gz</b></i><br />
<ul>
<li><b>move</b> the base -file to the <b>SDK platform directory</b>, for me that's <b>/opt/android-sdk-linux_x86/platforms/android-8</b></li>
<li><b></b><b>unpack</b> it (<i>tar xvfz </i><i><u>base-08d9d9a.tar.gz).</u></i></li>
<li><i><u></u></i>head into <b>eclipse</b>, and press F3 over some android source you're missing, like Activity. And get this pesky window, which we all hate:</li>
</ul>
<a href="http://1.bp.blogspot.com/-EOLiLbgezpM/TajcmKaBt3I/AAAAAAAAOjM/KoMgkn8OQRE/s1600/NotWorking.png" imageanchor="1" style="clear: left; display: inline !important; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="190" src="http://1.bp.blogspot.com/-EOLiLbgezpM/TajcmKaBt3I/AAAAAAAAOjM/KoMgkn8OQRE/s320/NotWorking.png" width="320" /></a><br />
<ul>
<li>Click <b>Attach Source</b>, choose <i>External Folder</i>, and choose the <b>core/java</b> in the base folder. For me that's <b>/opt/android-sdk-linux_x86/platforms/android-8/base-08d9d9a/core/java</b></li>
</ul>
There you go. Please post a comment and tell me how this turns out for you :)<br />
<span class="Apple-style-span" style="font-family: inherit;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: inherit;">.finn</span><br />
<span class="Apple-style-span" style="font-family: inherit;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: inherit;">(*1) There are loads of versions there, and it's a bit confusing. I've concluded the stuff we're looking for should end with <i>SDK.</i> However I'm not 100% certain about what version to download to match the Android version we see in the Android SDK download tool - this is just me guessing.</span>Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com6tag:blogger.com,1999:blog-8089567797675957527.post-6311242561901416772011-04-14T12:29:00.004+02:002011-04-16T02:49:58.990+02:00Getting that Skeleton test upWhen creating a new unit test file, getting the import statics right with Hamcrest is 30 seconds of hassle, every time.<br />
<br />
Here is the typical unit test start-up I prefer:<br />
<blockquote><blockquote><blockquote><span class="Apple-tab-span" style="font-weight: bold; white-space: pre;"> </span>@Test<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void skeletonTest() {<br />
<span class="Apple-tab-span" style="white-space: pre;"> <b> </b></span><b>assertThat(true, is(equalTo(true)));</b><br />
}</blockquote></blockquote></blockquote>Here is a eclipse <b>template</b>, which may solve this. But may also not, as I tend to forget little tricks like these. Time will tell if I've been able to incorporate this my reflexes.<br />
<br />
So, get the template in, make the new junit test file, type <b><i>skeltest</i></b> and press ctrl+space.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-Cu1dlacRBJ0/TabKi4FaXeI/AAAAAAAAOi4/beZeR0wrJ8M/s1600/eclipse-skeleton-test.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="400" src="http://1.bp.blogspot.com/-Cu1dlacRBJ0/TabKi4FaXeI/AAAAAAAAOi4/beZeR0wrJ8M/s400/eclipse-skeleton-test.png" width="355" /></a></div><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
The template:<br />
<blockquote><b>${imp:import(org.junit.Test)}<br />
${imps:importStatic(<br />
org.hamcrest.Matchers.equalTo,<br />
org.hamcrest.Matchers.is,<br />
org.junit.Assert.assertThat)}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>@Test<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void skeletonTest() {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>assertThat(true, is(equalTo(true)));<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}</b></blockquote>Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-82227731785347971032010-07-19T23:44:00.006+02:002011-04-16T02:50:18.889+02:00Tired of killing browsers?Launching the browser a lot from your IDE while working on / developing <some> web app?<br />
<br />
Getting zillions of tabs or new browser instances?<br />
<br />
Killing them all by hand every now and then?<br />
<br />
Small trick which <b>tells Firefox to put all URL requests in the same tab, reusing one tab.</b><br />
<br />
<blockquote>in the URL type: <b>about:config</b></blockquote><blockquote>find the property <b>browser.link.open_newwindow</b></blockquote><blockquote>change the value to <b>1</b></blockquote><b><br />
</b><br />
Follow up tip: Keep some <b>Firefox fork</b>/clone (or whatever) installation which you use just for development, and apply this setting to it. This way you don't mess up your Firefox for normal surfing. I keep swiftweasel in /opt/swiftweaselAnonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com1tag:blogger.com,1999:blog-8089567797675957527.post-18594462165702163352010-06-02T23:21:00.019+02:002010-07-20T00:10:57.518+02:00watch your code do actual work - in runtimeShort version: <i>Use AOP to log your method invocations. Store method input parameters and result object, serialized to XML. Put it all into context with a Graphviz file generated as a side-effect.</i><br />
<br />
Visual beats plain old text for a lot of purposes. So why not generate something visual from your running code, showing you what's happening using <b>boxes and arrows</b>. I've had tons of fun (and not too much sleep) lately digging into this using <a href="http://www.graphviz.org/">Graphviz</a>.<br />
<br />
The value of this is to track that the flow is as expected, and if you need to you can investigate the input and output data going into your ex. repositories or "logical services". The limitation of this is that all needs to run within the same VM and thread.<br />
<br />
Here is what the <a href="http://github.com/finnjohnsen/vizpoc">proof of concept</a> app produced from a <a href="http://github.com/finnjohnsen/vizpoc/blob/master/src/test/java/com/finnjohnsen/vizpoc/sample/ActionIntegrationTest.java">dummy java stack in a unit test</a>.<br />
<br />
<a href="http://4.bp.blogspot.com/_NOtfuEjKBzI/TAbDvUbydMI/AAAAAAAAL28/0uKzdfxCT2I/s1600/graphviz.dot.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="316" src="http://4.bp.blogspot.com/_NOtfuEjKBzI/TAbDvUbydMI/AAAAAAAAL28/0uKzdfxCT2I/s640/graphviz.dot.png" width="640" /></a><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
The text on the arrows are <b>clickable links</b> and gives the user this if clicking the "0.Arguments":<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_NOtfuEjKBzI/TAbEk8hI8hI/AAAAAAAAL3E/V99sSL_dO0Q/s1600/xml.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/_NOtfuEjKBzI/TAbEk8hI8hI/AAAAAAAAL3E/V99sSL_dO0Q/s320/xml.png" /></a></div>Okok, the arguments and results are just boring serialized XML data. They could probably be graphs too, but I haven't come around to that and that isn't really what I'm after.<br />
<br />
I also made <a href="http://github.com/finnjohnsen/vizpoc/blob/master/src/main/java/com/finnjohnsen/vizpoc/servlet/VizServlet.java">a simple Servlet</a>, which lists all generated graphs and makes you able to click and view any of these.<br />
<br />
<span class="Apple-style-span" style="font-size: x-large;">the code</span><br />
The rest of this blog will be slightly in-depth and describing the knots and bolts of this.<br />
<br />
The main idea is to accumulate a <a href="http://www.graphviz.org/doc/info/shapes.html#record">graphviz dot -file</a> a cross a call-stack. At the points you want as opposed to everything (using reflection and looking at your entire call stack).<br />
<br />
Aspect point cuts (<a href="http://static.springsource.org/spring/docs/2.5.x/reference/aop.html">Spring and AspectJ</a>) is perfect for the job. I use <a href="http://java.sun.com/javase/6/docs/api/java/lang/ThreadLocal.html">ThreadLocal</a> to keep a <a href="http://github.com/finnjohnsen/vizpoc/blob/master/src/main/java/com/finnjohnsen/vizpoc/aop/GraphvizContext.java">graph contex</a>t/handler and simply append to it every time the aspect is invoked. The context saves a file and is released when the call-stack is done.<br />
<br />
<a href="http://github.com/finnjohnsen/vizpoc/blob/master/src/main/java/com/finnjohnsen/vizpoc/servlet/VizServlet.java">The Servlet</a> in the proof of concept code is just a nice-to-have and requires graphviz to be installed on the "server". It invokes the 'dot' executable and pushes the output <a href="http://en.wikipedia.org/wiki/Scalable_Vector_Graphics">svg</a> (or pdf / png / <a href="http://www.graphviz.org/doc/info/output.html">whatever you want</a>) to the user.<br />
<br />
You probably don't want this logging done all the time, due to performance and extensive logging to your temp. So I've stuck a check for an environment variable in the aspect - so you can enable and disable when you need this.<br />
<br />
That's it really. You can check out the <a href="http://github.com/finnjohnsen/vizpoc">proof of concept from github</a> and run the tests to see the graph-files get generated. Use the code as you please. Check out the README and please comment if you see any weaknesses or have any opinions.<br />
<br />
/FinnAnonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com1tag:blogger.com,1999:blog-8089567797675957527.post-3939476606465337002010-05-12T22:26:00.006+02:002011-04-15T23:56:10.621+02:00+rw clipboard<span class="Apple-style-span" style="font-family: inherit;">I saw some guy do a </span><i><span class="Apple-style-span" style="font-family: inherit;">cat</span></i><span class="Apple-style-span" style="font-family: inherit;"> on some file (directly into his clipboard) and then paste/ctrl-v the text into his editor. My brain immediataly went "gimme! gimme! gimme!"</span><br />
<span class="Apple-style-span" style="font-family: inherit;"><br />
</span><br />
<div><s><span class="Apple-style-span" style="font-family: inherit;"><br />
</span> </s></div><div><span class="Apple-style-span" style="font-family: inherit;">After a little googling around I found that his tools, </span><b><span class="Apple-style-span" style="font-family: inherit;">pbcopy</span></b><span class="Apple-style-span" style="font-family: inherit;">/</span><b><span class="Apple-style-span" style="font-family: inherit;">pbpaste,</span></b><span class="Apple-style-span" style="font-family: inherit;"> was exclusively </span><b><span class="Apple-style-span" style="font-family: inherit;">for OS X</span></b><span class="Apple-style-span" style="font-family: inherit;">. A few minutes more with google showed me that the tool for the job in Ubuntu was </span><b><span class="Apple-style-span" style="font-family: inherit;">xsel</span></b><span class="Apple-style-span" style="font-family: inherit;">. </span><br />
<span class="Apple-style-span" style="font-family: inherit;"><br />
</span> <br />
<i><span class="Apple-style-span" style="font-family: inherit;">#apt-cache search xsel</span></i><br />
<i><span class="Apple-style-span" style="font-family: inherit;">xsel - command-line tool to access X clipboard and selection buffers</span></i><br />
<span class="Apple-style-span" style="font-family: inherit;"><br />
</span> <br />
<span class="Apple-style-span" style="font-family: inherit;">However xsel covers both read and write and uses parameter to distinct them. My brain isn't up for the job remembering parameters so I decided Steve Jobs'es command was my way. Alias will fix this right up and I have </span><i><span class="Apple-style-span" style="font-family: inherit;">pbcopy</span></i><span class="Apple-style-span" style="font-family: inherit;"> and </span><i><span class="Apple-style-span" style="font-family: inherit;">pbpaste</span></i><span class="Apple-style-span" style="font-family: inherit;"> and feel happy and warm inside.</span><br />
<div><span class="Apple-style-span" style="font-family: inherit;"><br />
</span> <br />
<span class="Apple-style-span" style="font-family: inherit;">get xsel</span></div><div><b><span class="Apple-style-span" style="font-family: inherit;">#sudo apt-get install xsel</span></b></div><div><s><span class="Apple-style-span" style="font-family: inherit;"><br />
</span> </s></div><div><span class="Apple-style-span" style="font-family: inherit;">Here are the commands:</span></div><div><b><span class="Apple-style-span" style="font-family: inherit;">#cat myfile.txt | xsel -ib</span></b></div><div><b><span class="Apple-style-span" style="font-family: inherit;">#xsel -o > mycopy.txt</span></b><br />
<b><span class="Apple-style-span" style="font-family: inherit;"><br />
</span> </b><br />
<span class="Apple-style-span" style="font-family: inherit;">put these two lines into ~/.bashrc if you want this the OS X -way.</span><br />
<span class="Apple-style-span" style="font-family: inherit;"><b></b></span><br />
<b><i><span class="Apple-style-span" style="font-family: inherit;">alias pbcopy='xsel -ib'</span></i><span class="Apple-style-span" style="font-family: inherit;"><br />
</span> <i><span class="Apple-style-span" style="font-family: inherit;">alias pbpaste='xsel -ob'</span></i><span class="Apple-style-span" style="font-family: inherit;"><br />
<br />
</span> <span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-family: inherit;">Do it like apple does:</span></span><span class="Apple-style-span" style="font-family: inherit;"><br />
#cat myfiles.txt | pbcopy<br />
#pbpaste > mycopy.txt</span> <span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span> </span></b><br />
<b><span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-family: inherit;">/Finn</span></span></b><br />
<b><span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></span></b><br />
<b><span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-family: inherit;"><span class="Apple-style-span" style="color: #333333; font-family: Georgia, serif; font-size: 13px; line-height: 20px;">edit.(15.04.2011)</span> </span></span></b><span class="Apple-style-span" style="color: #333333; font-family: Georgia, serif; font-size: 13px; line-height: 20px;">For some reason the xsel with Ubuntu 10.10. needs xsel -ib (not just xsel -i). No idea why, but blog post is updated accordingly.</span><br />
</div></div>Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-79809212780046230612010-04-24T20:14:00.015+02:002011-04-16T02:51:36.113+02:00Spotify links in Ubuntu & Chrome<a href="http://3.bp.blogspot.com/_NOtfuEjKBzI/S9M9i1xajyI/AAAAAAAALus/TgZivZG7on0/s1600/ubuntu_wine_spotify.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5463778441689730850" src="http://3.bp.blogspot.com/_NOtfuEjKBzI/S9M9i1xajyI/AAAAAAAALus/TgZivZG7on0/s200/ubuntu_wine_spotify.png" style="cursor: hand; cursor: pointer; float: left; height: 35px; margin: 0 0 10px 10px; width: 200px;" /></a><span class="Apple-style-span" style="font-size: medium;"></span><br />
<div><span class="Apple-style-span" style="font-size: medium;">Spotify doesn't work in Linux, natively. (<span class="Apple-style-span" style="color: red;">edit: it does now</span>) So it's done using wine following this excellent <a href="http://www.spotify.com/no/help/faq/wine/">howto</a>.</span></div><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-size: medium;"><br />
</span></span></div><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-size: medium;">This means however, that Chrome (and your Ubuntu) is unaware of spotify running "under the radar" as a wine/spotify.exe process. So when clicking a link, like this one: <a href="http://open.spotify.com/track/61K2lUXbNSvhEIOkhcozK4">http://open.spotify.com/track/61K2lUXbNSvhEIOkhcozK4</a> spotify doesn't react.</span></span></div><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-size: medium;"><br />
</span></span></div><div><span class="Apple-style-span" style="font-size: medium;">I've Copy&Paste this dead-on recipe from <a href="http://neo22s.com/spotify-links/">another blog</a> I found, just so I don't loose it in the future. I can confirm it's working on my Ubuntu 10.04 x64 desktop machine.</span></div><br />
<div><span class="Apple-style-span" style="font-size: medium;"><br />
</span></div><div><span class="Apple-style-span" style="font-size: medium;"></span><br />
<div><span class="Apple-style-span" style="font-size: medium;"><b><span class="Apple-style-span" style="font-size: small;"><span class="Apple-style-span" style="font-family: arial;">echo '#!/bin/sh' > ~/.browser2spotify</span></span></b></span></div><div><span class="Apple-style-span" style="font-size: medium;"><b><span class="Apple-style-span" style="font-size: small;"><span class="Apple-style-span" style="font-family: arial;">echo 'wine "$HOME/.wine/drive_c/Program Files/Spotify/spotify.exe" /uri "$@"' >> ~/.browser2spotify</span></span></b></span></div><div><span class="Apple-style-span" style="font-size: medium;"><b><span class="Apple-style-span" style="font-size: small;"><span class="Apple-style-span" style="font-family: arial;">chmod 755 ~/.browser2spotify</span></span></b></span></div><div><span class="Apple-style-span" style="font-size: medium;"><b><span class="Apple-style-span" style="font-size: small;"><span class="Apple-style-span" style="font-family: arial;">gconftool-2 -t string -s /desktop/gnome/url-handlers/spotify/command "/home/${USER}/.browser2spotify %s"</span></span></b></span></div><div><span class="Apple-style-span" style="font-size: medium;"><b><span class="Apple-style-span" style="font-size: small;"><span class="Apple-style-span" style="font-family: arial;">gconftool-2 -s /desktop/gnome/url-handlers/spotify/needs_terminal false -t bool</span></span></b></span></div><div><span class="Apple-style-span" style="font-size: medium;"><b><span class="Apple-style-span" style="font-size: small;"><span class="Apple-style-span" style="font-family: arial;">gconftool-2 -s /desktop/gnome/url-handlers/spotify/enabled true -t bool</span></span></b></span></div><div><span class="Apple-style-span" style="font-size: medium;"><b><span class="Apple-style-span" style="font-size: small;"><span class="Apple-style-span" style="font-family: arial;"><br />
</span></span></b></span></div><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family: arial;">The clue with this is to make gnome pass URLs starting with <i>spotify: </i>to the script which passes the URL to spotify.exe</span></span></div><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family: arial;"><br />
</span></span></div><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family: arial;">This will do the job until Spotify makes a proper native linux client. Id'e think that wouldn't be too hard as it's an Adobe Air application, which is flash, which is pretty platform independent and very capable of running properly on Linux.</span></span></div><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family: arial;"><br />
</span></span></div><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family: arial;">/Finn</span></span></div></div>Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com1tag:blogger.com,1999:blog-8089567797675957527.post-34174511197185093552010-04-13T23:50:00.022+02:002010-04-27T21:59:21.984+02:00sshfs - brilliantly simple<div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">Got another linux/unix -box sitting somewhere in your home? I do, and I want _everything_ available to me from where I sit at my desktop.</span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">I've used nfs quite a bit in the past, while quite easy to set-up it's a hassle compared to the simpleness of sshfs. And setting up samba is like getting skinned alive on this scale. </span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">(ubuntu)</span></span></div><div><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">#apt-get install sshfs</span></span></b></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">(ubuntu, the other machine / slave)</span></span></div><div><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">#apt-get install openssh-server</span></span></b></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">put this in /etc/fstab, and you can on-demand mount/unmount the other computer when you see fit:</span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></div><div><i><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">sshfs#finn@10.0.0.53:/ /home/finn/theslavecomputer fuse noauto,defaults,users,idmap=user 0 0</span></span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></i></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">Now you have the </span></span><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">root of the filesystem</span></span></b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"> of the other machine sitting in your home directory. Sweet?</span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></div><div><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">#mount </span></span></b><i><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">theslavecomputer</span></span></b></i></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">... any time you need it. I prefer not using auto mount as I only need access to the other machine like 1 in 20 times I boot. A good rule on fstab in my experience is to not put a lot of stuff on auto-mount. It will get you in trouble when booting eventually which makes you so miserable you'll not click 'like' on any comments you'll read Facebook that day.</span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">Tip: make this password less by uploading the public certificate. Google it and you'll get a step-by-step in a sec.</span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">/Finn</span></span></div>Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-84813379772283680982010-04-07T23:39:00.023+02:002010-04-27T22:00:02.290+02:00Synergy between Ubuntu and OS X<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_NOtfuEjKBzI/S8TIqVQWo3I/AAAAAAAABoE/CrSpdrQagYA/s1600/2010-04-08+22.07.34.jpg"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 150px;" src="http://2.bp.blogspot.com/_NOtfuEjKBzI/S8TIqVQWo3I/AAAAAAAABoE/CrSpdrQagYA/s200/2010-04-08+22.07.34.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5459709277865681778" /></a><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_NOtfuEjKBzI/S8THprd05kI/AAAAAAAABfU/YBMgJVnSE0Y/s1600/2010-04-08+22.07.34.jpg"></a></span></span><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">I use </span></span><a href="http://synergy2.sourceforge.net/"><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">Synergy</span></span></a><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"> to share one set of mouse and keyboard between my workstation PC, running Ubuntu 10.04 and my laptop sitting on my desk next to my workstation screen. The laptop is running OS X.</span></span><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">How about not raising your hands off your keyboard and mouse when you have to do stuff on that laptop? Greetings </span></span><a href="http://synergy2.sourceforge.net/"><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">Synergy</span></span></a></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">Here is how I configured it.</span></span></div><div><div><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></b></div><div><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">On OS X, the keboard+mouse -client</span></span></b></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">... I followed </span></span><a href="http://synergy2.sourceforge.net/autostart.html"><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">one of the suggested steps</span></span></a><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"> on synergys website. Copy&Paste:</span></span></div></div><div><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></div><div><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"># sudo su -</span></span></b></div><div><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"># </span></span></b><span class="Apple-style-span" style="white-space: pre; "><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">defaults read com.apple.loginwindow LoginHook</span></span></b></span></div><div><span class="Apple-style-span" style="white-space: pre; "><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"># sudo mkdir -p /Library/LoginWindow</span></span></b></span></div><div><span class="Apple-style-span" style="white-space: pre; "><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"># sudo vi </span></span></b><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">LoginHook.sh</span></span></b></span></div><div><span class="Apple-style-span" style="white-space: pre; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal; "><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></span></span></span></div><div><span class="Apple-style-span" style="white-space: pre; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal; "><i><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">#!/bin/sh </span></span></i></span></span></span></div><div><span class="Apple-style-span" style="white-space: pre; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal; "><i><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">prog=(/opt/synergy-1.3.1/synergyc </span></span></i><i><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">192.168.3.47</span></span></i><i><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">) </span></span></i></span></span></span></div><div><span class="Apple-style-span" style="white-space: pre; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal; "><i><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">killall ${prog[0]##*/} </span></span></i></span></span></span></div><div><span class="Apple-style-span" style="white-space: pre; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal; "><i><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">exec "${prog[@]}"</span></span></i></span></span></span></div><div><span class="Apple-style-span" style="white-space: pre; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal; "><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></span></span></span></div><div><span class="Apple-style-span" style="white-space: pre; "><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"># sudo chmod 755 /Library/LoginWindow/LoginHook.sh</span></span></b></span></div><div><span class="Apple-style-span" style="white-space: pre; "><b><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"># defaults write com.apple.loginwindow LoginHook /Library/LoginWindow/LoginHook.sh</span></span></b></span></div><div><span class="Apple-style-span" style="white-space: pre; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></span></span></span></span></div><div><span class="Apple-style-span" style="white-space: pre; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">On Ubuntu, the server with mouse+keyboard attached</span></span></span></span></span></span></div><div><span class="Apple-style-span" style="white-space: pre; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">... </span></span><span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;">the guide wasn't that much help as it wasn't specific for any distribution, so I decided to just put the startup after gdm is fired up.</span></span></span></span></span></span></span></div><div><span class="Apple-style-span" style="white-space: pre; font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"># sudo vi /etc/gdm/PostLogin/Default</span></span></span></span></span></span></div><div><span class="Apple-style-span" style="white-space: pre; font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal; "><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-size:medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></span></span></span></span></div><div><span class="Apple-style-span" style="font-family:arial;"><span class="Apple-style-span" style="white-space: pre; font-size:medium;"><div><i><span class="Apple-style-span" style="font-size:medium;">killall synergys</span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;">sleep 1</span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;">/usr/bin/synergys -c /etc/synergy.conf &</span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;"><br /></span></i></div><div><span class="Apple-style-span" style="font-size:medium;">My /etc/synergy.conf looks like this:</span></div><div><span class="Apple-style-span" style="font-size:medium;"><br /></span></div><div><i><span class="Apple-style-span" style="font-size:medium;">section: screens </span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;"> finnbuntu: </span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;"> finnmac.local: </span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;">end </span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;"><br /></span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;">section: links </span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;"></span><span class="Apple-style-span" style="font-style: normal; "><i><span class="Apple-style-span" style="font-size:medium;"> finnbuntu</span></i></span><span class="Apple-style-span" style="font-size:medium;">: </span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;"> right = finnmac.local </span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;"> finnmac.local: </span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;"> left = </span><span class="Apple-style-span" style="font-style: normal; "><i><span class="Apple-style-span" style="font-size:medium;">finnbuntu</span></i></span><span class="Apple-style-span" style="font-size:medium;"> </span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;">end</span></i></div><div><i><span class="Apple-style-span" style="font-size:medium;"><br /></span></i></div><div><span class="Apple-style-span" style="font-size:medium;">/Finn</span></div></span></span></div>Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0tag:blogger.com,1999:blog-8089567797675957527.post-54514252708774328622010-04-07T00:08:00.003+02:002010-04-07T00:21:35.238+02:00Rescue Ubuntu 10.04 graphics crash after grubThis is a note to self, in case I run into this problem again. Obviously a (beta) problem with the nvidia -driver.<div><br /></div><div>The symptoms is that you get the grub chooser showing just fine, but get a distorted strange looking graphics crash screen directly after - when it's supposed to show the boot splash. Turned out I had to disable nvidia to find my underlying problem which prevented me booting. This was a error in /etc/fstab, my own fault entirely.<br /><div><br /></div><div>This is a very generic and nice way to mount up and rescue your system, and using chroot you've almost got your system running as if you've booted it off your hard drive. (well, not entirely true)</div><div><br /></div><div> Boot off the Ubuntu the 10.04 CD and open a terminal</div><div><br /></div><div>#mount /dev/sda1 /mnt</div><div>#mount -o bind /proc /mnt/proc</div><div>#mount -o bind /dev /mnt/dev</div><div>#sudo chroot /mnt</div><div>#apt-get remove nvidia-96 --purge</div><div>#apt-get remove nvidia-173 --purge</div><div>#reboot</div></div>Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com2tag:blogger.com,1999:blog-8089567797675957527.post-56292199235327923572010-03-11T01:39:00.004+01:002010-03-22T21:26:53.914+01:00Android Market - The power of the latest comment<div>I've watched my download statistics closely about a month for Workout Rotation Diary on Android Market.</div><div><br /></div><div>I've seen a clear pattern telling me that the latest comment has <b>a huge</b> of impact on daily downloads. When the latest comment and rating is positive, the app can do 100-200 downloads a day. With a loud negative comment being the newest (like at the time of writing I have 2 really negative, the latest being: "USELESS!") it's down to 10-50 a day.</div><div><br /></div><div>My comfort is that it has 2k active installations and 5k downloads, so maybe there are some individuals who find it useful.</div><div><br /></div><div>... so not going to kill myself quite yet.</div>Anonymoushttp://www.blogger.com/profile/16113049669710039361noreply@blogger.com0