Skip to content

Commit 0b8a382

Browse files
authored
Toolset updates for Round 20 (TechEmpower#5648)
* Add tag support * add --list-tag * filter out broken tests * work on test modules * fix test order * :/ * work on test-modules * fix class * add url length checks to verifications * update cached-query key and vagrant to ubuntu 18.04
1 parent 77fd805 commit 0b8a382

File tree

18 files changed

+187
-131
lines changed

18 files changed

+187
-131
lines changed

deployment/vagrant/core.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def provision_bootstrap(config)
1212
def provider_libvirt(config)
1313
config.vm.provider :libvirt do |virt, override|
1414
override.vm.hostname = "TFB-all"
15-
override.vm.box = "generic/ubuntu1604"
15+
override.vm.box = "generic/ubuntu1804"
1616

1717
unless ENV.fetch('TFB_SHOW_VM', false)
1818
virt.graphics_type = "none"
@@ -28,7 +28,7 @@ def provider_libvirt(config)
2828
def provider_virtualbox(config)
2929
config.vm.provider :virtualbox do |vb, override|
3030
override.vm.hostname = "TFB-all"
31-
override.vm.box = "ubuntu/xenial64"
31+
override.vm.box = "ubuntu/bionic64"
3232

3333
# Allow increase in size for /dev/sda1
3434
# Would need plugin:

toolset/benchmark/test_types/__init__.py

-9
This file was deleted.

toolset/run-tests.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def main(argv=None):
133133
parser.add_argument(
134134
'--type',
135135
choices=[
136-
'all', 'json', 'db', 'query', 'cached_query', 'fortune', 'update',
136+
'all', 'json', 'db', 'query', 'cached-query', 'fortune', 'update',
137137
'plaintext'
138138
],
139139
nargs='+',

toolset/test_types/__init__.py

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import imp
2+
import re
3+
4+
from glob import glob
5+
6+
test_types = {}
7+
test_type_folders = glob("/FrameworkBenchmarks/toolset/test_types/*/")
8+
9+
# Loads all the test_types from the folders in this directory
10+
for folder in test_type_folders:
11+
# regex that grabs the characters between "toolset/test_types/"
12+
# and the final "/" in the folder string to get the name
13+
test_type_name = re.findall(r'.+\/(.+)\/$', folder, re.M)[0]
14+
test_type = imp.load_source("TestType", "%s%s.py" % (folder, test_type_name))
15+
test_types[test_type_name] = test_type.TestType

toolset/benchmark/test_types/framework_test_type.py renamed to toolset/test_types/abstract_test_type.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
import abc
12
import copy
23
import requests
34

45
from colorama import Fore
56
from toolset.utils.output_helper import log
67

7-
8-
class FrameworkTestType:
8+
class AbstractTestType:
99
'''
1010
Interface between a test type (json, query, plaintext, etc) and
1111
the rest of TFB. A test type defines a number of keys it expects
@@ -15,6 +15,7 @@ class FrameworkTestType:
1515
passes an argument list of ['spam'], then after parsing there will
1616
exist a member `X.spam = 'foobar'`.
1717
'''
18+
__metaclass__ = abc.ABCMeta
1819

1920
def __init__(self,
2021
config,
@@ -38,6 +39,13 @@ def __init__(self,
3839
self.failed = None
3940
self.warned = None
4041

42+
@classmethod
43+
@abc.abstractmethod
44+
def url(self):
45+
pass
46+
47+
@classmethod
48+
@abc.abstractmethod
4149
def accept(self, content_type):
4250
return {
4351
'json':
@@ -51,7 +59,7 @@ def accept(self, content_type):
5159
def parse(self, test_keys):
5260
'''
5361
Takes the dict of key/value pairs describing a FrameworkTest
54-
and collects all variables needed by this FrameworkTestType
62+
and collects all variables needed by this AbstractTestType
5563
5664
Raises AttributeError if required keys are missing
5765
'''

toolset/benchmark/test_types/cached_query_type.py renamed to toolset/test_types/cached-query/cached-query.py

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
from toolset.benchmark.test_types.framework_test_type import FrameworkTestType
2-
from toolset.benchmark.test_types.verifications import verify_query_cases
1+
from toolset.test_types.abstract_test_type import AbstractTestType
2+
from toolset.test_types.verifications import verify_query_cases
33

44

5-
class CachedQueryTestType(FrameworkTestType):
5+
class TestType(AbstractTestType):
66
def __init__(self, config):
77
self.cached_query_url = ""
88
kwargs = {
9-
'name': 'cached_query',
9+
'name': 'cached-query',
1010
'accept_header': self.accept('json'),
1111
'requires_db': True,
1212
'args': ['cached_query_url']
1313
}
14-
FrameworkTestType.__init__(self, config, **kwargs)
14+
AbstractTestType.__init__(self, config, **kwargs)
1515

1616
def get_url(self):
1717
return self.cached_query_url
@@ -31,6 +31,14 @@ def verify(self, base_url):
3131

3232
problems = verify_query_cases(self, cases, url)
3333

34+
# cached_query_url should be at least "/cached-worlds/"
35+
# some frameworks use a trailing slash while others use ?q=
36+
if len(self.cached_query_url) < 15:
37+
problems.append(
38+
("fail",
39+
"Route for cached queries must be at least 8 characters, found '{}' instead".format(self.cached_query_url),
40+
url))
41+
3442
if len(problems) == 0:
3543
return [('pass', '', url + case) for case, _ in cases]
3644
else:

toolset/benchmark/test_types/db_type.py renamed to toolset/test_types/db/db.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from toolset.benchmark.test_types.framework_test_type import FrameworkTestType
2-
from toolset.benchmark.test_types.verifications import basic_body_verification, verify_headers, verify_randomnumber_object, verify_queries_count
1+
from toolset.test_types.abstract_test_type import AbstractTestType
2+
from toolset.test_types.verifications import basic_body_verification, verify_headers, verify_randomnumber_object, verify_queries_count
33

44

5-
class DBTestType(FrameworkTestType):
5+
class TestType(AbstractTestType):
66
def __init__(self, config):
77
self.db_url = ""
88
kwargs = {
@@ -11,14 +11,14 @@ def __init__(self, config):
1111
'requires_db': True,
1212
'args': ['db_url', 'database']
1313
}
14-
FrameworkTestType.__init__(self, config, **kwargs)
14+
AbstractTestType.__init__(self, config, **kwargs)
1515

1616
def get_url(self):
1717
return self.db_url
1818

1919
def verify(self, base_url):
2020
'''
21-
Ensures body is valid JSON with a key 'id' and a key
21+
Ensures body is valid JSON with a key 'id' and a key
2222
'randomNumber', both of which must map to integers
2323
'''
2424

@@ -32,6 +32,13 @@ def verify(self, base_url):
3232

3333
response, problems = basic_body_verification(body, url)
3434

35+
# db should be at least "/db"
36+
if len(self.db_url) < 3:
37+
problems.append(
38+
("fail",
39+
"Route for db must be at least 3 characters, found '{}' instead".format(self.db_url),
40+
url))
41+
3542
if len(problems) > 0:
3643
return problems
3744

toolset/test_types/fortune/__init__.py

Whitespace-only changes.

toolset/benchmark/test_types/fortune_type.py renamed to toolset/test_types/fortune/fortune.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
from toolset.benchmark.test_types.framework_test_type import FrameworkTestType
2-
from toolset.benchmark.fortune_html_parser import FortuneHTMLParser
3-
from toolset.benchmark.test_types.verifications import basic_body_verification, verify_headers, verify_queries_count
1+
from toolset.test_types.abstract_test_type import AbstractTestType
2+
from toolset.test_types.fortune.fortune_html_parser import FortuneHTMLParser
3+
from toolset.test_types.verifications import basic_body_verification, verify_headers, verify_queries_count
44

55

6-
class FortuneTestType(FrameworkTestType):
6+
class TestType(AbstractTestType):
77
def __init__(self, config):
88
self.fortune_url = ""
99
kwargs = {
@@ -12,7 +12,7 @@ def __init__(self, config):
1212
'requires_db': True,
1313
'args': ['fortune_url','database']
1414
}
15-
FrameworkTestType.__init__(self, config, **kwargs)
15+
AbstractTestType.__init__(self, config, **kwargs)
1616

1717
def get_url(self):
1818
return self.fortune_url
@@ -34,6 +34,13 @@ def verify(self, base_url):
3434

3535
_, problems = basic_body_verification(body, url, is_json_check=False)
3636

37+
# fortune_url should be at least "/fortunes"
38+
if len(self.fortune_url) < 9:
39+
problems.append(
40+
("fail",
41+
"Route for fortunes must be at least 9 characters, found '{}' instead".format(self.fortune_url),
42+
url))
43+
3744
if len(problems) > 0:
3845
return problems
3946

toolset/benchmark/test_types/json_type.py renamed to toolset/test_types/json/json.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
from toolset.benchmark.test_types.framework_test_type import FrameworkTestType
2-
from toolset.benchmark.test_types.verifications import basic_body_verification, verify_headers, verify_helloworld_object
1+
from toolset.test_types.abstract_test_type import AbstractTestType
2+
from toolset.test_types.verifications import basic_body_verification, verify_headers, verify_helloworld_object
33

4-
5-
class JsonTestType(FrameworkTestType):
4+
class TestType(AbstractTestType):
65
def __init__(self, config):
76
self.json_url = ""
87
kwargs = {
@@ -11,15 +10,15 @@ def __init__(self, config):
1110
'requires_db': False,
1211
'args': ['json_url']
1312
}
14-
FrameworkTestType.__init__(self, config, **kwargs)
13+
AbstractTestType.__init__(self, config, **kwargs)
1514

1615
def get_url(self):
1716
return self.json_url
1817

1918
def verify(self, base_url):
2019
'''
21-
Validates the response is a JSON object of
22-
{ 'message' : 'hello, world!' }. Case insensitive and
20+
Validates the response is a JSON object of
21+
{ 'message' : 'hello, world!' }. Case insensitive and
2322
quoting style is ignored
2423
'''
2524

@@ -28,6 +27,13 @@ def verify(self, base_url):
2827

2928
response, problems = basic_body_verification(body, url)
3029

30+
# json_url should be at least "/json"
31+
if len(self.json_url) < 5:
32+
problems.append(
33+
("fail",
34+
"Route for json must be at least 5 characters, found '{}' instead".format(self.json_url),
35+
url))
36+
3137
if len(problems) > 0:
3238
return problems
3339

toolset/benchmark/test_types/plaintext_type.py renamed to toolset/test_types/plaintext/plaintext.py

+20-14
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
from toolset.benchmark.test_types.framework_test_type import FrameworkTestType
2-
from toolset.benchmark.test_types.verifications import basic_body_verification, verify_headers
3-
from time import sleep
1+
from toolset.test_types.verifications import basic_body_verification, verify_headers
2+
from toolset.test_types.abstract_test_type import AbstractTestType
43

54

6-
class PlaintextTestType(FrameworkTestType):
5+
class TestType(AbstractTestType):
76
def __init__(self, config):
87
self.plaintext_url = ""
98
kwargs = {
@@ -12,14 +11,21 @@ def __init__(self, config):
1211
'accept_header': self.accept('plaintext'),
1312
'args': ['plaintext_url']
1413
}
15-
FrameworkTestType.__init__(self, config, **kwargs)
14+
AbstractTestType.__init__(self, config, **kwargs)
1615

1716
def verify(self, base_url):
1817
url = base_url + self.plaintext_url
1918
headers, body = self.request_headers_and_body(url)
2019

2120
_, problems = basic_body_verification(body, url, is_json_check=False)
2221

22+
# plaintext_url should be at least "/plaintext"
23+
if len(self.plaintext_url) < 10:
24+
problems.append(
25+
("fail",
26+
"Route for plaintext must be at least 10 characters, found '{}' instead".format(self.plaintext_url),
27+
url))
28+
2329
if len(problems) > 0:
2430
return problems
2531

@@ -55,20 +61,20 @@ def get_script_name(self):
5561
def get_script_variables(self, name, url):
5662
return {
5763
'max_concurrency':
58-
max(self.config.concurrency_levels),
64+
max(self.config.concurrency_levels),
5965
'name':
60-
name,
66+
name,
6167
'duration':
62-
self.config.duration,
68+
self.config.duration,
6369
'levels':
64-
" ".join("{}".format(item)
65-
for item in self.config.pipeline_concurrency_levels),
70+
" ".join("{}".format(item)
71+
for item in self.config.pipeline_concurrency_levels),
6672
'server_host':
67-
self.config.server_host,
73+
self.config.server_host,
6874
'url':
69-
url,
75+
url,
7076
'pipeline':
71-
16,
77+
16,
7278
'accept':
73-
"text/plain,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7"
79+
"text/plain,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7"
7480
}

toolset/benchmark/test_types/query_type.py renamed to toolset/test_types/query/query.py

+16-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from toolset.benchmark.test_types.framework_test_type import FrameworkTestType
2-
from toolset.benchmark.test_types.verifications import verify_query_cases
1+
from toolset.test_types.abstract_test_type import AbstractTestType
2+
from toolset.test_types.verifications import verify_query_cases
33

44

5-
class QueryTestType(FrameworkTestType):
5+
class TestType(AbstractTestType):
66
def __init__(self, config):
77
self.query_url = ""
88
kwargs = {
@@ -11,17 +11,17 @@ def __init__(self, config):
1111
'requires_db': True,
1212
'args': ['query_url', 'database']
1313
}
14-
FrameworkTestType.__init__(self, config, **kwargs)
14+
AbstractTestType.__init__(self, config, **kwargs)
1515

1616
def get_url(self):
1717
return self.query_url
1818

1919
def verify(self, base_url):
2020
'''
21-
Validates the response is a JSON array of
22-
the proper length, each JSON Object in the array
23-
has keys 'id' and 'randomNumber', and these keys
24-
map to integers. Case insensitive and
21+
Validates the response is a JSON array of
22+
the proper length, each JSON Object in the array
23+
has keys 'id' and 'randomNumber', and these keys
24+
map to integers. Case insensitive and
2525
quoting style is ignored
2626
'''
2727

@@ -31,6 +31,14 @@ def verify(self, base_url):
3131

3232
problems = verify_query_cases(self, cases, url, False)
3333

34+
# queries_url should be at least "/queries/"
35+
# some frameworks use a trailing slash while others use ?q=
36+
if len(self.query_url) < 9:
37+
problems.append(
38+
("fail",
39+
"Route for queries must be at least 9 characters, found '{}' instead".format(self.query_url),
40+
url))
41+
3442
if len(problems) == 0:
3543
return [('pass', '', url + case) for case, _ in cases]
3644
else:

0 commit comments

Comments
 (0)