1# SPDX-License-Identifier: BSD-2-Clause 2# 3# Copyright (c) 2024 Axcient 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 26# Things that aren't tested due to lack of kernel support: 27# * Creating camsim ports 28# * Creating tpc ports 29# * Creating camtgt ports 30# * Creating umass ports 31 32# TODO 33# * Creating nvmf ports 34# * Creating ha ports 35# * Creating fc ports 36 37# The PGTAG can be any 16-bit number. The only constraint is that each 38# PGTAG,TARGET pair must be globally unique. 39PGTAG=30257 40 41skip_if_ctld() { 42 if service ctld onestatus > /dev/null; then 43 # If ctld is running on this server, let's not interfere. 44 atf_skip "Cannot run this test while ctld is running" 45 fi 46} 47 48cleanup() { 49 driver=$1 50 51 if [ -e port-create.txt ]; then 52 case "$driver" in 53 "ioctl") 54 PORTNUM=`awk '/port:/ {print $2}' port-create.txt` 55 ctladm port -r -d $driver -p $PORTNUM 56 ;; 57 "iscsi") 58 TARGET=`awk '/target:/ {print $2}' port-create.txt` 59 ctladm port -r -d $driver -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target=$TARGET 60 ;; 61 esac 62 fi 63} 64 65atf_test_case create_ioctl cleanup 66create_ioctl_head() 67{ 68 atf_set "descr" "ctladm can create a new ioctl port" 69 atf_set "require.user" "root" 70 atf_set "require.progs" ctladm 71} 72create_ioctl_body() 73{ 74 skip_if_ctld 75 76 atf_check -o save:port-create.txt ctladm port -c -d "ioctl" 77 atf_check egrep -q "Port created successfully" port-create.txt 78 atf_check egrep -q "frontend: *ioctl" port-create.txt 79 atf_check egrep -q "port: *[0-9]+" port-create.txt 80 portnum=`awk '/port:/ {print $2}' port-create.txt` 81 atf_check -o save:portlist.txt ctladm portlist -qf ioctl 82 atf_check egrep -q "$portnum *YES *ioctl *ioctl" portlist.txt 83} 84create_ioctl_cleanup() 85{ 86 cleanup ioctl 87} 88 89atf_test_case remove_ioctl_without_required_args cleanup 90remove_ioctl_without_required_args_head() 91{ 92 atf_set "descr" "ctladm will gracefully fail to remove an ioctl target if required arguments are missing" 93 atf_set "require.user" "root" 94 atf_set "require.progs" ctladm 95} 96remove_ioctl_without_required_args_body() 97{ 98 skip_if_ctld 99 100 atf_check -o save:port-create.txt ctladm port -c -d "ioctl" 101 atf_check egrep -q "Port created successfully" port-create.txt 102 atf_check -s exit:1 -e match:"Missing required argument: port_id" ctladm port -r -d "ioctl" 103} 104remove_ioctl_without_required_args_cleanup() 105{ 106 cleanup ioctl 107} 108 109atf_test_case create_iscsi cleanup 110create_iscsi_head() 111{ 112 atf_set "descr" "ctladm can create a new iscsi port" 113 atf_set "require.user" "root" 114 atf_set "require.progs" ctladm 115 atf_set "require.kmods" "cfiscsi" 116} 117create_iscsi_body() 118{ 119 skip_if_ctld 120 121 TARGET=iqn.2018-10.myhost.create_iscsi 122 atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET" 123 echo "target: $TARGET" >> port-create.txt 124 atf_check egrep -q "Port created successfully" port-create.txt 125 atf_check egrep -q "frontend: *iscsi" port-create.txt 126 atf_check egrep -q "port: *[0-9]+" port-create.txt 127 atf_check -o save:portlist.txt ctladm portlist -qf iscsi 128 # Unlike the ioctl driver, the iscsi driver creates ports in a disabled 129 # state, so the port's lunmap may be set before enabling it. 130 atf_check egrep -q "$portnum *NO *iscsi *iscsi.*$TARGET" portlist.txt 131} 132create_iscsi_cleanup() 133{ 134 cleanup iscsi 135} 136 137atf_test_case create_iscsi_alias cleanup 138create_iscsi_alias_head() 139{ 140 atf_set "descr" "ctladm can create a new iscsi port with a target alias" 141 atf_set "require.user" "root" 142 atf_set "require.progs" ctladm 143 atf_set "require.kmods" "cfiscsi" 144} 145create_iscsi_alias_body() 146{ 147 skip_if_ctld 148 149 TARGET=iqn.2018-10.myhost.create_iscsi_alias 150 ALIAS="foobar" 151 atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET" -O cfiscsi_target_alias="$ALIAS" 152 echo "target: $TARGET" >> port-create.txt 153 atf_check egrep -q "Port created successfully" port-create.txt 154 atf_check egrep -q "frontend: *iscsi" port-create.txt 155 atf_check egrep -q "port: *[0-9]+" port-create.txt 156 atf_check -o save:portlist.txt ctladm portlist -qvf iscsi 157 atf_check egrep -q "cfiscsi_target_alias=$ALIAS" portlist.txt 158} 159create_iscsi_alias_cleanup() 160{ 161 cleanup iscsi 162} 163 164atf_test_case create_iscsi_without_required_args 165create_iscsi_without_required_args_head() 166{ 167 atf_set "descr" "ctladm will gracefully fail to create an iSCSI target if required arguments are missing" 168 atf_set "require.user" "root" 169 atf_set "require.progs" ctladm 170 atf_set "require.kmods" "cfiscsi" 171} 172create_iscsi_without_required_args_body() 173{ 174 skip_if_ctld 175 176 TARGET=iqn.2018-10.myhost.create_iscsi 177 atf_check -s exit:1 -e match:"Missing required argument: cfiscsi_target" ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG 178 atf_check -s exit:1 -e match:"Missing required argument: cfiscsi_portal_group_tag" ctladm port -c -d "iscsi" -O cfiscsi_target=$TARGET 179} 180 181atf_test_case create_ioctl_options cleanup 182create_ioctl_options_head() 183{ 184 atf_set "descr" "ctladm can set options when creating a new ioctl port" 185 atf_set "require.user" "root" 186 atf_set "require.progs" ctladm 187} 188create_ioctl_options_body() 189{ 190 skip_if_ctld 191 192 atf_check -o save:port-create.txt ctladm port -c -d "ioctl" -O pp=101 -O vp=102 193 atf_check egrep -q "Port created successfully" port-create.txt 194 atf_check egrep -q "frontend: *ioctl" port-create.txt 195 atf_check egrep -q "port: *[0-9]+" port-create.txt 196 portnum=`awk '/port:/ {print $2}' port-create.txt` 197 atf_check -o save:portlist.txt ctladm portlist -qf ioctl 198 if ! egrep -q '101[[:space:]]+102' portlist.txt; then 199 ctladm portlist 200 atf_fail "Did not create the port with the specified options" 201 fi 202} 203create_ioctl_options_cleanup() 204{ 205 cleanup ioctl 206} 207 208 209atf_test_case disable_ioctl cleanup 210disable_ioctl_head() 211{ 212 atf_set "descr" "ctladm can disable an ioctl port" 213 atf_set "require.user" "root" 214 atf_set "require.progs" ctladm 215} 216disable_ioctl_body() 217{ 218 skip_if_ctld 219 220 atf_check -o save:port-create.txt ctladm port -c -d "ioctl" 221 portnum=`awk '/port:/ {print $2}' port-create.txt` 222 atf_check -o save:portlist.txt ctladm portlist -qf ioctl 223 atf_check -o ignore ctladm port -o off -p $portnum 224 atf_check -o match:"^$portnum *NO" ctladm portlist -qf ioctl 225} 226disable_ioctl_cleanup() 227{ 228 cleanup ioctl 229} 230 231atf_test_case enable_ioctl cleanup 232enable_ioctl_head() 233{ 234 atf_set "descr" "ctladm can enable an ioctl port" 235 atf_set "require.user" "root" 236 atf_set "require.progs" ctladm 237} 238enable_ioctl_body() 239{ 240 skip_if_ctld 241 242 atf_check -o save:port-create.txt ctladm port -c -d "ioctl" 243 portnum=`awk '/port:/ {print $2}' port-create.txt` 244 atf_check -o save:portlist.txt ctladm portlist -qf ioctl 245 atf_check -o ignore ctladm port -o off -p $portnum 246 atf_check -o ignore ctladm port -o on -p $portnum 247 atf_check -o match:"^$portnum *YES" ctladm portlist -qf ioctl 248} 249enable_ioctl_cleanup() 250{ 251 cleanup ioctl 252} 253 254atf_test_case remove_ioctl 255remove_ioctl_head() 256{ 257 atf_set "descr" "ctladm can remove an ioctl port" 258 atf_set "require.user" "root" 259 atf_set "require.progs" ctladm 260} 261remove_ioctl_body() 262{ 263 skip_if_ctld 264 265 # Specify exact pp and vp to make the post-removal portlist check 266 # unambiguous 267 atf_check -o save:port-create.txt ctladm port -c -d "ioctl" -O pp=10001 -O vp=10002 268 portnum=`awk '/port:/ {print $2}' port-create.txt` 269 atf_check -o save:portlist.txt ctladm portlist -qf ioctl 270 atf_check -o inline:"Port destroyed successfully\n" ctladm port -r -d ioctl -p $portnum 271 # Check that the port was removed. A new port may have been added with 272 # the same ID, so match against the pp and vp numbers, too. 273 if ctladm portlist -qf ioctl | egrep -q "^${portnum} .*10001 *10002"; then 274 ctladm portlist -qf ioctl 275 atf_fail "port was not removed" 276 fi 277} 278 279atf_test_case remove_iscsi 280remove_iscsi_head() 281{ 282 atf_set "descr" "ctladm can remove an iscsi port" 283 atf_set "require.user" "root" 284 atf_set "require.progs" ctladm 285 atf_set "require.kmods" "cfiscsi" 286} 287remove_iscsi_body() 288{ 289 skip_if_ctld 290 291 TARGET=iqn.2018-10.myhost.remove_iscsi 292 atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET" 293 portnum=`awk '/port:/ {print $2}' port-create.txt` 294 atf_check -o save:portlist.txt ctladm portlist -qf iscsi 295 atf_check -o inline:"Port destroyed successfully\n" ctladm port -r -d iscsi -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET" 296 # Check that the port was removed. A new port may have been added with 297 # the same ID, so match against the target and tag, too. 298 PGTAGHEX=0x7631 # PGTAG in hex 299 if ctladm portlist -qf iscsi | egrep -q "^${portnum} .*$PGTAG +[0-9]+ +$TARGET,t,$PGTAGHEX"; then 300 ctladm portlist -qf iscsi 301 atf_fail "port was not removed" 302 fi 303} 304 305atf_test_case remove_iscsi_without_required_args cleanup 306remove_iscsi_without_required_args_head() 307{ 308 atf_set "descr" "ctladm will gracefully fail to remove an iSCSI target if required arguments are missing" 309 atf_set "require.user" "root" 310 atf_set "require.progs" ctladm 311 atf_set "require.kmods" "cfiscsi" 312} 313remove_iscsi_without_required_args_body() 314{ 315 skip_if_ctld 316 317 TARGET=iqn.2018-10.myhost.remove_iscsi_without_required_args 318 atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET" 319 echo "target: $TARGET" >> port-create.txt 320 atf_check -s exit:1 -e match:"Missing required argument: cfiscsi_portal_group_tag" ctladm port -r -d iscsi -O cfiscsi_target="$TARGET" 321 atf_check -s exit:1 -e match:"Missing required argument: cfiscsi_target" ctladm port -r -d iscsi -O cfiscsi_portal_group_tag=$PGTAG 322} 323remove_iscsi_without_required_args_cleanup() 324{ 325 cleanup iscsi 326} 327 328atf_init_test_cases() 329{ 330 atf_add_test_case create_ioctl 331 atf_add_test_case create_iscsi 332 atf_add_test_case create_iscsi_without_required_args 333 atf_add_test_case create_iscsi_alias 334 atf_add_test_case create_ioctl_options 335 atf_add_test_case disable_ioctl 336 atf_add_test_case enable_ioctl 337 atf_add_test_case remove_ioctl 338 atf_add_test_case remove_ioctl_without_required_args 339 atf_add_test_case remove_iscsi 340 atf_add_test_case remove_iscsi_without_required_args 341} 342