base module quality
bzr revid: mra@tinyerp.com-20081227091014-ds6ad7ylqtfkgi6j
This commit is contained in:
parent
988263fd7c
commit
06882ed8a0
|
@ -26,34 +26,51 @@ class abstract_quality_check(object):
|
|||
This Class provide...
|
||||
'''
|
||||
|
||||
#This float have to store the rating of the module.
|
||||
#Used to compute the final score (average of all scores).
|
||||
score = 0.0
|
||||
|
||||
#This char have to store the result.
|
||||
#Used to display the result of the test.
|
||||
result = ""
|
||||
|
||||
#This char have to store the result with more details.
|
||||
#Used to provide more details if necessary.
|
||||
result_details = ""
|
||||
|
||||
#This bool defines if the test can be run only if the module is installed.
|
||||
#True => the module have to be installed.
|
||||
#False => the module can be uninstalled.
|
||||
bool_installed_only = True
|
||||
# #This float have to store the rating of the module.
|
||||
# #Used to compute the final score (average of all scores).
|
||||
# score = 0.0
|
||||
#
|
||||
# #This char have to store the result.
|
||||
# #Used to display the result of the test.
|
||||
# result = ""
|
||||
#
|
||||
# #This char have to store the result with more details.
|
||||
# #Used to provide more details if necessary.
|
||||
# result_details = ""
|
||||
#
|
||||
# #This bool defines if the test can be run only if the module is installed.
|
||||
# #True => the module have to be installed.
|
||||
# #False => the module can be uninstalled.
|
||||
# bool_installed_only = True
|
||||
|
||||
def __init__(self):
|
||||
'''
|
||||
this method should initialize the var
|
||||
'''
|
||||
raise 'Not Implemented'
|
||||
#This float have to store the rating of the module.
|
||||
#Used to compute the final score (average of all scores).
|
||||
self.score = 0.0
|
||||
|
||||
#This char have to store the result.
|
||||
#Used to display the result of the test.
|
||||
self.result = ""
|
||||
|
||||
#This char have to store the result with more details.
|
||||
#Used to provide more details if necessary.
|
||||
self.result_details = ""
|
||||
|
||||
#This bool defines if the test can be run only if the module is installed.
|
||||
#True => the module have to be installed.
|
||||
#False => the module can be uninstalled.
|
||||
self.bool_installed_only = True
|
||||
|
||||
# raise 'Not Implemented'
|
||||
|
||||
def run_test(self, cr, uid, module_path=""):
|
||||
'''
|
||||
this method should do the test and fill the score, result and result_details var
|
||||
'''
|
||||
raise 'Not Implemented'
|
||||
# raise 'Not Implemented'
|
||||
|
||||
def get_objects(self, cr, uid, module):
|
||||
# This function returns all object of the given module..
|
||||
|
@ -77,5 +94,30 @@ class abstract_quality_check(object):
|
|||
result_ids[obj] = ids
|
||||
return result_ids
|
||||
|
||||
def format_table(self, test='', header=[], data_list=[]):
|
||||
res_format = {}
|
||||
if test=='method':
|
||||
detail = ""
|
||||
detail += "\n===Method Test===\n"
|
||||
detail += ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-16s \n! %-20s \n! %-16s ') % (header[0].ljust(40), header[1].ljust(16), header[2].ljust(20), header[3].ljust(16))
|
||||
for res in data_list[1][0]:
|
||||
detail += ('\n|-\n| %s \n| %s \n| %s \n| %s ') % (res, data_list[1][0][res][0], data_list[1][0][res][1], data_list[1][0][res][2])
|
||||
res_format['summary'] = [data_list[0][0]]
|
||||
res_format['detail'] = [detail + '\n|}']
|
||||
elif test=='pylint':
|
||||
res_format['summary'] = data_list[0]
|
||||
res_format['detail'] = data_list[1]
|
||||
elif test=='speed':
|
||||
detail = ""
|
||||
detail += "\n===Speed Test===\n"
|
||||
detail += ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n! %-10s \n! %-10s \n! %-10s \n! %-20s') % (header[0].ljust(40), header[1].ljust(10), header[2].ljust(10), header[3].ljust(10), header[4].ljust(10), header[5].ljust(20))
|
||||
for data in data_list[1]:
|
||||
detail += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (data[0], data[1], data[2], data[3], data[4], data[5])
|
||||
res_format['summary'] = data_list[0]
|
||||
res_format['detail'] = [detail + '\n|}\n']
|
||||
return res_format
|
||||
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -9,8 +9,20 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Result">
|
||||
<separator string="Summary" colspan="4"/>
|
||||
<field name="general_info" widget="text_wiki" nolabel="1" colspan="4" height="350" width="800"/>
|
||||
<notebook>
|
||||
<page string="Summary">
|
||||
<!-- <separator string="Summary" colspan="4"/>-->
|
||||
<field name="general_info" widget="text_wiki" nolabel="1" colspan="4" height="350" width="800"/>
|
||||
</page>
|
||||
<page string="Detail">
|
||||
<!-- <separator string="Detail" colspan="4"/>-->
|
||||
<field name="detail" widget="text_wiki" nolabel="1" colspan="4" height="350" width="800"/>
|
||||
</page>
|
||||
<page string="Verbose detail">
|
||||
<!-- <separator string="Verbose detail" colspan="4"/>-->
|
||||
<field name="verbose_detail" widget="text_wiki" nolabel="1" colspan="4" height="350" width="800"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -30,12 +30,13 @@ import pooler
|
|||
class quality_test(base_module_quality.abstract_quality_check):
|
||||
|
||||
def __init__(self):
|
||||
self.result = """
|
||||
===Method Test===:
|
||||
|
||||
This test checks if the module classes are raising exception when calling basic methods or no.
|
||||
|
||||
"""
|
||||
super(quality_test, self).__init__()
|
||||
# self.result = """
|
||||
#===Method Test===:
|
||||
#
|
||||
#This test checks if the module classes are raising exception when calling basic methods or no.
|
||||
#
|
||||
#"""
|
||||
self.bool_installed_only = True
|
||||
return None
|
||||
|
||||
|
@ -46,7 +47,6 @@ This test checks if the module classes are raising exception when calling basic
|
|||
result = {}
|
||||
ok_count = 0
|
||||
ex_count = 0
|
||||
|
||||
for obj in obj_list:
|
||||
temp = []
|
||||
try:
|
||||
|
@ -71,13 +71,18 @@ This test checks if the module classes are raising exception when calling basic
|
|||
temp.append('Exception')
|
||||
ex_count += 1
|
||||
result[obj] = temp
|
||||
self.result += ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-16s \n! %-20s \n! %-16s ') % ('Object Name'.ljust(40), 'search()'.ljust(16), 'fields_view_get()'.ljust(20), 'read()'.ljust(16))
|
||||
|
||||
for res in result:
|
||||
self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s ') % (res, result[res][0],result[res][1], result[res][2])
|
||||
|
||||
self.result += '\n|}'
|
||||
# self.result += ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-16s \n! %-20s \n! %-16s ') % ('Object Name'.ljust(40), 'search()'.ljust(16), 'fields_view_get()'.ljust(20), 'read()'.ljust(16))
|
||||
header_list = ['Object Name', 'search()', 'fields_view_get', 'read']
|
||||
# for res in result:
|
||||
# self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s ') % (res, result[res][0],result[res][1], result[res][2])
|
||||
# self.result += '\n|}'
|
||||
self.score = (ok_count + ex_count) and float(ok_count)/float(ok_count + ex_count) or 0.0
|
||||
summary = """\n ===Method Test===:
|
||||
|
||||
This test checks if the module classes are raising exception when calling basic methods or no.
|
||||
|
||||
""" + "Score: " + str(self.score) + "/10\n"
|
||||
self.result = self.format_table(test='method', header=header_list, data_list=[[summary],[result]])
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
@ -30,12 +30,13 @@ from base_module_quality import base_module_quality
|
|||
class quality_test(base_module_quality.abstract_quality_check):
|
||||
|
||||
def __init__(self):
|
||||
self.result = """
|
||||
===Pylint Test===:
|
||||
|
||||
This test checks if the module satisfy the current coding standard used by OpenERP.
|
||||
|
||||
"""
|
||||
super(quality_test, self).__init__()
|
||||
# self.result = """
|
||||
#===Pylint Test===:
|
||||
#
|
||||
# This test checks if the module satisfy the current coding standard used by OpenERP.
|
||||
#
|
||||
#"""
|
||||
self.bool_installed_only = False
|
||||
return None
|
||||
|
||||
|
@ -50,6 +51,8 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
|
||||
n = 0
|
||||
score = 0.0
|
||||
detail = ""
|
||||
detail = "\n===Pylint Test===\n"
|
||||
for file in list_files:
|
||||
if file.split('.')[-1] == 'py' and not file.endswith('__init__.py') and not file.endswith('__terp__.py'):
|
||||
file_path = os.path.join(module_path, file)
|
||||
|
@ -64,13 +67,21 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
|
||||
try:
|
||||
score += float(res[leftchar+1:rightchar])
|
||||
self.result += file + ": " + res[leftchar+1:rightchar] + "/10\n"
|
||||
# self.result += file + ": " + res[leftchar+1:rightchar] + "/10\n"
|
||||
detail += file + ": " + res[leftchar+1:rightchar] + "/10\n"
|
||||
except:
|
||||
score += 0
|
||||
self.result += file + ": Unable to parse the result. Check the details.\n"
|
||||
|
||||
# self.result += file + ": Unable to parse the result. Check the details.\n"
|
||||
detail += file + ": Unable to parse the result. Check the details.\n"
|
||||
self.result_details += res
|
||||
self.score = n and score / n or score
|
||||
summary ="""
|
||||
===Pylint Test===:
|
||||
|
||||
This test checks if the module satisfy the current coding standard used by OpenERP.
|
||||
|
||||
""" + "Score: " + str(self.score) + "/10\n"
|
||||
self.result = self.format_table(test='pylint', data_list=[[summary],[detail]])
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
@ -34,74 +34,75 @@ from base_module_quality import base_module_quality
|
|||
class quality_test(base_module_quality.abstract_quality_check):
|
||||
|
||||
def __init__(self):
|
||||
self.result = """
|
||||
===Speed Test===:
|
||||
|
||||
This test checks the speed of the module.
|
||||
|
||||
"""
|
||||
super(quality_test, self).__init__()
|
||||
# self.result = """
|
||||
#===Speed Test===:
|
||||
#
|
||||
#This test checks the speed of the module.
|
||||
#
|
||||
#"""
|
||||
self.bool_installed_only = True
|
||||
return None
|
||||
|
||||
def run_test(self, cr, uid, module_path):
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
module_name = module_path.split('/')[-1]
|
||||
self.result+=('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n! %-10s \n! %-10s \n! %-10s \n! %-20s') % ('Object Name'.ljust(40), 'Size (S)'.ljust(10), '1'.ljust(10), 'S/2'.ljust(10), 'S'.ljust(10), 'Complexity'.ljust(20))
|
||||
# self.result+=('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n! %-10s \n! %-10s \n! %-10s \n! %-20s') % ('Object Name'.ljust(40), 'Size-Number of Records (S)'.ljust(10), '1'.ljust(10), 'S/2'.ljust(10), 'S'.ljust(10), 'Complexity using query'.ljust(20))
|
||||
header_list = ['Object Name', 'Size-Number of Records (S)', '1', 'S/2', 'S', 'Complexity using query']
|
||||
obj_list = self.get_objects(cr, uid, module_name)
|
||||
obj_counter = 0
|
||||
score = 0
|
||||
obj_ids = self.get_ids(cr, uid, obj_list)
|
||||
detail = ""
|
||||
list1 = []
|
||||
for obj in obj_ids:
|
||||
obj_counter += 1
|
||||
ids = obj_ids[obj]
|
||||
ids = ids[:100]
|
||||
size = len(ids)
|
||||
if size:
|
||||
c1 = time.time()
|
||||
c1 = cr.count
|
||||
|
||||
pool.get(obj).read(cr, uid, ids[0])
|
||||
c2 = time.time()
|
||||
base_time = c2 - c1
|
||||
c1 = time.time()
|
||||
pool.get(obj).read(cr, uid, ids[0])
|
||||
code_base_complexity = cr.count - c1
|
||||
|
||||
pool.get(obj).read(cr, uid, ids[:size/2])
|
||||
c2 = time.time()
|
||||
halfsize_time = c2 - c1
|
||||
c1 = time.time()
|
||||
pool.get(obj).read(cr, uid, ids[:size/2])
|
||||
code_half_complexity = cr.count - c1
|
||||
|
||||
pool.get(obj).read(cr, uid, ids)
|
||||
c2 = time.time()
|
||||
size_time = c2 - c1
|
||||
pool.get(obj).read(cr, uid, ids)
|
||||
code_size_complexity = cr.count - c1
|
||||
|
||||
if size < 5:
|
||||
self.score += -2
|
||||
self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, base_time, halfsize_time, size_time, "Warning! Not enough demo data")
|
||||
# self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, code_base_complexity, code_half_complexity, code_size_complexity, "Warning! Not enough demo data")
|
||||
list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, "Warning! Not enough demo data"]
|
||||
list1.append(list)
|
||||
else:
|
||||
tolerated_margin = 5/100
|
||||
complexity = "not recognized"
|
||||
if min(size_time,base_time,halfsize_time) != base_time:
|
||||
if code_size_complexity <= (code_base_complexity + size):
|
||||
complexity = "O(1)"
|
||||
score += 10
|
||||
|
||||
score = 10
|
||||
else:
|
||||
k1 = (halfsize_time - base_time)*1000 / ((size/2) - 1)
|
||||
k2 = (size_time - base_time)*1000 / ((size) - 1)
|
||||
tmp = k1 * tolerated_margin
|
||||
if (k1 - tmp) < k2 and k2 < (k1 + tmp):
|
||||
complexity = "O(n)"
|
||||
if round(tmp) == 0:
|
||||
complexity = "O(1)"
|
||||
score += 10
|
||||
else:
|
||||
score += 5
|
||||
else:
|
||||
complexity = "O(n²) or worst"
|
||||
score += 0
|
||||
|
||||
self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, base_time, halfsize_time, size_time, complexity)
|
||||
complexity = "O(n) or worst"
|
||||
score = 0
|
||||
# self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, code_base_complexity, code_half_complexity, code_size_complexity, complexity)
|
||||
list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, complexity]
|
||||
list1.append(list)
|
||||
else:
|
||||
score += -5
|
||||
self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, "", "", "", "Warning! Object has no demo data")
|
||||
|
||||
|
||||
self.result += '\n|}\n'
|
||||
# self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, "", "", "", "Warning! Object has no demo data")
|
||||
list = [obj, size, "", "", "", "Warning! Object has no demo data"]
|
||||
list1.append(list)
|
||||
# self.result += '\n|}\n'
|
||||
self.score = obj_counter and score/obj_counter or 0.0
|
||||
summary = """
|
||||
===Speed Test===:
|
||||
|
||||
This test checks the speed of the module.
|
||||
|
||||
"""+ "Score: " + str(self.score) + "/10\n"
|
||||
self.result = self.format_table(test='speed', header=header_list, data_list=[[summary],list1])
|
||||
return None
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -56,9 +56,9 @@ class wiz_quality_check(osv.osv_memory):
|
|||
# general_info = ""
|
||||
_name = 'wizard.quality.check'
|
||||
|
||||
|
||||
def _check(self, cr, uid, data, context={}):
|
||||
string_ret = ""
|
||||
string_detail = ""
|
||||
from tools import config
|
||||
data['ids'] = data.get('module_id', False)
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
|
@ -72,7 +72,7 @@ class wiz_quality_check(osv.osv_memory):
|
|||
if module_data[0].name == 'base':
|
||||
ad = tools.config['root_path']+'/addons'
|
||||
module_path = os.path.join(ad, module_data[0].name)
|
||||
item2 = 'base_module_quality.'+item+'.'+item
|
||||
item2 = 'base_module_quality.' + item +'.' + item
|
||||
x = __import__(item2)
|
||||
x2 = getattr(x, item)
|
||||
x3 = getattr(x2, item)
|
||||
|
@ -81,9 +81,14 @@ class wiz_quality_check(osv.osv_memory):
|
|||
val.run_test(cr, uid, str(module_path))
|
||||
else:
|
||||
val.result += "The module has to be installed before running this test."
|
||||
string_ret += val.result
|
||||
string_ret += val.result['summary'][0]
|
||||
string_detail += val.result['detail'][0]
|
||||
self.string_detail = string_detail
|
||||
return string_ret
|
||||
|
||||
def _check_detail(self, cr, uid, data, context={}):
|
||||
return self.string_detail
|
||||
|
||||
# def _general_info(self, cr, uid, data, context={}):
|
||||
# return self.general_info
|
||||
|
||||
|
@ -102,9 +107,12 @@ class wiz_quality_check(osv.osv_memory):
|
|||
#~ },
|
||||
_columns = {
|
||||
'general_info': fields.text('General Info', readonly="1",),
|
||||
'detail' : fields.text('Detail', readonly="1",),
|
||||
'verbose_detail' : fields.text('Verbose Detail', readonly="1",)
|
||||
}
|
||||
_defaults = {
|
||||
'general_info': _check
|
||||
'general_info': _check,
|
||||
'detail': _check_detail
|
||||
}
|
||||
|
||||
wiz_quality_check()
|
||||
|
|
Loading…
Reference in New Issue