File: datamash-io-errors.sh

package info (click to toggle)
datamash 1.9-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 13,600 kB
  • sloc: ansic: 65,320; sh: 8,982; perl: 5,127; makefile: 250; sed: 16
file content (113 lines) | stat: -rwxr-xr-x 3,784 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/bin/sh
#   Unit Tests for GNU Datamash - I/O error simulation

#    Copyright (C) 2014-2021 Assaf Gordon <assafgordon@gmail.com>
#
#    This file is part of GNU Datamash.
#
#    GNU Datamash is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    GNU Datamash 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 General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with GNU Datamash.  If not, see <https://www.gnu.org/licenses/>.
#
#    Written by Assaf Gordon

##
## This script tests datamash's handling of I/O errors.
## It requires special setup, and is skipped unless found.
##

. "${test_dir=.}/init.sh"; path_prepend_ ./src

expensive_

fail=0

##
## The required mounted file-systems
##
FULLFS=/tmp/fullfs/
BADFS=/tmp/badfs/

which mountpoint >/dev/null 2>&1 ||
    skip_ "requires mountpoint program"
stdbuf --version >/dev/null 2>&1 ||
    skip_ "requires GNU stdbuf program"
stat --version >/dev/null 2>&1 ||
    skip_ "requires GNU stat program"
mountpoint -q "$FULLFS" ||
    skip_ "requires special mounted file system '$FULLFS'"
mountpoint -q "$BADFS" ||
    skip_ "requires special mounted file system '$BADFS'"

##
## Clean files in the (almost) full file-system.
## This will ensure few writes are successful before getting "no space" error
## (unlike "/dev/full").
##
clean_full_fs()
{
  find "$FULLFS" -maxdepth 1 -type f -delete ||
    framework_failure_ "failed to clean full-fs"
  # Give the system time to actually delete the files
  fullfs_retries=1
  FREE=0
  while test $fullfs_retries -lt 5 && test $FREE -le 5 ; do
    sync ; sleep 1
    FREE=$(stat --file-system -c %a "$FULLFS") ||
      framework_failure_ "failed to find free space on $FULLFS"
    fullfs_retries=$((fullfs_retries+1))
  done
  # Ensure the (almost) full file system has a bit of free space...
  test "$FREE" -gt 5 ||
    framework_failure_ "almost-full-file system has no free space"
  # ... but not too much (otherwise the program will not get "no space" errors).
  test "$FREE" -lt 64 ||
    framework_failure_ "almost-full-file system has too much free spcae"
}

##
## Sanity checks:
## 1. Ensure the corrupted file system is corrupted
cat "$BADFS/numbers.txt" >/dev/null 2>&1 &&
    framework_failure_ "corrupted file system did not trigger I/O error"
## 2. Ensure the (almost) full file system gets full
clean_full_fs
seq 10000 >"$FULLFS/test.txt" 2>/dev/null &&
    framework_failure_ "almost full file system did not trigger no-space error"
clean_full_fs

## Test 1:
##  input error, reading file directly
datamash sum 1 < "$BADFS/numbers.txt" >/dev/null &&
	{ warn_ "datamash failed to detect read error" ; fail=1 ; }

## Test 2:
##  input error, using sort (and popen/pipe)
datamash -s -g 1 sum 1 < "$BADFS/numbers.txt" >/dev/null &&
	{ warn_ "datamash+sort failed to detect read error" ; fail=1 ; }

## Test 3:
##  output error, default line-buffering
seq 10000 | datamash -g 1 count 1 > "$FULLFS/test.txt" &&
	{ warn_ "datamash failed to detect no-space error" ; fail=1 ; }
clean_full_fs

## Test 4:
##  output error, with line-buffering.
##  This means few of the first "write()" calls will succeed,
##  and later ones should fail with "no space" (which is different than
##  writing to "/dev/full").
seq 10000 | stdbuf -oL datamash -g 1 count 1 > "$FULLFS/test.txt" &&
	{ warn_ "datamash failed to detect no-space error" ; fail=1 ; }
clean_full_fs

Exit $fail