goldb.org home

AS OF MAY 2008, THIS BLOG IS NO LONGER BEING UPDATED.
Visit the new blog at: http://coreygoldberg.blogspot.com



 Friday, January 19, 2007

LDTP and UI Test Tools for GNU/Linux

There currently aren't many commercial UI test tools for GNU/Linux applications.  GNU/Linux has come a long way towards becoming more popular on the desktop, but it is still somewhat niche in the business world.   There is a large contingent of Windows software testers and QA engineers that make their living using commercial UI test tools (WinRunner, QTP, SilkTest, Robot, etc) from the big tool vendors (HP/Mercury, IBM/Rational, Borland/Segue, Compuware, etc).  I am not talking about small test utilities; I am talking about large UI layer test suites that people build extensive customized test frameworks on top of.  These are used most often in large business applications for automating functional and regression tests.

Good test tooling is a prerequisite for any large deployment of a business application.  As GNU/Linux becomes more popular on the desktop, I think this will become a more important factor and tool vendors will begin to beef up their GNU/Linux UI test tool offerings.  It would be great if there were viable open source tools as an alternative.  On Windows, this never happened.  There are currently no high quality open source UI test tools available.


I just took a look at the GNU/Linux Desktop Testing Project (GNU/LDTP):

"GNU/Linux Desktop Testing Project (GNU/LDTP) is aimed at producing high quality test automation framework and cutting-edge tools that can be used to test GNU/Linux Desktop and improve it."


wow.. I had never heard of that until now.

The description looks good.. it is a UI layer test tool that works in both GNOME and KDE environments.

.. and it is Free/Open Source.

.. and it is written in Python (which completely rules)

I will be keeping an eye on this and any other open source test tools in that space.

#    Comments [0] |
 Tuesday, January 16, 2007

Python - Merge a Sequence of Lists Into a Single List

the function:

def merge(seq):
    merged = []
    for s in seq:
        for x in s:
            merged.append(x)
    return merged


sample usage:

foo = [['a', 'b'],['c'],['d', 'e', 'f']]
print merge(foo)

>>>['a', 'b', 'c', 'd', 'e', 'f']

Update:
Here is another implementation that uses a Python dictionary. This version merges the lists and only keeps unique entries.

def merge(seq):
d = {}
for s in seq:
for x in s:
d[x] = 1
return d.keys()
#    Comments [0] |
 Wednesday, January 10, 2007

VBScript - Creating a Microsoft Web Archive (*.mht) File Programmatically

Here is a little VBScript for generating a Microsoft Web Archive (*.mht) file.  Web archives are a convenient way to pack a bunch of web files (HTML/CSS/JavaScript) into a single file that is viewable in your browser.  The downside is MHT files are only viewable in MS Internet Explorer (lame).

Normally you would create an MHT by using the "Save As..." option in IE.  This script allows you to create one programmatically.

Sample Usage:

for a remote html file:

>cscript mht_converter.vbs http://www.example.com/temp/foo.html foo.mht


for a local html file:

>cscript mht_converter.vbs file:/temp/foo.html foo.mht



... And now the code:




'mht_converter.vbs

Const adSaveCreateNotExist = 1
Const adSaveCreateOverWrite = 2
Const adTypeBinary = 1
Const adTypeText = 2

Set args = WScript.Arguments

if args.Count = 0 then
WScript.Echo "Usage: [CScript | WScript] mht_converter.vbs <html file> <mht filename>"
WScript.Quit 1
end if

Set objMessage = CreateObject("CDO.Message")
objMessage.CreateMHTMLBody args.Item(0)
SaveToFile objMessage, args.Item(1)


Sub SaveToFile(Msg, Fn)
Dim Strm, Dsk
Set Strm = CreateObject("ADODB.Stream")
Strm.Type = adTypeText
Strm.Charset = "US-ASCII"
Strm.Open
Set Dsk = Msg.DataSource
Dsk.SaveToObject Strm, "_Stream"
Strm.SaveToFile Fn, adSaveCreateOverWrite
End Sub




Caveat:  I am not a VB programmer... don't pretend to be... and never wanna be.  This was just something I needed to do and this was the only way I could quickly figure out how to do it.

#    Comments [2] |
 Tuesday, January 09, 2007

Adding A Second Hard Drive To My Dell Laptop

I have a Dell Inspiron 600m laptop and I currently use Windows XP as the base Operating System with Ubuntu (GNU/Linux) running in a Virtual Machine (VMWare) on top of it.  This generally works really well... but I want to natively run Linux (instead of hosting it inside a VM) and I'm not crazy about the idea of partitioning my primary hard disk.

So what to do?

Dell offers a "2nd Hard Drive Module" to overcome this.  It is a replacement for the default CD tray that sits in the side of the laptop.  It fits in the same slot as the CD tray but inside it has an IDE adapter and hard drive mounting brackets.  This lets you use any 2.5" IDE Hard Drive as a second disk in your laptop... very cool.

I went with a Hitachi Travelstar E7K80 drive to put inside it (7200 RPM, 80 gig).



note: the 2nd Hard Drive Module" is horribly expensive from Dell directly but I picked one up on eBay for under 50 bucks

#    Comments [0] |

Python - Formatted Dates and Times

I am not sure why, but every time I need to use some formatted dates or times in Python, I end up spending about 20 minutes going through the docs and reading up on the datetime module; which leads to more confusion.

So for my own clarity, here is how we do it using only the time module:

>>> import time
>>> print time.strftime("%m/%d/%y %H:%M:%S", time.localtime())
01/09/07 12:17:25

All of the formatting options for strftime() can be found here: http://docs.python.org/lib/module-time.html

#    Comments [0] |
 Wednesday, January 03, 2007

Dojo JavaScript Toolkit with ASP.NET

Dojo is a free/open source JavaScript toolkit.  I wanted to add some its eye candy to one of my ASP.NET 2.0 applications, so I integrated the Fisheye menu (a menu that balloons out, similar to the launcher on OS X).






Here is how I did it:


First I downloaded Dojo and created a 'dojo' directory under my main project directory.  I dropped dojo.js and the entire Dojo 'src' directory here.

Then in my C# codebehind (.aspsx.cs), I add this to the Page_Load event:

protected void Page_Load(object sender, EventArgs e)
{
    HtmlGenericControl Include = new HtmlGenericControl("script");
    Include.Attributes.Add("type", "text/javascript");
    Include.Attributes.Add("src", "dojo/dojo.js");
    Page.Header.Controls.Add(Include);

    HtmlGenericControl Include2 = new HtmlGenericControl("script");
    Include2.Attributes.Add("type", "text/javascript");
    Include2.InnerHtml = "dojo.require('dojo.widget.FisheyeList');";
    Page.Header.Controls.Add(Include2);
}

(I do this in the codebehind because I am using a Master Page and I need to access the HTML header from an individual content page.)


Then inside my ASP.NET page (.aspx), I added this div:

<div class="fisheyelist">
    <div dojoType="FisheyeList"
        itemWidth="80" itemHeight="80"
        itemMaxWidth="200" itemMaxHeight="200"
        orientation="horizontal"
        effectUnits="2"
        itemPadding="10"
        attachEdge="center"
        labelEdge="bottom"
        conservativeTrigger="false"
    >
        <div dojoType="FisheyeListItem"
             onclick="window.location = 'item1.aspx';"
             caption="Item 1"
             iconsrc="img/item1.png">
        </div>
        <div dojoType="FisheyeListItem"
             onclick="window.location = 'item2.aspx';"
             caption="Item 2"
             iconsrc="img/item2.png">
        </div>
        <div dojoType="FisheyeListItem"
             onclick="window.location = 'item3.aspx';"
             caption="Item 3"
             iconsrc="img/item3.png">
        </div>
    </div>
</div>



.. and it works.

#    Comments [0] |

Python - Find And Replace A String In Every File In A Directory

The Python Cookbook has a recipe to find and replace a string in every file in a directory.

I needed to do something like this today, so I cleaned up the script a little to make it [hopefully] a little more pythonic:


#!/usr/bin/env python
# replace a string in multiple files

import fileinput
import glob
import sys
import os


if len(sys.argv) < 2:
    print 'usage: %s search_text replace_text directory' \
        % os.path.basename(sys.argv[0])
    sys.exit(0)


stext = sys.argv[1]
rtext = sys.argv[2]
if len(sys.argv) == 4:
    path = os.path.join(sys.argv[3], '*')
else:
    path = '*'


print 'finding: %s and replacing with: %s' % (stext, rtext)


files = glob.glob(path)
for line in fileinput.input(files, inplace=1):
    if stext in line:
        line = line.replace(stext, rtext)
    sys.stdout.write(line)


#    Comments [0] |

Tim Bray on Simplicity

Best Tim Bray quote:
"Don Park makes his blog go fast by applying WhirlyCache to the DAO layer, slipping in a transaction layer to reduce database integrity corruption, and using aspect-oriented programming technology via the Spring framework, with the help of Java annotations to mark transactional methods and classes. Yow! My approach is to have Apache serve static data out of the filesystem. Whatever; faster is better."

often simplicity trumps everything, eh?

#    Comments [0] |
 Tuesday, January 02, 2007

Free Books On Technology Subjects

This site has a collection of links to freely downloadable versions of some really good programming and computer science books:

www.techbooksforfree.com

#    Comments [0] |
 Friday, December 22, 2006

Schools of Software Testing

Cem Kaner just posted an incredible piece of writing about the Schools of Software Testing.

Especially intriguing was his explanations of "paradigms" in a generic sense, and references to Thomas Kuhn.

good stuff.


#    Comments [0] |
 Monday, December 18, 2006

Got Master's? Yup

I just finished my Master's Degree at Boston University and will be receiving my Diploma next month!  This is a big relief for me, as I have been working on it part time for the past 3.5 years while working full time as a software engineer.

I now have a Master of Science in Computer Information Systems (CIS).

The coursework included:
  • Advanced Java Programming
  • Architecture and Design of Multi-tiered Systems
  • Database Design and Implementation for Business
  • Data Communications and Computer Networks
  • Grid Computing
  • Human-Computer Interface Design with .NET
  • Information Systems Analysis and Design
  • IT Project Management
  • Operating Systems
  • Web Application Development

Finished with a 3.73 GPA.  w00t!

#    Comments [0] |
 Thursday, December 14, 2006

DevHouse Boston

I was at the first DevHouse Boston last Saturday.  What a great idea.. Have a bunch of talented and inspired hackers show up... serve up free wifi and pizza... let people talk and throw ideas around... break into small groupos... and knock out working code the same day.

I didn't get to stay until the end, but I spent time working with a great group working on a cool tool.

I hope DevHouse becomes a regular thing.

Two initial observations gleaned from this group:  Python and Ruby own.. and Macs are everwhere.

#    Comments [0] |
 Tuesday, December 12, 2006

Java In Nuclear Reactors?

This is pretty funny (or scary)

I always thought this excerpt from the Java license was odd:

"not designed or intended for use in the design, construction, operation or maintenance of any nuclear facility."

So it made me do a double-take when I read this:

Sun Solaris Grid Powers Next Generation Nuclear Reactor Design from the Department of Energy

from the article:

"The solution includes more than 230 Sun Solaris Servers powered by AMD  Opteron processors; and, more than 12 Terabytes of Sun StorEdge 6320 storage, the Solaris 9 operating system, Java Enterprise System and Java development software"

I guess the DOE likes to keep things exciting :)

#    Comments [0] |
 Thursday, December 07, 2006

C# - Read Contents Of A Randomly Selected File

string[] fileList = Directory.GetFiles(@"c:\temp");
Random random = new Random();
string fileName = fileList[random.Next(fileList.Length)];
StreamReader sr = File.OpenText(fileName);
string contents = sr.ReadToEnd();



#    Comments [0] |
 Thursday, November 30, 2006

Feed Reading in Firefox 2

From Ben Goodger (Googler and Lead Firefox Dev) on RSS in Firefox:

"... Firefox philosophy of having enough features, not too many or too few. In general, we felt that RSS reader was a very personal choice to be made by the user, and that we did not want to compete with existing RSS readers, which are very competent in a variety of ways. Rather, we wanted to allow users to easily subscribe to feeds using their favorite reader."

I love this feature.. it lets me quickly subscribe to feeds through Bloglines.

I think Firefox nailed this one.  A feed reader belongs in a plugin if you choose to use your browser for such tasks.  Keep the core simple and extensible.

#    Comments [0] |
 Friday, November 24, 2006

Python, IDEs, and Drones

Python is a very popular programming language with adoption and advocacy from many corporations, and large factions of open source programmers using it extensively.  However, in the world of "corporate drone programming", it is still pretty niche. 

Have a look at this indication of popularity among programming languages:
TIOBE Programming Community Index

One thing I like about Python is the simpilcity it strives for.  I find myself writing all my code in SciTE, a simple text editor; rather than a full blown IDE.

I always looked at this is a strong point for dynamic languages.

Over in the cult of corporate drone programmers, static languages (C++, C#, Java) are the norm, and life is spent inside an IDE.


from Robert on comp.lang.python:

"Flat Web/DB programming is one major field where programmer masses are born.  The other big one is RAD-GUI/DB programming. This field is probably still wide open. Best tooled Borland RAD systems are going down meanwhile because of the stiff compiler language. Programmers look around for the next language & toolset. Python is the language - but with Python there is again a similar confusion around IDE's and GUI-libs. There is no really good IDE (but fat ones). And the major gui libs there are not Python, but are fat sickening layers upon layers upon other OO-langs."

Not that I necesarilly want Python to become the next default language for drones, but it makes me think about further adaption and mainstreamability of Python and other dynamic languages (which typically aren't as well suited to the features of many IDEs)

#    Comments [0] |
 Thursday, November 23, 2006

SOAP and REST - Conceptually

After reading thousands of articles about SOAP vs. REST, I was more confused about everything than convinced of anything.

Finally, this quote  from Stefan Tilkov made the conceptual difference between SOA(P) and REST very clear to me:
"In REST, you have lots and lots of resources all supporting the same interface; in SOA(P) (at least the wide-spread paradigm), you have few endpoints all supporting different interfaces."

#    Comments [0] |
 Friday, November 17, 2006

Python - The New Choice For Computer Science Academia?

I have seen a few articles in the past couple days talking about how MIT is revamping its introductory computer science course from using Scheme/Lisp to using Python.  Apparantly, other CS programs are using Python as well.

As an undergrad in 1993, I took CS classes in a program that was somewhat modeled after the MIT curriculum.  We used the first edition of the [in]famous wizard book.  Head first into the weird ways of functional programming was a bit of a shock for me and Scheme nearly scarred me for life.  I think the move to using Python is certainly a good one.

I just took a look around the net and was surprised by how many people are pushing for Python as an introductory language that is well suited to be taught in an academic setting.


Some links to related articles:

Teaching with Python
Using Python in a High School Computer Science Program
EDU-SIG: Python in Education
Teaching Introductory Computer Science with Python

#    Comments [0] |
 Tuesday, November 14, 2006

MQSeries and .NET - Interacting With Message Queues from C#

Below is a C# Class that I use for interacting with MQSeries (reading/writing from/to queues). 

It contains 2 methods:
PutMessageOnQueue
GetMessageOffQueue

To use it, you must have IBM WebSphere MQ installed, and you must add an assembly reference to amqmdnet.dll (the .NET bindings that come with WebSphere MQ).

I am using:
.NET 2.0
VS 2005
WebSphere MQ 5.3.0




public class MQSeries
{
    string queueName;
    string queueManagerName;
   
    MQQueue queue;
    MQMessage queueMessage;
    MQQueueManager queueManager;
   

    public MQSeries()
    {
        queueName = "TESTQ";
        queueManagerName = "TESTQM";
        queueManager = new MQQueueManager(queueManagerName);
    }  


    public void PutMessageOnQueue(string message)
    {
        try
        {
            queue = queueManager.AccessQueue(queueName,
                    MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING);
            queueMessage = new MQMessage();
            queueMessage.WriteString(message);
            queueMessage.Format = MQC.MQFMT_STRING;

            queue.Put(queueMessage);
        }
        catch (MQException mqexp)
        {
            Console.WriteLine("MQSeries Exception: " + mqexp.Message);
        }
    }


    public string GetMessageOffQueue()
    {
        string message = "";
       
        queue = queueManager.AccessQueue(queueName,
                MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING);
        queueMessage = new MQMessage();
        queueMessage.Format = MQC.MQFMT_STRING;

        try
        {
            queue.Get(queueMessage);
            message = queueMessage.ReadString(queueMessage.MessageLength);
        }
        catch (MQException MQExp)
        {
            Console.WriteLine("MQQueue::Get ended with " + MQExp.Message);
        }

        return message;
    }

}
#    Comments [0] |
 Sunday, November 12, 2006

CPU Monitor With Python And WMI

Tim Golden's WMI module for Python is a lightweight wrapper around the WMI classes available for all Win32 platforms.

Windows Management Instrumentation (WMI) is Microsoft's implementation of Web-Based Enterprise Management (WBEM), an industry initiative to provide a Common Information Model (CIM) for pretty much any information about a computer system.

I will give a simple example of monitoring your local CPU using the WMI module from a Python program.


First, we can explore the WMI Win32_Processor class:

import wmi
c = wmi.WMI()
for s in c.Win32_Processor():
    print s


Output looks like this:

instance of Win32_Processor
{
    AddressWidth = 32;
    Architecture = 0;
    Availability = 3;
    Caption = "x86 Family 6 Model 13 Stepping 6";
    CpuStatus = 1;
    CreationClassName = "Win32_Processor";
    CurrentClockSpeed = 1794;
    CurrentVoltage = 33;
    DataWidth = 32;
    Description = "x86 Family 6 Model 13 Stepping 6";
    DeviceID = "CPU0";
    ExtClock = 133;
    Family = 2;
    L2CacheSize = 2048;
    Level = 6;
    LoadPercentage = 6;
    Manufacturer = "GenuineIntel";
    MaxClockSpeed = 1794;
    Name = "        Intel(R) Pentium(R) M processor 1.80GHz";
    PowerManagementSupported = FALSE;
    ProcessorId = "AFE9F9BF000006D6";
    ProcessorType = 3;
    Revision = 3334;
    Role = "CPU";
    SocketDesignation = "Microprocessor";
    Status = "OK";
    StatusInfo = 3;
    Stepping = "6";
    SystemCreationClassName = "Win32_ComputerSystem";
    SystemName = "GOLDB";
    UpgradeMethod = 6;
    Version = "Model 13, Stepping 6";
    VoltageCaps = 2;
};



Here I use it in a script that prints CPU utilization every 5 seconds:

import wmi
import time

c = wmi.WMI()
while True:
    for cpu in c.Win32_Processor():
        timestamp = time.strftime('%a, %d %b %Y %H:%M:%S', time.localtime())
        print '%s | Utilization: %s: %d %%' % (timestamp, cpu.DeviceID, cpu.LoadPercentage)
        time.sleep(5)


      
Output looks like this:

Sun, 12 Nov 2006 19:26:25 | Utilization: CPU0: 4 %
Sun, 12 Nov 2006 19:26:31 | Utilization: CPU0: 8 %
Sun, 12 Nov 2006 19:26:37 | Utilization: CPU0: 1 %
Sun, 12 Nov 2006 19:26:43 | Utilization: CPU0: 6 %
Sun, 12 Nov 2006 19:26:49 | Utilization: CPU0: 13 %

#    Comments [0] |
 Tuesday, November 07, 2006

Python - Removing Duplicates From A Sequence

Sequences (lists and tuples) are common data structures used in Python programming.

Here is a simple function that will remove duplicates from a sequence and return a sorted sequence of the unique items:


def remove_dups(seq):
    x = {}
    for y in seq:
        x[y] = 1
    u = x.keys()
    u.sort()
    return u


(Caveat:  It requires that all the sequence elements be hashable, and support equality comparison)


And another implementation (not sure which is better):

def remove_dups(seq):
    u = [x for x in seq if x not in locals()['_[1]']]
    u.sort()
    return u



Example using them from the Python Interpreter:

>>> my_seq = [1, 1, 3, 1, 2, 2, 7.75, 'foo', 7.75, 'foo']
>>> print remove_dups(my_seq)
[1, 2, 3, 7.75, 'foo']




Tim Peters has an excellent recipe in the Python Cookbook that dives into this much further:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560
#    Comments [0] |
 Sunday, November 05, 2006

Dynamic Languages On The CLR - IronPython For ASP.NET

OK... Dynamic Languages on the .NET CLR are getting serious:
(especially Python)

IronPython

... and infiltrating the .NET stack further:

IronPython for ASP.NET

The New Dynamic Language Extensibility Model for ASP.NET

#    Comments [0] |

Extending Copyrights: Elvis Is Not Going To Produce Any More Recordings In 1957

I think most people have a very confused view of what copyrights are for.

As usual, Richard Stallman clarifies this in his simple pointed words:  Misinterpreting Copyright

Further clarification from Larry Lessig:  

"[There is] fallacy in any public policy argument that tries to suggest there is an economic harm from failing to extend the term of an existing copyright. The key is the distinction between social value and individual value."

Yes..  Social Value vs. Individual Value.
I especially love Lessig's quote here about the "tax" (yes, it is a social tax or trade-off) of extending copyrights:

"The work is already produced. No matter what we do today, Elvis is not going to produce any more recordings in 1957. So it is a tax that benefits some plainly, but benefits society not at all."

#    Comments [0] |

Perl 6? The Long Wait

I've been waiting for Perl 6 for quite a few years now...

I initially started hacking Perl in 1998 in my days as a software tester.  Perl is a programming language that tends to be popular with testers... usually because of its powerful text processing features (built-in regex's, dynamic/weak typing, simple/powerful data structures, etc).  It is perfect for munging large data sets and slinging text into whatever test configurations you need.  I have written plenty of useful software in Perl.

But.. the Perl community has sort of stagnated and other languages are taking over what was once its niche  (By stagnated I mean in terms of getting a finished version out, certainly not in terms of work being done.. which there is lots of).  We have been waiting on Perl 6 for many years now and a working implementation is yet to be generally released.  Every year or so, we get a new term or acronym to chew on (Parrot, PONIE, PUGS), but day to day I write less and less Perl as other languages seem to be moving faster.  I know there are lots of very bright and talented people working on Perl 6... and I appreciate that.  But I get the feeling that it is concentrated in a few individuals.  I wonder why Perl 6 development hasn't scaled like some other languages have?  Other dynamic language communitues (i.e. Python/Ruby) seem to be constantly embraced and pushed forward... and with that comes a healthy community with diverse and active contributors.


#    Comments [2] |
 Thursday, November 02, 2006

NetPlot - Network Latency Monitor - New Release

I just released a new version of NetPlot (minor bugfixes).

You can get a new copy of the program and GPL'ed source code here:  http://www.goldb.org/netplot.html

NetPlot is a network monitoring tool written in Java. It uses your system's ping utility to send ICMP ECHO_REQUEST to a host or device. With each collection, it sends 3 pings to get the average latency. Results are then plotted in real-time so you can monitor network latency.



#    Comments [0] |