1#!/usr/bin/ksh
2#
3#
4# This file and its contents are supplied under the terms of the
5# Common Development and Distribution License ("CDDL"), version 1.0.
6# You may only use this file in accordance with the terms of version
7# 1.0 of the CDDL.
8#
9# A full copy of the text of the CDDL should have accompanied this
10# source.  A copy of the CDDL is also available via the Internet at
11# http://www.illumos.org/license/CDDL.
12#
13
14#
15# Copyright 2021 Oxide Computer Company
16#
17
18unalias -a
19set -o pipefail
20
21pcieadm_arg0="$(basename $0)"
22pcieadm_prog="/usr/lib/pci/pcieadm"
23pcieadm_data="$(dirname $0)/pci"
24pcieadm_exit=0
25pcieadm_tmpfile="/tmp/pcieadmtest.$$"
26
27warn()
28{
29	typeset msg="$*"
30	[[ -z "$msg" ]] && msg="failed"
31	echo "TEST FAILED: $pcieadm_arg0: $msg" >&2
32	pcieadm_exit=1
33}
34
35pcieadm_bad_args()
36{
37	if $pcieadm_prog $@ 2>/dev/null 1>/dev/null; then
38		warn "should have failed with args "$@", but passed"
39		return
40	fi
41
42	printf "TEST PASSED: invalid arguments %s\n" "$*"
43}
44
45pcieadm_validate_output()
46{
47	typeset input="$pcieadm_data/$1"
48	shift
49	typeset outfile="$pcieadm_data/$1"
50	shift
51	typeset expexit=$1
52	shift
53
54	$pcieadm_prog $@ <$input >"$pcieadm_tmpfile" 2>&1
55	if (( $? != expexit)); then
56		warn "$@: mismatched exit status, found $?, expected $expexit"
57	fi
58
59	if ! diff $outfile $pcieadm_tmpfile; then
60		warn "$@: output mismatched"
61	else
62		printf "TEST PASSED: %s\n" "$*"
63	fi
64}
65
66
67if [[ -n $PCIEADM ]]; then
68	pcieadm_prog=$PCIEADM
69fi
70
71#
72# Before we begin execution, set up the environment such that we have a
73# standard locale and that umem will help us catch mistakes.
74#
75export LC_ALL=C.UTF-8
76export LD_PRELOAD=libumem.so
77export UMEM_DEBUG=default
78
79if [[ ! -d $pcieadm_data ]]; then
80	printf "failed to find data directory %s\n" "$pcieadm_data" >&2
81	exit 1
82fi
83
84#
85# First work through bad options.
86#
87pcieadm_bad_args
88pcieadm_bad_args -d
89pcieadm_bad_args foobar
90pcieadm_bad_args save-cfgspace
91pcieadm_bad_args save-cfgspace -a
92pcieadm_bad_args save-cfgspace -d
93pcieadm_bad_args save-cfgspace -d final
94pcieadm_bad_args save-cfgspace -a -d fantasy
95pcieadm_bad_args show-devs -h
96pcieadm_bad_args show-devs -p
97pcieadm_bad_args show-devs -s -o
98pcieadm_bad_args show-cfgspace
99pcieadm_bad_args show-cfgspace -d -H
100pcieadm_bad_args show-cfgspace -d
101pcieadm_bad_args show-cfgspace -f
102pcieadm_bad_args show-cfgspace -h
103pcieadm_bad_args show-cfgspace -L
104pcieadm_bad_args show-cfgspace -L -n -f "$pcieadm_data/igb.pci"
105pcieadm_bad_args show-cfgspace -L -p -f "$pcieadm_data/igb.pci"
106pcieadm_bad_args show-cfgspace -p -f "$pcieadm_data/igb.pci"
107pcieadm_bad_args show-cfgspace -o foo -f "$pcieadm_data/igb.pci"
108pcieadm_bad_args show-cfgspace -L -o foo -f "$pcieadm_data/igb.pci"
109
110#
111# Test different output cases
112#
113pcieadm_validate_output igb.pci header0-basic.out 0 \
114    show-cfgspace -f /dev/stdin header0.vendor header0.device
115pcieadm_validate_output igb.pci header0-basic-L.out 0 \
116    show-cfgspace -L -f /dev/stdin header0.vendor header0.device
117pcieadm_validate_output igb.pci header0-basic-n.out 0 \
118    show-cfgspace -n -f /dev/stdin header0.vendor header0.device
119pcieadm_validate_output igb.pci header0-basic-LH.out 0 \
120    show-cfgspace -L -H -f /dev/stdin header0.vendor header0.device
121
122#
123# Specific filter behavior. We want to validate the following:
124#
125#  o An inexact filter (e.g. a cap or subcap) matches in human mode,
126#    but not parsable.
127#  o An exact filter will show its contents in human mode, but not
128#    parsable.
129#  o A missing filter causes to exit non-zero, but still show what we
130#    found with other filters or because of a prefix match.
131#
132pcieadm_validate_output igb.pci igb-ltr.out 0 \
133    show-cfgspace -f /dev/stdin ltr
134pcieadm_validate_output igb.pci igb-ltr-p.out 1 \
135    show-cfgspace -p -o short,value -f /dev/stdin ltr
136pcieadm_validate_output igb.pci header0-parse.out 0 \
137    show-cfgspace -p -o short,value -f /dev/stdin header0.vendor header0.device
138pcieadm_validate_output bridge.pci bridge-ht.out 0 \
139    show-cfgspace -f /dev/stdin ht
140pcieadm_validate_output bridge.pci bridge-ht.out 0 \
141    show-cfgspace -f /dev/stdin ht.msi
142pcieadm_validate_output bridge.pci bridge-ht.out 0 \
143    show-cfgspace -f /dev/stdin ht.msi.command
144pcieadm_validate_output bridge.pci bridge-ht-p.out 1 \
145    show-cfgspace -p -o value,short -f /dev/stdin ht
146pcieadm_validate_output bridge.pci bridge-ht.msi-p.out 1 \
147    show-cfgspace -p -o value,short -f /dev/stdin ht.msi
148pcieadm_validate_output bridge.pci bridge-ht.msi.command-p.out 0 \
149    show-cfgspace -p -o value,short -f /dev/stdin ht.msi.command
150pcieadm_validate_output bridge.pci bridge-efilt.out 1 \
151    show-cfgspace -f /dev/stdin pcie.linksts atelier
152pcieadm_validate_output bridge.pci bridge-efilt-p.out 1 \
153    show-cfgspace -p -o short,value -f /dev/stdin pcie.linksts atelier
154
155if (( pcieadm_exit == 0 )); then
156	printf "All tests passed successfully!\n"
157fi
158
159rm -f "$pcieadm_tmpfile"
160exit $pcieadm_exit
161