Skip to content

add test case bgp multipath relax#284

Merged
maggiemsft merged 7 commits intosonic-net:masterfrom
maggiemsft:masun/bgp_multipath
Oct 18, 2017
Merged

add test case bgp multipath relax#284
maggiemsft merged 7 commits intosonic-net:masterfrom
maggiemsft:masun/bgp_multipath

Conversation

@maggiemsft
Copy link
Copy Markdown
Contributor

solve issue #283

def main():
module = AnsibleModule(
argument_spec=dict(
show_cmd=dict(required=False, default=''),
Copy link
Copy Markdown
Contributor

@lguohan lguohan Sep 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you define parameter like
neighbor=?
direction=(adv/rcv)
prefix=?

direction is only available when neighbor is specified.

It it better for you to ask user to give parameter instead of letting use to give you the raw commands.
#Resolved

Copy link
Copy Markdown
Contributor Author

@maggiemsft maggiemsft Sep 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed with the suggestion #Resolved

{% endfor %}
{% set index = 1 %}
{% for subnet in host['vips']['ipv4']['range'] %}
ip prefix-list test_vip_{{ index }} seq 10 permit {{ subnet }}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you also need to increase the seq here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

{% set index = index + 1 %}
{% endfor %}
{% set index = 1 %}
{% for subnet in host['vips']['ipv4']['range'] %}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use only one subnet loop and add ip route, prefix-list and route-map in the loop.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of it when I first built the template, since this template create the startup configure file directly, not configuration input sequence , and I looked at the actual EOS config, prefixes are in one section and ip route are in one section, I am not 100% sure if I mixed them would be OK, this way is more safe.

{% endfor %}
{% set index = 1 %}
{% for subnet in host['vips']['ipv4']['range'] %}
route-map PREPENDAS permit 2{{ index }}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is 2{{ index }}, give a better name? vip_{{ index }}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is router-map read/apply sequence number. not a name. so has to be int. we don't have complicated route-map here, it's just a random picked 21, 22, ...

ipv6: fc00::4a/126
vips:
ipv4:
range:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

range -> prefix

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

that:
- vips_prefix in bgp_rt_neiadv.keys()
- bgp_rt_neiadv[vips_prefix]['paths'] | length == 2
- vips_asn in bgp_rt_neiadv[vips_prefix]['paths']
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you check if vips_asn is the last one? vips_asn == bgp_rt_neiadv[vips_prefix]['paths'][-1]?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

vips_prefixes: "{{ configuration[item]['vips']['ipv4']['range'] }}"
vips_asn: "{{ configuration[item]['vips']['ipv4']['asn'] }}"
with_items: "{{ dut_t0_nei }}"
when: "{{ 'vips' in configuration[item].keys() }}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems little bit complicated, and it is not guarantee to work if not all t0 advertise same vip prefixes. The assumption here is that all t0 advertising same set of vip prefixes.

I would suggest to add vip section (duplicated) in configuration_properties

  • vips:
    prefix:
    - 20.0.1.0/26
    t0:
    - arista01t0
    - arista01t1

it is duplicated data, but the ansible logic is easier.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, this would only work when all vips advertise same set of prefixes. change the topology yaml file like suggested here, will need carefully synced with configuration with each VM and the topology for whole testbed.
I changed the playbook to pick a prefix to validate that prefix's path.

Copy link
Copy Markdown
Contributor

@lguohan lguohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as comments.

@sonic-net sonic-net deleted a comment from msftclas Sep 27, 2017
bgp_route: show_cmd='100.0.0.1'

- name: Get BGP route information
bgp_route: show_cmd='neighbor 10.0.0.1 advert'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change according to the new params

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


- name: remove duplicate entries
set_fact:
vips_prefixes: "{{ vips_prefixes | unique }}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need another unique as we did the unique in line 44 already?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are correct, this is duplicated, there were a syntax error for filter which didn't apply unique

vips_asn: "{{ configuration[item]['vips']['ipv4']['asn'] }}"
with_items: "{{ dut_t0_nei }}"
when: vips_prefix in "{{ configuration[item]['vips']['ipv4']['prefixes'] }}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to verify the len(vips_t0) > 1 to multipath relax test, if the len() is <= 1, then we should not test and return failure.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, before I wrote a presumption that prefix is multipathed, but this check is much better, thanks

def main():
module = AnsibleModule(
argument_spec=dict(
neighbor=dict(required=False, default=''),
Copy link
Copy Markdown
Contributor

@lguohan lguohan Sep 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can default be None? #Resolved

Copy link
Copy Markdown
Contributor Author

@maggiemsft maggiemsft Sep 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this looks better #Resolved

bgproute = BgpRoutes()
regex_ip = re.compile('[0-9a-fA-F.:]+')
regex_iprange = re.compile('[0-9a-fA-F.:]+\/\d+')
if neigh == '' and direction == '' and prefix == '':
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if neigh == None and direction == None and prefix == None

* show ip bgp 100.0.0.1 ### show ip bgp prefix info
* show ip bgp neighbor 10.0.0.1 adv ### show ip bgp neighbor address advertised routes
- Retrieved facts will be inserted into the 'bgp_rt' or 'bgp_rt_neiadv'
'''
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still lacking proper documentation of the module, such as requirements, options sections.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

module = AnsibleModule(
argument_spec=dict(
neighbor=dict(required=False, default=None),
direction=dict(required=False, default=None),
Copy link
Copy Markdown
Contributor

@lguohan lguohan Oct 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

direction=dict(required=False, default=None [](start = 16, length = 43)

please use choices for direction option, check lldp_facts.py for the example. #Resolved

def get_facts(self):
return self.facts

def parse_bgp_rt_adv(self, cmd, cmd_result):
Copy link
Copy Markdown
Contributor

@lguohan lguohan Oct 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parse_bgp_rt_adv(self, cmd, cmd_result): [](start = 8, length = 40)

we should do some unit test code to test your parse logic.

check here.

http://docs.ansible.com/ansible/latest/dev_guide/testing_units.html
#WontFix

continue
else:
if not re.match('^\*', line):
continue
Copy link
Copy Markdown
Contributor

@lguohan lguohan Oct 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add comment here. only parse the valid route entries. #Resolved

self.facts['bgp_rt_neiadv']['neighbor'] = neighbor
### so far parsing by fixed length table
### will improve this if find better way to parse it
header_position = [0, 3, 20, 40, 47, 54, 61]
Copy link
Copy Markdown
Contributor

@lguohan lguohan Oct 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use regx split('\s+') into several fields for a line. #Resolved

Copy link
Copy Markdown
Contributor Author

@maggiemsft maggiemsft Oct 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, not every entry has all fields, so cannot split('\s+')
like following, loopback route has a matric of 0 which rest of the example lines do not have that field:
Network Next Hop Metric LocPrf Weight Path
*> 0.0.0.0 10.0.0.32 0 65200 ?
*> 10.1.0.32/32 10.0.0.32 0 32768 i
*> 100.1.0.1/32 10.0.0.32 0 65200 i #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see the differences.


In reply to: 144104841 [](ancestors = 144104841)

regex_prefix_paths = re.compile('^[0-9\s]+$')
regex_prefix_path_line1 = re.compile('.* from .*\([0-9a-fA-F.:]+\)')
regex_prefix_path_line2 = re.compile('\s+Origin')
regex_prefix_path_line3 = re.compile('\s+Last update:')
Copy link
Copy Markdown
Contributor

@lguohan lguohan Oct 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is better to give each line a meaning instead of 1,2,3... #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for example, line1 is source, line 2 is the attributes, line 3 is the update_time.


In reply to: 142343743 [](ancestors = 142343743)

self.facts['bgp_rt'][prefix]['found'] = False
return
result_lines = cmd_result.split('\n')
## search_state = ['header', 'path_prop', 'prefix_prop1', 'prefix_prop2', 'paths', 'path_l1', 'path_l2', 'path_l3', 'err' ]
Copy link
Copy Markdown
Contributor

@lguohan lguohan Oct 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

search_state = ['header [](start = 8, length = 26)

you seems like to like to compare strings, but it is better to define constant and then use the contant

for example,
HEADER_LINE=1
XXX_LINE=2
... #Resolved

Copy link
Copy Markdown
Contributor

@lguohan lguohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as comments.

if regex_neighbor.match(cmd):
neighbor = regex_neighbor.match(cmd).group(1)
else:
raise Exception('cannot find neighbor in "show ip bgp ' + cmd + '"')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[](start = 62, length = 1)

shoud be only one space here.

else:
raise Exception('cannot find neighbor in "show ip bgp ' + cmd + '"')
self.facts['bgp_route_neiadv']['neighbor'] = neighbor
### so far parsing prifix, nexthop and paths only
Copy link
Copy Markdown
Contributor

@lguohan lguohan Oct 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prifix [](start = 27, length = 6)

prefix #Resolved

else:
raise Exception('cannot find neighbor in "show ip bgp ' + cmd + '"')
self.facts['bgp_route_neiadv']['neighbor'] = neighbor
### so far parsing prifix, nexthop and paths only
Copy link
Copy Markdown
Contributor

@lguohan lguohan Oct 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

paths [](start = 47, length = 5)

path -> as path #Resolved

else:
raise Exception('cannot find neighbor in "show ip bgp ' + cmd + '"')
self.facts['bgp_route_neiadv']['neighbor'] = neighbor
### so far parsing prifix, nexthop and paths only
Copy link
Copy Markdown
Contributor

@lguohan lguohan Oct 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you also parse the origin, and also weight. #Resolved

line = result_lines.pop(0)
nexthop = line.strip().split()[0]
paths = re_path.match(line).group(2)
origin = re_path.match(line).group(4)
Copy link
Copy Markdown
Contributor

@lguohan lguohan Oct 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only need one match

m = re_aspath.match(line)

aspaths = m.group(2)
origin = m.group(4)

what if it does not aspath, is it still group 4? #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weight = m.group(1)


In reply to: 145203052 [](ancestors = 145203052)

paths = re_path.match(line).group(2)
origin = re_path.match(line).group(4)
if paths:
entry['paths'] = paths.split()
Copy link
Copy Markdown
Contributor

@lguohan lguohan Oct 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

paths [](start = 27, length = 5)

paths -> aspath #Resolved

def get_facts(self):
return self.facts

def parse_bgp_route_adv(self, cmd, cmd_result):
Copy link
Copy Markdown
Contributor

@lguohan lguohan Oct 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the argument should be neigh, you do not need to give the cmmand and use regex to re-parse it. #Resolved

if neigh and 'adv' in direction.lower():
show_cmd = "neighbor " + neigh + " adv"
(rc, out, err) = collect_data(module, show_cmd)
bgproute.parse_bgp_route_adv(show_cmd, out)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

proute.parse_bgp_route_adv(show_cmd, out) [](start = 14, length = 41)

parse_bgp_route_adv(neigh, out)

if neigh == None and direction == None and prefix == None:
raise Exception("parsing 'show ip bgp' full prefix table not implemented yet")
if neigh and (not netaddr.valid_ipv4(neigh)) and (not netaddr.valid_ipv6(neigh)) or neigh and not direction:
raise Exception('No support parsing this command " show ip(v6) bgp neighbor %s %s" yet' % (neigh, direction))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is parameter validation, should be in different block as the parsing the actual output.

m_args = module.params
neigh = m_args['neighbor']
direction = m_args['direction']
prefix = m_args['prefix']
Copy link
Copy Markdown
Contributor

@lguohan lguohan Oct 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall, we should first to parameter validation and raise any exception is parameters are incorrect.

Then, we run the command and get the results, raise errors when the return results are incorrect.

we should not mixed them in one block. #Resolved

(rc, out, err) = collect_data(module, prefix)
bgproute.parse_bgp_route_prefix(prefix, out)
else:
raise Exception('No support of this command "show ip(v6) bgp %s " yet ' % prefix)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exception('No support of this command "show ip(v6) bgp %s " yet ' % prefix) [](start = 22, length = 75)

this exception should be prefix not valid, not "no support of this command"

else:
raise Exception('No support of this command "show ip(v6) bgp %s " yet ' % prefix)
else:
raise Exception('No support parsing this command " show ip(v6) bgp neighbor=%s direction=%s prefix=%s" yet' % (neigh, direction, prefix))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exception [](start = 18, length = 9)

does exception work for ansible_module, will it return error, I thought we should always do module_exit_json.

bgp_route module improvement
Copy link
Copy Markdown
Contributor

@lguohan lguohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@maggiemsft maggiemsft merged commit b3761a1 into sonic-net:master Oct 18, 2017
@maggiemsft maggiemsft deleted the masun/bgp_multipath branch December 5, 2017 23:39
praveen-li pushed a commit to praveen-li/sonic-mgmt that referenced this pull request Jun 20, 2019
* msft_github/master:
  [test]: Add ptf_platform_dir: ptftests to enable more than 32 ports testbed (sonic-net#315)
  [bgp_speaker]: Support t0-64 topology (sonic-net#316)
  [Minigraph Templates]: Add new <DhcpRelays> node to Vlans as appropriate (sonic-net#298)
  [sensors]: Add comment to indicate the sensors data file path
  [ptf_runner]: Add ptf_platform_dir option to indicate --platform-dir option (sonic-net#304)
  Make fetch command arguments supported by newer ansible version (sonic-net#310)
  [arista7260cx3] define t0 116 ports topology
  [fast-reboot test]: Cosmetic fixes (sonic-net#307)
  [test]add more ARP and neighbor-mac tests (sonic-net#303)
  After boot_onie, admin up all bgp interfaces (sonic-net#306)
  Update README.test.md
  add test case bgp multipath relax (sonic-net#284)
  [minigraph]: Remove unnecessary quotes (sonic-net#301)
auspham pushed a commit to auspham/sonic-mgmt that referenced this pull request May 30, 2025
…emplate from config.bcm for TH5 platforms (sonic-net#284)

<!--
Please make sure you've read and understood our contributing guidelines;
https://github.com/sonic-net/SONiC/blob/gh-pages/CONTRIBUTING.md

Please provide following information to help code review process a bit easier:
-->
### Description of PR
<!--
- Please include a summary of the change and which issue is fixed.
- Please also include relevant motivation and context. Where should reviewer start? background context?
- List any dependencies that are required for this change.
-->

Summary:
Fixes # (issue)
This change enhances the `check_config` fixture in test_route_perf.py to support TH5 platforms in Broadcom (e.g., x86_64-arista_7060x6_64pe and x86_64-arista_7060x6_64pe_b) where the `l3_alpm_template` value is configured in the config.bcm file instead of being queried via `bcmcmd`.

### Type of change

<!--
- Fill x for your type of change.
- e.g.
- [x] Bug fix
-->

- [ ] Bug fix
- [ ] Testbed and Framework(new/improvement)
- [ ] New Test case
 - [ ] Skipped for non-supported platforms
- [x] Test case improvement

### Back port request
- [x] 202412

### Approach
#### What is the motivation for this PR?
TH5 devices manage ALPM configuration through config.bcm, and bcmcmd does not reflect runtime ALPM mode (l3_alpm_template) for them. Test case route/test_route_perf.py::test_perf_add_remove_routes would failed on TH5 platforms because it didn't support get ALPM configuration from bcm shell.

#### How did you do it?
- Added `get_l3_alpm_template_from_config_bcm()` helper to locate and copy the config.bcm file to /tmp and parse and retrieve the value of `l3_alpm_template`.
- Update the `check_config` fixture to use the new method for TH5 platforms.

#### How did you verify/test it?
Verified on TH5 device (x86_64-arista_7060x6_64pe): confirms the correct ALPM template value is retrieved and case test_perf_add_remove_routes can pass now.
```
route/test_route_perf.py::test_perf_add_remove_routes[4-str4-7060x6-64pe-10-None] PASSED [50%]
route/test_route_perf.py::test_perf_add_remove_routes[6-str4-7060x6-64pe-10-None] PASSED [100%]
```

#### Any platform specific information?

#### Supported testbed topology if it's a new test case?

### Documentation
<!--
(If it's a new feature, new test case)
Did you update documentation/Wiki relevant to your implementation?
Link to the wiki page?
-->

Signed-off-by: zitingguo-ms <zitingguo@microsoft.com>
auspham pushed a commit to auspham/sonic-mgmt that referenced this pull request May 30, 2025
)

```
81505c8 (az_upstream/202412) Merge branch '202411' of https://github.com/sonic-net/sonic-mgmt into 202412
30b7d73 (pub_upstream/202411) [202411 ] Updating the BGP, Reboot and LACP  convergence cases to latest Snappi Api Model instead of Snappi_convergence module [ PR 18044 ] (sonic-net#18391)
e146100 [action] [PR:18292] Fix Skip tests if no portchannels are found in prepare_test_port fixture (sonic-net#280)
d8b9193 [action] [PR:17985] [tests_mark_conditions.yaml]: Skip GNMI/ZMQ test for isolated topology (sonic-net#281)
ef951e6 [action] [PR:17943] Add default routes to t1-isolated-d128 (sonic-net#282)
2d3aec5 [action] [PR:18341] [route/test_route_perf] Support reading l3_alpm_template from config.bcm for TH5 platforms (sonic-net#284)
6390c7d [202412][PR: 18350] disable default pfcwd for all lossy DUT (sonic-net#271)
b621644 [Cherry-pick] modifying Ignore message for 'Failed to get port by bridge port ID' (sonic-net#263)
bc9a2d2 modifying Ignore message for 'Failed to get port by bridge port ID'
```
kazinator-arista pushed a commit to kazinator-arista/sonic-mgmt that referenced this pull request Mar 4, 2026
…ic-net#11790)

linkmgrd:
* e20e402 2022-08-18 | Update `handleMuxConfigNotification` logic (sonic-net#125) (HEAD -> 202205) [Jing Zhang]
* 8a54c06 2022-08-17 | [active-active] post mux metrics events (sonic-net#123) [Jing Zhang]

platform-daemon:
* 1a833f6 2022-08-18 | [ycabled] enable telemetry for 'active-active'; fix gRPC portid ordering (sonic-net#284) (HEAD -> 202205) [vdahiya12]

utilities:
* 4bacc1c 2022-08-19 | Fix issue: exception in is_rj45_port in multi ASIC env (sonic-net#2313) (HEAD -> 202205) [Stephen Sun]

swss:
* 4085d3f 2022-07-25 | Revert hwinfo count change (sonic-net#2383) (HEAD -> 202205) [andywongarista]

Signed-off-by: Ying Xie <ying.xie@microsoft.com>

Signed-off-by: Ying Xie <ying.xie@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants