`harness.get_relation_data()` returns `{}` although charm under test has set relation data
Although the machine charm under test sets relation data to the other charm in the relation-joined hook, harness,get_relation_data() still returns {}, making it impossible to write corresponding test expectations.
This is hitting us while pulling the ops framework from source (master) on 2022-02-17.
# metadata.yaml
name: nova-compute-nvidia-vgpu
subordinate: true
provides:
nova-vgpu:
interface: nova-vgpu
scope: container
requires:
juju-info:
interface: juju-info
scope: container
# src/charm.py
class NovaComputeNvidiaVgpuCharm(CharmBase):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.framework.observe(self.on.nova_vgpu_relation_joined,
self._on_nova_vgpu_relation_joined_or_changed)
self.framework.observe(self.on.nova_vgpu_relation_changed,
self._on_nova_vgpu_relation_joined_or_changed)
def _on_nova_vgpu_relation_joined_or_changed(self, event):
print('I HAVE BEEN CALLED')
event.relation.data[self.unit]['hello'] = 'hi'
# unit_tests/test_charm.py
class TestNovaComputeNvidiaVgpuCharm(CharmTestCase):
def setUp(self):
self.harness = Harness(src.charm.NovaComputeNvidiaVgpuCharm)
self.addCleanup(self.harness.cleanup)
self.harness.begin()
def test_nova_vgpu_relation_joined(self):
self.harness.set_leader(True)
relation_id = self.harness.add_relation('nova-vgpu', 'nova-compute')
self.harness.add_relation_unit(relation_id, 'nova-compute/0')
# PROBLEM: at this point this returns {} instead of {'hello': 'hi'}
# although we know that _on_nova_vgpu_relation_joined_or_changed() has
# been called:
self.harness.get_relation_data(relation_id, 'nova-compute/0')
Note that querying the other side of the relation also returns {}
unit_under_test = self.harness.charm.unit.name # -> nova-compute-nvidia-vgpu/0
print(self.harness.get_relation_data(relation_id, unit_under_test)) # -> {}
def _on_nova_vgpu_relation_joined_or_changed(self, event):
print('I HAVE BEEN CALLED')
event.relation.data[self.unit]['hello'] = 'hi'
This is setting the data for self.unit which should be something named based on NovaComputeNvidiaVgpuCharm. I certainly wouldn't expect nova-compute/0 to have any data, as your unit doesn't get to set remote data (you should be able to Harness.update_relation_data if you want to provide data from the remote to your unit.
I would expect unit_under_test from above to work
Thanks, yes you mean https://github.com/canonical/operator/issues/703#issuecomment-1048738575 should work, but doesn't for me
The example here passes for me (with ops 1.3):
def test_nova_vgpu_relation_joined(self):
self.harness.set_leader(True)
relation_id = self.harness.add_relation('nova-vgpu', 'nova-compute')
self.harness.add_relation_unit(relation_id, 'nova-compute/0')
unit_under_test = self.harness.charm.unit.name # -> nova-compute-nvidia-vgpu/0
self.assertEqual({'hello': 'hi'}, self.harness.get_relation_data(relation_id, unit_under_test))
@AurelienLourot - is there another issue that we have missed that needs to be addressed here?
I believe this is not an issue anymore.