Automation-assisted manual transformations
Posted by danielmeyer on January 18, 2010
I had been unit testing an SQL generator and had a bunch of tests that gave various input to the generator and tested its output against expected SQL. The SQL in my tests looked like this:
Now I was ready to feed the SQL to a database engine to verify that it was validly formed. I would generally use grep for this type of task; but here my SQL statements were formatted multiline for easier reading, and grep operates in a line-by-line mode. There were over 100 test cases, so it was worth figuring out an automated solution. I also wanted to avoid writing a single-purpose text-processing utility if possible.
I ended up writing down the following steps for myself:
- Turn the tests into a single line of text for ease of working with tools
On command line:cat Test*.cpp | tr -d "\n\r" > all-one-line.out - Discard everything but the queries, inserting a newline after each
In editor (SlickEdit for me), open all-one-line.out and Replace All (using Perl-style regexes):
.*?("SELECT[^;]+?;)
with
\1\n - Clean up what the regex didn’t
Delete the last line - Get rid of quotes
Replace\"with nothing - Get rid of semicolons
Replace;$with nothing - Get rid of extra spaces
Replace <space>+ with <space> - Save the file in the editor
- Get rid of Oracle-specific tests
grep --invert-match TO_DATE < all-one-line.out > all-one-line.cooked - Let cool for 5 minutes before serving
Pasteall-one-line.cookedinto MS SQL Server Management Studio and execute (with Results to Text)
This may look like a large number of steps, but I got to where I could run through them in about 30 seconds and test all 130 queries on the server. Nice!
Future improvements
Once I had the ability to test my test output against the database server, I wanted to do that each time the tests’ expected results changed. So where I had originally envisioned a single smoke test run, I ended up going through these automation-assisted manual steps ten or twenty times. In retrospect, the single-purpose utility script would clearly have been the better approach after all. I need to get more comfortable whipping up such scripts to lower the barrier to writing them when these occasions arise.
Twelve years in, I would think I would be at the top of my craft by now, but there are still things that seem pretty basic that I’m learning. Hmmm…I wonder if life really does begin at 40?
Posted in Technical Stuff | Tagged: automation, efficiency, experience, grep, regex | Leave a Comment »
Those red thingies with the X in them
Posted by danielmeyer on January 7, 2010
Sometimes the hardest part about finding the solution to a problem is finding the right terminology with which to characterize the problem.
I have been using SlickEdit 2009’s Build command to build my C++ project. The major reasons I commonly kick off the build from within the IDE (as opposed to from the command line) are:
- I can double-click on an error and jump to it; and
- Little red thingies with an X in them appear along the left side of the editor window, providing a quick visual of where the errors are on the current screen:

(It would be even nicer if there I could also get a view of where all the errors are in the current file, like Eclipse (or was it WinMerge?) provides.) I can hover over one of the red thingies to see all the errors for that line.
Today, the red thingies weren’t there. I could still build; I could still double-click on errors in the captured build output in the Build window; but I had to actually read things because the helpful visual wasn’t there.
Error Markers
It turns out that the red thingies with an X in them are called error markers, and you can manually call the set-error-markers command (hit Esc to get the SlickEdit command prompt) to make them show up. (I didn’t want to have to do this manually every time I build, though it is pretty intriguing to have access to such business logic functions.)
In the end, I was able to get the error markers to show up automatically again…by simply restarting SlickEdit.
Acknowledgments
These posts to the SlickEdit forums helped me get to the right terminology and find the set-error-markers command.
Posted in Technical Stuff | Tagged: C++, SlickEdit | Leave a Comment »
AQTime for C++ code coverage analysis
Posted by danielmeyer on December 23, 2009
There’s an area of the system that I’m about to make big changes to. I had started off by creating characterization tests as a way of understanding how the current system works while also weaving a safety net that will quickly give me feedback on the effects of my code changes.
I have a good suite of tests and was to the point where it would be helpful to me to know what areas of the code are still not exercised by any tests. I was hankering for a code coverage tool. I had tasted the goodness of EclEmma in Java/Eclipse land — “Is there anything available for C++?” I wondered.
I resisted stopping to learn a new tool.
I worried that support for C++ might be clunkier, less seamless than what I had experienced in Java.
I wondered what the company approval process would involve to purchase a license.
BUT, the alternatives seemed to be:
- Visually trace through my existing tests to get an idea of the code coverage, or
- Proceed without knowing what can break without the tests showing it
The tedium and error-proneness of alternative 1 combined with the spectre alternative 2 presented of an extended stabilization time trying to figure out afterwards what my code changes had caused overcame my reluctance, worries, and wonderings. Besides, if I could get a code coverage solution in place, next time I could conceivably just use it, whereas if I do alternative 1 or 2 this time I’ll be faced with this same dilemma next time.
OHHHHkay. I was moved to go ahead and try to figure this out.
Not as bad as I thought
It didn’t turn out nearly so bad as I feared.
When I asked around internally I found that as a company we already have some experience with a product called AQTime from a company called AutomatedQA.
Having gotten a license, I installed AQTime 6.3.0.
(Let me pause to mention that I find the approval process here to be remarkable. The IT department seems to have something in common with Jimmy John’s: “Service so fast you’ll freak”.)
1. Gathering the Coverage Data
I looked confusedly and dazedly at a few tutorials, then decided to just try something. Following is what I did (minus the dead ends and rabbit trails):
- (Previously) Had written a suite of unit tests (using the Boost unit test framework) and built the test executable (it might need to be a debug build)
- Dropped to a command prompt and ran the command we use to set up environment variables for our build environment
- Started AQTime from that command prompt (otherwise the DLLs needed by the test executable were not in the path, so AQTime was not able to start the executable)
- File -> New Project From Module… -> browsed to the unit test executable
- Selected the Coverage Profiler (I think the default was the Performance Profiler)
- In the Setup tab on the AQTime main window, expanded the tree view of my executable. In my case, my tests focus on the contents of one .obj file, so I context-clicked on that and said Add Selected to Area -> Add to New Area…

(The profiling level needs to be set to “Line” for code coverage profiling (the default is Routine level)) - Pressed the Run button (the program run lasted 10 or 12 seconds instead of the usual of about 2 seconds from the command line)
2. Displaying the Results
I initially had trouble finding the visual coverage output with the source code. It is available — I got to it thusly:
- Went to AQtime’s Results tab
- Double-clicked the thread under Last Results -> Source Files
- Selected the source file in the Report tab
- Clicked Editor in the Analyze Results panel
This Editor window provided just what I had envisioned. Now I can quickly see what’s covered, sometimes covered, and not covered. I browsed through, looking for red dots.
The first coverage gaps I saw were in error logging code:
I knew that my tests were probably not exercising these error logging sections, but this is a good confirmation and reminder to me. Those sections being lower risk, I’m not sure whether I’ll take the time to exercise them all… now I can make a more informed decision.
More interestingly though, here is a whole branch I didn’t realize I wasn’t testing:
This coverage check quickly showed me five to ten such branches that lack tests. These are areas where if I made changes to the production code, I could too easily miss finding out about the breakage. Good to know about them!
And next time I want a test coverage check, I shouldn’t have to go through all the preliminaries. I’m glad to have a coverage checker in place.
Acknowledgment
I found the AQtime application help to be quite…helpful in getting up and running, as I was not familiar with the concept of an “area” or how to get to an editor.
Posted in Technical Stuff | Tagged: AQTime, C++, code coverage, profiling | 1 Comment »
The Magic SysRq key
Posted by danielmeyer on December 8, 2009
Have you ever wondered of what use the SysRq key is?
While working on my dual monitor setup, I tried several paths that led to an unresponsive X session (black screen). Ctrl+Alt+[1-6] didn’t work; Ctrl+Alt+Backspace didn’t work; so I did a hard reboot (and after unplugging a monitor so that I could get back into X, I set my default runlevel to 3 in /etc/inittab till I could figure out what was going on!)
While researching, I stumbled upon a post in a forum for Ubuntu users where someone suggested holding down Alt+SysRq and typing S, U, B (sync all mounted filesystems, remount filesystems readonly, reboot). Next time I had X in an unresponsive state, I tried it. What do you know, it worked!
Turns out it’s the Magic SysRq Key feature of the Linux kernel.
I don’t think my wife would appreciate the beauty of this magic key combination (she remains unconvinced about the amazing utility of Ctrl+Shift+Alt+PgDn for shutting down the computer from an X session without prompts :) , but for a keyboard shortcut connoisseur like me it was a fun find.
Posted in Technical Stuff | Tagged: Linux | Leave a Comment »
Dual monitors in Mandriva
Posted by danielmeyer on December 8, 2009
There’s a lot of context to keep in my head when I do my C++ work. I wanted to be able to be productive when I work from home, and decided on a two-monitor setup toward that end.
I bought an NVidia GeForce 9500 GT dual DVI output board by EVGA (512MB DDR2, PCI Express 2.0, SLI Support, (Dual Link) Dual DVI), an Acer X233H LCD monitor capable of 1920×1080 resolution, and an eMachines E202Hwmd LCD monitor capable of 1600×900 resolution.
First Try
After installing the new card, I hooked up both monitors to the DVI outputs and fired up Mandriva 2009.1. It booted, but when X started the first screen went black (I think the other one never powered on).
The Ril Dil
Unplugging the video cable for the second monitor enabled me to reboot and get back into X. I tried some things to use the open source “nv” driver and I think it would work, but after working with it for a while I decided to try the (proprietary) nvidia driver. To do this, I ran Mandriva Control Panel, went into “Set up the graphical server”, and chose “GeForce 6100 and later”. When MCC alerted that a proprietary driver was available, I selected it. In the options, I chose to “Enable duplicate display on the second display”.
Now, as root, I ran the nvidia-settings program and set up the displays:
Here is the xorg.conf file that nvidia-settings generated for me:
# nvidia-settings: X configuration file generated by nvidia-settings # nvidia-settings: version 1.0 (mandrake@n2.mandriva.com) Sun Oct 18 07:57:16 EDT 2009 # File generated by XFdrake (rev ) # ********************************************************************** # Refer to the xorg.conf man page for details about the format of # this file. # ********************************************************************** Section "ServerLayout" Identifier "layout1" Screen 0 "Screen0" 0 0 InputDevice "Keyboard0" "CoreKeyboard" InputDevice "Mouse0" "CorePointer" EndSection Section "Module" Load "dbe" # Double-Buffering Extension Load "v4l" # Video for Linux Load "extmod" Load "glx" # 3D layer Disable "dri" EndSection Section "ServerFlags" # allows the server to start up even if the mouse does not work #DontZoom # disable <Ctrl><Alt><KP_+>/<KP_-> (resolution switching) Option "DontZap" "False" # disable <Ctrl><Alt><BS> (server abort) Option "allowmouseopenfail" Option "Xinerama" "0" EndSection Section "InputDevice" # generated from data in "/etc/sysconfig/keyboard" Identifier "Keyboard0" Driver "kbd" Option "XkbLayout" "us" Option "XkbModel" "pc105" EndSection Section "InputDevice" # generated from default Identifier "Mouse0" Driver "mouse" Option "Protocol" "auto" Option "Device" "/dev/psaux" Option "Emulate3Buttons" "no" Option "ZAxisMapping" "4 5" EndSection Section "Monitor" # Monitor preferred modeline (60.0 Hz vsync, 67.5 kHz hsync, ratio 16/9, 95 dpi) Identifier "monitor1" VendorName "Plug'n Play" ModelName "Acer X233H" HorizSync 30.0 - 94.0 VertRefresh 49.0 - 75.0 ModeLine "1920x1080" 148.5 1920 2008 2052 2200 1080 1084 1089 1125 +hsync +vsync ModeLine "768x576" 50.00 768 832 846 1000 576 590 595 630 ModeLine "768x576" 63.07 768 800 960 1024 576 578 590 616 ModeLine "1920x1080_120" 368.76 1920 2072 2288 2656 1080 1081 1084 1157 -hsync +vsync ModeLine "1920x1080_100" 302.02 1920 2072 2280 2640 1080 1081 1084 1144 -hsync +vsync ModeLine "1920x1080_85" 252.93 1920 2064 2272 2624 1080 1081 1084 1134 -hsync +vsync ModeLine "1920x1080_75" 220.64 1920 2056 2264 2608 1080 1081 1084 1128 -hsync +vsync ModeLine "1920x1080_60" 172.80 1920 2040 2248 2576 1080 1081 1084 1118 -hsync +vsync ModeLine "1920x1080_50" 141.45 1920 2032 2232 2544 1080 1081 1084 1112 -hsync +vsync ModeLine "1600x900_120" 255.69 1600 1728 1904 2208 900 901 904 965 -hsync +vsync ModeLine "1600x900_100" 208.90 1600 1720 1896 2192 900 901 904 953 -hsync +vsync ModeLine "1600x900_85" 174.79 1600 1712 1888 2176 900 901 904 945 -hsync +vsync ModeLine "1600x900_75" 152.28 1600 1704 1880 2160 900 901 904 940 -hsync +vsync ModeLine "1600x900_60" 119.00 1600 1696 1864 2128 900 901 904 932 -hsync +vsync ModeLine "1600x900_50" 97.04 1600 1680 1848 2096 900 901 904 926 -hsync +vsync ModeLine "1368x768_120" 185.67 1368 1472 1624 1880 768 769 772 823 -hsync +vsync ModeLine "1368x768_100" 151.73 1368 1464 1616 1864 768 769 772 814 -hsync +vsync ModeLine "1368x768_85" 125.67 1368 1456 1600 1832 768 769 772 807 -hsync +vsync ModeLine "1368x768_75" 110.19 1368 1456 1600 1832 768 769 772 802 -hsync +vsync ModeLine "1368x768_60" 85.86 1368 1440 1584 1800 768 769 772 795 -hsync +vsync ModeLine "1368x768_50" 69.92 1368 1424 1568 1768 768 769 772 791 -hsync +vsync ModeLine "1360x765_120" 182.63 1360 1456 1608 1856 765 766 769 820 -hsync +vsync ModeLine "1360x765_100" 149.22 1360 1456 1600 1840 765 766 769 811 -hsync +vsync ModeLine "1360x765_85" 124.65 1360 1448 1592 1824 765 766 769 804 -hsync +vsync ModeLine "1360x765_75" 108.34 1360 1440 1584 1808 765 766 769 799 -hsync +vsync ModeLine "1360x765_60" 84.40 1360 1424 1568 1776 765 766 769 792 -hsync +vsync ModeLine "1360x765_50" 69.34 1360 1416 1560 1760 765 766 769 788 -hsync +vsync ModeLine "1280x720_120" 161.56 1280 1376 1512 1744 720 721 724 772 -hsync +vsync ModeLine "1280x720_100" 131.85 1280 1368 1504 1728 720 721 724 763 -hsync +vsync ModeLine "1280x720_85" 110.01 1280 1360 1496 1712 720 721 724 756 -hsync +vsync ModeLine "1280x720_75" 95.65 1280 1352 1488 1696 720 721 724 752 -hsync +vsync ModeLine "1280x720_60" 74.48 1280 1336 1472 1664 720 721 724 746 -hsync +vsync ModeLine "1280x720_50" 60.47 1280 1328 1456 1632 720 721 724 741 -hsync +vsync EndSection Section "Monitor" Identifier "Monitor0" VendorName "Unknown" ModelName "Acer X233H" HorizSync 30.0 - 94.0 VertRefresh 49.0 - 75.0 EndSection Section "Device" Identifier "device1" Driver "nvidia" VendorName "nVidia Corporation" BoardName "NVIDIA GeForce 6100 and later" Option "DPMS" Option "TwinViewOrientation" "Clone" Option "TwinView" Option "AddARGBGLXVisuals" EndSection Section "Device" Identifier "Device0" Driver "nvidia" VendorName "NVIDIA Corporation" BoardName "GeForce 9500 GT" EndSection Section "Screen" Identifier "screen1" Device "device1" Monitor "monitor1" DefaultDepth 24 SubSection "Display" Depth 8 Modes "1920x1080" "1600x900" "1366x768" "1360x765" "1280x720" EndSubSection SubSection "Display" Depth 15 Modes "1920x1080" "1600x900" "1366x768" "1360x765" "1280x720" EndSubSection SubSection "Display" Depth 16 Modes "1920x1080" "1600x900" "1366x768" "1360x765" "1280x720" EndSubSection SubSection "Display" Depth 24 Modes "1920x1080" "1600x900" "1366x768" "1360x765" "1280x720" EndSubSection EndSection Section "Screen" Identifier "Screen0" Device "Device0" Monitor "Monitor0" DefaultDepth 24 Option "TwinView" "1" Option "TwinViewXineramaInfoOrder" "DFP-1" Option "metamodes" "DFP-0: 1920x1080 +1600+0, DFP-1: nvidia-auto-select +0+0; DFP-0: NULL, DFP-1: 1600x900 +0+0; DFP-0: NULL, DFP-1: 1280x720 +0+0" SubSection "Display" Depth 24 EndSubSection EndSection
Before X initializes, only one monitor is active (the one plugged in to DVI-0, I think). I plugged the Acer monitor into DVI-0 so if for some reason I’m not booting X I get the larger monitor; but in nvidia-settings I picked the eMachines monitor as my primary monitor so that the KDE taskbar is over on that monitor, leaving the Acer monitor fully free for an rdesktop session.
Posted in Technical Stuff | Tagged: Linux, X | Leave a Comment »
The return of chui red/green indicators
Posted by danielmeyer on December 2, 2009
Automated unit testing is not yet to a mature state here on the C++ side. We’re kind of just getting started*. Part of just getting started is a lack of tool support. Funny – when Jon talked about the importance of maintaining a readiness to create tools that streamline the work in your specific project or environment, I wasn’t sure if he was on track or not. How important is it, really?
Then I realized that I’m doing the same thing in my current environment. So I guess either I’m as crazy as Jon** or Jon’s onto something here. :)
On to my issue. Our C++ unit test support is currently command-line based, and it puts out a lot of text to the screen. I found I was having to carefully cull through a few screens of data looking for what went right or wrong. It was too much work for each test run. I decided to colorize. ANSI escape sequences to the rescue! (putting to use our research from before.)
The script
# chuiredgreenbar.py
#
# Purpose: Colorize the output of dmake runtest to highlight passing and failing tests.
# Author: Daniel Meyer
# Version: 0.1
# Date: 10/28/2009
#
# Usage:
# dmake runtest 2>&1 | python c:\bin\chuiredgreenbar.py | cat
#
# TODO: Figure out a way to get ANSI escape sequence support without cat (On my XP machine, cmd.exe doesn't
# seem to natively support the ANSI escape sequences; cat works around this).
import sys, re
def green_bar(s):
return chr(27) + "[32;40m" + s + chr(27) + "[0m"
def red_bar(s):
return chr(27) + "[31;40m" + s + chr(27) + "[0m"
pass_pattern = re.compile("passed")
fail_pattern = re.compile("([0-9]+).+[0-9]+ (failed|aborted)")
for raw_line in sys.stdin:
line = raw_line[:-1]
result = fail_pattern.search(line)
if result:
if result.group(1) == 0:
print green_bar(line)
else:
print red_bar(line)
elif pass_pattern.search(line):
print green_bar(line)
else:
print line
The command line
Filter the output of dmake through this script with the following command line (cover your eyes):
dmake runtest 2>&1 | python c:\bin\chuiredgreenbar.py | cat
Example output
Observations
- The red background is not part of the highlighting – that’s another tool thing I won’t get into here.
- I barely know Python
- The super hacky part is having to pipe the output to cat to get ANSI escape sequences interpreted (not to mention merging stderr in with stdout since some of dmake’s output goes one place, some the other and we need to process both)
This warty construction is “in production” on my PC – I use it ‘most every day. If it weren’t for something like this, I would probably still be straining my eyes to see which test cases failed. Perhaps eventually there will be a graphical UI for the Boost unit test output; but till then, this was an efficient way to fill a need.
*I could look at this negatively, but hey – I get to be part of bringing this discipline to my company, and besides that, there’s openness to the idea. Smells like opportunity to me!
**I would consider that designation an honor. We need more of that kind of crazy in the industry!
Posted in Technical Stuff | Tagged: Boost, C++, unit testing | 1 Comment »
The main problem was…
Posted by danielmeyer on November 19, 2009
Just having started at a new company recently, up to this point I had only contributed to an existing C++ project; but yesterday I needed to create a new one myself. After getting a basic makefile put together and putting some necessaries in the precompiled header, I bumped into a couple of linker errors:
link.exe @C:\DOCUME~1\DANIEL~1.MEY\LOCALS~1\Temp\mk1178003 /out:"DebugU\MyUtilityUD.exe" LINK : DebugU\MyUtilityUD.exe not found or not built by the last incremental link; performing full link Creating library DebugU\MyUtilityUD.lib and object DebugU\MyUtilityUD.exp main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) int __cdecl ir::recorderserver::ace_os_main_i(class ACE_Main_Base &,int,char * * const)" (__imp_?ace_os_main_i@recorderserver@ir@@YAHAAVACE_Main_Base@@HQAPAD@Z) referenced in function "int __cdecl ir::recorderserver::wmain(int,wchar_t * * const)" (?wmain@recorderserver@ir@@YAHHQAPA_W@Z) msvcrtd.lib(wcrtexe.obj) : error LNK2019: unresolved external symbol _wmain referenced in function ___tmainCRTStartup DebugU\MediaStatusGenUD.exe : fatal error LNK1120: 2 unresolved externals
I had a main() function. Did ACE expect _wmain() ? Or some weird ace_os_main_i()?
No, I had just placed my main() function inside a couple of namespaces rather than at the global level. Doh! Of course, main() needs to be declared in the global namespace.
Noting here so next time I don’t spend an hour of futile fiddling with the makefile for this. ;)
Posted in Technical Stuff | Tagged: C++ | Leave a Comment »
Calvin on software
Posted by danielmeyer on November 19, 2009
Institutes of the Christian Religion, John Calvin’s master work, is arranged in four volumes. Book I is titled “Of the Knowledge of God the Creator” and deals with the natural created order and God’s providence; Book II is “Of the Knowledge of God the Redeemer” and deals with salvation and redemption…
I’d been working my way through Book I recently — the teaching about providence has been such an encouragement to me with what’s been going on lately! I generally take a low view of playing games with a text and taking things out of context…but as a programmer I did do a double-take when I saw Calvin speaking of classes and objects:
…there being as many miracles of divine power, as many striking evidences of wisdom and goodness, as there are classes of objects, nay, as there are individual objects, great or small throughout the universe. (Book I c. XIV s. 21)
: )
Posted in Fun | Tagged: context | Leave a Comment »
Fencing
Posted by danielmeyer on November 14, 2009
I have thought for some time that it would be fun to learn fencing. Today I found out what can make fencing a VM so helpful.
A bit of background: We have a VMWare virtual machine farm. Someone sets up a VM with one of the nightly builds, and then developers or testers can clone those VMs for their own testing. Nice! The one snag is the IP address – if you simply clone the machine, the address will conflict with every other clone on the network. There are two ways around this.
The unfenced route:
- Discard the state of the config
- Open the config and go to Properties of the VM
- Delete the NIC and add a new one
This has the disadvantage, though, of you having to discard the state of the machine first (having the effect of setting it back to a power-off state? something like that?) All other things being equal, this would not be a big hardship, but when we’re testing on nightly builds, the system can be a bit fragile (ok, really fragile) and there can be issues restarting all our subsystems and getting them into a happy enough state to test. Whoever it is that sets up the VMs from the nightly builds gets the subsystems running and that’s the state in which they save the VM. I was losing that work when I discarded state to go the unfenced route. Then I had to spend time getting the subsystems running myself. Waste o time!
Instead, when you deploy the VM you can just check the Fenced box, and then the server farm somehow does address translation, finding an IP address unused by any of the other clones. Thus you don’t have to go to the minor work of deleting and re-adding the NIC, and more importantly (for us anyway) you also don’t have to discard the state and redo someone else’s work getting the system into a stable state for testing. Nice!
Posted in Uncategorized | Leave a Comment »







