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
     #
103
     #
104
     # Usage:
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
     # Run CMD with all ARGs and if exit status is zero, announce assertion
108
     # Run CMD with all ARGs and if exit status is zero, announce assertion
109
     # success (PASS), otherwise announce assertion failure (FAIL).
109
     # success (PASS), otherwise announce assertion failure (FAIL).
113
     # thereof.  E, g. expression '0,10-20' would be a valid expression,
113
     # thereof.  E, g. expression '0,10-20' would be a valid expression,
114
     # matching 0, 11, 20, but not 2 or 21.
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
     # If path R_OUT or R_ERR are provided, standard output and standard
120
     # If path R_OUT or R_ERR are provided, standard output and standard
117
     # error are saved to respective files.
121
     # error are saved to respective files.
118
     #
122
     #
119
     # See COMMON ARGUMENTS section for common assert options.
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
     local __jat__cmd=()
129
     local __jat__cmd=()
122
     local __jat__r_es
130
     local __jat__r_es
123
     local __jat__o_es=0
131
     local __jat__o_es=0
126
     local __jat__etype=TEST_ERROR
134
     local __jat__etype=TEST_ERROR
127
     local __jat__r_out
135
     local __jat__r_out
128
     local __jat__r_err
136
     local __jat__r_err
137
+    local __jat__r_esf
129
     #
138
     #
130
     # NOTE: names need to be qualified because they might interfere
139
     # NOTE: names need to be qualified because they might interfere
131
     #       with the actual execution of the assert command.
140
     #       with the actual execution of the assert command.
135
         -h) __jat__hint=$2; shift 2 || { __jat__usage "missing HINT"; return 2; } ;;
144
         -h) __jat__hint=$2; shift 2 || { __jat__usage "missing HINT"; return 2; } ;;
136
         -e) __jat__r_err=$2; shift 2 || { __jat__usage "missing R_ERR"; return 2; } ;;
145
         -e) __jat__r_err=$2; shift 2 || { __jat__usage "missing R_ERR"; return 2; } ;;
137
         -o) __jat__r_out=$2; shift 2 || { __jat__usage "missing R_OUT"; return 2; } ;;
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
         -S) __jat__o_es=$2; shift 2 || { __jat__usage "missing ES_EXPR"; return 2; } ;;
148
         -S) __jat__o_es=$2; shift 2 || { __jat__usage "missing ES_EXPR"; return 2; } ;;
139
         --) shift; break ;;
149
         --) shift; break ;;
140
         *) break ;;
150
         *) break ;;
150
         *:0) "${__jat__cmd[@]}" >"$__jat__r_out" ;;
160
         *:0) "${__jat__cmd[@]}" >"$__jat__r_out" ;;
151
         *:*) "${__jat__cmd[@]}" >"$__jat__r_out" 2>"$__jat__r_err" ;;
161
         *:*) "${__jat__cmd[@]}" >"$__jat__r_out" 2>"$__jat__r_err" ;;
152
     esac; __jat__r_es=$?
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
     if __jat__es_match "$__jat__o_es" "$__jat__r_es"; then
168
     if __jat__es_match "$__jat__o_es" "$__jat__r_es"; then
155
         __jat__etype=PASS
169
         __jat__etype=PASS
156
     else
170
     else
222
     #
236
     #
223
     # Usage:
237
     # Usage:
224
     #
238
     #
225
-    #     jat__eval [-S ES_EXPR] [--] CODE
239
+    #     jat__eval [-s R_ESF] [-S ES_EXPR] [--] CODE
226
     #
240
     #
227
     # Run CODE using eval builtin and if exit status is zero, announce assertion
241
     # Run CODE using eval builtin and if exit status is zero, announce assertion
228
     # success (PASS), otherwise announce assertion failure (FAIL).
242
     # success (PASS), otherwise announce assertion failure (FAIL).
232
     # thereof.  E, g. expression '0,10-20' would be a valid expression,
246
     # thereof.  E, g. expression '0,10-20' would be a valid expression,
233
     # matching 0, 11, 20, but not 2 or 21.
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
     # See COMMON ARGUMENTS section for common assert options.
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
     local __jat__code=""
263
     local __jat__code=""
241
     local __jat__r_es
264
     local __jat__r_es
265
+    local __jat__r_esf
242
     local __jat__o_es=0
266
     local __jat__o_es=0
243
     local __jat__hint
267
     local __jat__hint
244
     local __jat__beids=()
268
     local __jat__beids=()
250
     while true; do case $1 in
274
     while true; do case $1 in
251
         -b) __jat__beids+=("$2"); shift 2 || { __jat__usage "missing BEID"; return 2; } ;;
275
         -b) __jat__beids+=("$2"); shift 2 || { __jat__usage "missing BEID"; return 2; } ;;
252
         -h) __jat__hint=$2; shift 2 || { __jat__usage "missing HINT"; return 2; } ;;
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
         -S) __jat__o_es=$2; shift 2 || { __jat__usage "missing ES_EXPR"; return 2; } ;;
278
         -S) __jat__o_es=$2; shift 2 || { __jat__usage "missing ES_EXPR"; return 2; } ;;
254
         --) shift; break ;;
279
         --) shift; break ;;
255
         *) break ;;
280
         *) break ;;
265
     }
290
     }
266
     jat__log_info "CODE: $__jat__code"
291
     jat__log_info "CODE: $__jat__code"
267
     eval "$__jat__code"; __jat__r_es=$?
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
     debug -v __jat__r_es
297
     debug -v __jat__r_es
269
     if __jat__es_match "$__jat__o_es" "$__jat__r_es"; then
298
     if __jat__es_match "$__jat__o_es" "$__jat__r_es"; then
270
         __jat__etype=PASS
299
         __jat__etype=PASS