aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/README.md6
-rwxr-xr-xtest/functional/example_test.py2
-rwxr-xr-xtest/functional/feature_blocksdir.py2
-rwxr-xr-xtest/functional/feature_shutdown.py10
-rwxr-xr-xtest/functional/interface_rest.py29
-rwxr-xr-xtest/functional/interface_rpc.py13
-rwxr-xr-xtest/functional/p2p_segwit.py2
-rwxr-xr-xtest/lint/check-doc.py4
-rwxr-xr-xtest/lint/lint-format-strings.sh28
-rwxr-xr-xtest/lint/lint-python.sh148
-rwxr-xr-xtest/lint/lint-shell.sh46
-rwxr-xr-xtest/lint/lint-whitespace.sh2
12 files changed, 172 insertions, 120 deletions
diff --git a/test/functional/README.md b/test/functional/README.md
index d40052ac93..628c77eb11 100644
--- a/test/functional/README.md
+++ b/test/functional/README.md
@@ -20,9 +20,13 @@ don't have test cases for.
- Where possible, try to adhere to [PEP-8 guidelines](https://www.python.org/dev/peps/pep-0008/)
- Use a python linter like flake8 before submitting PRs to catch common style
nits (eg trailing whitespace, unused imports, etc)
+- The oldest supported Python version is specified in [doc/dependencies.md](/doc/dependencies.md).
+ Consider using [pyenv](https://github.com/pyenv/pyenv), which checks [.python-version](/.python-version),
+ to prevent accidentally introducing modern syntax from an unsupported Python version.
+ The Travis linter also checks this, but [possibly not in all cases](https://github.com/bitcoin/bitcoin/pull/14884#discussion_r239585126).
- See [the python lint script](/test/lint/lint-python.sh) that checks for violations that
could lead to bugs and issues in the test code.
-- Avoid wildcard imports where possible
+- Avoid wildcard imports
- Use a module-level docstring to describe what the test is testing, and how it
is testing it.
- When subclassing the BitcoinTestFramwork, place overrides for the
diff --git a/test/functional/example_test.py b/test/functional/example_test.py
index be3544ee74..f367e4fca8 100755
--- a/test/functional/example_test.py
+++ b/test/functional/example_test.py
@@ -13,7 +13,7 @@ is testing and *how* it's being tested
# libraries then local imports).
from collections import defaultdict
-# Avoid wildcard * imports if possible
+# Avoid wildcard * imports
from test_framework.blocktools import (create_block, create_coinbase)
from test_framework.messages import CInv
from test_framework.mininode import (
diff --git a/test/functional/feature_blocksdir.py b/test/functional/feature_blocksdir.py
index c170f510c8..3a4889bbe9 100755
--- a/test/functional/feature_blocksdir.py
+++ b/test/functional/feature_blocksdir.py
@@ -18,6 +18,8 @@ class BlocksdirTest(BitcoinTestFramework):
def run_test(self):
self.stop_node(0)
+ assert os.path.isdir(os.path.join(self.nodes[0].datadir, "regtest", "blocks"))
+ assert not os.path.isdir(os.path.join(self.nodes[0].datadir, "blocks"))
shutil.rmtree(self.nodes[0].datadir)
initialize_datadir(self.options.tmpdir, 0)
self.log.info("Starting with nonexistent blocksdir ...")
diff --git a/test/functional/feature_shutdown.py b/test/functional/feature_shutdown.py
index b633fabb1f..5084cb1322 100755
--- a/test/functional/feature_shutdown.py
+++ b/test/functional/feature_shutdown.py
@@ -5,7 +5,7 @@
"""Test bitcoind shutdown."""
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import assert_equal, get_rpc_proxy
+from test_framework.util import assert_equal, get_rpc_proxy, wait_until
from threading import Thread
def test_long_call(node):
@@ -20,8 +20,14 @@ class ShutdownTest(BitcoinTestFramework):
def run_test(self):
node = get_rpc_proxy(self.nodes[0].url, 1, timeout=600, coveragedir=self.nodes[0].coverage_dir)
+ # Force connection establishment by executing a dummy command.
+ node.getblockcount()
Thread(target=test_long_call, args=(node,)).start()
- # wait 1 second to ensure event loop waits for current connections to close
+ # Wait until the server is executing the above `waitfornewblock`.
+ wait_until(lambda: len(self.nodes[0].getrpcinfo()['active_commands']) == 2)
+ # Wait 1 second after requesting shutdown but not before the `stop` call
+ # finishes. This is to ensure event loop waits for current connections
+ # to close.
self.stop_node(0, wait=1000)
if __name__ == '__main__':
diff --git a/test/functional/interface_rest.py b/test/functional/interface_rest.py
index 72455a0788..f850a54462 100755
--- a/test/functional/interface_rest.py
+++ b/test/functional/interface_rest.py
@@ -199,9 +199,19 @@ class RESTTest (BitcoinTestFramework):
self.nodes[0].generate(1) # generate block to not affect upcoming tests
self.sync_all()
- self.log.info("Test the /block and /headers URIs")
+ self.log.info("Test the /block, /blockhashbyheight and /headers URIs")
bb_hash = self.nodes[0].getbestblockhash()
+ # Check result if block does not exists
+ assert_equal(self.test_rest_request('/headers/1/0000000000000000000000000000000000000000000000000000000000000000'), [])
+ self.test_rest_request('/block/0000000000000000000000000000000000000000000000000000000000000000', status=404, ret_type=RetType.OBJ)
+
+ # Check result if block is not in the active chain
+ self.nodes[0].invalidateblock(bb_hash)
+ assert_equal(self.test_rest_request('/headers/1/{}'.format(bb_hash)), [])
+ self.test_rest_request('/block/{}'.format(bb_hash))
+ self.nodes[0].reconsiderblock(bb_hash)
+
# Check binary format
response = self.test_rest_request("/block/{}".format(bb_hash), req_type=ReqType.BIN, ret_type=RetType.OBJ)
assert_greater_than(int(response.getheader('content-length')), 80)
@@ -228,6 +238,23 @@ class RESTTest (BitcoinTestFramework):
# Check json format
block_json_obj = self.test_rest_request("/block/{}".format(bb_hash))
assert_equal(block_json_obj['hash'], bb_hash)
+ assert_equal(self.test_rest_request("/blockhashbyheight/{}".format(block_json_obj['height']))['blockhash'], bb_hash)
+
+ # Check hex/bin format
+ resp_hex = self.test_rest_request("/blockhashbyheight/{}".format(block_json_obj['height']), req_type=ReqType.HEX, ret_type=RetType.OBJ)
+ assert_equal(resp_hex.read().decode('utf-8').rstrip(), bb_hash)
+ resp_bytes = self.test_rest_request("/blockhashbyheight/{}".format(block_json_obj['height']), req_type=ReqType.BIN, ret_type=RetType.BYTES)
+ blockhash = binascii.hexlify(resp_bytes[::-1]).decode('utf-8')
+ assert_equal(blockhash, bb_hash)
+
+ # Check invalid blockhashbyheight requests
+ resp = self.test_rest_request("/blockhashbyheight/abc", ret_type=RetType.OBJ, status=400)
+ assert_equal(resp.read().decode('utf-8').rstrip(), "Invalid height: abc")
+ resp = self.test_rest_request("/blockhashbyheight/1000000", ret_type=RetType.OBJ, status=404)
+ assert_equal(resp.read().decode('utf-8').rstrip(), "Block height out of range")
+ resp = self.test_rest_request("/blockhashbyheight/-1", ret_type=RetType.OBJ, status=400)
+ assert_equal(resp.read().decode('utf-8').rstrip(), "Invalid height: -1")
+ self.test_rest_request("/blockhashbyheight/", ret_type=RetType.OBJ, status=400)
# Compare with json block header
json_obj = self.test_rest_request("/headers/1/{}".format(bb_hash))
diff --git a/test/functional/interface_rpc.py b/test/functional/interface_rpc.py
index e3d7b0655d..b6955d4492 100755
--- a/test/functional/interface_rpc.py
+++ b/test/functional/interface_rpc.py
@@ -5,13 +5,23 @@
"""Tests some generic aspects of the RPC interface."""
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import assert_equal
+from test_framework.util import assert_equal, assert_greater_than_or_equal
class RPCInterfaceTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True
+ def test_getrpcinfo(self):
+ self.log.info("Testing getrpcinfo...")
+
+ info = self.nodes[0].getrpcinfo()
+ assert_equal(len(info['active_commands']), 1)
+
+ command = info['active_commands'][0]
+ assert_equal(command['method'], 'getrpcinfo')
+ assert_greater_than_or_equal(command['duration'], 0)
+
def test_batch_request(self):
self.log.info("Testing basic JSON-RPC batch request...")
@@ -39,6 +49,7 @@ class RPCInterfaceTest(BitcoinTestFramework):
assert result_by_id[3]['result'] is not None
def run_test(self):
+ self.test_getrpcinfo()
self.test_batch_request()
diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py
index d95da227e5..8f8e89cf15 100755
--- a/test/functional/p2p_segwit.py
+++ b/test/functional/p2p_segwit.py
@@ -755,7 +755,7 @@ class SegWitTest(BitcoinTestFramework):
spend_tx.vin[0].scriptSig = CScript([p2wsh_pubkey, b'a'])
spend_tx.rehash()
with self.nodes[0].assert_debug_log(
- expected_msgs=('Not relaying invalid transaction {}'.format(spend_tx.hash), 'was not accepted: mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)')):
+ expected_msgs=(spend_tx.hash, 'was not accepted: mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)')):
test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False)
# Now put the witness script in the witness, should succeed after
diff --git a/test/lint/check-doc.py b/test/lint/check-doc.py
index 4facd6c334..c370ce0c04 100755
--- a/test/lint/check-doc.py
+++ b/test/lint/check-doc.py
@@ -30,8 +30,8 @@ def main():
used = check_output(CMD_GREP_ARGS, shell=True, universal_newlines=True, encoding='utf8')
docd = check_output(CMD_GREP_DOCS, shell=True, universal_newlines=True, encoding='utf8')
else:
- used = check_output(CMD_GREP_ARGS, shell=True, universal_newlines=True) # encoding='utf8'
- docd = check_output(CMD_GREP_DOCS, shell=True, universal_newlines=True) # encoding='utf8'
+ used = check_output(CMD_GREP_ARGS, shell=True).decode('utf8').strip()
+ docd = check_output(CMD_GREP_DOCS, shell=True).decode('utf8').strip()
args_used = set(re.findall(re.compile(REGEX_ARG), used))
args_docd = set(re.findall(re.compile(REGEX_DOC), docd)).union(SET_DOC_OPTIONAL)
diff --git a/test/lint/lint-format-strings.sh b/test/lint/lint-format-strings.sh
index 2c443abf6b..c994ae3f4d 100755
--- a/test/lint/lint-format-strings.sh
+++ b/test/lint/lint-format-strings.sh
@@ -11,20 +11,20 @@
export LC_ALL=C
FUNCTION_NAMES_AND_NUMBER_OF_LEADING_ARGUMENTS=(
- FatalError,0
- fprintf,1
- LogConnectFailure,1
- LogPrint,1
- LogPrintf,0
- printf,0
- snprintf,2
- sprintf,1
- strprintf,0
- vfprintf,1
- vprintf,1
- vsnprintf,1
- vsprintf,1
- WalletLogPrintf,0
+ "FatalError,0"
+ "fprintf,1"
+ "LogConnectFailure,1"
+ "LogPrint,1"
+ "LogPrintf,0"
+ "printf,0"
+ "snprintf,2"
+ "sprintf,1"
+ "strprintf,0"
+ "vfprintf,1"
+ "vprintf,1"
+ "vsnprintf,1"
+ "vsprintf,1"
+ "WalletLogPrintf,0"
)
EXIT_CODE=0
diff --git a/test/lint/lint-python.sh b/test/lint/lint-python.sh
index 3dbb9fff28..f5b851aeab 100755
--- a/test/lint/lint-python.sh
+++ b/test/lint/lint-python.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Copyright (c) 2017 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
@@ -8,77 +8,79 @@
export LC_ALL=C
-# E101 indentation contains mixed spaces and tabs
-# E112 expected an indented block
-# E113 unexpected indentation
-# E115 expected an indented block (comment)
-# E116 unexpected indentation (comment)
-# E125 continuation line with same indent as next logical line
-# E129 visually indented line with same indent as next logical line
-# E131 continuation line unaligned for hanging indent
-# E133 closing bracket is missing indentation
-# E223 tab before operator
-# E224 tab after operator
-# E242 tab after ','
-# E266 too many leading '#' for block comment
-# E271 multiple spaces after keyword
-# E272 multiple spaces before keyword
-# E273 tab after keyword
-# E274 tab before keyword
-# E275 missing whitespace after keyword
-# E304 blank lines found after function decorator
-# E306 expected 1 blank line before a nested definition
-# E401 multiple imports on one line
-# E402 module level import not at top of file
-# F403 'from foo_module import *' used; unable to detect undefined names
-# F405 foo_function may be undefined, or defined from star imports: bar_module
-# E502 the backslash is redundant between brackets
-# E701 multiple statements on one line (colon)
-# E702 multiple statements on one line (semicolon)
-# E703 statement ends with a semicolon
-# E711 comparison to None should be 'if cond is None:'
-# E714 test for object identity should be "is not"
-# E721 do not compare types, use "isinstance()"
-# E741 do not use variables named "l", "O", or "I"
-# E742 do not define classes named "l", "O", or "I"
-# E743 do not define functions named "l", "O", or "I"
-# E901 SyntaxError: invalid syntax
-# E902 TokenError: EOF in multi-line string
-# F401 module imported but unused
-# F402 import module from line N shadowed by loop variable
-# F404 future import(s) name after other statements
-# F406 "from module import *" only allowed at module level
-# F407 an undefined __future__ feature name was imported
-# F601 dictionary key name repeated with different values
-# F602 dictionary key variable name repeated with different values
-# F621 too many expressions in an assignment with star-unpacking
-# F622 two or more starred expressions in an assignment (a, *b, *c = d)
-# F631 assertion test is a tuple, which are always True
-# F701 a break statement outside of a while or for loop
-# F702 a continue statement outside of a while or for loop
-# F703 a continue statement in a finally block in a loop
-# F704 a yield or yield from statement outside of a function
-# F705 a return statement with arguments inside a generator
-# F706 a return statement outside of a function/method
-# F707 an except: block as not the last exception handler
-# F811 redefinition of unused name from line N
-# F812 list comprehension redefines 'foo' from line N
-# F821 undefined name 'Foo'
-# F822 undefined name name in __all__
-# F823 local variable name … referenced before assignment
-# F831 duplicate argument name in function definition
-# F841 local variable 'foo' is assigned to but never used
-# W191 indentation contains tabs
-# W291 trailing whitespace
-# W292 no newline at end of file
-# W293 blank line contains whitespace
-# W504 line break after binary operator
-# W601 .has_key() is deprecated, use "in"
-# W602 deprecated form of raising exception
-# W603 "<>" is deprecated, use "!="
-# W604 backticks are deprecated, use "repr()"
-# W605 invalid escape sequence "x"
-# W606 'async' and 'await' are reserved keywords starting with Python 3.7
+enabled=(
+ E101 # indentation contains mixed spaces and tabs
+ E112 # expected an indented block
+ E113 # unexpected indentation
+ E115 # expected an indented block (comment)
+ E116 # unexpected indentation (comment)
+ E125 # continuation line with same indent as next logical line
+ E129 # visually indented line with same indent as next logical line
+ E131 # continuation line unaligned for hanging indent
+ E133 # closing bracket is missing indentation
+ E223 # tab before operator
+ E224 # tab after operator
+ E242 # tab after ','
+ E266 # too many leading '#' for block comment
+ E271 # multiple spaces after keyword
+ E272 # multiple spaces before keyword
+ E273 # tab after keyword
+ E274 # tab before keyword
+ E275 # missing whitespace after keyword
+ E304 # blank lines found after function decorator
+ E306 # expected 1 blank line before a nested definition
+ E401 # multiple imports on one line
+ E402 # module level import not at top of file
+ E502 # the backslash is redundant between brackets
+ E701 # multiple statements on one line (colon)
+ E702 # multiple statements on one line (semicolon)
+ E703 # statement ends with a semicolon
+ E711 # comparison to None should be 'if cond is None:'
+ E714 # test for object identity should be "is not"
+ E721 # do not compare types, use "isinstance()"
+ E741 # do not use variables named "l", "O", or "I"
+ E742 # do not define classes named "l", "O", or "I"
+ E743 # do not define functions named "l", "O", or "I"
+ E901 # SyntaxError: invalid syntax
+ E902 # TokenError: EOF in multi-line string
+ F401 # module imported but unused
+ F402 # import module from line N shadowed by loop variable
+ F403 # 'from foo_module import *' used; unable to detect undefined names
+ F404 # future import(s) name after other statements
+ F405 # foo_function may be undefined, or defined from star imports: bar_module
+ F406 # "from module import *" only allowed at module level
+ F407 # an undefined __future__ feature name was imported
+ F601 # dictionary key name repeated with different values
+ F602 # dictionary key variable name repeated with different values
+ F621 # too many expressions in an assignment with star-unpacking
+ F622 # two or more starred expressions in an assignment (a, *b, *c = d)
+ F631 # assertion test is a tuple, which are always True
+ F701 # a break statement outside of a while or for loop
+ F702 # a continue statement outside of a while or for loop
+ F703 # a continue statement in a finally block in a loop
+ F704 # a yield or yield from statement outside of a function
+ F705 # a return statement with arguments inside a generator
+ F706 # a return statement outside of a function/method
+ F707 # an except: block as not the last exception handler
+ F811 # redefinition of unused name from line N
+ F812 # list comprehension redefines 'foo' from line N
+ F821 # undefined name 'Foo'
+ F822 # undefined name name in __all__
+ F823 # local variable name … referenced before assignment
+ F831 # duplicate argument name in function definition
+ F841 # local variable 'foo' is assigned to but never used
+ W191 # indentation contains tabs
+ W291 # trailing whitespace
+ W292 # no newline at end of file
+ W293 # blank line contains whitespace
+ W504 # line break after binary operator
+ W601 # .has_key() is deprecated, use "in"
+ W602 # deprecated form of raising exception
+ W603 # "<>" is deprecated, use "!="
+ W604 # backticks are deprecated, use "repr()"
+ W605 # invalid escape sequence "x"
+ W606 # 'async' and 'await' are reserved keywords starting with Python 3.7
+)
if ! command -v flake8 > /dev/null; then
echo "Skipping Python linting since flake8 is not installed. Install by running \"pip3 install flake8\""
@@ -88,4 +90,4 @@ elif PYTHONWARNINGS="ignore" flake8 --version | grep -q "Python 2"; then
exit 0
fi
-PYTHONWARNINGS="ignore" flake8 --ignore=B,C,E,F,I,N,W --select=E101,E112,E113,E115,E116,E125,E129,E131,E133,E223,E224,E242,E266,E271,E272,E273,E274,E275,E304,E306,E401,E402,E502,E701,E702,E703,E711,E714,E721,E741,E742,E743,E901,E902,F401,F402,F403,F404,F405,F406,F407,F601,F602,F621,F622,F631,F701,F702,F703,F704,F705,F706,F707,F811,F812,F821,F822,F823,F831,F841,W191,W291,W292,W293,W504,W601,W602,W603,W604,W605,W606 "${@:-.}"
+PYTHONWARNINGS="ignore" flake8 --ignore=B,C,E,F,I,N,W --select=$(IFS=","; echo "${enabled[*]}") "${@:-.}"
diff --git a/test/lint/lint-shell.sh b/test/lint/lint-shell.sh
index 9af3c10ed6..6f5e6546c5 100755
--- a/test/lint/lint-shell.sh
+++ b/test/lint/lint-shell.sh
@@ -13,7 +13,7 @@ export LC_ALL=C
# respectively. So export LC_ALL=C is set as required by lint-shell-locale.sh
# but unset here in case of running in Travis.
if [ "$TRAVIS" = "true" ]; then
- unset LC_ALL
+ unset LC_ALL
fi
if ! command -v shellcheck > /dev/null; then
@@ -22,26 +22,26 @@ if ! command -v shellcheck > /dev/null; then
fi
# Disabled warnings:
-# SC1087: Use braces when expanding arrays, e.g. ${array[idx]} (or ${var}[.. to quiet).
-# SC1117: Backslash is literal in "\.". Prefer explicit escaping: "\\.".
-# SC2001: See if you can use ${variable//search/replace} instead.
-# SC2004: $/${} is unnecessary on arithmetic variables.
-# SC2005: Useless echo? Instead of 'echo $(cmd)', just use 'cmd'.
-# SC2006: Use $(..) instead of legacy `..`.
-# SC2016: Expressions don't expand in single quotes, use double quotes for that.
-# SC2028: echo won't expand escape sequences. Consider printf.
-# SC2046: Quote this to prevent word splitting.
-# SC2048: Use "$@" (with quotes) to prevent whitespace problems.
-# SC2066: Since you double quoted this, it will not word split, and the loop will only run once.
-# SC2086: Double quote to prevent globbing and word splitting.
-# SC2116: Useless echo? Instead of 'cmd $(echo foo)', just use 'cmd foo'.
-# SC2148: Tips depend on target shell and yours is unknown. Add a shebang.
-# SC2162: read without -r will mangle backslashes.
-# SC2166: Prefer [ p ] && [ q ] as [ p -a q ] is not well defined.
-# SC2166: Prefer [ p ] || [ q ] as [ p -o q ] is not well defined.
-# SC2181: Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
-# SC2206: Quote to prevent word splitting, or split robustly with mapfile or read -a.
-# SC2207: Prefer mapfile or read -a to split command output (or quote to avoid splitting).
-# SC2230: which is non-standard. Use builtin 'command -v' instead.
-shellcheck -e SC1087,SC1117,SC2001,SC2004,SC2005,SC2006,SC2016,SC2028,SC2046,SC2048,SC2066,SC2086,SC2116,SC2148,SC2162,SC2166,SC2181,SC2206,SC2207,SC2230 \
+disabled=(
+ SC1087 # Use braces when expanding arrays, e.g. ${array[idx]} (or ${var}[.. to quiet).
+ SC2001 # See if you can use ${variable//search/replace} instead.
+ SC2004 # $/${} is unnecessary on arithmetic variables.
+ SC2005 # Useless echo? Instead of 'echo $(cmd)', just use 'cmd'.
+ SC2006 # Use $(..) instead of legacy `..`.
+ SC2016 # Expressions don't expand in single quotes, use double quotes for that.
+ SC2028 # echo won't expand escape sequences. Consider printf.
+ SC2046 # Quote this to prevent word splitting.
+ SC2048 # Use "$@" (with quotes) to prevent whitespace problems.
+ SC2066 # Since you double quoted this, it will not word split, and the loop will only run once.
+ SC2086 # Double quote to prevent globbing and word splitting.
+ SC2116 # Useless echo? Instead of 'cmd $(echo foo)', just use 'cmd foo'.
+ SC2162 # read without -r will mangle backslashes.
+ SC2166 # Prefer [ p ] {&&,||} [ q ] as [ p -{a,o} q ] is not well defined.
+ SC2181 # Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
+ SC2206 # Quote to prevent word splitting, or split robustly with mapfile or read -a.
+ SC2207 # Prefer mapfile or read -a to split command output (or quote to avoid splitting).
+ SC2230 # which is non-standard. Use builtin 'command -v' instead.
+ SC2236 # Don't force -n instead of ! -z.
+)
+shellcheck -e "$(IFS=","; echo "${disabled[*]}")" \
$(git ls-files -- "*.sh" | grep -vE 'src/(secp256k1|univalue)/')
diff --git a/test/lint/lint-whitespace.sh b/test/lint/lint-whitespace.sh
index beb7ec42f4..f318e19071 100755
--- a/test/lint/lint-whitespace.sh
+++ b/test/lint/lint-whitespace.sh
@@ -23,7 +23,7 @@ while getopts "?" opt; do
done
if [ -z "${TRAVIS_COMMIT_RANGE}" ]; then
- if [ "$1" ]; then
+ if [ -n "$1" ]; then
TRAVIS_COMMIT_RANGE="HEAD~$1...HEAD"
else
TRAVIS_COMMIT_RANGE="HEAD"