Skip to content
This repository was archived by the owner on Dec 26, 2022. It is now read-only.

Commit 8e5805d

Browse files
committed
feat(regression): Allow different build options
Fixes #402. Allow the regression test to cover different build options including `--proxy_passthrough`, `--define mqtt=enable`, `--define db=enable`, `--define build_type=dbg`, `--define build_type=profile`.
1 parent 60cad21 commit 8e5805d

14 files changed

+232
-56
lines changed

tests/regression/0_build.sh

Lines changed: 0 additions & 11 deletions
This file was deleted.

tests/regression/1_run_TA_API.sh

Lines changed: 0 additions & 19 deletions
This file was deleted.

tests/regression/common.py

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
import requests
66
import statistics
77
import subprocess
8+
import argparse
89

9-
DEBUG_FLAG = False
1010
TIMES_TOTAL = 100
1111
TIMEOUT = 100 # [sec]
1212
STATUS_CODE_500 = "500"
@@ -24,19 +24,23 @@
2424

2525
def parse_cli_arg():
2626
global URL
27-
if len(sys.argv) == 2:
28-
raw_url = sys.argv[1]
29-
elif len(sys.argv) == 4:
30-
raw_url = sys.argv[1]
31-
if sys.argv[2] == 'Y':
32-
DEBUG_FLAG = True
33-
34-
# the 3rd arg is the option which determine if use the debugging mode of statistical tests
35-
if sys.argv[3] == 'Y':
36-
TIMES_TOTAL = 2
27+
parser = argparse.ArgumentParser('Regression test runner program')
28+
parser.add_argument('-u',
29+
'--url',
30+
dest='raw_url',
31+
default="localhost:8000")
32+
parser.add_argument('-d', '--debug', dest="debug", action="store_true")
33+
parser.add_argument('--nostat', dest="no_stat", action="store_true")
34+
args = parser.parse_args()
35+
36+
if args.no_stat:
37+
global TIMES_TOTAL
38+
TIMES_TOTAL = 2
39+
if args.debug:
40+
logging.basicConfig(level=logging.DEBUG)
3741
else:
38-
raw_url = "localhost:8000"
39-
URL = "http://" + raw_url
42+
logging.basicConfig(level=logging.INFO)
43+
URL = "http://" + args.raw_url
4044

4145

4246
def eval_stat(time_cost, func_name):
@@ -61,6 +65,17 @@ def gen_rand_trytes(tryte_len):
6165
return trytes
6266

6367

68+
def test_logger(f):
69+
logger = logging.getLogger(f.__module__)
70+
name = f.__name__
71+
72+
def decorate(instance):
73+
logger.debug(f"Testing case = {name}")
74+
return instance
75+
76+
return decorate(f)
77+
78+
6479
def valid_trytes(trytes, trytes_len):
6580
if len(trytes) != trytes_len:
6681
return False
@@ -81,18 +96,16 @@ def map_field(key, value):
8196

8297
def API(get_query, get_data=None, post_data=None):
8398
global URL
99+
command = "curl {} -X POST -H 'Content-Type: application/json' -w \", %{{http_code}}\" -d '{}'"
84100
try:
85101
response = {}
86102
if get_data is not None:
87-
r = requests.get(str(URL + get_query + get_data), timeout=TIMEOUT)
103+
command = str(URL + get_query + get_data)
104+
r = requests.get(command, timeout=TIMEOUT)
88105
response = {"content": r.text, "status_code": str(r.status_code)}
89106

90107
elif post_data is not None:
91-
command = "curl " + str(
92-
URL + get_query
93-
) + " -X POST -H 'Content-Type: application/json' -w \", %{http_code}\" -d '" + str(
94-
post_data) + "'"
95-
logging.debug("curl command = " + command)
108+
command = command.format(URL + get_query, post_data)
96109
p = subprocess.Popen(command,
97110
shell=True,
98111
stdout=subprocess.PIPE,
@@ -114,4 +127,6 @@ def API(get_query, get_data=None, post_data=None):
114127
if not response:
115128
response = None
116129

130+
logging.debug(f"Command = {command}, response = {response}")
131+
117132
return response

tests/regression/common.sh

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Build options
2+
setup_build_opts() {
3+
# The options are separated by '|', the format is as follows
4+
# <bazel build args> | <binary cli arguments>
5+
OPTIONS=(
6+
"|"
7+
"|--iri_host ${IRI_HOST}"
8+
"|--iri_port ${IRI_PORT}"
9+
"|--ta_host ${TA_HOST}"
10+
"|--db_host ${DB_HOST}"
11+
"|--verbose"
12+
"|--proxy_passthrough"
13+
"--define db=enable|"
14+
"--define build_type=debug|"
15+
"--define build_type=profile|"
16+
)
17+
success=()
18+
fail=()
19+
}
20+
21+
# Check environment variables
22+
check_env() {
23+
ENV_NAME=(
24+
"IRI_HOST"
25+
"IRI_PORT"
26+
"TA_HOST"
27+
"TA_PORT"
28+
"DB_HOST"
29+
)
30+
31+
echo "Checking environment variables"
32+
echo "=============================="
33+
34+
for (( i = 0; i < ${#ENV_NAME[@]}; i++ )); do
35+
name=${ENV_NAME[${i}]}
36+
if [[ -z ${!name} ]]; then
37+
echo "${name} not set"
38+
fail=1
39+
else
40+
echo "${name} is set to ${!name}"
41+
fi
42+
done
43+
44+
echo "=============================="
45+
46+
[ -z ${fail} ] || exit 1
47+
}
48+
49+
# Parse command line arguments
50+
get_cli_args () {
51+
sleep_time=$1
52+
shift
53+
remaining_args=$@ # Get the remaining arguments
54+
}

tests/regression/requirements.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1+
certifi==2019.11.28
2+
chardet==3.0.4
3+
idna==2.7
14
requests==2.20.0
5+
urllib3==1.24.3

tests/regression/run-api-with-mqtt.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/bin/bash
2+
3+
source tests/regression/common.sh
4+
5+
check_env
6+
setup_build_opts
7+
8+
# Get command line arguments
9+
# Current arguments parsed are <sleep_time> <remaining_args>
10+
get_cli_args $@
11+
12+
# Install prerequisites
13+
make MQTT
14+
pip install --user -r tests/regression/requirements.txt
15+
redis-server &
16+
17+
# Iterate over all available build options
18+
for (( i = 0; i < ${#OPTIONS[@]}; i++ )); do
19+
option=${OPTIONS[${i}]}
20+
cli_arg=${option} | cut -d '|' -f 1
21+
build_arg=${option} | cut -d '|' -f 2
22+
23+
bazel run accelerator ${build_arg} -- --ta_port=${TA_PORT} ${cli_arg} &
24+
TA=$!
25+
sleep ${sleep_time} # TA takes time to be built
26+
trap "kill -9 ${TA};" INT # Trap SIGINT from Ctrl-C to stop TA
27+
28+
python3 tests/regression/runner.py ${remaining_args} --url localhost:${TA_PORT}
29+
rc=$?
30+
31+
if [ $rc -ne 0 ]
32+
then
33+
echo "Build option '${option}' failed"
34+
fail+=("${option}")
35+
else
36+
success+=("${option}")
37+
fi
38+
39+
bazel clean
40+
wait $(kill -9 ${TA})
41+
done
42+
43+
echo "--------- Successful build options ---------"
44+
for (( i = 0; i < ${#success[@]}; i++ )); do echo ${success[${i}]}; done
45+
echo "----------- Failed build options -----------"
46+
for (( i = 0; i < ${#fail[@]}; i++ )); do echo ${fail[${i}]}; done

tests/regression/run-api.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/bin/bash
2+
3+
source tests/regression/common.sh
4+
5+
check_env
6+
setup_build_opts
7+
8+
# Get command line arguments
9+
# Current arguments parsed are <sleep_time> <remaining_args>
10+
get_cli_args $@
11+
12+
# Install prerequisites
13+
make
14+
pip install --user -r tests/regression/requirements.txt
15+
redis-server &
16+
17+
# Iterate over all available build options
18+
for (( i = 0; i < ${#OPTIONS[@]}; i++ )); do
19+
option=${OPTIONS[${i}]}
20+
cli_arg=${option} | cut -d '|' -f 1
21+
build_arg=${option} | cut -d '|' -f 2
22+
23+
bazel run accelerator ${build_arg} -- --ta_port=${TA_PORT} ${cli_arg} &
24+
TA=$!
25+
sleep ${sleep_time} # TA takes time to be built
26+
trap "kill -9 ${TA};" INT # Trap SIGINT from Ctrl-C to stop TA
27+
28+
python3 tests/regression/runner.py ${remaining_args} --url localhost:${TA_PORT}
29+
rc=$?
30+
31+
if [ $rc -ne 0 ]
32+
then
33+
echo "Build option '${option}' failed"
34+
fail+=("${option}")
35+
else
36+
success+=("${option}")
37+
fi
38+
39+
bazel clean
40+
wait $(kill -9 ${TA})
41+
done
42+
43+
echo "--------- Successful build options ---------"
44+
for (( i = 0; i < ${#success[@]}; i++ )); do echo ${success[${i}]}; done
45+
echo "----------- Failed build options -----------"
46+
for (( i = 0; i < ${#fail[@]}; i++ )); do echo ${fail[${i}]}; done

tests/regression/runner.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515

1616
# Run all the API Test here
1717
if __name__ == '__main__':
18-
if DEBUG_FLAG == True:
19-
logging.basicConfig(level=logging.DEBUG)
20-
else:
21-
logging.basicConfig(level=logging.INFO)
18+
ver = sys.version_info
19+
if ver.major < 3 or (ver.major == 3 and ver.minor < 6):
20+
raise Exception("Must be using Python 3.6 or greater")
21+
2222
parse_cli_arg()
2323

2424
suite_path = os.path.join(os.path.dirname(__file__), "test_suite")
@@ -27,4 +27,6 @@
2727
if module[-3:] == ".py":
2828
mod = __import__(module[:-3], locals(), globals())
2929
suite = unittest.TestLoader().loadTestsFromModule(mod)
30-
unittest.TextTestRunner().run(suite)
30+
result = unittest.TextTestRunner().run(suite)
31+
if not result.wasSuccessful():
32+
exit(1)

tests/regression/test_suite/generate_address.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
class GenerateAddress(unittest.TestCase):
99

1010
# Without additional GET parameter (pass)
11+
@test_logger
1112
def test_normal(self):
1213
res = API("/address/", get_data=self.query_string[0])
1314
res_json = json.loads(res["content"])
@@ -16,16 +17,19 @@ def test_normal(self):
1617
self.assertTrue(valid_trytes(res_json[0], LEN_ADDR))
1718

1819
# Ascii string (fail)
20+
@test_logger
1921
def test_ascii_string(self):
2022
res = API("/address/", get_data=self.query_string[1])
2123
self.assertEqual(STATUS_CODE_400, res["status_code"])
2224

2325
# Unicode string (fail)
26+
@test_logger
2427
def test_unicode_string(self):
2528
res = API("/address/", get_data=self.query_string[2])
2629
self.assertEqual(STATUS_CODE_400, res["status_code"])
2730

2831
# Time statistics
32+
@test_logger
2933
def test_time_statistics(self):
3034
time_cost = []
3135
for i in range(TIMES_TOTAL):

tests/regression/test_suite/get_tips.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
class GetTips(unittest.TestCase):
99

1010
# Without additional GET parameter (pass)
11+
@test_logger
1112
def test_normal(self):
1213
res = API("/tips/", get_data=self.query_string[0])
1314
self.assertEqual(STATUS_CODE_200, res["status_code"])
@@ -17,16 +18,19 @@ def test_normal(self):
1718
self.assertTrue(valid_trytes(tx_hash, LEN_ADDR))
1819

1920
# Ascii string (fail)
21+
@test_logger
2022
def test_ascii_string(self):
2123
res = API("/tips/", get_data=self.query_string[1])
2224
self.assertEqual(STATUS_CODE_400, res["status_code"])
2325

2426
# Unicode string (fail)
27+
@test_logger
2528
def test_unicode_string(self):
2629
res = API("/tips/", get_data=self.query_string[2])
2730
self.assertEqual(STATUS_CODE_400, res["status_code"])
2831

2932
# Time statistics
33+
@test_logger
3034
def test_time_statistics(self):
3135
time_cost = []
3236
for i in range(TIMES_TOTAL):

0 commit comments

Comments
 (0)