Home | History | Annotate | Download | only in webpagereplay
      1 #!/usr/bin/env python
      2 # Copyright 2012 Google Inc. All Rights Reserved.
      3 #
      4 # Licensed under the Apache License, Version 2.0 (the "License");
      5 # you may not use this file except in compliance with the License.
      6 # You may obtain a copy of the License at
      7 #
      8 #      http://www.apache.org/licenses/LICENSE-2.0
      9 #
     10 # Unless required by applicable law or agreed to in writing, software
     11 # distributed under the License is distributed on an "AS IS" BASIS,
     12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 # See the License for the specific language governing permissions and
     14 # limitations under the License.
     15 
     16 
     17 """Miscellaneous utility functions."""
     18 
     19 import inspect
     20 import logging
     21 import time
     22 
     23 try:
     24   # pkg_resources (part of setuptools) is needed when WPR is
     25   # distributed as a package. (Resources may need to be extracted from
     26   # the package.)
     27 
     28   import pkg_resources
     29 
     30   def resource_exists(resource_name):
     31     return pkg_resources.resource_exists(__name__, resource_name)
     32 
     33   def resource_string(resource_name):
     34     return pkg_resources.resource_string(__name__, resource_name)
     35 
     36 except ImportError:
     37   # Import of pkg_resources failed, so fall back to getting resources
     38   # from the file system.
     39 
     40   import os
     41 
     42   def _resource_path(resource_name):
     43     _replay_dir = os.path.dirname(os.path.abspath(__file__))
     44     return os.path.join(_replay_dir, resource_name)
     45 
     46   def resource_exists(resource_name):
     47     return os.path.exists(_resource_path(resource_name))
     48 
     49   def resource_string(resource_name):
     50     return open(_resource_path(resource_name)).read()
     51 
     52 
     53 class TimeoutException(Exception):
     54   pass
     55 
     56 
     57 def WaitFor(condition, timeout):
     58   """Waits for up to |timeout| secs for the function |condition| to return True.
     59 
     60   Polling frequency is (elapsed_time / 10), with a min of .1s and max of 5s.
     61 
     62   Returns:
     63     Result of |condition| function (if present).
     64   """
     65   min_poll_interval = 0.1
     66   max_poll_interval = 5
     67   output_interval = 300
     68 
     69   def GetConditionString():
     70     if condition.__name__ == '<lambda>':
     71       try:
     72         return inspect.getsource(condition).strip()
     73       except IOError:
     74         pass
     75     return condition.__name__
     76 
     77   start_time = time.time()
     78   last_output_time = start_time
     79   while True:
     80     res = condition()
     81     if res:
     82       return res
     83     now = time.time()
     84     elapsed_time = now - start_time
     85     last_output_elapsed_time = now - last_output_time
     86     if elapsed_time > timeout:
     87       raise TimeoutException('Timed out while waiting %ds for %s.' %
     88                                         (timeout, GetConditionString()))
     89     if last_output_elapsed_time > output_interval:
     90       logging.info('Continuing to wait %ds for %s. Elapsed: %ds.',
     91                    timeout, GetConditionString(), elapsed_time)
     92       last_output_time = time.time()
     93     poll_interval = min(max(elapsed_time / 10., min_poll_interval),
     94                         max_poll_interval)
     95     time.sleep(poll_interval)
     96