-
Notifications
You must be signed in to change notification settings - Fork 7
Refactor tests to a flat structure #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # Copyright 2019 The NATS Authors | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
| # | ||
|
|
||
| import pytest | ||
| import nkeys | ||
|
|
||
|
|
||
| @pytest.fixture(params=[ | ||
| nkeys.PREFIX_BYTE_OPERATOR, | ||
| nkeys.PREFIX_BYTE_SERVER, | ||
| nkeys.PREFIX_BYTE_CLUSTER, | ||
| nkeys.PREFIX_BYTE_ACCOUNT, | ||
| nkeys.PREFIX_BYTE_USER | ||
| ]) | ||
| def prefix(request): | ||
| return request.param |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -12,190 +12,158 @@ | |||||
| # limitations under the License. | ||||||
| # | ||||||
|
|
||||||
| import unittest | ||||||
| import sys | ||||||
| import pytest | ||||||
| import nkeys | ||||||
| import binascii | ||||||
| import base64 | ||||||
| import os | ||||||
|
|
||||||
| PREFIXES = [ | ||||||
| nkeys.PREFIX_BYTE_OPERATOR, | ||||||
| nkeys.PREFIX_BYTE_SERVER, | ||||||
| nkeys.PREFIX_BYTE_CLUSTER, | ||||||
| nkeys.PREFIX_BYTE_ACCOUNT, | ||||||
| nkeys.PREFIX_BYTE_USER | ||||||
| ] | ||||||
|
|
||||||
|
|
||||||
| class NatsTestCase(unittest.TestCase): | ||||||
|
|
||||||
| def setUp(self): | ||||||
| print( | ||||||
| "\n=== RUN {0}.{1}".format( | ||||||
| self.__class__.__name__, self._testMethodName | ||||||
| ) | ||||||
| ) | ||||||
|
|
||||||
|
|
||||||
| class NkeysTest(NatsTestCase): | ||||||
|
|
||||||
| def test_from_seed_keypair(self): | ||||||
| seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| kp = nkeys.from_seed(bytearray(seed.encode())) | ||||||
| self.assertTrue(type(kp) is nkeys.KeyPair) | ||||||
|
|
||||||
| def test_keypair_sign_nonce(self): | ||||||
| seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| kp = nkeys.from_seed(bytearray(seed.encode())) | ||||||
| raw = kp.sign(b"PXoWU7zWAMt75FY") | ||||||
| sig = base64.b64encode(raw) | ||||||
| self.assertEqual( | ||||||
| sig, | ||||||
| b'ZaAiVDgB5CeYoXoQ7cBCmq+ZllzUnGUoDVb8C7PilWvCs8XKfUchAUhz2P4BYAF++Dg3w05CqyQFRDiGL6LrDw==' | ||||||
| ) | ||||||
|
|
||||||
| def test_from_seed_keypair_bad_padding(self): | ||||||
| with self.assertRaises(nkeys.ErrInvalidSeed): | ||||||
| seed = "UAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| nkeys.from_seed(bytearray(seed.encode())) | ||||||
|
|
||||||
| def test_from_seed_keypair_invalid_seed(self): | ||||||
| with self.assertRaises(nkeys.ErrInvalidSeed): | ||||||
| seed = "AUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| nkeys.from_seed(bytearray(seed.encode())) | ||||||
|
|
||||||
| with self.assertRaises(nkeys.ErrInvalidSeed): | ||||||
| seed = "" | ||||||
| nkeys.from_seed(bytearray(seed.encode())) | ||||||
|
|
||||||
| def test_from_seed_keypair_valid_prefix_byte(self): | ||||||
| seeds = [ | ||||||
| "SNAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU", | ||||||
| "SCAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU", | ||||||
| "SOAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU", | ||||||
| "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| ] | ||||||
|
|
||||||
| def test_from_seed_keypair(): | ||||||
| seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| kp = nkeys.from_seed(bytearray(seed.encode())) | ||||||
| assert type(kp) is nkeys.KeyPair | ||||||
|
|
||||||
|
|
||||||
| def test_keypair_sign_nonce(): | ||||||
| seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| kp = nkeys.from_seed(bytearray(seed.encode())) | ||||||
| raw = kp.sign(b"PXoWU7zWAMt75FY") | ||||||
| sig = base64.b64encode(raw) | ||||||
| assert sig == b'ZaAiVDgB5CeYoXoQ7cBCmq+ZllzUnGUoDVb8C7PilWvCs8XKfUchAUhz2P4BYAF++Dg3w05CqyQFRDiGL6LrDw==' | ||||||
|
|
||||||
|
|
||||||
| def test_from_seed_keypair_bad_padding(): | ||||||
| with pytest.raises(nkeys.ErrInvalidSeed): | ||||||
| seed = "UAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| nkeys.from_seed(bytearray(seed.encode())) | ||||||
|
|
||||||
|
|
||||||
| def test_from_seed_keypair_invalid_seed(): | ||||||
| with pytest.raises(nkeys.ErrInvalidSeed): | ||||||
| seed = "AUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| nkeys.from_seed(bytearray(seed.encode())) | ||||||
|
|
||||||
| with pytest.raises(nkeys.ErrInvalidSeed): | ||||||
| seed = "" | ||||||
| nkeys.from_seed(bytearray(seed.encode())) | ||||||
|
|
||||||
|
|
||||||
| def test_from_seed_keypair_valid_prefix_byte(): | ||||||
| seeds = [ | ||||||
| "SNAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU", | ||||||
| "SCAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU", | ||||||
| "SOAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU", | ||||||
| "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| ] | ||||||
| for seed in seeds: | ||||||
| nkeys.from_seed(bytearray(seed.encode())) | ||||||
|
|
||||||
|
|
||||||
| def test_from_seed_keypair_invalid_public_prefix_byte(): | ||||||
| seeds = [ | ||||||
| b'SBAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU', | ||||||
| b'SDAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU', | ||||||
| b'PWAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU', | ||||||
| b'PMAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU' | ||||||
| ] | ||||||
| with pytest.raises(nkeys.ErrInvalidPrefixByte): | ||||||
| for seed in seeds: | ||||||
| nkeys.from_seed(bytearray(seed.encode())) | ||||||
|
|
||||||
| def test_from_seed_keypair_invalid_public_prefix_byte(self): | ||||||
| seeds = [ | ||||||
| b'SBAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU', | ||||||
| b'SDAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU', | ||||||
| b'PWAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU', | ||||||
| b'PMAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU' | ||||||
| ] | ||||||
| with self.assertRaises(nkeys.ErrInvalidPrefixByte): | ||||||
| for seed in seeds: | ||||||
| nkeys.from_seed(bytearray(seed)) | ||||||
|
|
||||||
| def test_keypair_wipe(self): | ||||||
| seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| kp = nkeys.from_seed(bytearray(seed.encode())) | ||||||
| self.assertTrue(kp._keys is not None) | ||||||
|
|
||||||
| kp.wipe() | ||||||
| with self.assertRaises(AttributeError): | ||||||
| kp._keys | ||||||
| with self.assertRaises(AttributeError): | ||||||
| kp._seed | ||||||
|
|
||||||
| def test_keypair_public_key(self): | ||||||
| seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| encoded_seed = bytearray(seed.encode()) | ||||||
| kp = nkeys.from_seed(encoded_seed) | ||||||
|
|
||||||
| self.assertEqual(None, kp._public_key) | ||||||
| self.assertEqual( | ||||||
| "UCK5N7N66OBOINFXAYC2ACJQYFSOD4VYNU6APEJTAVFZB2SVHLKGEW7L", | ||||||
| kp.public_key | ||||||
| ) | ||||||
|
|
||||||
| # Confirm that the public key is wiped as well. | ||||||
| kp.wipe() | ||||||
| with self.assertRaises(AttributeError): | ||||||
| kp._public_key | ||||||
|
|
||||||
| def test_keypair_use_seed_to_verify_signature(self): | ||||||
| seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| encoded_seed = bytearray(seed.encode()) | ||||||
| kp = nkeys.from_seed(encoded_seed) | ||||||
| nonce = b'NcMQZSlX2lZ3Y4w' | ||||||
| sig = kp.sign(nonce) | ||||||
| self.assertTrue(kp.verify(nonce, sig)) | ||||||
| with self.assertRaises(nkeys.ErrInvalidSignature): | ||||||
| kp.verify(nonce + b'asdf', sig) | ||||||
|
|
||||||
| def test_keypair_seed_property(self): | ||||||
| seed = bytearray( | ||||||
| b"SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| ) | ||||||
| kp = nkeys.from_seed(seed) | ||||||
| self.assertEqual( | ||||||
| kp.seed, | ||||||
| bytearray( | ||||||
| b"SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| ) | ||||||
| ) | ||||||
|
|
||||||
| # Throw away the seed. | ||||||
| kp.wipe() | ||||||
|
|
||||||
| with self.assertRaises(nkeys.ErrInvalidSeed): | ||||||
| kp.seed | ||||||
|
|
||||||
| def test_keypair_public_key(self): | ||||||
| seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| encoded_seed = bytearray(seed.encode()) | ||||||
| kp = nkeys.from_seed(encoded_seed) | ||||||
|
|
||||||
| self.assertEqual(None, kp._public_key) | ||||||
| self.assertEqual( | ||||||
| b"UCK5N7N66OBOINFXAYC2ACJQYFSOD4VYNU6APEJTAVFZB2SVHLKGEW7L", | ||||||
| kp.public_key | ||||||
| ) | ||||||
|
|
||||||
| # Confirm that the public key is wiped as well. | ||||||
| kp.wipe() | ||||||
| with self.assertRaises(AttributeError): | ||||||
| kp._public_key | ||||||
|
|
||||||
| def test_keypair_private_key(self): | ||||||
| seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| encoded_seed = bytearray(seed.encode()) | ||||||
| kp = nkeys.from_seed(encoded_seed) | ||||||
| self.assertEqual(None, kp._public_key) | ||||||
|
|
||||||
| priv = kp.private_key | ||||||
| self.assertEqual( | ||||||
| b"PDC2WWLK67NUTFW7ZH5A7FOPZC32VXYZYWYNQMQ6RQWP2FEEF6KDVFOW7W7PHAXEGS3QMBNABEYMCZHB6K4G2PAHSEZQKS4Q5JKTVVDCJORA", | ||||||
| priv | ||||||
| ) | ||||||
|
|
||||||
| # Confirm that the private_key is wiped as well. | ||||||
| kp.wipe() | ||||||
| with self.assertRaises(AttributeError): | ||||||
| kp._keys | ||||||
| with self.assertRaises(AttributeError): | ||||||
| kp._private_key | ||||||
|
|
||||||
| def test_roundtrip_seed_encoding(self): | ||||||
| # This test is a low-tech property test in disguise, | ||||||
| # testing the property: | ||||||
| # decode . encode == identity | ||||||
| # Using a proper framework like hypothesis might be preferable. | ||||||
| num_trials = 500 | ||||||
| raw_seeds = [os.urandom(32) for _ in range(num_trials)] | ||||||
| for raw_seed in raw_seeds: | ||||||
| for prefix in PREFIXES: | ||||||
| with self.subTest(rawseed=raw_seed, prefix=prefix): | ||||||
| encoded_seed = nkeys.encode_seed(raw_seed, prefix) | ||||||
| decoded_prefix, decoded_seed = nkeys.decode_seed(encoded_seed) | ||||||
| self.assertEqual(prefix, decoded_prefix) | ||||||
| self.assertEqual(raw_seed, decoded_seed) | ||||||
|
|
||||||
|
|
||||||
| if __name__ == '__main__': | ||||||
| runner = unittest.TextTestRunner(stream=sys.stdout) | ||||||
| unittest.main(verbosity=2, exit=False, testRunner=runner) | ||||||
| nkeys.from_seed(bytearray(seed)) | ||||||
|
|
||||||
|
|
||||||
| def test_keypair_wipe(): | ||||||
| seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| kp = nkeys.from_seed(bytearray(seed.encode())) | ||||||
| assert kp._keys is not None | ||||||
|
|
||||||
| kp.wipe() | ||||||
| with pytest.raises(AttributeError): | ||||||
| kp._keys | ||||||
| with pytest.raises(AttributeError): | ||||||
| kp._seed | ||||||
|
|
||||||
|
|
||||||
| def test_keypair_public_key(): | ||||||
| seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU" | ||||||
| encoded_seed = bytearray(seed.encode()) | ||||||
| kp = nkeys.from_seed(encoded_seed) | ||||||
|
|
||||||
| assert kp._public_key is None | ||||||
| assert kp.public_key == "UCK5N7N66OBOINFXAYC2ACJQYFSOD4VYNU6APEJTAVFZB2SVHLKGEW7L" | ||||||
|
||||||
| assert kp.public_key == "UCK5N7N66OBOINFXAYC2ACJQYFSOD4VYNU6APEJTAVFZB2SVHLKGEW7L" | |
| assert kp.public_key == b"UCK5N7N66OBOINFXAYC2ACJQYFSOD4VYNU6APEJTAVFZB2SVHLKGEW7L" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pytest.raises context manager will only catch the exception from the first iteration of the loop. If the first seed raises an exception, subsequent seeds won't be tested. Each seed should be tested individually with its own pytest.raises block, or use pytest.mark.parametrize to test each seed separately.