Skip to content

Commit ed36632

Browse files
committed
tests: Add tests for _thread module.
Includes functionality and stress tests.
1 parent f2892bd commit ed36632

13 files changed

+548
-0
lines changed

tests/thread/thread_exc1.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# test raising and catching an exception within a thread
2+
#
3+
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
4+
5+
try:
6+
import utime as time
7+
except ImportError:
8+
import time
9+
import _thread
10+
11+
def foo():
12+
raise ValueError
13+
14+
def thread_entry():
15+
try:
16+
foo()
17+
except ValueError:
18+
pass
19+
20+
for i in range(4):
21+
_thread.start_new_thread(thread_entry, ())
22+
23+
time.sleep(0.2)
24+
print('done')

tests/thread/thread_exit1.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# test _thread.exit() function
2+
#
3+
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
4+
5+
try:
6+
import utime as time
7+
except ImportError:
8+
import time
9+
import _thread
10+
11+
def thread_entry():
12+
_thread.exit()
13+
14+
_thread.start_new_thread(thread_entry, ())
15+
_thread.start_new_thread(thread_entry, ())
16+
17+
# wait for threads to finish
18+
time.sleep(0.2)
19+
print('done')

tests/thread/thread_exit2.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# test raising SystemExit to finish a thread
2+
#
3+
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
4+
5+
try:
6+
import utime as time
7+
except ImportError:
8+
import time
9+
import _thread
10+
11+
def thread_entry():
12+
raise SystemExit
13+
14+
_thread.start_new_thread(thread_entry, ())
15+
_thread.start_new_thread(thread_entry, ())
16+
17+
# wait for threads to finish
18+
time.sleep(0.2)
19+
print('done')

tests/thread/thread_ident1.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# test _thread.get_ident() function
2+
#
3+
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
4+
5+
try:
6+
import utime as time
7+
except ImportError:
8+
import time
9+
import _thread
10+
11+
def thread_entry():
12+
tid = _thread.get_ident()
13+
print('thread', type(tid) == int, tid != 0, tid != tid_main)
14+
15+
tid_main = _thread.get_ident()
16+
print('main', type(tid_main) == int, tid_main != 0)
17+
18+
_thread.start_new_thread(thread_entry, ())
19+
20+
time.sleep(0.2)
21+
print('done')

tests/thread/thread_lock1.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# test _thread lock object using a single thread
2+
#
3+
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
4+
5+
import _thread
6+
7+
# create lock
8+
lock = _thread.allocate_lock()
9+
10+
print(type(lock) == _thread.LockType)
11+
12+
# should be unlocked
13+
print(lock.locked())
14+
15+
# basic acquire and release
16+
print(lock.acquire())
17+
print(lock.locked())
18+
lock.release()
19+
print(lock.locked())
20+
21+
# try acquire twice (second should fail)
22+
print(lock.acquire())
23+
print(lock.locked())
24+
print(lock.acquire(0))
25+
print(lock.locked())
26+
lock.release()
27+
print(lock.locked())
28+
29+
# test with capabilities of lock
30+
with lock:
31+
print(lock.locked())
32+
33+
# test that lock is unlocked if an error is rasied
34+
try:
35+
with lock:
36+
print(lock.locked())
37+
raise KeyError
38+
except KeyError:
39+
print('KeyError')
40+
print(lock.locked())

tests/thread/thread_lock2.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# test _thread lock objects with multiple threads
2+
#
3+
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
4+
5+
try:
6+
import utime as time
7+
except ImportError:
8+
import time
9+
import _thread
10+
11+
lock = _thread.allocate_lock()
12+
13+
def thread_entry():
14+
lock.acquire()
15+
print('have it')
16+
lock.release()
17+
18+
# spawn the threads
19+
for i in range(4):
20+
_thread.start_new_thread(thread_entry, ())
21+
22+
# wait for threads to finish
23+
time.sleep(0.2)
24+
print('done')

tests/thread/thread_lock3.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# test thread coordination using a lock object
2+
#
3+
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
4+
5+
import _thread
6+
7+
lock = _thread.allocate_lock()
8+
n_thread = 10
9+
n_finished = 0
10+
11+
def thread_entry(idx):
12+
global n_finished
13+
while True:
14+
with lock:
15+
if n_finished == idx:
16+
break
17+
print('my turn:', idx)
18+
with lock:
19+
n_finished += 1
20+
21+
# spawn threads
22+
for i in range(n_thread):
23+
_thread.start_new_thread(thread_entry, (i,))
24+
25+
# busy wait for threads to finish
26+
while n_finished < n_thread:
27+
pass

tests/thread/thread_shared1.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# test capability for threads to access a shared immutable data structure
2+
#
3+
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
4+
5+
try:
6+
import utime as time
7+
except ImportError:
8+
import time
9+
import _thread
10+
11+
def foo(i):
12+
pass
13+
14+
def thread_entry(n, tup):
15+
for i in tup:
16+
foo(i)
17+
18+
tup = (1, 2, 3, 4)
19+
_thread.start_new_thread(thread_entry, (100, tup))
20+
_thread.start_new_thread(thread_entry, (100, tup))
21+
22+
# wait for threads to finish
23+
time.sleep(0.2)
24+
print(tup)

tests/thread/thread_shared2.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# test capability for threads to access a shared mutable data structure
2+
# (without contention because they access different parts of the structure)
3+
#
4+
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
5+
6+
try:
7+
import utime as time
8+
except ImportError:
9+
import time
10+
import _thread
11+
12+
def foo(lst, i):
13+
lst[i] += 1
14+
15+
def thread_entry(n, lst, idx):
16+
for i in range(n):
17+
foo(lst, idx)
18+
19+
lst = [0, 0]
20+
_thread.start_new_thread(thread_entry, (10, lst, 0))
21+
_thread.start_new_thread(thread_entry, (20, lst, 1))
22+
23+
# wait for threads to finish
24+
time.sleep(0.2)
25+
print(lst)

tests/thread/thread_sleep1.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# test threads sleeping
2+
#
3+
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
4+
5+
try:
6+
import utime as time
7+
except ImportError:
8+
import time
9+
import _thread
10+
11+
lock = _thread.allocate_lock()
12+
n_thread = 16
13+
n_finished = 0
14+
15+
def thread_entry(t):
16+
global n_finished
17+
time.sleep(t)
18+
time.sleep(2 * t)
19+
with lock:
20+
n_finished += 1
21+
22+
for i in range(n_thread):
23+
_thread.start_new_thread(thread_entry, (i / 100,))
24+
25+
# wait for threads to finish
26+
while n_finished < n_thread:
27+
time.sleep(0.1)
28+
print('done', n_thread)

0 commit comments

Comments
 (0)