From ec36a494fe108e4cd00bc8d6dbd140c210d8549d Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 6 Mar 2014 12:52:14 +0100 Subject: [PATCH 01/19] [FIX] do not expose posix only config options on windows bzr revid: chs@openerp.com-20140306115214-8wrfivy4runpzoar --- openerp/service/server.py | 7 ++++- openerp/tools/config.py | 62 +++++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/openerp/service/server.py b/openerp/service/server.py index 3d02215bbe6..974068c2b9c 100644 --- a/openerp/service/server.py +++ b/openerp/service/server.py @@ -9,7 +9,10 @@ import os.path import platform import psutil import random -import resource +if os.name == 'posix': + import resource +else: + resource = None import select import signal import socket @@ -638,6 +641,8 @@ class Worker(object): raise def process_limit(self): + if resource is None: + return # If our parent changed sucide if self.ppid != os.getppid(): _logger.info("Worker (%s) Parent changed", self.pid) diff --git a/openerp/tools/config.py b/openerp/tools/config.py index b6d239d75a8..255a065aa4f 100644 --- a/openerp/tools/config.py +++ b/openerp/tools/config.py @@ -252,7 +252,8 @@ class configmanager(object): # Advanced options group = optparse.OptionGroup(parser, "Advanced options") - group.add_option('--auto-reload', dest='auto_reload', action='store_true', my_default=False, help='enable auto reload') + if os.name == 'posix': + group.add_option('--auto-reload', dest='auto_reload', action='store_true', my_default=False, help='enable auto reload') group.add_option('--debug', dest='debug_mode', action='store_true', my_default=False, help='enable debug mode') group.add_option("--stop-after-init", action="store_true", dest="stop_after_init", my_default=False, help="stop the server after its initialization") @@ -274,27 +275,28 @@ class configmanager(object): help="Use the unaccent function provided by the database when available.") parser.add_option_group(group) - group = optparse.OptionGroup(parser, "Multiprocessing options") - # TODO sensible default for the three following limits. - group.add_option("--workers", dest="workers", my_default=0, - help="Specify the number of workers, 0 disable prefork mode.", - type="int") - group.add_option("--limit-memory-soft", dest="limit_memory_soft", my_default=2048 * 1024 * 1024, - help="Maximum allowed virtual memory per worker, when reached the worker be reset after the current request (default 671088640 aka 640MB).", - type="int") - group.add_option("--limit-memory-hard", dest="limit_memory_hard", my_default=2560 * 1024 * 1024, - help="Maximum allowed virtual memory per worker, when reached, any memory allocation will fail (default 805306368 aka 768MB).", - type="int") - group.add_option("--limit-time-cpu", dest="limit_time_cpu", my_default=60, - help="Maximum allowed CPU time per request (default 60).", - type="int") - group.add_option("--limit-time-real", dest="limit_time_real", my_default=120, - help="Maximum allowed Real time per request (default 120).", - type="int") - group.add_option("--limit-request", dest="limit_request", my_default=8192, - help="Maximum number of request to be processed per worker (default 8192).", - type="int") - parser.add_option_group(group) + if os.name == 'posix': + group = optparse.OptionGroup(parser, "Multiprocessing options") + # TODO sensible default for the three following limits. + group.add_option("--workers", dest="workers", my_default=0, + help="Specify the number of workers, 0 disable prefork mode.", + type="int") + group.add_option("--limit-memory-soft", dest="limit_memory_soft", my_default=2048 * 1024 * 1024, + help="Maximum allowed virtual memory per worker, when reached the worker be reset after the current request (default 671088640 aka 640MB).", + type="int") + group.add_option("--limit-memory-hard", dest="limit_memory_hard", my_default=2560 * 1024 * 1024, + help="Maximum allowed virtual memory per worker, when reached, any memory allocation will fail (default 805306368 aka 768MB).", + type="int") + group.add_option("--limit-time-cpu", dest="limit_time_cpu", my_default=60, + help="Maximum allowed CPU time per request (default 60).", + type="int") + group.add_option("--limit-time-real", dest="limit_time_real", my_default=120, + help="Maximum allowed Real time per request (default 120).", + type="int") + group.add_option("--limit-request", dest="limit_request", my_default=8192, + help="Maximum number of request to be processed per worker (default 8192).", + type="int") + parser.add_option_group(group) # Copy all optparse options (i.e. MyOption) into self.options. for group in parser.option_groups: @@ -405,12 +407,22 @@ class configmanager(object): 'list_db', 'xmlrpcs', 'proxy_mode', 'test_file', 'test_enable', 'test_commit', 'test_report_directory', 'osv_memory_count_limit', 'osv_memory_age_limit', 'max_cron_threads', 'unaccent', - 'workers', 'limit_memory_hard', 'limit_memory_soft', 'limit_time_cpu', 'limit_time_real', 'limit_request', - 'auto_reload', 'data_dir', + 'data_dir', ] + posix_keys = [ + 'auto_reload', 'workers', + 'limit_memory_hard', 'limit_memory_soft', + 'limit_time_cpu', 'limit_time_real', 'limit_request', + ] + + if os.name == 'posix': + keys += posix_keys + else: + self.options.update(dict.fromkeys(posix_keys, None)) + + # Copy the command-line arguments... for arg in keys: - # Copy the command-line argument... if getattr(opt, arg) is not None: self.options[arg] = getattr(opt, arg) # ... or keep, but cast, the config file value. From 1a38a08687227a7947cee723f7a3ace7b245ef8d Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 6 Mar 2014 17:05:00 +0100 Subject: [PATCH 02/19] [FIX] setup.py: pywebdav does not expose DAV import anymore bzr revid: chs@openerp.com-20140306160500-ey6o7iiiy1wmvkpp --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 05178fb12ac..a44e26fd36f 100644 --- a/setup.py +++ b/setup.py @@ -75,7 +75,7 @@ def py2exe_options(): "skip_archive": 1, "optimize": 0, # keep the assert running, because the integrated tests rely on them. "dist_dir": 'dist', - "packages": [ "DAV", "HTMLParser", "PIL", "asynchat", "asyncore", "commands", "dateutil", "decimal", "docutils", "email", "encodings", "imaplib", "jinja2", "lxml", "lxml._elementpath", "lxml.builder", "lxml.etree", "lxml.objectify", "mako", "openerp", "poplib", "pychart", "pydot", "pyparsing", "pytz", "reportlab", "select", "simplejson", "smtplib", "uuid", "vatnumber", "vobject", "xml", "xml.dom", "yaml", ], + "packages": ["HTMLParser", "PIL", "asynchat", "asyncore", "commands", "dateutil", "decimal", "docutils", "email", "encodings", "imaplib", "jinja2", "lxml", "lxml._elementpath", "lxml.builder", "lxml.etree", "lxml.objectify", "mako", "openerp", "poplib", "pychart", "pydot", "pyparsing", "pytz", "reportlab", "select", "simplejson", "smtplib", "uuid", "vatnumber", "vobject", "xml", "xml.dom", "yaml", ], "excludes" : ["Tkconstants","Tkinter","tcl"], } } From c878b34c3e3ef5808de3235ac69588835dad236c Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Thu, 6 Mar 2014 23:19:47 +0100 Subject: [PATCH 03/19] [FIX] --test-file regression introduced by chs bzr revid: al@openerp.com-20140306221947-ex5nk6mu2py0zinh --- openerp/service/server.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openerp/service/server.py b/openerp/service/server.py index 974068c2b9c..f9db66a28ef 100644 --- a/openerp/service/server.py +++ b/openerp/service/server.py @@ -851,7 +851,8 @@ def load_test_file_py(registry, test_file): stream = openerp.modules.module.TestStream() result = unittest2.TextTestRunner(verbosity=2, stream=stream).run(suite) success = result.wasSuccessful() - registry._assertion_report.report_result(success) + if hasattr(registry._assertion_report,'report_result'): + registry._assertion_report.report_result(success) if not success: _logger.error('%s: at least one error occurred in a test', test_file) From 3aa98edaaf439196f1145beb95eb6caf760a775e Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Fri, 7 Mar 2014 00:45:35 +0100 Subject: [PATCH 04/19] [IMP] test add an url_open helper to http case bzr revid: al@openerp.com-20140306234535-9zhumihumbzcddb2 --- openerp/tests/common.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/openerp/tests/common.py b/openerp/tests/common.py index b68bbfe20df..75207841454 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -13,6 +13,7 @@ import subprocess import threading import time import unittest2 +import urllib2 import xmlrpclib import openerp @@ -150,7 +151,7 @@ class SingleTransactionCase(BaseCase): class HttpCase(TransactionCase): - """ Transactionnal HTTP TestCase with a phantomjs helper. + """ Transactionnal HTTP TestCase with url_open and phantomjs helpers. """ def __init__(self, methodName='runTest'): @@ -171,11 +172,17 @@ class HttpCase(TransactionCase): self.cr._test_lock = threading.RLock() HTTP_SESSION[self.session_id] = self.cr - def tearDown(self): del HTTP_SESSION[self.session_id] super(HttpCase, self).tearDown() + def url_open(self, url, data=None, timeout=10): + opener = urllib2.build_opener() + opener.addheaders.append(('Cookie', 'session_id=%s' % self.session_id)) + if url.startswith('/'): + url = "http://localhost:%s%s" % (PORT, url) + return opener.open(url, data, timeout) + def phantom_poll(self, phantom, timeout): """ Phantomjs Test protocol. From cfb50cf7a94e430772f0b99a84bd299c3ed038c1 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Fri, 7 Mar 2014 00:46:57 +0100 Subject: [PATCH 05/19] [IMP] ir.actions.report.xml improve view, move rml specific fiels in a tab bzr revid: al@openerp.com-20140306234657-kblucn86ph9gjfu6 --- openerp/addons/base/ir/ir_actions.py | 35 ++++++++++++++------------- openerp/addons/base/ir/ir_actions.xml | 30 ++++++++++------------- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 9adbf2c608f..aa37d8cd61f 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -135,35 +135,36 @@ class ir_actions_report_xml(osv.osv): _sequence = 'ir_actions_id_seq' _order = 'name' _columns = { - 'name': fields.char('Name', size=64, required=True, translate=True), - 'model': fields.char('Object', size=64, required=True), 'type': fields.char('Action Type', size=32, required=True), - 'report_name': fields.char('Service Name', size=64, required=True), - 'usage': fields.char('Action Usage', size=32), - 'report_type': fields.char('Report Type', size=32, required=True, help="Report Type, e.g. pdf, html, raw, sxw, odt, html2html, mako2html, ..."), + 'name': fields.char('Name', size=64, required=True, translate=True), + + 'model': fields.char('Model', required=True), + 'report_type': fields.char('Report Type', required=True, help="Report Type: qweb-html, qweb-pdf, custom"), + 'report_name': fields.char('Service Name', required=True, help="URL of the report is /report//"), 'groups_id': fields.many2many('res.groups', 'res_groups_report_rel', 'uid', 'gid', 'Groups'), + + # options 'multi': fields.boolean('On Multiple Doc.', help="If set to true, the action will not be displayed on the right toolbar of a form view."), - 'attachment': fields.char('Save as Attachment Prefix', size=128, help='This is the filename of the attachment used to store the printing result. Keep empty to not save the printed reports. You can use a python expression with the object and time variables.'), 'attachment_use': fields.boolean('Reload from Attachment', help='If you check this, then the second time the user prints with same attachment name, it returns the previous report.'), + 'attachment': fields.char('Save as Attachment Prefix', size=128, help='This is the filename of the attachment used to store the printing result. Keep empty to not save the printed reports. You can use a python expression with the object and time variables.'), + + # Deprecated rml stuff + 'usage': fields.char('Action Usage', size=32), + 'header': fields.boolean('Add RML Header', help="Add or not the corporate RML header"), + 'parser': fields.char('Parser Class'), 'auto': fields.boolean('Custom Python Parser'), - 'header': fields.boolean('Add RML Header', help="Add or not the corporate RML header"), + 'report_xsl': fields.char('XSL Path'), + 'report_xml': fields.char('XML Path'), - 'report_xsl': fields.char('XSL Path', size=256), - 'report_xml': fields.char('XML Path', size=256, help=''), - - # Pending deprecation... to be replaced by report_file as this object will become the default report object (not so specific to RML anymore) - 'report_rml': fields.char('Main Report File Path', size=256, help="The path to the main report file (depending on Report Type) or NULL if the content is in another data field"), - # temporary related field as report_rml is pending deprecation - this field will replace report_rml after v6.0 - 'report_file': fields.related('report_rml', type="char", size=256, required=False, readonly=False, string='Report File', help="The path to the main report file (depending on Report Type) or NULL if the content is in another field", store=True), + 'report_rml': fields.char('Main Report File Path', help="The path to the main report file (depending on Report Type) or NULL if the content is in another data field"), + 'report_file': fields.related('report_rml', type="char", required=False, readonly=False, string='Report File', help="The path to the main report file (depending on Report Type) or NULL if the content is in another field", store=True), 'report_sxw': fields.function(_report_sxw, type='char', string='SXW Path'), 'report_sxw_content_data': fields.binary('SXW Content'), 'report_rml_content_data': fields.binary('RML Content'), 'report_sxw_content': fields.function(_report_content, fnct_inv=_report_content_inv, type='binary', string='SXW Content',), 'report_rml_content': fields.function(_report_content, fnct_inv=_report_content_inv, type='binary', string='RML Content'), - - 'parser': fields.char('Parser Class'), } _defaults = { 'type': 'ir.actions.report.xml', @@ -171,7 +172,7 @@ class ir_actions_report_xml(osv.osv): 'auto': True, 'header': True, 'report_sxw_content': False, - 'report_type': 'pdf', + 'report_type': 'qweb-pdf', 'attachment': False, } diff --git a/openerp/addons/base/ir/ir_actions.xml b/openerp/addons/base/ir/ir_actions.xml index 26c08d4f1b0..0bc8c9906a8 100644 --- a/openerp/addons/base/ir/ir_actions.xml +++ b/openerp/addons/base/ir/ir_actions.xml @@ -57,39 +57,35 @@ - + + - - - + + + - + + + + + + + + - - - - - - - - - - - - From cb82d9379613cd91dede6c5d1ad0e919e2a72874 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Fri, 7 Mar 2014 01:06:20 +0100 Subject: [PATCH 06/19] [IMP] report form view move inherited view, restore and refactor test case (kept commented atm) from non merged branch qweb-report bzr revid: al@openerp.com-20140307000620-kqxm55smy34nc0zz --- addons/report/__init__.py | 1 + addons/report/__openerp__.py | 3 +- addons/report/tests/__init__.py | 1 + addons/report/tests/test_reports.py | 26 +++++ .../views/{paperformat_view.xml => views.xml} | 95 ++++++++++--------- 5 files changed, 81 insertions(+), 45 deletions(-) create mode 100644 addons/report/tests/__init__.py create mode 100644 addons/report/tests/test_reports.py rename addons/report/views/{paperformat_view.xml => views.xml} (70%) diff --git a/addons/report/__init__.py b/addons/report/__init__.py index d08c9d29951..12d9fe89642 100644 --- a/addons/report/__init__.py +++ b/addons/report/__init__.py @@ -1,3 +1,4 @@ import controllers import models +import tests diff --git a/addons/report/__openerp__.py b/addons/report/__openerp__.py index 8ce4e46991c..c07cdc44403 100644 --- a/addons/report/__openerp__.py +++ b/addons/report/__openerp__.py @@ -10,8 +10,7 @@ Report 'depends': ['base'], 'data': [ 'views/layouts.xml', - 'views/paperformat_view.xml', - 'views/res_company_view.xml', + 'views/views.xml', 'data/report_paperformat.xml', 'security/ir.model.access.csv', ], diff --git a/addons/report/tests/__init__.py b/addons/report/tests/__init__.py new file mode 100644 index 00000000000..fc192463ec6 --- /dev/null +++ b/addons/report/tests/__init__.py @@ -0,0 +1 @@ +import test_reports diff --git a/addons/report/tests/test_reports.py b/addons/report/tests/test_reports.py new file mode 100644 index 00000000000..361e0a7aa0f --- /dev/null +++ b/addons/report/tests/test_reports.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +import logging + +import openerp +import urllib2 + +_logger = logging.getLogger(__name__) + +class TestReports(openerp.tests.HttpCase): + def test_reports(self): + registry, cr, uid = self.registry, self.cr, self.uid + r_model = registry('ir.actions.report.xml') + domain = [('report_type','like','qweb')] + for r in r_model.browse(cr, uid, r_model.search(cr, uid, domain)): + report_model = registry(r.model) + report_model_ids = report_model.search(cr, uid, [], limit=10) + if not report_model_ids: + _logger.info("no record found skipping report %s", r.report_name) + continue + if not r.multi: + report_model_ids = report_model_ids[:1] + url = "/report/%s/%s" % (r.report_name, ','.join(str(i) for i in report_model_ids)) + _logger.info("testing report %s", url) + # TODO sle: uncomment this + #content = self.url_open(url) + diff --git a/addons/report/views/paperformat_view.xml b/addons/report/views/views.xml similarity index 70% rename from addons/report/views/paperformat_view.xml rename to addons/report/views/views.xml index c885261416b..6de16c8b040 100644 --- a/addons/report/views/paperformat_view.xml +++ b/addons/report/views/views.xml @@ -2,27 +2,7 @@ - - - act_report_xml_view_inherit - - ir.actions.report.xml - - - - -