Monday, 19 January 2026

Understanding Software Testing Using a Simple JSP Web App

 

🎯 Lab Context (Very Important)

This project is a basic Maven web application created for learning DevOps concepts.

  • It displays a simple Hello World page (index.jsp)

  • It runs on Tomcat

  • Initially, it has no Java logic and no tests

  • Our goal is NOT to build a full application

  • Our goal IS to understand testing in CI/CD

⚠️ This lab focuses on learning testing concepts, not building features.


 

1️⃣ What Is Software Testing? 

✅ What

Software testing is how we verify that code behaves as expected.

In simple words:

“If I change something, how do I know I didn’t break it?”

✅ Why Testing Exists (DevOps Perspective)

In DevOps:

  • Code changes are frequent

  • Builds are automated

  • Deployments are fast

Without tests:

  • Bugs reach production

  • Pipelines deploy broken code

  • Teams lose confidence

Tests act as safety checks in the pipeline. 

✅ Types of Testing (High-Level)

TypeWhat it testsTool
 Unit TestJava logicJUnit
UI TestWeb pagesSelenium
Integration TestMultiple componentsTest frameworks
Security TestVulnerabilitiesSnyk
Quality ScanCode qualitySonarQube








2️⃣ Why We Do NOT Test index.jsp with JUnit

What index.jsp is:

  • A view

  • Mostly HTML

  • Rendered by Tomcat

What JUnit is designed for:

  • Java classes

  • Java methods

  • Business logic

JUnit:
❌ does not start Tomcat
❌ does not render JSPs
❌ does not test HTML

✅ Key Learning

Not all code is tested the same way.

This is a very important DevOps concept.

3️⃣ The Real-World Testing Pattern (What Companies Do)

Instead of testing JSPs directly, companies:

  • Keep JSPs simple

  • Put logic in Java classes

  • Unit-test the Java logic

Simple Architecture

Browser ↓ index.jsp (VIEW – not unit tested) ↓ HelloService (LOGIC – unit tested)

This keeps testing:

  • fast

  • reliable

  • automation-friendly



4️⃣ Why We Add a Small Java Class (Even for Hello World)

You may ask:

“Why add Java code if the app is just Hello World?”

Answer:

Because testing needs executable logic.

Without Java code:

  • No tests can run

  • No coverage can be generated

  • JaCoCo has nothing to measure

So we add the smallest possible logic to teach testing correctly.


5️⃣ Step-by-Step: Add Testable Java Logic

Step 5.1 — Create a simple Java class

Path

MyWebApp/src/main/java/com/mywebapp/HelloService.java

You can do this directly in bitbucket or locally and push
to bitbucket


package com.mywebapp; public class HelloService { public String getMessage() { return "Hello World"; } }
Commit changes

📘 This class:

  • Contains logic

  • Can be executed

  • Can be tested

  • Can be measured by coverage tools


6️⃣ Step-by-Step: Write a Unit Test (JUnit)

Step 6.1 — Create a test class

Path

MyWebApp/src/test/java/com/mywebapp/HelloServiceTest.java


package com.mywebapp; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; class HelloServiceTest { @Test void shouldReturnHelloWorldMessage() { HelloService service = new HelloService(); assertEquals("Hello World", service.getMessage()); } }

What this test does:

  • Calls the method

  • Checks the output

  • Passes if correct

  • Fails if changed


7️⃣ Running Tests (Understanding the Commands)

🔹 Run tests only

mvn clean test

This:

  • Compiles code

  • Runs unit tests

  • Does not generate coverage


🔹 Run tests WITH coverage (important for this lab)

mvn clean verify -Pcoverage

What -Pcoverage means:

  • Activates the coverage profile

  • Enables JaCoCo

  • Attaches the JaCoCo agent

  • Generates coverage data

📍 Output file:

MyWebApp/target/site/jacoco/jacoco.xml

8️⃣ What Is Code Coverage? (Simple Explanation)

Coverage answers:

“How much of my Java code was executed by tests?”

Examples:

  • 0% → No tests ran

  • 50% → Some code executed

  • 100% → All code executed

⚠️ Coverage does NOT mean “bug-free”
It means tested execution paths


9️⃣ How This Fits into Jenkins (Big Picture)

In Jenkins:

  1. Code is checked out

  2. Maven runs tests

  3. JaCoCo generates coverage

  4. SonarQube reads the coverage

  5. Pipeline decides:

    • PASS → deploy

    • FAIL → stop

This is real CI/CD behavior.


In Your Free style job Add below in your maven config

change from

clean install -Dv=${BUILD_NUMBER} sonar:sonar

To

clean verify -Pcoverage -Dv=${BUILD_NUMBER} sonar:sonar -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml


✅ Report File Pattern

**/target/site/jacoco/jacoco.xml



1) Add Maven Surefire plugin

Your build log showed an ancient surefire (2.12.4)

which often results in “No tests to run”

even when tests exist.

UPDATE YOUR POM

Add this inside <build><plugins> (outside the profile):

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.2.5</version> </plugin>

FINAL POM BELOW

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mywebapp</groupId> <artifactId>mywebapp</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>MyWebApp</name> <properties> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <jacoco.version>0.8.11</jacoco.version> </properties> <profiles> <profile> <id>coverage</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.2.5</version> </plugin> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>${jacoco.version}</version> <!-- 1️⃣ Prepare the agent before tests --> <executions> <execution> <id>prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <!-- 2️⃣ Generate the XML report after tests --> <execution> <id>report</id> <phase>verify</phase> <goals> <goal>report</goal> </goals> <configuration> <!-- We only need the XML form for SonarQube --> <outputDirectory>${project.build.directory}/site/jacoco</outputDirectory> <outputEncoding>UTF-8</outputEncoding> <formats> <format>XML</format> </formats> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> <dependencies> <!-- Old JUnit already present — keep it --> <!-- Example dependency for unit tests --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.10.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.10.0</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>MyWebApp</finalName> <plugins> <!-- JDK 21 Maven Compiler --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <release>21</release> </configuration> </plugin> <!-- WAR packaging support --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.4.0</version> </plugin> <plugin> <groupId>org.sonarsource.scanner.maven</groupId> <artifactId>sonar-maven-plugin</artifactId> <version>5.2.0.4988</version> </plugin> </plugins> </build> </project>


Saturday, 13 December 2025

BashScript to disable non performing Jenkins Plugin (Cure Slowness- Make Jenkins Fast Again)

 

 Here’s a portable bash script to disable the nonessential plugins we turned off (mercurial, theme-manager, dark-theme, pipeline-graph-view) on any Jenkins host:


#!/usr/bin/env bash

  set -euo pipefail


  JENKINS_HOME="${JENKINS_HOME:-/var/lib/jenkins}"

  PLUGINS_DIR="${JENKINS_HOME}/plugins"

  PLUGINS=("mercurial" "theme-manager" "dark-theme" "pipeline-graph-view")


  echo "JENKINS_HOME: $JENKINS_HOME"

  echo "Disabling: ${PLUGINS[*]}"


  for p in "${PLUGINS[@]}"; do

    for ext in jpi hpi; do

      if [[ -f "${PLUGINS_DIR}/${p}.${ext}" ]]; then

        sudo touch "${PLUGINS_DIR}/${p}.${ext}.disabled"

        echo " - ${p}.${ext} -> disabled"

      fi

    done

  done


  echo "Restarting Jenkins..."

  sudo systemctl restart jenkins


  echo "Done. Check status with: sudo systemctl status jenkins"


 Save/run it on the Jenkins controller (or any similar instance) with sudo rights. It only creates .disabled markers for the listed plugins if present, then restarts Jenkins

Sunday, 7 December 2025

Bash Script to Install Artifactory in Ubuntu 22

JFrog Artifactory OSS 7.21.5 — Install (Bash Script)

This script installs Artifactory OSS (no Docker, no Pro, works on Ubuntu 22 EC2).


# ==========================================
# Install JFrog Artifactory OSS on Ubuntu 22
# Version: 7.21.5
# ==========================================

# 1) Prerequisites
sudo apt update -y
sudo apt install -y openjdk-17-jdk wget tar

# 2) Create Artifactory directory
sudo mkdir -p /opt/artifactory
cd /opt/artifactory

# 3) Download verified OSS release
sudo wget https://releases.jfrog.io/artifactory/bintray-artifactory/org/artifactory/oss/jfrog-artifactory-oss/7.21.5/jfrog-artifactory-oss-7.21.5-linux.tar.gz

# 4) Extract & name correctly
sudo tar -xzf jfrog-artifactory-oss-7.21.5-linux.tar.gz
sudo mv artifactory-oss-7.21.5 app

# 5) Start Artifactory manually
sudo /opt/artifactory/app/app/bin/artifactory.sh start

# 6) Optional — status
sudo /opt/artifactory/app/app/bin/artifactory.sh status

# UI available:
#  http://SERVER-IP:8082/ui/

(Optional) Enable Artifactory systemd Service


sudo tee /lib/systemd/system/artifactory.service > /dev/null << 'EOF'
[Unit]
Description=JFrog Artifactory
After=network.target

[Service]
Type=simple
User=ubuntu
ExecStart=/opt/artifactory/app/app/bin/artifactory.sh start
ExecStop=/opt/artifactory/app/app/bin/artifactory.sh stop
Restart=always

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable artifactory
sudo systemctl start artifactory
sudo systemctl status artifactory --no-pager

Access Artifactory

Once started:

  • URL: http://SERVER-IP:8082/ui/
  • Default user: admin
  • Default password: password

How to Install jfrog Artifactory on Ubuntu 22

Install JFrog Artifactory OSS 7.21.5 on Ubuntu 22


1️⃣ Remove Previous Installation



sudo systemctl stop artifactory.service
sudo systemctl disable artifactory.service
sudo rm -rf /opt/artifactory
sudo rm -f /etc/systemd/system/artifactory.service
sudo systemctl daemon-reload

2️⃣ Install Java (OpenJDK 17)



sudo apt update
sudo apt install -y openjdk-17-jdk
java -version

3️⃣ Download Artifactory OSS 7.21.5



cd /opt
sudo wget https://releases.jfrog.io/artifactory/bintray-artifactory/org/artifactory/oss/jfrog-artifactory-oss/7.21.5/jfrog-artifactory-oss-7.21.5-linux.tar.gz

4️⃣ Extract & Structure Correctly



sudo mkdir /opt/artifactory
cd /opt/artifactory
sudo tar -xzf /opt/jfrog-artifactory-oss-7.21.5-linux.tar.gz
sudo mv artifactory-oss-7.21.5 app

Check structure:


sudo useradd --system --home /opt/artifactory --shell /bin/false artifactory || true
sudo chown -R artifactory:artifactory /opt/artifactory
sudo -u artifactory mkdir -p /opt/artifactory/app/app/run



5️⃣ Create SystemD Service


  sudo sh -c 'cat > /etc/systemd/system/artifactory.service <<'"'"'EOF'"'"'
  [Unit]
  Description=JFrog Artifactory
  After=network.target

  [Service]
  Type=forking
  User=artifactory
  Group=artifactory
  WorkingDirectory=/opt/artifactory/app/app/bin
  ExecStart=/opt/artifactory/app/app/bin/artifactory.sh start
  ExecStop=/opt/artifactory/app/app/bin/artifactory.sh stop
  PIDFile=/opt/artifactory/app/app/run/artifactory.pid
  Restart=on-failure
  LimitNOFILE=32000
  LimitNPROC=1024

  [Install]
  WantedBy=multi-user.target
  EOF'

6️⃣ Enable & Start Service



sudo systemctl daemon-reload
sudo systemctl enable artifactory.service
sudo systemctl start artifactory.service
sudo systemctl status artifactory.service

7️⃣ Access UI



http://YOUR_SERVER_IP:8082/ui/

---
username:admin
password: password

Saturday, 6 December 2025

How to Add a windows Agent to jenkins

 Prerequisite

  • Jenkins controller: Ubuntu 22 on AWS EC2

  • On Controller (Ubuntu Jenkins)

    • Port 8080 open

    • Port 50000 open

  • New agent: Windows Server (or Windows 10/11)--Lunch a new windows instance.


Then launch.... when instance is running ...Click connect to see how to connect ...then click Rdp ang get password to get password



Click Decrypt pasword to get password




Open RDP on your computer
Enter computer: Public Dns
Username: Administrator
Click connect and Enter the password




1. Prep the Windows machine

On the Windows box (the future agent):

  1. Install Java (same major as controller, e.g. JDK 17 or 21)

  2. Add Java to PATH (optional but helpful)

    • System Properties → Advanced → Environment Variables

    • Under System variables, edit Path → add:
      C:\Program Files\Java\jdk-21\bin

  3. Create a Jenkins work directory

    • For example: C:\jenkins

    • Make sure the user that will run the agent (e.g. jenkins or your login) has full rights.



  4. Network

    • Windows server must be able to reach the Jenkins URL over HTTP/HTTPS

    • If using inbound TCP agent port (default 50000), make sure it’s open on security group if needed

2. Create the Windows node in Jenkins

On the Jenkins controller UI:

  1. Go to Manage Jenkins → Nodes (or “Manage Nodes and Clouds”).

  2. Click New Node.

  3. Name it e.g. windows-agent-1.

  4. Choose Permanent Agent → OK.

Fill in:

  • # of executors: 1 (or more if the box is strong)

  • Remote root directory: C:\jenkins

  • Labels: e.g. windows maven (you’ll use these in jobs)

  • Usage: “Use this node as much as possible”

Launch method (very important)

Set Launch method to:

Launch agent by connecting it to the controller

This means the Windows machine will run java -jar agent.jar and connect in.

Click Save.

You’ll now see the node page with instructions like “Launch agent”, “jnlp” etc.



Save 
Then from the Agent browser browse to the Jenkins







Copy the 2 commands and run from the Agent commandline




if you face issues or errors; check if port is open and all firewall

Run on Jenkins Terminal
sudo ufw allow 8080/tcp






Your Agent is now connected 




Understanding Software Testing Using a Simple JSP Web App

  🎯 Lab Context (Very Important) This project is a basic Maven web application created for learning DevOps concepts. It displays a sim...