Files
infix/25.08/testing/index.html
T

2490 lines
61 KiB
HTML

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Infix Documentation">
<link rel="canonical" href="https://kernelkit.github.io/infix/25.08/testing/">
<link rel="prev" href="../netboot/">
<link rel="next" href="../test-arch/">
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.1">
<title>Regression Testing - User's Guide</title>
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.ab4e12ef.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<link rel="stylesheet" href="../extra.css">
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="orange" data-md-color-accent="orange">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#regression-testing-with-infamy" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<div data-md-color-scheme="default" data-md-component="outdated" hidden>
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="https://kernelkit.org/" title="User&#39;s Guide" class="md-header__button md-logo" aria-label="User's Guide" data-md-component="logo">
<img src="../logo-plain.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
User's Guide
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Regression Testing
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="orange" data-md-color-accent="orange" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="black" data-md-color-accent="orange" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/kernelkit/infix/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
kernelkit/infix
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="https://kernelkit.org/" title="User&#39;s Guide" class="md-nav__button md-logo" aria-label="User's Guide" data-md-component="logo">
<img src="../logo-plain.png" alt="logo">
</a>
User's Guide
</label>
<div class="md-nav__source">
<a href="https://github.com/kernelkit/infix/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
kernelkit/infix
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
<span class="md-ellipsis">
CLI
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
CLI
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../cli/introduction/" class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/configure/" class="md-nav__link">
<span class="md-ellipsis">
Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/keybindings/" class="md-nav__link">
<span class="md-ellipsis">
Keybindings
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/netcalc/" class="md-nav__link">
<span class="md-ellipsis">
Network Calculator
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/tcpdump/" class="md-nav__link">
<span class="md-ellipsis">
Network Monitoring
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/quick/" class="md-nav__link">
<span class="md-ellipsis">
Quickstart Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/text-editor/" class="md-nav__link">
<span class="md-ellipsis">
Text Editor
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/upgrade/" class="md-nav__link">
<span class="md-ellipsis">
Upgrading
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../container/" class="md-nav__link">
<span class="md-ellipsis">
Docker Containers
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-ellipsis">
Networking
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Networking
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../networking/" class="md-nav__link">
<span class="md-ellipsis">
Network Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../qos/" class="md-nav__link">
<span class="md-ellipsis">
Quality of Service
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../eth-counters/" class="md-nav__link">
<span class="md-ellipsis">
RMON Counters
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tunnels/" class="md-nav__link">
<span class="md-ellipsis">
Tunneling (L2/L3)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../wifi/" class="md-nav__link">
<span class="md-ellipsis">
Wireless LAN (WiFi)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-ellipsis">
Services
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Services
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../discovery/" class="md-nav__link">
<span class="md-ellipsis">
Device Discovery
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dhcp/" class="md-nav__link">
<span class="md-ellipsis">
DHCP Server
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
<span class="md-ellipsis">
System
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
System
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../boot/" class="md-nav__link">
<span class="md-ellipsis">
Boot Procedure
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../system/" class="md-nav__link">
<span class="md-ellipsis">
Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../hardware/" class="md-nav__link">
<span class="md-ellipsis">
Hardware Info & Status
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../management/" class="md-nav__link">
<span class="md-ellipsis">
Management
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../syslog/" class="md-nav__link">
<span class="md-ellipsis">
Syslog Support
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../upgrade/" class="md-nav__link">
<span class="md-ellipsis">
Upgrade
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_7" >
<label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="0">
<span class="md-ellipsis">
Scripting
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_7">
<span class="md-nav__icon md-icon"></span>
Scripting
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../scripting/" class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../scripting-sysrepocfg/" class="md-nav__link">
<span class="md-ellipsis">
Legacy Scripting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../scripting-prod/" class="md-nav__link">
<span class="md-ellipsis">
Production Testing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../scripting-restconf/" class="md-nav__link">
<span class="md-ellipsis">
Remote RESTCONF
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_8" checked>
<label class="md-nav__link" for="__nav_8" id="__nav_8_label" tabindex="0">
<span class="md-ellipsis">
Developer's Corner
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_8_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_8">
<span class="md-nav__icon md-icon"></span>
Developer's Corner
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../branding/" class="md-nav__link">
<span class="md-ellipsis">
Branding & Releases
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../developers-guide/" class="md-nav__link">
<span class="md-ellipsis">
Developer's Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../override-package/" class="md-nav__link">
<span class="md-ellipsis">
Developing with Buildroot
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../netboot/" class="md-nav__link">
<span class="md-ellipsis">
Netboot HowTo
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Regression Testing
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Regression Testing
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#modes-of-testing" class="md-nav__link">
<span class="md-ellipsis">
Modes of Testing
</span>
</a>
<nav class="md-nav" aria-label="Modes of Testing">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#virtual-devices" class="md-nav__link">
<span class="md-ellipsis">
Virtual Devices
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#physical-devices" class="md-nav__link">
<span class="md-ellipsis">
Physical Devices
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#make-run-devices" class="md-nav__link">
<span class="md-ellipsis">
make run Devices
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#interactive-usage" class="md-nav__link">
<span class="md-ellipsis">
Interactive Usage
</span>
</a>
<nav class="md-nav" aria-label="Interactive Usage">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#running-subsets-of-tests" class="md-nav__link">
<span class="md-ellipsis">
Running Subsets of Tests
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#connecting-to-infamy" class="md-nav__link">
<span class="md-ellipsis">
Connecting to Infamy
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#connecting-to-a-dut" class="md-nav__link">
<span class="md-ellipsis">
Connecting to a DUT
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#attaching-to-macvlans" class="md-nav__link">
<span class="md-ellipsis">
Attaching to MACVLANs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-the-python-debugger" class="md-nav__link">
<span class="md-ellipsis">
Using the Python Debugger
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#deterministic-topology-mappings" class="md-nav__link">
<span class="md-ellipsis">
Deterministic Topology Mappings
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#deterministic-transport-protocol" class="md-nav__link">
<span class="md-ellipsis">
Deterministic Transport Protocol
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#test-specification" class="md-nav__link">
<span class="md-ellipsis">
Test specification
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#test-development" class="md-nav__link">
<span class="md-ellipsis">
Test Development
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../test-arch/" class="md-nav__link">
<span class="md-ellipsis">
Test System Architecture
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../virtual/" class="md-nav__link">
<span class="md-ellipsis">
Virtual Environments
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../vpd/" class="md-nav__link">
<span class="md-ellipsis">
Vital Product Data (VPD)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../license/" class="md-nav__link">
<span class="md-ellipsis">
Origin & Licensing
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#modes-of-testing" class="md-nav__link">
<span class="md-ellipsis">
Modes of Testing
</span>
</a>
<nav class="md-nav" aria-label="Modes of Testing">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#virtual-devices" class="md-nav__link">
<span class="md-ellipsis">
Virtual Devices
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#physical-devices" class="md-nav__link">
<span class="md-ellipsis">
Physical Devices
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#make-run-devices" class="md-nav__link">
<span class="md-ellipsis">
make run Devices
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#interactive-usage" class="md-nav__link">
<span class="md-ellipsis">
Interactive Usage
</span>
</a>
<nav class="md-nav" aria-label="Interactive Usage">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#running-subsets-of-tests" class="md-nav__link">
<span class="md-ellipsis">
Running Subsets of Tests
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#connecting-to-infamy" class="md-nav__link">
<span class="md-ellipsis">
Connecting to Infamy
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#connecting-to-a-dut" class="md-nav__link">
<span class="md-ellipsis">
Connecting to a DUT
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#attaching-to-macvlans" class="md-nav__link">
<span class="md-ellipsis">
Attaching to MACVLANs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-the-python-debugger" class="md-nav__link">
<span class="md-ellipsis">
Using the Python Debugger
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#deterministic-topology-mappings" class="md-nav__link">
<span class="md-ellipsis">
Deterministic Topology Mappings
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#deterministic-transport-protocol" class="md-nav__link">
<span class="md-ellipsis">
Deterministic Transport Protocol
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#test-specification" class="md-nav__link">
<span class="md-ellipsis">
Test specification
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#test-development" class="md-nav__link">
<span class="md-ellipsis">
Test Development
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<nav class="md-path" aria-label="Navigation" >
<ol class="md-path__list">
<li class="md-path__item">
<a href=".." class="md-path__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-path__item">
<a href="../branding/" class="md-path__link">
<span class="md-ellipsis">
Developer's Corner
</span>
</a>
</li>
</ol>
</nav>
<article class="md-content__inner md-typeset">
<h1 id="regression-testing-with-infamy">Regression Testing with Infamy<a class="headerlink" href="#regression-testing-with-infamy" title="Permanent link">&para;</a></h1>
<p>Infix comes with a test suite that is intended to provide end-to-end
verification of supported features. Generally speaking, this means that
one or more DUTs are configured over NETCONF or RESTCONF; the resulting
network is then black-box tested by injecting and inspecting network
traffic at various points.</p>
<p>This document is intended to be a practical guide on how to run, develop
and debug tests. There is a separate document describing the <a href="../test-arch/">Test
System Architecture</a>.</p>
<h2 id="modes-of-testing">Modes of Testing<a class="headerlink" href="#modes-of-testing" title="Permanent link">&para;</a></h2>
<h3 id="virtual-devices">Virtual Devices<a class="headerlink" href="#virtual-devices" title="Permanent link">&para;</a></h3>
<p>By default, tests are run on a topology made up of virtual Infix nodes
using <a href="https://github.com/wkz/qeneth">Qeneth</a>. To run the full regression test suite: build Infix
for <code>x86_64</code>:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a>$ make x86_64_defconfig
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>...
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a>$ make
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a>...
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>$ make test
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a>...
</code></pre></div>
<h3 id="physical-devices">Physical Devices<a class="headerlink" href="#physical-devices" title="Permanent link">&para;</a></h3>
<p>To run the tests on a preexisting topology from the host's network
namespace, specify the <code>host</code> <code>TEST_MODE</code>:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a>$ make TEST_MODE=host test
<a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a>...
</code></pre></div>
<p>This typically used when testing on physical hardware. By default the
topology will be sourced from <code>/etc/infamy.dot</code>, but this can be
overwritten by setting the <code>TOPOLOGY</code> variable:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a>$ make TEST_MODE=host TOPOLOGY=~/my-topology.dot test
<a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a>...
</code></pre></div>
<h3 id="make-run-devices"><code>make run</code> Devices<a class="headerlink" href="#make-run-devices" title="Permanent link">&para;</a></h3>
<p>Some tests only require a single DUT. These can therefore be run
against an Infix image started from <code>make run</code>. This requires that the
instance is configured to use TAP networking.</p>
<p>When the instance is running, you can open a separate terminal and run
the subset of the test suite that can be mapped to it:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a>$ make TEST_MODE=run test
<a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a>...
</code></pre></div>
<h2 id="interactive-usage">Interactive Usage<a class="headerlink" href="#interactive-usage" title="Permanent link">&para;</a></h2>
<p>When developing and debugging tests, the overhead of repeatedly
setting up and tearing down the test environment can quickly start to
weigh you down. In these situation, you can start an interactive test
environment:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a>$ make test-sh
<a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a>Info: Generating topology
<a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a>Info: Generating node YAML
<a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a>Info: Generating executables
<a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a>Info: Launching dut1
<a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a>Info: Launching dut2
<a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a>Info: Launching dut3
<a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a>Info: Launching dut4
<a id="__codelineno-4-9" name="__codelineno-4-9" href="#__codelineno-4-9"></a>11:42:52 infamy0:test #
</code></pre></div>
<p>The example above uses the default mode (<code>qeneth</code>), but the <code>host</code> and
<code>run</code> modes also support the <code>test-sh</code> target.</p>
<p>It takes a little while to start up, but then we have a shell prompt
inside the container running Infamy. It's a very limited environment,
but it has enough to easily run single tests, connect to the virtual
devices, and <em>step</em> your code.</p>
<h3 id="running-subsets-of-tests">Running Subsets of Tests<a class="headerlink" href="#running-subsets-of-tests" title="Permanent link">&para;</a></h3>
<p>Each test case is a separate executable, which can be run without
arguments:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a>11:42:53 infamy0:test # ./case/infix_dhcp/dhcp_basic.py
</code></pre></div>
<p>To run a suite of tests, e.g., only the DHCP client tests, pass the
suite as an argument to <a href="https://github.com/rical/9pm">9PM</a>:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a>11:42:53 infamy0:test # ./9pm/9pm.py case/infix_dhcp/infix_dhcp.yaml
</code></pre></div>
<p>To run the suite of all tests:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a>11:42:53 infamy0:test # ./9pm/9pm.py case/all.yaml
</code></pre></div>
<h3 id="connecting-to-infamy">Connecting to Infamy<a class="headerlink" href="#connecting-to-infamy" title="Permanent link">&para;</a></h3>
<p>The test system runs in a Docker container, so to get a shell prompt in
<em>another terminal</em> you need to connect to that container. Infamy comes
with a helper script for this:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a>$ ./test/shell
<a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a>11:42:53 infamy0:test #
</code></pre></div>
<p>By default it connect to the latest started Infamy instance. If you for
some reason run multiple instances of Infamy the <code>shell</code> script takes an
optional argument "system", which is the hostname of the container you
want to connect to:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a>$ ./test/shell infamy2
<a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a>11:42:53 infamy2:test #
</code></pre></div>
<h3 id="connecting-to-a-dut">Connecting to a DUT<a class="headerlink" href="#connecting-to-a-dut" title="Permanent link">&para;</a></h3>
<div class="admonition tip">
<p class="admonition-title">Tip</p>
<p>The <code>console</code> script uses <code>telnet</code> to connect to a port forwarded to
<code>localhost</code> by the Docker container. To exit Telnet, use Ctrl-] and
then 'q' followed by enter. This can be customized in <code>~/.telnetrc</code></p>
</div>
<p>All DUTs in a virtual Infamy topology are emulated in Qemu instances
managed by qeneth. If you want to watch what's happening on one of the
target systems, e.g., tail a log file or run <code>tcpdump</code> during the test,
there is another helper script in Infamy for this:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a>$ ./test/console 1
<a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a>Trying 127.0.0.1...
<a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a>Connected to 127.0.0.1.
<a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a>
<a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a>Infix OS — Immutable.Friendly.Secure v23.11.0-226-g0c144da (console)
<a id="__codelineno-10-6" name="__codelineno-10-6" href="#__codelineno-10-6"></a>infix-00-00-00 login: admin
<a id="__codelineno-10-7" name="__codelineno-10-7" href="#__codelineno-10-7"></a>Password:
<a id="__codelineno-10-8" name="__codelineno-10-8" href="#__codelineno-10-8"></a>.-------.
<a id="__codelineno-10-9" name="__codelineno-10-9" href="#__codelineno-10-9"></a>| . . | Infix OS — Immutable.Friendly.Secure
<a id="__codelineno-10-10" name="__codelineno-10-10" href="#__codelineno-10-10"></a>|-. v .-| https://kernelkit.org
<a id="__codelineno-10-11" name="__codelineno-10-11" href="#__codelineno-10-11"></a>&#39;-&#39;---&#39;-&#39;
<a id="__codelineno-10-12" name="__codelineno-10-12" href="#__codelineno-10-12"></a>
<a id="__codelineno-10-13" name="__codelineno-10-13" href="#__codelineno-10-13"></a>Run the command &#39;cli&#39; for interactive OAM
<a id="__codelineno-10-14" name="__codelineno-10-14" href="#__codelineno-10-14"></a>
<a id="__codelineno-10-15" name="__codelineno-10-15" href="#__codelineno-10-15"></a>admin@infix-00-00-00:~$
</code></pre></div>
<p>From here we can observe <code>dut1</code> freely while running tests.</p>
<p>Like the <code>shell</code> script, <code>console</code> takes an optional "system" argument
in case you run multiple instances of Infamy:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a>$ ./test/console 1 infamy2
<a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a>...
</code></pre></div>
<p>You can also connect to the console of a DUT from within a <code>shell</code>:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a>$ ./test/shell
<a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a>11:42:54 infamy0:test # qeneth status
<a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a>11:42:54 infamy0:test # qeneth console dut1
<a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a>login: admin
<a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a>password: *****
<a id="__codelineno-12-6" name="__codelineno-12-6" href="#__codelineno-12-6"></a>admin@infix-00-00-00:~$
</code></pre></div>
<div class="admonition tip">
<p class="admonition-title">Tip</p>
<p>Disconnect from the qeneth console by bringing up the old Telnet
"menu" using Ctrl-], compared to standard Telnet this is the BusyBox
version so you press 'e' + enter instead of 'q' to quit.</p>
</div>
<h3 id="attaching-to-macvlans">Attaching to MACVLANs<a class="headerlink" href="#attaching-to-macvlans" title="Permanent link">&para;</a></h3>
<p>To fully isolate the host's interfaces from one another, many tests
will stack a MACVLAN on an interface, which is then placed in a
separate network namespace.</p>
<p>It is often useful to attach to those namespaces, so that you can
interactively inject traffic into the test setup.</p>
<p>First, connect to the Infamy instance in question:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a>$ ./test/shell
<a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a>11:43:19 infamy0:test #
</code></pre></div>
<p>Then, attach to the MACVLAN namespace by running the <code>nsenter</code> helper
script from the test directory, supplying the base interface name as
the first argument:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a>11:43:19 infamy0:test # ./nsenter d1b
<a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a>11:43:20 infamy0(d1b):test #
</code></pre></div>
<p>By default, an interactive shell is started, but you can also supply
another command:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a>11:43:19 infamy0:test # ./nsenter d1b ip -br addr
<a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a>lo UNKNOWN 127.0.0.1/8 ::1/128
<a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a>iface@if7 UP 10.0.0.1/24 fe80::38d0:88ff:fe77:b7cd/64
</code></pre></div>
<p>You can now freely debug the network activity of your test and the
responses from the DUT.</p>
<h3 id="using-the-python-debugger">Using the Python Debugger<a class="headerlink" href="#using-the-python-debugger" title="Permanent link">&para;</a></h3>
<p>The built in <code>breakpoint()</code> function in Python is very useful when you
want to run a test case to a certain point at which you might want to
interactively inspect either the test's or the device's state.</p>
<p>Simply insert a call to <code>breakpoint()</code> at the point of interest in
your test and run it as normal. Once Python executes the call, it will
drop you into the Python debugger:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a>11:42:58 infamy0:test # ./case/infix_dhcp/dhcp_basic.py
<a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a># Starting (2024-02-10 11:42:59)
<a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a># Probing dut1 on port d1a for IPv6LL mgmt address ...
<a id="__codelineno-16-4" name="__codelineno-16-4" href="#__codelineno-16-4"></a># Connecting to mgmt IP fe80::ff:fe00:0%d1a:830 ...
<a id="__codelineno-16-5" name="__codelineno-16-5" href="#__codelineno-16-5"></a>ok 1 - Initialize
<a id="__codelineno-16-6" name="__codelineno-16-6" href="#__codelineno-16-6"></a>&gt; /home/jocke/src/infix/test/case/infix_dhcp/dhcp_basic.py(44)&lt;module&gt;()
<a id="__codelineno-16-7" name="__codelineno-16-7" href="#__codelineno-16-7"></a>(Pdb)
</code></pre></div>
<p>At this point you have full access to the test's state, but it is also
an opportunity to inspect the state of the DUTs (e.g. via their
console or over SSH).</p>
<p>It is also possible to run a test under Pdb from the get-go, if you
want to setup breakpoints without modifying the source, or simply step
through the code:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a>11:42:58 infamy0:test # python -m pdb case/infix_dhcp/dhcp_basic.py
</code></pre></div>
<h3 id="deterministic-topology-mappings">Deterministic Topology Mappings<a class="headerlink" href="#deterministic-topology-mappings" title="Permanent link">&para;</a></h3>
<p>By default, mappings from logical to physical topologies are not
stable across test case executions. This can be very frustrating when
debugging a failing test, since logical nodes are suffled around
between phyical nodes. In such cases, supplying a <code>PYTHONHASHSEED</code>
variable (set to any 32-bit unsigned integer) when launching the test
environment will make sure that topology mappings are deterministic:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a>$ make PYTHONHASHSEED=0 test-sh
</code></pre></div>
<p>If a seed is not supplied, a random value is chosen. This seed is
logged by the <code>meta/reproducible.py</code> test case when running a test
suite:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a>$ make test
<a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a>Info: Generating topology
<a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a>Info: Generating node YAML
<a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a>Info: Generating executables
<a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a>Info: Launching dut1
<a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-6"></a>Info: Launching dut2
<a id="__codelineno-19-7" name="__codelineno-19-7" href="#__codelineno-19-7"></a>Info: Launching dut3
<a id="__codelineno-19-8" name="__codelineno-19-8" href="#__codelineno-19-8"></a>Info: Launching dut4
<a id="__codelineno-19-9" name="__codelineno-19-9" href="#__codelineno-19-9"></a>9PM - Simplicity is the ultimate sophistication
<a id="__codelineno-19-10" name="__codelineno-19-10" href="#__codelineno-19-10"></a>
<a id="__codelineno-19-11" name="__codelineno-19-11" href="#__codelineno-19-11"></a>Starting test 0002-reproducible.py
<a id="__codelineno-19-12" name="__codelineno-19-12" href="#__codelineno-19-12"></a>2024-05-03 10:40:30 # Starting (2024-05-03 10:40:30)
<a id="__codelineno-19-13" name="__codelineno-19-13" href="#__codelineno-19-13"></a>2024-05-03 10:40:30 # Specify PYTHONHASHSEED=3773822171 to reproduce this test environment
<a id="__codelineno-19-14" name="__codelineno-19-14" href="#__codelineno-19-14"></a>2024-05-03 10:40:30 ok 1 - $PYTHONHASHSEED is set
<a id="__codelineno-19-15" name="__codelineno-19-15" href="#__codelineno-19-15"></a>2024-05-03 10:40:30 # Exiting (2024-05-03 10:40:30)
<a id="__codelineno-19-16" name="__codelineno-19-16" href="#__codelineno-19-16"></a>2024-05-03 10:40:30 1..1
<a id="__codelineno-19-17" name="__codelineno-19-17" href="#__codelineno-19-17"></a>...
</code></pre></div>
<p>This is useful because this value can then be used to rerun a test (or
the whole suite) with identical topology mappings:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a>$ make PYTHONHASHSEED=3773822171 TESTS=case/ietf_system/hostname.py test
</code></pre></div>
<h3 id="deterministic-transport-protocol">Deterministic Transport Protocol<a class="headerlink" href="#deterministic-transport-protocol" title="Permanent link">&para;</a></h3>
<p>By default, the communication transport protocol (NETCONF/RESTCONF) is
chosen randomly. If you supply a <code>PYTHONHASHSEED</code> as described above,
you get the same protocol used for that hash. But if you want to choose
the protocol, add extra arguments to Infamy:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a>$ make INFAMY_EXTRA_ARGS=&quot;--transport=restconf&quot; TESTS=case/ietf_system/hostname.py test
</code></pre></div>
<p>or, when running interactively:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a>$ make test-sh
<a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a>09:08:17 infamy0:test # ./9pm/9pm.py -o&quot;--transport=restconf&quot; case/ietf_system/hostname.py
</code></pre></div>
<h3 id="test-specification">Test specification<a class="headerlink" href="#test-specification" title="Permanent link">&para;</a></h3>
<p>The test specification is automaticly generated from the test cases,
this puts some constraints on the test cases:</p>
<p>All test cases must be written so that it can be understandable with
only the steps so the result can be reproduced manually. E.g., instead
of <code>set ip address on the interface</code> it should be more human readable,
for example:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="n">test</span><span class="o">.</span><span class="n">step</span><span class="p">(</span><span class="s2">&quot;Set IPv4 address on the interface dut:cross&quot;</span><span class="p">)</span>
<a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a><span class="n">test</span><span class="o">.</span><span class="n">step</span><span class="p">(</span><span class="s2">&quot;Verify the IP address is set on dut:cross&quot;</span><span class="p">)</span>
</code></pre></div>
<p>where <em>dut</em>, <em>cross</em> and the IPv4 address could be found inside the
logical topology for the test.</p>
<p>Each test case must begin with the test name followed by a empty line
and the description of the test. For example:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a>&quot;&quot;&quot;
<a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a>Set hostname
<a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a>
<a id="__codelineno-24-4" name="__codelineno-24-4" href="#__codelineno-24-4"></a>Verify that it it possible to change hostname
<a id="__codelineno-24-5" name="__codelineno-24-5" href="#__codelineno-24-5"></a>&quot;&quot;&quot;
</code></pre></div>
<p>The test specifaction can be genererated with:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a>$ make test-spec
<a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a>...
</code></pre></div>
<h3 id="test-development">Test Development<a class="headerlink" href="#test-development" title="Permanent link">&para;</a></h3>
<p>For adding a new test to the automated regression test suite, it's best
to start by reviewing an existing test case.</p>
<p>All tests are located in the <code>infix/test/case</code> repository and are
grouped by the features they verify. For example,
<code>infix/test/case/infix_services</code> contains tests for various Infix
services, such as LLDP and mDNS.</p>
<p>While test grouping is flexible, each test should be placed in a
logically relevant category.</p>
<p>When creating a new test group, add it to <code>infix/test/case/all.yaml</code>, to
enable it to run as a <a href="#running-subsets-of-tests">subset of the test
suite</a>:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a>- name: infix-services
<a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a> suite: infix_services/infix_services.yaml
</code></pre></div>
<p>A new test (e.g., lldp_enable_disable) should be added to the
corresponding test group .yaml file, such as
<code>infix/test/cases/infix_services.yaml</code>:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a>- name: lldp_enable_disable
<a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a> case: lldp_enable_disable/test.py
</code></pre></div>
<p>It is necessary to include the test in
<code>infix/test/case/infix_services/Readme.adoc</code> to ensure proper test
specification generation:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a>include::lldp_enable_disable/Readme.adoc[]
</code></pre></div>
<p>Each test case should have its own directory under,
<code>infix/test/case/infix_services</code>, containing:</p>
<ul>
<li><code>test.py</code> - the test script</li>
<li><code>topology.dot</code> - the logical topology definition.</li>
</ul>
<p>When the <a href="#test-specification">test specification</a> is generated,
<code>topology.svg</code> and <code>Readme.adoc</code> should also be created.</p>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2022-2025 The KernelKit Team
</div>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<div class="md-progress" data-md-component="progress" role="progressbar"></div>
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["toc.follow", "navigation.path", "navigation.instant", "navigation.instant.progress", "navigation.tracking", "navigation.indexes", "search.highlight", "search.share", "content.code.copy", "content.code.annotate", "content.footnote.tooltips"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": {"provider": "mike"}}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
</body>
</html>