From 3b46a5c3c9fe5a076201c42b13141a7213bf44d6 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 19 Aug 2025 13:51:09 +0000 Subject: [PATCH] This commit introduces a README.md file, unit tests, and a GitHub Actions workflow for the network scanner script. - Adds a `README.md` with instructions on how to use the script. - Adds a `requirements.txt` file for easy dependency installation. - Implements unit tests for the `is_reachable` function using Python's `unittest` framework. - Mocks the `subprocess.Popen` call to avoid actual network activity during tests. - Sets up a GitHub Actions workflow to automatically run tests on push and pull requests to the main branch. - Adds a `.gitignore` file to exclude Python cache files and virtual environments from version control. --- .github/workflows/python-app.yml | 26 +++++++++++++++++++ .gitignore | 10 ++++++++ README.md | 40 +++++++++++++++++++++++++++++ requirements.txt | 1 + test_testping1.py | 43 ++++++++++++++++++++++++++++++++ 5 files changed, 120 insertions(+) create mode 100644 .github/workflows/python-app.yml create mode 100644 .gitignore create mode 100644 README.md create mode 100644 requirements.txt create mode 100644 test_testping1.py diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml new file mode 100644 index 0000000..da87bbd --- /dev/null +++ b/.github/workflows/python-app.yml @@ -0,0 +1,26 @@ +name: Python application test with unittest + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.10 + uses: actions/setup-python@v4 + with: + python-version: "3.10" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Test with unittest + run: | + python -m unittest discover diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..25aa2b9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# Environments +.env +.venv +env/ +venv/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..f2f0cf1 --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# Network Scanner + +This script, `testping1.py`, is a simple network scanner that checks for reachable devices within a specified IP address range. It uses the `ping` command to determine if a device is online. + +## Features + +- Pings a range of IP addresses. +- Displays reachable IP addresses. +- Shows a progress bar during the scan. + +## Requirements + +- Python 3 +- `tqdm` library + +## Installation + +1. Clone the repository: + ```bash + git clone + cd + ``` + +2. Install the required Python library: + ```bash + pip install -r requirements.txt + ``` + *(Note: A `requirements.txt` file will be added to the project)* + +## Usage + +Run the script from your terminal: + +```bash +python testping1.py +``` + +The script is pre-configured to scan the `192.168.43.1` to `192.168.43.254` IP range. You can modify the `start_ip` and `end_ip` variables in `testping1.py` to scan a different range. + +**Important:** Ensure you have permission to scan the network before running this script. Unauthorized network scanning can be disruptive and may be against the terms of service for the network you are on. diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..78620c4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +tqdm diff --git a/test_testping1.py b/test_testping1.py new file mode 100644 index 0000000..9be1547 --- /dev/null +++ b/test_testping1.py @@ -0,0 +1,43 @@ +import unittest +import subprocess +from unittest.mock import patch, MagicMock +from testping1 import is_reachable + +class TestIsReachable(unittest.TestCase): + + @patch('testping1.subprocess.Popen') + def test_is_reachable_success(self, mock_popen): + """Test is_reachable returns True for a successful ping.""" + mock_process = MagicMock() + # Simulate a successful ping response containing "bytes from" + mock_process.communicate.return_value = (b'64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.063 ms', b'') + mock_popen.return_value = mock_process + + self.assertTrue(is_reachable('127.0.0.1')) + + @patch('testping1.subprocess.Popen') + def test_is_reachable_failure(self, mock_popen): + """Test is_reachable returns False for a failed ping.""" + mock_process = MagicMock() + # Simulate a failed ping response + mock_process.communicate.return_value = (b'Request timed out.', b'') + mock_popen.return_value = mock_process + + self.assertFalse(is_reachable('10.0.0.1')) + + @patch('testping1.subprocess.Popen') + def test_is_reachable_calls_ping_correctly(self, mock_popen): + """Test is_reachable calls the ping command with correct arguments.""" + mock_process = MagicMock() + mock_process.communicate.return_value = (b'', b'') + mock_popen.return_value = mock_process + + is_reachable('192.168.1.1', timeout=5) + # Verify that subprocess.Popen was called with the correct arguments, including the timeout + mock_popen.assert_called_once_with( + ['ping', '-c', '1', '-W', '5', '192.168.1.1'], + stdout=subprocess.PIPE, stderr=subprocess.PIPE + ) + +if __name__ == '__main__': + unittest.main()