| OLD | NEW |
| (Empty) |
| 1 #!/bin/bash | |
| 2 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 # | |
| 6 # A crazily simple mocking framework for use with shunit2. | |
| 7 # In addition, a number of custom mocks are included which | |
| 8 # are used by cryptohome tests. | |
| 9 # Note, these are not subshell friendly so avoid () and |. | |
| 10 | |
| 11 # mock | |
| 12 # Replaces a variable with a given function call in a reversible | |
| 13 # manner. This is for use with utils/declare_commands. | |
| 14 # TODO: embed old command in the current_mocks instead of using old_$cmd | |
| 15 current_mocks="" | |
| 16 function mock() { | |
| 17 local cmd="$1" | |
| 18 local mock="$2" | |
| 19 local old_cmdname=old_$cmd | |
| 20 eval ${old_cmdname}="${!cmd}" | |
| 21 eval $cmd=$mock | |
| 22 current_mocks=$(echo "${current_mocks};$cmd;") | |
| 23 } | |
| 24 | |
| 25 # unmock | |
| 26 # Restores the original value in a given variable from a globally | |
| 27 # stored list. | |
| 28 function unmock() { | |
| 29 for cmd in "$@"; do | |
| 30 local old_cmdname=old_$cmd | |
| 31 eval $cmd="${!old_cmdname}" | |
| 32 current_mocks="${current_mocks/;$cmd;/}" | |
| 33 # Unset backup if nested mock. no gurantee the replacements | |
| 34 # are the same though. | |
| 35 if [[ "$current_mocks" == "${current_mocks/;$cmd;/}" ]]; then | |
| 36 unset ${old_cmdname} | |
| 37 fi | |
| 38 done | |
| 39 } | |
| 40 | |
| 41 # unmock_all | |
| 42 # Walks all current mocks and unmocks them. | |
| 43 function unmock_all() { | |
| 44 if [[ -n "${current_mocks}" ]]; then | |
| 45 unmock ${current_mocks//;/ } | |
| 46 fi | |
| 47 } | |
| 48 | |
| 49 # A boat load of mocks. | |
| 50 function mock::ok() { | |
| 51 return 0 | |
| 52 } | |
| 53 | |
| 54 function mock::fail() { | |
| 55 echo -n "[mock::fail] " 1>&2 | |
| 56 return 1 | |
| 57 } | |
| 58 | |
| 59 # Creates a function for mocking with the given arguments and i/o. | |
| 60 # Input: | |
| 61 # - $1: mock_name | |
| 62 # - $2: "'arg 1' 'arg 2' ..." | |
| 63 # - $3: "stdout" | |
| 64 # - $4: "stderr" | |
| 65 # - $5: "success return code" | |
| 66 # - $6: "failure return code" | |
| 67 function mock::factory::arg_validating() { | |
| 68 eval "function mock::$1() { | |
| 69 for arg in $2; do | |
| 70 if [[ \"\$arg\" == \"MOCK_WILD\" ]]; then | |
| 71 true # a-ok | |
| 72 elif [[ \"\$1\" != \"\$arg\" ]]; then | |
| 73 echo -ne \"$4\" 1>&2 | |
| 74 return $6 | |
| 75 fi | |
| 76 shift | |
| 77 done | |
| 78 echo -ne \"$3\" | |
| 79 return $5 | |
| 80 }" | |
| 81 } | |
| 82 | |
| 83 # Creates a function for mocking with the given arguments and i/o. | |
| 84 # Input: | |
| 85 # - $1: mock_name | |
| 86 # - $2: "stdin" | |
| 87 # - $3: "'arg 1' 'arg 2' ..." | |
| 88 # - $4: "stdout" | |
| 89 # - $5: "stderr" | |
| 90 # - $6: "success return code" | |
| 91 # - $7: "failure return code" | |
| 92 function mock::factory::input_and_arg_validating() { | |
| 93 eval "function mock::$1() { | |
| 94 read input | |
| 95 if [[ "\$input" != "$2" ]]; then | |
| 96 # TODO: really need to make this give meaningful mock logs. | |
| 97 echo \"\$FUNCNAME(\$@): Mismatched input: \\\"\$input\\\" != \\\"$2\\\"\"
1>&2 | |
| 98 echo -ne \"$5\" 1>&2 | |
| 99 return $7 | |
| 100 fi | |
| 101 for arg in $3; do | |
| 102 if [[ \"\$arg\" == \"MOCK_WILD\" ]]; then | |
| 103 true # a-ok | |
| 104 elif [[ \"\$1\" != \"\$arg\" ]]; then | |
| 105 echo -ne \"$5\" 1>&2 | |
| 106 return $7 | |
| 107 fi | |
| 108 shift | |
| 109 done | |
| 110 echo -ne \"$4\" | |
| 111 return $6 | |
| 112 }" | |
| 113 } | |
| 114 | |
| 115 # Creates a function for mocking with the given output. | |
| 116 # Input: | |
| 117 # - $1: mock_name | |
| 118 # - $2: "stdout" | |
| 119 # - $3: "stderr" | |
| 120 # - $4: "return code" | |
| 121 function mock::factory::simple_output() { | |
| 122 eval "function mock::$1() { | |
| 123 echo -ne "$2" | |
| 124 echo -ne "$3" 1>&2 | |
| 125 return $4 | |
| 126 }" | |
| 127 } | |
| 128 | |
| 129 # mock::helper::chained_shifter | |
| 130 # A helper function for factory::chained | |
| 131 # below which just pops the first entry off | |
| 132 # the given chained list. | |
| 133 # Input: | |
| 134 # - $1: chained list name | |
| 135 # - $*: current list | |
| 136 function mock::helper::chained_shifter() { | |
| 137 container="$1" | |
| 138 shift # pop name | |
| 139 shift # pop off first element | |
| 140 count=0 | |
| 141 eval "${container}=()" | |
| 142 for arg in "$@"; do | |
| 143 eval "${container}[$count]=\"$arg\"" | |
| 144 count=$((count+1)) | |
| 145 done | |
| 146 } | |
| 147 | |
| 148 # mock::factory::chained | |
| 149 # Creates a function which iterates over a list of expected, or chained, calls. | |
| 150 # When the end of the list is reached, the generated function will always | |
| 151 # return an error. | |
| 152 # Note: this is not subshell friendly as a global variable stores the current | |
| 153 # function chain list for the given wrapper function. If it crosses subsh
ell | |
| 154 # boundaries, it will not be properly updated. | |
| 155 # Input: | |
| 156 # - $1: function_name | |
| 157 # - $*: each subsequent expected function to call. | |
| 158 function mock::factory::chained() { | |
| 159 fname="$1" | |
| 160 shift | |
| 161 # Setup a global chained list to work from | |
| 162 eval "mock_${fname}_funcs=("$@")" | |
| 163 | |
| 164 eval "function mock::$fname() { | |
| 165 if [[ \${#mock_${fname}_funcs[*]} -eq 0 ]]; then | |
| 166 echo \"Chained mock called too many times\" 1>&2 | |
| 167 return 1 | |
| 168 fi | |
| 169 # If you want this debugging message, you are probably having subshell | |
| 170 # consistency problems. | |
| 171 # echo \"Calling \${mock_${fname}_funcs[@]} with args \\\"\$@\\\"\" 1>&2 | |
| 172 \${mock_${fname}_funcs[0]} \"\$@\" | |
| 173 local ret=\$? | |
| 174 mock::helper::chained_shifter mock_${fname}_funcs \"\${mock_${fname}_funcs[@
]}\" | |
| 175 # echo \"Remaining: \${mock_${fname}_funcs[@]}\" 1>&2 | |
| 176 return \$ret | |
| 177 }" | |
| 178 } | |
| 179 | |
| 180 | |
| 181 | |
| OLD | NEW |