From 2053d4dfb37c570569614eff0deaa2679d526a5c Mon Sep 17 00:00:00 2001 From: tuend Date: Tue, 9 Sep 2025 16:19:16 +0000 Subject: [PATCH] first --- run_stress_test.bat | 36 +++++++++++ stress_test.py | 150 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 run_stress_test.bat create mode 100644 stress_test.py diff --git a/run_stress_test.bat b/run_stress_test.bat new file mode 100644 index 0000000..ecff472 --- /dev/null +++ b/run_stress_test.bat @@ -0,0 +1,36 @@ +@echo off +echo Checking for Python installation... + +:: Kiểm tra xem Python có được cài đặt không +py --version >nul 2>&1 +if %ERRORLEVEL% neq 0 ( + echo Error: Python is not installed or not added to PATH. + echo Please install Python from https://www.python.org/ and ensure it's added to PATH. + pause + exit /b 1 +) + +:: Kiểm tra xem file stress_test.py có tồn tại không +if not exist "stress_test.py" ( + echo Error: stress_test.py not found in the current directory. + pause + exit /b 1 +) + +:: Kiểm tra và cài đặt thư viện requests nếu chưa có +echo Checking for requests library... +py -c "import requests" >nul 2>&1 +if %ERRORLEVEL% neq 0 ( + echo Installing requests library... + pip install requests + if %ERRORLEVEL% neq 0 ( + echo Error: Failed to install requests library. + pause + exit /b 1 + ) +) + +:: Chạy file stress_test.py +echo Running stress_test.py... +py stress_test.py +pause \ No newline at end of file diff --git a/stress_test.py b/stress_test.py new file mode 100644 index 0000000..d197247 --- /dev/null +++ b/stress_test.py @@ -0,0 +1,150 @@ +import requests +import threading +import time +from concurrent.futures import ThreadPoolExecutor +from urllib.parse import urlparse +import sys +import signal + +# Biến cờ để kiểm soát việc dừng luồng +stop_event = threading.Event() + +def make_request(url, request_count, thread_id): + """Hàm gửi một request đến URL và in kết quả""" + if stop_event.is_set(): + return None, None + try: + start_time = time.time() + response = requests.get(url, timeout=10) + elapsed_time = time.time() - start_time + status = response.status_code + print(f"Thread {thread_id} - Request {request_count}: Status {status}, Time {elapsed_time:.3f}s") + return status, elapsed_time + except requests.RequestException as e: + print(f"Thread {thread_id} - Request {request_count}: Error - {str(e)}") + return None, None + +def stress_test(url, num_requests, num_threads): + """Hàm chính thực hiện stress test""" + print(f"\nStarting stress test on {url}") + print(f"Total requests: {num_requests}, Threads: {num_threads}\n") + + # Tính số request mỗi luồng + requests_per_thread = num_requests // num_threads + extra_requests = num_requests % num_threads + + start_time = time.time() + success_count = 0 + total_time = 0 + request_count = 0 + + def worker(thread_id, req_count): + """Hàm worker cho mỗi luồng""" + nonlocal success_count, total_time, request_count + for i in range(1, req_count + 1): + if stop_event.is_set(): + break + status, elapsed = make_request(url, request_count + i, thread_id) + if status == 200: + success_count += 1 + total_time += elapsed + request_count += 1 + + # Tạo ThreadPoolExecutor để quản lý luồng + with ThreadPoolExecutor(max_workers=num_threads) as executor: + futures = [] + current_request_count = 0 + for i in range(num_threads): + reqs = requests_per_thread + (1 if i < extra_requests else 0) + if reqs > 0: + futures.append(executor.submit(worker, i + 1, reqs)) + current_request_count += reqs + + # Chờ tất cả các luồng hoàn thành hoặc bị dừng + try: + for future in futures: + future.result() + except KeyboardInterrupt: + print("\nReceived Ctrl+C, stopping all threads...") + stop_event.set() # Đặt cờ để dừng tất cả luồng + executor._threads.clear() # Xóa các luồng đang chạy + threading.enumerate()[-1].join() # Đợi luồng chính kết thúc + + total_duration = time.time() - start_time + avg_time = total_time / success_count if success_count > 0 else 0 + + # In báo cáo kết quả + print("\n=== Stress Test Report ===") + print(f"Total Requests Sent: {request_count}") + print(f"Successful Requests: {success_count}") + print(f"Failed Requests: {request_count - success_count}") + print(f"Total Duration: {total_duration:.2f}s") + print(f"Average Response Time (successful requests): {avg_time:.3f}s") + print(f"Requests per Second: {request_count / total_duration:.2f}" if total_duration > 0 else 0) + +def validate_url(url): + """Kiểm tra URL hợp lệ""" + if not url.startswith(('http://', 'https://')): + url = 'http://' + url + try: + result = urlparse(url) + return url if result.scheme and result.netloc else None + except: + return None + +def signal_handler(sig, frame): + """Xử lý tín hiệu Ctrl+C""" + print("\nReceived Ctrl+C, initiating graceful shutdown...") + stop_event.set() + sys.exit(1) + +def main(): + """Hàm chính để chạy chương trình""" + # Đăng ký xử lý tín hiệu Ctrl+C + signal.signal(signal.SIGINT, signal_handler) + + print("=== Stress Test Tool ===") + + # Nhập và kiểm tra URL + url = input("Enter target URL (e.g., http://example.com): ").strip() + url = validate_url(url) + while not url: + print("Invalid URL. Please enter a valid URL.") + url = input("Enter target URL (e.g., http://example.com): ").strip() + url = validate_url(url) + + # Nhập số lượng request + while True: + try: + num_requests = int(input("Enter number of requests: ")) + if num_requests <= 0: + print("Number of requests must be greater than 0.") + continue + break + except ValueError: + print("Please enter a valid number.") + + # Nhập số luồng + while True: + try: + num_threads = int(input("Enter number of threads: ")) + if num_threads <= 0: + print("Number of threads must be greater than 0.") + continue + if num_threads > num_requests: + print("Number of threads cannot exceed number of requests.") + continue + break + except ValueError: + print("Please enter a valid number.") + + # Chạy stress test + try: + stress_test(url, num_requests, num_threads) + except KeyboardInterrupt: + print("\nStress test interrupted by user.") + stop_event.set() + sys.exit(1) + +if __name__ == "__main__": + main() \ No newline at end of file