diff --git a/CHANGELOG.rst b/CHANGELOG.rst index da035f3..3e13c97 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -23,6 +23,14 @@ Fixed Security ======== +[2022.2.1] - 2022-08-15 +*********************** + +Fixed +===== +- Made a shallow copy when iterating on shared data structure to avoid RuntimeError size changed + + [2022.2.0] - 2022-08-08 *********************** diff --git a/kytos.json b/kytos.json index 1a3e8b6..11a8cff 100644 --- a/kytos.json +++ b/kytos.json @@ -3,7 +3,7 @@ "username": "amlight", "name": "flow_stats", "description": "Store flow information and show statistics about them.", - "version": "2022.2.0", + "version": "2022.2.1", "napp_dependencies": ["kytos/of_core"], "license": "", "tags": [], diff --git a/main.py b/main.py index cc3fec7..238da94 100644 --- a/main.py +++ b/main.py @@ -60,7 +60,7 @@ def id(self): """ hash_result = hashlib.md5() hash_result.update(str(self.version).encode('utf-8')) - for value in self.match.values(): + for value in self.match.copy().values(): if self.version == '0x01': hash_result.update(str(value).encode('utf-8')) else: @@ -98,7 +98,7 @@ def match_to_dict(self): """Convert a match in OF 1.3 to a dictionary.""" # pylint: disable=consider-using-dict-items match = {} - for name in self.match: + for name in self.match.copy(): match[name] = self.match[name].value return match @@ -263,7 +263,7 @@ def match10(self, args): def match13(self, args): """Match a packet against this flow (OF1.3).""" # pylint: disable=consider-using-dict-items - for name in self.match: + for name in self.match.copy(): if name not in args: return False if name == 'vlan_vid': @@ -296,7 +296,7 @@ def setup(self): So, if you have any setup routine, insert it here. """ log.info('Starting Kytos/Amlight flow manager') - for switch in self.controller.switches.values(): + for switch in self.controller.switches.copy().values(): switch.generic_flows = [] self.switch_stats_xid = {} self.switch_stats_lock = {} @@ -318,7 +318,7 @@ def shutdown(self): def flow_from_id(self, flow_id): """Flow from given flow_id.""" - for switch in self.controller.switches.values(): + for switch in self.controller.switches.copy().values(): try: for flow in switch.generic_flows: if flow.id == flow_id: diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index e352799..eb6c8b4 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -273,12 +273,11 @@ def test_flow_stats(self, mock_match_flows): def _patch_switch_flow(self, flow_id): """Helper method to patch controller to return switch/flow data.""" # patching the flow_stats object in the switch - self.napp.controller.switches = MagicMock() flow = self._get_mocked_flow_stats() flow.id = flow_id switch = MagicMock() switch.generic_flows = [flow] - self.napp.controller.switches.values.return_value = [switch] + self.napp.controller.switches = {"1": switch} self.napp.controller.get_switch_by_dpid = MagicMock() self.napp.controller.get_switch_by_dpid.return_value = switch