My Experiences with Requirements Traceability

August 3, 2011

With some positive feedback on my post on the Yahoo Test-driven Development group, I thought I’d post my comments here, to make them more accessible:

— abrar arshadwrote:

Yeah I know requirements traceability has always been related to formal requirements specification and in agile with don’t have formal documentation. … For instances, how do you know where to make changes if your client wants you to change a feature which already has been developed. There is a chance that changing one feature might effect the others as well. …

I was involved in Document-Driven approaches for quite a few years before joining the XP community. “Requirements Tracability” was always a promise of the document-driven approach, used in part to justify its high cost. But honestly, I have never seen it deliver as promised:

Requirements tracability advocates say that it will show you where to make a new change, and that it will highlight conflicting requirements. I have never seen this happen in practice.

Consider this example: We have a system that is computing hourly pay in several divisions at several union plants. There is a fair amount of hard-coded conditional code. We just renegotiated the overtime rates for one of the divisions at two plants.

For requirements tracability to be useful, it has to be easier to find the original requirements for these divisions and to trace these requirements down to code than it would be to find the code directly. And to see conflicts, one would have to go from all the requirements that are relevant to the code back to the requirements documents — and then somehow figure out what to do with a whole bunch of requirements statements — to see if they conflict or overlap in any way, and how to resolve the issues.

Generally, in practice, it’s pretty easy to find the relevant code, even without any external requirements documentation. It’s easier to find the code than to trace through a tangled mess of requirement number references.

And to make the change… Add or change tests. Then change the code so that it passes the tests. If there are conflicting requirements, other tests will fail. You’ll look at the other tests and probably learn something. Sometimes it’s a technical issue, easily solved. Sometimes it is a real conflict in the business requirements. In that case, you will probably have to go back to the business requirements and maybe to the people who specify them to resolve the business issue.

So requirements tracability is not only costly and quickly out of date, it turns out to not be very useful. About the only good thing I’ve seen requirements tracability do is to serve as a checklist of all the things the system must do: When they’re all checked off, then you have reason to believe that the system does everything that’s been requested. User stories with automated acceptance tests also do this — with much higher justifiable confidence levels.


What if your bug crashes the Mars rover?

January 23, 2011

In “This Developer’s Life” podcast “1.0.3 Problems” mentioned on Scott Hanselman’s blog

Regarding the “1.0.3 Problems” comments about how bad it would be to have written “the bug” that trashed a Mars rover:  I don’t think we have to speculate too much about hypothetical situations.  We have the Hubble telescope mirror, for instance:

http://en.wikipedia.org/wiki/Hubble_Space_Telescope#Flawed_mirror

and the Mars orbiter thing too:

http://en.wikipedia.org/wiki/Mars_Climate_Orbiter#Encounter_with_Mars

“Bummer, dude” is one possible response.


Lemp Haunted Mansion Tour

April 16, 2010

I went on the Lemp “Haunted” Mansion tour on Thursday night, led by members of a “supernatural investigation” group. A little over a dozen of us from the Saint Louis skeptics group went together on the tour. As skeptics, we had plenty of flashlights and cameras of our own. And we also played with two of our host’s infrared cameras.

http://www.lempmansion.com/lempExperience.pdf

I found the indoor aviary room (downstairs; part of the restaurant) most creepy, due to the dark painted outdoor scene. Unlike in my previous visit to the mansion, the gift shop was not freakishly cold this time. (The weather was different; previous trip was early winter, this trip was after a week of quite warm weather.)

It’s a nice bead and breakfast place: The two large 2nd floor rooms are very nice. I liked the cozy and modern bathroom in the Elsa Lemp Suite. I’d like to stay there.

http://www.lempmansion.com/bb.html

Being a caver, I am of course very interested in the cave under the mansion. Here is a very good site describing the cave:

http://www.trickykegstands.com/cherokeeCaveTour.html

Looks like when I stood on the 3×3 ft wood cover in the basement, I was probably standing right over a nasty 34 ft drop into the cave. Nice. Good thing I didn’t jump up and down on it. ;->

Here is a much better map of the cave than the one shown in the Lemp Mansion gift shop:

http://www.trickykegstands.com/media/cherokeeFull.jpg

(And the pool is properly marked on this map.)

Postcard from the old Cherokee Cave public tours shown at the bottom of this page:

http://www.stlouistimeportal.com/postcard_advertisement.htm

I have a VHS video tape that includes a legal visit to Cherokee Cave (and also the storm drains under Forest Park and the River des Peres. It’s a 50-minute KETC Channel 9 special called “Under St. Louis”, “St. Louis Chronicles”, 1998. “Produced in cooperation with the Missouri Historical Society.” I think it was a bonus sent to KETC members. (See it pays to be a contributing member of your local public TV and radio stations! ;-)

The eleven minute portion about Cherokee Cave is available on You Tube here:

Here’s a blog, with good pictures, of someone trespassing into the cave, a practice that is ILLEGAL and DANGEROUS!!!

http://sf0.org/MyrnaMinx/taskDetail/?id=816


Now Senior Technical Integration Consultant at Guidewire Software

January 22, 2010

I just accepted a position as a Senior Technical Integration Consultant at Guidewire Software, starting the first of next month.


Express-Scripts Layoff

January 3, 2010

Yes, I was part of the ESI layoff of 90% of contractors last month. I am working with Advantage Consulting and partners to find a new position.

As always, I am particularly interested in highly challenging and rewarding opportunities. And I am willing to take on a heavy travel schedule and to relocate.


Roller Coasters

June 20, 2009

The “Top Thrill Dragster” roller coaster at the Cedar Point Amusement Park in Sandusky, Ohio caught my eye recently. (One of my relatives spammed me with pictures of it. ;-)

Here are a few links:

For something a little slower, try this:

Found another… a “racing bicycle monorail”, the “Shweeb”, in New Zeland:


Caving Boots

April 3, 2009

The “Wellies” (Wellington boots) in the Facebook “Caving Gear” application inspired some brief conversations on good caving boots:

Some Wellington boots come with felt on the tread — which I’m told is good for traction on slippery rocks while fishing.

Some caving groups, such as the Chouteau Grotto, are known for using shoes with football cleats in very muddy caves like the Devil’s Icebox. And it occurs to me that this might be useful in Carol Cave as well — as long as the boots tie firmly enough to the foot as to not get pulled off when pulling feet out of mud! ;->

Last night at the Banff film festival, the “Canyoneer 2″ shoe, at five-ten was recommended. (See “Footwear -> Water” on their flash site.) Looks like it would hold onto the foot well, and keep most mud and sand out of the shoe. But the tread doesn’t look very ambitious. Maybe I should try these for my next pair of caving boots.


(A visitor was looking for OTB Footwear Sar Water Boots, so I thought I’d mention them.)


Bottom line: I have to recommend the Norcross Shrimp Boots, recommended by John Hargreaves.
(See comments.)


Start date at Monsanto

March 24, 2009

I have a start date to serve our customer, the research side of Monsanto, working through Comsys and Advantage consulting:  Monday, April 6th.

 

Monsanto is one of the best customers I’ve had the pleasure of working with, and I look forward to the opportunity to serve with them again.


Minor Fresh Concrete Crisis

March 17, 2009

Local color: They just poured concrete to repair the road outside my house this morning. Within seconds of them leaving, the neighbor’s youngest fell in it. I pulled him out by his feet; and while his parents washed him off, I caught the workers on the next street so they could fix the concrete. They said that things like this happen all the time. ;->

This one could be harder to explain to your supervisor, however:
Police car in fresh concrete (from this page)


The Pure Danger of Unfair Read-Write Locks

March 13, 2009

Attending the local No Fluff Just Stuff conference in Saint Louis on Friday, I raised a question during Alex Miller’s talk on Java Concurrency Idioms regarding the documented behavior of the ReentrantReadWriteLock of “A nonfair lock that is continously contended may indefinitely postpone one or more reader or writer threads, [...]

So I commented on Alex’s “Writing while reads pile up” blog entry, saying:

My question on Friday was regarding the potential for a sequential set of overlapping readers locking out a waiting writer forever. It seems that this could happen, as the JavaDoc explicitly says, “A nonfair lock that is continously contended may indefinitely postpone one or more reader or writer threads”.
The scenario I had in mind would work like this:
1. Reader 1 gets a read lock.
2. The writer requests a write lock, and is blocked.
3. Reader 2 requests a read lock — and let’s say they get it.
4. Reader 1 releases their read lock.
5. Reader 3 requests a read lock — and let’s say they get it.
6. Reader 2 releases their read lock.
As long as steps 5 and 6 are repeated as shown above, the writer would be delayed indefinately.
However, in writing tests for this, I’m finding that the ‘java.util.concurrent.locks.ReentrantReadWriteLock’ class has the (apparently undocumented) behavior that it stops granting read locks when a write lock is requested. So it appears that even in non-fair mode, readers will NOT block writers indefinitely. (…as long as every lock holder releases their lock within a reasonable period of time!)
What I find is that in step 3 above, Reader 2 is delayed until the writer gets, uses and releases the write lock. So the write does NOT get indefinitely postponed in this scenario.

Not wanting to keep secrets, I am posting here the code I’m using to come to this conclusion:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.junit.Test;

public class LockTest {
private List readThreads = new ArrayList();

@Test
public void runTest() throws InterruptedException {
final boolean isFair = false;
final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(isFair);
final ReadLock readLock = readWriteLock.readLock();
final WriteLock writeLock = readWriteLock.writeLock();

System.out.println(“===================================”);
System.out.println(“–> Start working read threads.”);
final int readersPerBatch = 5;
for (int idx = 0; idx Start blocking read threads.”);
for (int idx = 0; idx >> WRITE LOGIC HERE <<<”);
writeLock.unlock();
System.out.println(“Main: Released write lock.”);
System.out.println(“===================================”);

for (final Thread thread : readThreads) {
thread.join();
}
System.out.println(“===================================”);
System.out.println(“Done.”);
}

private void startReadLockThread(final ReadLock readLock, final int thisReaderNumber) {
final Thread thread = new Thread(new Runnable() {
@Override
public void run() {
final String messagePrefix = “Reader ” + thisReaderNumber + “: “;
System.out.println(messagePrefix + “Started.”);
sleepSeconds(1);
System.out.println(messagePrefix + “Asking for read lock.”);
readLock.lock();
try {
System.out.println(messagePrefix + “Has read lock.”);
System.out.println(messagePrefix + “‘Working’ with read lock.”);
sleepSeconds(6);
} finally {
System.out.println(messagePrefix + “Releasing read lock.”);
readLock.unlock();
}
}
});
readThreads.add(thread);
thread.start();
}

private static void sleepSeconds(double seconds) {
try {
final long milliseconds = Math.round(seconds * 1000);
Thread.sleep(milliseconds);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}

Sample Output:

===================================
--> Start working read threads.
Reader 1: Started.
Reader 3: Started.
Reader 2: Started.
Main: Sleeping.
Reader 5: Started.
Reader 4: Started.
Reader 5: Asking for read lock.
Reader 5: Has read lock.
Reader 5: 'Working' with read lock.
Reader 3: Asking for read lock.
Reader 3: Has read lock.
Reader 3: 'Working' with read lock.
Reader 1: Asking for read lock.
Reader 1: Has read lock.
Reader 1: 'Working' with read lock.
Reader 4: Asking for read lock.
Reader 4: Has read lock.
Reader 4: 'Working' with read lock.
Reader 2: Asking for read lock.
Reader 2: Has read lock.
Reader 2: 'Working' with read lock.
===================================
--> Start blocking read threads.
Reader 6: Started.
Reader 8: Started.
Reader 7: Started.
Reader 9: Started.
Main: Attempting to acquire write lock.
Reader 10: Started.
Reader 8: Asking for read lock.
Reader 10: Asking for read lock.
Reader 9: Asking for read lock.
Reader 7: Asking for read lock.
Reader 6: Asking for read lock.
Reader 2: Releasing read lock.
Reader 4: Releasing read lock.
Reader 1: Releasing read lock.
Reader 3: Releasing read lock.
Reader 5: Releasing read lock.
===================================
Main: Has write lock.
Main: >>> WRITE LOGIC HERE <<<
Main: Released write lock.
===================================
Reader 8: Has read lock.
Reader 8: 'Working' with read lock.
Reader 10: Has read lock.
Reader 10: 'Working' with read lock.
Reader 6: Has read lock.
Reader 6: 'Working' with read lock.
Reader 7: Has read lock.
Reader 7: 'Working' with read lock.
Reader 9: Has read lock.
Reader 9: 'Working' with read lock.
Reader 8: Releasing read lock.
Reader 6: Releasing read lock.
Reader 10: Releasing read lock.
Reader 7: Releasing read lock.
Reader 9: Releasing read lock.
===================================
Done.

Observe that the Main thread starts up five Reader threads, and waits for them to acquire read locks and start “working.” Main then fires up five more read threads and requests a write lock before the new threads request their read locks. Notice that the five new Reader threads WAIT until the first five threads finish, and the main thread acquires, uses and releases the write lock. And then the five Reader threads that have been waiting all get their locks, do their “work” and finish.

This is much better behavior than I had expected.


Follow

Get every new post delivered to your Inbox.