improvement of base_module_quality:

*changed signature of run_test() method, added cr and uid
*switched wizard to osv_memory, to use text_wiki in the result window
*improved method_test.py, added score computation, corrected self.bool_installed_only var, use text_wiki widget
*implemented speed_test.py, first throw
*improvement of base_module_quality/wizard/module_quality_check.py

bzr revid: qdp@tinyerp.com-20081223155847-4qm6095jomgwvuju
This commit is contained in:
qdp
2008-12-23 16:58:47 +01:00
parent 5daa2f6a58
commit cd6b3e1941
6 changed files with 166 additions and 52 deletions
@@ -49,7 +49,7 @@ class abstract_quality_check(object):
'''
raise 'Not Implemented'
def run_test(self, module_path=""):
def run_test(self, cr, uid, module_path=""):
'''
this method should do the test and fill the score, result and result_details var
'''
@@ -1,6 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<wizard id="base_module_quality" model="ir.module.module" name="base.module.quality" string="Check the Quality of module"/>
<!--<wizard id="base_module_quality" model="ir.module.module" name="base.module.quality" string="Check the Quality of module"/>-->
<record id="view_wizard_quality_check" model="ir.ui.view">
<field name="name">Results of Quality Checks</field>
<field name="model">wizard.quality.check</field>
<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"/>
</form>
</field>
</record>
<act_window
id="act_view_wiz_quality_check"
name="wizard quality chekc"
res_model="wizard.quality.check"
src_model="ir.module.module"
target="new"
view_mode="form"
context="{'module_id': active_id}"
/>
</data>
</openerp>
</openerp>
@@ -31,52 +31,63 @@ class quality_test(base_module_quality.abstract_quality_check):
def __init__(self):
self.result = """
Method Test:
------------
===Method Test===
This test checks if the class method has exception or not.
This test checks if the module classes are raising exception when calling basic methods or no.
"""
self.bool_installed_only = False
self.bool_installed_only = True
return None
def run_test(self, module_path, module_name=None, cr=None, uid=None):
model_list = []
def run_test(self, cr, uid, module_path):
pool = pooler.get_pool(cr.dbname)
model_obj = pool.get('ir.model.data')
ids2 = model_obj.search(cr, uid, [('module','=', module_name), ('model','=','ir.model')])
model_data = model_obj.browse(cr, uid, ids2)
module_name = module_path.split('/')[-1]
ids2 = pool.get('ir.model.data').search(cr, uid, [('module','=', module_name), ('model','=','ir.model')])
model_list = []
model_data = pool.get('ir.model.data').browse(cr, uid, ids2)
for model in model_data:
model_list.append(model.res_id)
obj_list = []
for mod in pool.get('ir.model').browse(cr, uid, model_list):
obj_list.append(str(mod.model))
result = {}
self.result += "Module Name:" + module_name + '\n' + '===============\n'
result={}
ok_count = 0
ex_count = 0
for obj in obj_list:
temp = []
try:
res = pool.get(obj).search(cr, uid, [])
temp.append('Ok')
ok_count += 1
except:
temp.append('Exception')
ex_count += 1
try:
res1 = pool.get(obj).fields_view_get(cr, uid,)
temp.append('Ok')
ok_count += 1
except:
temp.append('Exception')
ex_count += 1
try:
res2 = pool.get(obj).read(cr, uid, [])
temp.append('Ok')
ok_count += 1
except:
temp.append('Exception')
ex_count += 1
result[obj] = temp
self.result += ("%-40s %12s %16s %12s")%('Object Name'.ljust(40),'search','fields_view_get','read')
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))
for res in result:
self.result += ("%-40s %12s %16s %12s")%(res.ljust(40),result[res][0],result[res][1],result[res][2])
self.result += "\n"
self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s ') % (res, result[res][0],result[res][1], result[res][2])
self.result += '\n|}'
print "RES", self.result
self.score = (ok_count + ex_count) and float(ok_count)/float(ok_count + ex_count) or 0.0
return None
@@ -41,7 +41,7 @@ Pylint Test:
self.bool_installed_only = False
return None
def run_test(self, module_path):
def run_test(self, cr, uid, module_path):
config_file_path = config['addons_path']+'/base_module_quality/pylint_test/pylint_test_config.txt'
list_files = os.listdir(module_path)
for i in list_files:
@@ -24,6 +24,9 @@ import netsvc
from osv import fields, osv
import os
from tools import config
import pooler
import time
from base_module_quality import base_module_quality
@@ -32,19 +35,84 @@ class quality_test(base_module_quality.abstract_quality_check):
def __init__(self):
self.result = """
Speed Test:
------------
This test checks the speed of the module
===Speed Test===
to be continued...
This test checks the speed of the module.
"""
self.bool_installed_only = True
return None
def run_test(self, module_path):
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))
ids2 = pool.get('ir.model.data').search(cr, uid, [('module','=', module_name), ('model','=','ir.model')])
model_data = pool.get('ir.model.data').browse(cr, uid, ids2)
model_list = []
for model in model_data:
model_list.append(model.res_id)
obj_list = []
for mod in pool.get('ir.model').browse(cr, uid, model_list):
obj_list.append(str(mod.model))
obj_counter = 0
score = 0
for obj in obj_list:
obj_counter += 1
ids = pool.get(obj).search(cr, uid, [])
ids = ids[:100]
size = len(ids)
if size:
c1 = time.time()
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[:size/2])
c2 = time.time()
halfsize_time = c2 - c1
c1 = time.time()
pool.get(obj).read(cr, uid, ids)
c2 = time.time()
size_time = c2 - 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")
else:
tolerated_margin = 5/100
complexity = "not recognized"
if min(size_time,base_time,halfsize_time) != base_time:
complexity = "O(1)"
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)
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|}'
self.score = obj_counter and score/obj_counter or 0.0
return None
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -21,81 +21,94 @@
##############################################################################
import wizard
import pooler
from osv import osv, fields
import tools
import os
#TODO: (utiliser les nouveaux wizards pour heriter la vue et rajouter un onglet par test?)
#TODO: configure pylint
#TODO: implement the speed test
#TODO: implement the simple test
#TODO: add cheks: do the class quality_check inherits the class abstract_quality_check?
#TODO: improve translability
#TODO: clean
#To keep or not? to be discussed...
view_form = """<?xml version="1.0"?>
<form string="Check quality">
<notebook>
<page string="Summary">
<field name="general_info" nolabel="1" colspan="4" height="350" width="800"/>
</page>
</notebook>
</form>"""
#~ view_form = """<?xml version="1.0"?>
#~ <form string="Check quality">
#~ <notebook>
#~ <page string="Summary">
#~ <field name="general_info" widget="text_wiki" nolabel="1" colspan="4" height="350" width="800"/>
#~ </page>
#~ </notebook>
#~ </form>"""
view_field = {
"general_info": {'type': 'text', 'string': 'General Info', 'readonly':True},
}
#~ view_field = {
#~ "general_info": {'type': 'text', 'string': 'General Info', 'readonly':True},
#~ }
class wiz_quality_check(wizard.interface):
class wiz_quality_check(osv.osv_memory):
# general_info = ""
_name = 'wizard.quality.check'
def _check(self, cr, uid, data, context={}):
string_ret = ""
from tools import config
print data
data['ids'] = data.get('module_id', False)
pool = pooler.get_pool(cr.dbname)
module_data = pool.get('ir.module.module').browse(cr, uid, data['ids'])
module_data = pool.get('ir.module.module').browse(cr, uid, [data['ids']])
list_folders = os.listdir(config['addons_path']+'/base_module_quality/')
module_name = module_data[0].name
for item in list_folders:
path = config['addons_path']+'/base_module_quality/'+item
if os.path.exists(path+'/'+item+'.py') and item not in ['report', 'wizard', 'security']:
ad = tools.config['addons_path']
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
x = __import__(item2)
x2 = getattr(x, item)
x3 = getattr(x2, item)
val = x3.quality_test()
if (not val.bool_installed_only or module_data[0].state == "installed") and item == 'method_test':
val.run_test(str(module_path), module_name, cr, uid)
elif not val.bool_installed_only or module_data[0].state == "installed" :
val.run_test(str(module_path))
if (not val.bool_installed_only or module_data[0].state == "installed"):
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
return string_ret
return {'general_info':string_ret}
# def _general_info(self, cr, uid, data, context={}):
# return self.general_info
states = {
#~ states = {
#~ 'init': {
#~ 'actions': [_check],
#~ 'result': {'type':'form', 'arch':view_form, 'fields':view_field, 'state':[('end','Ok')]},
#~ },
#~ }
#To keep or not? to be discussed...
#~ 'init': {
#~ 'actions': [],
#~ 'result': {'type':'form', 'arch':form_check, 'fields':fields_check, 'state':[('end','Cancel'),('do','Do Test')]}
#~ },
'init': {
'actions': [_check],
'result': {'type':'form', 'arch':view_form, 'fields':view_field, 'state':[('end','Ok')]},
},
}
_columns = {
'general_info': fields.text('General Info', readonly="1",),
}
_defaults = {
'general_info': _check
}
wiz_quality_check('base.module.quality')
wiz_quality_check()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: