<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
#    The refactoring about the OpenSSL support come from Tryton
#    Copyright (C) 2007-2009 Cédric Krier.
#    Copyright (C) 2007-2009 Bertrand Chenal.
#    Copyright (C) 2008 B2CK SPRL.
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import SimpleXMLRPCServer
import SocketServer
import logging
import logging.handlers
import os
import signal
import socket
import sys
import threading
import time
import xmlrpclib
import release

class Service(object):
    """ Base class for *Local* services

        Functionality here is trusted, no authentication.
    """
    _services = {}
    def __init__(self, name, audience=''):
        Service._services[name] = self
        self.__name = name
        self._methods = {}

    def joinGroup(self, name):
        raise Exception("No group for local services")
        #GROUPS.setdefault(name, {})[self.__name] = self

    @classmethod
    def exists(cls, name):
        return name in cls._services

    @classmethod
    def remove(cls, name):
        if cls.exits(name):
            cls._services.pop(name)

    def exportMethod(self, method):
        if callable(method):
            self._methods[method.__name__] = method

    def abortResponse(self, error, description, origin, details):
        if not tools.config['debug_mode']:
            raise Exception("%s -- %s\n\n%s"%(origin, description, details))
        else:
            raise

class LocalService(object):
    """ Proxy for local services.

        Any instance of this class will behave like the single instance
        of Service(name)
    """
    def __init__(self, name):
        self.__name = name
        try:
            self._service = Service._services[name]
            for method_name, method_definition in self._service._methods.items():
                setattr(self, method_name, method_definition)
        except KeyError, keyError:
            Logger().notifyChannel('module', LOG_ERROR, 'This service does not exist: %s' % (str(keyError),) )
            raise
    def __call__(self, method, *params):
        return getattr(self, method)(*params)

class ExportService(object):
    """ Proxy for exported services.

    All methods here should take an AuthProxy as their first parameter. It
    will be appended by the calling framework.

    Note that this class has no direct proxy, capable of calling
    eservice.method(). Rather, the proxy should call
    dispatch(method,auth,params)
    """

    _services = {}
    _groups = {}

    def __init__(self, name, audience=''):
        ExportService._services[name] = self
        self.__name = name

    def joinGroup(self, name):
        ExportService._groups.setdefault(name, {})[self.__name] = self

    @classmethod
    def getService(cls,name):
        return cls._services[name]

    def dispatch(self, method, auth, params):
        raise Exception("stub dispatch at %s" % self.__name)

    def new_dispatch(self,method,auth,params):
        raise Exception("stub dispatch at %s" % self.__name)

    def abortResponse(self, error, description, origin, details):
        if not tools.config['debug_mode']:
            raise Exception("%s -- %s\n\n%s"%(origin, description, details))
        else:
            raise

LOG_NOTSET = 'notset'
LOG_DEBUG_RPC = 'debug_rpc'
LOG_DEBUG = 'debug'
LOG_DEBUG2 = 'debug2'
LOG_INFO = 'info'
LOG_WARNING = 'warn'
LOG_ERROR = 'error'
LOG_CRITICAL = 'critical'

# add new log level below DEBUG
logging.DEBUG2 = logging.DEBUG - 1
logging.DEBUG_RPC = logging.DEBUG2 - 1

def init_logger():
    import os
    from tools.translate import resetlocale
    resetlocale()

    logger = logging.getLogger()
    # create a format for log messages and dates
    formatter = logging.Formatter('[%(asctime)s] %(levelname)s:%(name)s:%(message)s')

    if tools.config['syslog']:
        # SysLog Handler
        if os.name == 'nt':
            handler = logging.handlers.NTEventLogHandler("%s %s" %
                                                         (release.description,
                                                          release.version))
        else:
            handler = logging.handlers.SysLogHandler('/dev/log')
        formatter = logging.Formatter("%s %s" % (release.description, release.version) + ':%(levelname)s:%(name)s:%(message)s')

    elif tools.config['logfile']:
        # LogFile Handler
        logf = tools.config['logfile']
        try:
            dirname = os.path.dirname(logf)
            if dirname and not os.path.isdir(dirname):
                os.makedirs(dirname)
            if tools.config['logrotate'] is not False:
                handler = logging.handlers.TimedRotatingFileHandler(logf,'D',1,30)
            elif os.name == 'posix':
                handler = logging.handlers.WatchedFileHandler(logf)
            else:
                handler = logging.handlers.FileHandler(logf)
        except Exception, ex:
            sys.stderr.write("ERROR: couldn't create the logfile directory. Logging to the standard output.\n")
            handler = logging.StreamHandler(sys.stdout)
    else:
        # Normal Handler on standard output
        handler = logging.StreamHandler(sys.stdout)

    # tell the handler to use this format
    handler.setFormatter(formatter)

    # add the handler to the root logger
    logger.addHandler(handler)
    logger.setLevel(int(tools.config['log_level'] or '0'))

    if (not isinstance(handler, logging.FileHandler)) and os.name != 'nt':
        # change color of level names
        # uses of ANSI color codes
        # see http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html
        # maybe use http://code.activestate.com/recipes/574451/
        colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', None, 'default']
        foreground = lambda f: 30 + colors.index(f)
        background = lambda f: 40 + colors.index(f)

        mapping = {
            'DEBUG_RPC': ('blue', 'white'),
            'DEBUG2': ('green', 'white'),
            'DEBUG': ('blue', 'default'),
            'INFO': ('green', 'default'),
            'WARNING': ('yellow', 'default'),
            'ERROR': ('red', 'default'),
            'CRITICAL': ('white', 'red'),
        }

        for level, (fg, bg) in mapping.items():
            msg = "\x1b[%dm\x1b[%dm%s\x1b[0m" % (foreground(fg), background(bg), level)
            logging.addLevelName(getattr(logging, level), msg)

class Logger(object):

    def notifyChannel(self, name, level, msg):
        from service.web_services import common

        log = logging.getLogger(tools.ustr(name))

        if level == LOG_DEBUG2 and not hasattr(log, level):
            fct = lambda msg, *args, **kwargs: log.log(logging.DEBUG2, msg, *args, **kwargs)
            setattr(log, LOG_DEBUG2, fct)

        if level == LOG_DEBUG_RPC and not hasattr(log, level):
            fct = lambda msg, *args, **kwargs: log.log(logging.DEBUG_RPC, msg, *args, **kwargs)
            setattr(log, LOG_DEBUG_RPC, fct)

        level_method = getattr(log, level)

        if isinstance(msg, Exception):
            msg = tools.exception_to_unicode(msg)

        try:
            msg = tools.ustr(msg).strip()
            if level in (LOG_ERROR,LOG_CRITICAL) and tools.config.get_misc('debug','env_info',False):
                msg = common().exp_get_server_environment() + "\n" + msg

            result = msg.split('\n')
        except UnicodeDecodeError:
            result = msg.strip().split('\n')
        try:
            if len(result)>1:
                for idx, s in enumerate(result):
                    level_method('[%02d]: %s' % (idx+1, s,))
            elif result:
                level_method(result[0])
        except IOError,e:
            # TODO: perhaps reset the logger streams?
            #if logrotate closes our files, we end up here..
            pass
        except:
            # better ignore the exception and carry on..
            pass

    def set_loglevel(self, level):
        log = logging.getLogger()
        log.setLevel(logging.INFO) # make sure next msg is printed
        log.info("Log level changed to %s" % logging.getLevelName(level))
        log.setLevel(level)

    def shutdown(self):
        logging.shutdown()

import tools
init_logger()

class Agent(object):
    _timers = {}
    _logger = Logger()

    def setAlarm(self, fn, dt, db_name, *args, **kwargs):
        wait = dt - time.time()
        if wait > 0:
            self._logger.notifyChannel('timers', LOG_DEBUG, "Job scheduled in %.3g seconds for %s.%s" % (wait, fn.im_class.__name__, fn.func_name))
            timer = threading.Timer(wait, fn, args, kwargs)
            timer.start()
            self._timers.setdefault(db_name, []).append(timer)

        for db in self._timers:
            for timer in self._timers[db]:
                if not timer.isAlive():
                    self._timers[db].remove(timer)

    @classmethod
    def cancel(cls, db_name):
        """Cancel all timers for a given database. If None passed, all timers are cancelled"""
        for db in cls._timers:
            if db_name is None or db == db_name:
                for timer in cls._timers[db]:
                    timer.cancel()

    @classmethod
    def quit(cls):
        cls.cancel(None)

import traceback

class Server:
    """ Generic interface for all servers with an event loop etc.
        Override this to impement http, net-rpc etc. servers.

        Servers here must have threaded behaviour. start() must not block,
        there is no run().
    """
    __is_started = False
    __servers = []

    def __init__(self):
        if Server.__is_started:
            raise Exception('All instances of servers must be inited before the startAll()')
        Server.__servers.append(self)

    def start(self):
        print "called stub Server.start"
        pass

    def stop(self):
        print "called stub Server.stop"
        pass

    def stats(self):
        """ This function should return statistics about the server """
        return "%s: No statistics" % str(self.__class__)

    @classmethod
    def startAll(cls):
        if cls.__is_started:
            return
        Logger().notifyChannel("services", LOG_INFO,
            "Starting %d services" % len(cls.__servers))
        for srv in cls.__servers:
            srv.start()
        cls.__is_started = True

    @classmethod
    def quitAll(cls):
        if not cls.__is_started:
            return
        Logger().notifyChannel("services", LOG_INFO,
            "Stopping %d services" % len(cls.__servers))
        for srv in cls.__servers:
            srv.stop()
        cls.__is_started = False

    @classmethod
    def allStats(cls):
        res = ''
        if cls.__is_started:
            res += "Servers started\n"
        else:
            res += "Servers stopped\n"
        for srv in cls.__servers:
            try:
                res += srv.stats() + "\n"
            except:
                pass
        return res

class OpenERPDispatcherException(Exception):
    def __init__(self, exception, traceback):
        self.exception = exception
        self.traceback = traceback

class OpenERPDispatcher:
    def log(self, title, msg):
        from pprint import pformat
        Logger().notifyChannel('%s' % title, LOG_DEBUG_RPC, pformat(msg))

    def dispatch(self, service_name, method, params):
        try:
            self.log('service', service_name)
            self.log('method', method)
            self.log('params', params)
            auth = getattr(self, 'auth_provider', None)
            result = ExportService.getService(service_name).dispatch(method, auth, params)
            self.log('result', result)
            # We shouldn't marshall None,
            if result == None:
                result = False
            return result
        except Exception, e:
            self.log('exception', tools.exception_to_unicode(e))
            tb = getattr(e, 'traceback', sys.exc_info())
            tb_s = "".join(traceback.format_exception(*tb))
            if tools.config['debug_mode']:
                import pdb
                pdb.post_mortem(tb[2])
            raise OpenERPDispatcherException(e, tb_s)

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<commit_msg>[FIX] typo<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
#    The refactoring about the OpenSSL support come from Tryton
#    Copyright (C) 2007-2009 Cédric Krier.
#    Copyright (C) 2007-2009 Bertrand Chenal.
#    Copyright (C) 2008 B2CK SPRL.
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import SimpleXMLRPCServer
import SocketServer
import logging
import logging.handlers
import os
import signal
import socket
import sys
import threading
import time
import xmlrpclib
import release

class Service(object):
    """ Base class for *Local* services

        Functionality here is trusted, no authentication.
    """
    _services = {}
    def __init__(self, name, audience=''):
        Service._services[name] = self
        self.__name = name
        self._methods = {}

    def joinGroup(self, name):
        raise Exception("No group for local services")
        #GROUPS.setdefault(name, {})[self.__name] = self

    @classmethod
    def exists(cls, name):
        return name in cls._services

    @classmethod
    def remove(cls, name):
        if cls.exists(name):
            cls._services.pop(name)

    def exportMethod(self, method):
        if callable(method):
            self._methods[method.__name__] = method

    def abortResponse(self, error, description, origin, details):
        if not tools.config['debug_mode']:
            raise Exception("%s -- %s\n\n%s"%(origin, description, details))
        else:
            raise

class LocalService(object):
    """ Proxy for local services.

        Any instance of this class will behave like the single instance
        of Service(name)
    """
    def __init__(self, name):
        self.__name = name
        try:
            self._service = Service._services[name]
            for method_name, method_definition in self._service._methods.items():
                setattr(self, method_name, method_definition)
        except KeyError, keyError:
            Logger().notifyChannel('module', LOG_ERROR, 'This service does not exist: %s' % (str(keyError),) )
            raise
    def __call__(self, method, *params):
        return getattr(self, method)(*params)

class ExportService(object):
    """ Proxy for exported services.

    All methods here should take an AuthProxy as their first parameter. It
    will be appended by the calling framework.

    Note that this class has no direct proxy, capable of calling
    eservice.method(). Rather, the proxy should call
    dispatch(method,auth,params)
    """

    _services = {}
    _groups = {}

    def __init__(self, name, audience=''):
        ExportService._services[name] = self
        self.__name = name

    def joinGroup(self, name):
        ExportService._groups.setdefault(name, {})[self.__name] = self

    @classmethod
    def getService(cls,name):
        return cls._services[name]

    def dispatch(self, method, auth, params):
        raise Exception("stub dispatch at %s" % self.__name)

    def new_dispatch(self,method,auth,params):
        raise Exception("stub dispatch at %s" % self.__name)

    def abortResponse(self, error, description, origin, details):
        if not tools.config['debug_mode']:
            raise Exception("%s -- %s\n\n%s"%(origin, description, details))
        else:
            raise

LOG_NOTSET = 'notset'
LOG_DEBUG_RPC = 'debug_rpc'
LOG_DEBUG = 'debug'
LOG_DEBUG2 = 'debug2'
LOG_INFO = 'info'
LOG_WARNING = 'warn'
LOG_ERROR = 'error'
LOG_CRITICAL = 'critical'

# add new log level below DEBUG
logging.DEBUG2 = logging.DEBUG - 1
logging.DEBUG_RPC = logging.DEBUG2 - 1

def init_logger():
    import os
    from tools.translate import resetlocale
    resetlocale()

    logger = logging.getLogger()
    # create a format for log messages and dates
    formatter = logging.Formatter('[%(asctime)s] %(levelname)s:%(name)s:%(message)s')

    if tools.config['syslog']:
        # SysLog Handler
        if os.name == 'nt':
            handler = logging.handlers.NTEventLogHandler("%s %s" %
                                                         (release.description,
                                                          release.version))
        else:
            handler = logging.handlers.SysLogHandler('/dev/log')
        formatter = logging.Formatter("%s %s" % (release.description, release.version) + ':%(levelname)s:%(name)s:%(message)s')

    elif tools.config['logfile']:
        # LogFile Handler
        logf = tools.config['logfile']
        try:
            dirname = os.path.dirname(logf)
            if dirname and not os.path.isdir(dirname):
                os.makedirs(dirname)
            if tools.config['logrotate'] is not False:
                handler = logging.handlers.TimedRotatingFileHandler(logf,'D',1,30)
            elif os.name == 'posix':
                handler = logging.handlers.WatchedFileHandler(logf)
            else:
                handler = logging.handlers.FileHandler(logf)
        except Exception, ex:
            sys.stderr.write("ERROR: couldn't create the logfile directory. Logging to the standard output.\n")
            handler = logging.StreamHandler(sys.stdout)
    else:
        # Normal Handler on standard output
        handler = logging.StreamHandler(sys.stdout)

    # tell the handler to use this format
    handler.setFormatter(formatter)

    # add the handler to the root logger
    logger.addHandler(handler)
    logger.setLevel(int(tools.config['log_level'] or '0'))

    if (not isinstance(handler, logging.FileHandler)) and os.name != 'nt':
        # change color of level names
        # uses of ANSI color codes
        # see http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html
        # maybe use http://code.activestate.com/recipes/574451/
        colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', None, 'default']
        foreground = lambda f: 30 + colors.index(f)
        background = lambda f: 40 + colors.index(f)

        mapping = {
            'DEBUG_RPC': ('blue', 'white'),
            'DEBUG2': ('green', 'white'),
            'DEBUG': ('blue', 'default'),
            'INFO': ('green', 'default'),
            'WARNING': ('yellow', 'default'),
            'ERROR': ('red', 'default'),
            'CRITICAL': ('white', 'red'),
        }

        for level, (fg, bg) in mapping.items():
            msg = "\x1b[%dm\x1b[%dm%s\x1b[0m" % (foreground(fg), background(bg), level)
            logging.addLevelName(getattr(logging, level), msg)

class Logger(object):

    def notifyChannel(self, name, level, msg):
        from service.web_services import common

        log = logging.getLogger(tools.ustr(name))

        if level == LOG_DEBUG2 and not hasattr(log, level):
            fct = lambda msg, *args, **kwargs: log.log(logging.DEBUG2, msg, *args, **kwargs)
            setattr(log, LOG_DEBUG2, fct)

        if level == LOG_DEBUG_RPC and not hasattr(log, level):
            fct = lambda msg, *args, **kwargs: log.log(logging.DEBUG_RPC, msg, *args, **kwargs)
            setattr(log, LOG_DEBUG_RPC, fct)

        level_method = getattr(log, level)

        if isinstance(msg, Exception):
            msg = tools.exception_to_unicode(msg)

        try:
            msg = tools.ustr(msg).strip()
            if level in (LOG_ERROR,LOG_CRITICAL) and tools.config.get_misc('debug','env_info',False):
                msg = common().exp_get_server_environment() + "\n" + msg

            result = msg.split('\n')
        except UnicodeDecodeError:
            result = msg.strip().split('\n')
        try:
            if len(result)>1:
                for idx, s in enumerate(result):
                    level_method('[%02d]: %s' % (idx+1, s,))
            elif result:
                level_method(result[0])
        except IOError,e:
            # TODO: perhaps reset the logger streams?
            #if logrotate closes our files, we end up here..
            pass
        except:
            # better ignore the exception and carry on..
            pass

    def set_loglevel(self, level):
        log = logging.getLogger()
        log.setLevel(logging.INFO) # make sure next msg is printed
        log.info("Log level changed to %s" % logging.getLevelName(level))
        log.setLevel(level)

    def shutdown(self):
        logging.shutdown()

import tools
init_logger()

class Agent(object):
    _timers = {}
    _logger = Logger()

    def setAlarm(self, fn, dt, db_name, *args, **kwargs):
        wait = dt - time.time()
        if wait > 0:
            self._logger.notifyChannel('timers', LOG_DEBUG, "Job scheduled in %.3g seconds for %s.%s" % (wait, fn.im_class.__name__, fn.func_name))
            timer = threading.Timer(wait, fn, args, kwargs)
            timer.start()
            self._timers.setdefault(db_name, []).append(timer)

        for db in self._timers:
            for timer in self._timers[db]:
                if not timer.isAlive():
                    self._timers[db].remove(timer)

    @classmethod
    def cancel(cls, db_name):
        """Cancel all timers for a given database. If None passed, all timers are cancelled"""
        for db in cls._timers:
            if db_name is None or db == db_name:
                for timer in cls._timers[db]:
                    timer.cancel()

    @classmethod
    def quit(cls):
        cls.cancel(None)

import traceback

class Server:
    """ Generic interface for all servers with an event loop etc.
        Override this to impement http, net-rpc etc. servers.

        Servers here must have threaded behaviour. start() must not block,
        there is no run().
    """
    __is_started = False
    __servers = []

    def __init__(self):
        if Server.__is_started:
            raise Exception('All instances of servers must be inited before the startAll()')
        Server.__servers.append(self)

    def start(self):
        print "called stub Server.start"
        pass

    def stop(self):
        print "called stub Server.stop"
        pass

    def stats(self):
        """ This function should return statistics about the server """
        return "%s: No statistics" % str(self.__class__)

    @classmethod
    def startAll(cls):
        if cls.__is_started:
            return
        Logger().notifyChannel("services", LOG_INFO,
            "Starting %d services" % len(cls.__servers))
        for srv in cls.__servers:
            srv.start()
        cls.__is_started = True

    @classmethod
    def quitAll(cls):
        if not cls.__is_started:
            return
        Logger().notifyChannel("services", LOG_INFO,
            "Stopping %d services" % len(cls.__servers))
        for srv in cls.__servers:
            srv.stop()
        cls.__is_started = False

    @classmethod
    def allStats(cls):
        res = ''
        if cls.__is_started:
            res += "Servers started\n"
        else:
            res += "Servers stopped\n"
        for srv in cls.__servers:
            try:
                res += srv.stats() + "\n"
            except:
                pass
        return res

class OpenERPDispatcherException(Exception):
    def __init__(self, exception, traceback):
        self.exception = exception
        self.traceback = traceback

class OpenERPDispatcher:
    def log(self, title, msg):
        from pprint import pformat
        Logger().notifyChannel('%s' % title, LOG_DEBUG_RPC, pformat(msg))

    def dispatch(self, service_name, method, params):
        try:
            self.log('service', service_name)
            self.log('method', method)
            self.log('params', params)
            auth = getattr(self, 'auth_provider', None)
            result = ExportService.getService(service_name).dispatch(method, auth, params)
            self.log('result', result)
            # We shouldn't marshall None,
            if result == None:
                result = False
            return result
        except Exception, e:
            self.log('exception', tools.exception_to_unicode(e))
            tb = getattr(e, 'traceback', sys.exc_info())
            tb_s = "".join(traceback.format_exception(*tb))
            if tools.config['debug_mode']:
                import pdb
                pdb.post_mortem(tb[2])
            raise OpenERPDispatcherException(e, tb_s)

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<|endoftext|>


<commit_before># Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import shutil
import tempfile
import time
import unittest

from telemetry import story
from telemetry.core import exceptions
from telemetry.core import util
from telemetry import decorators
from telemetry.internal.browser import user_agent
from telemetry.internal.results import results_options
from telemetry.internal import story_runner
from telemetry.internal.testing.test_page_sets import example_domain
from telemetry.page import page as page_module
from telemetry.page import legacy_page_test
from telemetry.page import shared_page_state
from telemetry.page import traffic_setting as traffic_setting_module
from telemetry.util import image_util
from telemetry.testing import options_for_unittests

class DummyTest(legacy_page_test.LegacyPageTest):
  def ValidateAndMeasurePage(self, *_):
    pass

# TODO(crbug.com/1025765): Remove test cases that use real browsers and replace
# with a story_runner or shared_page_state unittest that tests the same logic.
class ActualPageRunEndToEndTests(unittest.TestCase):
  def setUp(self):
    self.options = options_for_unittests.GetRunOptions(
        output_dir=tempfile.mkdtemp())

  def tearDown(self):
    shutil.rmtree(self.options.output_dir)

  def RunStorySet(self, test, story_set, **kwargs):
    with results_options.CreateResults(self.options) as results:
      story_runner.RunStorySet(test, story_set, self.options, results, **kwargs)
    return results

  def testBrowserRestartsAfterEachPage(self):
    story_set = story.StorySet()
    story_set.AddStory(page_module.Page(
        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='foo'))
    story_set.AddStory(page_module.Page(
        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='bar'))

    class Test(legacy_page_test.LegacyPageTest):
      def __init__(self):
        super(Test, self).__init__()
        self.browser_starts = 0
        self.platform_name = None

      def DidStartBrowser(self, browser):
        super(Test, self).DidStartBrowser(browser)
        self.browser_starts += 1
        self.platform_name = browser.platform.GetOSName()

      def ValidateAndMeasurePage(self, page, tab, results):
        pass

    test = Test()
    results = self.RunStorySet(test, story_set)
    self.assertFalse(results.benchmark_interrupted)
    self.assertEquals(len(story_set), results.num_successful)
    # Browser is started once per story run, except in ChromeOS where a single
    # instance is reused for all stories.
    if test.platform_name == 'chromeos':
      self.assertEquals(1, test.browser_starts)
    else:
      self.assertEquals(len(story_set), test.browser_starts)

  @decorators.Disabled('chromeos')  # crbug.com/483212
  def testUserAgent(self):
    story_set = story.StorySet()
    page = page_module.Page(
        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
        shared_page_state_class=shared_page_state.SharedTabletPageState,
        name='blank.html')
    story_set.AddStory(page)

    class TestUserAgent(legacy_page_test.LegacyPageTest):
      def ValidateAndMeasurePage(self, page, tab, results):
        del page, results  # unused
        actual_user_agent = tab.EvaluateJavaScript(
            'window.navigator.userAgent')
        expected_user_agent = user_agent.UA_TYPE_MAPPING['tablet']
        assert actual_user_agent.strip() == expected_user_agent

        # This is so we can check later that the test actually made it into this
        # function. Previously it was timing out before even getting here, which
        # should fail, but since it skipped all the asserts, it slipped by.
        self.hasRun = True  # pylint: disable=attribute-defined-outside-init

    test = TestUserAgent()
    self.RunStorySet(test, story_set)
    self.assertTrue(hasattr(test, 'hasRun') and test.hasRun)

  # Ensure that story_runner forces exactly 1 tab before running a page.
  @decorators.Enabled('has tabs')
  def testOneTab(self):
    story_set = story.StorySet()
    page = page_module.Page(
        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='blank.html')
    story_set.AddStory(page)

    class TestOneTab(legacy_page_test.LegacyPageTest):
      def DidStartBrowser(self, browser):
        browser.tabs.New()

      def ValidateAndMeasurePage(self, page, tab, results):
        del page, results  # unused
        assert len(tab.browser.tabs) == 1

    test = TestOneTab()
    self.RunStorySet(test, story_set)

  def testTrafficSettings(self):
    story_set = story.StorySet()
    slow_page = page_module.Page(
        'file://green_rect.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='slow',
        traffic_setting=traffic_setting_module.GOOD_3G)
    fast_page = page_module.Page(
        'file://green_rect.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='fast',
        traffic_setting=traffic_setting_module.WIFI)
    story_set.AddStory(slow_page)
    story_set.AddStory(fast_page)

    latencies_by_page_in_ms = {}

    class MeasureLatency(legacy_page_test.LegacyPageTest):
      def __init__(self):
        super(MeasureLatency, self).__init__()
        self._will_navigate_time = None

      def WillNavigateToPage(self, page, tab):
        del page, tab # unused
        self._will_navigate_time = time.time() * 1000

      def ValidateAndMeasurePage(self, page, tab, results):
        del results  # unused
        latencies_by_page_in_ms[page.name] = (
            time.time() * 1000 - self._will_navigate_time)

    test = MeasureLatency()
    results = self.RunStorySet(test, story_set)

    failure_messages = []
    for r in results.IterStoryRuns():
      if r.failure_str:
        failure_messages.append(
            'Failure message of story %s:\n%s' % (r.story, r.failure_str))
    self.assertFalse(results.had_failures, msg=''.join(failure_messages))
    self.assertIn('slow', latencies_by_page_in_ms)
    self.assertIn('fast', latencies_by_page_in_ms)
    # Slow page should be slower than fast page by at least 40 ms (roundtrip
    # time of good 3G) - 2 ms (roundtrip time of Wifi)
    self.assertGreater(latencies_by_page_in_ms['slow'],
                       latencies_by_page_in_ms['fast'] + 40 - 2)

  # Ensure that story_runner allows the test to customize the browser
  # before it launches.
  def testBrowserBeforeLaunch(self):
    story_set = story.StorySet()
    page = page_module.Page(
        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='blank.html')
    story_set.AddStory(page)

    class TestBeforeLaunch(legacy_page_test.LegacyPageTest):
      def __init__(self):
        super(TestBeforeLaunch, self).__init__()
        self._did_call_will_start = False
        self._did_call_did_start = False

      def WillStartBrowser(self, platform):
        self._did_call_will_start = True
        # TODO(simonjam): Test that the profile is available.

      def DidStartBrowser(self, browser):
        assert self._did_call_will_start
        self._did_call_did_start = True

      def ValidateAndMeasurePage(self, *_):
        assert self._did_call_did_start

    test = TestBeforeLaunch()
    self.RunStorySet(test, story_set)

  # Ensure that story_runner calls cleanUp when a page run fails.
  def testCleanUpPage(self):
    story_set = story.StorySet()
    page = page_module.Page(
        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='blank.html')
    story_set.AddStory(page)

    class Test(legacy_page_test.LegacyPageTest):
      def __init__(self):
        super(Test, self).__init__()
        self.did_call_clean_up = False

      def ValidateAndMeasurePage(self, *_):
        raise legacy_page_test.Failure

      def DidRunPage(self, platform):
        del platform  # unused
        self.did_call_clean_up = True

    test = Test()
    self.RunStorySet(test, story_set)
    assert test.did_call_clean_up

  # Ensure skipping the test if shared state cannot be run on the browser.
  def testSharedPageStateCannotRunOnBrowser(self):
    story_set = story.StorySet()

    class UnrunnableSharedState(shared_page_state.SharedPageState):
      def CanRunOnBrowser(self, browser_info, page):
        del browser_info, page  # unused
        return False

      def ValidateAndMeasurePage(self, _):
        pass

    story_set.AddStory(page_module.Page(
        url='file://blank.html', page_set=story_set,
        base_dir=util.GetUnittestDataDir(),
        shared_page_state_class=UnrunnableSharedState,
        name='blank.html'))

    class Test(legacy_page_test.LegacyPageTest):
      def __init__(self, *args, **kwargs):
        super(Test, self).__init__(*args, **kwargs)
        self.will_navigate_to_page_called = False

      def ValidateAndMeasurePage(self, *args):
        del args  # unused
        raise Exception('Exception should not be thrown')

      def WillNavigateToPage(self, page, tab):
        del page, tab  # unused
        self.will_navigate_to_page_called = True

    test = Test()
    results = self.RunStorySet(test, story_set)

    self.assertFalse(test.will_navigate_to_page_called)
    self.assertEquals(1, results.num_expected)  # One expected skip.
    self.assertTrue(results.had_skips)
    self.assertFalse(results.had_failures)

  # Verifies that if the browser is not closed between story runs (as happens
  # e.g. on ChromeOS), the page state is reset. The first page scrolls to the
  # end, and the second page loads the same url and checks the scroll position
  # to ensure it is at the top.
  def testPageResetWhenBrowserReusedBetweenStories(self):
    class NoClosingBrowserSharedState(shared_page_state.SharedPageState):
      def ShouldReuseBrowserForAllStoryRuns(self):
        return True

    # Loads a page and scrolls it to the end.
    class ScrollingPage(page_module.Page):
      def __init__(self, url, page_set, base_dir):
        super(ScrollingPage, self).__init__(page_set=page_set,
                                            base_dir=base_dir,
                                            shared_page_state_class=
                                            NoClosingBrowserSharedState,
                                            url=url, name='ScrollingPage')

      def RunPageInteractions(self, action_runner):
        action_runner.ScrollPage()

    # Loads same page as ScrollingPage() and records if the scroll position is
    # at the top of the page (in was_page_at_top_on_start).
    class CheckScrollPositionPage(page_module.Page):
      def __init__(self, url, page_set, base_dir):
        super(CheckScrollPositionPage, self).__init__(
            page_set=page_set, base_dir=base_dir,
            shared_page_state_class=NoClosingBrowserSharedState, url=url,
            name='CheckScroll')
        self.was_page_at_top_on_start = False

      def RunPageInteractions(self, action_runner):
        scroll_y = action_runner.tab.EvaluateJavaScript('window.scrollY')
        self.was_page_at_top_on_start = scroll_y == 0

    story_set = story.StorySet()
    story_set.AddStory(ScrollingPage(
        url='file://page_with_swipeables.html', page_set=story_set,
        base_dir=util.GetUnittestDataDir()))
    test_page = CheckScrollPositionPage(
        url='file://page_with_swipeables.html', page_set=story_set,
        base_dir=util.GetUnittestDataDir())
    story_set.AddStory(test_page)
    self.RunStorySet(DummyTest(), story_set)
    self.assertTrue(test_page.was_page_at_top_on_start)

  def testSingleTabMeansCrashWillCauseFailure(self):
    class TestPage(page_module.Page):
      def RunNavigateSteps(self, _):
        raise exceptions.AppCrashException

    story_set = story.StorySet()
    for i in range(5):
      story_set.AddStory(
          TestPage('file://blank.html', story_set,
                   base_dir=util.GetUnittestDataDir(), name='foo%d' % i))

    results = self.RunStorySet(DummyTest(), story_set, max_failures=1)
    self.assertTrue(results.benchmark_interrupted)
    self.assertEquals(3, results.num_skipped)
    self.assertEquals(2, results.num_failed)  # max_failures + 1

  def testWebPageReplay(self):
    story_set = example_domain.ExampleDomainPageSet()
    body = []

    class TestWpr(legacy_page_test.LegacyPageTest):
      def ValidateAndMeasurePage(self, page, tab, results):
        del page, results  # unused
        body.append(tab.EvaluateJavaScript('document.body.innerText'))

      def DidRunPage(self, platform):
        # Force the replay server to restart between pages; this verifies that
        # the restart mechanism works.
        platform.network_controller.StopReplay()

    test = TestWpr()
    results = self.RunStorySet(test, story_set)

    self.longMessage = True
    self.assertIn('Example Domain', body[0],
                  msg='URL: %s' % story_set.stories[0].url)
    self.assertIn('Example Domain', body[1],
                  msg='URL: %s' % story_set.stories[1].url)

    self.assertEquals(2, results.num_successful)
    self.assertFalse(results.had_failures)

  def testScreenShotTakenForFailedPage(self):
    platform_screenshot_supported = [False]
    tab_screenshot_supported = [False]
    chrome_version_screen_shot = [None]

    class FailingTestPage(page_module.Page):

      def RunNavigateSteps(self, action_runner):
        action_runner.Navigate(self._url)
        platform_screenshot_supported[0] = (
            action_runner.tab.browser.platform.CanTakeScreenshot)
        tab_screenshot_supported[0] = action_runner.tab.screenshot_supported
        if not platform_screenshot_supported[0] and tab_screenshot_supported[0]:
          chrome_version_screen_shot[0] = action_runner.tab.Screenshot()
        raise exceptions.AppCrashException

    story_set = story.StorySet()
    story_set.AddStory(page_module.Page('file://blank.html', story_set,
                                        name='blank.html'))
    failing_page = FailingTestPage('chrome://version', story_set,
                                   name='failing')
    story_set.AddStory(failing_page)

    self.options.browser_options.take_screenshot_for_failed_page = True
    results = self.RunStorySet(DummyTest(), story_set, max_failures=2)
    self.assertTrue(results.had_failures)
    if not platform_screenshot_supported[0] and tab_screenshot_supported[0]:
      failed_run = next(run for run in results.IterStoryRuns()
                        if run.story.name == failing_page.name)
      screenshot_file_path = failed_run.GetArtifact('screenshot').local_path

      actual_screenshot = image_util.FromPngFile(screenshot_file_path)
      self.assertEquals(image_util.Pixels(chrome_version_screen_shot[0]),
                        image_util.Pixels(actual_screenshot))
<commit_msg>[Telemetry] Fix and update testScreenShotTakenForFailedPage<commit_after># Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import shutil
import tempfile
import time
import unittest

from telemetry import story
from telemetry.core import exceptions
from telemetry.core import util
from telemetry import decorators
from telemetry.internal.browser import user_agent
from telemetry.internal.results import results_options
from telemetry.internal import story_runner
from telemetry.internal.testing.test_page_sets import example_domain
from telemetry.page import page as page_module
from telemetry.page import legacy_page_test
from telemetry.page import shared_page_state
from telemetry.page import traffic_setting as traffic_setting_module
from telemetry.util import image_util
from telemetry.testing import options_for_unittests

class DummyTest(legacy_page_test.LegacyPageTest):
  def ValidateAndMeasurePage(self, *_):
    pass

# TODO(crbug.com/1025765): Remove test cases that use real browsers and replace
# with a story_runner or shared_page_state unittest that tests the same logic.
class ActualPageRunEndToEndTests(unittest.TestCase):
  def setUp(self):
    self.options = options_for_unittests.GetRunOptions(
        output_dir=tempfile.mkdtemp())

  def tearDown(self):
    shutil.rmtree(self.options.output_dir)

  def RunStorySet(self, test, story_set, **kwargs):
    with results_options.CreateResults(self.options) as results:
      story_runner.RunStorySet(test, story_set, self.options, results, **kwargs)
    return results

  def ReadTestResults(self):
    return results_options.ReadTestResults(self.options.intermediate_dir)

  def testBrowserRestartsAfterEachPage(self):
    story_set = story.StorySet()
    story_set.AddStory(page_module.Page(
        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='foo'))
    story_set.AddStory(page_module.Page(
        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='bar'))

    class Test(legacy_page_test.LegacyPageTest):
      def __init__(self):
        super(Test, self).__init__()
        self.browser_starts = 0
        self.platform_name = None

      def DidStartBrowser(self, browser):
        super(Test, self).DidStartBrowser(browser)
        self.browser_starts += 1
        self.platform_name = browser.platform.GetOSName()

      def ValidateAndMeasurePage(self, page, tab, results):
        pass

    test = Test()
    results = self.RunStorySet(test, story_set)
    self.assertFalse(results.benchmark_interrupted)
    self.assertEquals(len(story_set), results.num_successful)
    # Browser is started once per story run, except in ChromeOS where a single
    # instance is reused for all stories.
    if test.platform_name == 'chromeos':
      self.assertEquals(1, test.browser_starts)
    else:
      self.assertEquals(len(story_set), test.browser_starts)

  @decorators.Disabled('chromeos')  # crbug.com/483212
  def testUserAgent(self):
    story_set = story.StorySet()
    page = page_module.Page(
        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
        shared_page_state_class=shared_page_state.SharedTabletPageState,
        name='blank.html')
    story_set.AddStory(page)

    class TestUserAgent(legacy_page_test.LegacyPageTest):
      def ValidateAndMeasurePage(self, page, tab, results):
        del page, results  # unused
        actual_user_agent = tab.EvaluateJavaScript(
            'window.navigator.userAgent')
        expected_user_agent = user_agent.UA_TYPE_MAPPING['tablet']
        assert actual_user_agent.strip() == expected_user_agent

        # This is so we can check later that the test actually made it into this
        # function. Previously it was timing out before even getting here, which
        # should fail, but since it skipped all the asserts, it slipped by.
        self.hasRun = True  # pylint: disable=attribute-defined-outside-init

    test = TestUserAgent()
    self.RunStorySet(test, story_set)
    self.assertTrue(hasattr(test, 'hasRun') and test.hasRun)

  # Ensure that story_runner forces exactly 1 tab before running a page.
  @decorators.Enabled('has tabs')
  def testOneTab(self):
    story_set = story.StorySet()
    page = page_module.Page(
        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='blank.html')
    story_set.AddStory(page)

    class TestOneTab(legacy_page_test.LegacyPageTest):
      def DidStartBrowser(self, browser):
        browser.tabs.New()

      def ValidateAndMeasurePage(self, page, tab, results):
        del page, results  # unused
        assert len(tab.browser.tabs) == 1

    test = TestOneTab()
    self.RunStorySet(test, story_set)

  def testTrafficSettings(self):
    story_set = story.StorySet()
    slow_page = page_module.Page(
        'file://green_rect.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='slow',
        traffic_setting=traffic_setting_module.GOOD_3G)
    fast_page = page_module.Page(
        'file://green_rect.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='fast',
        traffic_setting=traffic_setting_module.WIFI)
    story_set.AddStory(slow_page)
    story_set.AddStory(fast_page)

    latencies_by_page_in_ms = {}

    class MeasureLatency(legacy_page_test.LegacyPageTest):
      def __init__(self):
        super(MeasureLatency, self).__init__()
        self._will_navigate_time = None

      def WillNavigateToPage(self, page, tab):
        del page, tab # unused
        self._will_navigate_time = time.time() * 1000

      def ValidateAndMeasurePage(self, page, tab, results):
        del results  # unused
        latencies_by_page_in_ms[page.name] = (
            time.time() * 1000 - self._will_navigate_time)

    test = MeasureLatency()
    results = self.RunStorySet(test, story_set)

    failure_messages = []
    for r in results.IterStoryRuns():
      if r.failure_str:
        failure_messages.append(
            'Failure message of story %s:\n%s' % (r.story, r.failure_str))
    self.assertFalse(results.had_failures, msg=''.join(failure_messages))
    self.assertIn('slow', latencies_by_page_in_ms)
    self.assertIn('fast', latencies_by_page_in_ms)
    # Slow page should be slower than fast page by at least 40 ms (roundtrip
    # time of good 3G) - 2 ms (roundtrip time of Wifi)
    self.assertGreater(latencies_by_page_in_ms['slow'],
                       latencies_by_page_in_ms['fast'] + 40 - 2)

  # Ensure that story_runner allows the test to customize the browser
  # before it launches.
  def testBrowserBeforeLaunch(self):
    story_set = story.StorySet()
    page = page_module.Page(
        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='blank.html')
    story_set.AddStory(page)

    class TestBeforeLaunch(legacy_page_test.LegacyPageTest):
      def __init__(self):
        super(TestBeforeLaunch, self).__init__()
        self._did_call_will_start = False
        self._did_call_did_start = False

      def WillStartBrowser(self, platform):
        self._did_call_will_start = True
        # TODO(simonjam): Test that the profile is available.

      def DidStartBrowser(self, browser):
        assert self._did_call_will_start
        self._did_call_did_start = True

      def ValidateAndMeasurePage(self, *_):
        assert self._did_call_did_start

    test = TestBeforeLaunch()
    self.RunStorySet(test, story_set)

  # Ensure that story_runner calls cleanUp when a page run fails.
  def testCleanUpPage(self):
    story_set = story.StorySet()
    page = page_module.Page(
        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
        name='blank.html')
    story_set.AddStory(page)

    class Test(legacy_page_test.LegacyPageTest):
      def __init__(self):
        super(Test, self).__init__()
        self.did_call_clean_up = False

      def ValidateAndMeasurePage(self, *_):
        raise legacy_page_test.Failure

      def DidRunPage(self, platform):
        del platform  # unused
        self.did_call_clean_up = True

    test = Test()
    self.RunStorySet(test, story_set)
    assert test.did_call_clean_up

  # Ensure skipping the test if shared state cannot be run on the browser.
  def testSharedPageStateCannotRunOnBrowser(self):
    story_set = story.StorySet()

    class UnrunnableSharedState(shared_page_state.SharedPageState):
      def CanRunOnBrowser(self, browser_info, page):
        del browser_info, page  # unused
        return False

      def ValidateAndMeasurePage(self, _):
        pass

    story_set.AddStory(page_module.Page(
        url='file://blank.html', page_set=story_set,
        base_dir=util.GetUnittestDataDir(),
        shared_page_state_class=UnrunnableSharedState,
        name='blank.html'))

    class Test(legacy_page_test.LegacyPageTest):
      def __init__(self, *args, **kwargs):
        super(Test, self).__init__(*args, **kwargs)
        self.will_navigate_to_page_called = False

      def ValidateAndMeasurePage(self, *args):
        del args  # unused
        raise Exception('Exception should not be thrown')

      def WillNavigateToPage(self, page, tab):
        del page, tab  # unused
        self.will_navigate_to_page_called = True

    test = Test()
    results = self.RunStorySet(test, story_set)

    self.assertFalse(test.will_navigate_to_page_called)
    self.assertEquals(1, results.num_expected)  # One expected skip.
    self.assertTrue(results.had_skips)
    self.assertFalse(results.had_failures)

  # Verifies that if the browser is not closed between story runs (as happens
  # e.g. on ChromeOS), the page state is reset. The first page scrolls to the
  # end, and the second page loads the same url and checks the scroll position
  # to ensure it is at the top.
  def testPageResetWhenBrowserReusedBetweenStories(self):
    class NoClosingBrowserSharedState(shared_page_state.SharedPageState):
      def ShouldReuseBrowserForAllStoryRuns(self):
        return True

    # Loads a page and scrolls it to the end.
    class ScrollingPage(page_module.Page):
      def __init__(self, url, page_set, base_dir):
        super(ScrollingPage, self).__init__(page_set=page_set,
                                            base_dir=base_dir,
                                            shared_page_state_class=
                                            NoClosingBrowserSharedState,
                                            url=url, name='ScrollingPage')

      def RunPageInteractions(self, action_runner):
        action_runner.ScrollPage()

    # Loads same page as ScrollingPage() and records if the scroll position is
    # at the top of the page (in was_page_at_top_on_start).
    class CheckScrollPositionPage(page_module.Page):
      def __init__(self, url, page_set, base_dir):
        super(CheckScrollPositionPage, self).__init__(
            page_set=page_set, base_dir=base_dir,
            shared_page_state_class=NoClosingBrowserSharedState, url=url,
            name='CheckScroll')
        self.was_page_at_top_on_start = False

      def RunPageInteractions(self, action_runner):
        scroll_y = action_runner.tab.EvaluateJavaScript('window.scrollY')
        self.was_page_at_top_on_start = scroll_y == 0

    story_set = story.StorySet()
    story_set.AddStory(ScrollingPage(
        url='file://page_with_swipeables.html', page_set=story_set,
        base_dir=util.GetUnittestDataDir()))
    test_page = CheckScrollPositionPage(
        url='file://page_with_swipeables.html', page_set=story_set,
        base_dir=util.GetUnittestDataDir())
    story_set.AddStory(test_page)
    self.RunStorySet(DummyTest(), story_set)
    self.assertTrue(test_page.was_page_at_top_on_start)

  def testSingleTabMeansCrashWillCauseFailure(self):
    class TestPage(page_module.Page):
      def RunNavigateSteps(self, _):
        raise exceptions.AppCrashException

    story_set = story.StorySet()
    for i in range(5):
      story_set.AddStory(
          TestPage('file://blank.html', story_set,
                   base_dir=util.GetUnittestDataDir(), name='foo%d' % i))

    results = self.RunStorySet(DummyTest(), story_set, max_failures=1)
    self.assertTrue(results.benchmark_interrupted)
    self.assertEquals(3, results.num_skipped)
    self.assertEquals(2, results.num_failed)  # max_failures + 1

  def testWebPageReplay(self):
    story_set = example_domain.ExampleDomainPageSet()
    body = []

    class TestWpr(legacy_page_test.LegacyPageTest):
      def ValidateAndMeasurePage(self, page, tab, results):
        del page, results  # unused
        body.append(tab.EvaluateJavaScript('document.body.innerText'))

      def DidRunPage(self, platform):
        # Force the replay server to restart between pages; this verifies that
        # the restart mechanism works.
        platform.network_controller.StopReplay()

    test = TestWpr()
    results = self.RunStorySet(test, story_set)

    self.longMessage = True
    self.assertIn('Example Domain', body[0],
                  msg='URL: %s' % story_set.stories[0].url)
    self.assertIn('Example Domain', body[1],
                  msg='URL: %s' % story_set.stories[1].url)

    self.assertEquals(2, results.num_successful)
    self.assertFalse(results.had_failures)

  def testScreenShotTakenForFailedPage(self):
    class FailingTestPage(page_module.Page):
      def RunNavigateSteps(self, action_runner):
        action_runner.Navigate(self._url)
        raise exceptions.AppCrashException

    story_set = story.StorySet()
    story_set.AddStory(page_module.Page('file://blank.html', story_set,
                                        name='blank.html'))
    failing_page = FailingTestPage('chrome://version', story_set,
                                   name='failing')
    story_set.AddStory(failing_page)

    self.options.browser_options.take_screenshot_for_failed_page = True
    results = self.RunStorySet(DummyTest(), story_set, max_failures=2)
    self.assertTrue(results.had_failures)
    # Check that we can find the artifact with a non-empty PNG screenshot.
    failing_run = next(run for run in self.ReadTestResults()
                       if run['testPath'].endswith('/failing'))
    screenshot = image_util.FromPngFile(
        failing_run['outputArtifacts']['screenshot.png']['filePath'])
    self.assertGreater(image_util.Width(screenshot), 0)
    self.assertGreater(image_util.Height(screenshot), 0)
<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- encoding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
#    $Id$
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import time
import threading

import SimpleXMLRPCServer, signal, sys, xmlrpclib
import SocketServer
import socket
import logging
import logging.handlers
import os

_service = {}
_group = {}
_res_id = 1
_res = {}

class ServiceEndPointCall(object):
    def __init__(self, id, method):
        self._id = id
        self._meth = method

    def __call__(self, *args):
        _res[self._id] = self._meth(*args)
        return self._id

class ServiceEndPoint(object):
    def __init__(self, name, id):
        self._id = id
        self._meth = {}
        s = _service[name]
        for m in s._method:
            self._meth[m] = s._method[m]

    def __getattr__(self, name):
        return ServiceEndPointCall(self._id, self._meth[name])

class Service(object):
    _serviceEndPointID = 0

    def __init__(self, name, audience=''):
        _service[name] = self
        self.__name = name
        self._method = {}
        self.exportedMethods = None
        self._response_process = None
        self._response_process_id = None
        self._response = None

    def joinGroup(self, name):
        if not name in _group:
            _group[name] = {}
        _group[name][self.__name] = self

    def exportMethod(self, m):
        if callable(m):
            self._method[m.__name__] = m

    def serviceEndPoint(self, s):
        if Service._serviceEndPointID >= 2**16:
            Service._serviceEndPointID = 0
        Service._serviceEndPointID += 1
        return ServiceEndPoint(s, self._serviceEndPointID)

    def conversationId(self):
        return 1

    def processResponse(self, s, id):
        self._response_process, self._response_process_id = s, id

    def processFailure(self, s, id):
        pass

    def resumeResponse(self, s):
        pass

    def cancelResponse(self, s):
        pass

    def suspendResponse(self, s):
        if self._response_process:
            self._response_process(self._response_process_id,
                                   _res[self._response_process_id])
        self._response_process = None
        self._response = s(self._response_process_id)

    def abortResponse(self, error, description, origin, details):
        import tools
        if not tools.config['debug_mode']:
            raise Exception("%s -- %s\n\n%s"%(origin, description, details))
        else:
            raise

    def currentFailure(self, s):
        pass

class LocalService(Service):
    def __init__(self, name):
        self.__name = name
        try:
            s = _service[name]
            self._service = s
            for m in s._method:
                setattr(self, m, s._method[m])
        except KeyError, keyError:
            Logger().notifyChannel('module', LOG_ERROR, 'This service does not exists: %s' % (str(keyError),) )
            raise

class ServiceUnavailable(Exception):
    pass

def service_exist(name):
    return (name in _service) and bool(_service[name])

def get_rpc_paths():
    return map(lambda s: '/xmlrpc/%s' % s, _service)

LOG_DEBUG = 'debug'
LOG_INFO = 'info'
LOG_WARNING = 'warn'
LOG_ERROR = 'error'
LOG_CRITICAL = 'critical'

def init_logger():
    from tools import config
    import os

    if config['logfile']:
        logf = config['logfile']
        # test if the directories exist, else create them
        try:
            dirname = os.path.dirname(logf)
            if not os.path.isdir(dirname):
                res = os.makedirs(dirname)
            handler = logging.handlers.TimedRotatingFileHandler(logf,'D',1,30)
        except:
            sys.stderr.write("ERROR: couldn't create the logfile directory\n")
            handler = logging.StreamHandler(sys.stdout)
    else:
        handler = logging.StreamHandler(sys.stdout)

    # create a format for log messages and dates
    formatter = logging.Formatter('[%(asctime)s] %(levelname)s:%(name)s:%(message)s', '%a %b %d %H:%M:%S %Y')

    # tell the handler to use this format
    handler.setFormatter(formatter)

    # add the handler to the root logger
    logging.getLogger().addHandler(handler)
    logging.getLogger().setLevel(logging.INFO)

    if isinstance(handler, logging.StreamHandler) and os.name != 'nt':
        # change color of level names
        # uses of ANSI color codes
        # see http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html
        # maybe use http://code.activestate.com/recipes/574451/
        colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', None, 'default']
        foreground = lambda f: 30 + colors.index(f)
        background = lambda f: 40 + colors.index(f)

        mapping = {
            'DEBUG': ('blue', 'default'),
            'INFO': ('green', 'default'),
            'WARNING': ('yellow', 'default'),
            'ERROR': ('red', 'default'),
            'CRITICAL': ('white', 'red'),
        }

        for level, (fg, bg) in mapping.items():
            msg = "\x1b[%dm\x1b[%dm%s\x1b[0m" % (foreground(fg), background(bg), level)
            logging.addLevelName(getattr(logging, level), msg)

class Logger(object):
    def notifyChannel(self, name, level, msg):
        log = logging.getLogger(name)
        getattr(log, level)(msg)

init_logger()

class Agent(object):
    _timers = []
    _logger = Logger()

    def setAlarm(self, fn, dt, args=None, kwargs=None):
        if not args:
            args = []
        if not kwargs:
            kwargs = {}
        wait = dt - time.time()
        if wait > 0:
            self._logger.notifyChannel('timers', LOG_DEBUG, "Job scheduled in %s seconds for %s.%s" % (wait, fn.im_class.__name__, fn.func_name))
            timer = threading.Timer(wait, fn, args, kwargs)
            timer.start()
            self._timers.append(timer)
        for timer in self._timers[:]:
            if not timer.isAlive():
                self._timers.remove(timer)

    def quit(cls):
        for timer in cls._timers:
            timer.cancel()
    quit = classmethod(quit)

class RpcGateway(object):
    def __init__(self, name):
        self.name = name

class Dispatcher(object):
    def __init__(self):
        pass

    def monitor(self, signal):
        pass

    def run(self):
        pass

class xmlrpc(object):
    class RpcGateway(object):
        def __init__(self, name):
            self.name = name

class GenericXMLRPCRequestHandler:
    def _dispatch(self, method, params):
        #print 'TERP-CALL : ',method, params
        import traceback
        try:
            n = self.path.split("/")[-1]
            s = LocalService(n)
            m = getattr(s, method)
            s._service._response = None
            r = m(*params)
            res = s._service._response
            if res != None:
                r = res
            return r
        except Exception, e:
            tb_s = reduce(lambda x, y: x+y, traceback.format_exception(
                sys.exc_type, sys.exc_value, sys.exc_traceback))
            s = str(e)
            import tools
            if tools.config['debug_mode']:
                import pdb
                tb = sys.exc_info()[2]
                pdb.post_mortem(tb)
            raise xmlrpclib.Fault(s, tb_s)

class SimpleXMLRPCRequestHandler(GenericXMLRPCRequestHandler, SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
    SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.rpc_paths = get_rpc_paths()

class SimpleThreadedXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer.SimpleXMLRPCServer):

    def server_bind(self):
        try:
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            SimpleXMLRPCServer.SimpleXMLRPCServer.server_bind(self)
        except:
            Logger().notifyChannel('init', LOG_ERROR, 'Address already in use')
            sys.exit(1)

class HttpDaemon(threading.Thread):

    def __init__(self, interface, port, secure=False):
        threading.Thread.__init__(self)
        self.__port = port
        self.__interface = interface
        self.secure = secure
        if secure:
            from ssl import SecureXMLRPCServer

            class SecureXMLRPCRequestHandler(GenericXMLRPCRequestHandler, SecureXMLRPCServer.SecureXMLRPCRequestHandler):
                SecureXMLRPCServer.SecureXMLRPCRequestHandler.rpc_paths = get_rpc_paths()

            class SecureThreadedXMLRPCServer(SocketServer.ThreadingMixIn, SecureXMLRPCServer.SecureXMLRPCServer):
                def server_bind(self):
                    try:
                        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                        SecureXMLRPCServer.SecureXMLRPCServer.server_bind(self)
                    except:
                        sys.stderr.write("ERROR: address already in use\n")
                        sys.exit(1)

            self.server = SecureThreadedXMLRPCServer((interface, port),
                    SecureXMLRPCRequestHandler, 0)
        else:
            self.server = SimpleThreadedXMLRPCServer((interface, port),
                    SimpleXMLRPCRequestHandler, 0)

    def attach(self, path, gw):
        pass

    def stop(self):
        self.running = False
        if os.name != 'nt':
            if hasattr(socket, 'SHUT_RDWR'):
                if self.secure:
                    self.server.socket.sock_shutdown(socket.SHUT_RDWR)
                else:
                    self.server.socket.shutdown(socket.SHUT_RDWR)
            else:
                if self.secure:
                    self.server.socket.sock_shutdown(2)
                else:
                    self.server.socket.shutdown(2)
        self.server.socket.close()

    def run(self):
        self.server.register_introspection_functions()

        self.running = True
        while self.running:
            self.server.handle_request()
        return True

        # If the server need to be run recursively
        #
        #signal.signal(signal.SIGALRM, self.my_handler)
        #signal.alarm(6)
        #while True:
        #   self.server.handle_request()
        #signal.alarm(0)          # Disable the alarm

import tiny_socket
class TinySocketClientThread(threading.Thread):
    def __init__(self, sock, threads):
        threading.Thread.__init__(self)
        self.sock = sock
        self.threads = threads

    def run(self):
        import traceback
        import time
        import select
        self.running = True
        try:
            ts = tiny_socket.mysocket(self.sock)
        except:
            self.sock.close()
            self.threads.remove(self)
            return False
        while self.running:
            try:
                msg = ts.myreceive()
            except:
                self.sock.close()
                self.threads.remove(self)
                return False
            try:
                s = LocalService(msg[0])
                m = getattr(s, msg[1])
                s._service._response = None
                r = m(*msg[2:])
                res = s._service._response
                if res != None:
                    r = res
                ts.mysend(r)
            except Exception, e:
                tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
                s = str(e)
                import tools
                if tools.config['debug_mode']:
                    import pdb
                    tb = sys.exc_info()[2]
                    pdb.post_mortem(tb)
                ts.mysend(e, exception=True, traceback=tb_s)
            except:
                pass
            self.sock.close()
            self.threads.remove(self)
            return True

    def stop(self):
        self.running = False

class TinySocketServerThread(threading.Thread):
    def __init__(self, interface, port, secure=False):
        threading.Thread.__init__(self)
        self.__port = port
        self.__interface = interface
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.bind((self.__interface, self.__port))
        self.socket.listen(5)
        self.threads = []

    def run(self):
        import select
        try:
            self.running = True
            while self.running:
                (clientsocket, address) = self.socket.accept()
                ct = TinySocketClientThread(clientsocket, self.threads)
                self.threads.append(ct)
                ct.start()
            self.socket.close()
        except Exception, e:
            self.socket.close()
            return False

    def stop(self):
        self.running = False
        for t in self.threads:
            t.stop()
        try:
            if hasattr(socket, 'SHUT_RDWR'):
                self.socket.shutdown(socket.SHUT_RDWR)
            else:
                self.socket.shutdown(2)
            self.socket.close()
        except:
            return False

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<commit_msg>[IMP] Change the presentation of the logger<commit_after>#!/usr/bin/python
# -*- encoding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
#    $Id$
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import time
import threading

import SimpleXMLRPCServer, signal, sys, xmlrpclib
import SocketServer
import socket
import logging
import logging.handlers
import os

_service = {}
_group = {}
_res_id = 1
_res = {}

class ServiceEndPointCall(object):
    def __init__(self, id, method):
        self._id = id
        self._meth = method

    def __call__(self, *args):
        _res[self._id] = self._meth(*args)
        return self._id

class ServiceEndPoint(object):
    def __init__(self, name, id):
        self._id = id
        self._meth = {}
        s = _service[name]
        for m in s._method:
            self._meth[m] = s._method[m]

    def __getattr__(self, name):
        return ServiceEndPointCall(self._id, self._meth[name])

class Service(object):
    _serviceEndPointID = 0

    def __init__(self, name, audience=''):
        _service[name] = self
        self.__name = name
        self._method = {}
        self.exportedMethods = None
        self._response_process = None
        self._response_process_id = None
        self._response = None

    def joinGroup(self, name):
        if not name in _group:
            _group[name] = {}
        _group[name][self.__name] = self

    def exportMethod(self, m):
        if callable(m):
            self._method[m.__name__] = m

    def serviceEndPoint(self, s):
        if Service._serviceEndPointID >= 2**16:
            Service._serviceEndPointID = 0
        Service._serviceEndPointID += 1
        return ServiceEndPoint(s, self._serviceEndPointID)

    def conversationId(self):
        return 1

    def processResponse(self, s, id):
        self._response_process, self._response_process_id = s, id

    def processFailure(self, s, id):
        pass

    def resumeResponse(self, s):
        pass

    def cancelResponse(self, s):
        pass

    def suspendResponse(self, s):
        if self._response_process:
            self._response_process(self._response_process_id,
                                   _res[self._response_process_id])
        self._response_process = None
        self._response = s(self._response_process_id)

    def abortResponse(self, error, description, origin, details):
        import tools
        if not tools.config['debug_mode']:
            raise Exception("%s -- %s\n\n%s"%(origin, description, details))
        else:
            raise

    def currentFailure(self, s):
        pass

class LocalService(Service):
    def __init__(self, name):
        self.__name = name
        try:
            s = _service[name]
            self._service = s
            for m in s._method:
                setattr(self, m, s._method[m])
        except KeyError, keyError:
            Logger().notifyChannel('module', LOG_ERROR, 'This service does not exists: %s' % (str(keyError),) )
            raise

class ServiceUnavailable(Exception):
    pass

def service_exist(name):
    return (name in _service) and bool(_service[name])

def get_rpc_paths():
    return map(lambda s: '/xmlrpc/%s' % s, _service)

LOG_DEBUG = 'debug'
LOG_INFO = 'info'
LOG_WARNING = 'warn'
LOG_ERROR = 'error'
LOG_CRITICAL = 'critical'

def init_logger():
    from tools import config
    import os

    if config['logfile']:
        logf = config['logfile']
        # test if the directories exist, else create them
        try:
            dirname = os.path.dirname(logf)
            if not os.path.isdir(dirname):
                res = os.makedirs(dirname)
            handler = logging.handlers.TimedRotatingFileHandler(logf,'D',1,30)
        except:
            sys.stderr.write("ERROR: couldn't create the logfile directory\n")
            handler = logging.StreamHandler(sys.stdout)
    else:
        handler = logging.StreamHandler(sys.stdout)

    # create a format for log messages and dates
    formatter = logging.Formatter('[%(asctime)s] %(levelname)s:%(name)s:%(message)s', '%a %b %d %H:%M:%S %Y')

    # tell the handler to use this format
    handler.setFormatter(formatter)

    # add the handler to the root logger
    logging.getLogger().addHandler(handler)
    logging.getLogger().setLevel(logging.INFO)

    if isinstance(handler, logging.StreamHandler) and os.name != 'nt':
        # change color of level names
        # uses of ANSI color codes
        # see http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html
        # maybe use http://code.activestate.com/recipes/574451/
        colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', None, 'default']
        foreground = lambda f: 30 + colors.index(f)
        background = lambda f: 40 + colors.index(f)

        mapping = {
            'DEBUG': ('blue', 'default'),
            'INFO': ('green', 'default'),
            'WARNING': ('yellow', 'default'),
            'ERROR': ('red', 'default'),
            'CRITICAL': ('white', 'red'),
        }

        for level, (fg, bg) in mapping.items():
            msg = "\x1b[%dm\x1b[%dm%s\x1b[0m" % (foreground(fg), background(bg), level)
            logging.addLevelName(getattr(logging, level), msg)

class Logger(object):
    def notifyChannel(self, name, level, msg):
        log = logging.getLogger(name)
        level_method = getattr(log, level)

        result = msg.strip().split('\n')
        if len(result)>1:
            for idx, s in enumerate(result):
                level_method('[%02d]: %s' % (idx+1, s,))
        elif result:
            level_method(result[0])

init_logger()

class Agent(object):
    _timers = []
    _logger = Logger()

    def setAlarm(self, fn, dt, args=None, kwargs=None):
        if not args:
            args = []
        if not kwargs:
            kwargs = {}
        wait = dt - time.time()
        if wait > 0:
            self._logger.notifyChannel('timers', LOG_DEBUG, "Job scheduled in %s seconds for %s.%s" % (wait, fn.im_class.__name__, fn.func_name))
            timer = threading.Timer(wait, fn, args, kwargs)
            timer.start()
            self._timers.append(timer)
        for timer in self._timers[:]:
            if not timer.isAlive():
                self._timers.remove(timer)

    def quit(cls):
        for timer in cls._timers:
            timer.cancel()
    quit = classmethod(quit)

class RpcGateway(object):
    def __init__(self, name):
        self.name = name

class Dispatcher(object):
    def __init__(self):
        pass

    def monitor(self, signal):
        pass

    def run(self):
        pass

class xmlrpc(object):
    class RpcGateway(object):
        def __init__(self, name):
            self.name = name

class GenericXMLRPCRequestHandler:
    def _dispatch(self, method, params):
        #print 'TERP-CALL : ',method, params
        import traceback
        try:
            n = self.path.split("/")[-1]
            s = LocalService(n)
            m = getattr(s, method)
            s._service._response = None
            r = m(*params)
            res = s._service._response
            if res != None:
                r = res
            return r
        except Exception, e:
            tb_s = reduce(lambda x, y: x+y, traceback.format_exception(
                sys.exc_type, sys.exc_value, sys.exc_traceback))
            s = str(e)
            import tools
            if tools.config['debug_mode']:
                import pdb
                tb = sys.exc_info()[2]
                pdb.post_mortem(tb)
            raise xmlrpclib.Fault(s, tb_s)

class SimpleXMLRPCRequestHandler(GenericXMLRPCRequestHandler, SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
    SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.rpc_paths = get_rpc_paths()

class SimpleThreadedXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer.SimpleXMLRPCServer):

    def server_bind(self):
        try:
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            SimpleXMLRPCServer.SimpleXMLRPCServer.server_bind(self)
        except:
            Logger().notifyChannel('init', LOG_ERROR, 'Address already in use')
            sys.exit(1)

class HttpDaemon(threading.Thread):

    def __init__(self, interface, port, secure=False):
        threading.Thread.__init__(self)
        self.__port = port
        self.__interface = interface
        self.secure = secure
        if secure:
            from ssl import SecureXMLRPCServer

            class SecureXMLRPCRequestHandler(GenericXMLRPCRequestHandler, SecureXMLRPCServer.SecureXMLRPCRequestHandler):
                SecureXMLRPCServer.SecureXMLRPCRequestHandler.rpc_paths = get_rpc_paths()

            class SecureThreadedXMLRPCServer(SocketServer.ThreadingMixIn, SecureXMLRPCServer.SecureXMLRPCServer):
                def server_bind(self):
                    try:
                        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                        SecureXMLRPCServer.SecureXMLRPCServer.server_bind(self)
                    except:
                        sys.stderr.write("ERROR: address already in use\n")
                        sys.exit(1)

            self.server = SecureThreadedXMLRPCServer((interface, port),
                    SecureXMLRPCRequestHandler, 0)
        else:
            self.server = SimpleThreadedXMLRPCServer((interface, port),
                    SimpleXMLRPCRequestHandler, 0)

    def attach(self, path, gw):
        pass

    def stop(self):
        self.running = False
        if os.name != 'nt':
            if hasattr(socket, 'SHUT_RDWR'):
                if self.secure:
                    self.server.socket.sock_shutdown(socket.SHUT_RDWR)
                else:
                    self.server.socket.shutdown(socket.SHUT_RDWR)
            else:
                if self.secure:
                    self.server.socket.sock_shutdown(2)
                else:
                    self.server.socket.shutdown(2)
        self.server.socket.close()

    def run(self):
        self.server.register_introspection_functions()

        self.running = True
        while self.running:
            self.server.handle_request()
        return True

        # If the server need to be run recursively
        #
        #signal.signal(signal.SIGALRM, self.my_handler)
        #signal.alarm(6)
        #while True:
        #   self.server.handle_request()
        #signal.alarm(0)          # Disable the alarm

import tiny_socket
class TinySocketClientThread(threading.Thread):
    def __init__(self, sock, threads):
        threading.Thread.__init__(self)
        self.sock = sock
        self.threads = threads

    def run(self):
        import traceback
        import time
        import select
        self.running = True
        try:
            ts = tiny_socket.mysocket(self.sock)
        except:
            self.sock.close()
            self.threads.remove(self)
            return False
        while self.running:
            try:
                msg = ts.myreceive()
            except:
                self.sock.close()
                self.threads.remove(self)
                return False
            try:
                s = LocalService(msg[0])
                m = getattr(s, msg[1])
                s._service._response = None
                r = m(*msg[2:])
                res = s._service._response
                if res != None:
                    r = res
                ts.mysend(r)
            except Exception, e:
                tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
                s = str(e)
                import tools
                if tools.config['debug_mode']:
                    import pdb
                    tb = sys.exc_info()[2]
                    pdb.post_mortem(tb)
                ts.mysend(e, exception=True, traceback=tb_s)
            except:
                pass
            self.sock.close()
            self.threads.remove(self)
            return True

    def stop(self):
        self.running = False

class TinySocketServerThread(threading.Thread):
    def __init__(self, interface, port, secure=False):
        threading.Thread.__init__(self)
        self.__port = port
        self.__interface = interface
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.bind((self.__interface, self.__port))
        self.socket.listen(5)
        self.threads = []

    def run(self):
        import select
        try:
            self.running = True
            while self.running:
                (clientsocket, address) = self.socket.accept()
                ct = TinySocketClientThread(clientsocket, self.threads)
                self.threads.append(ct)
                ct.start()
            self.socket.close()
        except Exception, e:
            self.socket.close()
            return False

    def stop(self):
        self.running = False
        for t in self.threads:
            t.stop()
        try:
            if hasattr(socket, 'SHUT_RDWR'):
                self.socket.shutdown(socket.SHUT_RDWR)
            else:
                self.socket.shutdown(2)
            self.socket.close()
        except:
            return False

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<|endoftext|>


<commit_before>#!/usr/bin/python
#
# checkpoint.py:  Construct a list of hashes to use as checkpoints.
#
#
# Copyright (c) 2016 The Reddcoin developers
# Distributed under the MIT/X11 software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#

import json
import struct
import re
import base64
import httplib
import sys

ERR_SLEEP = 15
MAX_NONCE = 1000000L

settings = {}

class BitcoinRPC:
	OBJID = 1

	def __init__(self, host, port, username, password):
		authpair = "%s:%s" % (username, password)
		self.authhdr = "Basic %s" % (base64.b64encode(authpair))
		self.conn = httplib.HTTPConnection(host, port, False, 30)
	def rpc(self, method, params=None):
		self.OBJID += 1
		obj = { 'version' : '1.1',
			'method' : method,
			'id' : self.OBJID }
		if params is None:
			obj['params'] = []
		else:
			obj['params'] = params
		self.conn.request('POST', '/', json.dumps(obj),
			{ 'Authorization' : self.authhdr,
			  'Content-type' : 'application/json' })

		resp = self.conn.getresponse()
		if resp is None:
			print "JSON-RPC: no response"
			return None

		body = resp.read()
		resp_obj = json.loads(body)
		if resp_obj is None:
			print "JSON-RPC: cannot JSON-decode body"
			return None
		if 'error' in resp_obj and resp_obj['error'] != None:
			return resp_obj['error']
		if 'result' not in resp_obj:
			print "JSON-RPC: no result in object"
			return None

		return resp_obj['result']

	def getblockcount(self):
		return self.rpc('getblockcount')
	def getblock(self, hash, verbose=True):
		return self.rpc('getblock', [hash, verbose])
	def getblockhash(self, index):
		return self.rpc('getblockhash', [index])

def getblockcount(rpc):
	count = rpc.getblockcount()

	return count

def getblock(rpc, settings, n):
	hash = rpc.getblockhash(n)
	blockdata = rpc.getblock(hash)
	#data = hexdata.decode('hex')

	return blockdata

def get_blocks(settings):
	rpc = BitcoinRPC(settings['host'], settings['port'],
			 settings['rpcuser'], settings['rpcpassword'])

	if (settings['max_height'] == 0):
		settings['max_height']=getblockcount(rpc)
	print "MaxHeight = " + repr(settings['max_height'])
	print "MinHeight = " + repr(settings['min_height'])

	prevtime=0

	outf = open(settings['output'], 'wb')
	#out = "block,difficulty,version\r\n"
	#outf.write(out)

	for height in xrange(settings['min_height'], settings['max_height']+1, settings['step']):
		blockdata = getblock(rpc, settings, height)
		time = blockdata["time"]
		blkheight = blockdata["height"]
                blkhash = blockdata["hash"]

		if (height >= settings['min_height']):
#			out = repr(height - 1) + " - " + repr(height) + "," + repr(diff) + "," + repr(time - prevtime) + "\r\n"
			out = "(" + '{:>7}'.format(repr(blkheight)) + ", uint256(\"0x" + str(blkhash) + "\"))\r\n"
			outf.write(out)

		prevtime=time

		if (height % 1000) == 0:
			sys.stdout.write("Wrote block " + str(height) + "\n")

if __name__ == '__main__':
	if len(sys.argv) != 2:
		print "Usage: blocktime.py CONFIG-FILE"
		sys.exit(1)

	f = open(sys.argv[1])
	for line in f:
		# skip comment lines
		m = re.search('^\s*#', line)
		if m:
			continue

		# parse key=value lines
		m = re.search('^(\w+)\s*=\s*(\S.*)$', line)
		if m is None:
			continue
		settings[m.group(1)] = m.group(2)
	f.close()

	if 'netmagic' not in settings:
		settings['netmagic'] = 'f9beb4d9'
	if 'output' not in settings:
		settings['output'] = 'blocktimes.log'
	if 'host' not in settings:
		settings['host'] = '127.0.0.1'
	if 'port' not in settings:
		settings['port'] = 8332
	if 'min_height' not in settings:
		settings['min_height'] = 0
	if 'max_height' not in settings:
		settings['max_height'] = 0 #if zero we will read from blockchain for last block height
	if 'step' not in settings:
		settings['step'] = 1
	if 'rpcuser' not in settings or 'rpcpassword' not in settings:
		print "Missing username and/or password in cfg file"
		sys.exit(1)

	settings['netmagic'] = settings['netmagic'].decode('hex')
	settings['port'] = int(settings['port'])
	settings['min_height'] = int(settings['min_height'])
	settings['max_height'] = int(settings['max_height'])
	settings['step'] = int(settings['step'])

	get_blocks(settings)

<commit_msg>update checkpoint python script<commit_after>#!/usr/bin/python
#
# checkpoint.py:  Construct a list of hashes to use as checkpoints.
#
#
# Copyright (c) 2016 The Reddcoin developers
# Distributed under the MIT/X11 software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#

import json
import struct
import re
import base64
import httplib
import sys

ERR_SLEEP = 15
# MAX_NONCE = 1000000L

settings = {}

class BitcoinRPC:
	OBJID = 1

	def __init__(self, host, port, username, password):
		authpair = "%s:%s" % (username, password)
		self.authhdr = "Basic %s" % (base64.b64encode(authpair))
		self.conn = httplib.HTTPConnection(host, port, False, 60)
	def rpc(self, method, params=None):
		self.OBJID += 1
		obj = { 'version' : '1.1',
			'method' : method,
			'id' : self.OBJID }
		if params is None:
			obj['params'] = []
		else:
			obj['params'] = params
		self.conn.request('POST', '/', json.dumps(obj),
			{ 'Authorization' : self.authhdr,
			  'Content-type' : 'application/json' })

		resp = self.conn.getresponse()
		if resp is None:
			print("JSON-RPC: no response")
			return None

		body = resp.read()
		resp_obj = json.loads(body)
		if resp_obj is None:
			print("JSON-RPC: cannot JSON-decode body")
			return None
		if 'error' in resp_obj and resp_obj['error'] != None:
			return resp_obj['error']
		if 'result' not in resp_obj:
			print("JSON-RPC: no result in object")
			return None

		return resp_obj['result']

	def getblockcount(self):
		return self.rpc('getblockcount')
	def getblock(self, hash, verbose=True):
		return self.rpc('getblock', [hash, verbose])
	def getblockhash(self, index):
		return self.rpc('getblockhash', [index])

def getblockcount(rpc):
	count = rpc.getblockcount()

	return count

def getblock(rpc, settings, n):
	hash = rpc.getblockhash(n)
	blockdata = rpc.getblock(hash)
	#data = hexdata.decode('hex')

	return blockdata

def get_blocks(settings):
	rpc = BitcoinRPC(settings['host'], settings['port'],
			 settings['rpcuser'], settings['rpcpassword'])

	if (settings['max_height'] == 0):
		settings['max_height']=getblockcount(rpc)
	print("MaxHeight = " + repr(settings['max_height']))
	print("MinHeight = " + repr(settings['min_height']))

	prevtime=0

	outf = open(settings['output'], 'wb')
	#out = "block,difficulty,version\r\n"
	#outf.write(out)

	for height in xrange(settings['min_height'], settings['max_height']+1, settings['step']):
		blockdata = getblock(rpc, settings, height)
		time = blockdata["time"]
		blkheight = blockdata["height"]
		blkhash = blockdata["hash"]

		if (height >= settings['min_height']):
#			out = repr(height - 1) + " - " + repr(height) + "," + repr(diff) + "," + repr(time - prevtime) + "\r\n"
			out = "    (" + '{:>7}'.format(repr(blkheight)) + ", uint256(\"0x" + str(blkhash) + "\"))\r\n"
			outf.write(out)

		prevtime=time

		if (height % 1000) == 0:
			sys.stdout.write("Wrote block " + str(height) + "\n")

if __name__ == '__main__':
	if len(sys.argv) != 2:
		print("Usage: blocktime.py CONFIG-FILE")
		sys.exit(1)

	f = open(sys.argv[1])
	for line in f:
		# skip comment lines
		m = re.search('^\s*#', line)
		if m:
			continue

		# parse key=value lines
		m = re.search('^(\w+)\s*=\s*(\S.*)$', line)
		if m is None:
			continue
		settings[m.group(1)] = m.group(2)
	f.close()

	if 'netmagic' not in settings:
		settings['netmagic'] = 'f9beb4d9'
	if 'output' not in settings:
		settings['output'] = 'blocktimes.log'
	if 'host' not in settings:
		settings['host'] = '127.0.0.1'
	if 'port' not in settings:
		settings['port'] = 8332
	if 'min_height' not in settings:
		settings['min_height'] = 0
	if 'max_height' not in settings:
		settings['max_height'] = 0 #if zero we will read from blockchain for last block height
	if 'step' not in settings:
		settings['step'] = 1
	if 'rpcuser' not in settings or 'rpcpassword' not in settings:
		print("Missing username and/or password in cfg file")
		sys.exit(1)

	settings['netmagic'] = settings['netmagic'].decode('hex')
	settings['port'] = int(settings['port'])
	settings['min_height'] = int(settings['min_height'])
	settings['max_height'] = int(settings['max_height'])
	settings['step'] = int(settings['step'])

	get_blocks(settings)
<|endoftext|>


<commit_before>import argparse
import eg_config
import eg_util
import sys

def run_eg():

    parser = argparse.ArgumentParser(
        description='eg provides examples of common command usage.'
    )

    parser.add_argument(
        '-v',
        '--version',
        action='store_true',
        help='Display version information about eg'
    )

    parser.add_argument(
        '--config-file',
        help='Path to the .egrc file, if it is not in the default location.'
    )

    parser.add_argument(
        '--examples-dir',
        help='The location to the examples/ dir that ships with eg'
    )

    parser.add_argument(
        '--custom-dir',
        help='Path to a directory containing user-defined examples.'
    )

    parser.add_argument(
        '--list',
        action='store_true',
        help='Show all the programs with eg entries.'
    )

    parser.add_argument(
        '--color',
        action='store_true',
        dest='use_color',
        default=None,
        help='Colorize output.'
    )

    parser.add_argument(
        '--no-color',
        action='store_false',
        dest='use_color',
        help='Do not colorize output.'
    )

    parser.add_argument(
        'program',
        nargs='?',
        help='The program for which to display examples.'
    )

    args = parser.parse_args()

    if len(sys.argv) < 2:
        parser.print_help()
    elif not args.version and not args.list and not args.program:
        print 'you must specify a program or pass the --list or --version flags'
    else:
        config = eg_config.get_resolved_config_items(
            egrc_path=args.config_file,
            examples_dir=args.examples_dir,
            custom_dir=args.custom_dir,
            use_color=args.use_color
        )

        if args.list:
            # Show what's available.
            supported_programs = eg_util.get_list_of_all_supported_commands(
                config
            )
            msg_line_1 = 'Legend: '
            msg_line_2 = ('    ' +
                          eg_util.FLAG_ONLY_CUSTOM +
                          ' only custom files'
                          )
            msg_line_3 = ('    ' +
                          eg_util.FLAG_CUSTOM_AND_DEFAULT +
                          ' custom and default files'
                          )
            msg_line_4 = '    ' + '  only default files (no symbol)'
            msg_line_5 = ''
            msg_line_6 = 'Programs supported by eg: '

            preamble = [
                msg_line_1,
                msg_line_2,
                msg_line_3,
                msg_line_4,
                msg_line_5,
                msg_line_6
            ]

            for line in preamble:
                print line

            for program in supported_programs:
                print program
        elif args.version:
            print eg_util.VERSION
        else:
            eg_util.handle_program(args.program, config)

# We want people to be able to use eg without pip, by so we'll allow this to be
# invoked directly.
if __name__ == '__main__':
    run_eg()
<commit_msg>pipe --list output through pager<commit_after>import argparse
import eg_config
import eg_util
import pydoc
import sys

def run_eg():

    parser = argparse.ArgumentParser(
        description='eg provides examples of common command usage.'
    )

    parser.add_argument(
        '-v',
        '--version',
        action='store_true',
        help='Display version information about eg'
    )

    parser.add_argument(
        '--config-file',
        help='Path to the .egrc file, if it is not in the default location.'
    )

    parser.add_argument(
        '--examples-dir',
        help='The location to the examples/ dir that ships with eg'
    )

    parser.add_argument(
        '--custom-dir',
        help='Path to a directory containing user-defined examples.'
    )

    parser.add_argument(
        '--list',
        action='store_true',
        help='Show all the programs with eg entries.'
    )

    parser.add_argument(
        '--color',
        action='store_true',
        dest='use_color',
        default=None,
        help='Colorize output.'
    )

    parser.add_argument(
        '--no-color',
        action='store_false',
        dest='use_color',
        help='Do not colorize output.'
    )

    parser.add_argument(
        'program',
        nargs='?',
        help='The program for which to display examples.'
    )

    args = parser.parse_args()

    if len(sys.argv) < 2:
        parser.print_help()
    elif not args.version and not args.list and not args.program:
        print 'you must specify a program or pass the --list or --version flags'
    else:
        config = eg_config.get_resolved_config_items(
            egrc_path=args.config_file,
            examples_dir=args.examples_dir,
            custom_dir=args.custom_dir,
            use_color=args.use_color
        )

        if args.list:
            # Show what's available.
            supported_programs = eg_util.get_list_of_all_supported_commands(
                config
            )
            msg_line_1 = 'Legend: '
            msg_line_2 = ('    ' +
                          eg_util.FLAG_ONLY_CUSTOM +
                          ' only custom files'
                          )
            msg_line_3 = ('    ' +
                          eg_util.FLAG_CUSTOM_AND_DEFAULT +
                          ' custom and default files'
                          )
            msg_line_4 = '    ' + '  only default files (no symbol)'
            msg_line_5 = ''
            msg_line_6 = 'Programs supported by eg: '

            preamble = [
                msg_line_1,
                msg_line_2,
                msg_line_3,
                msg_line_4,
                msg_line_5,
                msg_line_6
            ]

            complete_message = '\n'.join(preamble)
            complete_message += '\n' + '\n'.join(supported_programs)

            pydoc.pager(complete_message)
        elif args.version:
            print eg_util.VERSION
        else:
            eg_util.handle_program(args.program, config)

# We want people to be able to use eg without pip, by so we'll allow this to be
# invoked directly.
if __name__ == '__main__':
    run_eg()
<|endoftext|>