Add New Application For Coverage Report
Pre-Requisites for Bookworm Slim
To enable code coverage, the standard runtime image is modified into a “hybrid” image that contains both the .NET SDK and the production runtime. Additionally, a specialized entrypoint script is introduced to manage the process lifecycle, ensuring that the application runs under instrumentation and shuts down gracefully without losing coverage data.
1. Description of Dockerfile Additions
- SDK & Runtime Convergence: Instead of using separate AS build and AS runtime final stages, this file installs the .NET SDK 8.0 directly onto the 8.0-bookworm-slim base. This allows the use of dotnet tool to install the coverage agents.
- Bookworm Native Stack: It installs libc6, libssl3, and libgssapi-krb5-2 specifically for Debian 12. It also includes procps (for the ps command) and coreutils, which are necessary for the background process management used in the entrypoint.
- Tooling Path: The environment variable PATH=”$PATH:/root/.dotnet/tools” is set so that the system can locate dotnet-coverage globally.
- Script Injection: The local entrypoint.sh is copied into the image and granted execution permissions (chmod +x).
2. Description of Entrypoint Script Logic
The entrypoint.sh script is the “brain” of the container at runtime.
- PID 1 Management: By running as the entrypoint, the script becomes Process ID 1. It is responsible for reaping “zombie” processes and handling system signals.
Appendix: Implementation Files
In the sections below, the code added specifically for Code Coverage changes it will added in runtime or final stage is highlighted.
Note: If the environment variable COMPlus_EnableDiagnostics is set to 0 in the docker file, the .NET runtime disables CLR diagnostics and profiling APIs. In this state, code coverage instrumentation will not work, and no coverage data will be collected.
Required Change in Dockerfile
For code coverage instrumentation to function correctly, the following change must be made in the Dockerfile (runtime/final stage):
ENV COMPlus_EnableDiagnostics=1
A. The Dockerfile
# RUN ALL CONTAINERS FROM ROOT (folder with .sln file):
# docker-compose build
# docker-compose up
#
# RUN JUST THIS CONTAINER FROM ROOT (folder with .sln file):
# docker build –pull -t web -f src/Web/Dockerfile .
#
# RUN COMMAND
# docker run –name eshopweb –rm -it -p 5106:5106 web
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim AS build
WORKDIR /app
COPY *.sln ./
COPY . .
WORKDIR /app/src/Web
RUN dotnet restore
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:8.0-bookworm-slim AS runtime
WORKDIR /app
# ————————
# OS dependencies
# ————————
RUN apt-get update && apt-get install -y –no-install-recommends \
ca-certificates \
wget \
curl \
gnupg \
libc6 \
libc6-dev \
libgcc-s1 \
libstdc++6 \
libssl3 \
zlib1g \
libxml2 \
libgssapi-krb5-2 \
procps \
coreutils \
&& rm -rf /var/lib/apt/lists/*
# ————————
# Install Microsoft repo
# ————————
RUN wget https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \
&& dpkg -i packages-microsoft-prod.deb \
&& rm packages-microsoft-prod.deb
# ————————
# Install .NET SDK 8
# ————————
RUN apt-get update && apt-get install -y –no-install-recommends \
dotnet-sdk-8.0 \
&& rm -rf /var/lib/apt/lists/*
# ————————
# Install coverage tools
# ————————
RUN dotnet tool install –tool-path /tools dotnet-coverage \
&& dotnet tool install –tool-path /tools dotnet-reportgenerator-globaltool
ENV PATH=”/tools:${PATH}”
COPY –from=build /app/src/Web/out ./
COPY src/Web/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT [“/entrypoint.sh”]
B. The Entrypoint Script (entrypoint.sh)
Bash
#!/bin/sh
set -e
# Start app in background
dotnet {{application dll}}&
APP_PID=$!
# Signal Trap for Graceful Shutdown
_term() {
echo “Entrypoint: TERM/INT received, forwarding to child…” >&2
if [ -n “$APP_PID” ] && kill -0 “$APP_PID” 2>/dev/null; then
kill -TERM “$APP_PID” 2>/dev/null || true
wait “$APP_PID” 2>/dev/null || true
fi
exit 0
}
trap _term TERM INT
# Wait for App Exit
if [ -n “$APP_PID” ]; then
wait “$APP_PID” 2>/dev/null
echo “Entrypoint: child (pid $APP_PID) exited.” >&2
APP_PID=””
fi
# Keep container alive for data collection
tail -f /dev/null
Required Changes in deployment.yaml for supporting code coverage in READ_ONLY container
It will work with build number 4.14.1_31 onwards as there are some minor changes in the remote scripts to handle the “COVERAGE_BASE_PATH” variable.
——————————————————————-
Ensure memory and cpu limit as 512
Add the highlighted items under the corresponding labels in your deployment.yaml file
volumes:
– name: tmp-writable
emptyDir: {}
volumeMounts:
– name: tmp-writable
mountPath: /tmp
containers:
– name: container_name
image:image_name:latest
securityContext:
readOnlyRootFilesystem: true
env:
– name: COVERAGE_BASE_PATH
value: “/tmp”
Add New Application
To create a new application for Code Coverage, click the “+” icon next to the Application dropdown. This opens the New Application for Coverage Report window, where users must specify the required configuration. Users can also edit an existing application by selecting its name from the Application dropdown menu. Once an application is rebuilt with code coverage enabled, it will always run with code coverage turned on; to disable code coverage, the application must be rebuilt again after removing the code coverage arguments.
Common Configuration Fields
- Application Name: Enter a unique name for the application for which you want to initiate code coverage.
- Server Type: User needs to select between Host and Kubernetes.
- Application Type: Select either Java or .NET depending on the application’s technology stack.
- Report Coverage For: Specify the complete file path of the application binary (JAR, WAR, DLL, or executable) for which code coverage needs to be generated. It supports multiple DLLs/ JARs / WARs as comma separated. The first one should be the main application entry point.
- Source Code Path on Cavisson Controller: Specify the complete file path of the application binary, JAR, WAR DLL, or executable on the Cavisson Controller for which coverage needs to be generated. Example: /home/cavisson/work/app/lib/myapp.jar. Do note that in case this is not provided, a line by line coverage drilldown will not be visible.
Configuration for Applications running on Hosts
- IP Address: Enter the IP address of the host machine where the application is deployed. If required, include the port number as well (for example, 237.84.2.178:7899).
- SSH User Name: Provide the valid SSH username that has access to the target host where the application is running.
- SSH Password: Enter the corresponding SSH password for the specified username. This is used to securely connect to the host for enabling code coverage.
Configuration for applications running on Kubernetes:
- Authentication Method
- Managed Identity: Utilize the existing managed identity configured with Cavisson to authenticate with the Kubernetes cluster.
- Token Based Authentication:
- API Server URL: Enter the URL of the Kubernetes control plane used to manage and communicate with the cluster. This URL can be obtained from the Kubernetes cluster configuration file (kubeconfig), by running kubectl config view, or from the Kubernetes administrator or cloud provider’s cluster details (for example, https://10.10.10.4:6443).
- Service Account Token: Click this link to check how to retrieve the service account token bearer token.
- Namespace: Enter the Kubernetes namespace where the application resources are deployed. Example: sample-namespace
- Select POD Using: Choose how the target pod is identified. You can select Label to identify pods based on Kubernetes labels, or Pod Pattern to identify pods using a regular expression pattern.
- Label: Enter the Kubernetes label key-value pair associated with the application pod (for example, app=my-app).
- Pod Pattern: Enter a regex pattern to match the pod name (for example, my-app-* or .*backend.*). This will collect the coverage data from a single service type matching with the DLL mentioned in the “Report Coverage for” field.
Advanced Options: The code coverage requires target application to be stopped and started and following are the different modes to take start and stop command options.
- Manual Mode: Use this option to manually handle the start and stop operations for the application, which is required for the code coverage collection and specify the Coverage Capture File Path where the coverage output file will be stored, for Java type of application.
- Auto Mode: Use this option to automatically detect, stop and finally start the application process with a coverage agent when the user presses the “Start Code Coverage” button. Specify the Target Application, which is the application’s main class or entry point pattern. It is optional, but required only when the target application default pattern is not sufficient to identify the application. Example: Web.dll.
- Explicit Start / Stop Commands: Use this mode when custom commands are required to control start / stop of the target application.
- Start Command: Enter the command to start the target application .
- Stop Command: Enter the command to stop the target application.
- Coverage Capture File Path: Enter the path where the output file will be stored, only applicable for Java type of application
Action Buttons
- Save: Saves the application configuration without starting coverage.
- Save & Start: Saves the configuration and immediately starts the coverage process.
- Reset: Clears all entered fields and resets the form to default values.
After the New Application for Coverage Report has been created, the user needs to perform the following tasks.
Code Coverage Home Page
Overview
The Code Coverage Report presents a detailed breakdown of how much of the application’s code was executed during a run. It summarizes key metrics such as line coverage, branch coverage, total executable lines, and uncovered areas. This structured view helps identify gaps in test execution and highlights portions of the code that may require additional testing or validation. By clearly outlining covered and uncovered sections, the report ensures that users can assess test completeness, improve overall application reliability, and make informed decisions about where further testing effort is needed.
Code Coverage Report Process
- Application: This dropdown displays the list of all configured applications. The user needs to select the application for which the code coverage process should be initiated.
- Notes: This optional field allows the user to enter any additional information or remarks related to the coverage run, such as a specific use case, build number, test scenario name, or environment details. These notes are not mandatory and will appear in the Report History for future reference.
- Start Code Coverage: After selecting the application and entering notes, the user must click on Start Code Coverage to initiate the coverage process. When this option is clicked, a confirmation window appears displaying the Manual Coverage Mode Instructions if the said option is selected while adding the application.
Note: Ensure the application server is not running before starting coverage. It will start automatically, and you can use the application normally while data is collected. The system will not stop the server; it only captures execution data to generate the coverage report.
Global Action Icons
- Analyze Coverage Report: Allows the user to analyze the selected coverage report and view combined coverage insights.
- Delete: Enables the user to remove one or more selected reports from the Report History table.
- Column Filter: Helps the user filter table data based on specific column values.
- Manage Columns: Allows the user to show or hide columns to customize the table view as per requirement.
- Download: Users can export the report data in Word, PDF, Excel, or CSV format.
Move Column Left / Move Column Right: This option allows the user to reposition the selected column by shifting it one step to the left or right within the table layout.
Hide Column: This option hides the selected column from the table view.
Report History Table
- Master Checkbox: Located at the top-left corner, it allows the user to select or deselect all rows in the table for performing bulk actions.
- Status: Shows the current state of the coverage run, which can be either Running or Completed.
- Application Name: Shows the name of the application for which the coverage run was executed.
- Date: Indicates the date and time when the coverage run was initiated.
- Duration: Shows the total time taken to complete the coverage run.
- User: Displays the name of the user who initiated the code coverage run.
- Notes: Displays any remarks or notes provided by the user at the time of starting the coverage process.
- Action: When the coverage report starts, the Stop button is displayed. The Code Coverage Report option allows users to view the generated coverage report once execution is complete. The Edit Notes option enables users to edit the history of notes. The Show Logs option allows users to view code coverage logs and pod details.