Browse Source

Add support for saving exit status into file

Since exit status of code-executing assert functions cannot be
guarranteed to match exit status of the code being executed, there is
now a way to get the latter in more reliable way.  This should be also
useful in cases when there are further asserts on value of the status.
Alois Mahdal 6 years ago
parent
commit
c6a7256976
1 changed files with 34 additions and 5 deletions
  1. 34
    5
      src/jat.sh.skel

+ 34
- 5
src/jat.sh.skel View File

@@ -103,7 +103,7 @@ jat__cmd() {
103 103
     #
104 104
     # Usage:
105 105
     #
106
-    #     jat__cmd [-o R_OUT] [-e R_ERR] [-S ES_EXPR] [--] CMD [ARG]..
106
+    #     jat__cmd [-o R_OUT] [-e R_ERR] [-s R_ESF] [-S ES_EXPR] [--] CMD [ARG]..
107 107
     #
108 108
     # Run CMD with all ARGs and if exit status is zero, announce assertion
109 109
     # success (PASS), otherwise announce assertion failure (FAIL).
@@ -113,11 +113,19 @@ jat__cmd() {
113 113
     # thereof.  E, g. expression '0,10-20' would be a valid expression,
114 114
     # matching 0, 11, 20, but not 2 or 21.
115 115
     #
116
+    # If R_ESF is passed, it will be treated as path to file where exit status
117
+    # of CODE is written.  This is recommended over consulting $?, since the
118
+    # latter is not reliable; see below.
119
+    #
116 120
     # If path R_OUT or R_ERR are provided, standard output and standard
117 121
     # error are saved to respective files.
118 122
     #
119 123
     # See COMMON ARGUMENTS section for common assert options.
120 124
     #
125
+    # Exit status of the this function normally will, but IS NOT GUARRANTEED TO
126
+    # correspond to the exit status of the CODE. For example, if the function
127
+    # call is incomplete, the exit status will be 2.
128
+    #
121 129
     local __jat__cmd=()
122 130
     local __jat__r_es
123 131
     local __jat__o_es=0
@@ -126,6 +134,7 @@ jat__cmd() {
126 134
     local __jat__etype=TEST_ERROR
127 135
     local __jat__r_out
128 136
     local __jat__r_err
137
+    local __jat__r_esf
129 138
     #
130 139
     # NOTE: names need to be qualified because they might interfere
131 140
     #       with the actual execution of the assert command.
@@ -135,6 +144,7 @@ jat__cmd() {
135 144
         -h) __jat__hint=$2; shift 2 || { __jat__usage "missing HINT"; return 2; } ;;
136 145
         -e) __jat__r_err=$2; shift 2 || { __jat__usage "missing R_ERR"; return 2; } ;;
137 146
         -o) __jat__r_out=$2; shift 2 || { __jat__usage "missing R_OUT"; return 2; } ;;
147
+        -s) __jat__r_esf=$2; shift 2 || { __jat__usage "missing R_ESF"; return 2; } ;;
138 148
         -S) __jat__o_es=$2; shift 2 || { __jat__usage "missing ES_EXPR"; return 2; } ;;
139 149
         --) shift; break ;;
140 150
         *) break ;;
@@ -150,7 +160,11 @@ jat__cmd() {
150 160
         *:0) "${__jat__cmd[@]}" >"$__jat__r_out" ;;
151 161
         *:*) "${__jat__cmd[@]}" >"$__jat__r_out" 2>"$__jat__r_err" ;;
152 162
     esac; __jat__r_es=$?
153
-    debug -v __jat__r_es
163
+    debug -v __jat__r_es __jat__r_esf
164
+    if test -n "$__jat__r_esf"; then
165
+        echo $__jat__r_es > "$__jat__r_esf" \
166
+         || jat__log_error "error writing R_ESF file: $__jat__r_esf"
167
+    fi
154 168
     if __jat__es_match "$__jat__o_es" "$__jat__r_es"; then
155 169
         __jat__etype=PASS
156 170
     else
@@ -222,7 +236,7 @@ jat__eval() {
222 236
     #
223 237
     # Usage:
224 238
     #
225
-    #     jat__eval [-S ES_EXPR] [--] CODE
239
+    #     jat__eval [-s R_ESF] [-S ES_EXPR] [--] CODE
226 240
     #
227 241
     # Run CODE using eval builtin and if exit status is zero, announce assertion
228 242
     # success (PASS), otherwise announce assertion failure (FAIL).
@@ -232,13 +246,23 @@ jat__eval() {
232 246
     # thereof.  E, g. expression '0,10-20' would be a valid expression,
233 247
     # matching 0, 11, 20, but not 2 or 21.
234 248
     #
235
-    # This is similar to jat__cmd(), except that code is checked agains syntax
236
-    # errors and user is given slightly full control over redirections.
249
+    # If R_ESF is passed, it will be treated as path to file where exit status
250
+    # of CODE is written.  This is recommended over consulting $?, since the
251
+    # latter is not reliable; see below.
252
+    #
253
+    # This is similar to jat__cmd(), except that code is checked against syntax
254
+    # errors and user is given full control over redirections.
237 255
     #
238 256
     # See COMMON ARGUMENTS section for common assert options.
239 257
     #
258
+    # Exit status of the this function normally will, but IS NOT GUARRANTEED TO
259
+    # correspond to the exit status of the CODE. For example, if the function
260
+    # call is incomplete, the exit status will be 2.  If there is syntax error
261
+    # in CODE, the exit status will be 3.
262
+    #
240 263
     local __jat__code=""
241 264
     local __jat__r_es
265
+    local __jat__r_esf
242 266
     local __jat__o_es=0
243 267
     local __jat__hint
244 268
     local __jat__beids=()
@@ -250,6 +274,7 @@ jat__eval() {
250 274
     while true; do case $1 in
251 275
         -b) __jat__beids+=("$2"); shift 2 || { __jat__usage "missing BEID"; return 2; } ;;
252 276
         -h) __jat__hint=$2; shift 2 || { __jat__usage "missing HINT"; return 2; } ;;
277
+        -s) __jat__r_esf=$2; shift 2 || { __jat__usage "missing R_ESF"; return 2; } ;;
253 278
         -S) __jat__o_es=$2; shift 2 || { __jat__usage "missing ES_EXPR"; return 2; } ;;
254 279
         --) shift; break ;;
255 280
         *) break ;;
@@ -265,6 +290,10 @@ jat__eval() {
265 290
     }
266 291
     jat__log_info "CODE: $__jat__code"
267 292
     eval "$__jat__code"; __jat__r_es=$?
293
+    if test -n "$__jat__r_esf"; then
294
+        echo $__jat__r_es > "$__jat__r_esf" \
295
+         || jat__log_error "error writing R_ESF file: $__jat__r_esf"
296
+    fi
268 297
     debug -v __jat__r_es
269 298
     if __jat__es_match "$__jat__o_es" "$__jat__r_es"; then
270 299
         __jat__etype=PASS