Skip to content

Commit

Permalink
api coverage add category (#67)
Browse files Browse the repository at this point in the history
* fix(rxl): api-coverage add prodcutattributes

* fix(rxl): 增加{num}类型匹配

* fix(rxl): Save local changes

* fix(rxl): Save local changes

* fix(rxl): Save local changes

* fix(rxl): Save local changes

* fix(rxl): Save local changes

* fix(rxl): Save local changes

* fix(rxl): Save local changes

* fix(rxl): Delete unnecessary modifications

* fix(rxl): Modify report modules

* fix(rxl): report file modifyy method

* fix(rxl): Delete unnecessary changes
  • Loading branch information
lxwiiiiiii authored May 25, 2023
1 parent beb9f06 commit 84bafc4
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 75 deletions.
21 changes: 16 additions & 5 deletions frontend/src/components/apiList.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
<template>
<div id="tab" class="box box-solid">
<div class="box-body" style="max-height:calc(100vh - 100px); overflow:auto">
<i-table stripe :columns="columns" :data="showedAPIData" ></i-table>
<div class="box-body" style="max-height:calc(100vh - 100px) overflow:auto">
<i-table stripe :columns="columns" :data="showedAPIData">
<template #category="{ row }">
<span v-if="row.category.length !== 0">
<span v-for="(item, index) in row.category" :key="index">
<Tag v-if="item.status == 1" color="green">{{item.label}}</Tag>
</span>
</span>
</template>
</i-table>
<Modal
v-model="isApiDetailModalShow"
title="Flow Detail"
Expand Down Expand Up @@ -38,19 +46,16 @@ export default {
title: 'Priority',
key: 'priority',
sortable: true,
width: 110,
},
{
title: 'API',
key: 'url',
sortable: true,
width: 380,
},
{
title: 'Description',
key: 'desc',
sortable: true,
width: 200,
},
{
title: 'Count',
Expand Down Expand Up @@ -97,6 +102,12 @@ export default {
return row.status === null
},
},
{
title: 'Category',
key: 'category',
slot: 'category',
sortable: true,
},
{
title: 'Detail',
key: 'id',
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default new Vuex.Store({
apis
.getCoverage()
.then((response) => {
context.commit('setCoverageData', response.data)
context.commit('setCoverageData', response.data.coverage)
})
.catch(() => {
this.$Notice.open({ title: 'loadCoverageData error!' })
Expand Down
4 changes: 2 additions & 2 deletions lyrebird_api_coverage/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ def generate(data):
# 获取内存里保存的测试结果API
# /getTest
def get_test_data():
return Response(stream_with_context(generate({'test_data': app_context.merge_list})), content_type='application/json')
return context.make_ok_response(test_data=app_context.merge_list)

# 获取内存里保存的测试覆盖率信息
# /getCoverage
def get_coverage():
return Response(stream_with_context(generate(app_context.coverage)), content_type='application/json')
return context.make_ok_response(coverage = app_context.coverage)

# 保存测试数据在本地
# /saveResult
Expand Down
4 changes: 4 additions & 0 deletions lyrebird_api_coverage/client/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ def __init__(self):
self.covtime = 0
# 时间间隔,每隔指定时间触发1次socket io消息,防止刷新频繁
self.SOCKET_PUSH_INTERVAL = 1
# 是否使用接口请求实时base数据
self.is_api_base_data = False
# category信息
self.category = ''


# 单例模式
Expand Down
36 changes: 30 additions & 6 deletions lyrebird_api_coverage/client/load_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@
import hashlib
import json
import lyrebird
from pathlib import Path
from lyrebird.log import get_logger
import os
import imp
import traceback

from lyrebird_api_coverage.client.context import app_context

PLUGINS_CONF_DIR = lyrebird.get_plugin_storage()
DEFAULT_BASE = os.path.join(PLUGINS_CONF_DIR, 'base.json')
CURRENT_DIR = os.path.dirname(__file__)

logger = get_logger()


def get_file_sha1(path):
with open(path, 'rb') as f:
Expand All @@ -25,12 +30,31 @@ def auto_load_base():
# 读取指定base文件,写入到base.json
if lyrebird_conf.get('hunter.base'):
base_path = lyrebird_conf.get('hunter.base')
base = codecs.open(base_path, 'r', 'utf-8').read()
f = codecs.open(DEFAULT_BASE, 'w', 'utf-8')
f.write(base)
f.close()
app_context.base_sha1 = get_file_sha1(DEFAULT_BASE)
return json.loads(base)
base_path_obj = Path(base_path)
if not base_path_obj.is_file():
return
# 判断是否需要实时获取接口数据
if base_path_obj.suffix == '.py':
try:
init_base_file = imp.load_source('load_base', str(base_path_obj))
except Exception:
logger.warning(f'Failed to load the file, {traceback.format_exc()}')
return
if not hasattr(init_base_file, 'load_api_base'):
logger.warning(f'load_api_base does not exist')
return
if not callable(init_base_file.load_api_base):
logger.warning(f'The method does not exist')
return
app_context.is_api_base_data = True
return init_base_file.load_api_base()
else:
base = codecs.open(base_path, 'r', 'utf-8').read()
f = codecs.open(DEFAULT_BASE, 'w', 'utf-8')
f.write(base)
f.close()
app_context.base_sha1 = get_file_sha1(DEFAULT_BASE)
return json.loads(base)
# 通过本地默认base文件获取base
elif not os.path.exists(DEFAULT_BASE):
copy_file(DEFAULT_BASE)
Expand Down
99 changes: 65 additions & 34 deletions lyrebird_api_coverage/client/merge_algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,36 @@ def init_basedata_handler(self, dic):
# url_dic = {'url': k, 'desc': v.get('desc'), 'priority': v.get('priority'), 'count': 0, 'status': 0,
# 'org': []}
# app_context.merge_list.append(url_dic)
dict2 = {'count': 0, 'status': 0, 'id': ''}
for item in dic.get('api_list'):
# 处理带参数的情况
if '?' in item['url']:
path = item['url'].split('?')[0].lower()
params = item['url'].split('?')[1].split('&')
param_dic = {}
for i in params:
key = i.split('=')[0]
val = i.split('=')[1]
param_dic[key] = val

if app_context.path_param_dic.get(path):
app_context.path_param_dic[path].append({'url': item['url'], 'params': param_dic,
'url_base': format_url.format_api_source(
item.get('url')).lower()})
else:
app_context.path_param_dic[path] = [{'url': item['url'], 'params': param_dic,
'url_base': format_url.format_api_source(
item.get('url')).lower()}]

# format base源 同时变成大小写归一化,变小写
item['url'] = format_url.format_api_source(item.get('url')).lower()
item.update(dict2)
app_context.merge_list.append(item)

def merge_handler_new(self, user_url, path_id):
if app_context.is_api_base_data:
# 如果接口获取base数据,同步merge_list内容
app_context.merge_list = dic.get('api_list')
else:
dict2 = {'count': 0, 'status': 0, 'id': ''}
for item in dic.get('api_list'):
# 处理带参数的情况
if '?' in item['url']:
path = item['url'].split('?')[0].lower()
params = item['url'].split('?')[1].split('&')
param_dic = {}
for i in params:
key = i.split('=')[0]
val = i.split('=')[1]
param_dic[key] = val

if app_context.path_param_dic.get(path):
app_context.path_param_dic[path].append({'url': item['url'], 'params': param_dic,
'url_base': format_url.format_api_source(
item.get('url')).lower()})
else:
app_context.path_param_dic[path] = [{'url': item['url'], 'params': param_dic,
'url_base': format_url.format_api_source(
item.get('url')).lower()}]
# format base源 同时变成大小写归一化,变小写
item['url'] = format_url.format_api_source(item.get('url')).lower()
item.update(dict2)
app_context.merge_list.append(item)

def merge_handler_new(self, user_url, path_id, category):
"""
status=0 base中包含未覆盖,status=1 base中包含已覆盖,status=2 base中不包含且覆盖到的;
path_id表示URL的handler_context的唯一标识,查看详情用
Expand All @@ -75,17 +78,45 @@ def merge_handler_new(self, user_url, path_id):
specific_dic = specific_filter_list[0]
# 移除掉对应的数据为插入index0的位置做前置处理
app_context.merge_list.remove(specific_dic)
# 做业务处理
if specific_dic['status'] == 0:
specific_dic['status'] = 1
# 把首次覆盖到的API,放入user_list里面
app_context.user_list.append(user_url)
# 根据数据源,进行业务处理
if app_context.is_api_base_data:
category_dic = specific_dic.get('category')
for p in category_dic:
if category == p['name'] and p['status'] == 0:
p['status'] = 1
p['count'] += 1
p['id'] = path_id
if specific_dic['status'] == 0:
specific_dic['status'] = 1
# 把首次覆盖到的API,放入user_list里面
app_context.user_list.append(user_url)
else:
# 非接口获取base数据
if specific_dic['status'] == 0:
specific_dic['status'] = 1
# 把首次覆盖到的API,放入user_list里面
app_context.user_list.append(user_url)
# count +1
specific_dic['count'] += 1 # 插入原始url # specific_dic['org'].append(org_url)
specific_dic['id'] = path_id
else:
# specific_dic = {'url': user_url, 'desc': '', 'priority': '', 'count': 1, 'status': 2, 'org': [org_url]}
specific_dic = {'url': user_url, 'desc': '', 'priority': None, 'count': 1, 'status': 2, 'id': path_id}
if app_context.is_api_base_data:
specific_dic = {
'url': user_url,
'desc': '',
'priority': None,
'status': 2,
'count': 1,
'category': []
}
specific_dic['category'].append({
'id': None,
'name': category,
'status': 2,
'count': 1
})
else:
specific_dic = {'url': user_url, 'desc': '', 'priority': None, 'count': 1, 'status': 2, 'id': path_id}
# 插入到 index=0 的位置
app_context.merge_list.insert(0, specific_dic)

Expand Down
27 changes: 17 additions & 10 deletions lyrebird_api_coverage/client/report.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from lyrebird_api_coverage.client.context import app_context
from lyrebird import report
from lyrebird import publish

"""
上报处理器,用户请求行为上报到ELK中
ps:需要在lyrebird中设定reporter相关配置
"""

class ReportHandler:
def check_url_info(self, url, device_ip):
def check_url_info(self, url, device_ip, category):
specific_list = list(filter(lambda x: x.get('url') == url, app_context.merge_list))
if specific_list and specific_list[0].get('status') == 1:
desc = specific_list[0].get('desc')
Expand All @@ -17,19 +17,26 @@ def check_url_info(self, url, device_ip):
desc = 'N/A'
count_flag = -1
priority = -1
info_dict = {'url': url, 'desc': desc, 'priority': priority, 'count_flag': count_flag,
'business': app_context.business, 'version_name': app_context.version_name,
'version_code': app_context.version_code}
info_dict = {
'coverage':{
'url': url,
'desc': desc,
'priority': priority,
'count_flag': count_flag,
'version_name': app_context.version_name,
'version_code': app_context.version_code,
'category': category
}
}
if app_context.info.get(device_ip):
# 如果有Device信息,就上报device相关的信息
info_dict.update(app_context.info.get(device_ip))
info_dict['coverage'].update(app_context.info.get(device_ip))
return info_dict


report_handler = ReportHandler()


def report_worker(url, device_ip):
update_data = report_handler.check_url_info(url, device_ip)
update_data.update({"action": "api-coverage", "user_info": app_context.user_info})
report(update_data)
def report_worker(url, device_ip, category):
update_data = report_handler.check_url_info(url, device_ip, category)
publish('coverage', update_data)
13 changes: 7 additions & 6 deletions lyrebird_api_coverage/handlers/base_source_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ def get_base_source(self):
def check_base(self, obj):
try:
# 检查base schema
check_schema(obj)
if not app_context.is_api_base_data:
check_schema(obj)
# 检查url是否有重复项存在
redundant_items = check_url_redundant(obj)
if redundant_items:
Expand All @@ -59,12 +60,12 @@ def check_base(self, obj):
resp = context.make_fail_response('导入API有重复项' + str(redundant_items))
lyrebird.publish('api_coverage', 'error', name='import_base')
return resp
# 获取base内容,解析出base的business等字段
filename = obj.get('business') + obj.get('version_name') + '.' + str(obj.get('version_code'))
# 获取base内容,解析出base的business等字段
filename = f'''{obj.get('business','')}{obj.get('version_name','')}{obj.get('version_code','')}'''
app_context.filename = filename
app_context.business = obj.get('business')
app_context.version_name = obj.get('version_name')
app_context.version_code = obj.get('version_code')
app_context.business = obj.get('business', '')
app_context.version_name = obj.get('version_name', '--')
app_context.version_code = obj.get('version_code', '--')
return
except Exception as e:
resp = context.make_fail_response(f'导入文件有误: {e}\n请重新import base')
Expand Down
Loading

0 comments on commit 84bafc4

Please sign in to comment.