1315320Sngie/*- 2346920Sngie * Copyright (c) 2017 Enji Cooper <ngie@freebsd.org> 3315320Sngie * 4315320Sngie * Redistribution and use in source and binary forms, with or without 5315320Sngie * modification, are permitted provided that the following conditions 6315320Sngie * are met: 7315320Sngie * 1. Redistributions of source code must retain the above copyright 8315320Sngie * notice, this list of conditions and the following disclaimer. 9315320Sngie * 2. Redistributions in binary form must reproduce the above copyright 10315320Sngie * notice, this list of conditions and the following disclaimer in the 11315320Sngie * documentation and/or other materials provided with the distribution. 12315320Sngie * 13315320Sngie * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14315320Sngie * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15315320Sngie * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16315320Sngie * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17315320Sngie * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18315320Sngie * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19315320Sngie * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20315320Sngie * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21315320Sngie * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22315320Sngie * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23315320Sngie * SUCH DAMAGE. 24315320Sngie */ 25315320Sngie 26326782Sasomers/* Tests functions in lib/libcam/camlib.c */ 27326782Sasomers 28321117Sngie#include <sys/cdefs.h> 29321117Sngie__FBSDID("$FreeBSD: stable/11/lib/libcam/tests/libcam_test.c 346920 2019-04-29 19:36:46Z ngie $"); 30321117Sngie 31315320Sngie#include <errno.h> 32315320Sngie#include <fcntl.h> 33315320Sngie#include <stdio.h> 34315320Sngie#include <camlib.h> 35315320Sngie 36315320Sngie#include <atf-c.h> 37315320Sngie 38315320Sngiestatic const char * 39315320Sngieget_cam_test_device(const atf_tc_t *tc) 40315320Sngie{ 41315320Sngie const char *cam_test_device; 42315320Sngie 43315320Sngie cam_test_device = atf_tc_get_config_var(tc, "cam_test_device"); 44315320Sngie 45315320Sngie return (cam_test_device); 46315320Sngie} 47315320Sngie 48315320Sngiestatic void 49315320Sngiecam_clear_error(void) 50315320Sngie{ 51315320Sngie 52315320Sngie strcpy(cam_errbuf, ""); 53315320Sngie} 54315320Sngie 55315320Sngiestatic bool 56315320Sngiecam_has_error(void) 57315320Sngie{ 58315320Sngie 59315320Sngie return (strlen(cam_errbuf) != 0); 60315320Sngie} 61315320Sngie 62321123SngieATF_TC_WITHOUT_HEAD(cam_get_device_negative_test_NULL_path); 63321123SngieATF_TC_BODY(cam_get_device_negative_test_NULL_path, tc) 64321123Sngie{ 65321123Sngie char parsed_dev_name[DEV_IDLEN + 1]; 66321123Sngie int parsed_unit; 67321123Sngie 68321123Sngie ATF_REQUIRE_MSG(cam_get_device(NULL, parsed_dev_name, 69321123Sngie nitems(parsed_dev_name), &parsed_unit) == -1, 70321123Sngie "cam_get_device succeeded unexpectedly"); 71321123Sngie} 72321123Sngie 73321123SngieATF_TC_WITHOUT_HEAD(cam_get_device_negative_test_bad_path); 74321123SngieATF_TC_BODY(cam_get_device_negative_test_bad_path, tc) 75321123Sngie{ 76321123Sngie char parsed_dev_name[DEV_IDLEN + 1]; 77321123Sngie int parsed_unit; 78321123Sngie 79321123Sngie ATF_REQUIRE_MSG(cam_get_device("1ada", parsed_dev_name, 80321123Sngie nitems(parsed_dev_name), &parsed_unit) == -1, 81321123Sngie "cam_get_device succeeded unexpectedly"); 82321123Sngie} 83321123Sngie 84321123SngieATF_TC_WITHOUT_HEAD(cam_get_device_negative_test_nul_path); 85321123SngieATF_TC_BODY(cam_get_device_negative_test_nul_path, tc) 86321123Sngie{ 87321123Sngie char parsed_dev_name[DEV_IDLEN + 1]; 88321123Sngie int parsed_unit; 89321123Sngie 90321123Sngie ATF_REQUIRE_MSG(cam_get_device("", parsed_dev_name, 91321123Sngie nitems(parsed_dev_name), &parsed_unit) == -1, 92321123Sngie "cam_get_device succeeded unexpectedly"); 93321123Sngie} 94321123Sngie 95321123SngieATF_TC_WITHOUT_HEAD(cam_get_device_negative_test_root); 96321123SngieATF_TC_BODY(cam_get_device_negative_test_root, tc) 97321123Sngie{ 98321123Sngie char parsed_dev_name[DEV_IDLEN + 1]; 99321123Sngie int parsed_unit; 100321123Sngie 101321123Sngie ATF_REQUIRE_MSG(cam_get_device("/", parsed_dev_name, 102321123Sngie nitems(parsed_dev_name), &parsed_unit) == -1, 103321123Sngie "cam_get_device succeeded unexpectedly"); 104321123Sngie} 105321123Sngie 106321123SngieATF_TC_WITHOUT_HEAD(cam_get_device_positive_test); 107321123SngieATF_TC_BODY(cam_get_device_positive_test, tc) 108321123Sngie{ 109321123Sngie char expected_dev_name[] = "foo"; 110321123Sngie char parsed_dev_name[DEV_IDLEN + 1]; 111321123Sngie int expected_unit, parsed_unit; 112321123Sngie 113321123Sngie expected_unit = 1; 114321123Sngie 115321123Sngie ATF_REQUIRE_MSG(cam_get_device("/dev/foo1", parsed_dev_name, 116321123Sngie nitems(parsed_dev_name), &parsed_unit) == 0, 117321123Sngie "cam_get_device failed"); 118321123Sngie ATF_REQUIRE_STREQ(parsed_dev_name, expected_dev_name); 119321123Sngie ATF_REQUIRE(parsed_unit == expected_unit); 120321123Sngie 121321123Sngie strcpy(parsed_dev_name, ""); 122321123Sngie parsed_unit = -1; 123321123Sngie 124321123Sngie ATF_REQUIRE_MSG(cam_get_device("foo1", parsed_dev_name, 125321123Sngie nitems(parsed_dev_name), &parsed_unit) == 0, 126321123Sngie "cam_get_device failed"); 127321123Sngie ATF_REQUIRE_STREQ(parsed_dev_name, expected_dev_name); 128321123Sngie ATF_REQUIRE(parsed_unit == expected_unit); 129321123Sngie} 130321123Sngie 131326827Sasomers/* 132326827Sasomers * sa(4) uniquely creates nsa and esa device nodes for non-rewind operations 133326827Sasomers * and eject-on-close operations. cam_get_device must special case these nodes 134326827Sasomers * to always return the base device. 135326827Sasomers */ 136326827SasomersATF_TC_WITHOUT_HEAD(cam_get_device_sa_test); 137326827SasomersATF_TC_BODY(cam_get_device_sa_test, tc) 138326827Sasomers{ 139326827Sasomers char parsed_dev_name[DEV_IDLEN + 1]; 140326827Sasomers int parsed_unit; 141326827Sasomers 142326827Sasomers ATF_REQUIRE_MSG(cam_get_device("nsa99", parsed_dev_name, 143326827Sasomers nitems(parsed_dev_name), &parsed_unit) == 0, 144326827Sasomers "cam_get_device failed"); 145326827Sasomers ATF_REQUIRE_STREQ(parsed_dev_name, "sa"); 146326827Sasomers ATF_REQUIRE(parsed_unit == 99); 147326827Sasomers 148326827Sasomers strcpy(parsed_dev_name, ""); 149326827Sasomers parsed_unit = -1; 150326827Sasomers 151326827Sasomers ATF_REQUIRE_MSG(cam_get_device("esa99", parsed_dev_name, 152326827Sasomers nitems(parsed_dev_name), &parsed_unit) == 0, 153326827Sasomers "cam_get_device failed"); 154326827Sasomers ATF_REQUIRE_STREQ(parsed_dev_name, "sa"); 155326827Sasomers ATF_REQUIRE(parsed_unit == 99); 156326827Sasomers} 157326827Sasomers 158315320SngieATF_TC(cam_open_device_negative_test_O_RDONLY); 159315320SngieATF_TC_HEAD(cam_open_device_negative_test_O_RDONLY, tc) 160315320Sngie{ 161315320Sngie 162315320Sngie atf_tc_set_md_var(tc, "descr", 163315320Sngie "test that cam_open_device(`cam_device`, O_RDONLY) fails to open " 164315320Sngie "the underlying pass(4) device (bug 217649)"); 165315320Sngie atf_tc_set_md_var(tc, "require.config", "cam_test_device"); 166315320Sngie atf_tc_set_md_var(tc, "require.user", "root"); 167315320Sngie} 168315320Sngie 169315320SngieATF_TC_BODY(cam_open_device_negative_test_O_RDONLY, tc) 170315320Sngie{ 171315320Sngie const char *cam_test_device; 172315320Sngie 173315320Sngie cam_test_device = get_cam_test_device(tc); 174315320Sngie 175315320Sngie cam_clear_error(); 176315320Sngie ATF_CHECK(cam_open_device(cam_test_device, O_RDONLY) == NULL); 177315320Sngie ATF_REQUIRE(cam_has_error()); 178315320Sngie} 179315320Sngie 180315320SngieATF_TC(cam_open_device_negative_test_nonexistent); 181315320SngieATF_TC_HEAD(cam_open_device_negative_test_nonexistent, tc) 182315320Sngie{ 183315320Sngie 184315320Sngie atf_tc_set_md_var(tc, "require.user", "root"); 185315320Sngie} 186315320Sngie 187315320SngieATF_TC_BODY(cam_open_device_negative_test_nonexistent, tc) 188315320Sngie{ 189315320Sngie 190315320Sngie cam_clear_error(); 191315320Sngie ATF_REQUIRE(cam_open_device("/nonexistent", O_RDWR) == NULL); 192315320Sngie ATF_REQUIRE(cam_has_error()); 193315320Sngie} 194315320Sngie 195315320SngieATF_TC(cam_open_device_negative_test_unprivileged); 196315320SngieATF_TC_HEAD(cam_open_device_negative_test_unprivileged, tc) 197315320Sngie{ 198315320Sngie 199315320Sngie atf_tc_set_md_var(tc, "require.config", "cam_test_device"); 200315320Sngie atf_tc_set_md_var(tc, "require.user", "unprivileged"); 201315320Sngie} 202315320Sngie 203315320SngieATF_TC_BODY(cam_open_device_negative_test_unprivileged, tc) 204315320Sngie{ 205315320Sngie const char *cam_test_device; 206315320Sngie 207315320Sngie cam_test_device = get_cam_test_device(tc); 208315320Sngie 209315320Sngie cam_clear_error(); 210315320Sngie ATF_CHECK(cam_open_device(cam_test_device, O_RDONLY) == NULL); 211315320Sngie ATF_REQUIRE(cam_has_error()); 212315320Sngie 213315320Sngie cam_clear_error(); 214315320Sngie ATF_CHECK(cam_open_device(cam_test_device, O_RDWR) == NULL); 215315320Sngie ATF_REQUIRE(cam_has_error()); 216315320Sngie} 217315320Sngie 218315320SngieATF_TC(cam_open_device_positive_test); 219315320SngieATF_TC_HEAD(cam_open_device_positive_test, tc) 220315320Sngie{ 221315320Sngie 222315320Sngie atf_tc_set_md_var(tc, "require.config", "cam_test_device"); 223315320Sngie atf_tc_set_md_var(tc, "require.user", "root"); 224315320Sngie} 225315320Sngie 226315320SngieATF_TC_BODY(cam_open_device_positive_test, tc) 227315320Sngie{ 228315320Sngie struct cam_device *cam_dev; 229315320Sngie const char *cam_test_device; 230315320Sngie 231315320Sngie cam_test_device = get_cam_test_device(tc); 232315320Sngie 233315320Sngie cam_clear_error(); 234315320Sngie cam_dev = cam_open_device(cam_test_device, O_RDWR); 235315320Sngie ATF_CHECK_MSG(cam_dev != NULL, "cam_open_device failed: %s", 236315320Sngie cam_errbuf); 237315320Sngie ATF_REQUIRE(!cam_has_error()); 238315320Sngie cam_close_device(cam_dev); 239315320Sngie} 240315320Sngie 241315320SngieATF_TC(cam_close_device_negative_test_NULL); 242315320SngieATF_TC_HEAD(cam_close_device_negative_test_NULL, tc) 243315320Sngie{ 244315320Sngie 245315320Sngie atf_tc_set_md_var(tc, "descr", 246315320Sngie "test that cam_close_device(NULL) succeeds without error"); 247315320Sngie atf_tc_set_md_var(tc, "require.user", "root"); 248315320Sngie} 249315320Sngie 250315320SngieATF_TC_BODY(cam_close_device_negative_test_NULL, tc) 251315320Sngie{ 252315320Sngie 253315320Sngie cam_clear_error(); 254315320Sngie cam_close_device(NULL); 255315320Sngie ATF_REQUIRE(!cam_has_error()); 256315320Sngie} 257315320Sngie 258315320SngieATF_TC(cam_getccb_positive_test); 259315320SngieATF_TC_HEAD(cam_getccb_positive_test, tc) 260315320Sngie{ 261315320Sngie 262315320Sngie atf_tc_set_md_var(tc, "require.config", "cam_test_device"); 263315320Sngie atf_tc_set_md_var(tc, "require.user", "root"); 264315320Sngie} 265315320Sngie 266315320SngieATF_TC_BODY(cam_getccb_positive_test, tc) 267315320Sngie{ 268315320Sngie union ccb *cam_ccb; 269315320Sngie struct cam_device *cam_dev; 270315320Sngie const char *cam_test_device; 271315320Sngie 272315320Sngie cam_test_device = get_cam_test_device(tc); 273315320Sngie 274315320Sngie cam_clear_error(); 275315320Sngie cam_dev = cam_open_device(cam_test_device, O_RDWR); 276315320Sngie ATF_CHECK_MSG(cam_dev != NULL, "cam_open_device failed: %s", 277315320Sngie cam_errbuf); 278315320Sngie ATF_REQUIRE(!cam_has_error()); 279315320Sngie cam_ccb = cam_getccb(cam_dev); 280315320Sngie ATF_CHECK_MSG(cam_ccb != NULL, "get_camccb failed: %s", cam_errbuf); 281315320Sngie ATF_REQUIRE(!cam_has_error()); 282315320Sngie cam_freeccb(cam_ccb); 283315320Sngie cam_close_device(cam_dev); 284315320Sngie} 285315320Sngie 286315320SngieATF_TC(cam_freeccb_negative_test_NULL); 287315320SngieATF_TC_HEAD(cam_freeccb_negative_test_NULL, tc) 288315320Sngie{ 289315320Sngie 290315320Sngie atf_tc_set_md_var(tc, "descr", 291315320Sngie "test that cam_freeccb(NULL) succeeds without error"); 292315320Sngie atf_tc_set_md_var(tc, "require.user", "root"); 293315320Sngie} 294315320Sngie 295315320SngieATF_TC_BODY(cam_freeccb_negative_test_NULL, tc) 296315320Sngie{ 297315320Sngie 298315320Sngie cam_clear_error(); 299315320Sngie cam_freeccb(NULL); 300315320Sngie ATF_REQUIRE(!cam_has_error()); 301315320Sngie} 302315320Sngie 303315320SngieATF_TP_ADD_TCS(tp) 304315320Sngie{ 305315320Sngie 306321123Sngie ATF_TP_ADD_TC(tp, cam_get_device_negative_test_NULL_path); 307321123Sngie ATF_TP_ADD_TC(tp, cam_get_device_negative_test_bad_path); 308321123Sngie ATF_TP_ADD_TC(tp, cam_get_device_negative_test_nul_path); 309321123Sngie ATF_TP_ADD_TC(tp, cam_get_device_negative_test_root); 310321123Sngie ATF_TP_ADD_TC(tp, cam_get_device_positive_test); 311326827Sasomers ATF_TP_ADD_TC(tp, cam_get_device_sa_test); 312315320Sngie ATF_TP_ADD_TC(tp, cam_open_device_negative_test_O_RDONLY); 313315320Sngie ATF_TP_ADD_TC(tp, cam_open_device_negative_test_nonexistent); 314315320Sngie ATF_TP_ADD_TC(tp, cam_open_device_negative_test_unprivileged); 315315320Sngie ATF_TP_ADD_TC(tp, cam_open_device_positive_test); 316315320Sngie ATF_TP_ADD_TC(tp, cam_close_device_negative_test_NULL); 317315320Sngie ATF_TP_ADD_TC(tp, cam_getccb_positive_test); 318315320Sngie ATF_TP_ADD_TC(tp, cam_freeccb_negative_test_NULL); 319315320Sngie 320315320Sngie return (atf_no_error()); 321315320Sngie} 322