1*4882a593Smuzhiyun#!/bin/bash 2*4882a593Smuzhiyun# 3*4882a593Smuzhiyun# (C) Copyright 2014 Suriyan Ramasami 4*4882a593Smuzhiyun# 5*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0+ 6*4882a593Smuzhiyun# 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun# Invoke this test script from U-Boot base directory as ./test/fs/fs-test.sh 9*4882a593Smuzhiyun# It currently tests the fs/sb and native commands for ext4 and fat partitions 10*4882a593Smuzhiyun# Expected results are as follows: 11*4882a593Smuzhiyun# EXT4 tests: 12*4882a593Smuzhiyun# fs-test.sb.ext4.out: Summary: PASS: 23 FAIL: 0 13*4882a593Smuzhiyun# fs-test.ext4.out: Summary: PASS: 23 FAIL: 0 14*4882a593Smuzhiyun# fs-test.fs.ext4.out: Summary: PASS: 23 FAIL: 0 15*4882a593Smuzhiyun# FAT tests: 16*4882a593Smuzhiyun# fs-test.sb.fat.out: Summary: PASS: 23 FAIL: 0 17*4882a593Smuzhiyun# fs-test.fat.out: Summary: PASS: 20 FAIL: 3 18*4882a593Smuzhiyun# fs-test.fs.fat.out: Summary: PASS: 20 FAIL: 3 19*4882a593Smuzhiyun# Total Summary: TOTAL PASS: 132 TOTAL FAIL: 6 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun# pre-requisite binaries list. 22*4882a593SmuzhiyunPREREQ_BINS="md5sum mkfs mount umount dd fallocate mkdir" 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun# All generated output files from this test will be in $OUT_DIR 25*4882a593Smuzhiyun# Hence everything is sandboxed. 26*4882a593SmuzhiyunOUT_DIR="sandbox/test/fs" 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun# Location of generated sandbox u-boot 29*4882a593SmuzhiyunUBOOT="./sandbox/u-boot" 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun# Our mount directory will be in the sandbox 32*4882a593SmuzhiyunMOUNT_DIR="${OUT_DIR}/mnt" 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun# The file system image we create will have the $IMG prefix. 35*4882a593SmuzhiyunIMG="${OUT_DIR}/3GB" 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun# $SMALL_FILE is the name of the 1MB file in the file system image 38*4882a593SmuzhiyunSMALL_FILE="1MB.file" 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun# $BIG_FILE is the name of the 2.5GB file in the file system image 41*4882a593SmuzhiyunBIG_FILE="2.5GB.file" 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun# $MD5_FILE will have the expected md5s when we do the test 44*4882a593Smuzhiyun# They shall have a suffix which represents their file system (ext4/fat) 45*4882a593SmuzhiyunMD5_FILE="${OUT_DIR}/md5s.list" 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun# $OUT shall be the prefix of the test output. Their suffix will be .out 48*4882a593SmuzhiyunOUT="${OUT_DIR}/fs-test" 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun# Full Path of the 1 MB file that shall be created in the fs image. 51*4882a593SmuzhiyunMB1="${MOUNT_DIR}/${SMALL_FILE}" 52*4882a593SmuzhiyunGB2p5="${MOUNT_DIR}/${BIG_FILE}" 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun# ************************ 55*4882a593Smuzhiyun# * Functions start here * 56*4882a593Smuzhiyun# ************************ 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun# Check if the prereq binaries exist, or exit 59*4882a593Smuzhiyunfunction check_prereq() { 60*4882a593Smuzhiyun for prereq in $PREREQ_BINS; do 61*4882a593Smuzhiyun if [ ! -x "`which $prereq`" ]; then 62*4882a593Smuzhiyun echo "Missing $prereq binary. Exiting!" 63*4882a593Smuzhiyun exit 64*4882a593Smuzhiyun fi 65*4882a593Smuzhiyun done 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun # We use /dev/urandom to create files. Check if it exists. 68*4882a593Smuzhiyun if [ ! -c /dev/urandom ]; then 69*4882a593Smuzhiyun echo "Missing character special /dev/urandom. Exiting!" 70*4882a593Smuzhiyun exit 71*4882a593Smuzhiyun fi 72*4882a593Smuzhiyun} 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun# If 1st param is "clean", then clean out the generated files and exit 75*4882a593Smuzhiyunfunction check_clean() { 76*4882a593Smuzhiyun if [ "$1" = "clean" ]; then 77*4882a593Smuzhiyun rm -rf "$OUT_DIR" 78*4882a593Smuzhiyun echo "Cleaned up generated files. Exiting" 79*4882a593Smuzhiyun exit 80*4882a593Smuzhiyun fi 81*4882a593Smuzhiyun} 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun# Generate sandbox U-Boot - gleaned from /test/dm/test-dm.sh 84*4882a593Smuzhiyunfunction compile_sandbox() { 85*4882a593Smuzhiyun unset CROSS_COMPILE 86*4882a593Smuzhiyun NUM_CPUS=$(cat /proc/cpuinfo |grep -c processor) 87*4882a593Smuzhiyun make O=sandbox sandbox_config 88*4882a593Smuzhiyun make O=sandbox -s -j${NUM_CPUS} 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun # Check if U-Boot exists 91*4882a593Smuzhiyun if [ ! -x "$UBOOT" ]; then 92*4882a593Smuzhiyun echo "$UBOOT does not exist or is not executable" 93*4882a593Smuzhiyun echo "Build error?" 94*4882a593Smuzhiyun echo "Please run this script as ./test/fs/`basename $0`" 95*4882a593Smuzhiyun exit 96*4882a593Smuzhiyun fi 97*4882a593Smuzhiyun} 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun# Clean out all generated files other than the file system images 100*4882a593Smuzhiyun# We save time by not deleting and recreating the file system images 101*4882a593Smuzhiyunfunction prepare_env() { 102*4882a593Smuzhiyun rm -f ${MD5_FILE}.* ${OUT}.* 103*4882a593Smuzhiyun mkdir -p ${OUT_DIR} 104*4882a593Smuzhiyun} 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun# 1st parameter is the name of the image file to be created 107*4882a593Smuzhiyun# 2nd parameter is the filesystem - fat ext4 etc 108*4882a593Smuzhiyun# -F cant be used with fat as it means something else. 109*4882a593Smuzhiyunfunction create_image() { 110*4882a593Smuzhiyun # Create image if not already present - saves time, while debugging 111*4882a593Smuzhiyun if [ "$2" = "ext4" ]; then 112*4882a593Smuzhiyun MKFS_OPTION="-F" 113*4882a593Smuzhiyun else 114*4882a593Smuzhiyun MKFS_OPTION="" 115*4882a593Smuzhiyun fi 116*4882a593Smuzhiyun if [ ! -f "$1" ]; then 117*4882a593Smuzhiyun fallocate -l 3G "$1" &> /dev/null 118*4882a593Smuzhiyun if [ $? -ne 0 ]; then 119*4882a593Smuzhiyun echo fallocate failed - using dd instead 120*4882a593Smuzhiyun dd if=/dev/zero of=$1 bs=1024 count=$((3 * 1024 * 1024)) 121*4882a593Smuzhiyun if [ $? -ne 0 ]; then 122*4882a593Smuzhiyun echo Could not create empty disk image 123*4882a593Smuzhiyun exit $? 124*4882a593Smuzhiyun fi 125*4882a593Smuzhiyun fi 126*4882a593Smuzhiyun mkfs -t "$2" $MKFS_OPTION "$1" &> /dev/null 127*4882a593Smuzhiyun if [ $? -ne 0 -a "$2" = "fat" ]; then 128*4882a593Smuzhiyun # If we fail and we did fat, try vfat. 129*4882a593Smuzhiyun mkfs -t vfat $MKFS_OPTION "$1" &> /dev/null 130*4882a593Smuzhiyun fi 131*4882a593Smuzhiyun if [ $? -ne 0 ]; then 132*4882a593Smuzhiyun echo Could not create filesystem 133*4882a593Smuzhiyun exit $? 134*4882a593Smuzhiyun fi 135*4882a593Smuzhiyun fi 136*4882a593Smuzhiyun} 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun# 1st parameter is image file 139*4882a593Smuzhiyun# 2nd parameter is file system type - fat/ext4 140*4882a593Smuzhiyun# 3rd parameter is name of small file 141*4882a593Smuzhiyun# 4th parameter is name of big file 142*4882a593Smuzhiyun# 5th parameter is fs/nonfs/sb - to dictate generic fs commands or 143*4882a593Smuzhiyun# otherwise or sb hostfs 144*4882a593Smuzhiyun# 6th parameter is the directory path for the files. Its "" for generic 145*4882a593Smuzhiyun# fs and ext4/fat and full patch for sb hostfs 146*4882a593Smuzhiyun# UBOOT is set in env 147*4882a593Smuzhiyunfunction test_image() { 148*4882a593Smuzhiyun addr="0x01000008" 149*4882a593Smuzhiyun length="0x00100000" 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun case "$2" in 152*4882a593Smuzhiyun fat) 153*4882a593Smuzhiyun FPATH="" 154*4882a593Smuzhiyun PREFIX="fat" 155*4882a593Smuzhiyun WRITE="write" 156*4882a593Smuzhiyun ;; 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun ext4) 159*4882a593Smuzhiyun # ext4 needs absolute path 160*4882a593Smuzhiyun FPATH="/" 161*4882a593Smuzhiyun PREFIX="ext4" 162*4882a593Smuzhiyun WRITE="write" 163*4882a593Smuzhiyun ;; 164*4882a593Smuzhiyun 165*4882a593Smuzhiyun *) 166*4882a593Smuzhiyun echo "Unhandled filesystem $2. Exiting!" 167*4882a593Smuzhiyun exit 168*4882a593Smuzhiyun ;; 169*4882a593Smuzhiyun esac 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun case "$5" in 172*4882a593Smuzhiyun fs) 173*4882a593Smuzhiyun PREFIX="" 174*4882a593Smuzhiyun WRITE="save" 175*4882a593Smuzhiyun SUFFIX=" 0:0" 176*4882a593Smuzhiyun ;; 177*4882a593Smuzhiyun 178*4882a593Smuzhiyun nonfs) 179*4882a593Smuzhiyun SUFFIX=" 0:0" 180*4882a593Smuzhiyun ;; 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun sb) 183*4882a593Smuzhiyun PREFIX="sb " 184*4882a593Smuzhiyun WRITE="save" 185*4882a593Smuzhiyun SUFFIX="fs -" 186*4882a593Smuzhiyun ;; 187*4882a593Smuzhiyun 188*4882a593Smuzhiyun *) 189*4882a593Smuzhiyun echo "Unhandled mode $5. Exiting!" 190*4882a593Smuzhiyun exit 191*4882a593Smuzhiyun ;; 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun esac 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun # sb always uses full path to mointpoint, irrespective of filesystem 196*4882a593Smuzhiyun if [ "$5" = "sb" ]; then 197*4882a593Smuzhiyun FPATH=${6}/ 198*4882a593Smuzhiyun fi 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun FILE_WRITE=${3}.w 201*4882a593Smuzhiyun FILE_SMALL=$3 202*4882a593Smuzhiyun FILE_BIG=$4 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun # In u-boot commands, <interface> stands for host or hostfs 205*4882a593Smuzhiyun # hostfs maps to the host fs. 206*4882a593Smuzhiyun # host maps to the "sb bind" that we do 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun $UBOOT << EOF 209*4882a593Smuzhiyunsb=$5 210*4882a593Smuzhiyunsetenv bind 'if test "\$sb" != sb; then sb bind 0 "$1"; fi' 211*4882a593Smuzhiyunrun bind 212*4882a593Smuzhiyun# Test Case 1 - ls 213*4882a593Smuzhiyun${PREFIX}ls host${SUFFIX} $6 214*4882a593Smuzhiyun# 215*4882a593Smuzhiyun# We want ${PREFIX}size host 0:0 $3 for host commands and 216*4882a593Smuzhiyun# sb size hostfs - $3 for hostfs commands. 217*4882a593Smuzhiyun# 1MB is 0x0010 0000 218*4882a593Smuzhiyun# Test Case 2 - size of small file 219*4882a593Smuzhiyun${PREFIX}size host${SUFFIX} ${FPATH}$FILE_SMALL 220*4882a593Smuzhiyunprintenv filesize 221*4882a593Smuzhiyunsetenv filesize 222*4882a593Smuzhiyun 223*4882a593Smuzhiyun# 2.5GB (1024*1024*2500) is 0x9C40 0000 224*4882a593Smuzhiyun# Test Case 3 - size of big file 225*4882a593Smuzhiyun${PREFIX}size host${SUFFIX} ${FPATH}$FILE_BIG 226*4882a593Smuzhiyunprintenv filesize 227*4882a593Smuzhiyunsetenv filesize 228*4882a593Smuzhiyun 229*4882a593Smuzhiyun# Notes about load operation 230*4882a593Smuzhiyun# If I use 0x01000000 I get DMA misaligned error message 231*4882a593Smuzhiyun# Last two parameters are size and offset. 232*4882a593Smuzhiyun 233*4882a593Smuzhiyun# Test Case 4a - Read full 1MB of small file 234*4882a593Smuzhiyun${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_SMALL 235*4882a593Smuzhiyunprintenv filesize 236*4882a593Smuzhiyun# Test Case 4b - Read full 1MB of small file 237*4882a593Smuzhiyunmd5sum $addr \$filesize 238*4882a593Smuzhiyunsetenv filesize 239*4882a593Smuzhiyun 240*4882a593Smuzhiyun# Test Case 5a - First 1MB of big file 241*4882a593Smuzhiyun${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x0 242*4882a593Smuzhiyunprintenv filesize 243*4882a593Smuzhiyun# Test Case 5b - First 1MB of big file 244*4882a593Smuzhiyunmd5sum $addr \$filesize 245*4882a593Smuzhiyunsetenv filesize 246*4882a593Smuzhiyun 247*4882a593Smuzhiyun# fails for ext as no offset support 248*4882a593Smuzhiyun# Test Case 6a - Last 1MB of big file 249*4882a593Smuzhiyun${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x9C300000 250*4882a593Smuzhiyunprintenv filesize 251*4882a593Smuzhiyun# Test Case 6b - Last 1MB of big file 252*4882a593Smuzhiyunmd5sum $addr \$filesize 253*4882a593Smuzhiyunsetenv filesize 254*4882a593Smuzhiyun 255*4882a593Smuzhiyun# fails for ext as no offset support 256*4882a593Smuzhiyun# Test Case 7a - One from the last 1MB chunk of 2GB 257*4882a593Smuzhiyun${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x7FF00000 258*4882a593Smuzhiyunprintenv filesize 259*4882a593Smuzhiyun# Test Case 7b - One from the last 1MB chunk of 2GB 260*4882a593Smuzhiyunmd5sum $addr \$filesize 261*4882a593Smuzhiyunsetenv filesize 262*4882a593Smuzhiyun 263*4882a593Smuzhiyun# fails for ext as no offset support 264*4882a593Smuzhiyun# Test Case 8a - One from the start 1MB chunk from 2GB 265*4882a593Smuzhiyun${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x80000000 266*4882a593Smuzhiyunprintenv filesize 267*4882a593Smuzhiyun# Test Case 8b - One from the start 1MB chunk from 2GB 268*4882a593Smuzhiyunmd5sum $addr \$filesize 269*4882a593Smuzhiyunsetenv filesize 270*4882a593Smuzhiyun 271*4882a593Smuzhiyun# fails for ext as no offset support 272*4882a593Smuzhiyun# Test Case 9a - One 1MB chunk crossing the 2GB boundary 273*4882a593Smuzhiyun${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x7FF80000 274*4882a593Smuzhiyunprintenv filesize 275*4882a593Smuzhiyun# Test Case 9b - One 1MB chunk crossing the 2GB boundary 276*4882a593Smuzhiyunmd5sum $addr \$filesize 277*4882a593Smuzhiyunsetenv filesize 278*4882a593Smuzhiyun 279*4882a593Smuzhiyun# Generic failure case 280*4882a593Smuzhiyun# Test Case 10 - 2MB chunk from the last 1MB of big file 281*4882a593Smuzhiyun${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG 0x00200000 0x9C300000 282*4882a593Smuzhiyunprintenv filesize 283*4882a593Smuzhiyun# 284*4882a593Smuzhiyun 285*4882a593Smuzhiyun# Read 1MB from small file 286*4882a593Smuzhiyun${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_SMALL 287*4882a593Smuzhiyun# Write it back to test the writes 288*4882a593Smuzhiyun# Test Case 11a - Check that the write succeeded 289*4882a593Smuzhiyun${PREFIX}${WRITE} host${SUFFIX} $addr ${FPATH}$FILE_WRITE \$filesize 290*4882a593Smuzhiyunmw.b $addr 00 100 291*4882a593Smuzhiyun${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_WRITE 292*4882a593Smuzhiyun# Test Case 11b - Check md5 of written to is same as the one read from 293*4882a593Smuzhiyunmd5sum $addr \$filesize 294*4882a593Smuzhiyunsetenv filesize 295*4882a593Smuzhiyun# 296*4882a593Smuzhiyun 297*4882a593Smuzhiyun# Next test case checks writing a file whose dirent 298*4882a593Smuzhiyun# is the first in the block, which is always true for "." 299*4882a593Smuzhiyun# The write should fail, but the lookup should work 300*4882a593Smuzhiyun# Test Case 12 - Check directory traversal 301*4882a593Smuzhiyun${PREFIX}${WRITE} host${SUFFIX} $addr ${FPATH}. 0x10 302*4882a593Smuzhiyun 303*4882a593Smuzhiyun# Read 1MB from small file 304*4882a593Smuzhiyun${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_SMALL 305*4882a593Smuzhiyun# Write it via "same directory", i.e. "." dirent 306*4882a593Smuzhiyun# Test Case 13a - Check directory traversal 307*4882a593Smuzhiyun${PREFIX}${WRITE} host${SUFFIX} $addr ${FPATH}./${FILE_WRITE}2 \$filesize 308*4882a593Smuzhiyunmw.b $addr 00 100 309*4882a593Smuzhiyun${PREFIX}load host${SUFFIX} $addr ${FPATH}./${FILE_WRITE}2 310*4882a593Smuzhiyun# Test Case 13b - Check md5 of written to is same as the one read from 311*4882a593Smuzhiyunmd5sum $addr \$filesize 312*4882a593Smuzhiyunsetenv filesize 313*4882a593Smuzhiyunmw.b $addr 00 100 314*4882a593Smuzhiyun${PREFIX}load host${SUFFIX} $addr ${FPATH}${FILE_WRITE}2 315*4882a593Smuzhiyun# Test Case 13c - Check md5 of written to is same as the one read from 316*4882a593Smuzhiyunmd5sum $addr \$filesize 317*4882a593Smuzhiyunsetenv filesize 318*4882a593Smuzhiyun# 319*4882a593Smuzhiyunreset 320*4882a593Smuzhiyun 321*4882a593SmuzhiyunEOF 322*4882a593Smuzhiyun} 323*4882a593Smuzhiyun 324*4882a593Smuzhiyun# 1st argument is the name of the image file. 325*4882a593Smuzhiyun# 2nd argument is the file where we generate the md5s of the files 326*4882a593Smuzhiyun# generated with the appropriate start and length that we use to test. 327*4882a593Smuzhiyun# It creates the necessary files in the image to test. 328*4882a593Smuzhiyun# $GB2p5 is the path of the big file (2.5 GB) 329*4882a593Smuzhiyun# $MB1 is the path of the small file (1 MB) 330*4882a593Smuzhiyun# $MOUNT_DIR is the path we can use to mount the image file. 331*4882a593Smuzhiyunfunction create_files() { 332*4882a593Smuzhiyun # Mount the image so we can populate it. 333*4882a593Smuzhiyun mkdir -p "$MOUNT_DIR" 334*4882a593Smuzhiyun sudo mount -o loop,rw "$1" "$MOUNT_DIR" 335*4882a593Smuzhiyun 336*4882a593Smuzhiyun # Create big file in this image. 337*4882a593Smuzhiyun # Note that we work only on the start 1MB, couple MBs in the 2GB range 338*4882a593Smuzhiyun # and the last 1 MB of the huge 2.5GB file. 339*4882a593Smuzhiyun # So, just put random values only in those areas. 340*4882a593Smuzhiyun if [ ! -f "${GB2p5}" ]; then 341*4882a593Smuzhiyun sudo dd if=/dev/urandom of="${GB2p5}" bs=1M count=1 \ 342*4882a593Smuzhiyun &> /dev/null 343*4882a593Smuzhiyun sudo dd if=/dev/urandom of="${GB2p5}" bs=1M count=2 seek=2047 \ 344*4882a593Smuzhiyun &> /dev/null 345*4882a593Smuzhiyun sudo dd if=/dev/urandom of="${GB2p5}" bs=1M count=1 seek=2499 \ 346*4882a593Smuzhiyun &> /dev/null 347*4882a593Smuzhiyun fi 348*4882a593Smuzhiyun 349*4882a593Smuzhiyun # Create a small file in this image. 350*4882a593Smuzhiyun if [ ! -f "${MB1}" ]; then 351*4882a593Smuzhiyun sudo dd if=/dev/urandom of="${MB1}" bs=1M count=1 \ 352*4882a593Smuzhiyun &> /dev/null 353*4882a593Smuzhiyun fi 354*4882a593Smuzhiyun 355*4882a593Smuzhiyun # Delete the small file copies which possibly are written as part of a 356*4882a593Smuzhiyun # previous test. 357*4882a593Smuzhiyun sudo rm -f "${MB1}.w" 358*4882a593Smuzhiyun sudo rm -f "${MB1}.w2" 359*4882a593Smuzhiyun 360*4882a593Smuzhiyun # Generate the md5sums of reads that we will test against small file 361*4882a593Smuzhiyun dd if="${MB1}" bs=1M skip=0 count=1 2> /dev/null | md5sum > "$2" 362*4882a593Smuzhiyun 363*4882a593Smuzhiyun # Generate the md5sums of reads that we will test against big file 364*4882a593Smuzhiyun # One from beginning of file. 365*4882a593Smuzhiyun dd if="${GB2p5}" bs=1M skip=0 count=1 \ 366*4882a593Smuzhiyun 2> /dev/null | md5sum >> "$2" 367*4882a593Smuzhiyun 368*4882a593Smuzhiyun # One from end of file. 369*4882a593Smuzhiyun dd if="${GB2p5}" bs=1M skip=2499 count=1 \ 370*4882a593Smuzhiyun 2> /dev/null | md5sum >> "$2" 371*4882a593Smuzhiyun 372*4882a593Smuzhiyun # One from the last 1MB chunk of 2GB 373*4882a593Smuzhiyun dd if="${GB2p5}" bs=1M skip=2047 count=1 \ 374*4882a593Smuzhiyun 2> /dev/null | md5sum >> "$2" 375*4882a593Smuzhiyun 376*4882a593Smuzhiyun # One from the start 1MB chunk from 2GB 377*4882a593Smuzhiyun dd if="${GB2p5}" bs=1M skip=2048 count=1 \ 378*4882a593Smuzhiyun 2> /dev/null | md5sum >> "$2" 379*4882a593Smuzhiyun 380*4882a593Smuzhiyun # One 1MB chunk crossing the 2GB boundary 381*4882a593Smuzhiyun dd if="${GB2p5}" bs=512K skip=4095 count=2 \ 382*4882a593Smuzhiyun 2> /dev/null | md5sum >> "$2" 383*4882a593Smuzhiyun 384*4882a593Smuzhiyun sync 385*4882a593Smuzhiyun sudo umount "$MOUNT_DIR" 386*4882a593Smuzhiyun rmdir "$MOUNT_DIR" 387*4882a593Smuzhiyun} 388*4882a593Smuzhiyun 389*4882a593Smuzhiyun# 1st parameter is the text to print 390*4882a593Smuzhiyun# if $? is 0 its a pass, else a fail 391*4882a593Smuzhiyun# As a side effect it shall update env variable PASS and FAIL 392*4882a593Smuzhiyunfunction pass_fail() { 393*4882a593Smuzhiyun if [ $? -eq 0 ]; then 394*4882a593Smuzhiyun echo pass - "$1" 395*4882a593Smuzhiyun PASS=$((PASS + 1)) 396*4882a593Smuzhiyun else 397*4882a593Smuzhiyun echo FAIL - "$1" 398*4882a593Smuzhiyun FAIL=$((FAIL + 1)) 399*4882a593Smuzhiyun fi 400*4882a593Smuzhiyun} 401*4882a593Smuzhiyun 402*4882a593Smuzhiyun# 1st parameter is the string which leads to an md5 generation 403*4882a593Smuzhiyun# 2nd parameter is the file we grep, for that string 404*4882a593Smuzhiyun# 3rd parameter is the name of the file which has md5s in it 405*4882a593Smuzhiyun# 4th parameter is the line # in the md5 file that we match it against 406*4882a593Smuzhiyun# This function checks if the md5 of the file in the sandbox matches 407*4882a593Smuzhiyun# that calculated while generating the file 408*4882a593Smuzhiyun# 5th parameter is the string to print with the result 409*4882a593Smuzhiyuncheck_md5() { 410*4882a593Smuzhiyun # md5sum in u-boot has output of form: 411*4882a593Smuzhiyun # md5 for 01000008 ... 01100007 ==> <md5> 412*4882a593Smuzhiyun # the 7th field is the actual md5 413*4882a593Smuzhiyun md5_src=`grep -A2 "$1" "$2" | grep "md5 for" | tr -d '\r'` 414*4882a593Smuzhiyun md5_src=($md5_src) 415*4882a593Smuzhiyun md5_src=${md5_src[6]} 416*4882a593Smuzhiyun 417*4882a593Smuzhiyun # The md5 list, each line is of the form: 418*4882a593Smuzhiyun # - <md5> 419*4882a593Smuzhiyun # the 2nd field is the actual md5 420*4882a593Smuzhiyun md5_dst=`sed -n $4p $3` 421*4882a593Smuzhiyun md5_dst=($md5_dst) 422*4882a593Smuzhiyun md5_dst=${md5_dst[0]} 423*4882a593Smuzhiyun 424*4882a593Smuzhiyun # For a pass they should match. 425*4882a593Smuzhiyun [ "$md5_src" = "$md5_dst" ] 426*4882a593Smuzhiyun pass_fail "$5" 427*4882a593Smuzhiyun} 428*4882a593Smuzhiyun 429*4882a593Smuzhiyun# 1st parameter is the name of the output file to check 430*4882a593Smuzhiyun# 2nd parameter is the name of the file containing the md5 expected 431*4882a593Smuzhiyun# 3rd parameter is the name of the small file 432*4882a593Smuzhiyun# 4th parameter is the name of the big file 433*4882a593Smuzhiyun# 5th paramter is the name of the written file 434*4882a593Smuzhiyun# This function checks the output file for correct results. 435*4882a593Smuzhiyunfunction check_results() { 436*4882a593Smuzhiyun echo "** Start $1" 437*4882a593Smuzhiyun 438*4882a593Smuzhiyun PASS=0 439*4882a593Smuzhiyun FAIL=0 440*4882a593Smuzhiyun 441*4882a593Smuzhiyun # Check if the ls is showing correct results for 2.5 gb file 442*4882a593Smuzhiyun grep -A6 "Test Case 1 " "$1" | egrep -iq "2621440000 *$4" 443*4882a593Smuzhiyun pass_fail "TC1: ls of $4" 444*4882a593Smuzhiyun 445*4882a593Smuzhiyun # Check if the ls is showing correct results for 1 mb file 446*4882a593Smuzhiyun grep -A6 "Test Case 1 " "$1" | egrep -iq "1048576 *$3" 447*4882a593Smuzhiyun pass_fail "TC1: ls of $3" 448*4882a593Smuzhiyun 449*4882a593Smuzhiyun # Check size command on 1MB.file 450*4882a593Smuzhiyun egrep -A3 "Test Case 2 " "$1" | grep -q "filesize=100000" 451*4882a593Smuzhiyun pass_fail "TC2: size of $3" 452*4882a593Smuzhiyun 453*4882a593Smuzhiyun # Check size command on 2.5GB.file 454*4882a593Smuzhiyun egrep -A3 "Test Case 3 " "$1" | grep -q "filesize=9c400000" 455*4882a593Smuzhiyun pass_fail "TC3: size of $4" 456*4882a593Smuzhiyun 457*4882a593Smuzhiyun # Check read full mb of 1MB.file 458*4882a593Smuzhiyun grep -A4 "Test Case 4a " "$1" | grep -q "filesize=100000" 459*4882a593Smuzhiyun pass_fail "TC4: load of $3 size" 460*4882a593Smuzhiyun check_md5 "Test Case 4b " "$1" "$2" 1 "TC4: load from $3" 461*4882a593Smuzhiyun 462*4882a593Smuzhiyun # Check first mb of 2.5GB.file 463*4882a593Smuzhiyun grep -A4 "Test Case 5a " "$1" | grep -q "filesize=100000" 464*4882a593Smuzhiyun pass_fail "TC5: load of 1st MB from $4 size" 465*4882a593Smuzhiyun check_md5 "Test Case 5b " "$1" "$2" 2 "TC5: load of 1st MB from $4" 466*4882a593Smuzhiyun 467*4882a593Smuzhiyun # Check last mb of 2.5GB.file 468*4882a593Smuzhiyun grep -A4 "Test Case 6a " "$1" | grep -q "filesize=100000" 469*4882a593Smuzhiyun pass_fail "TC6: load of last MB from $4 size" 470*4882a593Smuzhiyun check_md5 "Test Case 6b " "$1" "$2" 3 "TC6: load of last MB from $4" 471*4882a593Smuzhiyun 472*4882a593Smuzhiyun # Check last 1mb chunk of 2gb from 2.5GB file 473*4882a593Smuzhiyun grep -A4 "Test Case 7a " "$1" | grep -q "filesize=100000" 474*4882a593Smuzhiyun pass_fail "TC7: load of last 1mb chunk of 2GB from $4 size" 475*4882a593Smuzhiyun check_md5 "Test Case 7b " "$1" "$2" 4 \ 476*4882a593Smuzhiyun "TC7: load of last 1mb chunk of 2GB from $4" 477*4882a593Smuzhiyun 478*4882a593Smuzhiyun # Check first 1mb chunk after 2gb from 2.5GB file 479*4882a593Smuzhiyun grep -A4 "Test Case 8a " "$1" | grep -q "filesize=100000" 480*4882a593Smuzhiyun pass_fail "TC8: load 1st MB chunk after 2GB from $4 size" 481*4882a593Smuzhiyun check_md5 "Test Case 8b " "$1" "$2" 5 \ 482*4882a593Smuzhiyun "TC8: load 1st MB chunk after 2GB from $4" 483*4882a593Smuzhiyun 484*4882a593Smuzhiyun # Check 1mb chunk crossing the 2gb boundary from 2.5GB file 485*4882a593Smuzhiyun grep -A4 "Test Case 9a " "$1" | grep -q "filesize=100000" 486*4882a593Smuzhiyun pass_fail "TC9: load 1MB chunk crossing 2GB boundary from $4 size" 487*4882a593Smuzhiyun check_md5 "Test Case 9b " "$1" "$2" 6 \ 488*4882a593Smuzhiyun "TC9: load 1MB chunk crossing 2GB boundary from $4" 489*4882a593Smuzhiyun 490*4882a593Smuzhiyun # Check 2mb chunk from the last 1MB of 2.5GB file loads 1MB 491*4882a593Smuzhiyun grep -A5 "Test Case 10 " "$1" | grep -q "filesize=100000" 492*4882a593Smuzhiyun pass_fail "TC10: load 2MB from the last 1MB of $4 loads 1MB" 493*4882a593Smuzhiyun 494*4882a593Smuzhiyun # Check 1mb chunk write 495*4882a593Smuzhiyun grep -A2 "Test Case 11a " "$1" | grep -q '1048576 bytes written' 496*4882a593Smuzhiyun pass_fail "TC11: 1MB write to $3.w - write succeeded" 497*4882a593Smuzhiyun check_md5 "Test Case 11b " "$1" "$2" 1 \ 498*4882a593Smuzhiyun "TC11: 1MB write to $3.w - content verified" 499*4882a593Smuzhiyun 500*4882a593Smuzhiyun # Check lookup of 'dot' directory 501*4882a593Smuzhiyun grep -A4 "Test Case 12 " "$1" | grep -q 'Unable to write file' 502*4882a593Smuzhiyun pass_fail "TC12: 1MB write to . - write denied" 503*4882a593Smuzhiyun 504*4882a593Smuzhiyun # Check directory traversal 505*4882a593Smuzhiyun grep -A2 "Test Case 13a " "$1" | grep -q '1048576 bytes written' 506*4882a593Smuzhiyun pass_fail "TC13: 1MB write to ./$3.w2 - write succeeded" 507*4882a593Smuzhiyun check_md5 "Test Case 13b " "$1" "$2" 1 \ 508*4882a593Smuzhiyun "TC13: 1MB read from ./$3.w2 - content verified" 509*4882a593Smuzhiyun check_md5 "Test Case 13c " "$1" "$2" 1 \ 510*4882a593Smuzhiyun "TC13: 1MB read from $3.w2 - content verified" 511*4882a593Smuzhiyun 512*4882a593Smuzhiyun echo "** End $1" 513*4882a593Smuzhiyun} 514*4882a593Smuzhiyun 515*4882a593Smuzhiyun# Takes in one parameter which is "fs" or "nonfs", which then dictates 516*4882a593Smuzhiyun# if a fs test (size/load/save) or a nonfs test (fatread/extread) needs to 517*4882a593Smuzhiyun# be performed. 518*4882a593Smuzhiyunfunction test_fs_nonfs() { 519*4882a593Smuzhiyun echo "Creating files in $fs image if not already present." 520*4882a593Smuzhiyun create_files $IMAGE $MD5_FILE_FS 521*4882a593Smuzhiyun 522*4882a593Smuzhiyun OUT_FILE="${OUT}.$1.${fs}.out" 523*4882a593Smuzhiyun test_image $IMAGE $fs $SMALL_FILE $BIG_FILE $1 "" \ 524*4882a593Smuzhiyun > ${OUT_FILE} 2>&1 525*4882a593Smuzhiyun # strip out noise from fs code 526*4882a593Smuzhiyun grep -v -e "File System is consistent\|update journal finished" \ 527*4882a593Smuzhiyun -e "reading .*\.file\|writing .*\.file.w" \ 528*4882a593Smuzhiyun < ${OUT_FILE} > ${OUT_FILE}_clean 529*4882a593Smuzhiyun check_results ${OUT_FILE}_clean $MD5_FILE_FS $SMALL_FILE \ 530*4882a593Smuzhiyun $BIG_FILE 531*4882a593Smuzhiyun TOTAL_FAIL=$((TOTAL_FAIL + FAIL)) 532*4882a593Smuzhiyun TOTAL_PASS=$((TOTAL_PASS + PASS)) 533*4882a593Smuzhiyun echo "Summary: PASS: $PASS FAIL: $FAIL" 534*4882a593Smuzhiyun echo "--------------------------------------------" 535*4882a593Smuzhiyun} 536*4882a593Smuzhiyun 537*4882a593Smuzhiyun# ******************** 538*4882a593Smuzhiyun# * End of functions * 539*4882a593Smuzhiyun# ******************** 540*4882a593Smuzhiyun 541*4882a593Smuzhiyuncheck_clean "$1" 542*4882a593Smuzhiyuncheck_prereq 543*4882a593Smuzhiyuncompile_sandbox 544*4882a593Smuzhiyunprepare_env 545*4882a593Smuzhiyun 546*4882a593Smuzhiyun# Track TOTAL_FAIL and TOTAL_PASS 547*4882a593SmuzhiyunTOTAL_FAIL=0 548*4882a593SmuzhiyunTOTAL_PASS=0 549*4882a593Smuzhiyun 550*4882a593Smuzhiyun# In each loop, for a given file system image, we test both the 551*4882a593Smuzhiyun# fs command, like load/size/write, the file system specific command 552*4882a593Smuzhiyun# like: ext4load/ext4size/ext4write and the sb load/ls/save commands. 553*4882a593Smuzhiyunfor fs in ext4 fat; do 554*4882a593Smuzhiyun 555*4882a593Smuzhiyun echo "Creating $fs image if not already present." 556*4882a593Smuzhiyun IMAGE=${IMG}.${fs}.img 557*4882a593Smuzhiyun MD5_FILE_FS="${MD5_FILE}.${fs}" 558*4882a593Smuzhiyun create_image $IMAGE $fs 559*4882a593Smuzhiyun 560*4882a593Smuzhiyun # sb commands test 561*4882a593Smuzhiyun echo "Creating files in $fs image if not already present." 562*4882a593Smuzhiyun create_files $IMAGE $MD5_FILE_FS 563*4882a593Smuzhiyun 564*4882a593Smuzhiyun # Lets mount the image and test sb hostfs commands 565*4882a593Smuzhiyun mkdir -p "$MOUNT_DIR" 566*4882a593Smuzhiyun if [ "$fs" = "fat" ]; then 567*4882a593Smuzhiyun uid="uid=`id -u`" 568*4882a593Smuzhiyun else 569*4882a593Smuzhiyun uid="" 570*4882a593Smuzhiyun fi 571*4882a593Smuzhiyun sudo mount -o loop,rw,$uid "$IMAGE" "$MOUNT_DIR" 572*4882a593Smuzhiyun sudo chmod 777 "$MOUNT_DIR" 573*4882a593Smuzhiyun 574*4882a593Smuzhiyun OUT_FILE="${OUT}.sb.${fs}.out" 575*4882a593Smuzhiyun test_image $IMAGE $fs $SMALL_FILE $BIG_FILE sb `pwd`/$MOUNT_DIR \ 576*4882a593Smuzhiyun > ${OUT_FILE} 2>&1 577*4882a593Smuzhiyun sudo umount "$MOUNT_DIR" 578*4882a593Smuzhiyun rmdir "$MOUNT_DIR" 579*4882a593Smuzhiyun 580*4882a593Smuzhiyun check_results $OUT_FILE $MD5_FILE_FS $SMALL_FILE $BIG_FILE 581*4882a593Smuzhiyun TOTAL_FAIL=$((TOTAL_FAIL + FAIL)) 582*4882a593Smuzhiyun TOTAL_PASS=$((TOTAL_PASS + PASS)) 583*4882a593Smuzhiyun echo "Summary: PASS: $PASS FAIL: $FAIL" 584*4882a593Smuzhiyun echo "--------------------------------------------" 585*4882a593Smuzhiyun 586*4882a593Smuzhiyun test_fs_nonfs nonfs 587*4882a593Smuzhiyun test_fs_nonfs fs 588*4882a593Smuzhiyundone 589*4882a593Smuzhiyun 590*4882a593Smuzhiyunecho "Total Summary: TOTAL PASS: $TOTAL_PASS TOTAL FAIL: $TOTAL_FAIL" 591*4882a593Smuzhiyunecho "--------------------------------------------" 592*4882a593Smuzhiyunif [ $TOTAL_FAIL -eq 0 ]; then 593*4882a593Smuzhiyun echo "PASSED" 594*4882a593Smuzhiyun exit 0 595*4882a593Smuzhiyunelse 596*4882a593Smuzhiyun echo "FAILED" 597*4882a593Smuzhiyun exit 1 598*4882a593Smuzhiyunfi 599