1# Copyright (C) 2016 Nippon Telegraph and Telephone Corporation. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12# implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import unittest 17import logging 18try: 19 import mock # Python 2 20except ImportError: 21 from unittest import mock # Python 3 22 23from nose.tools import eq_ 24 25from ryu.lib.packet import bgp 26from ryu.services.protocols.bgp import peer 27 28 29LOG = logging.getLogger(__name__) 30 31 32class Test_Peer(unittest.TestCase): 33 """ 34 Test case for peer.Peer 35 """ 36 37 @mock.patch.object( 38 peer.Peer, '__init__', mock.MagicMock(return_value=None)) 39 def _test_construct_as_path_attr( 40 self, input_as_path, input_as4_path, expected_as_path): 41 # Prepare input data 42 input_as_path_attr = bgp.BGPPathAttributeAsPath(input_as_path) 43 input_as4_path_attr = bgp.BGPPathAttributeAs4Path(input_as4_path) 44 _peer = peer.Peer(None, None, None, None, None) 45 46 # TEST 47 output_as_path_attr = _peer._construct_as_path_attr( 48 input_as_path_attr, input_as4_path_attr) 49 50 eq_(bgp.BGP_ATTR_TYPE_AS_PATH, output_as_path_attr.type) 51 eq_(expected_as_path, output_as_path_attr.path_seg_list) 52 53 def test_construct_as_path_attr_sequence_only(self): 54 # Test Data 55 # Input: 56 input_as_path = [[65000, 4000, 23456, 23456, 40001]] 57 input_as4_path = [[400000, 300000, 40001]] 58 # Expected: 59 expected_as_path = [[65000, 4000, 400000, 300000, 40001]] 60 61 self._test_construct_as_path_attr( 62 input_as_path, input_as4_path, expected_as_path) 63 64 def test_construct_as_path_attr_aggregated_as_path_1(self): 65 # Test Data 66 # Input: 67 input_as_path = [[65000, 4000], {10, 20, 30}, [23456, 23456, 40001]] 68 input_as4_path = [[400000, 300000, 40001]] 69 # Expected: 70 expected_as_path = [[65000, 4000], {10, 20, 30}, [400000, 300000, 40001]] 71 72 self._test_construct_as_path_attr( 73 input_as_path, input_as4_path, expected_as_path) 74 75 def test_construct_as_path_attr_aggregated_as_path_2(self): 76 # Test Data 77 # Input: 78 input_as_path = [[65000, 4000], {10, 20, 30}, [23456, 23456, 40001]] 79 input_as4_path = [[3000, 400000, 300000, 40001]] 80 # Expected: 81 expected_as_path = [[65000, 4000, 3000, 400000, 300000, 40001]] 82 83 self._test_construct_as_path_attr( 84 input_as_path, input_as4_path, expected_as_path) 85 86 def test_construct_as_path_attr_aggregated_path_3(self): 87 # Test Data 88 # Input: 89 input_as_path = [[65000, 4000, 23456, 23456, 40001]] 90 input_as4_path = [[400000, 300000, 40001], {10, 20, 30}] 91 # Expected: 92 expected_as_path = [[65000, 400000, 300000, 40001], {10, 20, 30}] 93 94 self._test_construct_as_path_attr( 95 input_as_path, input_as4_path, expected_as_path) 96 97 def test_construct_as_path_attr_aggregated_as4_path(self): 98 # Test Data 99 # Input: 100 input_as_path = [[65000, 4000, 23456, 23456, 40001]] 101 input_as4_path = [{10, 20, 30}, [400000, 300000, 40001]] 102 # Expected: 103 expected_as_path = [[65000], {10, 20, 30}, [400000, 300000, 40001]] 104 105 self._test_construct_as_path_attr( 106 input_as_path, input_as4_path, expected_as_path) 107 108 def test_construct_as_path_attr_too_short_as_path(self): 109 # Test Data 110 # Input: 111 input_as_path = [[65000, 4000, 23456, 23456, 40001]] 112 input_as4_path = [[100000, 65000, 4000, 400000, 300000, 40001]] 113 # Expected: 114 expected_as_path = [[65000, 4000, 23456, 23456, 40001]] 115 116 self._test_construct_as_path_attr( 117 input_as_path, input_as4_path, expected_as_path) 118 119 def test_construct_as_path_attr_too_short_as4_path(self): 120 # Test Data 121 # Input: 122 input_as_path = [[65000, 4000, 23456, 23456, 40001]] 123 input_as4_path = [[300000, 40001]] 124 # Expected: 125 expected_as_path = [[65000, 4000, 23456, 300000, 40001]] 126 127 self._test_construct_as_path_attr( 128 input_as_path, input_as4_path, expected_as_path) 129 130 def test_construct_as_path_attr_empty_as4_path(self): 131 # Test Data 132 # Input: 133 input_as_path = [[65000, 4000, 23456, 23456, 40001]] 134 input_as4_path = [[]] 135 # Expected: 136 expected_as_path = [[65000, 4000, 23456, 23456, 40001]] 137 138 self._test_construct_as_path_attr( 139 input_as_path, input_as4_path, expected_as_path) 140 141 @mock.patch.object( 142 peer.Peer, '__init__', mock.MagicMock(return_value=None)) 143 def test_construct_as_path_attr_as4_path_None(self): 144 # Test Data 145 # Input: 146 input_as_path = [[65000, 4000, 23456, 23456, 40001]] 147 # input_as4_path = None 148 # Expected: 149 expected_as_path = [[65000, 4000, 23456, 23456, 40001]] 150 151 # Prepare input data 152 input_as_path_attr = bgp.BGPPathAttributeAsPath(input_as_path) 153 input_as4_path_attr = None 154 _peer = peer.Peer(None, None, None, None, None) 155 156 # TEST 157 output_as_path_attr = _peer._construct_as_path_attr( 158 input_as_path_attr, input_as4_path_attr) 159 160 eq_(bgp.BGP_ATTR_TYPE_AS_PATH, output_as_path_attr.type) 161 eq_(expected_as_path, output_as_path_attr.path_seg_list) 162 163 @mock.patch.object( 164 peer.Peer, '__init__', mock.MagicMock(return_value=None)) 165 def _test_trans_as_path( 166 self, input_as_path, expected_as_path, expected_as4_path): 167 # Prepare input data 168 _peer = peer.Peer(None, None, None, None, None) 169 170 # TEST 171 output_as_path, output_as4_path = _peer._trans_as_path(input_as_path) 172 173 eq_(expected_as_path, output_as_path) 174 eq_(expected_as4_path, output_as4_path) 175 176 @mock.patch.object( 177 peer.Peer, 'is_four_octet_as_number_cap_valid', 178 mock.MagicMock(return_value=True)) 179 def test_trans_as_path_as4_path_is_supported(self): 180 # Test Data 181 # Input: 182 input_as_path = [[65000, 4000, 400000, 300000, 40001]] 183 # Expected: 184 expected_as_path = [[65000, 4000, 400000, 300000, 40001]] 185 expected_as4_path = None 186 187 self._test_trans_as_path( 188 input_as_path, expected_as_path, expected_as4_path) 189 190 @mock.patch.object( 191 peer.Peer, 'is_four_octet_as_number_cap_valid', 192 mock.MagicMock(return_value=False)) 193 def test_trans_as_path_sequence_only(self): 194 # Test Data 195 # Input: 196 input_as_path = [[65000, 4000, 400000, 300000, 40001]] 197 # Expected: 198 expected_as_path = [[65000, 4000, 23456, 23456, 40001]] 199 expected_as4_path = [[65000, 4000, 400000, 300000, 40001]] 200 201 self._test_trans_as_path( 202 input_as_path, expected_as_path, expected_as4_path) 203 204 @mock.patch.object( 205 peer.Peer, 'is_four_octet_as_number_cap_valid', 206 mock.MagicMock(return_value=False)) 207 def test_trans_as_path_no_trans(self): 208 # Test Data 209 # Input: 210 input_as_path = [[65000, 4000, 40000, 30000, 40001]] 211 # Expected: 212 expected_as_path = [[65000, 4000, 40000, 30000, 40001]] 213 expected_as4_path = None 214 215 self._test_trans_as_path( 216 input_as_path, expected_as_path, expected_as4_path) 217 218 @mock.patch.object( 219 peer.Peer, '__init__', mock.MagicMock(return_value=None)) 220 def _test_extract_and_reconstruct_as_path( 221 self, path_attributes, ex_as_path_value, 222 ex_aggregator_as_number, ex_aggregator_addr): 223 # Prepare test data 224 update_msg = bgp.BGPUpdate(path_attributes=path_attributes) 225 _peer = peer.Peer(None, None, None, None, None) 226 227 # Test 228 _peer._extract_and_reconstruct_as_path(update_msg) 229 230 umsg_pattrs = update_msg.pathattr_map 231 as_path_attr = umsg_pattrs.get( 232 bgp.BGP_ATTR_TYPE_AS_PATH, None) 233 as4_path_attr = umsg_pattrs.get( 234 bgp.BGP_ATTR_TYPE_AS4_PATH, None) 235 aggregator_attr = umsg_pattrs.get( 236 bgp.BGP_ATTR_TYPE_AGGREGATOR, None) 237 as4_aggregator_attr = umsg_pattrs.get( 238 bgp.BGP_ATTR_TYPE_AS4_AGGREGATOR, None) 239 240 eq_(ex_as_path_value, as_path_attr.value) 241 eq_(None, as4_path_attr) 242 eq_(ex_aggregator_as_number, aggregator_attr.as_number) 243 eq_(ex_aggregator_addr, aggregator_attr.addr) 244 eq_(None, as4_aggregator_attr) 245 246 @mock.patch.object( 247 peer.Peer, '__init__', mock.MagicMock(return_value=None)) 248 def test_extract_and_reconstruct_as_path_with_no_as4_attr(self): 249 # Input values 250 in_as_path_value = [[1000, 2000, 3000]] 251 # in_as4_path_value 252 in_aggregator_as_number = 4000 253 in_aggregator_addr = '10.0.0.1' 254 # in_as4_aggregator_as_number 255 # in_as4_aggregator_addr 256 257 # Expected values 258 ex_as_path_value = [[1000, 2000, 3000]] 259 ex_aggregator_as_number = 4000 260 ex_aggregator_addr = '10.0.0.1' 261 262 # Prepare test data 263 path_attributes = [ 264 bgp.BGPPathAttributeAsPath( 265 value=in_as_path_value), 266 bgp.BGPPathAttributeAggregator( 267 as_number=in_aggregator_as_number, addr=in_aggregator_addr), 268 ] 269 270 # Test 271 self._test_extract_and_reconstruct_as_path( 272 path_attributes, ex_as_path_value, 273 ex_aggregator_as_number, ex_aggregator_addr) 274 275 @mock.patch.object( 276 peer.Peer, '__init__', mock.MagicMock(return_value=None)) 277 def test_extract_and_reconstruct_as_path_with_as4_attr(self): 278 # Input values 279 in_as_path_value = [[1000, 23456, 3000]] 280 in_as4_path_value = [[2000, 3000]] 281 in_aggregator_as_number = 23456 282 in_aggregator_addr = '10.0.0.1' 283 in_as4_aggregator_as_number = 4000 284 in_as4_aggregator_addr = '10.0.0.1' 285 286 # Expected values 287 ex_as_path_value = [[1000, 2000, 3000]] 288 ex_aggregator_as_number = 4000 289 ex_aggregator_addr = '10.0.0.1' 290 291 # Prepare test data 292 path_attributes = [ 293 bgp.BGPPathAttributeAsPath( 294 value=in_as_path_value), 295 bgp.BGPPathAttributeAs4Path( 296 value=in_as4_path_value), 297 bgp.BGPPathAttributeAggregator( 298 as_number=in_aggregator_as_number, 299 addr=in_aggregator_addr), 300 bgp.BGPPathAttributeAs4Aggregator( 301 as_number=in_as4_aggregator_as_number, 302 addr=in_as4_aggregator_addr), 303 ] 304 305 # Test 306 self._test_extract_and_reconstruct_as_path( 307 path_attributes, ex_as_path_value, 308 ex_aggregator_as_number, ex_aggregator_addr) 309 310 @mock.patch.object( 311 peer.Peer, '__init__', mock.MagicMock(return_value=None)) 312 def test_extract_and_reconstruct_as_path_with_not_trans_as_aggr(self): 313 # Input values 314 in_as_path_value = [[1000, 23456, 3000]] 315 in_as4_path_value = [[2000, 3000]] 316 in_aggregator_as_number = 4000 # not AS_TRANS 317 in_aggregator_addr = '10.0.0.1' 318 in_as4_aggregator_as_number = 4000 319 in_as4_aggregator_addr = '10.0.0.1' 320 321 # Expected values 322 ex_as_path_value = [[1000, 23456, 3000]] 323 ex_aggregator_as_number = 4000 324 ex_aggregator_addr = '10.0.0.1' 325 326 # Prepare test data 327 path_attributes = [ 328 bgp.BGPPathAttributeAsPath( 329 value=in_as_path_value), 330 bgp.BGPPathAttributeAs4Path( 331 value=in_as4_path_value), 332 bgp.BGPPathAttributeAggregator( 333 as_number=in_aggregator_as_number, 334 addr=in_aggregator_addr), 335 bgp.BGPPathAttributeAs4Aggregator( 336 as_number=in_as4_aggregator_as_number, 337 addr=in_as4_aggregator_addr), 338 ] 339 340 # Test 341 self._test_extract_and_reconstruct_as_path( 342 path_attributes, ex_as_path_value, 343 ex_aggregator_as_number, ex_aggregator_addr) 344 345 @mock.patch.object( 346 peer.Peer, '__init__', mock.MagicMock(return_value=None)) 347 def test_extract_and_reconstruct_as_path_with_short_as_path(self): 348 # Input values 349 in_as_path_value = [[1000, 23456, 3000]] 350 in_as4_path_value = [[2000, 3000, 4000, 5000]] # longer than AS_PATH 351 in_aggregator_as_number = 4000 352 in_aggregator_addr = '10.0.0.1' 353 # in_as4_aggregator_as_number 354 # in_as4_aggregator_addr 355 356 # Expected values 357 ex_as_path_value = [[1000, 23456, 3000]] 358 ex_aggregator_as_number = 4000 359 ex_aggregator_addr = '10.0.0.1' 360 361 # Prepare test data 362 path_attributes = [ 363 bgp.BGPPathAttributeAsPath( 364 value=in_as_path_value), 365 bgp.BGPPathAttributeAs4Path( 366 value=in_as4_path_value), 367 bgp.BGPPathAttributeAggregator( 368 as_number=in_aggregator_as_number, 369 addr=in_aggregator_addr), 370 ] 371 372 # Test 373 self._test_extract_and_reconstruct_as_path( 374 path_attributes, ex_as_path_value, 375 ex_aggregator_as_number, ex_aggregator_addr) 376