diff --git a/Autotestplat/celery.py b/Autotestplat/celery.py index 17c581b7..c95fa578 100644 --- a/Autotestplat/celery.py +++ b/Autotestplat/celery.py @@ -10,7 +10,7 @@ from django.conf import settings os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Autotestplat.settings') -django.setup() + app = Celery('Autotestplat') @@ -20,6 +20,8 @@ app.conf.enable_utc = True app.conf.timezone = "Asia/Shanghai" +django.setup() + @app.task(bind=True) def debug_task(self): print('Request: {0!r}'.format(self.request)) \ No newline at end of file diff --git a/Autotestplat/settings.py b/Autotestplat/settings.py index 7e962b67..d70c7ec5 100644 --- a/Autotestplat/settings.py +++ b/Autotestplat/settings.py @@ -73,7 +73,6 @@ WSGI_APPLICATION = 'Autotestplat.wsgi.application' - DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', @@ -81,7 +80,12 @@ 'HOST': '127.0.0.1', 'PORT': 3306, 'USER': 'root', - 'PASSWORD': 'test123456'} + 'PASSWORD': 'Liuzhichao@123', + 'OPTIONS': { + 'charset': 'utf8mb4', + 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", + }, + } } AUTH_PASSWORD_VALIDATORS = [ @@ -104,14 +108,14 @@ TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True -USE_TZ = True +USE_TZ = False STATIC_URL = '/static/' STATICFILES_DIRS = [ - os.path.join(BASE_DIR, "autotest").join("static") + os.path.join(BASE_DIR, "autotest", "static") ] - +STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') MEDIA_URL = "/upload/" MEDIA_ROOT = os.path.join(BASE_DIR,'upload') @@ -125,9 +129,18 @@ CUBES_REDIS_TIMEOUT=60*60 NEVER_REDIS_TIMEOUT=365*24*60*60 - +# 根据 settings.py 配置,项目使用了 3 个 Redis 数据库: +# Redis 缓存(CACHES) +# 地址:redis://127.0.0.1:6379/1 +# 用途:Django 缓存后端 +# Celery Broker +# 地址:redis://127.0.0.1:6379/0 +# 用途:Celery 任务队列消息代理 +# Celery 结果后端 +# 地址:redis://127.0.0.1:6379/1 +# 用途:存储 Celery 任务执行结果 CELERY_TIMEZONE = 'Asia/Shanghai' -CELERY_ENABLE_UTC=True +CELERY_ENABLE_UTC=False # BROKER_URL= 'amqp://root:root@127.0.0.1:5672/of1' #rabbitmq BROKER_URL = 'redis://127.0.0.1:6379/0' BROKER_TRANSPORT = 'redis' @@ -135,4 +148,16 @@ CELERY_ACCEPT_CONTENT = ['json'] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' -CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler' \ No newline at end of file +CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler' + +# 设置 Celery Beat 自动检测数据库变化的间隔(秒) +# 默认是 5 分钟,设置为 10 秒可以更快生效 +# CELERYBEAT_MAX_LOOP_INTERVAL = 10 + +LOGIN_URL = '/autotest/login/' +LOGIN_REDIRECT_URL = '/autotest/index/' +LOGOUT_REDIRECT_URL = '/autotest/login/' + +SESSION_COOKIE_AGE = 3600 # 1 小时(60 * 60 = 3600 秒) +SESSION_EXPIRE_AT_BROWSER_CLOSE = True # 关闭浏览器后失效 +SESSION_SAVE_EVERY_REQUEST = False # 不刷新过期时间(固定窗口) \ No newline at end of file diff --git a/Redis-x64-3.2.100/dump.rdb b/Redis-x64-3.2.100/dump.rdb index cda7b72c..694d8464 100644 Binary files a/Redis-x64-3.2.100/dump.rdb and b/Redis-x64-3.2.100/dump.rdb differ diff --git a/autotest/models.py b/autotest/models.py index fac32d19..464d04c8 100644 --- a/autotest/models.py +++ b/autotest/models.py @@ -216,15 +216,15 @@ class Meta: db_table = 'autotestplat_testplan_interface' class AutotestplatTestplanInterfaceResult(models.Model): - report_id = models.CharField(max_length=20,null=True) + report_id = models.CharField(max_length=50,null=True) product_id = models.IntegerField(null=True) product_name = models.CharField(max_length=255, blank=True, null=True) suit_id = models.IntegerField(null=True) suit_name = models.CharField(max_length=100, null=True) suit_interface_id = models.IntegerField(null=True) interface_name = models.CharField(max_length=200,null=True) - url = models.CharField(max_length=100,null=True) - body = models.CharField(max_length=200,null=True) + url = models.CharField(max_length=500,null=True) + body = models.TextField(null=True, blank=True) mode = models.CharField(max_length=20,null=True) assert_keywords_old = models.CharField(max_length=20,null=True) task_mode = models.CharField(max_length=20,null=True) @@ -232,7 +232,7 @@ class AutotestplatTestplanInterfaceResult(models.Model): response_time = models.TextField(null=True) result = models.CharField(max_length=20,null=True) pass_pers = models.CharField(max_length=20, null=True) - date_time = models.CharField(max_length=20,null=True) + date_time = models.CharField(max_length=50,null=True) class Meta: managed = True diff --git a/autotest/static/js/performance.js b/autotest/static/js/performance.js index faf91dd6..7b91458c 100644 --- a/autotest/static/js/performance.js +++ b/autotest/static/js/performance.js @@ -1,4 +1,5 @@ setProgressURL = 'apiperformance/progress/' +checkStatusURL = 'apiperformance/status/' function search_performance_interface() { @@ -145,14 +146,14 @@ function search_performance_interface() { return; } else if(num_bf == ''){ - alert('请输入“并发数”') + alert('请输入"并发数"') return; } else if(num_sj == ''){ - alert('请输入“持续运行时间”') + alert('请输入"持续运行时间"') return; } - + $('.jmeter_status').empty().append('状态:准备执行'); $.ajax({ url: "/autotest/apiperformance/prepare/", @@ -163,34 +164,82 @@ function search_performance_interface() { success: function(result) { console.log(result); if(result == 'success'){ - + $('.jmeter_status').empty().append('') var progressBar = document.getElementById('progressBar'); - var duration = document.getElementById('num_sj').value; - var increment = parseInt(duration) * 60; + var duration = parseInt(document.getElementById('num_sj').value); + var increment = duration * 60; progressBar.max = increment; - let startTime = new Date(); - - var intervalId = setInterval(function() { - let now = new Date(); - let elapsed = now - startTime; - let seconds = Math.floor(elapsed / 1000); - progressBar.value = seconds % 60; - $.ajax({ - url: appURL+setProgressURL, - type: 'POST', - data: JSON.stringify({ - progress: progressBar.value, - progress_total: increment, - }), - success: (rst) => { - console.log("success") + + // 【关键修改】:启动 JMeter 并立即开始轮询真实状态 + $.ajax({ + url: "/autotest/apiperformance/start/", + headers:{'X-CSRFToken': '{{ csrf_token }}'}, + contentType: 'application/json;charset=utf-8', + type: "POST", + traditional: true, + success: function(result) { + if(result == 'success'){ + $('.jmeter_status').empty().append('状态:测试进行中'); + + // 启动状态轮询 + var statusCheckInterval = setInterval(function() { + $.ajax({ + url: appURL + checkStatusURL, + type: 'GET', + success: function(statusData) { + if(statusData.running) { + // JMeter 仍在运行,更新进度条 + progressBar.value = statusData.progress; + + // 更新数据库中的进度 + $.ajax({ + url: appURL + setProgressURL, + type: 'POST', + data: JSON.stringify({ + progress: statusData.progress, + progress_total: increment, + }), + success: (rst) => { + console.log("进度更新成功") + } + }); + } else { + // JMeter 已结束 + clearInterval(statusCheckInterval); + $('.jmeter_status').empty().append('状态:测试完成'); + progressBar.value = increment; + + // 更新最终状态 + $.ajax({ + url: appURL + setProgressURL, + type: 'POST', + data: JSON.stringify({ + progress: increment, + progress_total: increment, + }), + success: (rst) => { + console.log("最终状态更新成功") + } + }); + } + }, + error: function(err) { + console.error("状态检查失败:", err); + clearInterval(statusCheckInterval); + $('.jmeter_status').empty().append('状态:状态检查异常'); + } + }); + }, 500); // 每2秒轮询一次 } - }); - if (progressBar.value === progressBar.max-1) { - clearInterval(intervalId); - } - }, 100); + else { + $('.jmeter_status').empty().append('状态:启动失败'); + } + }, + fail: function(result) { + debugger + } + }); } else { $('.jmeter_status').empty().append('状态:出现异常'); @@ -201,49 +250,26 @@ function search_performance_interface() { debugger } }); - - $.ajax({ - url: "/autotest/apiperformance/start/", - headers:{'X-CSRFToken': '{{ csrf_token }}'}, - contentType: 'application/json;charset=utf-8', - type: "POST", - traditional: true, - success: function(result) { - console.log(result); - if(result == 'success'){ - $('.jmeter_status').empty().append('状态:测试完成'); - $.ajax({ - url: appURL+setProgressURL, - type: 'POST', - data: JSON.stringify({ - progress: 0, - progress_total: 1, - }), - success: (rst) => { - console.log("success") - } - }); - } - else { - $('.jmeter_status').empty().append('状态:测试失败'); - } - }, - fail: function(result) { - debugger - } - }); } function select_login(id1,name1,module1) { $('#login_panel').append(''+name1+''); + +} + +function view_test_result() { + window.open('/autotest/apiperformance/report/', '_blank'); } + function select_not_login(id1,name1,module1) { $('#not_login_panel').append(''+name1+''); } + function remove_login_selected(ele) { var id1 = '#'+ele; $('#login_panel').find(id1).remove(); } + function remove_not_login_selected(ele) { var id1 = '#'+ele; $('#not_login_panel').find(id1).remove(); diff --git a/autotest/static/js/webtestcase.js b/autotest/static/js/webtestcase.js index 6dad5fff..890eb440 100644 --- a/autotest/static/js/webtestcase.js +++ b/autotest/static/js/webtestcase.js @@ -563,7 +563,13 @@ function run_webtestcase_bycode(e,tips="运行成功"){ $("#addModal").modal('hide') } else{ - return alert(rst) + // 解析 JSON 响应 + var response = typeof rst === 'string' ? JSON.parse(rst) : rst; + if(response.message) { + alert(response.message); + } else { + alert('运行完成。该用例为:' + (response.web_testcase_code || web_testcase_code)); + } } }, error: (rst) =>{ @@ -585,7 +591,13 @@ function run_webtestcase_byproduct(e,tips="运行成功"){ $("#addModal").modal('hide') } else{ - return alert(rst) + // 解析 JSON 响应 + var response = typeof rst === 'string' ? JSON.parse(rst) : rst; + if(response.message) { + alert(response.message); + } else { + alert('运行完成'); + } } }, error: (rst) =>{ diff --git a/autotest/tasks.py b/autotest/tasks.py index 85be720f..56c2e0f4 100644 --- a/autotest/tasks.py +++ b/autotest/tasks.py @@ -1,4 +1,4 @@ -# -*- coding:utf-8 -*- +# -*- coding:utf-8 -*- from Autotestplat.celery import app @app.task(bind=True) diff --git a/autotest/templates/interface_performance.html b/autotest/templates/interface_performance.html index 704c7613..3ffe67da 100644 --- a/autotest/templates/interface_performance.html +++ b/autotest/templates/interface_performance.html @@ -1,5 +1,4 @@ - - + + + + + + + + +
+
+ 快运交接单服务系统
+