-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #29 from mogproject/develop
Develop #17
- Loading branch information
Showing
5 changed files
with
128 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
from .caseclass import CaseClass | ||
from .asserttype import assert_type | ||
from .progressbar import ProgressBar | ||
from .unicodeutil import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import sys | ||
import threading | ||
from Queue import Queue | ||
|
||
|
||
class ProgressBar(object): | ||
""" | ||
Print progress bar in the separated thread | ||
""" | ||
|
||
def __init__(self, interval=1, fp=sys.stdout): | ||
""" | ||
Start thread for progress bar | ||
:param interval: interval seconds to write dots | ||
:param fp: file pointer to write | ||
""" | ||
self.interval = interval | ||
self.fp = fp | ||
self.ex_queue = Queue() # store all exceptions raised in thread | ||
|
||
# create event for handling termination | ||
self.__stop_event = threading.Event() | ||
|
||
# create and start new thread | ||
self.thread = threading.Thread(target=lambda: self.__capture_exceptions(self.__target)) | ||
self.thread.start() | ||
|
||
def stop(self): | ||
""" | ||
Terminate progress bar thread | ||
""" | ||
self.__stop_event.set() | ||
self.thread.join() | ||
|
||
# check thread's exceptions | ||
if not self.ex_queue.empty(): | ||
raise self.ex_queue.get_nowait() | ||
|
||
def __capture_exceptions(self, f): | ||
""" | ||
Wrapper function to capture all exceptions which are raised in the thread | ||
""" | ||
try: | ||
f() | ||
except Exception as e: | ||
self.ex_queue.put(e) | ||
raise e | ||
|
||
def __target(self): | ||
""" | ||
Inner method for writing dots in the separated thread | ||
""" | ||
event = self.__stop_event | ||
|
||
while not event.is_set(): | ||
self.fp.write('.') | ||
self.fp.flush() | ||
event.wait(self.interval) | ||
self.fp.write('\n') | ||
|
||
def __enter__(self): | ||
return self | ||
|
||
def __exit__(self, *args, **kwargs): | ||
self.stop() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import unittest | ||
from StringIO import StringIO | ||
import time | ||
from artifactcli.util.progressbar import ProgressBar | ||
|
||
|
||
class TestProgressBar(unittest.TestCase): | ||
def test_progress_bar(self): | ||
fp = StringIO() | ||
p = ProgressBar(0.6, fp) | ||
time.sleep(1) | ||
p.stop() | ||
s = fp.getvalue() | ||
fp.close() | ||
self.assertEqual(s, '..\n') | ||
|
||
def test_progress_bar_with(self): | ||
fp = StringIO() | ||
with ProgressBar(0.6, fp): | ||
time.sleep(1) | ||
s = fp.getvalue() | ||
fp.close() | ||
self.assertEqual(s, '..\n') | ||
|
||
def test_progress_bar_runtime_error(self): | ||
fp = StringIO() | ||
try: | ||
with ProgressBar(0.6, fp): | ||
time.sleep(1) | ||
raise RuntimeError | ||
except RuntimeError: | ||
pass | ||
|
||
time.sleep(0.5) | ||
s = fp.getvalue() | ||
fp.close() | ||
self.assertEqual(s, '..\n') | ||
|
||
def test_progress_bar_io_error(self): | ||
fp = StringIO() | ||
p = ProgressBar(0.6, fp) | ||
time.sleep(1) | ||
fp.close() | ||
time.sleep(1) | ||
|
||
self.assertRaises(ValueError, p.stop) |