Skip to content

Instantly share code, notes, and snippets.

@sgnn7
Created October 1, 2015 20:27
Show Gist options
  • Save sgnn7/d9400b432c06704e536c to your computer and use it in GitHub Desktop.
Save sgnn7/d9400b432c06704e536c to your computer and use it in GitHub Desktop.
Script to test file transfer speeds between two machines (in this case a Linux host and Netgear NAS
#!/bin/bash -e
if [ $# -ne 4 ]; then
echo "Usage: $0 <target device> <target file> <username> <password>"
exit 1
fi
# Requires packages:
# nfs-common
# mbuffer
# lftp
# Requires packages on target:
# openssh-server
# netcat
TARGET_DEVICE=$1
TARGET_FILE=$2
FILE_SIZE=$(stat -c %s $TARGET_FILE)
USERNAME=$3
PASSWORD=$4
REMOTE_FOLDER=transfer_test
REMOTE_FOLDER_PREFIX=Main
REMOTE_MOUNT=/run/nfs4/$REMOTE_FOLDER_PREFIX/$REMOTE_FOLDER
LOCAL_MOUNT=$(pwd)/nfs_mount
#MBUFFER_BUFFER_CHUNK=512k
MBUFFER_TOTAL_BUFFER=200M
MBUFFER_START=100 #percent
NC_PORT=1234
declare -A UPLOAD_METHODS
# Can't install rcp-server on NAS
#UPLOAD_METHODS["RCP"]="upload_rcp"
#UPLOAD_METHODS["RCP_DES"]="upload_rcp_des"
UPLOAD_METHODS["rsync"]="upload_rsync"
UPLOAD_METHODS["rsync_over_ssh"]="upload_rsync_ssh"
UPLOAD_METHODS["rsync_over_ssh_optimized"]="upload_rsync_ssh_v2"
UPLOAD_METHODS["rsync_over_nfs_mount"]="upload_nfs_rsync"
UPLOAD_METHODS["cp_over_nfs_mount"]="upload_nfs_cp"
UPLOAD_METHODS["scp"]="upload_scp"
UPLOAD_METHODS["optimized_scp"]="upload_scp_v2"
UPLOAD_METHODS["ftp"]="upload_ftp"
UPLOAD_METHODS["passive_ftp"]="upload_ftp_passive"
UPLOAD_METHODS["lftp"]="upload_lftp"
UPLOAD_METHODS["passive_lftp"]="upload_lftp_passive"
UPLOAD_METHODS["mbuffered_ssh_tar"]="upload_tar_mbuffer"
UPLOAD_METHODS["optimized_mbuffered_ssh_tar"]="upload_tar_mbuffer_v2"
UPLOAD_METHODS["mbuffered_ssh_cat"]="upload_cat_mbuffer"
UPLOAD_METHODS["tcp_netcat"]="upload_netcat_tcp"
UPLOAD_METHODS["udp_netcat"]="upload_netcat_udp"
remove_test_file() {
lftp -c "set ssl:verify-certificate no; \
open -u $USERNAME,$PASSWORD $TARGET_DEVICE; \
cd $REMOTE_FOLDER; \
rm $(basename $TARGET_FILE); \
bye" &> /dev/null || true
}
has_test_file() {
if lftp -c "set ssl:verify-certificate no; \
open -u $USERNAME,$PASSWORD $TARGET_DEVICE; \
cd $REMOTE_FOLDER; \
cls -q $(basename $TARGET_FILE); \
bye" > /dev/null; then
return 0;
else
return 1;
fi
}
upload_ftp() {
ftp -n <<EOF
open $TARGET_DEVICE
user $USERNAME $PASSWORD
binary
cd $REMOTE_FOLDER
put $TARGET_FILE
close
EOF
}
upload_netcat_tcp() {
ssh $USERNAME@$TARGET_DEVICE "nc -l -p $NC_PORT > $REMOTE_MOUNT/$(basename $TARGET_FILE) &"
nc -w 10 -q 3 $TARGET_DEVICE $NC_PORT < $TARGET_FILE
ssh $USERNAME@$TARGET_DEVICE "ps -ef | grep nc | grep $NC_PORT | awk '{print \$2}' | xargs kill" || true
}
upload_netcat_udp() {
ssh $USERNAME@$TARGET_DEVICE "nc -u -l -p $NC_PORT > $REMOTE_MOUNT/$(basename $TARGET_FILE) &"
nc -u -w 10 -q 3 $TARGET_DEVICE $NC_PORT < $TARGET_FILE
ssh $USERNAME@$TARGET_DEVICE "ps -ef | grep nc | grep $NC_PORT | awk '{print \$2}' | xargs kill" || true
}
upload_ftp_passive() {
ftp -p -n <<EOF
open $TARGET_DEVICE
user $USERNAME $PASSWORD
binary
cd $REMOTE_FOLDER
put $TARGET_FILE
close
EOF
}
upload_lftp() {
lftp -c "set ftp:passive-mode false; set ssl:verify-certificate no; open -u $USERNAME,$PASSWORD $TARGET_DEVICE; put -O $REMOTE_FOLDER $TARGET_FILE; bye"
}
upload_lftp_passive() {
lftp -c "set ssl:verify-certificate no; open -u $USERNAME,$PASSWORD $TARGET_DEVICE; put -O $REMOTE_FOLDER $TARGET_FILE; bye"
}
upload_tar_mbuffer() {
tar zcf - $TARGET_FILE \
| mbuffer -q -P $MBUFFER_START -m $MBUFFER_TOTAL_BUFFER \
| ssh $USERNAME@$TARGET_DEVICE \
"cd $REMOTE_MOUNT && tar zxf -"
}
upload_tar_mbuffer_v2() {
tar zcf - $TARGET_FILE \
| mbuffer -q -P $MBUFFER_START -m $MBUFFER_TOTAL_BUFFER \
| ssh -c arcfour128,blowfish-cbc $USERNAME@$TARGET_DEVICE \
"cd $REMOTE_MOUNT && tar zxf -"
}
upload_cat_mbuffer() {
mbuffer -q -P $MBUFFER_START -m $MBUFFER_TOTAL_BUFFER -i $TARGET_FILE \
| ssh -c arcfour128,blowfish-cbc $USERNAME@$TARGET_DEVICE \
"cat - > $REMOTE_MOUNT/$(basename $TARGET_FILE)"
}
upload_nfs_rsync() {
rsync $TARGET_FILE $LOCAL_MOUNT
}
upload_nfs_cp() {
cp $TARGET_FILE $LOCAL_MOUNT
}
upload_rsync() {
rsync $TARGET_FILE $TARGET_DEVICE::$REMOTE_FOLDER
}
upload_rsync_ssh() {
rsync $TARGET_FILE $USERNAME@$TARGET_DEVICE:$REMOTE_MOUNT
}
upload_rsync_ssh_v2() {
rsync -e "ssh -c arcfour128,blowfish-cbc" $TARGET_FILE $USERNAME@$TARGET_DEVICE:$REMOTE_MOUNT
}
upload_rcp() {
rcp $TARGET_FILE $USERNAME@$TARGET_DEVICE:$REMOTE_MOUNT
}
upload_rcp() {
rcp -x $TARGET_FILE $USERNAME@$TARGET_DEVICE:$REMOTE_MOUNT
}
upload_scp() {
scp -q $TARGET_FILE $USERNAME@$TARGET_DEVICE:$REMOTE_MOUNT
}
upload_scp_v2() {
scp -q -c arcfour,blowfish-cbc $TARGET_FILE $USERNAME@$TARGET_DEVICE:$REMOTE_MOUNT
}
echo "Testing transfer with: $TARGET_FILE (${FILE_SIZE}b)"
echo
if ! mountpoint -q "$LOCAL_MOUNT"; then
echo "Setting up local mount at $LOCAL_MOUNT"
mkdir -p $LOCAL_MOUNT
sudo mount $TARGET_DEVICE:/$REMOTE_FOLDER_PREFIX/$REMOTE_FOLDER $LOCAL_MOUNT #-o rw,bg,soft,vers=3,noexec,nosuid
echo
fi
declare -A UPLOAD_TIMES
declare -A UPLOAD_SPEEDS
count=0
total_count=${#UPLOAD_METHODS[@]}
for upload_type in "${!UPLOAD_METHODS[@]}"; do
if [ $DEBUG ]; then
echo "Testing $upload_type"
fi
remove_test_file
count=$(( $count + 1 ))
prefix_string="($count/$total_count) $upload_type"
start_date=$(date +%s%3N)
${UPLOAD_METHODS["${upload_type}"]}
end_date=$(date +%s%3N)
time_diff=$(( $end_date - $start_date ))
duration=$(bc <<< "scale=3;$time_diff/1000")
speed=$(bc <<< "scale=3;$FILE_SIZE / ${time_diff}.0")
UPLOAD_TIMES["${upload_type}"]=$duration
UPLOAD_SPEEDS["${upload_type}"]=$speed
# Verify
if has_test_file; then
echo -e "$prefix_string: \e[92mOK\e[0m"
else
echo -ne "\e[31m"
echo -n "$prefix_string: FAIL! - File was not on the target!"
echo -e "\e[0m"
fi
done
echo "Cleanup..."
remove_test_file
sudo umount $LOCAL_MOUNT
echo
values=""
for upload_type in "${!UPLOAD_METHODS[@]}"; do
values+="$upload_type ${UPLOAD_SPEEDS[$upload_type]}\n"
done
echo -e "Type\t\t\t\tSpeed (KBps)"
echo "----------------------------------"
echo -ne "\e[92m"
echo -e $values | column -t | sort -n -r -k 2,2
echo -e "\e[0m"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment