From a3b577e239aa8d7d1ec2da3429945005b6a25e20 Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Thu, 11 Feb 2021 15:31:37 +0900 Subject: [PATCH] Add one actual and three skipped thread tests to the test suite --- test/testNoiseList.krk | 48 ++++++++++++++++++++++++++++++ test/testNoiseList.krk.expect | 0 test/testNoiseTupleKeys.krk | 46 ++++++++++++++++++++++++++++ test/testNoiseTupleKeys.krk.expect | 0 test/testSimpleThreads.krk | 26 ++++++++++++++++ test/testSimpleThreads.krk.expect | 1 + test/testUnlockedInt.krk | 48 ++++++++++++++++++++++++++++++ test/testUnlockedInt.krk.expect | 0 8 files changed, 169 insertions(+) create mode 100644 test/testNoiseList.krk create mode 100644 test/testNoiseList.krk.expect create mode 100644 test/testNoiseTupleKeys.krk create mode 100644 test/testNoiseTupleKeys.krk.expect create mode 100644 test/testSimpleThreads.krk create mode 100644 test/testSimpleThreads.krk.expect create mode 100644 test/testUnlockedInt.krk create mode 100644 test/testUnlockedInt.krk.expect diff --git a/test/testNoiseList.krk b/test/testNoiseList.krk new file mode 100644 index 0000000..3d1894c --- /dev/null +++ b/test/testNoiseList.krk @@ -0,0 +1,48 @@ +import os +if 'KUROKO_TEST_ENV' in os.environ: + return 0 + +from time import sleep +from fileio import open, stdin +from threading import Thread + +let d = [] +let stop = False + +for y in range(0x40): + let l = [] + for x in range(0x40): + l.append(0) + d.append(l) + +class NoisePainter(Thread): + def run(self): + let myRando = open('/dev/urandom','rb') + while not stop: + let bytes = myRando.read(3) + let x = bytes[0] & 0x3F + let y = bytes[1] & 0x3F + d[y][x] = bytes[2] + +let painters = [NoisePainter() for i in range(5)] + +for painter in painters: + painter.start() + +def drawScreen(): + print("\[[H",end="") + for y in range(0x20): + for x in range(0x40): + let top = d[y*2][x] + let bottom = d[y*2+1][x] + print("\[[38","2",top,top,top,"48","2",bottom,bottom,bottom,sep=";",end="m▀") + print("\[[0m") + +for i in range(5): + drawScreen() + +stop = True +for painter in painters: + painter.join() + +drawScreen() diff --git a/test/testNoiseList.krk.expect b/test/testNoiseList.krk.expect new file mode 100644 index 0000000..e69de29 diff --git a/test/testNoiseTupleKeys.krk b/test/testNoiseTupleKeys.krk new file mode 100644 index 0000000..9162b65 --- /dev/null +++ b/test/testNoiseTupleKeys.krk @@ -0,0 +1,46 @@ +import os +if 'KUROKO_TEST_ENV' in os.environ: + return 0 + +from time import sleep +from fileio import open, stdin +from threading import Thread + +let d = {} +let stop = False + +for y in range(0x40): + for x in range(0x40): + d[(y,x)] = 0 + +class NoisePainter(Thread): + def run(self): + let myRando = open('/dev/urandom','rb') + while not stop: + let bytes = myRando.read(3) + let x = bytes[0] & 0x3F + let y = bytes[1] & 0x3F + d[(y,x)] = bytes[2] + +let painters = [NoisePainter() for i in range(5)] + +for painter in painters: + painter.start() + +def drawScreen(): + print("\[[H",end="") + for y in range(0x20): + for x in range(0x40): + let top = d[(y*2,x)] + let bottom = d[(y*2+1,x)] + print("\[[38","2",top,top,top,"48","2",bottom,bottom,bottom,sep=";",end="m▀") + print("\[[0m") + +for i in range(5): + drawScreen() + +stop = True +for painter in painters: + painter.join() + +drawScreen() diff --git a/test/testNoiseTupleKeys.krk.expect b/test/testNoiseTupleKeys.krk.expect new file mode 100644 index 0000000..e69de29 diff --git a/test/testSimpleThreads.krk b/test/testSimpleThreads.krk new file mode 100644 index 0000000..ec01c7c --- /dev/null +++ b/test/testSimpleThreads.krk @@ -0,0 +1,26 @@ +# Stripped down version of a more flexible example +from threading import Thread, Lock + +def __main__(): + + let threadcount = 10 + let i = 0 + let lock = Lock() + + class Incrementer(Thread): + def run(): + for c in range(1000): + with lock: + i += 1 + + let threads = [Incrementer() for j in range(threadcount)] + for thread in threads: thread.start() + for thread in threads: thread.join() + + print(i) + + return 0 + +if __name__ == '__main__': + return __main__() + diff --git a/test/testSimpleThreads.krk.expect b/test/testSimpleThreads.krk.expect new file mode 100644 index 0000000..5caff40 --- /dev/null +++ b/test/testSimpleThreads.krk.expect @@ -0,0 +1 @@ +10000 diff --git a/test/testUnlockedInt.krk b/test/testUnlockedInt.krk new file mode 100644 index 0000000..6fc2ee1 --- /dev/null +++ b/test/testUnlockedInt.krk @@ -0,0 +1,48 @@ +''' +Demonstrates the classic threading problem of multiple threads +non-atomically modifying a value concurrently by get/add/set. + +Can take two arguments: + + --locked Wrap access in a lock. + --threads N Create N threads. + +''' +import os +if 'KUROKO_TEST_ENV' in os.environ: + return 0 + +import kuroko +from threading import Thread, Lock + +def __main__(): + + # Simple flag argument processing. + let locked = '--locked' in kuroko.argv + let threadcount = 10 if '--threads' not in kuroko.argv else (int(kuroko.argv[kuroko.argv.index('--threads')+1])) + + # This also demonstrates threads accessing an upvalue + # which has not yet been closed in another thread. + let i = 0 + let lock = Lock() + + class Incrementer(Thread): + def run(): + for c in range(1000): + if locked: + with lock: + i += 1 + else: + i += 1 + + let threads = [Incrementer() for j in range(threadcount)] + for thread in threads: thread.start() + for thread in threads: thread.join() + + # Should be 1000 * threadcount - but is it? Almost definitely not without a lock! + print(i) + + return 0 + +if __name__ == '__main__': + return __main__() diff --git a/test/testUnlockedInt.krk.expect b/test/testUnlockedInt.krk.expect new file mode 100644 index 0000000..e69de29