Skip to content

Commit 19404ba

Browse files
author
=
committed
Update CI/CDs
1 parent 716556e commit 19404ba

File tree

3 files changed

+139
-2
lines changed

3 files changed

+139
-2
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,12 @@ async def main():
7979
loop = asyncio.get_running_loop()
8080

8181
with ThreadPoolExecutorPlus.ThreadPoolExecutor() as pool:
82-
result = await loop.run_in_executor(
82+
result1 = await loop.run_in_executor(
8383
pool, blocking_io)
84-
print('custom thread pool', result)
84+
result2 = await loop.run_in_executor(
85+
pool, cpu_bound)
86+
print('custom thread pool', result1)
87+
print('custom thread pool', result2)
8588

8689
asyncio.run(main())
8790
```

tests/test_compatibility.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import os , sys
2+
sys.path.append(os.getcwd())
3+
import pytest
4+
from ThreadPoolExecutorPlus import *
5+
import concurrent.futures
6+
import urllib.request
7+
import asyncio
8+
9+
10+
def test_threadpoolexecutor_example():
11+
URLS = [
12+
'http://www.foxnews.com/',
13+
'http://www.cnn.com/',
14+
'http://europe.wsj.com/',
15+
'http://www.bbc.co.uk/',
16+
'http://www.google.com/',
17+
'http://www.youtube.com/'
18+
]
19+
20+
def load_url(url, timeout):
21+
with urllib.request.urlopen(url, timeout=timeout) as conn:
22+
return conn.read()
23+
24+
with ThreadPoolExecutor(max_workers=6) as executor:
25+
future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}
26+
succeed_count = 0
27+
for future in concurrent.futures.as_completed(future_to_url):
28+
url = future_to_url[future]
29+
try:
30+
data = future.result()
31+
except Exception as exc:
32+
pass
33+
else:
34+
assert len(data) > 0
35+
succeed_count += 1
36+
assert succeed_count > 0
37+
38+
@pytest.mark.asyncio
39+
async def test_executing_code_in_thread_or_process_pools():
40+
41+
def blocking_io():
42+
with open('/dev/urandom', 'rb') as f:
43+
return f.read(100)
44+
45+
def cpu_bound():
46+
return sum(i * i for i in range(2 * 10 ** 6))
47+
48+
loop = asyncio.get_running_loop() if 'get_running_loop' in dir(asyncio) else asyncio.get_event_loop()
49+
50+
with ThreadPoolExecutor() as pool:
51+
result1 = await loop.run_in_executor(pool, blocking_io)
52+
result2 = await loop.run_in_executor(pool, cpu_bound)
53+
assert len(result1) == 100
54+
assert result2 == 2666664666667000000

tests/test_feature.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import os , sys
2+
sys.path.append(os.getcwd())
3+
import pytest
4+
from ThreadPoolExecutorPlus import *
5+
import time
6+
7+
def test_feature():
8+
9+
def some_func(arg):
10+
# does some heavy lifting
11+
# outputs some results
12+
time.sleep(arg)
13+
return arg
14+
15+
def some_error():
16+
raise RuntimeError()
17+
18+
with ThreadPoolExecutor() as executor:
19+
assert executor._max_workers >= executor._min_workers
20+
21+
# test reuseability
22+
results = []
23+
_range = 10
24+
_sec = 0.5
25+
for _ in range(_range):
26+
results.append(executor.submit(some_func , _sec / 2))
27+
time.sleep(_sec)
28+
assert len(executor._threads) == min(_ + 1 , executor._min_workers)
29+
30+
# test return
31+
results = list(map(lambda x:x.result() , results))
32+
assert results == [_sec / 2] * _range
33+
34+
# test raise
35+
result = executor.submit(some_error)
36+
time.sleep(_sec)
37+
assert result.done()
38+
assert isinstance(result.exception() , RuntimeError)
39+
40+
# test opt
41+
_range2 = 2
42+
_range3 = 10
43+
_time2 = 5
44+
_sleeptime = 2
45+
_interval = 0.01
46+
_inaccuracy = 0.5
47+
executor.set_daemon_opts(min_workers = _range2 , max_workers = _range3 , keep_alive_time = _time2)
48+
assert executor._min_workers == _range2
49+
assert executor._max_workers == _range3
50+
assert executor._keep_alive_time == _time2
51+
52+
# test execute
53+
results = []
54+
start_time = time.time()
55+
for _ in range(_range3):
56+
results.append(executor.submit(some_func , _sleeptime))
57+
time.sleep(_interval)
58+
59+
list(map(lambda x:x.result() , results))
60+
end_time = time.time()
61+
assert (_sleeptime - _inaccuracy) <= (end_time - start_time) <= (_sleeptime + _inaccuracy + _interval * _range3)
62+
63+
# test shrink
64+
assert len(executor._threads) == _range3
65+
time.sleep(_time2 + _inaccuracy * 2)
66+
assert len(executor._threads) == _range2 or len(executor._threads) == (_range2 + 1)
67+
68+
# test overflow
69+
_range4 = _range2 * 2
70+
_time3 = 0.5
71+
executor.set_daemon_opts(min_workers = _range2 , max_workers = _range2)
72+
results = []
73+
start_time = time.time()
74+
for _ in range(_range4):
75+
results.append(executor.submit(some_func , _time3))
76+
77+
list(map(lambda x:x.result() , results))
78+
end_time = time.time()
79+
expect_time = (_time3 * _range4) / _range2
80+
assert (expect_time - _inaccuracy) <= (end_time - start_time) <= (expect_time + _inaccuracy)

0 commit comments

Comments
 (0)