Applies to: BizTalk Server 2006 with the HL7 1.3 Accelerator

  1. Outline of the problem
    1. Trailing Delimiters are empty values at the end of an object in a HL7 ER7 formatted message.
    2. Examples:
      1. Empty Field
        1. NTE|P|
        2. NTE|P||
      2. Empty component
        1. ORC|1|725^
      3. Empty Subcomponent
        1. ORC|1|||||27&
      4. Empty repeat
        1. OBR|1||||||||027~
    3. Trailing delimiters indicate the following object exists and is empty, which is quite different from null, null is an explicit value indicated by a pair of double quotes -> "".
    4. The BizTalk HL7 Accelerator by default does not allow trailing delimiters.
  2. There are three methods to allow trailing delimiters.

    NOTE: All Schemas always allow trailing delimiters in the MSH Segment

    1. Using party identifiers
      1. MSH3.1 – Receive/inbound processing, using this value as a party allows you to configure the system to allow inbound trailing delimiters.
      2. MSH5.1 – Send/outbound processing, using this value as a party allows you to configure the system to allow outbound trailing delimiters.
      3. Generally, if you allow inbound trailing delimiters, unless you are willing to programmatically remove all trailing delimiters, then you need to configure the send to allow trailing delimiters.
      4. Add the appropriate parties to the BizTalk Parties list from these two fields in your message stream.
      5. Open the BizTalk HL7 Configuration tool and for each party check the "Allow trailing delimiters (separators)" check box on the Validation tab.

      Disadvantage – Each MSH3.1 and MSH5.1 value must be represented in the parties list and configured.

      Advantage – granular control over system behavior for each inbound/outbound system.

    2. Using instance properties of a pipeline used in a send port or receive location.
      1. Open the BizTalk Server Administration console
      2. locate the send port or receive location that contains the BTAHL72XReceivePipeline or BTAHL72XSendPipeline pipeline.
      3. Open the properties
      4. To the right of the pipeline selected locate the […] ellipses button
      5. In the property list, locate the "TrailingDelimiterAllowed" property and set it to True.

      Advantage – All messages through a particular Send Port or Receive Location will allow trailing delimiters.

      Disadvantage – Must configure each Send Port or Receive Location. No granular control over which remote parties will send or receive messages with trailing delimiters.

    3. Using a custom pipeline that uses a pre-configured BTA HL7 Pipeline component.
      1. Use Visual Studio to construct a custom receive and send pipeline using the appropriate assembler or dissasembler.
      2. Set the component property to "TrailingDelimitersAllowed" to True
      3. Compile and deploy the custom pipeline
      4. Use the custom pipeline instead of the standard pipeline for all HL7 message processing

      Advantage – All messages using the custom pipeline will automatically allow trailing delimiters.

      Disadvantage – Requires custom coding and development to create and deploy the custom pipeline. No granular control over which remote parties will send or receive messages with trailing delimiters.

    4. What does a Trailing Delimiter do to the XML Schema?

      Allowing trailing delimiters does not have the impact often expected in the actual XML Schema.
      The Schema reproduces the message with no data loss.
      Thus, the message when represented in XML must contain the extra fields, in order to reproduce the outbound message.
      Thus, a trialing delimiter results in an empty XML field.
      Trailing Delmiters are not stripped from the inbound message.

      Example:
      <PID_21>44172</PID_21>
      <PID_21>9257</PID_21> -> the original maximum number of repeats
      <PID_21></PID_21> -> The empty repeated field

    5. Allowing trailing delimiters not remove the trailing delimiters from the message, it simply suppresses the check that will cause the message to fail parse with trailing delimiters.
  3. When can you not fix the problem by enabling trailing delimiters
    1. Each object in a message must have a location in the target BTAHL7 schema for its content to reside.
      If you have more objects in the message than are contained at that location, then enabling trailing delimiters will not resolve the problem. The schema must be extended to accommodate the empty message content.
      Examples:
      1. Extra Field

        NTE|P||||
        Only 4 fields in NTE Segment, the 4th field exists, but is empty.

      2. Extra component

        PID|1|1523|47^^^^^^^
        Only 5 components in a CX data type, the 5th component exists, but is empty

      3. Extra subcomponent

        ORC|1|||||27&&
        Only 2 subcomponents in a CQ data type, the 3rd subcomponent is empty, but exists.

      4. Extra Repeat

        PID|1||||||||||||||||||||4419~5217~
        Only 2 repeats allowed for the field "Mother's identifier", the repeat is empty, but exists.

    2. In each of these cases, you must locate the failing object and extend the type to allow an additional object of that type.
  • Field
    Add a field of ST to the end of the segment with a suitable name in the segments_nnn.xsd
  • Component

    Create a new Custom CX data type (i.e. CX_XtraComp) in the datatypes_nnn.xsd and add a new component to the custom CX data type. Update the field in the segments_nnn.xsd file to use the custom data type instead of the standard datatype.

  • Subcomponent

    Create a new Custom CQ data type that accepts an additional TS value at the end of the data type. Create a custom TQ data type that uses the new custom CQ data type as the first subcomponent. Modify the ORC segment to use the new CQ data type at ORC.7 instead of the standard CQ data type.

  • Repeat
    Modify the Field definition for PID.21 in the segments_nnn.xsd to allow more repeats in the field.

 

The Distinguished Field is often seen as the weaker of the two types of Fields when handling Fields in BizTalk.

After all, the Distinguished Field can’t be used as a filter on a message, and it’s slower than its big brother the Promoted Field.

Well, today I’m here to dispel the myth of the wimpy Distinguished Field and place in the pantheon of power that equals, and in some ways exceeds the Promoted Field.

MYTH: Getting the value of a Distinguished Field requires loading the entire message into memory.

The first myth that we need to dispel is that the Promoted Field is a quicker field to access than the Distinguished Field.

This is due to the statement in the BizTalk Documentation, and I quote:

The BizTalk Server Message
… Lots of stuff cut out …
“One of the benefits of promoted Fields is that the value of the element that is promoted is available in the context of the message. This means that retrieving that value is inexpensive, as it does not require loading the message into memory to execute an XPath statement on the message.”

What is implied here is that for the Promoted Field reading its value doesn’t require an XPath read into the message and conversely, that the Distinguished Field does require loading the message and has a performance cost because it’s evaluated when queried.

Nothing could be further from the truth! In fact, the both the Promoted and Distinguished Fields are evaluated at the same time, and both are placed in the message context at the same time. So, let’s talk about how fields get into the message context.

About BizTalk Message Context Fields
… Lots of stuff cut out...
“Since Distinguished fields do not require a separate property schema, the evaluation of Distinguished fields by the Orchestration engine consumes less overhead than the evaluation of Property fields by the Orchestration engine. The evaluation of Property fields requires an XPath query, the evaluation of Distinguished fields does not require an XPath query as the pipeline disassembler populates the Distinguished fields in the context and the orchestration engine gets the cached values. However, if the orchestration engine does not find the property in the context, it will then evaluate the XPath query to find the value. Distinguished fields do not have a size limitation.

Now, how does Promoted and Distinguished Fields get into the Message Context? This occurs automatically in the Receive Pipeline by certain pre-built pipeline components?

Out of the box, the BizTalk XML Disassembler, BizTalk Flat File Disassembler and the BizTalk Framework Disassembler Promote Fields to the message context. All other production level Pipelines promote fields, most also support Distinguished Fields.

Distinguished Fields are written to the Message Context if one of these Receive Pipeline Components is used in the Pipeline. Interestingly enough, this explains why the Passthrough pipeline doesn’t promote Fields from the message, there are no components in the Passthrough Pipeline, it does nothing to the message content and therefore nothing gets promoted, especially BTS.MessageType.

As far as performance, Distinguished Fields beat out Promoted Fields 9 days each week. This is because both Promoted and Distinguished require the same overhead of writing the message value to the context Field bag in the Message Box, but Promoted Fields have the additional overhead of both being written to the Message Box context database AND the Subscription database. Promoted Fields have an impact every time a message is written to the Message Box because each Promoted Field that exists musts be evaluated in a massive union (very efficiently written union mind you!) that builds the list of matching activation subscriptions. So in short, the more Promoted Fields that you have the costlier the subscription process.

RECOMMENDATION: Use Promoted somewhat sparingly, don’t avoid them, but do not use them if you do not need to. Use Promoted Fields as they were designed, to facilitate message routing, but not to make it easy to access a message value. Instead primarily use Distinguished Fields.

MYTH: Its always safe to use a Promoted or Distinguished Field in an Orchestration.

Using Operators in Expressions

exists test for the existence of a message context property BTS.RetryCount exists Message_In

Let us talk about how to handle message content that is missing when it is a Promoted Field and a Distinguished Field. What we are talking about specifically is the field that was Promoted or Distinguished did not exist in the inbound message. The XLANG/s xpath statement that was used to query the message for the content during pipeline processing returned a null object.

The first thing to understand is when a Promoted and Distinguished Field comes into existence. They are essentially the same, and this occurs when a Pipeline component parses a message and either Promotes or Writes the value to the context. The simple answer is, when the value does not exist, the Field is not created. A query to the context for the Field returns a null object.

So, if you attempt to access a Promoted or Distinguished Field that didn’t exist in the inbound message, you can cause an unhandled exception to be thrown. Specifically in both cases a NullReferenceException.

Promoted Fields, have a special XLang/s test exists (see my previous blog post in this) that you can use to determine if they exist before attempting to use them. In this case, Promoted Fields can always be tested for existence before use and can safely be avoided when they don’t exist.

Unfortunately, Distinguished Fields don’t have such a special test, and can cause an unpreventable unhandled exception. Specifically if you use a Field that the underlying type is a native non-nullable type. For instance, suppose the value that you have distinguished is a integer. Integers cannot be null (and yes, I am aware of the Nullable<T> generics, but we are talking about what BizTalk XLANG/s has, not what is C# has) and if the underlying value didn’t exist and you attempt to use the value, or even test to see if the value exists will cause an unhandled NullReferenceException when BizTalk’s XLang engine attempts to convert a null value into an integer by calling the System.Number.Parse(string) method with a null value.

Here comes in the kicker and why a Distinguished field can appear to be fine at design time, but bite you at run-time.

At design-time the expression editor generates a pseudo class-like dotted object for you to use in your expression. At run-time there is simple type-casting that occurs by the run-time engine that inspects the XML datatype of the node in the Schema, retrieves the value as an object… then attempts to call the appropriate ConvertTo method on the Object. When casting a Null to an Int32 or anyother intrinsic datatype, a NullReferenceException is thrown and the Orchestration fails.

The primary difference (excluding Routing) between Promoted and Distinguished Fields is the developer design-time experience. Distinguished Fields are easy to use because they emulate .Net Class dotted notation.

RECOMMENDATION: If there is any chance that accessing the Distinguished Field may cause an exception, then place the check in a Scope Shape that has a catch shape to handle the NullReferenceException.

MYTH: Distinguished Fields are only accessible in Orchestrations

WRONG Documentation: Field Schemas
RIGHT Documentation: Distinguished Fields in Disassembler Pipeline Components, Processing the Message, Promote Properties (Node Property of All Schemas)

Another major fallacy about Distinguished Fields is that they are only accessible in the Orchestration. This is also untrue, the BizTalk Server Documentation clearly has an example of how to use Distinguished Fields in any component from the RIGHT Documentation above.

All Distinguished Fields outside of an Orchestration use a fixed schema:
http://schemas.microsoft.com/BizTalk/2003/btsDistinguishedFields

The Field to use is the XPath of the node that is Distinguished such as:
/*[local-name()='PO' and namespace-uri()='http://SendHtmlMessage.PO']/*[local-name()='Price' and namespace-uri()='']

Thus to access this you would use the Read Method:
MyObject = MyMessageContext.Read("/*[local-name()='PO' and namespace-uri()='http://SendHtmlMessage.PO']/*[local-name()='Price' and namespace-uri()='']", " http://schemas.microsoft.com/BizTalk/2003/btsDistinguishedFields”);

If the Field exists, then MyObject will contain an object that can be cast to the appropriate type.

RECOMMENDATION: Once a the proper Pipeline Component has processed the message, use the Distinguished Field as you would any Field without the Xpath lookup overhead.

MYTH: Distinguished Fields in Orchestration Expression shapes are actually code.

You have to hand it to the people who did the coding for XLANG/s. It looks like C#, it feels like C# and 99% of the time it pretty much generates standard C#.

In many ways, this is not your father’s C#, it is really XLANG/s and it has it’s own syntax and special components. Distinguished Fields are a prime example.

Think back on all the times you used a distinguished Field. It feels like it’s a C# Object! It uses dotted notation (Node.Node.Node.Attribute). You assign values to it, you use it’s value in an expression and it comes out as the correct type. When the node is Boolean, then it behaves like a Boolean. Nothing could be further from the actual behavior. Just because it looks like a duck, doesn’t mean that it’s a duck. It really is a trick, that the Expression Editor parses the XSD on the fly and generates a classlike editor experience, but no actual code ever gets generated.

Further Reading

1) Planning and Architecture > BizTalk Server Architecture > Runtime Architecture > The BizTalk Server Message

2) Planning and Architecture > BizTalk Server Architecture > Runtime Architecture > Processing the Message

3) Developing BizTalk Server Applications > Creating Pipelines Using Pipeline Designer > About Pipelines, Stages, and Components > Distinguished Fields in Disassembler Pipeline Components

4) Creating Orchestrations Using Orchestration Designer > Creating Orchestrations > Using Expressions in Orchestrations > Using Operators in Expressions

5) Creating Schemas Using BizTalk Editor > About Schemas > Different Types of BizTalk Schemas > Field Schemas

6) Creating Schemas Using BizTalk Editor > About Schemas > Ways to Use Message Content to Control Message Processing > About BizTalk Message Context Fields

7) Schema Property Reference > Node Properties - Alphabetical Listings > Node Properties of All Schemas > Promote Properties (Node Property of All Schemas)

8) Creating Schemas Using BizTalk Editor > Creating Schemas > Promoting Properties > How to Copy Data to the Message Context as Distinguished Fields

Property Field values are stored in a database, and therefore have more overhead than Distinguished Fields. Distinguished Fields do not require any additional storage; they are essentially an alias for an XPath, thereby allowing orchestrations to more easily access the relevant values directly from the message.

NOTE:

The variable PropExists as bool has been already created

The Property of interest is BTS.RetryCount

The Message is Message_In

The list from Using Operators in Expressions (http://msdn.microsoft.com/en-us/library/aa561847.aspx) has the typical list of stuff that you expect in C#, multiplication, bit operations (shift left and right) and Boolean operators, but a couple of extremely useful constructs are available that are unique to BizTalk.

The most important of these (in my humble opinion) is the exists operator.

As you are all aware, to even check whether a property exists in an expression throws an exception… as in the following case:

PropExists = (Message_In(BTS.RetryCount) != null && Message_In(BTS.RetryCount) != "");

If BTS.RetryCount does not exist in the message context, then the MissingPropertyException (Windows Event Log Event ID 10019) is thrown.

Without having to resort to a scope shape and exception handler, the exists operator allows you to check if a property exists in a message and is used in the following format:

PropExists = BTS.RetryCount exists Message_In;

OR

if (BTS.RetryCount exists Message_In)

{

     …;

}

Conclusion:

Using the XLANG/s exists operator in your orchestration allows you to test for the existence of a property in a message without having to resort to a scope shape and exception handler.

Below are a few of more XLANG/s functions that can provide some value in your Orchestrations:

Operator

Description

Example

checked()

raise error on arithmetic overflow

checked(x = y * 1000)

unchecked()

ignore arithmetic overflow

unchecked(x = y * 1000)

succeeded()

test for successful completion of transactional scope or orchestration

succeeded(<transaction ID for child transaction of current scope or service>)

exists

test for the existence of a message context property

BTS.RetryCount exists Message_In

I'm sure that over time you've run into the dreaded "File transport does not have read/write privileges for receive location "C:\Flatfile\SAPTestIn\".".

Usually you simply go to the folder and either give the BizTalk account full permission (bad) or Everyone full permission (really bad).

So for a production environment, what is the absolute minimum permissions required?

For the Receive File Adapter the explicit permission are:

NTFS Attribute

Property Name

DELETE

Delete Files

FILE_READ_DATA

List Folder / Read Data

FILE_WRITE_DATA

Create Files / Write Data

FILE_APPEND_DATA

Create Folders / Append Data

FILE_READ_EA

Read Extended Attributes

FILE_WRITE_EA

Write Extended Attributes

FILE_DELETE_CHILD

Delete Subfolders and Files

FILE_READ_ATTRIBUTES

Read Permissions

FILE_WRITE_ATTRIBUTES

Write Attributes

How does this translate into what to do in the System?

Right clicking on the folder and in the security tab,
setting "Modify" is not enough, though you would think so:
clip_image002

Strangely enough the Delete Subfolders and Files attribute is not set when the Modify property is set, you need to add the
FILE_DELETE_CHILD "Delete Subfolders and Files" Attribute:
clip_image004

Once you have added the Delete Subfolders and Files check box you will have the minimum permissions for the file receive adapter:
clip_image006

For the Send Adapter

The permission for the File Send adapter depends on what properties you have set in the Adapter Advance properties:
clip_image008

If you have the "Use temporary file while writing" flag un-checked then all you need are:

NTFS Attribute

Property Name

FILE_WRITE_DATA

Create Files / Write Data

 

clip_image010

If you have the "Use temporary file while writing" flag checked then the flags you need are:

NTFS Attribute

Property Name

DELETE

Delete Files

FILE_WRITE_DATA

Create Files / Write Data

FILE_DELETE_CHILD

Delete Subfolders and Files

FILE_READ_ATTRIBUTES

Read Permissions

 

clip_image012

Back in 1980 or so, I attended the Naval Nuclear Propulsion Training and in January, after nearly two years of training, I was stationed on the USS Bremerton (SSN 698) and after another year of training finally got my dolphins.

During the course of training, one would be frequently asked seemingly inane questions about some trivial feature or object on the system that you were studying.

One example asked of me while I was studying at S1W in INEL was “Where is the red, white and blue valve?”. After weeks of searching, I finally found the valve, and here was my answer “Just forward of the Reactor Upper room, there is an entry into the Auxiliary Machinery Mezzanine. As you step through the entry going forward, there is a plate embedded in the floor. If you lift that plate, under it is another plate attached to a retention chain. Once you lift the second plate, the red, white and blue value is actually just aft of the opening.” At that point the person would sign off my “qual card” for the area I was actually examining for.

What was the point here? As it was explained to me, the training was not just to get you to memorize tons of information about the reactor, the auxiliary systems and operations. It was to get you to “learn it yourself”. An attempt to get you to actually dig into the books, crawl into every nook and cranny and find out what and where this information was.

Where did the term “ooly” (sometimes uli and ooley) come from? As was told that on the original drawings for S1W, the “Reactor Fresh Water Coolers” on one plan was misspelled “Reactor Fresh Water oolers” and to prove that you had actually read, and deeply understand the plan, the question at that time was “Where are the oolers and what do they do?”.

Thus the phrase “ooly” became the technical term for a deep detail about something that took a lot of research to dig out.

NOTE:

The variable PropExists as bool has been already created

The Property of interest is BTS.RetryCount

The Message is Message_In

The list from Using Operators in Expressions (http://msdn2.microsoft.com/en-us/library/aa561847.aspx) has the typical list of stuff that you expect in C#, multiplication, bit operations (shift left and right) and Boolean operators, but a couple of extremely useful constructs are available that are unique to BizTalk.

The most important of these (in my humble opinion) is the exists operator.

As you are all aware, to even check whether a property exists in an expression throws an exception… as in the following case:

PropExists = (Message_In(BTS.RetryCount) != null && Message_In(BTS.RetryCount) != "");

If BTS.RetryCount does not exist in the message context, then the MissingPropertyException (Windows Event Log Event ID 10019) is thrown.

Without having to resort to a scope shape and exception handler, the exists operator allows you to check if a property exists in a message and is used in the following format:

PropExists = BTS.RetryCount exists Message_In;

OR

if (BTS.RetryCount exists Message_In)

{

     …;

}

Conclusion:

Using the XLANG/s exists operator in your orchestration allows you to test for the existence of a property in a message without having to resort to a scope shape and exception handler.

Below are a few of more XLANG/s functions that can provide some value in your Orchestrations:

Operator

Description

Example

checked()

raise error on arithmetic overflow

checked(x = y * 1000)

unchecked()

ignore arithmetic overflow

unchecked(x = y * 1000)

succeeded()

test for successful completion of transactional scope or orchestration

succeeded(<transaction ID for child transaction of current scope or service>)

exists

test for the existence of a message context property

BTS.RetryCount exists Message_In

Recently I was working in the Staging environment at my current client.

A Debugging Opportunity occurred and I needed to trace into a Called Orchestration.

clip_image002

“No symbolic information was found for this orchestration. In the Visual Studio project containing the orchestration, set the Embed Tracking Information option to True. Rebuild and redeploy to enable tracking and debugging.”

I have NO idea how this came about, but after inspecting the properties of the Project and comparing it to a working Orchestration I noted something odd about the Project Properties.

In both DEBUG and RELEASE configuration the “Define TRACE constant” was unchecked. As soon as I checked this, rebuilt, redeployed the Assembly, the Orchestration Debugger started working.

image

I’ve talked about some features and issues with where I want to take the HL7 Accelerator.

Today’s post is more about why we should all care. After all, HL7 is a little protocol that some computers use to communicate, who cares?

In part, I want to talk about where HL7 stands in the world of it’s personal impact to you, your family and friends.

Have you seen a doctor recently? Maybe a family member had a check for swine flu, cholesterol or rheumatoid arthritis?

You have been touched by the HL7 Protocol. After all, where do you think your doctors gets the information from? That’s right, there is a diligent worker out there, that takes that sample of blood, skin or sputum and does some magic with it. The result is that they type in information into their Electronic Lab Notebook, or the device feeds it to the system.

From there, the path is somewhat convoluted. The LAB company (Quest, LABCORP and so on) then attempts to transmit that information electronically to your health care company… yes via HL7.

It then arrives, and they need to find you! What was your medical record number (oops, someone typed it in wrong) and update your electronic healthcare record (EHR).

There are many things that the EHR does, including billing your insurance company and so on, but as far as I’m concerned the NUT of the problem is, am I healthy!

The HL7 protocol was the first system to allow automatic updates on the patient health status.

When the CDC needs to be updated about a regional outbreak of some “notifiable” condition they get those results via an HL7 message.

So, the HL7 messaging system also tells us, is the country healthy?

HL7 Messages are the only electronic communication on the planet that could literally kill someone!

What if the HL7 message is delay, misrouted or misapplied.

Aunt Sally could be diagnosed with a terrible disease that requires aggressive treatment, when actually all she had was gout!

The HL7 protocol is not an idle, irrelevant hard to understand messaging protocol, but instead is a critical element in the rapid, and accurate diagnosis and management of the entire patient experience.

Science fiction has predicted killer computer programs, I have the honor of actually working with that on a daily basis.

HL7, take care, we love it, but we know it’s value.

My wife this weekend noted as she was reading CNET that WordPress had announced a vulnerability to a worm.

Well, actually, they announced that if you had skipped the last two releases, failed to do your updates, that you would be vulnerable to the worm.

The question often happens, not so much in the actual software development shops, but rather from the common user

How does this happen? They should find all the bugs before they ship!

 

I’ve thought about this question a lot. It really does seem somewhat straightforward.

Simply put, test the product before it ships, and don’t allow it to have bugs!

hmmm… let me think about that for a second.

A novel idea, but how do we actually do this? I’ve done professional software development for almost 20 years, and before that, self taught software development for 10 years. I should be the perfect candidate for building bug-free software, I can test it myself, I understand all the tricks.

I can’t do it, and it simply comes down to numbers.

 

Let me tell you a story.

About 12 years or so, as a fairly senior software tester, I was given the task of verifying a bug had been fixed in the software.

The test seemed pretty simple.

I had a field on a form, and the field was 16 characters long.

The bug was that if the first character in the form was not one of your US based letters, but rather something from a non-english language like French, that the letter would be ignored.

So, if the user typed in:

[ÅÅÅÅuter hansten]

The actual value would be:

[uter hansten    ]

 

This was pretty easy to test, I fired up my trusty GUI test engine, and wrote a quick little program that looped through all the valid characters and checked to see if they worked.

Being Friday afternoon, I thought giving the program the entire weekend to run would be ample time. I turned away from my test PC and back to my real machine, I suddenly paused.

I wondered, how many tests would this little program actually do?

Lets see… this math looks pretty simple.

Q: How many letters are in the alphabet that need to be tested?

A: This looks like I can safely say we need all the special letters, that was part of the problem, so 256 – 32 = 224 (this is a-Z, numbers, special characters, and the extended characters)

Q: How many characters in the field?

A: 16

Q: So, how many loops will I have to do?

A: 16 224 = 5.2 × 10 269

SCREECHING HALT… WHAT? WHAT WAS THAT NUMBER?

I happened to recall that a GOOGOL = 10 100 was a number larger  than the number of subatomic particles in the visible universe.

This number, the loops I had to do would NEVER complete by the end of the weekend, as a matter of fact, it would be quicker to count all those subatomic particles in the visible universe than to run this test.

I turned back to my test PC and canceled the test. (oh and for you code heads, I simply inspected the software and was able to reduce my test count to TWO test cases, rather than 5.2 × 10 269)

 

First off, I want the casual user to understand some very important things.

No software can bug free. Just look at the current software you are using to view this blog. It has many places that you can type in more than 16 characters. Every one of those places needs to be tested, but there is only so much time before the end of the universe as we know it (which is somewhere in the neighborhood of 37 years).

Secondly, even testing the software, and fixing every bug does not actually improve the quality of the software. Most bug fixing actually adds more bugs than it fixes.

Wait, what do you mean, when you fix a bug you have one less bug!

Yes, that bug may be fixed (and this is maybe, some attempts to fix a bug actually do not fix anything) but the new code to fix the bug may have bugs in itself.

I call this the (very similar to the Neutron Lifecycle in a nuclear reactor) the defect life-cycle.

Each cycle of the software starts with a fixed number of bugs.

As the software build for the next release approaches:

Current bugs exist in the software, let use call this value Bc (Bugs current)

Attempts are made to fix bugs that are known (the Bug List) and some of those are actually removed, let us call this value Pr (planned and removed)

Review of the software during the development cycle discovers unknown bugs, and these are attempted to be fixed, let us call this value Rr (reviewed and removed)

New features are added to the software, and these new features have bugs in them, let us call this value Na (New and added)

Attempts to fix bugs that are know cause additional bugs in the software, let use call this value Pa (planned and added)

Review of the software that discovers bugs, and the attempts to fix the bugs cause new bugs, let use call this Ra (reviewed and added)

The Bugs that remain in the product after a build is the result of this formula, and let us call this value Ba (Bugs after cycle)

So, for each internal build, the rate at which bugs are fixed is:

Ba = Bc – Pr – Rr + Na + Pa + Ra

So, if the Sum of the added bugs is less than Sum of the Bugs removed, then the quality of the software has improved.

Unfortunately this condition is actually rare! Most cycles of the build actually increase the number of the bugs, because the constant pressure of adding new features to the product, and attempts by the junior developers to fix bugs introduced by senior developers (who can’t be bothered to fix that old code). Often overwhelm the any bugs that are actually removed.

Please note, nowhere in this do the actual bugs found have a positive impact on the quality of the software, rather you could strongly argue that by finding bugs the team is practically guaranteed to be adding bugs and making the software worse.

How do we get out of this?

First off, make sure that you understand that software testing will never improve the quality of the software.

Actually, it is a measuring tool, a sounding rod.

If you are testing 10% of the product and you find 100 critical bugs, then it seems that your total critical bug count would be in the neighborhood of 1,000 bugs.

Make a judgement call at this point, can you, as the software company handle that support load?

Are you putting peoples lives at risk?

Many other relevant questions…

BUT at this point do not turn to your software test team and ask them… the sounding rod measures, it does not judge.

I’ve been running Windows 7 for only a short time now.

But in that, as a developer, I find that I avoid doing my development on my actual desktop.

Specifically, I have several customers today that run different versions of BizTalk Server from 2004 to 2009.

In addition, many of these customers require you to install VPN software that can wreck havoc with your most critical hardware asset you bring to the table, your personal laptop.

 

Let us examine a typical work flow that I have encountered several times.

I develop a clean bootable Windows Server 2008 Virtual machine on my Windows 7 Desktop

I ship the VHD to corporate, and they deploy it on our Hyper-V environment

Me and my team working remotely, share and update the system

I pull back the VHD and give it to the customer who is running Virtual PC 2007 SP1

 

For each of these stages, the migration process is the same.

  1. Uninstall the Integration Components (IC)
  2. At the command prompt, run the following command:
bcdedit /set {current} detecthal yes

 

What happened here?

The {current} value tells BCD to modify the currently running boot configuration.

The detecthal yes value tells to force a redetect of the of the hardware during boot

What will happen, is that at the next boot, the system will determine the best HAL to boot from and update the configuration to use it.

Thus, at boot, if the system has been moved from Hyper-V to Virtual PC, the HAL needed will change and the system will locate and update itself to use the new HAL.

This procedure should work for most optimizing Hyper Visors as they all require somewhat different HALs.