Incremental Scope Analysis using gmStudio


The Problem

One of the most important tasks for an upgrade project is planning how to implement and deliver the upgrade work in a way that accelerates project velocity to produce initial results that users can understand and test. This article describes an approach for using gmStudio to facilitate planning an incremental upgrade that delivers a large system in pieces – engaging users earlier and avoiding a "big bang" deployment at the end of the effort.  Note: there are several ways to do this, but this approach assumes you want to move to production subsets of functional new code and phase out the old system incrementally.

Planning an Incremental Transition

Upgrade project scope may be described in terms of the legacy AS-IS and the desired TO-BE states of the system. Many teams begin with a simplistic requirement: "we want to upgrade from VB6 to .NET". OK... but the problems are in the details and the "VB6 to .NET" requirement must be unpacked and defined in detail.The AS-IS side of the scope can be revealed by static analysis on the legacy system code. The TO-BE scope requires analysis and decisions regarding options -- ROI, risk, etc. And even after you have pinned down your AS-IS and TO-BE, you must still answer the question of HOW: how will you do the work (schedule, staffing); how will you use gmStudio; how will you verify results; and how will you transition the new system to your users in production?

The question of transition can be particularly difficult.  Large systems that have emerged over decades of development usually contain hundreds of forms and numerous complex operations done by dozens of different types of users. Most organizations are not comfortable with a "big bang" transition where the newly upgraded system replaces the legacy system in its entirety all at once. These organizations prefer an incremental transition that impacts one group of users at a time, often along functional/departmental lines. The order and nature of technical work needed to enable an incremental transition can be determined by the following steps:

1) functional scope definition: users identify functional parts of the system they use and how they use them (e.g., user stories)
2) functional scope prioritization: users set the desired order for transitioning functional parts of the system into production
3) technical scope analysis: for each functional part, and in the order desired, the technical team must identify the technical upgrade features needed to support the transition.

Identifying Technical Upgrade Features for Incremental Transition

The functional view of a system is a black box: it describes what the system does but does not explain the technical platform services behind the scenes.  However, system modernization is deliberately based on technical objectives.  To determine technical scope from functional scope, one must look inside the box.  Figuring out where in the box to look can be done using four features of gmStudio:

1) VB6 Instrumentation
2) Reference Reporting
3) Source GUI Scan Reporting
4) Source Scan Reporting

VB6 Instrumentation

VB6 Instrumentation is the process of adding logic to a VB6 application such that running the application reveals information about what is happening behind the scenes. Properly instrumented code can be used in two ways:

  • running the instrumented VB6 to determine which methods are executed for a given application function
  • running both the instrumented VB6 and its translation side-by-side to create trace logs to help analyze behind the scenes differences.

This process will modify each VBP by adding a reference to a module called containing the settings and functions for logging services.
The process will also modify every VB6 code file referenced by each VBP adding trace logging calls to the subs and functions. Note,
properties are not instrumented, but this could be added by modifying instrument.gmsl.

gmStudio includes a facility for instrumenting a VB6 system. Two files are used:

  • instrument.gmsl: a gmSL script that contains logic for instrumenting VB6 code
  • instrument.xml: a gmPL script that specifies the set of VBPs referencing the VB6 code to instrument

The steps for using these scripts are as follows:

1) Make a backup of the original source so you can restore and rerun
   the instrumentation as needed.

2) Copy this file and instrument.gmsl to the usr folder in your workspace.

   Optionally, you may edit instrument.gmsl to set the logging option:
   
   Const ProfileOnly As Boolean = True ' True: unique method names only, False: all calls
   
   NOTE: using ProfileOnly=false can generate very large logs 
   and significantly slow running the VB6 code.
   
   For scope analysis, set ProfileOnly=true. The resulting log file will 
   contain the methods executed.  The methods will be listed only once 
   and in the order they were executed.

3) Add this script as a task to a gmProj file. (i.e. InstrumentApp.gmproj)

4) Edit this script adding a <Load Project> command for each VBP 
   you wish to instrument.

	<Load Project="C:\gmClients\App\proj1.vbp" />
	<Load Project="C:\gmClients\App\proj2.vbp" />
   ...
	<Load Project="C:\gmClients\App\projN.vbp" />

5) Execute the script (i.e. Run the Translate operation on this script in gmStudio).

   This will produce a bundle file (*.bnd) containing the instrumented VB6 code files:
   
   a) Authoring a proj_gmTraceLogger.bas module in each VBPs folder
   b) Referencing the proj_gmTraceLogger.bas module from each proj.VBP
   c) Modifying every function and sub with logic to write trace messages 
      to a log file.

   By default the trace files are written to C:\temp\gmTraceLogger_vb6.log; 
   you must have access to the log directory to run the application. 
   You may change the location of the log file by altering instrument.gmsl.    
      
6) Deploy the bundle; this will replace original VB6 files with instrumented VB6 files.

   WARNING: This process modifies the VB6 code in place.

7) Verify the instrumented code.
   a) Rebuild the original VB6 to make sure it is still all well formed
   b) Compare the original and instrumented VB6 files to be comfortable with the changes

8) Translate the instrumented VB6 to produce a corresponding instrumented .NET code.

   Tip: you may want to modify your application translation script by adding 
   an Author/Fix so that VB6 logs and .NET trace  logs will not clobber each 
   other, for example:
   
   <Author...>
      <Fix name="General Fixes" host="">
         <Replace name="rename trace logger file">
         <OldBlock><![CDATA[gmTraceLogger_vb6.log]]></OldBlock>
         <NewBlock><![CDATA[gmTraceLogger_net.log]]></NewBlock>
         </Replace>
      </Fix>    
   </Author>

9) Run side-by-side tests to compare functionality and use the trace logs
   to help you analyze behind the scenes differences.
See instrument.xml in the sample rules folder for the latest notes on using these scripts

Reference Reporting

gmStudio generates .NET code from a detailed model of the source code and other inputs. This model is extremely detailed and may also be used to generate other outputs including the References Report. Each Reference Report record provides information on both the type of symbol referenced and also the location where the reference is made. Reference Reports only include references in logic code, not in GUI designer code. Reference Reports are tab-delimited files that can be very large. They may be loaded into a relational database system to facilitate analysis.

Source GUI Scan Reporting

gmStudio can produce detailed reports of the GUI designer information in a VB6 code. Each GUI Scan Report record provides information on both the type of GUI designer property being set and also the location where the property is set. GUI Scan Reports are tab-delimited files that can be very large. They may be loaded into a relational database system to facilitate analysis. GUI Scan Records must be combined with Reference Report records to create a comprehensive body of reference data including both logic code and GUI designer code.

Source Code Scan Reporting

gmStudio can produce detailed reports of locations of patterns in a VB6 code. The default set of patterns used with this report can be used to identify the locations of potential language incompatibilities in the VB6 code.  Each Code Scan Report record provides information on both the type of pattern found and the location where the pattern is found. Code Scan Reports are tab-delimited files that can be very large. They may be loaded into a relational database system to facilitate analysis.\


GUI References

The activity logging based on methods executed is missing a key piece of information: the work needed to layout and initialize forms based on their designer code.  Form layout/initialization all done by the VB6 runtime without executing a user-define methods.  It uses is in a special type of user code that is not maintained directly by the VB6 programmer, but is still crucial to the behavior and appearance of the desktop application.  These GUI references must be included when planning the work needed to complete the upgrade and they must be included in the estimation effort.  

Using the Trace Logs with gmStudio Reports

The reports described above contain information for an entire VBP or set of VBPs. This is useful for identifying the overall AS-IS state of a legacy application. This overall AS-IS information is a critical factor in planning the upgrade project, but it does not lend itself to identifying subsets of work needed for each functional subset of the system. In order to get a subset of AS-IS state, we must use the method list produced by the instrumented code and use it to filter the reports.  The various reports filtered on the list of methods in the trace log, provides details on the COM, Win32, and potential language incompatibilities in the subset of source code executed in the functional test.  The upgrade solution must address these issues in order to make the .NET code meet coding standards and ready for functional testing.  Addressing the issues means doing things like replacing COM/Win32 APIs with .NET APIs, reworking language incompatabilities and making other structural changes and optimizations.  

Assuming the reports have been loaded into a relational database, the method list may be used as shown in the following query:

declare @TestCase [nvarchar](255)
set @TestCase = '%'

--/*
---------------------------------
select distinct -- COM/Win32 LOGIC
---------------------------------
	TestCase 'TestCase',
	case r.MemType
	when 'Declaration' then 'WIN32'
	else  'COM'
	end 'Category', 
	MemLibr, Memclas, MemName, MemType--, SrcName, LocName, LocMemb, LocText
from 
	anaref r 
	inner join liblookup l on (r.MemLibr = l.LibName or r.MemType = 'Declaration')
	inner join ScopeMethods m on  (r.srcName+'.'+r.locname+'.'+r.locmemb = m.Method)
where (1=1)
	and l.src = '3PC'
	and memlibr <> 'VB' 
	and m.TestCase like @TestCase
	--and MemLibr+'.'+MemClas+'.'+MemType+'.'+MemName = 'ADODB._Parameter.Lib_Property.Value'
---------------------------------
UNION -- COM/VB6 GUI
---------------------------------
select distinct 
	TestCase 'TestCase',
	'COM' 'Category', 
	MemLibr, Memclas, dbo.Word(MemName,'(',1) 'MemName', MemType--, SrcName, LocName, LocMemb, LocText
from 
	anaref r 
	inner join ScopeMethods m on  (r.srcName = dbo.Word(m.Method,'.',1) and r.locName = dbo.Word(m.Method,'.',2))
where (1=1)
	and MemType like 'GUI%'	
	and (not memName like 'Client%')
	and (not memname in ('_StockProps','_ExtentX','_ExtentY','_Version','LinkTopic','Left','Top','Height','Width','_ctor'))
	and (not (memClas = 'SSTab' and loctext like 'Tab(%'))
	and (not MemClas = 'Font')
---------------------------------
UNION -- Language Issues
---------------------------------
SELECT distinct
	TestCase 'TestCase',
	'LANG' 'Catagory',
	MemLibr, MemClas, MemName, MemType--,SrcName, LocName, LocMemb, LocText
FROM 
	SrcScan s
	inner join ScopeMethods m on  (s.srcName+'.'+s.locname+'.'+s.locmemb = m.Method)
where (1=1)
	and m.TestCase like @TestCase
 
')

Final Thoughts

The analysis work described above allows the Upgrade Team to break upgrade planning into more manageable, understandable pieces. It can provide AS-IS context to help the team focus and prioritize the TO-BE and HOW decisions required to estimate the project.  AS-IS, TO-BE, and HOW decisions impact the cost, risk and effort of the project. Estimating the full effort may still be difficult for several reasons. For example, the first increment in an incremental transition requires more behind the scenes technical, procedural, and business decisions. It is a good idea to limit the functionality of the first increment to allow getting all of this worked out. Also, beware that not all increments of a legacy system are equal: some increments will bring new types of technical upgrade challenges while others will be technically the same as those already completed. And, since the increments are, by definition, different in terms of functionality, testing procedures and effort can vary significantly. Also, one should expect project efficiency to increase as the Upgrade Solution and the Upgrade Team mature. The bottom line is this: accurate project estimation requires synthesis of many difficult-to-quantify variables.  The approach here will help provide some scale and organize that work but you must still account for the details of your specific requirements and organization.