1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
# (C) Copyright 2005-2023 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
import os
import shutil
import tempfile
import threading
import unittest
from traits.api import HasTraits, on_trait_change, Bool, Float, List
from traits import trait_notifiers
from traits.util.event_tracer import (
ChangeEventRecorder,
MultiThreadChangeEventRecorder,
MultiThreadRecordContainer,
RecordContainer,
record_events,
)
class ExampleObject(HasTraits):
number = Float(2.0)
list_of_numbers = List(Float())
flag = Bool
@on_trait_change("number")
def _add_number_to_list(self, value):
self.list_of_numbers.append(value)
def add_to_number(self, value):
self.number += value
class TestRecordEvents(unittest.TestCase):
def setUp(self):
self.directory = tempfile.mkdtemp()
def tearDown(self):
shutil.rmtree(self.directory)
def test_change_event_recorder(self):
test_object = ExampleObject()
container = RecordContainer()
recorder = ChangeEventRecorder(container=container)
trait_notifiers.set_change_event_tracers(
pre_tracer=recorder.pre_tracer, post_tracer=recorder.post_tracer
)
try:
test_object.number = 5.0
finally:
trait_notifiers.clear_change_event_tracers()
filename = os.path.join(self.directory, "MainThread.trace")
container.save_to_file(filename)
with open(filename, "r", encoding="utf-8") as handle:
lines = handle.readlines()
self.assertEqual(len(lines), 4)
# very basic checking
self.assertTrue(
"-> 'number' changed from 2.0 to 5.0 in 'ExampleObject'\n"
in lines[0]
)
self.assertTrue("CALLING" in lines[1])
self.assertTrue("EXIT" in lines[2])
def test_multi_thread_change_event_recorder(self):
test_object = ExampleObject()
container = MultiThreadRecordContainer()
recorder = MultiThreadChangeEventRecorder(container=container)
trait_notifiers.set_change_event_tracers(
pre_tracer=recorder.pre_tracer, post_tracer=recorder.post_tracer
)
try:
test_object.number = 5.0
thread = threading.Thread(
target=test_object.add_to_number, args=(5,)
)
thread.start()
thread.join()
finally:
trait_notifiers.clear_change_event_tracers()
self.assertEqual(len(container._record_containers), 2)
# save records
container.save_to_directory(self.directory)
for name in container._record_containers:
filename = os.path.join(self.directory, "{0}.trace".format(name))
with open(filename, "r", encoding="utf-8") as handle:
lines = handle.readlines()
self.assertEqual(len(lines), 4)
# very basic checking
if "MainThread.trace" in filename:
self.assertTrue(
"-> 'number' changed from 2.0 to 5.0 in 'ExampleObject'\n"
in lines[0]
)
else:
self.assertTrue(
"-> 'number' changed from 5.0 to 10.0 in 'ExampleObject'\n"
in lines[0]
)
self.assertTrue("CALLING" in lines[1])
self.assertTrue("EXIT" in lines[2])
def test_record_events(self):
test_object = ExampleObject()
with record_events() as container:
test_object.number = 5.0
thread = threading.Thread(
target=test_object.add_to_number, args=(3,)
)
thread.start()
thread.join()
# save records
container.save_to_directory(self.directory)
for name in container._record_containers:
filename = os.path.join(self.directory, "{0}.trace".format(name))
with open(filename, "r", encoding="utf-8") as handle:
lines = handle.readlines()
self.assertEqual(len(lines), 4)
# very basic checking
if "MainThread.trace" in filename:
self.assertTrue(
"-> 'number' changed from 2.0 to 5.0 in 'ExampleObject'\n"
in lines[0]
)
else:
self.assertTrue(
"-> 'number' changed from 5.0 to 8.0 in 'ExampleObject'\n"
in lines[0]
)
self.assertTrue("CALLING" in lines[1])
self.assertTrue("EXIT" in lines[2])
|