|
- """passlib.tests -- tests for passlib.pwd"""
- #=============================================================================
- # imports
- #=============================================================================
- # core
- import itertools
- import logging; log = logging.getLogger(__name__)
- # site
- # pkg
- from passlib.tests.utils import TestCase
- # local
- __all__ = [
- "UtilsTest",
- "GenerateTest",
- "StrengthTest",
- ]
-
- #=============================================================================
- #
- #=============================================================================
- class UtilsTest(TestCase):
- """test internal utilities"""
- descriptionPrefix = "passlib.pwd"
-
- def test_self_info_rate(self):
- """_self_info_rate()"""
- from passlib.pwd import _self_info_rate
-
- self.assertEqual(_self_info_rate(""), 0)
-
- self.assertEqual(_self_info_rate("a" * 8), 0)
-
- self.assertEqual(_self_info_rate("ab"), 1)
- self.assertEqual(_self_info_rate("ab" * 8), 1)
-
- self.assertEqual(_self_info_rate("abcd"), 2)
- self.assertEqual(_self_info_rate("abcd" * 8), 2)
- self.assertAlmostEqual(_self_info_rate("abcdaaaa"), 1.5488, places=4)
-
- # def test_total_self_info(self):
- # """_total_self_info()"""
- # from passlib.pwd import _total_self_info
- #
- # self.assertEqual(_total_self_info(""), 0)
- #
- # self.assertEqual(_total_self_info("a" * 8), 0)
- #
- # self.assertEqual(_total_self_info("ab"), 2)
- # self.assertEqual(_total_self_info("ab" * 8), 16)
- #
- # self.assertEqual(_total_self_info("abcd"), 8)
- # self.assertEqual(_total_self_info("abcd" * 8), 64)
- # self.assertAlmostEqual(_total_self_info("abcdaaaa"), 12.3904, places=4)
-
- #=============================================================================
- # word generation
- #=============================================================================
-
- # import subject
- from passlib.pwd import genword, default_charsets
- ascii_62 = default_charsets['ascii_62']
- hex = default_charsets['hex']
-
- class WordGeneratorTest(TestCase):
- """test generation routines"""
- descriptionPrefix = "passlib.pwd.genword()"
-
- def setUp(self):
- super(WordGeneratorTest, self).setUp()
-
- # patch some RNG references so they're reproducible.
- from passlib.pwd import SequenceGenerator
- self.patchAttr(SequenceGenerator, "rng",
- self.getRandom("pwd generator"))
-
- def assertResultContents(self, results, count, chars, unique=True):
- """check result list matches expected count & charset"""
- self.assertEqual(len(results), count)
- if unique:
- if unique is True:
- unique = count
- self.assertEqual(len(set(results)), unique)
- self.assertEqual(set("".join(results)), set(chars))
-
- def test_general(self):
- """general behavior"""
-
- # basic usage
- result = genword()
- self.assertEqual(len(result), 9)
-
- # malformed keyword should have useful error.
- self.assertRaisesRegex(TypeError, "(?i)unexpected keyword.*badkwd", genword, badkwd=True)
-
- def test_returns(self):
- """'returns' keyword"""
- # returns=int option
- results = genword(returns=5000)
- self.assertResultContents(results, 5000, ascii_62)
-
- # returns=iter option
- gen = genword(returns=iter)
- results = [next(gen) for _ in range(5000)]
- self.assertResultContents(results, 5000, ascii_62)
-
- # invalid returns option
- self.assertRaises(TypeError, genword, returns='invalid-type')
-
- def test_charset(self):
- """'charset' & 'chars' options"""
- # charset option
- results = genword(charset="hex", returns=5000)
- self.assertResultContents(results, 5000, hex)
-
- # chars option
- # there are 3**3=27 possible combinations
- results = genword(length=3, chars="abc", returns=5000)
- self.assertResultContents(results, 5000, "abc", unique=27)
-
- # chars + charset
- self.assertRaises(TypeError, genword, chars='abc', charset='hex')
-
- # TODO: test rng option
-
- #=============================================================================
- # phrase generation
- #=============================================================================
-
- # import subject
- from passlib.pwd import genphrase
- simple_words = ["alpha", "beta", "gamma"]
-
- class PhraseGeneratorTest(TestCase):
- """test generation routines"""
- descriptionPrefix = "passlib.pwd.genphrase()"
-
- def assertResultContents(self, results, count, words, unique=True, sep=" "):
- """check result list matches expected count & charset"""
- self.assertEqual(len(results), count)
- if unique:
- if unique is True:
- unique = count
- self.assertEqual(len(set(results)), unique)
- out = set(itertools.chain.from_iterable(elem.split(sep) for elem in results))
- self.assertEqual(out, set(words))
-
- def test_general(self):
- """general behavior"""
-
- # basic usage
- result = genphrase()
- self.assertEqual(len(result.split(" ")), 4) # 48 / log(7776, 2) ~= 3.7 -> 4
-
- # malformed keyword should have useful error.
- self.assertRaisesRegex(TypeError, "(?i)unexpected keyword.*badkwd", genphrase, badkwd=True)
-
- def test_entropy(self):
- """'length' & 'entropy' keywords"""
-
- # custom entropy
- result = genphrase(entropy=70)
- self.assertEqual(len(result.split(" ")), 6) # 70 / log(7776, 2) ~= 5.4 -> 6
-
- # custom length
- result = genphrase(length=3)
- self.assertEqual(len(result.split(" ")), 3)
-
- # custom length < entropy
- result = genphrase(length=3, entropy=48)
- self.assertEqual(len(result.split(" ")), 4)
-
- # custom length > entropy
- result = genphrase(length=4, entropy=12)
- self.assertEqual(len(result.split(" ")), 4)
-
- def test_returns(self):
- """'returns' keyword"""
- # returns=int option
- results = genphrase(returns=1000, words=simple_words)
- self.assertResultContents(results, 1000, simple_words)
-
- # returns=iter option
- gen = genphrase(returns=iter, words=simple_words)
- results = [next(gen) for _ in range(1000)]
- self.assertResultContents(results, 1000, simple_words)
-
- # invalid returns option
- self.assertRaises(TypeError, genphrase, returns='invalid-type')
-
- def test_wordset(self):
- """'wordset' & 'words' options"""
- # wordset option
- results = genphrase(words=simple_words, returns=5000)
- self.assertResultContents(results, 5000, simple_words)
-
- # words option
- results = genphrase(length=3, words=simple_words, returns=5000)
- self.assertResultContents(results, 5000, simple_words, unique=3**3)
-
- # words + wordset
- self.assertRaises(TypeError, genphrase, words=simple_words, wordset='bip39')
-
- #=============================================================================
- # eof
- #=============================================================================
|