Skip to content

Commit 43e135b

Browse files
committed
Use parameterized tests to avoid repetition.
1 parent 0d623a1 commit 43e135b

File tree

3 files changed

+57
-100
lines changed

3 files changed

+57
-100
lines changed

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@
1414
<version>4.12</version>
1515
<scope>test</scope>
1616
</dependency>
17+
18+
<dependency>
19+
<groupId>pl.pragmatists</groupId>
20+
<artifactId>JUnitParams</artifactId>
21+
<version>1.1.1</version>
22+
<scope>test</scope>
23+
</dependency>
1724
</dependencies>
1825

1926
<build>

src/test/java/com/eatthepath/otp/HmacOneTimePasswordGeneratorTest.java

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@
2929

3030
import javax.crypto.spec.SecretKeySpec;
3131

32+
import junitparams.JUnitParamsRunner;
33+
import junitparams.Parameters;
3234
import org.junit.Test;
35+
import org.junit.runner.RunWith;
3336

37+
@RunWith(JUnitParamsRunner.class)
3438
public class HmacOneTimePasswordGeneratorTest {
3539

3640
@Test(expected = IllegalArgumentException.class)
@@ -65,27 +69,22 @@ public void testGetAlgorithm() throws NoSuchAlgorithmException {
6569
* <a href="https://tools.ietf.org/html/rfc4226#appendix-D">RFC&nbsp;4226, Appendix D</a>.
6670
*/
6771
@Test
68-
public void testGetOneTimePassword() throws InvalidKeyException, NoSuchAlgorithmException {
72+
@Parameters({
73+
"0, 755224",
74+
"1, 287082",
75+
"2, 359152",
76+
"3, 969429",
77+
"4, 338314",
78+
"5, 254676",
79+
"6, 287922",
80+
"7, 162583",
81+
"8, 399871",
82+
"9, 520489" })
83+
public void testGenerateOneTimePassword(final int counter, final int expectedOneTimePassword) throws Exception {
6984
final HmacOneTimePasswordGenerator hmacOneTimePasswordGenerator = this.getDefaultGenerator();
7085

7186
final Key key = new SecretKeySpec("12345678901234567890".getBytes(StandardCharsets.US_ASCII), "RAW");
72-
73-
final int[] expectedValues = new int[] {
74-
755224,
75-
287082,
76-
359152,
77-
969429,
78-
338314,
79-
254676,
80-
287922,
81-
162583,
82-
399871,
83-
520489
84-
};
85-
86-
for (int i = 0; i < expectedValues.length; i++) {
87-
assertEquals(expectedValues[i], hmacOneTimePasswordGenerator.generateOneTimePassword(key, i));
88-
}
87+
assertEquals(expectedOneTimePassword, hmacOneTimePasswordGenerator.generateOneTimePassword(key, counter));
8988
}
9089

9190
protected HmacOneTimePasswordGenerator getDefaultGenerator() throws NoSuchAlgorithmException {

src/test/java/com/eatthepath/otp/TimeBasedOneTimePasswordGeneratorTest.java

Lines changed: 33 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,12 @@
3333

3434
import javax.crypto.spec.SecretKeySpec;
3535

36+
import junitparams.JUnitParamsRunner;
37+
import junitparams.Parameters;
3638
import org.junit.Test;
39+
import org.junit.runner.RunWith;
3740

41+
@RunWith(JUnitParamsRunner.class)
3842
public class TimeBasedOneTimePasswordGeneratorTest extends HmacOneTimePasswordGeneratorTest {
3943

4044
@Override
@@ -54,93 +58,40 @@ public void testGetTimeStep() throws NoSuchAlgorithmException {
5458
}
5559

5660
/**
57-
* Tests time-based one-time password generation using HMAC-SHA1 and the test vectors from
58-
* <a href="https://tools.ietf.org/html/rfc6238#appendix-B">RFC&nbsp;6238, Appendix B</a>.
61+
* Tests time-based one-time password generation using the test vectors from
62+
* <a href="https://tools.ietf.org/html/rfc6238#appendix-B">RFC&nbsp;6238, Appendix B</a>. Note that the RFC
63+
* incorrectly states that the same key is used for all test vectors. The
64+
* <a href="https://www.rfc-editor.org/errata_search.php?rfc=6238&eid=2866">>errata</a> correctly points out that
65+
* different keys are used for each of the various HMAC algorithms.
5966
*/
6067
@Test
61-
public void testGenerateOneTimePasswordSha1() throws NoSuchAlgorithmException, InvalidKeyException {
62-
final TimeBasedOneTimePasswordGenerator totp =
63-
new TimeBasedOneTimePasswordGenerator(30, TimeUnit.SECONDS, 8, TimeBasedOneTimePasswordGenerator.TOTP_ALGORITHM_HMAC_SHA1);
64-
65-
final Key key;
66-
{
67-
final String keyString = "12345678901234567890";
68-
key = new SecretKeySpec(keyString.getBytes(StandardCharsets.US_ASCII), "RAW");
69-
}
70-
71-
final Map<Date, Integer> expectedPasswords = new HashMap<>();
72-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(59)), 94287082);
73-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(1111111109)), 7081804);
74-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(1111111111)), 14050471);
75-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(1234567890)), 89005924);
76-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(2000000000)), 69279037);
77-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(20000000000L)), 65353130);
68+
@Parameters({
69+
"59, 94287082, 12345678901234567890, HmacSHA1",
70+
"1111111109, 7081804, 12345678901234567890, HmacSHA1",
71+
"1111111111, 14050471, 12345678901234567890, HmacSHA1",
72+
"1234567890, 89005924, 12345678901234567890, HmacSHA1",
73+
"2000000000, 69279037, 12345678901234567890, HmacSHA1",
74+
"20000000000, 65353130, 12345678901234567890, HmacSHA1",
75+
"59, 46119246, 12345678901234567890123456789012, HmacSHA256",
76+
"1111111109, 68084774, 12345678901234567890123456789012, HmacSHA256",
77+
"1111111111, 67062674, 12345678901234567890123456789012, HmacSHA256",
78+
"1234567890, 91819424, 12345678901234567890123456789012, HmacSHA256",
79+
"2000000000, 90698825, 12345678901234567890123456789012, HmacSHA256",
80+
"20000000000, 77737706, 12345678901234567890123456789012, HmacSHA256",
81+
"59, 90693936, 1234567890123456789012345678901234567890123456789012345678901234, HmacSHA512",
82+
"1111111109, 25091201, 1234567890123456789012345678901234567890123456789012345678901234, HmacSHA512",
83+
"1111111111, 99943326, 1234567890123456789012345678901234567890123456789012345678901234, HmacSHA512",
84+
"1234567890, 93441116, 1234567890123456789012345678901234567890123456789012345678901234, HmacSHA512",
85+
"2000000000, 38618901, 1234567890123456789012345678901234567890123456789012345678901234, HmacSHA512",
86+
"20000000000, 47863826, 1234567890123456789012345678901234567890123456789012345678901234, HmacSHA512" })
87+
public void testGenerateOneTimePassword(final long epochSeconds, final int expectedOneTimePassword, final String keyString, final String algorithm) throws Exception {
7888

79-
this.validateOneTimePasswords(totp, key, expectedPasswords);
80-
}
81-
82-
/**
83-
* Tests time-based one-time password generation using HMAC-SHA256 and the test vectors from
84-
* <a href="https://tools.ietf.org/html/rfc6238#appendix-B">RFC&nbsp;6238, Appendix B</a>.
85-
*/
86-
@Test
87-
public void testGenerateOneTimePasswordSha256() throws NoSuchAlgorithmException, InvalidKeyException {
8889
final TimeBasedOneTimePasswordGenerator totp =
89-
new TimeBasedOneTimePasswordGenerator(30, TimeUnit.SECONDS, 8, TimeBasedOneTimePasswordGenerator.TOTP_ALGORITHM_HMAC_SHA256);
90-
91-
final Key key;
92-
{
93-
// The RFC incorrectly states that the same key is used for all test vectors, but that's not actually true;
94-
// see the errata (https://www.rfc-editor.org/errata_search.php?rfc=6238&eid=2866) for details
95-
final String keyString = "12345678901234567890123456789012";
96-
key = new SecretKeySpec(keyString.getBytes(StandardCharsets.US_ASCII), "RAW");
97-
}
98-
99-
final Map<Date, Integer> expectedPasswords = new HashMap<>();
100-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(59)), 46119246);
101-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(1111111109)), 68084774);
102-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(1111111111)), 67062674);
103-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(1234567890)), 91819424);
104-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(2000000000)), 90698825);
105-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(20000000000L)), 77737706);
106-
107-
this.validateOneTimePasswords(totp, key, expectedPasswords);
108-
}
109-
110-
/**
111-
* Tests time-based one-time password generation using HMAC-SHA512 and the test vectors from
112-
* <a href="https://tools.ietf.org/html/rfc6238#appendix-B">RFC&nbsp;6238, Appendix B</a>.
113-
*/
114-
@Test
115-
public void testGenerateOneTimePasswordSha512() throws NoSuchAlgorithmException, InvalidKeyException {
116-
final TimeBasedOneTimePasswordGenerator totp =
117-
new TimeBasedOneTimePasswordGenerator(30, TimeUnit.SECONDS, 8, TimeBasedOneTimePasswordGenerator.TOTP_ALGORITHM_HMAC_SHA512);
118-
119-
final Key key;
120-
{
121-
// The RFC incorrectly states that the same key is used for all test vectors, but that's not actually true;
122-
// see the errata (https://www.rfc-editor.org/errata_search.php?rfc=6238&eid=2866) for details
123-
final String keyString = "1234567890123456789012345678901234567890123456789012345678901234";
124-
key = new SecretKeySpec(keyString.getBytes(StandardCharsets.US_ASCII), "RAW");
125-
}
126-
127-
final Map<Date, Integer> expectedPasswords = new HashMap<>();
128-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(59)), 90693936);
129-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(1111111109)), 25091201);
130-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(1111111111)), 99943326);
131-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(1234567890)), 93441116);
132-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(2000000000)), 38618901);
133-
expectedPasswords.put(new Date(TimeUnit.SECONDS.toMillis(20000000000L)), 47863826);
134-
135-
this.validateOneTimePasswords(totp, key, expectedPasswords);
136-
}
90+
new TimeBasedOneTimePasswordGenerator(30, TimeUnit.SECONDS, 8, algorithm);
13791

138-
private void validateOneTimePasswords(final TimeBasedOneTimePasswordGenerator totp, final Key key, final Map<Date, Integer> expectedPasswords) throws InvalidKeyException {
139-
for (final Map.Entry<Date, Integer> entry : expectedPasswords.entrySet()) {
140-
final Date date = entry.getKey();
141-
final int expectedPassword = entry.getValue();
92+
final Key key = new SecretKeySpec(keyString.getBytes(StandardCharsets.US_ASCII), "RAW");
93+
final Date date = new Date(TimeUnit.SECONDS.toMillis(epochSeconds));
14294

143-
assertEquals(expectedPassword, totp.generateOneTimePassword(key, date));
144-
}
95+
assertEquals(expectedOneTimePassword, totp.generateOneTimePassword(key, date));
14596
}
14697
}

0 commit comments

Comments
 (0)