Skip to content

Commit 54c5975

Browse files
authored
Move to pytest (#6427)
1 parent 27b02df commit 54c5975

30 files changed

+570
-556
lines changed

awscli/customizations/ec2/bundleinstance.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def _generate_signature(params):
135135
policy = base64.b64encode(six.b(policy)).decode('utf-8')
136136
new_hmac = hmac.new(sak.encode('utf-8'), digestmod=sha1)
137137
new_hmac.update(six.b(policy))
138-
ps = base64.encodestring(new_hmac.digest()).strip().decode('utf-8')
138+
ps = base64.encodebytes(new_hmac.digest()).strip().decode('utf-8')
139139
params['UploadPolicySignature'] = ps
140140
del params['_SAK']
141141

awscli/customizations/opsworks.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ def determine_details(self, args):
302302
if 'PublicIpAddress' in self._ec2_instance:
303303
self._use_address = self._ec2_instance['PublicIpAddress']
304304
elif 'PrivateIpAddress' in self._ec2_instance:
305-
LOG.warn(
305+
LOG.warning(
306306
"Instance does not have a public IP address. Trying "
307307
"to use the private address to connect.")
308308
self._use_address = self._ec2_instance['PrivateIpAddress']

awscli/testutils.py

+1
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,7 @@ class TestEventHandler(object):
917917
def __init__(self, handler=None):
918918
self._handler = handler
919919
self._called = False
920+
self.__test__ = False
920921

921922
@property
922923
def called(self):

pyproject.toml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[tool.pytest.ini_options]
2+
markers = [
3+
"slow: marks tests as slow",
4+
]

requirements-check.txt

+3
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
check-manifest==0.37
2+
3+
# We need setuptools>=43.0 to include pyproject.toml
4+
setuptools>=43.0

scripts/ci/run-tests

+3-6
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,7 @@ def process_args(args):
3333
runner = args.test_runner
3434
test_args = ""
3535
if args.with_cov:
36-
test_args += (
37-
f"--with-xunit --cover-erase --with-coverage "
38-
f"--cover-package {PACKAGE} --cover-xml -v "
39-
)
36+
test_args += f"--cov={PACKAGE} --cov-report xml "
4037
dirs = " ".join(args.test_dirs)
4138

4239
return runner, test_args, dirs
@@ -53,8 +50,8 @@ if __name__ == "__main__":
5350
parser.add_argument(
5451
"-r",
5552
"--test-runner",
56-
default="nosetests",
57-
help="Test runner to execute tests. Defaults to nose.",
53+
default="pytest",
54+
help="Test runner to execute tests. Defaults to pytest.",
5855
)
5956
parser.add_argument(
6057
"-c",

tests/functional/docs/test_examples.py

+53-30
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import docutils.parsers.rst
2929
import docutils.utils
3030

31+
import pytest
32+
3133
from awscli.argparser import MainArgParser
3234
from awscli.argparser import ServiceArgParser
3335
from awscli.testutils import BaseAWSHelpOutputTest, create_clidriver
@@ -66,13 +68,45 @@ def noop_test(self):
6668
pass
6769

6870

69-
def test_examples():
71+
def _get_example_test_cases():
72+
test_cases = []
7073
for command, subcommands in COMMAND_EXAMPLES.items():
7174
for subcommand in subcommands:
72-
yield verify_has_examples, command, subcommand
75+
test_cases.append((command, subcommand))
76+
return test_cases
77+
78+
79+
def _get_all_doc_examples():
80+
rst_doc_examples = []
81+
other_doc_examples = []
82+
# Iterate over all rst doc examples0
83+
for root, _, filenames in os.walk(EXAMPLES_DIR):
84+
for filename in filenames:
85+
full_path = os.path.join(root, filename)
86+
if not filename.endswith('.rst'):
87+
other_doc_examples.append(full_path)
88+
continue
89+
rst_doc_examples.append(full_path)
90+
return rst_doc_examples, other_doc_examples
91+
92+
93+
RST_DOC_EXAMPLES, OTHER_DOC_EXAMPLES = _get_all_doc_examples()
94+
EXAMPLE_COMMAND_TESTS = _get_example_test_cases()
95+
96+
97+
@pytest.fixture(scope="module")
98+
def command_validator():
99+
# CLIDriver can take up a lot of resources so we'll just create one
100+
# instance and use it for all the validation tests.
101+
driver = create_clidriver()
102+
return CommandValidator(driver)
73103

74104

75-
def verify_has_examples(command, subcommand):
105+
@pytest.mark.parametrize(
106+
"command, subcommand",
107+
EXAMPLE_COMMAND_TESTS
108+
)
109+
def test_examples(command, subcommand):
76110
t = _ExampleTests(methodName='noop_test')
77111
t.setUp()
78112
try:
@@ -82,27 +116,14 @@ def verify_has_examples(command, subcommand):
82116
t.tearDown()
83117

84118

85-
def test_all_doc_examples():
86-
# CLIDriver can take up a lot of resources so we'll just create one
87-
# instance and use it for all the validation tests.
88-
driver = create_clidriver()
89-
command_validator = CommandValidator(driver)
90-
91-
for example_file in iter_all_doc_examples():
92-
yield verify_has_only_ascii_chars, example_file
93-
yield verify_is_valid_rst, example_file
94-
yield verify_cli_commands_valid, example_file, command_validator
95-
96-
97-
def iter_all_doc_examples():
98-
# Iterate over all rst doc examples0
99-
_dname = os.path.dirname
100-
for rootdir, _, filenames in os.walk(EXAMPLES_DIR):
101-
for filename in filenames:
102-
if not filename.endswith('.rst'):
103-
continue
104-
full_path = os.path.join(rootdir, filename)
105-
yield full_path
119+
@pytest.mark.parametrize(
120+
"example_file",
121+
RST_DOC_EXAMPLES
122+
)
123+
def test_rst_doc_examples(command_validator, example_file):
124+
verify_has_only_ascii_chars(example_file)
125+
verify_is_valid_rst(example_file)
126+
verify_cli_commands_valid(example_file, command_validator)
106127

107128

108129
def verify_has_only_ascii_chars(filename):
@@ -263,12 +284,14 @@ def default_visit(self, node):
263284
pass
264285

265286

266-
def test_example_file_names():
267-
for root, _, files in os.walk(EXAMPLES_DIR):
268-
for filename in files:
269-
filepath = os.path.join(root, filename)
270-
yield (_assert_file_is_rst_or_txt, filepath)
271-
yield (_assert_name_contains_only_allowed_characters, filename)
287+
@pytest.mark.parametrize(
288+
"example_file",
289+
RST_DOC_EXAMPLES + OTHER_DOC_EXAMPLES
290+
)
291+
def test_example_file_name(example_file):
292+
filename = example_file.split(os.sep)[-1]
293+
_assert_file_is_rst_or_txt(example_file)
294+
_assert_name_contains_only_allowed_characters(filename)
272295

273296

274297
def _assert_file_is_rst_or_txt(filepath):

tests/functional/ec2/test_bundle_instance.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def test_no_policy_provided(self):
6969

7070
def test_policy_provided(self):
7171
policy = '{"notarealpolicy":true}'
72-
base64policy = base64.encodestring(six.b(policy)).strip().decode('utf-8')
72+
base64policy = base64.encodebytes(six.b(policy)).strip().decode('utf-8')
7373
policy_signature = 'a5SmoLOxoM0MHpOdC25nE7KIafg='
7474
args = ' --instance-id i-12345678 --owner-akid AKIAIOSFODNN7EXAMPLE'
7575
args += ' --owner-sak wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'

tests/functional/eks/test_util.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,15 @@
1414
"""This module contains some helpers for mocking eks clusters"""
1515

1616
import os
17-
from nose.tools import nottest
1817

1918

2019
EXAMPLE_NAME = "ExampleCluster"
2120

22-
@nottest
2321
def get_testdata(file_name):
2422
"""Get the path of a specific fixture"""
25-
return os.path.join(os.path.dirname(os.path.realpath(__file__)),
26-
"testdata",
27-
file_name)
23+
return os.path.join(
24+
os.path.dirname(os.path.realpath(__file__)), "testdata", file_name
25+
)
2826

2927

3028
def list_cluster_response():

tests/functional/test_shadowing.py

+27-24
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,26 @@
1010
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
1111
# ANY KIND, either express or implied. See the License for the specific
1212
# language governing permissions and limitations under the License.
13+
import pytest
14+
1315
from awscli.clidriver import create_clidriver
1416

1517

16-
def _assert_does_not_shadow(command_name, command_table, builtins):
17-
errors = []
18-
for sub_name, sub_command in command_table.items():
19-
op_help = sub_command.create_help_command()
20-
arg_table = op_help.arg_table
21-
for arg_name in arg_table:
22-
if any(p.startswith(arg_name) for p in builtins):
23-
# Then we are shadowing or prefixing a top level argument
24-
errors.append(
25-
'Shadowing/Prefixing a top level option: '
26-
'%s.%s.%s' % (command_name, sub_name, arg_name))
27-
if errors:
28-
raise AssertionError('\n' + '\n'.join(errors))
18+
def _generate_command_tests():
19+
driver = create_clidriver()
20+
help_command = driver.create_help_command()
21+
top_level_params = set(driver.create_help_command().arg_table)
22+
for command_name, command_obj in help_command.command_table.items():
23+
sub_help = command_obj.create_help_command()
24+
if hasattr(sub_help, 'command_table'):
25+
yield command_name, sub_help.command_table, top_level_params
2926

3027

31-
def test_no_shadowed_builtins():
28+
@pytest.mark.parametrize(
29+
"command_name, command_table, builtins",
30+
_generate_command_tests()
31+
)
32+
def test_no_shadowed_builtins(command_name, command_table, builtins):
3233
"""Verify no command params are shadowed or prefixed by the built in param.
3334
3435
The CLI parses all command line options into a single namespace.
@@ -54,13 +55,15 @@ def test_no_shadowed_builtins():
5455
a single test failure.
5556
5657
"""
57-
driver = create_clidriver()
58-
help_command = driver.create_help_command()
59-
top_level_params = set(driver.create_help_command().arg_table)
60-
for command_name, command_obj in help_command.command_table.items():
61-
sub_help = command_obj.create_help_command()
62-
if hasattr(sub_help, 'command_table'):
63-
yield (
64-
_assert_does_not_shadow,
65-
command_name, sub_help.command_table, top_level_params
66-
)
58+
errors = []
59+
for sub_name, sub_command in command_table.items():
60+
op_help = sub_command.create_help_command()
61+
arg_table = op_help.arg_table
62+
for arg_name in arg_table:
63+
if any(p.startswith(arg_name) for p in builtins):
64+
# Then we are shadowing or prefixing a top level argument
65+
errors.append(
66+
'Shadowing/Prefixing a top level option: '
67+
'%s.%s.%s' % (command_name, sub_name, arg_name))
68+
if errors:
69+
raise AssertionError('\n' + '\n'.join(errors))

0 commit comments

Comments
 (0)