Printing Multi-Page Posters

An easy way to print a picture over multiple pages is to use a spread sheet program.

Programs like Microsoft Excel and Openoffice already support multi-page printing for spreadsheets. To print a multi-page picture, or a picture on multiple pages, insert a picture into a sheet. Scale the image the way you will like to print out. In Excel (and probably in Open Office  too), you can do a print preview to start seeing the printed page boundaries. That will give you an idea about how many printed pages will the picture print on. Using this information, you can scale the image to get it to fit in the right number of pages.

Remember to adjust orientation (landscape or portrait) based on the aspect ratio of your picture. That might let you print on fewer pages. Adjust the margins on the page and turn off header and footer to get even more space.

Then just print as you normally would and you will get a multi-page picture that  you can paste together to get a large poster!

Sending Mail From Command line

Being able to send an email using a script or command line is a handy capability. This capability is quite useful for a number of actions including

  1. Sending errors and results of recurring unattended scripts such as backup
  2. Sending status at the end of running automated test scripts
  3. Create a tool to send automated emails to a set of your contacts (no spam please!)

I was looking for a capability like this which would

  1. Be a native windows binary so I do not have to install perl, php etc
  2. Be able to send inline text and attachements
  3. Be able use both authorized as well as non-authorized smtp servers (including SSL, TLS etc.)

I looked around and it was a surprisingly difficult search. I tried different tools. Most free/open source tools did not include secure smtp servers (most of which now are). Most paid ones were $49 or more and that was too much for an occasional use.

I finally found what I was looking for: a really nice utility called by mailsend written by Muhammad A Muquit. The web page for this site is http://www.muquit.com/muquit/software/mailsend/mailsend.html.

One question would be, which smtp server to use. A very good answer is: use gmail. Google let’s you send email through your account by connecting through smtp.Make sure that you download the smtp enabled exe. There are two exe/zips on the site, the first one is without TLS support that will not work on gmail. Last time I checked, the name of the script with TLS support was mailsend1.15b5.tar.gz or mailsend1.15b5.exe.zip.

Using this software, one way to send email using your gmail account would be:

mailsend1.15b5.exe -t touser@todomain.com -sub Subject -from from@fromdomain.com -smtp smtp.gmail.com -starttls -auth-login -user gmail_user -pass gmail_password +cc +bc -attach filename1,text/plain,i -attach filename2,text/plain,a

Some notes:

Use quotes around arguments that have spaces in them (like Subject)

gmail_user and gmail_password are the gmail user and password you use to login to your gmail account

+cc and +bc means do not ask for cc and bc fields. Other wise, the app will go into an interactive mode to ask for values for these fields which you do not want for a script

the first -attach says, include filename1 as inline. The second -attach says, include filename2 as attachment. The second field in -attach indicates the mime type you want to use.

 

 

Efficacy of a Test Harness

I am a big proponent and follower of test automation as an integral part of software development. A test harness is a software system that enables the definition of tests, running of the tests and collecting and publishing of results of test runs.

What makes a test harness effective?

In my opinion, there are at least the following three critical requirements of a test harness:

Immediate: The time it takes to run the harness and to publish the results should be small. How small is small? My preference would be that a test harness takes less time to run than the time between two consecutive builds. That means that each build can be sent through the test harness and a break in a test can be determined before the second build with the break is done. For continuous integration enviroments, and more and more people are adopting this methodology, this becomes an important means to detect breaks before they impact the product or the development process in a big way.

Accurate: The tests that are run as part of the harness should be accurate. The tests should be testing the features correctly. I have seen too many tests written that miss the essence of feature testing. They lack either in use cases, testing edge conditions or in completeness. Having a large number of tests that fail to test the feature under question give a false sense of security. One tool to provide partial comfort is a code coverage tool that should be run in conjunction with tests so that you get at least a sense of the amount of code that is being left untested. However, even close to 100% code coverage is not a substitute for an analysis of the quality of your tests. Most complex problems arise as a combination of pre-conditions that one will miss even with close to 100% code coverage.

Easy to deal with failures: Many a test harness will fall in to disuse if it is hard to debug where the problem occured when a test fails. A test harness is useless if it is not passing all the tests most of the time. If it takes too long to debug failures, people tend to give up on the harness, more and more tests start failing and the harness becomes useless.

Picasa’s Face Recognition works really well

I take a lot of pictures. I have probably more than 10,000 pictures on my disk comprising almost 30 GB of storage. I have tried a number of photo organization tools and had finally settled on imatch from photools. This tool has very nice categorization features though it still requires a lot of manual work.

I had tried Picasa about two years ago and it seemed completely inadequate to me. It tried to do everything and it was hard for me make it do what I wanted. I tried Picasa 3.6 this week and I totally converted.

THe best feature that makes Picasa a winner is face recognition. It works amazingly well and it improves continuously. First it locates faces quite well. Secondly, it has a very efficient user interface that lets you tag photos with people’s names. Then, it finds matching faces with 90-95% accuracy and continously adds to the collection, seemingly improving its match algorithm. It even correctly identified pictures from people over 20 years of aging.

The naming tools are also quite efficient. For example, in the unnamed category, the tools similar faces close to each other so you can select multiple images and tag at once.

In addition, the photo processing tools it provides are quite good. It has the usual special effects tools such as contrast, sharpening, sepia etc. Another useful tools is cropping. It comes with some preset cropping ratios and even provides some cropping suggestions based on face placement.

Over all, a great improvement as compared to previous versions.

Powerpoint to Video

As part of a presentation for work, I was looking for a tool that could convert a powerpoint presentation to video. There are a number of tools out there but they cost between $49 to $399 or more. I eventually discovered a tool at http://www.effectmatrix.com/PowerPoint-Video-Converter/index.htm called E. M. Powerpoint converter. This tool lets you convert to a limited but useful set of video formats for free without any water mark. You only pay for additional formats and if you need a command line utility. I used it to convert it to wmv format. Even in the set of of free formats, the tool supports a variety of sizes and qualities.

The tools works like a charm and I like their sales model in which you can use the tool for free for a one-off personal use. I highly recommend it and encourage you to try and buy it.

The Anti-Facebook

It is an understatement to say that Facebook is an exploding phenomenon. It is a great platform to share your pics and other tidbits with your circle of friends or the world in general.

But, there are large parts of your life you DO NOT want to share with the world. It is for yours to manage, preserve for when you want to look back at life and cherish. You want to be able to create and store information in a way that is easy available but is safe so you can always get to it and secure so no prying eyes can look into it.

Towards this end, a few friends of mine and I created a website called, bereadyforlife.com. The idea was to enable a place on the web, or in the cloud as it is called nowadays, where we can keep our digital assets in a secure fashion. This could include

  • Important documents such as copies of house deeds, tax returns, warranty information etc.
  • Your personal thoughts in the form of loose documents or as a journal or diary
  • Checklists such as important numbers, emergency preparedness lists etc.
  • List of assets and their value so you can easily create insurance claims
  • And we added interesting information management apps such as shopping list manager

We then created security mechanisms such as high strength 256-bit encryption for your documents, journal, checklists etc. so that only you can get access to them. This is multi-level security. The site is first protected by your password. Then each area such as document vaults and diary is protected by separate keys. No one knows the keys except you. It is not stored anywhere on the site. So you can be assured that no one can compromise your data.

In fact, we keep our own data now on this site.

Check it out. I will welcome your comments on the beta version of the site at bereadyforlife.com. And spread the word!

Installing SSL Certificate in Apache2

I went through a major process to set up an SSL certificate in a web server going through a number of error messages including:

Data Transfer Interrupted

The connection to has terminated unexpectedly.
Some data may have been transferred.

and


(98)Address already in use: make_sock: could not bind to address 0.0.0.0:80

I am using a certificate from GoDaddy and running Apache2 on Ubuntu 8.04.

Not sure what series of corrections fixed the problem but the following configuration is now working:

/etc/apache2/sites-enabled/000-default


NameVirtualHost :443
NameVirtualHost :80


Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all

:80>
RewriteEngine On
RewriteOptions Inherit
DocumentRoot
ServerAdmin
ServerName :80

:443>
SSLEngine on
SSLOptions +StrictRequire

SSLVerifyClient none
SSLProxyEngine off

SSLProtocol -all +TLSv1 +SSLv3
SSLCipherSuite HIGH:MEDIUM:!aNULL:+SHA1:+MD5:+HIGH:+MEDIUM


AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl

RewriteEngine On
RewriteOptions Inherit
ServerAdmin
DocumentRoot /var/app/public
ServerName :443


And, the ssl.conf directory (/etc/apache2/mods-enabled/ssl.conf)


SSLRandomSeed startup builtin
SSLRandomSeed startup file:/dev/urandom 512
SSLRandomSeed connect builtin
SSLRandomSeed connect file:/dev/urandom 512

##
## SSL Global Context
##
## All SSL configuration in this context applies both to
## the main server and all SSL-enabled virtual hosts.
##

#
# Some MIME-types for downloading Certificates and CRLs
#
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl

# Pass Phrase Dialog:
# Configure the pass phrase gathering process.
# The filtering dialog program (`builtin’ is a internal
# terminal dialog) has to provide the pass phrase on stdout.
SSLPassPhraseDialog builtin

# Inter-Process Session Cache:
# Configure the SSL Session Cache: First the mechanism
# to use and second the expiring timeout (in seconds).
SSLSessionCache shmcb:/var/run/apache2/ssl_scache(512000)
SSLSessionCacheTimeout 300

# Semaphore:
# Configure the path to the mutual exclusion semaphore the
# SSL engine uses internally for inter-process synchronization.
SSLMutex file:/var/run/apache2/ssl_mutex

#SSLEngine on
SSLCertificateFile SSLCertificateKeyFile SSLCertificateChainFile

SSLRandomSeed startup file:/dev/urandom 1024
SSLRandomSeed connect file:/dev/urandom 1024

SSLSessionCache shm:/usr/local/apache2/logs/ssl_cache_shm
SSLSessionCacheTimeout 600

Hope this helps some other soul having the same tribulations.

Selenium Locators

I am a big fan of automated testing and have started to look at Selenium as an automation tool. I have used Watir before as a tool to drive the browser, but have found that the learning curve for Ruby is too much of an overhead for some QA engineers. Since Selenium has a good IDE to capture and record actions, it is very easy to get started. It also has a rich set of functions that can be used to drive the browser. I also like the fact that every recorded action has a corresponding visible script text that can be edited by hand.

After you use the record and play for a few times, the next big road block that you have to get over is to learn how to select elements on the web page especially if it has a complicated nested structure, does not have an id or in case of using third party libraries such as extJS, the ids can change with each run.

In that case, I have found xpath to be very powerful. Below are some examples of the locators. Note that if an expression can return more than one element, the first element is returned by default. You can also use [1], [2] etc. to get a specific element.

  1. If you know attribute value of an element

    //div[@id='xyz']: selects the div whose id is exactly xyz

  2. If the attribute value should contain a string

    //div[contains(@id, 'xyz')]: matches divs whose id attribute contains the string xyz

  3. If you want to select an element inside another one

    //div[contains(@id, 'xyz')]//div[@id='abc']: matches div whose id is abc and is contained in a div whose id contains the string xyz in it.

  4. If you want to match on the text in an element

    //a[text()='My Text']: matches a link whose text is “My Text”

  5. If you want to match more than one string in attribute or text

    //a[contains(text(),'Bill') && contains(text(), 'Clinton')]: matches a link whose text contains both Bill and Clinton. You can use any xpath function or operator to create your expression

  6. Find the nth element of a type

    //div[position()=3]: matches the third div on the page

    //div[@id='abc']//table[position()=3]: matches the third table inside the div whose id is abc

As a complicated example consider

//div[@id='editClaimPopupPanelDiv']//div[contains(@class,'x-grid3-row')][1]//table//tr[1]/td[1]

This find the div whose id is editClaimPopupPanelDiv. Inside div(s), the first div whose class attribute contains x-grid3-row is matched. Inside this div the first table is matched inside which the the first row and then the first td is matched.

Some functions you might find useful are (excerpted from the w3 spec):
String Functions

  1. string concat(string, string, string*) : The concat function returns the concatenation of its arguments.
  2. boolean starts-with(string, string) : The starts-with function returns true if the first argument string starts with the second argument string, and otherwise returns false.
  3. boolean contains(string, string) : The contains function returns true if the first argument string contains the second argument string, and otherwise returns false.
  4. string substring-before(string, string) : The substring-before function returns the substring of the first argument string that precedes the first occurrence of the second argument string in the first argument string, or the empty string if the first argument string does not contain the second argument string.
  5. string substring-after(string, string) : The substring-after function returns the substring of the first argument string that follows the first occurrence of the second argument string in the first argument string, or the empty string if the first argument string does not contain the second argument string.
  6. string substring(string, number, number?) : The substring function returns the substring of the first argument starting at the position specified in the second argument with length specified in the third argument.

Node Selection Functions

  1. number last()
  2. number position() : position of selected element

For a detailed review of xpath see the w3 spec

Hiring by small companies for success in India

India has been in the limelight in the context of outsourcing of software development jobs for many years now. The outsourcing process started with business process outsourcing (BPO) with the activities like call centers. It expanded later to outsourcing software development, maintenance and QA jobs to India.

As more and more companies moved to India, a major issue has been and still is being felt in the areas of hiring and retaining good people. Culturally, Indian engineers have gravitated towards larger companies like IBM, Oracle, Google. And due to the huge demand for limited talent, typical engineers have developed a knack for jumping jobs to gain increases in their compensation packages. In this context, smaller companies including startups are finding it hard to acquire good people.

I am experiencing similar issues in the hiring for people for my company, Arlak. We develop web applications hosted at infodoro.com. I have had some early successes. The strategy that has worked for me is to hire people who are early in their careers. The key is to look for people who are hungry to grow and hungry to learn. Find people who have the fire in their belly even though their skills are still not yet up to par. Then, nurture them, mentor them and educate them just like you would a young engineer in the US. Treat them with respect as people and as professionals. Give them challenges and important work, not just work that you don’t want your US engineers not to do. In one of my previous jobs, we outsourced mundane work that we wanted to protect our US engineers from and the low quality of people and the work produced was a reflection of this attitude.

In some ways, the selection of enthusiastic and willing people for small companies is a self-selecting process. Given the current environment, the people whom you will be able to attract to your small company will be the ones who are hungry to grow. You have to make sure that you have the commitment and the will to mentor these cubs.

Stumble it!

Software Development Tools and Infrastructure

Creating an effective infrastructure for the software development process can make a huge difference in the productivity of any team. In today’s environment of distributed and global development, it is even more important that the right tools for the creation, capture and preservation of knowledge and intellectual property are put in place from the outset.

We have found the following tools to be help teams of software developers.

Source Control System (SCS)

The product of a software development process is source code. All the investment and effort of the process ultimately goes towards producing this asset. Therefore, it is important that the source code is protected on an ongoing basis. However, a source control system is more than just a backup. It needs to aid in the development process by providing features such version management, roll-back, and support for branching.

A set of desirable features for a source control system are:

  • Maintenance of version history: The SCS should be able to maintain the version of each check-in to the code so that the state of the code as it existed at an earlier time can be recreated as necessary.
  • Atomic commits: The SCS should support atomic commit so that a commit failure does not leave the SCS in an inconsistent state.
  • Support secure Internet access: The SCS should support access in a secure manner over the Internet so that distributed teams can collaborate.
  • Efficient Branching and Tagging: The development team should be able to tag any revision as a significant revision. During the development process, it will be necessary to branch the code for operations such as development of a new version and bug fixing. The SCS should provide support for creating and new branches and for merging. In particular, good SCSs will create a lazy copy for a branch so that multiple identical copies of files are not created.

There are a number of commercial SCS (Perforce, Clear Case, Microsoft Source Safe) as well open source SCSs (Subversion, CVS).

We have used Subversion with success in co-located as well as distributed teams.

Bug or Issue Tracker

Where there is code, there are bugs!

An effective bug and issue tracking system is critical to build and maintain quality of code. It is important to be able to log issues and defects as they arise so that decisions as to the priority and scheduling of the issue can be made.

A good bug/defect/issue tracker system should support:

  1. Simple user interface
  2. Search and filtering capability
  3. Notification system
  4. Support for work flows
  5. Access control
  6. Integration with source control system
  7. Custom Fields
  8. Monitoring capability

There are a number of commercial (ClearQuest, BMC Desk Express, JIRA) and open-source issue tracking (e.g., Bugzilla, Mantis) systems

We have found Mantis, an open-source tracking system to be an effective system providing all of the above features.

Continuous Integration

The traditional model of breaking your development into modules, developing the modules independently and then, late in the development cycle, integrating them into one whole system is fraught with finding incompatibilities and system-level issues late in the process when everyone is in a crunch. Most often, it leads to schedule slippages, buggy software and unhappy customers.

Continuous Integration (CI) is a means of reducing the chances of finding surprises late in the development cycle. CI involves building the latest code into a package to make sure that the code at least compiles and any recent changes have not caused compile failures. In addition, a good CI process should deploy the code as well as run automated tests to catch regression failures due to new changes in the code.

CruiseControl is a popular continuous integration tool that supports automated builds and test integration. It also supports a web-based console for the tool.

Wiki

A wiki is a collaborative communication tool. Simply put, it is a website that can be edited by authorized users using the web interface itself. Most wikis support versioning so that any old version of the edited page can be viewed or recovered. Wikis provide a simplified mark up language so that an editor can created a formatted page with different formatting elements such font styles, indentations, and tables.

A wiki provides a mechanism for the team to create areas of discussion. The informal nature of content creation on a Wiki encourages team members to create content more rapidly and keep them more current than in more formal documents. In addition, the web nature of the tool make the wiki available to every member of the team irrespective of location and time. In addition, a wiki always provides the latest version of the document as opposed to documents created as MS Word files or in some such desktop tool.

There are a variety of commercial (Confluence, SocialText) as well as open-source (e.g., MediaWiki) wikis.

Automated Testing System

For any project of significant value, the number of tests to perform feature, acceptance and regression testing will grow in to the thousands. In many cases, the ability of the QA team to run these tests becomes a gating factor for how quickly and how often new features can be released. I speak from experience!

The good news is that a large percentage of these test can be automated resulting in significant savings in human effort. And since it is much cheaper and easier to put additional computers into service than hiring new QA personnel, automating tests has a great return on investment.

There are a number of test automation levels (unit testing, acceptance testing) and tools (Junit, Winrunner, WATIR).

Test Tracking System

A test tracking system is an important tool for a Quality Assurance (QA) team. This tool lets the QA team keep track of the test cases to test a product in a systematic manner. These tools let the team organize the test cases in test scripts and test plans. Good test tracking systems also integrate with the bug tracking system This way failed tests can be linked to bugs when when fixed get reflected in the test case. Also, integration into a test automation system enables the running of the test cases and updating the pass/fail status of the system.

In summary, installing a set of collaboration tools and using them in a disciplined manner can increase the productivity of a software development team significantly. And, most tools are now available in open source form, there by reducing the investment into these tools.