Skip to content

Commit

Permalink
deeper reinit
Browse files Browse the repository at this point in the history
  • Loading branch information
PietroPasotti committed Sep 23, 2022
1 parent 4132e05 commit a4e688d
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 5 deletions.
16 changes: 16 additions & 0 deletions ops/framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,22 @@ def __init__(self, storage: Union[SQLiteStorage, JujuStorage], charm_dir: 'Path'
self._juju_debug_at = (set(x.strip() for x in debug_at.split(','))
if debug_at else set()) # type: Set[str]

def _clear_all_state(self):
"""Clear the state.
Allows testing environments to clean the framework up and instantiate the
same Object (Handle, specifically) multiple times.
"""
if self.model._backend._hook_is_running: # type: ignore # noqa
raise RuntimeError('You should not do this while a hook is running. '
'This method is for testing only.')

self._objects.clear()
self._observers.clear()
self._observer.clear()
self._type_registry.clear()
self._type_known.clear()

def set_breakpointhook(self):
"""Hook into sys.breakpointhook so the builtin breakpoint() works as expected.
Expand Down
2 changes: 1 addition & 1 deletion ops/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def emit_event(self, evt: BoundEvent, *args: Any, **kwargs: Any):
evt.emit(*args, **kwargs)

def _reinitialize_charm(self):
self._framework._forget(self.charm)
self._framework._clear_all_state() # type:ignore # noqa
self._charm = None
self.begin()

Expand Down
13 changes: 9 additions & 4 deletions test/test_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@

is_linux = platform.system() == 'Linux'

# fixme: setting this to true breaks plenty of our own tests
# because of all the event recording hackiness we do.
# see esp. StorageTester.observed_events and RecordingCharm.changes
testing.REINITIALIZE_CHARM_ON_EVENT = False


class SetLeaderErrorTester(CharmBase):
"""Sets peer relation data inside leader-elected."""
Expand Down Expand Up @@ -4325,7 +4330,7 @@ def test_reinitialize(self):

# mapping from ID to instances
initial_charm_instance = self.harness.charm
charm_ids = {id(initial_charm_instance)}
charm_instances = [initial_charm_instance]

# we test with all events that are easy to mock, i.e. no args/kwargs.
bound_events = (
Expand All @@ -4341,9 +4346,9 @@ def test_reinitialize(self):
for i, evt in enumerate(bound_events):
with self.subTest(name=str(evt)):
self.harness.emit_event(evt)
new_charm_id = id(self.harness.charm)
self.assertNotIn(new_charm_id, charm_ids)
charm_ids.add(new_charm_id)
new_charm_instance = self.harness.charm
self.assertNotIn(new_charm_instance, charm_instances)
charm_instances.append(new_charm_instance)

def test_not_reinitialize(self):
testing.REINITIALIZE_CHARM_ON_EVENT = False
Expand Down

0 comments on commit a4e688d

Please sign in to comment.