2014-02-21 13:59:10 +04:00
/*
* Copyright ( C ) 2014 Red Hat , Inc .
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library . If not , see
* < http : //www.gnu.org/licenses/>.
*/
# include <config.h>
2014-03-21 15:14:12 +04:00
# include "testutils.h"
2014-02-21 13:59:10 +04:00
# ifdef WIN32
int
main ( void )
{
return EXIT_AM_SKIP ;
}
# else
2018-12-13 17:53:50 +03:00
# define LIBVIRT_VIRCOMMANDPRIV_H_ALLOW
2014-02-21 13:59:10 +04:00
# include "vircommandpriv.h"
# include "viriscsi.h"
# define VIR_FROM_THIS VIR_FROM_NONE
static const char * iscsiadmSessionOutput =
" tcp: [1] 10.20.30.40:3260,1 iqn.2004-06.example:example1:iscsi.test \n "
" tcp: [2] 10.20.30.41:3260,1 iqn.2005-05.example:example1:iscsi.hello \n "
" tcp: [3] 10.20.30.42:3260,1 iqn.2006-04.example:example1:iscsi.world \n "
" tcp: [5] 10.20.30.43:3260,1 iqn.2007-04.example:example1:iscsi.foo \n "
" tcp: [6] 10.20.30.44:3260,1 iqn.2008-04.example:example1:iscsi.bar \n "
" tcp: [7] 10.20.30.45:3260,1 iqn.2009-04.example:example1:iscsi.seven \n " ;
static const char * iscsiadmSessionOutputNonFlash =
" tcp: [1] 10.20.30.40:3260,1 iqn.2004-06.example:example1:iscsi.test (non-flash) \n "
" tcp: [2] 10.20.30.41:3260,1 iqn.2005-05.example:example1:iscsi.hello (non-flash) \n "
" tcp: [3] 10.20.30.42:3260,1 iqn.2006-04.example:example1:iscsi.world (non-flash) \n "
" tcp: [5] 10.20.30.43:3260,1 iqn.2007-04.example:example1:iscsi.foo (non-flash) \n "
" tcp: [6] 10.20.30.44:3260,1 iqn.2008-04.example:example1:iscsi.bar (non-flash) \n "
" tcp: [7] 10.20.30.45:3260,1 iqn.2009-04.example:example1:iscsi.seven (non-flash) \n " ;
2014-03-19 17:02:09 +04:00
const char * iscsiadmSendtargetsOutput =
" 10.20.30.40:3260,1 iqn.2004-06.example:example1:iscsi.test \n "
" 10.20.30.40:3260,1 iqn.2005-05.example:example1:iscsi.hello \n "
" 10.20.30.40:3260,1 iqn.2006-04.example:example1:iscsi.world \n "
" 10.20.30.40:3260,1 iqn.2007-04.example:example1:iscsi.foo \n "
" 10.20.30.40:3260,1 iqn.2008-04.example:example1:iscsi.bar \n "
" 10.20.30.40:3260,1 iqn.2009-04.example:example1:iscsi.seven \n " ;
2018-07-04 11:41:54 +03:00
const char * iscsiadmIfaceDefaultOutput =
" default tcp,<empty>,<empty>,<empty>,<empty> \n "
" iser iser,<empty>,<empty>,<empty>,<empty> \n " ;
const char * iscsiadmIfaceIfaceOutput =
" default tcp,<empty>,<empty>,<empty>,<empty> \n "
" iser iser,<empty>,<empty>,<empty>,<empty> \n "
" libvirt-iface-03020100 tcp,<empty>,<empty>,<empty>,iqn.2004-06.example:example1:initiator \n " ;
2018-07-04 11:47:07 +03:00
struct testIscsiadmCbData {
bool output_version ;
2018-07-04 11:41:54 +03:00
bool iface_created ;
2018-07-04 11:47:07 +03:00
} ;
2014-02-21 13:59:10 +04:00
static void testIscsiadmCb ( const char * const * args ,
const char * const * env ATTRIBUTE_UNUSED ,
const char * input ATTRIBUTE_UNUSED ,
char * * output ,
char * * error ATTRIBUTE_UNUSED ,
int * status ,
void * opaque )
{
2018-07-04 11:47:07 +03:00
struct testIscsiadmCbData * data = opaque ;
2014-02-21 13:59:10 +04:00
if ( args [ 0 ] & & STREQ ( args [ 0 ] , ISCSIADM ) & &
args [ 1 ] & & STREQ ( args [ 1 ] , " --mode " ) & &
args [ 2 ] & & STREQ ( args [ 2 ] , " session " ) & &
args [ 3 ] = = NULL ) {
2018-07-04 11:47:07 +03:00
if ( data - > output_version )
2014-02-21 13:59:10 +04:00
ignore_value ( VIR_STRDUP ( * output , iscsiadmSessionOutputNonFlash ) ) ;
else
ignore_value ( VIR_STRDUP ( * output , iscsiadmSessionOutput ) ) ;
2014-03-19 17:02:09 +04:00
} else if ( args [ 0 ] & & STREQ ( args [ 0 ] , ISCSIADM ) & &
args [ 1 ] & & STREQ ( args [ 1 ] , " --mode " ) & &
args [ 2 ] & & STREQ ( args [ 2 ] , " discovery " ) & &
args [ 3 ] & & STREQ ( args [ 3 ] , " --type " ) & &
args [ 4 ] & & STREQ ( args [ 4 ] , " sendtargets " ) & &
args [ 5 ] & & STREQ ( args [ 5 ] , " --portal " ) & &
args [ 6 ] & & STREQ ( args [ 6 ] , " 10.20.30.40:3260,1 " ) & &
2016-05-13 18:19:09 +03:00
args [ 7 ] & & STREQ ( args [ 7 ] , " --op " ) & &
args [ 8 ] & & STREQ ( args [ 8 ] , " nonpersistent " ) & &
args [ 9 ] = = NULL ) {
2014-03-19 17:02:09 +04:00
ignore_value ( VIR_STRDUP ( * output , iscsiadmSendtargetsOutput ) ) ;
2018-07-04 11:08:48 +03:00
} else if ( args [ 0 ] & & STREQ ( args [ 0 ] , ISCSIADM ) & &
args [ 1 ] & & STREQ ( args [ 1 ] , " --mode " ) & &
args [ 2 ] & & STREQ ( args [ 2 ] , " node " ) & &
args [ 3 ] & & STREQ ( args [ 3 ] , " --portal " ) & &
args [ 4 ] & & STREQ ( args [ 4 ] , " 10.20.30.40:3260,1 " ) & &
args [ 5 ] & & STREQ ( args [ 5 ] , " --targetname " ) & &
args [ 6 ] & & STREQ ( args [ 6 ] , " iqn.2004-06.example:example1:iscsi.test " ) & &
args [ 7 ] & & STREQ ( args [ 7 ] , " --login " ) & &
args [ 8 ] = = NULL ) {
/* Mocking real environment output is not needed for now.
* Example output from real environment :
*
* Logging in to [ iface : default , \
* target : iqn .2004 - 06. example : example1 : iscsi . test , \
* portal : 10.20 .30 .40 : 3260 , 1 ] ( multiple )
* Login to [ iface : default , \
* target : iqn .2004 - 06. example : example1 : iscsi . test , \
* portal : 10.20 .30 .40 : 3260 , 1 ] successful .
*/
2018-07-04 11:41:54 +03:00
} else if ( args [ 0 ] & & STREQ ( args [ 0 ] , ISCSIADM ) & &
args [ 1 ] & & STREQ ( args [ 1 ] , " --mode " ) & &
args [ 2 ] & & STREQ ( args [ 2 ] , " iface " ) & &
args [ 3 ] = = NULL ) {
if ( data - > iface_created )
ignore_value ( VIR_STRDUP ( * output , iscsiadmIfaceIfaceOutput ) ) ;
else
ignore_value ( VIR_STRDUP ( * output , iscsiadmIfaceDefaultOutput ) ) ;
} else if ( args [ 0 ] & & STREQ ( args [ 0 ] , ISCSIADM ) & &
args [ 1 ] & & STREQ ( args [ 1 ] , " --mode " ) & &
args [ 2 ] & & STREQ ( args [ 2 ] , " iface " ) & &
args [ 3 ] & & STREQ ( args [ 3 ] , " --interface " ) & &
args [ 4 ] & & STREQ ( args [ 4 ] , " libvirt-iface-03020100 " ) & &
args [ 5 ] & & STREQ ( args [ 5 ] , " --op " ) & &
args [ 6 ] & & STREQ ( args [ 6 ] , " new " ) & &
args [ 7 ] = = NULL ) {
/* Mocking real environment output is not needed for now.
* Example output from real environment :
*
* New interface libvirt - iface - 03020100 added
*/
data - > iface_created = true ;
} else if ( args [ 0 ] & & STREQ ( args [ 0 ] , ISCSIADM ) & &
args [ 1 ] & & STREQ ( args [ 1 ] , " --mode " ) & &
args [ 2 ] & & STREQ ( args [ 2 ] , " iface " ) & &
args [ 3 ] & & STREQ ( args [ 3 ] , " --interface " ) & &
args [ 4 ] & & STREQ ( args [ 4 ] , " libvirt-iface-03020100 " ) & &
args [ 5 ] & & STREQ ( args [ 5 ] , " --op " ) & &
args [ 6 ] & & STREQ ( args [ 6 ] , " update " ) & &
args [ 7 ] & & STREQ ( args [ 7 ] , " --name " ) & &
args [ 8 ] & & STREQ ( args [ 8 ] , " iface.initiatorname " ) & &
args [ 9 ] & & STREQ ( args [ 9 ] , " --value " ) & &
args [ 10 ] & & STREQ ( args [ 10 ] , " iqn.2004-06.example:example1:initiator " ) & &
args [ 11 ] = = NULL & &
data - > iface_created ) {
/* Mocking real environment output is not needed for now.
* Example output from real environment :
*
* libvirt - iface - 03020100 updated .
*/
} else if ( args [ 0 ] & & STREQ ( args [ 0 ] , ISCSIADM ) & &
args [ 1 ] & & STREQ ( args [ 1 ] , " --mode " ) & &
args [ 2 ] & & STREQ ( args [ 2 ] , " discovery " ) & &
args [ 3 ] & & STREQ ( args [ 3 ] , " --type " ) & &
args [ 4 ] & & STREQ ( args [ 4 ] , " sendtargets " ) & &
args [ 5 ] & & STREQ ( args [ 5 ] , " --portal " ) & &
args [ 6 ] & & STREQ ( args [ 6 ] , " 10.20.30.40:3260,1 " ) & &
args [ 7 ] & & STREQ ( args [ 7 ] , " --interface " ) & &
args [ 8 ] & & STREQ ( args [ 8 ] , " libvirt-iface-03020100 " ) & &
args [ 9 ] = = NULL & &
data - > iface_created ) {
ignore_value ( VIR_STRDUP ( * output , iscsiadmSendtargetsOutput ) ) ;
} else if ( args [ 0 ] & & STREQ ( args [ 0 ] , ISCSIADM ) & &
args [ 1 ] & & STREQ ( args [ 1 ] , " --mode " ) & &
args [ 2 ] & & STREQ ( args [ 2 ] , " node " ) & &
args [ 3 ] & & STREQ ( args [ 3 ] , " --portal " ) & &
args [ 4 ] & & STREQ ( args [ 4 ] , " 10.20.30.40:3260,1 " ) & &
args [ 5 ] & & STREQ ( args [ 5 ] , " --targetname " ) & &
args [ 6 ] & & STREQ ( args [ 6 ] , " iqn.2004-06.example:example1:iscsi.test " ) & &
args [ 7 ] & & STREQ ( args [ 7 ] , " --login " ) & &
args [ 8 ] & & STREQ ( args [ 8 ] , " --interface " ) & &
args [ 9 ] & & STREQ ( args [ 9 ] , " libvirt-iface-03020100 " ) & &
args [ 10 ] = = NULL & &
data - > iface_created ) {
/* Mocking real environment output is not needed for now.
* Example output from real environment :
*
* Logging in to [ iface : libvirt - iface - 03020100 , \
* target : iqn .2004 - 06. example : example1 : iscsi . test , \
* portal : 10.20 .30 .40 : 3260 , 1 ] ( multiple )
* Login to [ iface : libvirt - iface - 03020100 , \
* target : iqn .2004 - 06. example : example1 : iscsi . test , \
* portal : 10.20 .30 .40 : 3260 , 1 ] successful .
*/
2014-02-21 13:59:10 +04:00
} else {
* status = - 1 ;
}
}
2018-07-04 11:43:36 +03:00
struct testSessionInfo {
const char * device_path ;
2018-07-04 11:47:07 +03:00
bool output_version ;
2018-07-04 11:43:36 +03:00
const char * expected_session ;
} ;
2014-02-21 13:59:10 +04:00
static int
testISCSIGetSession ( const void * data )
{
const struct testSessionInfo * info = data ;
2018-07-04 11:47:07 +03:00
struct testIscsiadmCbData cbData = { 0 } ;
2014-02-21 13:59:10 +04:00
char * actual_session = NULL ;
int ret = - 1 ;
2018-07-04 11:47:07 +03:00
cbData . output_version = info - > output_version ;
virCommandSetDryRun ( NULL , testIscsiadmCb , & cbData ) ;
2014-02-21 13:59:10 +04:00
actual_session = virISCSIGetSession ( info - > device_path , true ) ;
if ( STRNEQ_NULLABLE ( actual_session , info - > expected_session ) ) {
virReportError ( VIR_ERR_INTERNAL_ERROR ,
" Expected session: '%s' got: '%s' " ,
NULLSTR ( info - > expected_session ) ,
NULLSTR ( actual_session ) ) ;
goto cleanup ;
}
ret = 0 ;
2014-03-25 10:53:44 +04:00
cleanup :
2014-02-21 13:59:10 +04:00
virCommandSetDryRun ( NULL , NULL , NULL ) ;
VIR_FREE ( actual_session ) ;
return ret ;
}
2014-03-19 17:02:09 +04:00
struct testScanTargetsInfo {
const char * fake_cmd_output ;
const char * portal ;
const char * * expected_targets ;
size_t nexpected ;
} ;
static int
testISCSIScanTargets ( const void * data )
{
const struct testScanTargetsInfo * info = data ;
size_t ntargets = 0 ;
char * * targets = NULL ;
int ret = - 1 ;
size_t i ;
virCommandSetDryRun ( NULL , testIscsiadmCb , NULL ) ;
2018-06-29 17:18:23 +03:00
if ( virISCSIScanTargets ( info - > portal , NULL ,
false , & ntargets , & targets ) < 0 )
2014-03-19 17:02:09 +04:00
goto cleanup ;
if ( info - > nexpected ! = ntargets ) {
virReportError ( VIR_ERR_INTERNAL_ERROR ,
" Expected %zu targets, got %zu " ,
info - > nexpected , ntargets ) ;
goto cleanup ;
}
for ( i = 0 ; i < ntargets ; i + + ) {
if ( STRNEQ ( info - > expected_targets [ i ] , targets [ i ] ) ) {
virReportError ( VIR_ERR_INTERNAL_ERROR ,
" Expected target '%s', got '%s' " ,
info - > expected_targets [ i ] , targets [ i ] ) ;
goto cleanup ;
}
}
ret = 0 ;
2014-03-25 10:53:44 +04:00
cleanup :
2014-03-19 17:02:09 +04:00
virCommandSetDryRun ( NULL , NULL , NULL ) ;
for ( i = 0 ; i < ntargets ; i + + )
VIR_FREE ( targets [ i ] ) ;
VIR_FREE ( targets ) ;
return ret ;
}
2018-07-04 11:08:48 +03:00
struct testConnectionInfoLogin {
const char * portal ;
const char * initiatoriqn ;
const char * target ;
} ;
static int
testISCSIConnectionLogin ( const void * data )
{
const struct testConnectionInfoLogin * info = data ;
2018-07-04 11:41:54 +03:00
struct testIscsiadmCbData cbData = { 0 } ;
2018-07-04 11:08:48 +03:00
int ret = - 1 ;
2018-07-04 11:41:54 +03:00
virCommandSetDryRun ( NULL , testIscsiadmCb , & cbData ) ;
2018-07-04 11:08:48 +03:00
if ( virISCSIConnectionLogin ( info - > portal , info - > initiatoriqn , info - > target ) < 0 )
goto cleanup ;
ret = 0 ;
cleanup :
virCommandSetDryRun ( NULL , NULL , NULL ) ;
return ret ;
}
2014-02-21 13:59:10 +04:00
static int
mymain ( void )
{
int rv = 0 ;
2017-11-03 15:09:47 +03:00
# define DO_SESSION_TEST(name, session) \
do { \
2018-07-04 11:47:07 +03:00
struct testSessionInfo info = { name , false , session } ; \
2017-11-03 15:09:47 +03:00
if ( virTestRun ( " ISCSI get session test " name , \
testISCSIGetSession , & info ) < 0 ) \
rv = - 1 ; \
2018-07-04 11:47:07 +03:00
info . output_version = true ; \
2017-11-03 15:09:47 +03:00
if ( virTestRun ( " ISCSI get (non-flash) session test " name , \
testISCSIGetSession , & info ) < 0 ) \
rv = - 1 ; \
2014-02-21 13:59:10 +04:00
} while ( 0 )
DO_SESSION_TEST ( " iqn.2004-06.example:example1:iscsi.test " , " 1 " ) ;
DO_SESSION_TEST ( " iqn.2009-04.example:example1:iscsi.seven " , " 7 " ) ;
DO_SESSION_TEST ( " iqn.2009-04.example:example1:iscsi.eight " , NULL ) ;
2014-03-19 17:02:09 +04:00
const char * targets [ ] = {
" iqn.2004-06.example:example1:iscsi.test " ,
" iqn.2005-05.example:example1:iscsi.hello " ,
" iqn.2006-04.example:example1:iscsi.world " ,
" iqn.2007-04.example:example1:iscsi.foo " ,
" iqn.2008-04.example:example1:iscsi.bar " ,
" iqn.2009-04.example:example1:iscsi.seven "
} ;
struct testScanTargetsInfo infoTargets = {
. fake_cmd_output = " iscsiadm_sendtargets " ,
. portal = " 10.20.30.40:3260,1 " ,
. expected_targets = targets ,
. nexpected = ARRAY_CARDINALITY ( targets ) ,
} ;
2016-05-26 18:01:50 +03:00
if ( virTestRun ( " ISCSI scan targets " , testISCSIScanTargets , & infoTargets ) < 0 )
2014-03-19 17:02:09 +04:00
rv = - 1 ;
2018-07-04 11:08:48 +03:00
# define DO_LOGIN_TEST(portal, iqn, target) \
do { \
struct testConnectionInfoLogin info = { portal , iqn , target } ; \
if ( virTestRun ( " ISCSI login " portal , \
testISCSIConnectionLogin , & info ) < 0 ) \
rv = - 1 ; \
} while ( 0 )
DO_LOGIN_TEST ( " 10.20.30.40:3260,1 " , NULL , " iqn.2004-06.example:example1:iscsi.test " ) ;
2018-07-04 11:41:54 +03:00
DO_LOGIN_TEST ( " 10.20.30.40:3260,1 " , " iqn.2004-06.example:example1:initiator " ,
" iqn.2004-06.example:example1:iscsi.test " ) ;
2018-07-04 11:08:48 +03:00
2014-02-21 13:59:10 +04:00
if ( rv < 0 )
return EXIT_FAILURE ;
return EXIT_SUCCESS ;
}
2018-07-04 11:41:54 +03:00
VIR_TEST_MAIN_PRELOAD ( mymain ,
abs_builddir " /.libs/virrandommock.so " )
2014-02-21 13:59:10 +04:00
# endif /* WIN32 */