Chapter 9: Developing Phase: Deployment Considerations and Testing Activities

This chapter discusses the key development considerations for deploying applications migrated to the Microsoft® .NET Framework. It also discusses the testing activities involved in the Developing Phase. This chapter will help you identify the activities and milestones required to complete the Developing Phase.

On This Page

Deployment Considerations Deployment Considerations
Testing Activities Testing Activities
Interim Milestone: Internal Release n Interim Milestone: Internal Release n
Closing the Developing Phase Closing the Developing Phase

Deployment Considerations

To ensure a smooth deployment in the upcoming Deploying Phase, you need to address the following topics in the Developing Phase:

  • Process environment

  • Building the application in .NET

  • .NET deployment considerations

  • Instrumentation

The process for deploying the migrated application is discussed in detail in Volume 5, Deploy and Operate of this guide.

You can use the information provided in this section to identify implementation requirements, such as environment variables and system message logging, which need to be considered when creating the migrated environment in .NET.

Process Environment

This section describes the key elements of the process environment and highlights the notable differences in these elements between UNIX and .NET. The process environment contains the following key elements:

  • Environment variables

  • Computer information

  • Logging system messages

This section also provides the necessary information for setting up or retrieving various environment-specific details in the .NET environment.

Environment Variables

Every process has an environment block associated with it. An environment block is a block of memory allocated within the address space of the process. Each block contains a set of environment variables and their values. Both UNIX and Microsoft Windows® operating systems support the process environment blocks, although differences may exist depending on the supplier and the version of UNIX.

The .NET Framework provides an Environment class in the System namespace that provides information about, and the means to manipulate, the current environment and platform. You can use the Environment class to retrieve information such as command-line arguments, the exit code, environment variable settings, contents of the call stack, time since last system boot, and the version of the common language runtime (CLR).

The following C# code example accesses the environment block in .NET.

.NET example: Accessing the environment block

Note: Some of the lines in the following code have been displayed on multiple lines for better readability.

using System;
using System.Collections;
class Sample 
{
  public static void Main() 
  {
   String str;
   String nl = Environment.NewLine;
   Console.WriteLine("-- Environment members --");
   Console.WriteLine("ExitCode: {0}", 
   Environment.ExitCode);
   Console.WriteLine("MachineName: {0}", 
   Environment.MachineName);
Console.WriteLine("OSVersion: {0}", 
Environment.OSVersion.ToString());
Console.WriteLine("SystemDirectory: {0}", 
Environment.SystemDirectory);
Console.WriteLine("UserDomainName: {0}", 
   Environment.UserDomainName);
   Console.WriteLine("UserName: {0}", 
   Environment.UserName);
Console.WriteLine("Version of the CLR: {0}", 
Environment.Version.ToString());
String query = "My system drive is %SystemDrive% and 
my system root is %SystemRoot%";
   str = Environment.ExpandEnvironmentVariables(query);
   Console.WriteLine("ExpandEnvironmentVariables:
   {0}  {1}", nl, str);
Console.WriteLine("GetEnvironmentVariable: {0}  
My temporary directory is {1}.", nl,
   Environment.GetEnvironmentVariable("TEMP"));
   Console.WriteLine("GetEnvironmentVariables: ");
IDictionary    environmentVariables = Environment.
GetEnvironmentVariables();
   foreach (DictionaryEntry de in environmentVariables)
   {
       Console.WriteLine("  {0} = {1}", 
   de.Key, de.Value);
   }
  }
}

(Source File: N_ProcessEnv-UAMV4C9.01.cs)

Computer Information

At times, it is necessary to obtain information about a computer. This is particularly important when an application is designed to support multiple users or different types of hardware and operating systems. Some information that an application may require are:

  • The host name.

  • The operating system name.

  • The network name of the computer.

  • The release level of the operating system.

  • The version number of the operating system.

In UNIX, the gethostname and uname functions are used to obtain this information. In.NET Framework, there are two classes—the System.Environment class and the System.Windows.Forms.SystemInformation class—that provide the system information. The following code example in UNIX prints out the system information, such as the computer host name, node name, operating system release, and version number, to the console.

UNIX example: Printing the system information

Note: Some of the lines in the following code have been displayed on multiple lines for better readability.

#include <unistd.h>
#include <stdio.h>
#include <sys/utsname.h>
int main()
{
    char computer[256];
    struct utsname uts;
    if(gethostname(computer, 255) != 0 || 
    uname(&uts) < 0) {
        fprintf(stderr, 
    "Could not get host information\n");
        exit(1);
    }
    printf("Computer host name is %s\n", computer);
    printf("Nodename is %s\n", uts.nodename);
    printf("Version is %s, %s\n", uts.release,
    uts.version);
    exit(0);
}

(Source File: U_SysInfo-UAMV4C9.01.c)

The following example in C# displays some of the system information, such as the computer host name, domain name, user name of the currently logged on user, the operating system version number, and the current platform to the console using the System.Environment class. If you are developing a Windows Forms application, then consider using the System.Windows.Forms.SystemInformation class.

.NET example: Printing the system information

Note: Some of the lines in the following code have been displayed on multiple lines for better readability.

using System;
public class MySysInfo
{
    static void Main() 
    {
    //Creates an object of OperatingSystem class
    OperatingSystem obOS = System.Environment.OSVersion;
    //Displays the Host name of the Computer
    Console.WriteLine("Computer Name:{0}",
    System.Environment.MachineName);
    //Displays the Domain name of the computer
    Console.WriteLine("Domain Name:{0}",
    System.Environment.UserDomainName);
    //Displays the log-in name of the user 
    //currently logged in
    Console.WriteLine("Logged In User:{0}",
    System.Environment.UserName);
    //Displays the OS Version No(Major,Minor and 
    Revision No combined)
    Console.WriteLine("OS Version:{0}",
    obOS.Version.ToString());
    //Displayes the current platform
    Console.WriteLine("Platform:{0}",
    obOS.Platform.ToString());                
    }
}

(Source File: N_SysInfo-UAMV4C9.01.cs)

Note More information on the Environment class and its members is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemEnvironmentClassTopic.asp.
More information on the SystemInformation class and its members is available at
https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwindowsformssysteminformationmemberstopic.asp.

Logging System Messages

In UNIX, diagnostic messages are logged by writing the formatted output to the system logger. The diagnostic messages are written to the system log files, such as USERS, or forwarded to the appropriate computer. If a log daemon process is not running, the log information may be written to a standard log file, such as /var/adm/log/logger.

Table 9.1 lists the numerous levels of logged information contained in the daemon syslogd in UNIX.

Table 9.1. UNIX Logging System Messages

Priority

Description

LOG_EMERG

A panic condition.

LOG_ALERT

A condition that should be corrected immediately.

LOG_CRIT

Critical conditions, such as hard device errors.

LOG_ERR

Errors.

LOG_WARNING

Warnings.

LOG_NOTICE

Non-error–related conditions.

LOG_INFO

Informational messages.

LOG_DEBUG

Messages intended for debug purposes.

The .NET Framework provides an EventLog class that interacts with the Windows event logs. The EventLog class enables you to access or customize Windows event logs, which record information about important software or hardware events. Using EventLog, you can read from the existing logs, write entries to logs, create or delete event sources, delete logs, and respond to log entries. The CreateEventSource method is used to create an event source for writing entries to a log. While creating an event source, you can specify the name of the log such as application, security, system, or custom event log. The WriteEntry method can be used to write any customized message into the event source. The event type of the event log can also be specified in this method. This type can be one of the following examples listed in Table 9.2.

Table 9.2. .NET EventLog Class Event Types

Name of Event

Description

Error

This indicates a significant problem the user should know about, usually a loss of functionality or data.

FailureAudit

This indicates a security event that occurs when an audited access attempt fails.

Information

This indicates a significant, successful operation.

SuccessAudit

This indicates a security event that occurs when an audited access attempt is successful.

Warning

This indicates a problem that is not immediately significant but that may signify conditions that could cause future problems.

UNIX example: System logging

#include <syslog.h>
#include <stdio.h>
int main()
{
    FILE *fp;
    fp = fopen("Bad_File_Name","r");
    if(!fp)
        syslog(LOG_INFO|LOG_USER,"error - %m\n");
    fclose(fp);
    exit(0);
}

(Source File: U_SysLog-UAMV4C9.01.c)

The message in this example would be logged to /var/log/messages on a typical Linux system, to /var/adm/messages on a Solaris system, and to /var/adm/log/messages on Interix (when syslogd in running). Refer to the /etc/syslog.conf file for more specific information—specifically, a *.info entry that specifies the file where the preceding message will be logged.

.NET example: System logging

Note: Some of the lines in the following code have been displayed on multiple lines for better readability.

using System;
using System.Diagnostics;
using System.Threading;
class MySample{
    public static void Main(){
        // Create the source, if it does 
        // not already exist.
        if(!EventLog.SourceExists("MySource")){
            EventLog.CreateEventSource("MySource",
        "MyNewLog");
            Console.WriteLine("CreatingEventSource");
        }
        // Create an EventLog instance and 
        // assign its source.
        EventLog myLog = new EventLog();
        myLog.Source = "MySource";
        // Write an informational entry to the event log.    
        myLog.WriteEntry("Writing to event log.");
    }
}

(Source File: N_SysLog-UAMV4C9.01.cs)

If the log that you specify in a call to CreateEventSource does not exist on the computer, the system creates a custom log and registers the application as a source for that log. You can use the EventLog class to read and write entries to any event log for which you have the appropriate access. Figure 9.1 depicts a new log, MyNewLog, created using the CreateEventSource call. As the log did not initially exist on the computer, the log is created after running the Eventvwr.exe code.

Figure 9.1. Windows Event Viewer

Figure 9.1. Windows Event Viewer

Double-clicking the Information option in the Type column opens a detailed view of the event, as depicted in Figure 9.2.

Figure 9.2. Details of an event in Windows Event Viewer

Figure 9.2. Details of an event in Windows Event Viewer

This is a very simple example of generating log information and posting it to the Windows event log.

Note More details and complexities of event logging in Windows are available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/vbconIntroductionToEventLogComponents.asp.

Building the Application in .NET

Microsoft Visual Studio® .NET 2003 offers a variety of methods for organizing the files that are to be included in a build of a solution or a project, setting the project properties in effect while building and arranging the order in which the projects is to be built.

Following are the common Visual Studio procedures for preparing and managing builds.

To build or rebuild an entire solution

  1. In Solution Explorer, select or open the desired solution.

  2. On the Build menu, click Build Solution or Rebuild Solution as per the following requirements:

    • Click Build <ProjectName>  to compile only the necessary project files and components in the project named <ProjectName> of the solution.

    • Click Build Solution to compile only those project files and components in all the projects of the solution.

    • Click Rebuild Solution to clean the solution first, and then build all the project files and components.

Note "Cleaning" a solution or project deletes all the intermediate and output files, leaving only the project and component files, from which new instances of the intermediate and output files are built.

Note More information on building the application in .NET using the Visual Studio .NET integrated development environment (IDE) is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vxtskPrepareandManageBuilds.asp.

.NET applications can also be built from the command line. The syntax for building a .NET application from the command line is given as follows:

devenv /build ConfigName [/project ProjName] [/projectconfig ConfigName] SolutionName .

The summary information for builds, including errors, appears in the command prompt. It can also be redirected to any log file using the /out argument.

Note More information on the available command-line parameters for building the application from the command line is available at https://msdn.microsoft.com/library/en-us/vsintro7/html/vxlrfBuild.asp.

.NET Deployment Activities

Deploying an application involves at least two different activities: packaging the code and distributing the packages to the various clients and servers on which the application is to be deployed. One of the primary goals of the .NET Framework is to simplify the deployment process, especially the distribution aspect, by making the zero-impact install and an XCopy deployment feasible. The following subsections describe the most important .NET deployment considerations: assemblies, configuration files, and packaging tools.

Assemblies

The .NET Framework introduces assemblies, which form the fundamental unit of deployment, version control, reuse, activation scoping, and security permissions. Assemblies act as the smallest distribution unit for the component code in the .NET Framework. Assemblies are self-describing deployment units; they are self-describing through metadata called a manifest. The .NET Framework uses the metadata to describe the types as well as the assemblies that contain the types.

Assemblies consist of four elements: the assembly metadata (manifest), metadata describing the types, the intermediate language (IL) code that implements the types, and a set of resources. Not all of these elements are present in each assembly. The manifest is mandatory for all assemblies and either types or resources are needed to give the assembly any meaningful functionality. Versioning in .NET is done at the assembly level.

There are two types of assemblies in the .NET infrastructure: private and shared.

Private Assemblies

Private assemblies are not designed to be shared. They are designed to be used by one application and must reside in the directory or subdirectory of that application. By default, all assemblies are private. An XCopy deployment can only be done for private assemblies.

Shared Assemblies

For the components that must be distributed, .NET offers the shared assembly. The shared assembly concept is centered on two principles. The first, called side-by-side execution, allows the CLR to house multiple versions of the same component on a single computer. The second, termed binding, ensures that the clients obtain the version of the component that they expect.

Shared assemblies have the following two issues:

  • Shared assemblies can be updated by anyone in the absence of a proper authorization.

  • If an assembly is shared by more than one party and one or more components in the assembly are updated without the knowledge of the other sharing parties, the clients may receive the incorrect version of one or more requested components.

The first issue can be resolved by using a private key to sign an assembly, allowing only the developer signing the key to update the assembly. Using the Global Assembly Cache (GAC), a computer-wide code cache that exists on a computer where the CLR is installed, can resolve the second issue. GAC can house multiple copies of a shared assembly based on the signature and the version information used to build it. Before installing the assemblies to GAC, they should be strongly named using the Strong Name tool (Sn.exe), provided with Visual Studio .NET 2003. The Global Assembly Cache tool (GACUtil.exe) allows you to view and manipulate the contents of the global assembly cache. This information (signature and version) is stored in the manifest of all clients who want to access the assembly, allowing the CLR to load the appropriate version at run time.

Note More information about assemblies in .NET is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconassemblies.asp. More information on Global Assembly Cache (GAC) is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconglobalassemblycache.asp.

Configuration Files

Configuration files in .NET are XML files that can be changed as required. Developers can use the configuration files to change the settings without recompiling the applications. Administrators can use the configuration files to set policies that affect how the applications run on the computers. This section helps you understand the .NET configuration files and their role in .NET applications.

The .NET Framework provides the System.Configuration class to read the setting from the configuration files. There are three types of configuration files in .NET:

  • Machine configuration files

  • Application configuration files

  • Security configuration files

Note More information on configuration files in .NET and their formats is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconconfigurationfiles.asp.

Machine Configuration Files

The machine configuration file, Machine.config, contains settings that apply to an entire computer. This file is located in the %runtime install path%\Config directory. Machine.config contains configuration settings for the machine-wide assembly binding, built-in remoting channels, authentication modes, and authorization modes for ASP.NET applications.

The configuration system first looks in the machine configuration file for the <appSettings> element and other configuration sections that a developer might define. After that, the configuration system looks in the application configuration file.

Application Configuration Files

It is possible to configure an application by using a configuration file in the same directory as the application. The name of the configuration file is the name of the application with a .config extension for Windows applications or Web.config for the Web applications. Therefore, a configuration file for the ListBoxAdd application is called ListBoxAdd.exe.config.

The application configuration file contains settings specific to an individual application. This file contains configuration settings that the CLR can read (such as assembly binding policy and remoting objects) and settings that the application can read (such as the location of the files and database connection string). The assembly binding policy that defines how assemblies should be probed is also configured in this file.

If probing fails to find an assembly in either the application directory or a subdirectory with the same name as the assembly, it next looks for probing instructions in the application configuration file (if one exists).

Here is an example of an application configuration file:

<configuration>
<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
     <probing privatePath="AssemblyDir1;AssemblyDir2"/>
  </assemblyBinding>
</runtime>
</configuration>

This application configuration file uses a probing tag to set the private path to be probed to include two directories, called AssemblyDir1 and AssemblyDir2. These directories are considered as subdirectories that exist below the application directory.

Security Configuration Files

The security configuration file contains information about the code group hierarchy and the permission sets associated at a policy level. It is strongly recommended that you use the .NET Framework Configuration tool (Mscorcfg.msc) or Code Access Security Policy tool (Caspol.exe) to modify the security policy to ensure that the policy changes do not corrupt the security configuration files.

Note More information on the .NET Framework Configuration tool is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpconNETFrameworkAdministrationToolMscorcfgmsc.asp.  
More information on the Code Access Security Policy tool is available at
https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpgrfCodeAccessSecurityPolicyUtilityCaspolexe.asp.
More information on configuration files in .NET is available at
https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconconfigurationfiles.asp.

Manifests

Manifests are XML files used to describe the side-by-side execution of assemblies or the isolated application through the assembly's <assemblyIdentity> element. Side-by-side execution is the process of maintaining multiple of versions of the same assembly on a single computer. Manifests contain information used for binding and activation. Side-by-side assemblies are not registered on the system but are available to applications and other assemblies on the system that specify dependencies in manifest files. Side-by-side assemblies can be installed as shared assemblies or as private assemblies.

The following types of manifests are used with side-by-side assemblies:

  • Assembly manifests describe side-by-side assemblies. These are used to manage the names, versions, resources, and dependent assemblies of side-by-side assemblies. The manifests of shared assemblies are stored in the WinSxS folder of the system. Private assembly manifests are stored either as a resource in the DLL or in the application folder.

  • Application manifests describe isolated applications. These are used to manage the names and versions of shared side-by-side assemblies that the application should bind to at run time. Application manifests are copied into the same folder as the application executable file or included as a resource in the application's executable file.

  • Application Configuration Files. These are manifests used to override and redirect the versions of dependent assemblies used by side-by-side assemblies and applications.

  • Publisher Configuration Files. These are manifests used to redirect the version of a side-by-side assembly to another compatible version. The version that the assembly is being redirected to should have the same major.minor values as the original version.

Packaging Tools

The .NET Framework comes with tools that allow developers to quickly build and deploy robust applications that take advantage of the new CLR environment to provide a fully managed and feature-rich application-execution environment. The .NET Framework also provides the following benefits:

  • Improved isolation of application components.

  • Simplified application deployment.

  • Robust version numbering.

The .NET Framework SDK includes several useful tools for examining assemblies and working with the system assembly cache. Following is the list of the tools:

  • Assembly Linker (Al.exe). For creating assembly manifests, satellite assemblies, and working with the Global Assembly Cache (GAC).

  • Global Assembly Cache Tool (Gacutil.exe). Console tool that manages the Global Assembly (GAC) and download caches.

  • MSIL Disassembler (Ildasm.exe). Windows-based tool for examining the manifest (containing metadata) and MSIL code inside assemblies.

  • Assembly Binding Log Viewer (Fuslogvw.exe). Windows-based tool for examining assembly and resource bind requests.

  • Strong Name Tool (Sn.exe). Console tool to help generate strongly named assemblies.

Note More information on these tools is available at https://msdn.microsoft.com/library/en-us/cptutorials/html/Appendix_B___Packaging_and_Deployment_Tools.asp.

The following five packaging options are available in the .NET Framework:

  • As-built (DLLs and EXEs). An application can be deployed in the format produced by building the application using the development tool. In many scenarios, no special packaging is required.

  • CAB files. CAB files can be used to compress an application for more efficient downloads.

    CAB files provide the following benefits:

    • Delivery of all application files in one file.

    • Prevention of partial installations.

    • Capability to install an application from multiple sources.

    You can use Microsoft Visual Studio .NET 2003 to generate a CAB file automatically, or you can create a custom CAB file. You can distribute the CAB files for an application from a variety of sources, including a Web site, a memory storage card, another device, or a server or desktop computer.

Note More information on CAB file projects is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vbconcabfileprojects.asp.

  • Microsoft Windows Installer packages. Visual Studio .NET 2003 and other installation tools allow developers to build Windows Installer packages (.msi files), which enable developers to take advantage of the application repair, on-demand install, and other Microsoft Windows application-management features.

    Windows Installer is based on a data-driven model that provides all installation data and instructions in a single package. In contrast, traditional scripted setup programs were based on a procedural model, providing scripted instructions for application installations. Scripted setup programs focused on how to install something, whereas Windows Installer focuses on what to install.

    With Windows Installer, each computer keeps a database of information about every application that it installs, including files, registry keys, and components. When an application is uninstalled, the database is checked to ensure that no other applications rely on a file, registry key, or component before removing it. This prevents breaking of other applications because of the removal of an application.

    Windows Installer also supports self-repair, the capability of an application to automatically reinstall missing files that may have inadvertently been deleted by the user. In addition, Windows Installer provides the capability to roll back an installation. For example, if an application relies on a specific database and the database is not found during the installation, installation can be aborted and the computer returned to its preinstallation state.

    The deployment tools in Visual Studio .NET 2003 build on the foundation of Windows Installer, providing you with rich capabilities for rapidly deploying and maintaining applications built with Visual Studio .NET 2003.

Note More information of Windows Installer is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vbconwhatyouneedtoknowaboutmicrosoftwindowsinstaller.asp.

  • Merge module projects. Merge module projects allow developers to create reusable setup components. A merge module (.msm file) is a single package that contains all the files, resources, registry entries, and setup logic necessary to install a component. Merge modules cannot be installed alone, but must be used within the context of a Windows Installer (.msi) file.

Note More information on merge module projects is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vbconMergeModuleProjects.asp.

  • Setup projects. Setup projects allow developers to create installers to distribute an application. The resulting Windows Installer (.msi) file contains the application, any dependent files, and information about the application, such as registry entries and instructions for installation. There are two types of setup projects in Visual Studio: Setup projects and Web Setup projects. The distinction between a Setup project and a Web Setup project is the location where the Windows Installer will be deployed. Setup projects will install files into the file system of a target computer; whereas Web Setup projects install files into a virtual directory of a Web server.

Note More information on Setup projects is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vbconSetupProjects.asp.

  • ClickOnce. ClickOnce is the feature supported by the latest versions of Visual Studio .NET 2005. ClickOnce provides a new deployment technology that gives the best of a rich Windows-based application user experience and the deployment and maintenance benefits of Web applications. It allows a user to download and execute a rich client application over the Web, off a network file share, or from local media. It offers a full Windows user interface running on a desktop, while allowing single server deployment of application files and updates. Client applications are automatically deployed and updated on the user's computer from the deployment server in a safe way and will not affect other applications or data that already exists on the computer.

Note More information on ClickOnce is available at https://msdn.microsoft.com/msdnmag/issues/04/05/ClickOnce/.

The following are three third-party products that you can use for packaging the developed application:

Note More information on deploying the applications in Visual Studio .NET 2003 is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vboriDeploymentInVisualStudio.asp.

Instrumentation

Windows Management Instrumentation (WMI) provides a rich set of system management services built into the Microsoft Windows operating system. The use of WMI-based management systems leads to a more robust computing environment and an increased level of system reliability, which allows the automation of administrative tasks in an enterprise environment.

In the .NET Framework, the System.Management namespace provides common classes to traverse the WMI schema. In addition to the .NET Framework, you must have WMI installed on the computer to make use of the management features in this namespace.

Note More information on instrumentation in .NET is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconmanagingapplicationsusingwmi.asp.

Testing Activities

This section discusses the testing activities designed to identify and address potential solution issues prior to deployment. Testing starts when you begin developing the solution and ends when the testing team certifies that the solution components meet the schedule and quality goals established in the project plan.

Testing in migration projects involving infrastructure services is focused on finding discrepancies between the behavior of the original application, as seen by its clients, and the behavior of the newly migrated application. All discrepancies must be investigated and fixed.

In the Developing Phase, the testing team executes the test plans for acceptance tests on the application submitted for a formal round of testing on the test environment. The testing team assesses the solution, makes a report on its overall quality and feature completeness, and certifies that the solution features, functions, and components address the project goals.

The inputs required for the Developing Phase include:

  • Functional specifications document.

  • A feature-complete application, which has been unit tested.

The documents that are used during the Developing Phase include:

  • Test plan. The test plan is prepared during the Planning Phase. It should describe in detail everything that the test team, the program management team, and the development team must know about the testing to be done.

  • Test specification. The test specification conveys the entire scope of testing required for a set of functionality and defines individual test cases sufficiently for the testers. It also specifies the deliverables and the readiness criteria.

  • Test environment. The test environment is an exact replica of the production environment; it is used to test the application under realistic environments. It also describes the software, hardware, and tools required for testing purposes.

  • Test data. The test data is a set of data for testing the application. Test data is usually a diverse set of data that helps test the application under different conditions.

  • Test report. The test report is an error report of the tests performed. It includes a description of the errors that occurred, steps to reproduce the errors, severity of the errors, and names of the developers who are responsible for fixing them.

    The test report is updated during the Stabilizing Phase and is also one of the outputs of this phase, along with the tested and stabilized application.

The key deliverables of the Developing Phase include:

  • Application ready to be deployed in the production environment.

  • Application source code.

  • Project documentation and user manual.

  • Test plan, test specification, and test reports.

  • Release notes.

  • Other project-related documents.

Testing begins with a code review of the application and unit testing. In the Developing Phase, the application is subjected to various tests. The test plan organizes the testing process into the following elements:

  • Code component testing

  • Integration testing

  • Database testing

  • Security testing

  • Management testing

You can test the migrated application in all the scenarios by using a defined testing strategy. Although each test has a different purpose, together they verify that all system elements are properly integrated and perform their allocated functions.

Visual Studio .NET 2005 provides the integrated test environment along with the integrated development environment (IDE).

Note More information on Testing features of Visual Studio .NET 2005 is available at https://msdn.microsoft.com/vstudio/products/newfeatures/209/default.aspx.

Code Component Testing

A component may be a class or a group of related classes performing a similar task. Component testing is the next step after unit testing. Component testing is the process of verifying a software component with respect to its design and functional specifications.

Component testing in a migration project is the process of finding the discrepancies between the functionality and output of components in the Windows application and the original UNIX application. Basic smoke testing, boundary conditions, and error test cases are written based on the functional specification of the component.

Code component testing tests the components for the following:

  • Functionality

  • Input and output, interactions within and with other components

  • Stress testing

  • Performance

The test cases for component testing cover, either directly or indirectly, constraints on their inputs and outputs (pre-conditions and post-conditions), the state of the object, interactions between methods, attributes of the object, and other components.

The code component testing requires the following inputs:

  • Test plan and specification. It provides the test cases.

  • System requirements. These are used to determine the required behaviors for individual domain-level classes. The use case model is also used to determine which parts of a component must be tested for vulnerabilities.

  • Specifications of the component. The specifications are used to build the functional test cases. Information on the component inputs, outputs, and interactions with other components can be derived from here.

  • Design document. The actual implementation of the design provides the information necessary to construct the structural and interaction test cases.

Components must also be stress tested. Stress testing is the process of loading the component to the defined and undefined limits. Each component must be stressed under a load to ensure that it performs well within a reasonable performance limit.

System CPU and memory usage per component can also be measured and monitored to determine the performance of individual components. For this, you can use such tools as the Windows Performance Monitor. For more information, refer to the "Testing and Optimization Tools" section of Chapter 10, “Stabilizing Phase” of this volume.

Integration Testing

Integration testing involves testing the application as a whole, with all the components of the application put together. Component testing is done during the testing performed in the Developing Phase. Integration testing is the process of verifying the application with respect to the behavior of components in the integrated application, interaction with other components, and the functional specifications of the application as a whole. Integration testing in a migration project is the process of finding discrepancies in the interaction between components and the behavior of components in the Windows application and the original UNIX application.

Integration testing tests the components for:

  • Functionality: behavior of the application as a whole and the individual components after integration.

  • Input and output: interactions within and with other components.

  • Response to various types of stresses.

  • Performance.

Test cases for integration testing directly or indirectly include functionality of the components, constraints on their inputs and outputs (pre-conditions and post-conditions), the state of the object, interactions between components, attributes of the object, and other components. The application must also be stress tested. Inputs required for integration testing include:

  • Test plan. It provides the details of testing the application.

  • Test specification. It is used to determine the required behaviors for individual domain-level classes. The use case model is also used to determine which parts of the application must be tested for vulnerabilities.

Stress testing must also be performed. Stress testing is the process of loading the application to the defined and undefined limits to ensure that it performs well within a reasonable performance limit.

System testing is also performed after completion of integration testing. System testing is the process of ensuring that the integrated application is compatible with all platforms and to test against its requirements. The system CPU and memory usage for the application can also be measured and monitored to determine their performance. For this, you can use such tools as the Windows Performance Monitor.

Note For more information, refer to the "Testing and Optimization Tools" section of Chapter 10, "Stabilizing Phase."

Database Testing

The database component is a critical piece of any data-enabled application. In a migration project, the database may be the same or may have been replaced by another database. In both cases, data must be migrated to the respective database on Windows. Testing of a migrated database includes testing of:

  • Migrated procedural code.

  • Data integration with heterogeneous data sources (if applicable).

  • Customized data transformations and extraction.

Database testing also involves testing at the data access layer, which is the point at which your application communicates with the database. Database testing in a migration project involves:

  • Testing the data and the structure and design of the migrated database objects.

  • Testing the procedures and functions related to database access.

  • Security testing, which tests the database to guarantee proper authentication and authorization so that only users with the appropriate authority access the database. The database administrator must establish different security settings for each user in the test environment.

  • Testing of data access layer.

  • Performance testing of data access layer.

  • Manageability testing of the database.

An application maintains the following three databases, which are replicas of each other:

  • Development database. This is where most of the testing is carried out.

  • Deployment database (or integration database). This is where the tests are run prior to deployment to ensure that the local database changes are applied.

  • Live database. This has the live data; it cannot be used for testing.

Database testing is done on the development database during development, and the integrated application is tested using the deployment database.

Security Testing

Security is about controlling access to a variety of resources, such as application components, data, and hardware. Security testing is performed on the application to ensure that only users with the appropriate authority are able to use the applicable features of the application. Security testing also involves testing the application from the point of view of providing the same security features and measures that were provide by the original application.

To ensure that the application is as secure as possible, most security measures are based on the following four concepts:

  • Authentication. This is the process of confirming the identity of the users, which is one layer of security control. Before an application can authorize access to a resource, it must confirm the identity of the requestor.

  • Authorization. This is the process of verifying that an authenticated party has the permission to access a particular resource, which is the layer of security control following the authentication layer.

  • Data protection. This is the process of providing data confidentiality, integrity, and nonrepudiability. Encrypting the data provides data confidentiality. Data integrity is achieved through the use of hash algorithms, digital signatures, and message authentication codes. Message authentication codes (MACs) are used by technologies such as SSL/TLS to verify that data has not been altered while in transit.

  • Auditing. This is the process of logging and monitoring events that occur in a system and are of interest to security.

Note For more information, refer to "Event Logging" on the TechNet Web site at* *https://technet2.microsoft.com/WindowsServer/en/Library/0473658c-693d-4a06-b95b-ebe8a76648a91033.mspx.

The systems engineer establishes different security settings for each user in the test environment. Network security testing is performed to help secure the network from unauthorized users. To minimize the risks associated with unchecked errors on the system, you should know the user context in which system processes run, keeping to a minimum the privileges that these accounts have, and log their access to these accounts. Active monitoring can be accomplished using the Windows Performance Monitor for real-time feedback.

All security settings and security features of the application must be documented properly.

Note
More information about security testing is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsent7/html/vxcontestingforsecurability.asp.
More information on how to make your code more secure is available at https://msdn.microsoft.com/security/securecode/.
More information on "Secure Coding Guidelines for the .NET Framework" is available at https://msdn.microsoft.com/security/securecode/bestpractices/default.aspx?pull=/library/en-us/dnnetsec/html/seccodeguide.asp.

Management Testing

Testing for manageability involves testing the deployment, maintenance, and monitoring technologies that you have incorporated into your migrated application.

Following are some important testing recommendations to verify that you have developed a manageable application:

  • Test Windows Management Instrumentation (WMI). WMI can provide important information about your application and the resources it uses. During the design of your application, you made certain decisions about the types of WMI information that must be provided. These might include server and network configurations, event log error messages, CPU consumption, available disk space, network traffic, application settings, and many other application messages. You must test every source of information and be certain you can monitor each one.

  • Test Network Load Balancing (NLB) and cluster configuration.You can use Application Center 2000 clustering to add a front- or back-end server while the application is still running. After installing new server hardware on the network, use your monitoring console to replicate the application image and start the server. The new server should automatically begin sharing some of the workload. You can set up the Application Center 2000 Performance Monitor (PerfMon) to track multiple front-end Web servers. After setting up PerfMon, make some requests to generate traffic. PerfMon will show you that there is an increase in traffic in the back-end servers and that the workload is evenly spread across the front-end computers.

Note Additional information about Application Center 2000 is available at https://www.microsoft.com/applicationcenter/.

  • Test change control procedures. An important part of application management is the handling of both scheduled and emergency maintenance changes. Test and validate all of the change control procedures including the automated and manual processes. It is especially important to test all people-based procedures to ensure that the necessary communication, authority, and skills are available to support an error-free change control process.

Note Additional information on testing for manageability is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsent7/html/vxcontestingformanageability.asp.

Interim Milestone: Internal Release n

The project needs interim milestones to help the team measure their progress in the actual building of the solution during the Developing Phase. Each internal release signifies a major step toward the completion of the solution featuresets and achievement of the associated quality level. Depending on the complexity of the solution, a number of internal releases may be required. Each internal release represents a fully functional addition to the solution’s core feature set, indicating that it is potentially ready to move on to the Stabilizing Phase.

Closing the Developing Phase

Closing the Developing Phase requires completing a milestone approval process. The team documents the results of different tasks that it has performed in this phase and obtains a sign-off on the completion of development from the stakeholders (including the customer).

Key Milestone: Scope Complete

The Developing Phase culminates in the Scope Complete Milestone. At this milestone, all features are complete and the solution is ready for external testing and stabilization. This milestone provides the opportunity for customers and users, operations and support personnel, and key project stakeholders to evaluate the solution and identify any remaining issues that must be addressed before beginning the transition to stabilization and, ultimately, to release.

Key stakeholders, typically representatives of each team role and any important customer representatives who are not on the project team, signal their approval of the milestone by signing or initialing a document stating that the milestone is complete. The sign-off document becomes a project deliverable and is archived for future reference.

Now the team must shift its focus to verify that the quality of the solution meets the acceptance criteria for release readiness. The next phase, the Stabilizing Phase, describes the activities—for example, user acceptance testing (UAT), regression testing, and conducting the pilot—required to achieve these objectives.

Download

Get the UNIX Custom Application Migration Guide

Update Notifications

Sign up to learn about updates and new releases

Feedback

Send us your comments or suggestions