I hate upgrading Ubuntu, because every time I upgrade, something breaks. Sometimes it's small things, sometimes not so small. For instance, the last time I tried upgrading to a newer version of KDE 4, I ended up irreparably borking the installation and just switching to GNOME. (And by "irreparably", I mean messing it up bad enough that I had neither the time nor inclination to repair it.) Interestingly, the change was much less disruptive than I thought. Apparently I just don't care that much about desktop integration anymore. Chalk it up to switching back and forth between platforms all the time.
Anyway, this time the breakage was in the permission fixing script for my Sansa e280 MP3 player. The short version is that when the script ran mattrib -h to clear the "hidden" attrbiute on a directory, it just printed out the mattrib usage message, despite the fact that there was no error in the command syntax. After all, the same script had been working flawlessly for over a year in Ubuntu 8.10 and 9.04.
Well, after an hour or two of messing around and fruitless Googling, I finally stumbled upon the answer. It turns out that in the build of mtools 4.0.10 that ships with Ubuntu 9.10, the option to remove the hidden attribute has changed from -h to -H. Of course, the usage message still says -h and the man page still says -h, but it's -H that actually works. So, basically, I lost an hour of my life because somebody, whether in upstream of the package maintainer in universe, screwed up and forgot to update the documentation.
Anyway, I did my duty and filed a bug report. We'll see if anything comes of it. I'm sure it's not a high priority, though - if the Google results are any indication, I'm about the only person in the world who uses mattrib on a regular basis anymore.
I finally got around to fixing my MP3 player this weekend. I have a Sandisk Sansa e280 running the Rockbox open-source firmware replacement. Despite being a little light on capacity (8GB internal flash plus 2GB for the non-HC microSD slot), I like it a lot. However, recently the headphone jack had gotten very loose. If I jiggled the jack a little, the sound would cut in and out. After a while, it reached the point where I had to pull the cord at just the right angle to maintain enough contact to listen to anything.
Fortunately, this turned out to be relatively easy to fix. I found some instructions on the abi forum, along with links to pictures. It took a little time, but I got the headphone jack working like new again.
The main problem I had was prying up the plastic headphone jack. The plastic part is only held to the board by the metal contacts, which are soldered on. So you can just lift it off to get to the contacts themselves. However, I didn't want to use too much force to pry up the plastic, lest I break one of the contacts or crack the board. After fiddling around with it for a while, I decided to try the opposite route, taking advantage of the fact that you can see the top of the contact poking through the plastic. So, rather than pulling on the plastic, I held onto the plastic part and held the board up off the table. Then, I pushed down on the top of the contacts with a pin and they slid out without too much effort. So I bent the contacts in a bit and put small pieces of a rubber band behind the to try to prevent them from bending in the future. Then, to get the plastic back over them, I gently pushed on the top of the contacts with a straight screwdriver to guide them back into the channels in the jack.
Worked like a charm! I listened to my Sansa all day today and didn't have the sound cut out once. I was starting to fear I'd have to get a new MP3 player. And while the Sansa View and Sansa Fuze look nice enough, and have high-capacity microSD slots, Rockbox isn't stable on them yet. And frankly, Sandisk's native firmware isn't that great. If nothing else, I just like that Rockbox lets you use both database and file system navigation. Not to mention those handy plugins and the extra media formats.
OK, I'm not crazy! At least, not for the reason I thought.
I was playing with adding some dependencies to my Selenium PHPUnit tests. See, PHPUnit 3.4 has this handy little test dependency feature, the @depends annotation. It's basically a PHPDoc comment that includes a test name. You add that to a test and, if PHPUnit hasn't run the dependency yet, it skips the current test.
Well, I'm working on Windows. And every time I added an @depends to a test, PHPUnit would skip it. Even if the dependency had run! Even on the example from the documentation! I thought I was losing my mind.
However, it turns out that it's a known bug in PHPUnit. Basically just a line ending issue. The bug ticket has a 2 character patch that fixes it, or you can just save your files with UNIX line endings. Go figure.
Update: Wow, talk about weird timing. It turns out this issue was fixed in PHPUnit 3.4.1, which was released the day after I posted this.
Here's a weird little "feature" I came across the other day. It seems that Selenium discriminates between spacing in source and rendered HTML. I suppose this shouldn't be that surprising, but I just hadn't thought to account for it.
Here's what happened: I was writing a Selenium test case using PHPUnit's Selenium extension and I kept getting a failure on a simple assertTextPresent() call. I checked the page manually, and the text was definitely there. I selected the text and right-clicked to try the assertion in Selenium IDE, and it worked there. Then I tried copying the expected string out of my PHP test case and checking that in the IDE, and that's where it failed.
The only difference: one extra space in the PHP string. The real kicker is that that space is present in the page source. But when I stopped to think about it, it make perfect sense. Selenium interacts with the page through the DOM, and multiple spaces get rendered as one in HTML. The source is irrelevant - it's the rendered code that counts. I'll have to remember that for next time.
Ah, Raymond Chen. You can always count on him for a good tip stated in a way that makes it seem blindingly obvious.
The other day I got a couple of good tips from his blog. While writing a simple batch script to wrap up executing some Selenium RC test cases, I had the need to change to another directory and then change back. A little Googling led me to this page, where Raymond expounds on the eminently useful %CD% environment variable, which stores the current directory. (Of course, I ended up just using pushd and popd, which I'd forgotten Windows had, but that's not the point.)
On the same page, Raymond links to a handy little 90-byte batch script that does the equivalent of the UNIX which command. I thought that was really great. In fact, that's something I've always wanted. I've got the UnxUtils, which includes a Windows port of which, but it's just not the same, because it requires you to specify the file extension. I'm not much of a batch scripter, so I never would have thought to even try doing that in a batch file. Go Raymond!
Here's a little problem I ran across at work the other day. I was writing a little script to SSH into our 2 app servers and restart Memcached. Simple and easy, right?
Well, not quite. When I ran the script, the restart was hanging the SSH session. The service restarted properly, but my SSH connection never closed, so the script couldn't move on to the second server. What the heck?!?
Turns out that this is an issue with the way OpenSSH handles I/O streams. Apparently the init script for starting memcached didn't close standard output, so OpenSSH stuck around waiting for it. The solution: redirect STDOUT and STDERR on the server to /dev/null. That closes the streams and keeps the session from hanging. Of course, that could be a problem if you actually need to see any of the output, but in this case, I didn't.
Yes, this is yet another "reminder to myself" Postgres post, because I've had to look this up at least 3 times.
To turn on expanded query output formatting in psql, the Postgres command-line client, run either \pset expanded or simply \x. They both do the same thing - make Postgres output each column in a result set as a separate line. This is equivalent to the mysql command-line client trick of ending the query with \G instead of a semi-colon.
Incidentally both of the above commands are boolean toggles. You run them once to turn on expanded formatting and run them again to turn it off.
So at my new job (maybe I'll post something about that later), we use PostgreSQL for our RDBMS. And, for reasons I won't get into, our application stores dates as UNIX timestamps, rather than, you know, actual dates. Thus this quick note to myself so I don't have to keep looking up how to convert between the two.
Date to UNIX timestamp in Postgres (from this page):select date_part('epoch',now()) as unixtime; -- This will do it.
select extract('epoch' from now()) as unixtime; -- ... and so will this.
UNIX timestamp to Postgres TIMESTAMP (from this page):SELECT TIMESTAMP 'epoch' + 1195374767 * INTERVAL '1 second';
In case there was any doubt, I'm not a hardware guy. Yeah, I can do the basics - put a PC together from parts, swap out components if something goes bad - but it's not an area where I have a lot of experience or confidence.
So what should happen to me last week? Hardware problems galore! It started with one relatively small thing and just snowballed to both the PCs in my house being more or less out of commission.
The first problem was with Sarah's PC. It would occasionally soft-lock (meaning it wasn't completely unresponsive, but wasn't operational either) and need to be rebooted. A quick inspection revealed a bunch of I/O errors. My first instinct was "bad drive", but just to be safe, I figured I'd put the drive in my PC, just to make sure the SATA controller wasn't going bad.
Good thing I did, because after some testing, it looked like it was the controller! On Sarah's PC, heavy disk activity (copying a few dozen gigs of data) always resulted in an error sooner or later. But on my PC, I never saw any problem. I even tried swapping out the SATA cable with one from my box and it didn't make any difference. So I concluded that the problem was the SATA controller.
Meanwhile, some time during this testing, one of the drives on my PC went bad! I'm assuming the problem was in the drive's controller card, because the disk was still spinning up and not making any funny noises, but the system BIOS just wasn't seeing it. In fact, when the drive was connected, the BIOS would hang on detecting it! The worst part was that it was the new 750GB drive I bought just over a month ago! On the up side, I didn't have anything irreplacable on it, and was eventually able to revive it long enough to copy most of the data off (unfortunately I didn't have enough working storage for everything, but I got the stuff I really cared about). Of course I was just past NewEgg's return window, so I had to put in an RMA to the manufacturer.
So fast-forward to this past weekend. The new $20 PCI SATA/RAID controller for Sarah's box came in. I've never dealt with an add-on SATA controller before, but it was dead simple to install - put it in the PCI slot, connect the drive, and you're done. It worked great - for one evening. Then I started seeing more disk errors. This time they were failures from ext3_find_entry() rather than generic I/O errors, but that's still not too helpful. So now I'm back to square one on that.
On top of that, I've now been seeing lock-ups on my PC. Hard locks, too, as in the system goes totally unresponsive and the capslock light starts blinking. That, for the Linux people in the crowd, indicates a kernel panic. This one was a bitch to track down, too, because it was happening randomly as I did things from within X11, but didn't seem to happen on the command line. And since kernel panic output gets dumped to the console, I couldn't see what was going on (because you can't switch from an X display to the console when the system is crashed). So I ended up leaving the system at the console and eventually got a kernel panic again. Turns out it was coming from the USB subsystem somewhere. I still don't know if it's one of my peripherals, my hub, or the USB controller, so I'll have to do some experimenting.
It's weeks like this when I really appreciate the philosophy of technical people who say, "Forget building it, just buy from a system vendor so that you can have it repaired under warranty." Fixing problems like this is sickeningly time consuming and generally not much fun. Especially if you're not a hardware guy.
As I mentioned the other day, I recently acquired a hand-me-down laptop. My sister-in-law bought herself a shiny new Dell and gave me her old Compaq Presario R4000 with the dead battery.
So I'm currently in the process of fixing this system up. So far I've just wiped the drive, laid down a fresh install of Windows XP SP3, and installed the drivers and some standard applications. It's actually not a bad little system - Athlon XP-64 processor, 80GB hard drive, DVD burner. Hardly state of the art, but it beats the pants off my old Dell Inspiron B120.
Aside from the battery (which is gonna cost me about $75 to replace), there's only one problem: memory. The system comes with 512MB of RAM, which was fine for the time, but is a little small now. The problem is that the system has two 256MB RAM modules - one of which is under the keyboard, which is really annoying. And they're not especcially cheap modules, either - it takes DDR PC2700 sticks, which go for about $40 per gig on NewEgg. By way of contrast, I recently got another 1GB stick of DDR2 PC5300 to max out the RAM on my Dell, and it only cost me $12 with free shipping.
So I'm debating how much to get now. In better times, I'd just spend the $80 and max out the memory. But times are tough, and it's an old laptop, and I'm already spending $75 to get a new battery. So maybe I'll just stick to 1GB, or perhaps even half a gig. It wouldn't be quite so annoying if they'd just used 1 stick in the first place. As it is, I'm going to lose half the existing RAM if I upgrade either DIMM slot, so I'm not going to get out of this as cheap as I'd hoped.
Either way, it'll still be nice to have another laptop around, so that Sarah and I aren't fighting over the one. And even if I max out the RAM, it's still way cheaper than getting a new system, so it's still a win-win situation.