1#!/usr/local/bin/bash
2
3ulimit -c unlimited
4
5#####################################################################
6## Lyrics:
7##
8## That script has three parameters:
9##
10##      config_name : it will try to find configuration file
11##                    cfg/config_name.cfg ( optional )
12##                    default config name is 'standard'
13##     time_minutes : run time of script in minutes ( optional )
14##                    default time is 180 minutes
15##    bin_directory : place where binary files like remote-fuser
16##                    etc are located ( mandatory )
17##
18#####################################################################
19
20##  Where we are, who we are?
21##
22SCR_DIR=`dirname $0`
23SCR_DIR=`cd $SCR_DIR; pwd`
24
25SCR_NAME=`basename $0`
26SCR_SNAME=`basename $0 .sh`
27
28##  Loading common things to live
29##
30CMN_SCR="$SCR_DIR/remote_fuser_common.sh"
31if [ ! -f "$CMN_SCR" ]
32then
33    echo "ERROR: Can not stat script '$CMN_SCR' ... exiting"
34    exit 1
35fi
36
37. $CMN_SCR
38
39#####################################################################
40##
41## Simple setup : directory
42##
43## TEST_DIR ---/ USER ---/ HOST ---/ PID ---/ cache_dir /
44##                 |-/ logs           |-/ mount_point /
45##                 |-/ bin            |-/ tmp_dir /
46##                 |-/ depot          |-/ status_file
47##
48## depot - directory with test binaries, just a history
49## bin - test binaries in work
50## status_file - says a lot ... but heart-bot
51##
52#####################################################################
53
54##  Config file
55##
56CFG_DIR=$SCR_DIR/cfg
57if [ ! -d "$CFG_DIR" ]
58then
59    _err_exit "Can not stat directory '$CFG_DIR'"
60fi
61
62####
63##  Here the usage and Arguments processing
64#
65CFG_NAME_DEF="standard"
66CFG_NAME=$CFG_NAME_DEF
67
68RUN_TIME_DEF=180
69RUN_TIME=$RUN_TIME_DEF
70
71BIN_DIR=""
72
73usage ( )
74{
75    cat >&2 <<EOF
76
77This script will test remote_fuser utility. 
78
79Syntax is :
80
81    $SCR_NAME [ config_name ] [ run_time ] binary_directory
82
83Where :
84
85         config_name - name of config to use. 
86                       String. Optional. Default "$CFG_NAME_DEF"
87            run_time - time to run script.
88                       Integer. Optional. Default "$RUN_TIME_DEF"
89    binary_directory - directory which contains executables, like
90                       remote-fuser, remote-fuser-reader, etc
91
92EOF
93}
94
95_qualify ()
96{
97    VAL=$1
98
99    if [ -z "$VAL" ]
100    then
101        _err_exit "qualify(): missed parameter"
102    fi
103
104##  Simple, if it is number, it is time, overwise it is config name
105##
106    if [[ $VAL != *[!0-9]* ]]
107    then
108        RUN_TIME=$VAL
109    else
110        CFG_NAME=$VAL
111    fi
112}
113
114case $# in
115    3)
116        _qualify $1
117        _qualify $2
118        BIN_DIR=$3
119        ;;
120    2)
121        _qualify $1
122        BIN_DIR=$2
123        ;;
124    1)
125        BIN_DIR=$1
126        ;;
127    *)
128        usage
129        _err_exit Invalid parameters
130        ;;
131esac
132
133##  Checking arguments
134##
135CFG_FILE=$CFG_DIR/${CFG_NAME}.cfg
136if [ ! -f "$CFG_FILE" ]
137then
138    _err_exit "Can not stat config file with name '$CFG_NAME'"
139fi
140
141##  Checking RUN_TIME ... it should not be less than 3 minutes
142##
143if [ $RUN_TIME -le 3 ]
144then
145    _err_exit "Run time parameter should be greater than 3 minutes"
146fi
147
148##  Checking BIN_DIR and binaries
149##
150if [ ! -d "$BIN_DIR" ]
151then
152    _err_exit "Can not stat BIN_DIR directory '$BIN_DIR'"
153fi
154
155BIN_DIR=$BIN_DIR/../bin
156if [ ! -d "$BIN_DIR" ]
157then
158    _err_exit "Can not stat BIN_DIR directory '$BIN_DIR'"
159fi
160BIN_DIR=`cd $BIN_DIR; pwd`
161
162TESTBIN_DIR=$BIN_DIR/../test-bin
163if [ ! -d "$TESTBIN_DIR" ]
164then
165    _err_exit "Can not stat TESTBIN_DIR directory '$TESTBIN_DIR'"
166fi
167TESTBIN_DIR=`cd $TESTBIN_DIR; pwd`
168
169####
170##  Loading fonfig file
171#
172. $CFG_FILE
173if [ $? -ne 0 ]
174then
175    _err_exit "Can not load config file '$CFG_NAME'"
176fi
177
178####
179##  Checking config file data and prepareing environment
180#
181if [ -z "$TEST_DIR" ]
182then
183    _err_exit "Config does not have definition for variable TEST_DIR"
184fi
185
186if [ ! -d "$TEST_DIR" ]
187then
188    _err_exit "Can not stat directory '$TEST_DIR'"
189fi
190
191###
192### Prefixes U_(ser), H_(ost), P_(rocess), F_(inal) - is what we use
193###
194
195_assign_create_dir $TEST_DIR/$DAS_USER U_TEST_DIR
196_assign_create_dir $U_TEST_DIR/$DAS_HOST H_TEST_DIR
197_assign_create_dir $H_TEST_DIR/$DAS_PID P_TEST_DIR
198
199###
200## There are logs, bin and depot on user level of test direcotry
201#
202_assign_create_dir $U_TEST_DIR/bin   F_BIN_DIR
203_assign_create_dir $U_TEST_DIR/depot F_DEPOT_DIR
204_assign_create_dir $U_TEST_DIR/log   F_LOG_DIR
205
206###
207## There are cache, mount and temp on process level of test direcotry
208#
209_assign_create_dir $P_TEST_DIR/cache F_CACHE_DIR
210_assign_create_dir $P_TEST_DIR/mount F_MOUNT_DIR
211_assign_create_dir $P_TEST_DIR/temp  F_TEMP_DIR
212
213F_STATUS_FILE=$P_TEST_DIR/status.file
214
215##  Checking mounts and old logs are moved to outside script
216##
217
218##  Here we are logging and execing
219##
220F_LOG_FILE=$F_LOG_DIR/${SCR_SNAME}.log.${DAS_CTX}.${DAS_TSTAMP}
221echo Log file: $F_LOG_FILE
222
223exec >$F_LOG_FILE 2>&1
224
225## One more time for log file
226##
227_print_env $@
228
229## Cleaning old data
230##
231_bump
232_msg Cleaning old data
233
234CLN_CMD="$SCR_DIR/remote_fuser_clean.sh"
235if [ -f "$CLN_CMD" ]
236then
237    nohup $CLN_CMD $CFG_NAME &
238fi
239
240## Here we are copying binaries
241##
242_copy_assign_app ()
243{
244    if [ $# -ne 3 ]
245    then
246        _err_exit "_copy_assign_app(): requires two arguments"
247    fi
248
249    SRC=$1/$2
250    if [ ! -x "$SRC" ]
251    then
252        _err_exit "_copy_assign_app(): can not stat file '$SRC'"
253    fi
254
255    LNK=$F_BIN_DIR/$2
256
257    eval cmp $SRC $LNK
258    if [ $? -ne 0 ]
259    then
260        DST=$F_DEPOT_DIR/${2}.${DAS_TSTAMP}
261        _exec cp -p $SRC $DST
262        _exec rm -f $LNK
263        _exec ln -s $DST $LNK
264    fi
265
266    eval "$3=$LNK"
267}
268
269_copy_assign_app $BIN_DIR remote-fuser REMOTE_FUSER_APP
270_copy_assign_app $TESTBIN_DIR remote-fuser-test REMOTE_FUSER_TEST_APP
271
272###
273##  Here we are checking and pre-processing XML file
274#
275if [ -z "$XML_URL" ]
276then
277    _err_exit "Config does not have definition for variable XML_URL"
278fi
279
280eval HEAD "$XML_URL" >/dev/null
281if [ $? -ne 0 ]
282then
283    _err_exit "Can not stat XML file from '$XML_URL'"
284fi
285
286F_FUSE_XML=$F_TEMP_DIR/FUSE.xml.${DAS_CTX}.${DAS_TSTAMP}
287eval GET "$XML_URL" >$F_FUSE_XML
288if [ $? -ne 0 ]
289then
290    _err_exit "Can not download XML file from '$XML_URL'"
291fi
292
293###
294##  Here we are starting FUSER
295#
296_msg Starting Fuse
297
298FUSER_LOG=$F_LOG_DIR/remote-fuser.log.${DAS_CTX}.${DAS_TSTAMP}
299FUSER_CMD="$REMOTE_FUSER_APP -d -x $XML_URL -m $F_MOUNT_DIR -e $F_CACHE_DIR -L 5 -B 4 -o kernel_cache"
300
301_msg "## $FUSER_CMD"
302$FUSER_CMD >$FUSER_LOG 2>&1 &
303FUSER_PID=$!
304
305## Because!
306
307_store_fuser_params $F_STATUS_FILE $FUSER_PID $F_MOUNT_DIR
308
309_clear_data ()
310{
311    _msg "Removing test data"
312
313    _exec_plain rm -rf $P_TEST_DIR
314    if [ $? -ne 0 ]
315    then
316        _err "Can not remove test data"
317
318        sleep 2
319
320        _msg "Removing test data attempt 2"
321
322        _exec_plain rm -rf $P_TEST_DIR
323        if [ $? -ne 0 ]
324        then
325            _err "Can not remove test data"
326            return 1
327        fi
328    fi
329
330    _msg "Test data removed"
331}
332
333_stop_fuser ()
334{
335    _msg "Stopping Fuse"
336    MCD="$REMOTE_FUSER_APP -u -m $F_MOUNT_DIR"
337    _msg "## $MCD"
338    $MCD
339
340    sleep 100
341
342    _is_fuser_run $FUSER_PID $F_MOUNT_DIR
343    if [ $? -eq 0 ]
344    then
345        _shutdown_fuser $FUSER_PID $F_MOUNT_DIR
346    fi
347
348    _clear_data
349}
350
351_test_failed ()
352{
353    _err "TEST FAILED: $@"
354
355    _stop_fuser
356
357    _err_exit
358}
359
360##  Here we should wait a some time and check that mount is success
361##  The mount is success if there is record in mtab and some files
362##  appeared in mount directory
363##
364for i in All the way home from Baltimore "(C)" Talking Heads THE_END
365do
366    case $i in
367        THE_END)
368            _err Can not start fuser
369            _shutdown_fuser $FUSER_PID $F_MOUNT_DIR
370            ;;
371        *)
372            echo -n "$i "
373            sleep 1
374            _check_dir_mounted $F_MOUNT_DIR
375            if [ $? -eq 0 ]
376            then
377                echo ...
378                break
379            fi
380            ;;
381    esac
382done
383
384#####################################################################
385#####################################################################
386#####
387### First test is checking that file downloads full and correctly
388#
389
390_bump
391_msg TEST 1: Downloading single file
392
393## First we are trying to choose not big file to download
394##
395LINF=` grep "<File" $F_FUSE_XML | sed "s#name=##1" | sed "s#size=##1" | sed "s#path=##1" | sed "s#\"##g" | awk ' { print $2 " " $3 " " $4 } ' | sort -n -k 2 | awk ' BEGIN { SZ=0; NM=""; UR="" } { if ( SZ < 100000 ) { if ( SZ < int ( $2 ) ) { SZ = int ( $2 ); NM = $1; UR = $3 } } } END { print NM " " SZ " "  UR } ' `
396if [ -z "$LINF" ]
397then
398    _test_failed "Invalid XML file '$F_FUSE_XML'"
399fi
400
401REMOTE_URL=`echo $LINF | awk ' { print $3 } ' `
402LOCAL_FILE=`echo $LINF | awk ' { print $1 } ' `
403TEMP_FILE=$F_TEMP_DIR/${LOCAL_FILE}.${DAS_CTX}.${DAS_TSTAMP}
404
405## Downloading copy of proxied file
406##
407_msg "Downloading file '$REMOTE_URL'"
408eval GET "$REMOTE_URL" >$TEMP_FILE
409if [ $? -ne 0 ]
410then
411    _test_failed "Can not load remote file '$REMOTE_URL'"
412fi
413
414## Compareing downloaded file with file proxied by FUSE
415##
416_msg "Compareing downloaded file '$REMOTE_URL' with $F_MOUNT_DIR/$LOCAL_FILE"
417eval cmp $TEMP_FILE $F_MOUNT_DIR/$LOCAL_FILE
418if [ $? -ne 0 ]
419then
420    _test_failed "Invalid file content '$F_MOUNT_DIR/$LOCAL_FILE'"
421fi
422
423## Checking CACHE directory, cuz here should be only one file,
424## without ".cache" extention
425##
426RCA_DIR=$F_CACHE_DIR/.cache
427FILES=(`ls $RCA_DIR`)
428if [ ${#FILES[@]} -ne 1 ]
429then
430    ls $RCA_DIR >&2
431    _test_failed "Invalid content of cache directory '$RCA_DIR'"
432fi
433
434if [[ "${FILES[0]}" == *.cache ]]
435then
436    ls $RCA_DIR >&2
437    _test_failed "Partially downloaded file at '$RCA_DIR'"
438fi
439
440_msg TEST 1: Passed
441
442#####################################################################
443#####################################################################
444#####
445### Second multithread access to singe file
446#
447
448_bump
449_msg TEST 2: Multithread acces to single file
450
451R_TM=2
452N_THR=30
453
454## First we should choose file big enough for a test ...
455## couple hundred megs is OK
456##
457
458for i in `ls $F_MOUNT_DIR`
459do
460    if [ `stat --print="%s" $F_MOUNT_DIR/$i` -gt 200000000 ]
461    then
462        FILE_NAME=$i
463        break
464    fi
465done
466
467if [ -z "$FILE_NAME" ]
468then
469    _test_failed "Can not find file with suitable size"
470fi
471
472TEST_CMD="$REMOTE_FUSER_TEST_APP -t $N_THR -r $R_TM $F_MOUNT_DIR/$FILE_NAME"
473_msg "## $TEST_CMD"
474eval "$TEST_CMD"
475if [ $? -ne 0 ]
476then
477    _test_failed "Single file test failed"
478fi
479
480_msg TEST 2: Passed
481
482#####################################################################
483#####################################################################
484#####
485### Second multithread access to set of files
486#
487
488_bump
489_msg TEST 3: Multithread acces to set of files
490
491## First we should create list of files with limitation
492##
493
494LIST_FILE=$F_TEMP_DIR/listfile.${DAS_CTX}.$DAS_TSTAMP
495for i in `ls $F_MOUNT_DIR`
496do
497    echo $F_MOUNT_DIR/$i >>$LIST_FILE
498done
499
500TEST_CMD="$REMOTE_FUSER_TEST_APP -t $N_THR -r $RUN_TIME -l $LIST_FILE"
501_msg "## $TEST_CMD"
502eval "$TEST_CMD"
503if [ $? -ne 0 ]
504then
505    _test_failed "Multiply files test failed"
506fi
507
508
509_msg TEST 3: Passed
510
511#####
512### Here we are stopping fuser
513#
514_stop_fuser
515
516_msg TEST PASSED!
517