Public Access
fix return-value/deprecated API bugs, accumulation lock leaks, code cleanup
- raise instead of silent None for unsupported operands and empty negation - validate before acquiring lock in Accumulation operators (no RLock leak) - Accumulation._copy_provenance helper, ADC_Result._copy_metadata for all result paths - shared _sandbox_stdout_redirect contextmanager for sandboxed scripts - TemperatureMonitor dead code removal (gtk helper, traceback, unused properties) - new unit tests incl. lock-freedom regression test - gitignore sphinx generated doc/_autosummary/ and doc/damaris/
This commit is contained in:
1 parent
91ade4376c
commit
f9d8de7697
26 files changed
+590
-236
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import subprocess
|
||||
import threading
|
||||
import unittest
|
||||
from datetime import datetime
|
||||
|
||||
@@ -258,7 +259,7 @@ class TestAccumulation(unittest.TestCase):
|
||||
np.testing.assert_array_equal(accu.y[i], y[i] - 10)
|
||||
|
||||
# test float subtraction
|
||||
adc -= 10.
|
||||
accu -= 10.
|
||||
for i in range(adc.get_nChannels()):
|
||||
np.testing.assert_array_equal(accu.y[i], y[i] - 10 - 10.)
|
||||
|
||||
@@ -312,5 +313,74 @@ class TestAccumulation(unittest.TestCase):
|
||||
self.assertRaises(ValueError, accu.__floordiv__, 1.0)
|
||||
self.assertRaises(ValueError, accu.__ifloordiv__, 1.0)
|
||||
|
||||
def test_add_invalid_operand_raises(self):
|
||||
"""accu + bogus must raise ValueError instead of returning None."""
|
||||
adc = self.create_adc_result()
|
||||
accu = Accumulation()
|
||||
accu += adc
|
||||
self.assertRaises(ValueError, accu.__add__, "foo")
|
||||
self.assertRaises(ValueError, accu.__iadd__, "foo")
|
||||
|
||||
def test_neg_empty_raises(self):
|
||||
"""-empty accumulation must raise ValueError."""
|
||||
self.assertRaises(ValueError, Accumulation().__neg__)
|
||||
|
||||
def test_add_adc_result_does_not_modify_job_ids(self):
|
||||
"""accu + adc must not insert the adc job id into accu.job_ids."""
|
||||
accu = Accumulation()
|
||||
accu += self.create_adc_result()
|
||||
n_before = len(accu.job_ids)
|
||||
adc2 = self.create_adc_result()
|
||||
adc2.job_id = 12
|
||||
r = accu + adc2
|
||||
self.assertIn(12, r.job_ids)
|
||||
self.assertNotIn(12, accu.job_ids)
|
||||
self.assertEqual(len(accu.job_ids), n_before)
|
||||
|
||||
def test_empty_plus_accumulation_copies_data(self):
|
||||
"""empty_accu + accu must copy arrays and metadata, not alias them."""
|
||||
adc = self.create_adc_result()
|
||||
accu = Accumulation()
|
||||
accu += adc
|
||||
accu.is_clipped = True
|
||||
|
||||
r = Accumulation() + accu
|
||||
self.assertIsNot(r.y[0], accu.y[0])
|
||||
self.assertIsNot(r.job_ids, accu.job_ids)
|
||||
self.assertTrue(r.is_clipped)
|
||||
# in-place operation on the result must leave the operand unchanged
|
||||
r *= 2
|
||||
np.testing.assert_array_equal(accu.y[0], np.array([10, 20, 30], dtype="float32"))
|
||||
|
||||
def test_accumulation_plus_accumulation_keeps_both_job_ids(self):
|
||||
"""accu1 + accu2 must keep the provenance of both operands."""
|
||||
adc1 = self.create_adc_result()
|
||||
adc2 = self.create_adc_result()
|
||||
adc2.job_id = 12
|
||||
accu1 = Accumulation()
|
||||
accu1 += adc1
|
||||
accu2 = Accumulation()
|
||||
accu2 += adc2
|
||||
r = accu1 + accu2
|
||||
self.assertEqual(set(r.job_ids.keys()), {11, 12})
|
||||
self.assertEqual(set(accu1.job_ids.keys()), {11})
|
||||
self.assertEqual(set(accu2.job_ids.keys()), {12})
|
||||
|
||||
def test_empty_error_plus_non_error_raises(self):
|
||||
"""error accumulation + non-error accumulation must raise ValueError."""
|
||||
accu = Accumulation()
|
||||
accu += self.create_adc_result()
|
||||
empty_err = Accumulation(error=True)
|
||||
self.assertRaises(ValueError, empty_err.__add__, accu)
|
||||
free = []
|
||||
def check_lock():
|
||||
if empty_err.lock.acquire(timeout=1):
|
||||
free.append(True)
|
||||
empty_err.lock.release()
|
||||
t = threading.Thread(target=check_lock)
|
||||
t.start()
|
||||
t.join(3)
|
||||
self.assertTrue(free, "lock leaked after ValueError in __add__")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user