[h5py] 86/455: Add threading unit tests
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Thu Jul 2 18:19:20 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to annotated tag 1.3.0
in repository h5py.
commit bd5bdd12275ff395e18ee8c0b7c71946f57ce067
Author: andrewcollette <andrew.collette at gmail.com>
Date: Tue Jul 29 02:37:42 2008 +0000
Add threading unit tests
---
h5py/tests/test_threads.py | 244 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 244 insertions(+)
diff --git a/h5py/tests/test_threads.py b/h5py/tests/test_threads.py
new file mode 100644
index 0000000..9411482
--- /dev/null
+++ b/h5py/tests/test_threads.py
@@ -0,0 +1,244 @@
+#+
+#
+# This file is part of h5py, a low-level Python interface to the HDF5 library.
+#
+# Copyright (C) 2008 Andrew Collette
+# http://h5py.alfven.org
+# License: BSD (See LICENSE.txt for full license)
+#
+# $Date$
+#
+#-
+from __future__ import with_statement
+
+import unittest
+import threading
+import dummy_threading
+import tempfile
+from threading import Thread
+import os
+import numpy
+import time
+
+from h5py import *
+from h5py.h5 import H5Error
+from h5py.extras import h5sync
+import h5py
+
+LOCKTYPE = threading.RLock
+SHAPE = (10,10)
+BIGSHAPE = (5300,5000) # About 200MB worth of doubles
+
+class WriterThread(Thread):
+
+ def __init__(self, name, value, dset, reclist):
+ Thread.__init__(self)
+ self.arr = numpy.ones(SHAPE)*value # Value to be written
+ self.dset = dset # Dataset to write to
+ self.reclist = reclist # We'll append our name to this when done
+ self.name = name
+ self.next_thread = None # Thread we'll try to get to break the lock
+ self.sleeptime = 0 # How long do we give that thread to try
+
+ def run(self):
+ # Try to fill the dataset with our values
+
+ with self.dset.lock:
+ if self.next_thread is not None:
+ self.next_thread.start() # Try to make the next thread steal the dataset
+ time.sleep(self.sleeptime) # Make sure it has a chance to misbehave
+ self.dset[...] = self.arr
+ self.reclist.append(self.name) # Add our name to the record, before releasing the lock.
+
+class TimedWriter(Thread):
+
+ def __init__(self, dset, arr):
+ Thread.__init__(self)
+ self.dset = dset
+ self.arr = arr
+ self.timestart = 0
+ self.timestop = 0
+
+ def run(self):
+ self.timestart = time.time()
+ self.dset.id.write(h5s.ALL, h5s.ALL, self.arr)
+ self.timestop = time.time()
+
+class NullWriter(Thread):
+
+ def __init__(self):
+ Thread.__init__(self)
+ self.time = 0
+
+ def run(self):
+ self.time = time.time()
+
+class TestThreads(unittest.TestCase):
+
+ def setUp(self):
+
+ self.fname = tempfile.mktemp('.hdf5')
+ self.f = File(self.fname, 'w')
+ self.old_lock = h5py.config.RLock
+ h5py.config.RLock = LOCKTYPE
+
+ def tearDown(self):
+ self.f.close()
+ os.unlink(self.fname)
+ h5py.config.RLock = self.old_lock
+
+ def test_hl_pos(self):
+
+ reclist = []
+
+ dset = self.f.create_dataset('ds',(10,10), dtype='=f8')
+ thread_a = WriterThread('A', 1.0, dset, reclist)
+ thread_b = WriterThread('B', 2.0, dset, reclist)
+ thread_c = WriterThread('C', 3.0, dset, reclist)
+ thread_d = WriterThread('D', 4.0, dset, reclist)
+
+ thread_a.next_thread = thread_b
+ thread_b.next_thread = thread_c
+ thread_c.next_thread = thread_d
+
+ thread_a.sleeptime = 3 # Must be larger than b, so that b attempts to steal the lock.
+ thread_b.sleeptime = 2 # Must be larger than c, for the same reason
+ thread_c.sleeptime = 1
+
+ thread_a.start()
+
+ # Ensure they all finish
+ # TODO: Handle a possible deadlock more gracefully.
+ thread_a.join()
+ thread_b.join()
+ thread_c.join()
+ thread_d.join()
+
+ self.assertEqual(reclist, ['A','B','C','D'])
+ self.assert_(numpy.all(dset.value == numpy.ones(SHAPE)*4.0))
+
+ def test_hl_neg(self):
+
+ oldlock = h5py.config.RLock
+ try:
+ # Force the threads to operate in reverse order, by defeating locks
+ h5py.config.RLock = dummy_threading.RLock
+
+ reclist = []
+
+ dset = self.f.create_dataset('ds',(10,10), dtype='=f8')
+ thread_a = WriterThread('A', 1.0, dset, reclist)
+ thread_b = WriterThread('B', 2.0, dset, reclist)
+ thread_c = WriterThread('C', 3.0, dset, reclist)
+ thread_d = WriterThread('D', 4.0, dset, reclist)
+
+ thread_a.next_thread = thread_b
+ thread_b.next_thread = thread_c
+ thread_c.next_thread = thread_d
+
+ thread_a.sleeptime = 3 # Must be larger than b, so that b attempts to steal the lock.
+ thread_b.sleeptime = 2 # Must be larger than c, for the same reason
+ thread_c.sleeptime = 1
+
+ thread_a.start()
+
+ # Ensure they all finish
+ # TODO: Handle a possible deadlock more gracefully.
+ thread_a.join()
+ thread_b.join()
+ thread_c.join()
+ thread_d.join()
+
+ self.assertEqual(reclist, ['D','C','B','A'])
+ self.assert_(numpy.all(dset.value == numpy.ones(SHAPE)*1.0))
+ finally:
+ h5py.config.RLock = oldlock
+
+ def test_nonblock(self):
+ # Ensure low-level I/O blocking behavior
+
+ dset = self.f.create_dataset('ds', BIGSHAPE, '=f8')
+ arr = numpy.ones(BIGSHAPE, '=f8')
+ DELAY = 0.1
+
+ thread_a = TimedWriter(dset, arr)
+ thread_b = NullWriter()
+
+ thread_a.start()
+ time.sleep(DELAY)
+ thread_b.start()
+
+ thread_a.join()
+ thread_b.join()
+
+ write_time = thread_a.timestop - thread_a.timestart
+ if write_time < DELAY:
+ raise Exception("Write was too fast to test blocking (%f sec; need %f)" % (write_time, DELAY))
+
+ if h5py.config.compile_opts['IO_NONBLOCK']:
+ self.assert_(thread_b.time < thread_a.timestop)
+ else:
+ self.assert_(thread_b.time > thread_a.timestop)
+
+ def test_lock_behavior(self):
+ # Check to make sure the user-provided lock class behaves correctly
+ # when called from C code
+
+ dset = self.f.create_dataset('ds', SHAPE, '=f8')
+ arr = numpy.ones(SHAPE, '=f8')
+
+ writethread = TimedWriter(dset, arr)
+
+ with h5py.config.lock:
+ writethread.start()
+ time.sleep(2) # give it more than enough time to finish, if it ignores the lock
+ exit_lock_time = time.time()
+ time.sleep(0.1)
+ writethread.join()
+
+ if h5py.config.compile_opts['IO_NONBLOCK']:
+ self.assert_(writethread.timestop > exit_lock_time)
+ else:
+ self.assert_(writethread.timestop < exit_lock_time)
+
+
+ def test_decorator(self):
+
+ time1 = 0
+ time2 = 0
+
+ class SleeperThread(Thread):
+
+ def __init__(self, sleeptime):
+ Thread.__init__(self)
+ self.sleeptime = sleeptime
+ self.time = 0
+
+ @h5sync
+ def run(self):
+ time.sleep(self.sleeptime)
+ self.time = time.time()
+
+ thread_a = SleeperThread(2)
+ thread_b = SleeperThread(1)
+
+ thread_a.start()
+ thread_b.start()
+
+ thread_a.join()
+ thread_b.join()
+
+ self.assert_(thread_a.time < thread_b.time)
+
+ @h5sync
+ def thisismyname(foo):
+ pass
+
+ self.assertEqual(thisismyname.__name__, "thisismyname")
+
+
+
+
+
+
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/h5py.git
More information about the debian-science-commits
mailing list