 2e4707a0a7
			
		
	
	
		2e4707a0a7
		
	
	
	
	
		
			
			This is used in the tests, too, and was already covered by the build.sh script, but not this README file. Signed-off-by: Vasyl Vavrychuk <vvavrychuk@gmail.com>
		
			
				
	
	
		
			220 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			220 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| Automated hostapd/wpa_supplicant testing with mac80211_hwsim
 | |
| ------------------------------------------------------------
 | |
| 
 | |
| This directory contains testing infrastructure and test cases to run
 | |
| automated tests of full hostapd and wpa_supplicant functionality. This
 | |
| testing is done with the help of mac80211_hwsim which is Linux kernel
 | |
| driver that simulates IEEE 802.11 radios without requiring any
 | |
| additional hardware. This setup most of the hostapd and wpa_supplicant
 | |
| functionality (and large parts of the Linux cfg80211 and mac80211
 | |
| functionality for that matter) to be tested.
 | |
| 
 | |
| mac80211_hwsim is loaded with five simulated radios to allow different
 | |
| device combinations to be tested. wlantest is used analyze raw packets
 | |
| captured through the hwsim0 monitor interface that capture all frames
 | |
| sent on all channels. wlantest is used to store the frames for
 | |
| analysis. Three wpa_supplicant processes are used to control three
 | |
| virtual radios and one hostapd process is used to dynamically control
 | |
| the other two virtual radios. wpa_supplicant/hostapd test functionality
 | |
| is used to verify that data connection (both unicast and broadcast)
 | |
| works between two netdevs.
 | |
| 
 | |
| The python scripts and tools in this directory control test case
 | |
| execution. They interact wpa_supplicant and hostapd through control
 | |
| interfaces to perform the operations. In addition, wlantest_cli is used
 | |
| to verify that operations have been performed correctly and that the
 | |
| network connection works in the expected way.
 | |
| 
 | |
| These test cases are run automatically against the hostap.git commits
 | |
| for regression testing and to help in keeping the hostap.git master
 | |
| branch in stable state. Results from these tests are available here:
 | |
| http://buildbot.w1.fi/hwsim/
 | |
| 
 | |
| 
 | |
| Building binaries for testing
 | |
| -----------------------------
 | |
| 
 | |
| You will need to build (or use already built) components to be
 | |
| tested. These are available in the hostap.git repository and can be
 | |
| built for example as follows:
 | |
| 
 | |
| cd ../../wpa_supplicant
 | |
| cp ../tests/hwsim/example-wpa_supplicant.config .config
 | |
| make clean
 | |
| make
 | |
| cd ../hostapd
 | |
| cp ../tests/hwsim/example-hostapd.config .config
 | |
| make clean
 | |
| make hostapd hostapd_cli hlr_auc_gw
 | |
| cd ../wlantest
 | |
| make clean
 | |
| make
 | |
| 
 | |
| Alternatively, the build.sh script here can be used to run these steps
 | |
| with conditional creation of .config files only if they do not exist.
 | |
| 
 | |
| The test scripts can find the binaries in the locations where they were
 | |
| built. It is also possible to install wlantest_cli somewhere on the path
 | |
| to use pre-built tools.
 | |
| 
 | |
| Please note that some of the configuration parameters used to enable
 | |
| more testing coverage may require development packages that may not be
 | |
| installed by default in many distributions. For example, following
 | |
| Debian/Ubuntu packages are likely to be needed:
 | |
| - binutils-dev
 | |
| - libsqlite3-dev
 | |
| - libpcap-dev
 | |
| 
 | |
| example-setup.txt provides more complete step-by-step example on how a
 | |
| test setup can be built.
 | |
| 
 | |
| 
 | |
| wpaspy
 | |
| ------
 | |
| 
 | |
| The python scripts use wpaspy.py to interact with the wpa_supplicant
 | |
| control interface, but the run-tests.py script adds the (relative)
 | |
| path into the environment so it doesn't need to be installed.
 | |
| 
 | |
| 
 | |
| mac80211_hwsim
 | |
| --------------
 | |
| 
 | |
| mac80211_hwsim kernel module is available from the upstream Linux
 | |
| kernel. Some Linux distributions enable it by default. If that's not the
 | |
| case, you can either enable it in the kernel configuration
 | |
| (CONFIG_MAC80211_HWSIM=m) and rebuild your kernel or use Backports with
 | |
| CPTCFG_MAC80211_HWSIM=m to replace the wireless LAN components in the
 | |
| base kernel.
 | |
| 
 | |
| 
 | |
| sudo
 | |
| ----
 | |
| 
 | |
| Some parts of the testing process requires root privileges. The test
 | |
| scripts are currently using sudo to achieve this. To be able to run the
 | |
| tests, you'll probably want to enable sudo with a timeout to not expire
 | |
| password entry very quickly. For example, use this in the sudoers file:
 | |
| 
 | |
| Defaults        env_reset,timestamp_timeout=180
 | |
| 
 | |
| Or on a dedicated test system, you could even disable password prompting
 | |
| with this in sudoers:
 | |
| 
 | |
| %sudo   ALL=NOPASSWD: ALL
 | |
| 
 | |
| 
 | |
| Other network interfaces
 | |
| ------------------------
 | |
| 
 | |
| Some of the test scripts are still using hardcoded interface names, so
 | |
| the easiest way of making things work is to avoid using other network
 | |
| devices that may use conflicting interface names. For example, unload
 | |
| any wireless LAN driver before running the tests and make sure that
 | |
| wlan0..4 gets assigned as the interface names for the mac80211_hwsim
 | |
| radios. It may also be possible to rename the interface expectations in
 | |
| run-tests.py to allow other names to be used.
 | |
| 
 | |
| Please also note that some commonly enabled tools, like NetworkManager,
 | |
| may end up trying to control new network interfaces automatically. This
 | |
| can result in conflicts with the test scripts and you may need to
 | |
| disable such network services or at least mark the mac80211_hwsim wlan#
 | |
| interfaces as umanaged. As an example, this can be done in
 | |
| /etc/NetworkManager/NetworkManager.conf with following addition:
 | |
| 
 | |
| [keyfile]
 | |
| unmanaged-devices=mac:02:00:00:00:00:00;mac:02:00:00:00:01:00;mac:02:00:00:00:02:00;mac:02:00:00:00:03:00;mac:02:00:00:00:04:00
 | |
| 
 | |
| 
 | |
| Running tests
 | |
| -------------
 | |
| 
 | |
| Simplest way to run a full set of the test cases is by running
 | |
| run-all.sh in tests/hwsim directory. This will use start.sh to load the
 | |
| mac80211_hwsim module and start wpa_supplicant, hostapd, and various
 | |
| test tools. run-tests.sh is then used to run through all the defined
 | |
| test cases and stop.sh to stop the programs and unload the kernel
 | |
| module.
 | |
| 
 | |
| run-all.sh can be used to run the same test cases under different
 | |
| conditions:
 | |
| 
 | |
| # run normal test cases
 | |
| ./run-all.sh
 | |
| 
 | |
| # run normal test cases under valgrind
 | |
| ./run-all.sh valgrind
 | |
| 
 | |
| # run normal test cases with Linux tracing
 | |
| ./run-all.sh trace
 | |
| 
 | |
| # run normal test cases with multi channel support (see details below)
 | |
| ./run-all.sh channels=<num of channels>
 | |
| 
 | |
| run-all.sh directs debug logs into the logs subdirectory (or $LOGDIR if
 | |
| present in the environment). Log file names include the current UNIX
 | |
| timestamp and a postfix to identify the specific log:
 | |
| - *.log0 = wpa_supplicant debug log for the first radio
 | |
| - *.log1 = wpa_supplicant debug log for the second radio
 | |
| - *.log2 = wpa_supplicant debug log for the third radio
 | |
| - *.hostapd = hostapd debug log
 | |
| - hwsim0 = wlantest debug log
 | |
| - hwsim0.pcapng = capture with all frames exchanged during the tests
 | |
| - *.log = debug prints from the test scripts
 | |
| - trace.dat = Linux tracing record (if enabled)
 | |
| - hlr_auc_gw - hlr_auc_gw (EAP-SIM/AKA/AKA' authentication) log
 | |
| - auth_serv - hostapd as RADIUS authentication server log
 | |
| 
 | |
| 
 | |
| For manual testing, ./start.sh can be used to initialize interfaces and
 | |
| programs and run-tests.py to execute one or more test
 | |
| cases. run-tests.py output verbosity can be controlled with -d (more
 | |
| verbose debug output) and -q (less verbose output) on the command
 | |
| line. "-f <module name>" (pointing to file test_<module name>.py) can be
 | |
| used to specify that all test cases from a single file are to be
 | |
| run. Test name as the last command line argument can be specified that a
 | |
| single test case is to be run (e.g., "./run-tests.py ap_pmf_required").
 | |
| 
 | |
| Notice that some tests require the driver to support concurrent
 | |
| operation on multi channels in order to run. These tests will be skipped
 | |
| in case the driver does not support multi channels. To enable support
 | |
| for multi channel, the number of supported channel is passed as an
 | |
| argument to run-all.sh or start.sh
 | |
| 
 | |
| 
 | |
| Adding/modifying test cases
 | |
| ---------------------------
 | |
| 
 | |
| All the test cases are defined in the test_*.py files. These are python
 | |
| scripts that can use the local helper classes to interact with the test
 | |
| components. While various python constructs can be used in the scripts,
 | |
| only a minimal level of python knowledge should really be needed to
 | |
| modify and add new test cases. The easiest starting point for this is
 | |
| likely to take a look at some of the example scripts. When working on a
 | |
| new test, run-tests.py with -d and the test case name on the command
 | |
| line is a convenient way of verifying functionality.
 | |
| 
 | |
| run-tests.py will automatically import all test cases from the test_*.py
 | |
| files in this directory. All functions starting with the "test_" prefix
 | |
| in these files are assumed to be test cases. Each test case is named by
 | |
| the function name following the "test_" prefix.
 | |
| 
 | |
| 
 | |
| Results database
 | |
| ----------------
 | |
| 
 | |
| run-tests.py can be requested to write results from the execution of
 | |
| each test case into an sqlite database. The "-S <path to database>" and
 | |
| "-b <build id>" command line arguments can be used to do that. The
 | |
| database must have been prepared before this, e.g., with following:
 | |
| 
 | |
| cat | sqlite3 /tmp/example.db <<EOF
 | |
| CREATE TABLE results (test,result,run,time,duration,build,commitid);
 | |
| CREATE INDEX results_idx ON results (test);
 | |
| CREATE INDEX results_idx2 ON results (run);
 | |
| CREATE TABLE tests (test,description);
 | |
| CREATE UNIQUE INDEX tests_idx ON tests (test);
 | |
| CREATE TABLE logs (test,run,type,contents);
 | |
| CREATE INDEX logs_idx ON logs (test);
 | |
| CREATE INDEX logs_idx2 ON logs (run);
 | |
| EOF
 |