mirror of
https://git.FreeBSD.org/src.git
synced 2024-10-18 02:19:39 +00:00
sound tests: Add sndstat nvlist ATF test
Sponsored by: The FreeBSD Foundation MFC after: 2 days Reviewed by: dev_submerge.ch, markj Differential Revision: https://reviews.freebsd.org/D45901
This commit is contained in:
parent
c15c9315b2
commit
95eb4b873b
@ -30,6 +30,7 @@ TESTS_SUBDIRS+= netpfil
|
||||
TESTS_SUBDIRS+= opencrypto
|
||||
TESTS_SUBDIRS+= posixshm
|
||||
TESTS_SUBDIRS+= ses
|
||||
TESTS_SUBDIRS+= sound
|
||||
TESTS_SUBDIRS+= sys
|
||||
TESTS_SUBDIRS+= vfs
|
||||
TESTS_SUBDIRS+= vm
|
||||
|
9
tests/sys/sound/Makefile
Normal file
9
tests/sys/sound/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
PACKAGE= tests
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/sys/sound
|
||||
|
||||
ATF_TESTS_C+= sndstat
|
||||
|
||||
LDFLAGS+= -lnv
|
||||
|
||||
.include <bsd.test.mk>
|
214
tests/sys/sound/sndstat.c
Normal file
214
tests/sys/sound/sndstat.c
Normal file
@ -0,0 +1,214 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2024 The FreeBSD Foundation
|
||||
*
|
||||
* This software was developed by Christos Margiolis <christos@FreeBSD.org>
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/sndstat.h>
|
||||
#include <sys/nv.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void
|
||||
load_dummy(void)
|
||||
{
|
||||
if (kldload("snd_dummy.ko") < 0 && errno != EEXIST)
|
||||
atf_tc_skip("snd_dummy.ko not found");
|
||||
}
|
||||
|
||||
ATF_TC(sndstat_nv);
|
||||
ATF_TC_HEAD(sndstat_nv, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "/dev/sndstat nvlist test");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(sndstat_nv, tc)
|
||||
{
|
||||
nvlist_t *nvl;
|
||||
const nvlist_t * const *di;
|
||||
const nvlist_t * const *cdi;
|
||||
struct sndstioc_nv_arg arg;
|
||||
size_t nitems, nchans, i, j;
|
||||
int fd, rc;
|
||||
int pchan, rchan;
|
||||
|
||||
load_dummy();
|
||||
|
||||
if ((fd = open("/dev/sndstat", O_RDONLY)) < 0)
|
||||
atf_tc_skip("/dev/sndstat not found, load sound(4)");
|
||||
|
||||
rc = ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL);
|
||||
ATF_REQUIRE_EQ(rc, 0);
|
||||
|
||||
arg.nbytes = 0;
|
||||
arg.buf = NULL;
|
||||
rc = ioctl(fd, SNDSTIOC_GET_DEVS, &arg);
|
||||
ATF_REQUIRE_EQ_MSG(rc, 0, "ioctl(SNDSTIOC_GET_DEVS#1) failed");
|
||||
|
||||
arg.buf = malloc(arg.nbytes);
|
||||
ATF_REQUIRE(arg.buf != NULL);
|
||||
|
||||
rc = ioctl(fd, SNDSTIOC_GET_DEVS, &arg);
|
||||
ATF_REQUIRE_EQ_MSG(rc, 0, "ioctl(SNDSTIOC_GET_DEVS#2) failed");
|
||||
|
||||
nvl = nvlist_unpack(arg.buf, arg.nbytes, 0);
|
||||
ATF_REQUIRE(nvl != NULL);
|
||||
|
||||
if (nvlist_empty(nvl) || !nvlist_exists(nvl, SNDST_DSPS))
|
||||
atf_tc_skip("no soundcards attached");
|
||||
|
||||
di = nvlist_get_nvlist_array(nvl, SNDST_DSPS, &nitems);
|
||||
for (i = 0; i < nitems; i++) {
|
||||
#define NV(type, item) do { \
|
||||
ATF_REQUIRE_MSG(nvlist_exists(di[i], SNDST_DSPS_ ## item), \
|
||||
"SNDST_DSPS_" #item " does not exist"); \
|
||||
nvlist_get_ ## type (di[i], SNDST_DSPS_ ## item); \
|
||||
} while (0)
|
||||
NV(string, NAMEUNIT);
|
||||
NV(bool, FROM_USER);
|
||||
NV(string, DEVNODE);
|
||||
NV(string, DESC);
|
||||
NV(string, PROVIDER);
|
||||
NV(number, PCHAN);
|
||||
NV(number, RCHAN);
|
||||
#undef NV
|
||||
|
||||
/* Cannot asign using the macro. */
|
||||
pchan = nvlist_get_number(di[i], SNDST_DSPS_PCHAN);
|
||||
rchan = nvlist_get_number(di[i], SNDST_DSPS_RCHAN);
|
||||
|
||||
if (pchan && !nvlist_exists(di[i], SNDST_DSPS_INFO_PLAY))
|
||||
atf_tc_fail("playback channel list empty");
|
||||
if (rchan && !nvlist_exists(di[i], SNDST_DSPS_INFO_REC))
|
||||
atf_tc_fail("recording channel list empty");
|
||||
|
||||
#define NV(type, mode, item) do { \
|
||||
ATF_REQUIRE_MSG(nvlist_exists(nvlist_get_nvlist(di[i], \
|
||||
SNDST_DSPS_INFO_ ## mode), SNDST_DSPS_INFO_ ## item), \
|
||||
"SNDST_DSPS_INFO_" #item " does not exist"); \
|
||||
nvlist_get_ ## type (nvlist_get_nvlist(di[i], \
|
||||
SNDST_DSPS_INFO_ ## mode), SNDST_DSPS_INFO_ ## item); \
|
||||
} while (0)
|
||||
if (pchan) {
|
||||
NV(number, PLAY, MIN_RATE);
|
||||
NV(number, PLAY, MAX_RATE);
|
||||
NV(number, PLAY, FORMATS);
|
||||
NV(number, PLAY, MIN_CHN);
|
||||
NV(number, PLAY, MAX_CHN);
|
||||
}
|
||||
if (rchan) {
|
||||
NV(number, REC, MIN_RATE);
|
||||
NV(number, REC, MAX_RATE);
|
||||
NV(number, REC, FORMATS);
|
||||
NV(number, REC, MIN_CHN);
|
||||
NV(number, REC, MAX_CHN);
|
||||
}
|
||||
#undef NV
|
||||
|
||||
/* XXX Do we need to skip the TC? userdevs won't have this list */
|
||||
if (!nvlist_exists(di[i], SNDST_DSPS_PROVIDER_INFO))
|
||||
continue;
|
||||
|
||||
#define NV(type, item) do { \
|
||||
ATF_REQUIRE_MSG(nvlist_exists(nvlist_get_nvlist(di[i], \
|
||||
SNDST_DSPS_PROVIDER_INFO), SNDST_DSPS_SOUND4_ ## item), \
|
||||
"SNDST_DSPS_SOUND4_" #item " does not exist"); \
|
||||
nvlist_get_ ## type (nvlist_get_nvlist(di[i], \
|
||||
SNDST_DSPS_PROVIDER_INFO), SNDST_DSPS_SOUND4_ ## item); \
|
||||
} while (0)
|
||||
NV(number, UNIT);
|
||||
NV(string, STATUS);
|
||||
NV(bool, BITPERFECT);
|
||||
NV(number, PVCHAN);
|
||||
NV(number, PVCHANRATE);
|
||||
NV(number, PVCHANFORMAT);
|
||||
NV(number, RVCHAN);
|
||||
NV(number, PVCHANRATE);
|
||||
NV(number, PVCHANFORMAT);
|
||||
#undef NV
|
||||
|
||||
if (!nvlist_exists(nvlist_get_nvlist(di[i],
|
||||
SNDST_DSPS_PROVIDER_INFO), SNDST_DSPS_SOUND4_CHAN_INFO))
|
||||
atf_tc_fail("channel info list empty");
|
||||
|
||||
cdi = nvlist_get_nvlist_array(
|
||||
nvlist_get_nvlist(di[i], SNDST_DSPS_PROVIDER_INFO),
|
||||
SNDST_DSPS_SOUND4_CHAN_INFO, &nchans);
|
||||
for (j = 0; j < nchans; j++) {
|
||||
#define NV(type, item) do { \
|
||||
ATF_REQUIRE_MSG(nvlist_exists(cdi[j], SNDST_DSPS_SOUND4_CHAN_ ## item), \
|
||||
"SNDST_DSPS_SOUND4_CHAN_" #item " does not exist"); \
|
||||
nvlist_get_ ## type (cdi[j], SNDST_DSPS_SOUND4_CHAN_ ## item); \
|
||||
} while (0)
|
||||
NV(string, NAME);
|
||||
NV(string, PARENTCHAN);
|
||||
NV(number, UNIT);
|
||||
NV(number, CAPS);
|
||||
NV(number, LATENCY);
|
||||
NV(number, RATE);
|
||||
NV(number, FORMAT);
|
||||
NV(number, PID);
|
||||
NV(string, COMM);
|
||||
NV(number, INTR);
|
||||
NV(number, XRUNS);
|
||||
NV(number, FEEDCNT);
|
||||
NV(number, LEFTVOL);
|
||||
NV(number, RIGHTVOL);
|
||||
NV(number, HWBUF_FORMAT);
|
||||
NV(number, HWBUF_SIZE);
|
||||
NV(number, HWBUF_BLKSZ);
|
||||
NV(number, HWBUF_BLKCNT);
|
||||
NV(number, HWBUF_FREE);
|
||||
NV(number, HWBUF_READY);
|
||||
NV(number, SWBUF_FORMAT);
|
||||
NV(number, SWBUF_SIZE);
|
||||
NV(number, SWBUF_BLKSZ);
|
||||
NV(number, SWBUF_BLKCNT);
|
||||
NV(number, SWBUF_FREE);
|
||||
NV(number, SWBUF_READY);
|
||||
NV(string, FEEDERCHAIN);
|
||||
#undef NV
|
||||
}
|
||||
}
|
||||
|
||||
free(arg.buf);
|
||||
nvlist_destroy(nvl);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, sndstat_nv);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
Loading…
Reference in New Issue
Block a user