Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
code_block_timer
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
code_block_timer
Commits
dca04ff6
Commit
dca04ff6
authored
Feb 15, 2015
by
John Eskew
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6 from doctoryes/doctoryes/combine_decorator_and_context_mgr
Merge context manager and decorator to single class.
parents
3882cc77
c20b6f70
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
57 additions
and
29 deletions
+57
-29
README.md
+33
-6
code_block_timer/__init__.py
+5
-11
code_block_timer/tests/test_timer.py
+17
-11
requirements.txt
+2
-1
No files found.
README.md
View file @
dca04ff6
...
@@ -4,9 +4,11 @@ Features
...
@@ -4,9 +4,11 @@ Features
--------
--------
*
Nesting of timers - higher level timers continue to tick during lower-level timers starting/stopping.
*
Nesting of timers - higher level timers continue to tick during lower-level timers starting/stopping.
*
Timing storage in a SQLite DB.
*
Timing storage in a SQLite DB.
*
Can be used as a decorator -or- a context manager.
Usage
Usage
-----
-----
As a context manager:
```
python
```
python
from
code_block_timer
import
CodeBlockTimer
from
code_block_timer
import
CodeBlockTimer
...
@@ -23,11 +25,36 @@ for __ in xrange(2):
...
@@ -23,11 +25,36 @@ for __ in xrange(2):
```
```
In the SQLite DB, you'll now see six rows, similar to these:
In the SQLite DB, you'll now see six rows, similar to these:
```
```
1|1|all blocks:block1|
201.16|2014-10-12 12:26:01
1|1|all blocks:block1|
4003.94415855408|2015-02-15 18:30:32
2|1|all blocks:block2|5
16.492|2014-10-12 12:26:01
2|1|all blocks:block2|5
003.18717956543|2015-02-15 18:30:37
3|1|all blocks|
916.54|2014-10-12 12:26:01
3|1|all blocks|
11016.9990062714|2015-02-15 18:30:37
4|2|all blocks:block1|
199.16|2014-10-12 12:26:04
4|2|all blocks:block1|
4003.73291969299|2015-02-15 18:30:43
5|2|all blocks:block2|50
5.142|2014-10-12 12:26:04
5|2|all blocks:block2|50
03.61299514771|2015-02-15 18:30:48
6|2|all blocks|
903.212|2014-10-12 12:26:04
6|2|all blocks|
11017.0860290527|2015-02-15 18:30:48
```
```
---
As a decorator:
```
python
from
code_block_timer
import
CodeBlockTimer
@CodeBlockTimer
(
'method2'
)
def
perform_another_lengthy_task
():
# Do several things.
pass
@CodeBlockTimer
(
'method1'
)
def
perform_lengthy_task
():
# Do several things.
perform_another_lengthy_task
()
for
__
in
xrange
(
2
):
perform_lengthy_task
()
```
In the SQLite DB, you'll now see four rows, similar to these:
```
1|1|method1:method2|2000.66590309143|2015-02-15 18:38:40
2|1|method1|3005.31411170959|2015-02-15 18:38:40
3|2|method1:method2|2001.1157989502|2015-02-15 18:38:43
4|2|method1|3003.61204147339|2015-02-15 18:38:43
```
code_block_timer/__init__.py
View file @
dca04ff6
...
@@ -12,11 +12,9 @@
...
@@ -12,11 +12,9 @@
# See the License for the specific language governing permissions and
# See the License for the specific language governing permissions and
# limitations under the License.
# limitations under the License.
import
functools
import
threading
import
threading
from
timeit
import
default_timer
from
timeit
import
default_timer
from
code_block_timer.storage
import
TimingDataStorage
import
storage
class
Globals
(
threading
.
local
):
class
Globals
(
threading
.
local
):
...
@@ -69,12 +67,8 @@ class CodeBlockTimer(object):
...
@@ -69,12 +67,8 @@ class CodeBlockTimer(object):
self
.
block_desc
,
self
.
elapsed
self
.
block_desc
,
self
.
elapsed
)
)
def
__call__
(
self
,
func
):
def
code_block_timer
(
block_desc
,
**
cbt_kwargs
):
def
wrapper
(
*
args
,
**
kwargs
):
def
outer
(
func
):
with
self
:
@functools.wraps
(
func
)
def
inner
(
*
args
,
**
kwargs
):
with
CodeBlockTimer
(
block_desc
,
**
cbt_kwargs
):
return
func
(
*
args
,
**
kwargs
)
return
func
(
*
args
,
**
kwargs
)
return
inner
return
wrapper
return
outer
code_block_timer/tests/test_timer.py
View file @
dca04ff6
import
mock
import
os
import
os
import
unittest
import
unittest
import
random
import
random
import
math
import
math
import
sqlite3
import
sqlite3
from
code_block_timer
import
CodeBlockTimer
,
code_block_timer
,
_m
import
mock
import
ddt
import
ddt
from
code_block_timer
import
CodeBlockTimer
,
_m
@ddt.ddt
@ddt.ddt
...
@@ -37,14 +37,17 @@ class TestCodeBlockTimer(unittest.TestCase):
...
@@ -37,14 +37,17 @@ class TestCodeBlockTimer(unittest.TestCase):
z
=
math
.
factorial
(
10
)
z
=
math
.
factorial
(
10
)
self
.
_verifyEvents
(
run_id
,
[
'test'
,
]
+
[
"test:{}"
.
format
(
x
)
for
x
in
iterations
])
self
.
_verifyEvents
(
run_id
,
[
'test'
,
]
+
[
"test:{}"
.
format
(
x
)
for
x
in
iterations
])
@mock.patch
(
'code_block_timer.
storage.
TimingDataStorage'
)
@mock.patch
(
'code_block_timer.TimingDataStorage'
)
def
test_decorator
(
self
,
mock_class
):
def
test_decorator
(
self
,
mock_class
):
"""
Test the decorator for timing - but mock out the storage.
"""
timing_storage
=
mock
.
Mock
()
timing_storage
.
run_id
.
return_value
=
45
mock_class
.
return_value
=
timing_storage
store
=
mock
.
Mock
()
#@code_block_timer('decorator_test', db_name=self.db_name)
mock_class
.
return_value
=
store
@CodeBlockTimer
(
'decorator_test'
,
db_name
=
self
.
db_name
)
store
.
run_id
.
return_value
=
45
@code_block_timer
(
'decorator_test'
,
db_name
=
self
.
db_name
)
def
wrapped_thing
(
*
args
,
**
kwargs
):
def
wrapped_thing
(
*
args
,
**
kwargs
):
self
.
assertEquals
(
args
,
(
'an_arg'
,))
self
.
assertEquals
(
args
,
(
'an_arg'
,))
self
.
assertEquals
(
kwargs
,
{
'a_dict'
:
{}})
self
.
assertEquals
(
kwargs
,
{
'a_dict'
:
{}})
...
@@ -52,9 +55,12 @@ class TestCodeBlockTimer(unittest.TestCase):
...
@@ -52,9 +55,12 @@ class TestCodeBlockTimer(unittest.TestCase):
test_dict
=
{}
test_dict
=
{}
run_id
=
wrapped_thing
(
'an_arg'
,
a_dict
=
test_dict
)
run_id
=
wrapped_thing
(
'an_arg'
,
a_dict
=
test_dict
)
# Was the TimingStorage class itself constructed?
mock_class
.
assert_called_once_with
(
db_name
=
self
.
db_name
)
mock_class
.
assert_called_once_with
(
db_name
=
self
.
db_name
)
# Was wrapped_thing() called -and- did it complete?
self
.
assertTrue
(
test_dict
[
'entered'
])
self
.
assertTrue
(
test_dict
[
'entered'
])
store
.
store
.
assert_called_with
(
45
,
'decorator_test'
,
mock
.
ANY
)
# Did the TimingStorage.store() method get called with the proper params?
timing_storage
.
store
.
assert_called_with
(
45
,
'decorator_test'
,
mock
.
ANY
)
def
test_exception_handled
(
self
):
def
test_exception_handled
(
self
):
msg
=
"exception_but_still_timed"
msg
=
"exception_but_still_timed"
...
@@ -74,8 +80,8 @@ class TestCodeBlockTimer(unittest.TestCase):
...
@@ -74,8 +80,8 @@ class TestCodeBlockTimer(unittest.TestCase):
z
=
math
.
factorial
(
10
)
z
=
math
.
factorial
(
10
)
self
.
_verifyEvents
(
run_id
,
[
'test'
,
'test:delimiter'
])
self
.
_verifyEvents
(
run_id
,
[
'test'
,
'test:delimiter'
])
@ddt.data
(
':::::'
,
'
%
'
,
'-'
,
'/'
)
@ddt.data
(
':::::'
,
'
%
'
,
'-'
,
'/'
,
''
)
def
test_delimiters
(
self
,
delimiter
):
def
test_
arbitrary_
delimiters
(
self
,
delimiter
):
with
CodeBlockTimer
(
"test"
,
delimiter
=
delimiter
,
db_name
=
self
.
db_name
)
as
timer
:
with
CodeBlockTimer
(
"test"
,
delimiter
=
delimiter
,
db_name
=
self
.
db_name
)
as
timer
:
run_id
=
_m
.
run_id
run_id
=
_m
.
run_id
with
CodeBlockTimer
(
"delimiter"
,
delimiter
=
delimiter
,
db_name
=
self
.
db_name
)
as
inner
:
with
CodeBlockTimer
(
"delimiter"
,
delimiter
=
delimiter
,
db_name
=
self
.
db_name
)
as
inner
:
...
...
requirements.txt
View file @
dca04ff6
# Packages needed for testing only.
ddt
==1.0.0
ddt
==1.0.0
path.py
==7.2
mock
==1.0.1
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment