Provide an API for during runtime tests.
[ADDED] masterpassword-tests provides an API for performing runtime tests of whether the master password algorithm performs as it should on the current platform.
This commit is contained in:
parent
acdb96cb6f
commit
188353d39b
@ -39,18 +39,6 @@
|
||||
<version>1.4.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- TESTING -->
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -1,88 +0,0 @@
|
||||
package com.lyndir.masterpassword;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
import com.google.common.io.Resources;
|
||||
import com.lyndir.lhunath.opal.system.CodeUtils;
|
||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||
import com.lyndir.lhunath.opal.system.util.StringUtils;
|
||||
import java.net.URL;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
||||
public class MasterKeyTest {
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
private static final Logger logger = Logger.get( MasterKeyTest.class );
|
||||
|
||||
private MPWTests tests;
|
||||
private MPWTests.Case defaultCase;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp()
|
||||
throws Exception {
|
||||
|
||||
URL testCasesResource = Resources.getResource( "mpw_tests.xml" );
|
||||
tests = (MPWTests) JAXBContext.newInstance( MPWTests.class ).createUnmarshaller().unmarshal( testCasesResource );
|
||||
for (MPWTests.Case testCase : tests.getCases())
|
||||
testCase.initializeParentHierarchy( tests );
|
||||
defaultCase = tests.getCase( MPWTests.ID_DEFAULT );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncode()
|
||||
throws Exception {
|
||||
|
||||
for (MPWTests.Case testCase : tests.getCases()) {
|
||||
if (testCase.getResult().isEmpty())
|
||||
continue;
|
||||
|
||||
logger.inf( "Running test case: %s [testEncode]", testCase.getIdentifier() );
|
||||
MasterKey masterKey = MasterKey.create( testCase.getAlgorithm(), testCase.getFullName(), testCase.getMasterPassword() );
|
||||
assertEquals(
|
||||
masterKey.encode( testCase.getSiteName(), testCase.getSiteType(), testCase.getSiteCounter(), testCase.getSiteVariant(),
|
||||
testCase.getSiteContext() ), testCase.getResult(), "Failed test case: " + testCase );
|
||||
logger.inf( "passed!" );
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserName()
|
||||
throws Exception {
|
||||
|
||||
assertEquals( MasterKey.create( defaultCase.getFullName(), defaultCase.getMasterPassword() ).getFullName(),
|
||||
defaultCase.getFullName() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetKeyID()
|
||||
throws Exception {
|
||||
|
||||
for (MPWTests.Case testCase : tests.getCases()) {
|
||||
if (testCase.getResult().isEmpty())
|
||||
continue;
|
||||
|
||||
logger.inf( "Running test case: %s [testGetKeyID]", testCase.getIdentifier() );
|
||||
MasterKey masterKey = MasterKey.create( testCase.getFullName(), testCase.getMasterPassword() );
|
||||
assertEquals( CodeUtils.encodeHex( masterKey.getKeyID() ), testCase.getKeyID(), "Failed test case: " + testCase );
|
||||
logger.inf( "passed!" );
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidate()
|
||||
throws Exception {
|
||||
|
||||
try {
|
||||
MasterKey masterKey = MasterKey.create( defaultCase.getFullName(), defaultCase.getMasterPassword() );
|
||||
masterKey.invalidate();
|
||||
masterKey.encode( defaultCase.getSiteName(), defaultCase.getSiteType(), defaultCase.getSiteCounter(),
|
||||
defaultCase.getSiteVariant(), defaultCase.getSiteContext() );
|
||||
assertTrue( false, "Master key should have been invalidated, but was still usable." );
|
||||
}
|
||||
catch (IllegalStateException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
43
MasterPassword/Java/masterpassword-tests/pom.xml
Normal file
43
MasterPassword/Java/masterpassword-tests/pom.xml
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<!-- PROJECT METADATA -->
|
||||
<parent>
|
||||
<groupId>com.lyndir.masterpassword</groupId>
|
||||
<artifactId>masterpassword</artifactId>
|
||||
<version>GIT-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<name>Master Password Test Suite</name>
|
||||
<description>The standard test suite to ensure the Master Password algorithm is operating as it should</description>
|
||||
|
||||
<artifactId>masterpassword-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<!-- DEPENDENCY MANAGEMENT -->
|
||||
<dependencies>
|
||||
|
||||
<!-- PROJECT REFERENCES -->
|
||||
<dependency>
|
||||
<groupId>com.lyndir.masterpassword</groupId>
|
||||
<artifactId>masterpassword-algorithm</artifactId>
|
||||
<version>GIT-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- TESTING -->
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,82 @@
|
||||
package com.lyndir.masterpassword;
|
||||
|
||||
import com.google.common.io.Resources;
|
||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||
import com.lyndir.lhunath.opal.system.util.NNFunctionNN;
|
||||
import java.net.URL;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
||||
|
||||
/**
|
||||
* @author lhunath, 2015-12-22
|
||||
*/
|
||||
public class MPTestSuite {
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
private static final Logger logger = Logger.get( MPTestSuite.class );
|
||||
private static final String DEFAULT_RESOURCE_NAME = "mpw_tests.xml";
|
||||
|
||||
private MPTests tests;
|
||||
|
||||
public MPTestSuite()
|
||||
throws UnavailableException {
|
||||
this( DEFAULT_RESOURCE_NAME );
|
||||
}
|
||||
|
||||
public MPTestSuite(String resourceName)
|
||||
throws UnavailableException {
|
||||
try {
|
||||
URL testCasesResource = Resources.getResource( resourceName );
|
||||
tests = (MPTests) JAXBContext.newInstance( MPTests.class ).createUnmarshaller().unmarshal( testCasesResource );
|
||||
|
||||
for (MPTests.Case testCase : tests.getCases())
|
||||
testCase.initializeParentHierarchy( tests );
|
||||
}
|
||||
catch (IllegalArgumentException | JAXBException e) {
|
||||
throw new UnavailableException( e );
|
||||
}
|
||||
}
|
||||
|
||||
public MPTests getTests() {
|
||||
return tests;
|
||||
}
|
||||
|
||||
public boolean forEach(String testName, NNFunctionNN<MPTests.Case, Boolean> testFunction) {
|
||||
for (MPTests.Case testCase : tests.getCases()) {
|
||||
if (testCase.getResult().isEmpty())
|
||||
continue;
|
||||
|
||||
logger.inf( "[%s] on %s...", testName, testCase.getIdentifier() );
|
||||
if (!testFunction.apply( testCase )) {
|
||||
logger.err( "[%s] on %s: FAILED!", testName, testCase.getIdentifier() );
|
||||
return false;
|
||||
}
|
||||
logger.inf( "[%s] on %s: passed!", testName, testCase.getIdentifier() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean run() {
|
||||
return forEach( "mpw", new NNFunctionNN<MPTests.Case, Boolean>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Boolean apply(@Nonnull final MPTests.Case testCase) {
|
||||
MasterKey masterKey = MasterKey.create( testCase.getAlgorithm(), testCase.getFullName(), testCase.getMasterPassword() );
|
||||
String sitePassword = masterKey.encode( testCase.getSiteName(), testCase.getSiteType(), testCase.getSiteCounter(),
|
||||
testCase.getSiteVariant(), testCase.getSiteContext() );
|
||||
|
||||
return testCase.getResult().equals( sitePassword );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
public static class UnavailableException extends Exception {
|
||||
|
||||
public UnavailableException(final Throwable cause) {
|
||||
super( cause );
|
||||
}
|
||||
}
|
||||
}
|
@ -15,12 +15,12 @@ import javax.xml.bind.annotation.*;
|
||||
* @author lhunath, 14-12-05
|
||||
*/
|
||||
@XmlRootElement(name = "tests")
|
||||
public class MPWTests {
|
||||
public class MPTests {
|
||||
|
||||
public static final String ID_DEFAULT = "default";
|
||||
private static final String ID_DEFAULT = "default";
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
private static final Logger logger = Logger.get( MPWTests.class );
|
||||
private static final Logger logger = Logger.get( MPTests.class );
|
||||
|
||||
@XmlElement(name = "case")
|
||||
private List<Case> cases;
|
||||
@ -38,6 +38,15 @@ public class MPWTests {
|
||||
throw new IllegalArgumentException( "No case for identifier: " + identifier );
|
||||
}
|
||||
|
||||
public Case getDefaultCase() {
|
||||
try {
|
||||
return getCase( ID_DEFAULT );
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new IllegalStateException( "Missing default case in test suite. Add a case with id: " + ID_DEFAULT, e );
|
||||
}
|
||||
}
|
||||
|
||||
@XmlRootElement(name = "case")
|
||||
public static class Case {
|
||||
|
||||
@ -68,7 +77,7 @@ public class MPWTests {
|
||||
|
||||
private transient Case parentCase;
|
||||
|
||||
public void initializeParentHierarchy(MPWTests tests) {
|
||||
public void initializeParentHierarchy(MPTests tests) {
|
||||
|
||||
if (parent != null) {
|
||||
parentCase = tests.getCase( parent );
|
@ -0,0 +1,96 @@
|
||||
package com.lyndir.masterpassword;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
import com.google.common.io.Resources;
|
||||
import com.lyndir.lhunath.opal.system.CodeUtils;
|
||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||
import com.lyndir.lhunath.opal.system.util.NNFunctionNN;
|
||||
import com.lyndir.lhunath.opal.system.util.StringUtils;
|
||||
import java.net.URL;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
||||
public class MasterKeyTest {
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
private static final Logger logger = Logger.get( MasterKeyTest.class );
|
||||
|
||||
private MPTestSuite testSuite;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp()
|
||||
throws Exception {
|
||||
|
||||
testSuite = new MPTestSuite();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncode()
|
||||
throws Exception {
|
||||
|
||||
testSuite.forEach( "testEncode", new NNFunctionNN<MPTests.Case, Boolean>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Boolean apply(@Nonnull final MPTests.Case testCase) {
|
||||
MasterKey masterKey = MasterKey.create( testCase.getAlgorithm(), testCase.getFullName(), testCase.getMasterPassword() );
|
||||
|
||||
assertEquals(
|
||||
masterKey.encode( testCase.getSiteName(), testCase.getSiteType(), testCase.getSiteCounter(),
|
||||
testCase.getSiteVariant(), testCase.getSiteContext() ),
|
||||
testCase.getResult(), "[testEncode] Failed test case: " + testCase );
|
||||
|
||||
return true;
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserName()
|
||||
throws Exception {
|
||||
|
||||
MPTests.Case defaultCase = testSuite.getTests().getDefaultCase();
|
||||
|
||||
assertEquals( MasterKey.create( defaultCase.getFullName(), defaultCase.getMasterPassword() ).getFullName(),
|
||||
defaultCase.getFullName(), "[testGetUserName] Failed test case: " + defaultCase );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetKeyID()
|
||||
throws Exception {
|
||||
|
||||
testSuite.forEach( "testGetKeyID", new NNFunctionNN<MPTests.Case, Boolean>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Boolean apply(@Nonnull final MPTests.Case testCase) {
|
||||
MasterKey masterKey = MasterKey.create( testCase.getFullName(), testCase.getMasterPassword() );
|
||||
|
||||
assertEquals( CodeUtils.encodeHex( masterKey.getKeyID() ),
|
||||
testCase.getKeyID(), "[testGetKeyID] Failed test case: " + testCase );
|
||||
|
||||
return true;
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidate()
|
||||
throws Exception {
|
||||
|
||||
try {
|
||||
MPTests.Case defaultCase = testSuite.getTests().getDefaultCase();
|
||||
|
||||
MasterKey masterKey = MasterKey.create( defaultCase.getFullName(), defaultCase.getMasterPassword() );
|
||||
masterKey.invalidate();
|
||||
masterKey.encode( defaultCase.getSiteName(), defaultCase.getSiteType(), defaultCase.getSiteCounter(),
|
||||
defaultCase.getSiteVariant(), defaultCase.getSiteContext() );
|
||||
|
||||
assertTrue( false, "[testInvalidate] Master key should have been invalidated, but was still usable." );
|
||||
}
|
||||
catch (IllegalStateException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>masterpassword-tests</module>
|
||||
<module>masterpassword-algorithm</module>
|
||||
<module>masterpassword-model</module>
|
||||
<module>masterpassword-cli</module>
|
||||
|
Loading…
Reference in New Issue
Block a user