neutron/neutron/tests/functional/agent/linux/test_of_monitor.py

99 lines
3.7 KiB
Python

# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from neutron.agent.linux import of_monitor
from neutron.common import utils
from neutron.tests.common import net_helpers
from neutron.tests.functional import base as functional_base
class OFMonitorTestCase(functional_base.BaseSudoTestCase):
DEFAULT_FLOW = {'table': 0, 'cookie': '0', 'actions': 'NORMAL'}
def setUp(self):
super(OFMonitorTestCase, self).setUp()
self.bridge = self.useFixture(net_helpers.OVSBridgeFixture()).bridge
self.of_monitor = of_monitor.OFMonitor(self.bridge.br_name,
start=False)
self.addCleanup(self.of_monitor.stop)
def _format_flow(self, flow, event_type):
deleted = ''
if event_type == 'DELETED':
deleted = 'reason=delete'
table = 'table=%s' % flow['table']
cookie = flow.get('cookie') or hex(self.bridge._default_cookie)
# NOTE(ralonsoh): remove PY2 "L" suffix in longs
cookie = 'cookie=' + cookie.rstrip('L')
filters = []
if flow.get('in_port'):
filters.append('in_port=%s' % flow.get('in_port'))
if flow.get('dl_vlan'):
filters.append('dl_vlan=%s' % flow.get('dl_vlan'))
if flow.get('dl_src'):
filters.append('dl_src=%s' % flow.get('dl_src'))
filters = ','.join(filters)
actions = ''
if flow.get('actions'):
actions += 'actions=%s' % flow.get('actions')
flow_sections = [section for section
in (deleted, table, cookie, filters, actions)
if section]
return ' '.join(flow_sections)
def _check_flow(self, reference_flow, event_type):
def _read_and_check():
event = self.of_monitor.of_events
if len(event) == 1:
events_container.append(event[0])
return True
return False
events_container = []
try:
utils.wait_until_true(_read_and_check, timeout=5)
except utils.WaitTimeout:
self.fail('Flow "%s" with action %s not found' % (reference_flow,
event_type))
event = events_container.pop()
self.assertEqual(event_type, event.event_type)
self.assertEqual(self._format_flow(reference_flow, event_type),
event.flow)
def test_of_events(self):
self.of_monitor.start()
self._check_flow(self.DEFAULT_FLOW, 'ADDED')
flow = {'table': 10, 'in_port': 20, 'dl_vlan': 30,
'dl_src': '00:00:00:00:00:01', 'actions': 'NORMAL'}
self.bridge.add_flow(**flow)
self._check_flow(flow, 'ADDED')
flow['table'] = 50
self.bridge.add_flow(**flow)
self._check_flow(flow, 'ADDED')
flow['actions'] = 'resubmit:100'
self.bridge.mod_flow(**flow)
self._check_flow(flow, 'MODIFIED')
flow['table'] = 10
flow['actions'] = 'NORMAL'
flow_to_delete = flow.copy()
flow_to_delete.pop('actions')
self.bridge.delete_flows(**flow_to_delete)
self._check_flow(flow, 'DELETED')