Friday, June 28, 2013

Python assertRaises exception inside generator

So I have a generator and I want to make sure it throws an exception after a certain number of calls. So expected behaviour is this:
def generate():
    yield 1
    yield 2
    raise Exception()
How do you check that in a test? You can't do this:
class testExample(unittest.TestCase):
    def test_generatorExample(self):
        self.assertRaises(Exception, a)
since a generator isn't callable. Turns out that assertRaises is a context manager as of python 2.7, which is very cool:
class testExample(unittest.TestCase):
    def test_generatorExample(self):
        with self.assertRaises(Exception):
            list(a)
Or for earlier versions of python you could use a lambda:
self.assertRaises(Exception, lambda: list(a))

Thursday, June 27, 2013

Continuously loop (cycle) through a list in python

Thank you itertools:
In [7]: a=[1,2,3]

In [8]: licycle = itertools.cycle(a)

In [9]: licycle.next()
Out[9]: 1

In [10]: licycle.next()
Out[10]: 2

In [11]: licycle.next()
Out[11]: 3

In [12]: licycle.next()
Out[12]: 1

In [13]: licycle.next()
Out[13]: 2

In [14]: licycle.next()
Out[14]: 3

In [15]: licycle.next()
Out[15]: 1

In [16]: licycle.next()
Out[16]: 2

In [17]: licycle.next()
Out[17]: 3

Wednesday, June 12, 2013

Disable Java web applet in Internet Explorer

Microsoft has joined the good fight to make disabling the vulnerability-ridden Java web plugin easier. They have released a fixit that blocks the Java ActiveX DLLs from loading and disables the JNLP handler, which effectively disables Java in IE.

Sunday, June 2, 2013

SQL join syntax

Jeff Atwood posted a useful memory aid for SQL join syntax, although as many commenters point out there are a number of caveats to using set theory for this task.

Wednesday, May 29, 2013

Puppet: service checking on OS X without using the inbuilt service stanza

Normal service enforcement is easy with puppet, it looks like this for an OS X launchdaemon:
class something::myservice {

  File { owner => 'root', group => 'wheel', mode => '0644' }
  
  file { 'myservice_launchd_plist':
    ensure => file,
    path   => '/Library/LaunchDaemons/com.blah.myservice.plist',
    source => 'puppet:///modules/something/myservice/myservice_launchd.plist',
  }
   
  service { 'com.blah.myservice':
    ensure  => 'running',
    enable  => true,
    require => File['myservice_launchd_plist'],
  }
   
}
Which is great, until you don't want to manage that plist inside of puppet. In my case it was getting installed separately. If all the clients don't get upgraded properly then laying down the new plist with puppet (which points to different paths per version) will break old versions. It also means the plist needs to be updated in two places: inside puppet and inside the package for each release. So it's a hassle. I just want a simple check to restart it if it isn't running.

First attempt:
class something::myservice {

  File { owner => 'root', group => 'wheel', mode => '0644' }
  
  file { 'myservice_launchd_plist':
    path   => '/Library/LaunchDaemons/com.blah.myservice.plist',
  }
   
  service { 'com.blah.myservice':
    ensure  => 'running',
    enable  => true,
    require => File['myservice_launchd_plist'],
  }
   
}
This works fine, until the plist isn't there: i.e. the install failed for some reason, or this machine didn't get myservice installed. In that situation puppet will exit with an error code, so puppet management is effectively broken. No good. So, can we replicate what the service stanza is doing with a couple of simple exec statements? Seems easy...
class something::myservice {

  File { owner => 'root', group => 'wheel', mode => '0644' }

  exec { 'myservice':
    onlyif  => ['! /bin/launchctl list com.blah.myservice &> /dev/null',
                '/bin/test -f /Library/LaunchDaemons/com.blah.myservice.plist'],
    command => '/bin/launchctl load /Library/LaunchDaemons/com.blah.myservice.plist',
  }

}
This will run launchctl load if the service isn't running and the plist is actually there. The problem is puppet is overzealous in its command checking and will fail with this error:
Could not evaluate: Could not find command '!'
OK, what if we do onlyif and unless. Documentation is silent on what happens if you do this. It does appear to work:
class something::myservice {

  File { owner => 'root', group => 'wheel', mode => '0644' }

  exec { 'myservice':
    onlyif  => '/bin/test -f /Library/LaunchDaemons/com.blah.myservice.plist'
    command => '/bin/launchctl load /Library/LaunchDaemons/com.blah.myservice.plist',
    unless  => '/bin/launchctl list com.blah.myservice &> /dev/null',
  }

}
But both conditions always need to be evaluated, and I'm not sure this is actually going to work in the future. In my testing 'onlyif' was run before 'unless' but I wouldn't rely on that either. So lets just work around the broken commandline checking by adding a NOP with true &&:
class something::myservice {

  File { owner => 'root', group => 'wheel', mode => '0644' }

  exec { 'myservice':
    path    => ["/bin", "/usr/bin"],
    onlyif  => ['true && ! /bin/launchctl list com.blah.myservice &> /dev/null',
                '/bin/test -f /Library/LaunchDaemons/com.blah.myservice.plist'],
    command => '/bin/launchctl load /Library/LaunchDaemons/com.blah.myservice.plist',
  }

}
The path is necessary since the commandline checking wants the first part of the command to be an absolute path, or the path specified in 'path'. Since true is an inbuilt part of bash we need to specify path.

Friday, May 17, 2013

pdb and gdb conditional breakpoints

Use a debugger enough and you'll eventually be in a loop looking for a certain condition. And it's too tedious to walk through all iterations of the loop to get to the one you want. Enter conditional breakpoints. In GDB you'd use something like this (borrowed from here):
(gdb) br test.cpp:2
Breakpoint 1 at 0x1234: file test.cpp, line 2.
(gdb) cond 1 i==2147483648
(gdb) run
Or this for strings:
break test2.cpp:10 if strcmp(y,"hello") == 0
In the python debugger the syntax is a little different:
b(reak) ([file:]lineno | function) [, condition]
Like this:
(Pdb) break blah.py:1, somevalue=2

Tuesday, May 14, 2013

python set a variable conditional on another variable

Tiny python snippet. If you're doing this:
if value:
  output = value
else:
  output = 'somethingelse'
Do this instead:
output = value or 'somethingelse'