Skip to main content

time manipulation utilities for testing in python

Project description

ci coveralls pypi docs license

Yatta!

—Hiro Nakamura

Hiro context manager

Timeline context

The hiro.Timeline context manager hijacks a few commonly used time functions to allow time manipulation within its context. Specifically time.sleep, time.time, time.gmtime, datetime.now, datetime.utcnow and datetime.today behave according the configuration of the context.

The context provides the following manipulation options:

  • rewind: accepts seconds as an integer or a timedelta object.

  • forward: accepts seconds as an integer or a timedelta object.

  • freeze: accepts a floating point time since epoch or datetime or date object to freeze the time at.

  • unfreeze: resumes time from the point it was frozen at.

  • scale: accepts a floating point to accelerate/decelerate time by. > 1 = acceleration, < 1 = deceleration

  • reset: resets all time alterations.

import hiro
from datetime import timedelta, datetime
import time

datetime.now().isoformat()
# OUT: '2013-12-01T06:55:41.706060'
with hiro.Timeline() as timeline:

    # forward by an hour
    timeline.forward(60*60)
    datetime.now().isoformat()
    # OUT: '2013-12-01T07:55:41.707383'

    # jump forward by 10 minutes
    timeline.forward(timedelta(minutes=10))
    datetime.now().isoformat()
    # OUT: '2013-12-01T08:05:41.707425'

    # jump to yesterday and freeze
    timeline.freeze(datetime.now() - timedelta(hours=24))
    datetime.now().isoformat()
    # OUT: '2013-11-30T09:15:41'

    timeline.scale(5) # scale time by 5x
    time.sleep(5) # this will effectively only sleep for 1 second

    # since time is frozen the sleep has no effect
    datetime.now().isoformat()
    # OUT: '2013-11-30T09:15:41'

    timeline.rewind(timedelta(days=365))

    datetime.now().isoformat()
    # OUT: '2012-11-30T09:15:41'

To reduce the amount of statements inside the context, certain timeline setup tasks can be done via the constructor and/or by using the fluent interface.

import hiro
import time
from datetime import timedelta, datetime

start_point = datetime(2012,12,12,0,0,0)
my_timeline = hiro.Timeline(scale=5).forward(60*60).freeze()
with my_timeline as timeline:
    print datetime.now()
    # OUT: '2012-12-12 01:00:00.000315'
    time.sleep(5) # effectively 1 second
    # no effect as time is frozen
    datetime.now()
    # OUT: '2012-12-12 01:00:00.000315'
    timeline.unfreeze()
    # back to starting point
    datetime.now()
    # OUT: '2012-12-12 01:00:00.000317'
    time.sleep(5) # effectively 1 second
    # takes effect (+5 seconds)
    datetime.now()
    # OUT: '2012-12-12 01:00:05.003100'

Timeline can additionally be used as a decorator

import hiro
import time, datetime

@hiro.Timeline(scale=50000)
def sleeper():
    datetime.datetime.now()
    # OUT: '2013-11-30 14:27:43.409291'
    time.sleep(60*60) # effectively 72 ms
    datetime.datetime.now()
    # OUT: '2013-11-30 15:28:36.240675'

@hiro.Timeline()
def sleeper_aware(timeline):
    datetime.datetime.now()
    # OUT: '2013-11-30 14:27:43.409291'
    timeline.forward(60*60)
    datetime.datetime.now()
    # OUT: '2013-11-30 15:28:36.240675'

Hiro executors

In order to execute certain callables within a Timeline context, two shortcut functions are provided.

  • run_sync(factor=1, callable, *args, **kwargs)

  • run_async(factor=1, callable, *args, **kwargs)

Both functions return a ScaledRunner object which provides the following methods

  • get_execution_time: The actual execution time of the callable

  • get_response (will either return the actual return value of callable or raise the exception that was thrown)

run_async returns a derived class of ScaledRunner that additionally provides the following methods

  • is_running: True/False depending on whether the callable has completed execution

  • join: blocks until the callable completes execution

Example

import hiro
import time

def _slow_function(n):
    time.sleep(n)
    if n > 10:
        raise RuntimeError()
    return n

runner = hiro.run_sync(10, _slow_function, 10)
runner.get_response()
# OUT: 10

# due to the scale factor 10 it only took 1s to execute
runner.get_execution_time()
# OUT: 1.1052658557891846

runner = hiro.run_async(10, _slow_function, 11)
runner.is_running()
# OUT: True
runner.join()
runner.get_execution_time()
# OUT: 1.1052658557891846
runner.get_response()
# OUT: Traceback (most recent call last):
# ....
# OUT:   File "<input>", line 4, in _slow_function
# OUT: RuntimeError

Changelog

v1.0.2

Release Date: 2023-01-11

Chores:
  • Update documentation theme

v1.0.1

Release Date: 2023-01-11

Compatibility:
  • Update package classifiers to reflect python version support

v1.0.0

Release Date: 2023-01-10

Compatibility:
  • Drop support for python < 3.7

  • Update sources to not need six for compatibility

Chores:
  • Standardize linting

  • Add Asia/Shanghai to CI matrix

v0.5.1

Release Date: 2019-10-10

Code cleanup

v0.5

Release Date: 2017-07-26

Bug Fix:

v0.1.8

Release Date: 2015-06-07

  • Add Python 3.x support

v0.1.5

Release Date: 2014-04-03

Bug Fix:
  • Imports from time weren’t being patched.

v0.1.3

Release Date: 2014-04-01

Enhanced timeline decorator to pass generated timeline to decorated function

v0.1.2

Release Date: 2014-02-20

  • Added blacklist for unpatchable modules

  • CI improvements

  • removed ScaledTimeline

v0.1.1

Release Date: 2013-12-05

Added pypy support

v0.0.3

Release Date: 2013-11-30

Allow ScaledTimeline to be used as a decorator

v0.0.1

Release Date: 2013-11-30

Initial Release

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hiro-1.0.2.tar.gz (30.4 kB view details)

Uploaded Source

Built Distributions

hiro-1.0.2-py3.7.egg (20.4 kB view details)

Uploaded Source

hiro-1.0.2-py3-none-any.whl (11.0 kB view details)

Uploaded Python 3

File details

Details for the file hiro-1.0.2.tar.gz.

File metadata

  • Download URL: hiro-1.0.2.tar.gz
  • Upload date:
  • Size: 30.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.7.13

File hashes

Hashes for hiro-1.0.2.tar.gz
Algorithm Hash digest
SHA256 7c87f689ed95ce0e1bdf8d4f39103dd5c65b97691571450c278623204d987b85
MD5 12aa7b44b328c21f5241519ed9326521
BLAKE2b-256 65d34236e9442094b45d2ac07538fa367e6f46822f5e24fc9cb215c8c0e8e00b

See more details on using hashes here.

File details

Details for the file hiro-1.0.2-py3.7.egg.

File metadata

  • Download URL: hiro-1.0.2-py3.7.egg
  • Upload date:
  • Size: 20.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.7.13

File hashes

Hashes for hiro-1.0.2-py3.7.egg
Algorithm Hash digest
SHA256 6d99a0889407d656a43f0caacd5d9375716f91c721d9d564e1faacebff7a3eb6
MD5 19f1add1d7b94e20865f254754397c1f
BLAKE2b-256 12fa8a8bab6e60fabc1c291decc7bb8789c572d2a5cdb316d1f3466391199c5d

See more details on using hashes here.

File details

Details for the file hiro-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: hiro-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 11.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.7.13

File hashes

Hashes for hiro-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7367a83defe36df296f3e88aa2d5bd3315312ff090003056e566eea34b7ae754
MD5 d02d3156cd4b2c9640a10fc56479e980
BLAKE2b-256 efee8e5a1544b3e95b6a01aa3564f311a1b5c2e5dd4db36e1ae474ffd37e36bc

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page