make some better use of mocks during unit tests

This commit is contained in:
Sebastian Stenzel
2015-12-07 14:59:12 +01:00
parent 0697e19b01
commit 97a72ecbf7
15 changed files with 252 additions and 28 deletions
@@ -103,14 +103,11 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration {
/**
* Creates a new Cryptor with a newly initialized PRNG.
*/
public Aes256Cryptor() {
try {
securePrng = SecureRandom.getInstanceStrong();
// No setSeed needed. See SecureRandom.getInstance(String):
// The first call to nextBytes will force the SecureRandom object to seed itself
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("PRNG algorithm should exist.", e);
}
Aes256Cryptor(SecureRandom securePrng) {
this.securePrng = securePrng;
// No setSeed needed. See SecureRandom.getInstance(String):
// The first call to nextBytes will force the SecureRandom object to seed itself
}
@Override
@@ -0,0 +1,15 @@
package org.cryptomator.crypto.aes256;
import javax.inject.Singleton;
import org.cryptomator.crypto.Cryptor;
import dagger.Component;
@Singleton
@Component(modules = CryptoModule.class)
interface CryptoComponent {
Cryptor cryptor();
}
@@ -0,0 +1,29 @@
package org.cryptomator.crypto.aes256;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import org.cryptomator.crypto.Cryptor;
import dagger.Module;
import dagger.Provides;
@Module
public class CryptoModule {
@Provides
SecureRandom provideRandomNumberGenerator() {
try {
return SecureRandom.getInstanceStrong();
} catch (NoSuchAlgorithmException e) {
// quote "Every implementation of the Java platform is required to support at least one strong SecureRandom implementation."
throw new AssertionError("No SecureRandom implementation available.");
}
}
@Provides
public Cryptor provideCryptor(SecureRandom secureRandom) {
return new Aes256Cryptor(secureRandom);
}
}
@@ -19,6 +19,7 @@ import java.util.Arrays;
import javax.security.auth.DestroyFailedException;
import org.apache.commons.io.IOUtils;
import org.cryptomator.crypto.Cryptor;
import org.cryptomator.crypto.exceptions.DecryptFailedException;
import org.cryptomator.crypto.exceptions.EncryptFailedException;
import org.cryptomator.crypto.exceptions.UnsupportedKeyLengthException;
@@ -29,13 +30,18 @@ import org.junit.Test;
public class Aes256CryptorTest {
private final Aes256Cryptor cryptor;
private final Cryptor cryptor;
public Aes256CryptorTest() {
cryptor = new Aes256Cryptor();
cryptor = DaggerCryptoTestComponent.create().cryptor();
cryptor.randomizeMasterKey();
}
@Test
public void testMultipleCryptorInstances() {
Assert.assertNotSame(DaggerCryptoTestComponent.create().cryptor(), DaggerCryptoTestComponent.create().cryptor());
}
@Test(timeout = 10000)
public void testCorrectPassword() throws IOException, WrongPasswordException, DecryptFailedException, UnsupportedKeyLengthException, DestroyFailedException, UnsupportedVaultException {
final String pw = "asd";
@@ -44,7 +50,7 @@ public class Aes256CryptorTest {
cryptor.encryptMasterKey(out, pw);
cryptor.destroy();
final Aes256Cryptor decryptor = new Aes256Cryptor();
final Cryptor decryptor = DaggerCryptoTestComponent.create().cryptor();
final InputStream in = new ByteArrayInputStream(out.toByteArray());
decryptor.decryptMasterKey(in, pw);
@@ -63,7 +69,7 @@ public class Aes256CryptorTest {
// all these passwords are expected to fail.
final String[] wrongPws = {"a", "as", "asdf", "sdf", "das", "dsa", "foo", "bar", "baz"};
final Aes256Cryptor decryptor = new Aes256Cryptor();
final Cryptor decryptor = DaggerCryptoTestComponent.create().cryptor();
for (final String wrongPw : wrongPws) {
final InputStream in = new ByteArrayInputStream(out.toByteArray());
try {
@@ -0,0 +1,15 @@
package org.cryptomator.crypto.aes256;
import javax.inject.Singleton;
import org.cryptomator.crypto.Cryptor;
import dagger.Component;
@Singleton
@Component(modules = CryptoTestModule.class)
public interface CryptoTestComponent {
Cryptor cryptor();
}
@@ -0,0 +1,25 @@
package org.cryptomator.crypto.aes256;
import java.security.SecureRandom;
import org.cryptomator.crypto.Cryptor;
import dagger.Module;
import dagger.Provides;
@Module
public class CryptoTestModule {
@Provides
@SuppressWarnings("deprecation")
SecureRandom provideRandomNumberGenerator() {
// we use this class for testing only, as unit tests on CI servers tend to stall, if they rely on true randomness.
return new InsecureRandomMock();
}
@Provides
Cryptor provideCryptor(SecureRandom secureRandom) {
return new Aes256Cryptor(secureRandom);
}
}
@@ -0,0 +1,23 @@
package org.cryptomator.crypto.aes256;
import java.security.SecureRandom;
import java.util.Random;
/**
* <b>DO NOT USE</b>
*
* This class is for testing only.
*/
@Deprecated // marked as deprecated and made package-private inside /src/test/java to avoid accidential use.
class InsecureRandomMock extends SecureRandom {
private static final long serialVersionUID = 1505563778398085504L;
private final Random random = new Random();
@Override
public void nextBytes(byte[] bytes) {
// let the deterministic RNG do the work:
this.random.nextBytes(bytes);
}
}