Commit f5e86625 authored by Nicolas Gilmard's avatar Nicolas Gilmard

Correct tests for TangibleApplication constructor with adapter load

reflexively
parent e6cf607c
package org.neverfear.assertexit;
import java.io.FileDescriptor;
import java.net.InetAddress;
import java.security.Permission;
/**
* Glue designed to allow a default delegate to implement most of the behaviour,
* but for a sub class to override specific methods.
*
* @author doug@neverfear.org
*
*/
abstract class DelegateSecurityManager
extends SecurityManager {
private final SecurityManager delegate;
DelegateSecurityManager(final SecurityManager delegate) {
super();
this.delegate = delegate;
}
@Override
public boolean getInCheck() {
return this.delegate.getInCheck();
}
@Override
public Object getSecurityContext() {
return this.delegate.getSecurityContext();
}
@Override
public void checkPermission(final Permission perm) {
this.delegate.checkPermission(perm);
}
@Override
public void checkPermission(final Permission perm, final Object context) {
this.delegate.checkPermission(perm, context);
}
@Override
public void checkCreateClassLoader() {
this.delegate.checkCreateClassLoader();
}
@Override
public void checkAccess(final Thread t) {
this.delegate.checkAccess(t);
}
@Override
public void checkAccess(final ThreadGroup g) {
this.delegate.checkAccess(g);
}
@Override
public void checkExit(final int status) {
this.delegate.checkExit(status);
}
@Override
public void checkExec(final String cmd) {
this.delegate.checkExec(cmd);
}
@Override
public void checkLink(final String lib) {
this.delegate.checkLink(lib);
}
@Override
public void checkRead(final FileDescriptor fd) {
this.delegate.checkRead(fd);
}
@Override
public void checkRead(final String file) {
this.delegate.checkRead(file);
}
@Override
public void checkRead(final String file, final Object context) {
this.delegate.checkRead(file, context);
}
@Override
public void checkWrite(final FileDescriptor fd) {
this.delegate.checkWrite(fd);
}
@Override
public void checkWrite(final String file) {
this.delegate.checkWrite(file);
}
@Override
public void checkDelete(final String file) {
this.delegate.checkDelete(file);
}
@Override
public void checkConnect(final String host, final int port) {
this.delegate.checkConnect(host, port);
}
@Override
public void checkConnect(final String host, final int port, final Object context) {
this.delegate.checkConnect(host, port, context);
}
@Override
public void checkListen(final int port) {
this.delegate.checkListen(port);
}
@Override
public void checkAccept(final String host, final int port) {
this.delegate.checkAccept(host, port);
}
@Override
public void checkMulticast(final InetAddress maddr) {
this.delegate.checkMulticast(maddr);
}
@Override
public void checkMulticast(final InetAddress maddr, final byte ttl) {
this.delegate.checkMulticast(maddr, ttl);
}
@Override
public void checkPropertiesAccess() {
this.delegate.checkPropertiesAccess();
}
@Override
public void checkPropertyAccess(final String key) {
this.delegate.checkPropertyAccess(key);
}
@Override
public boolean checkTopLevelWindow(final Object window) {
return this.delegate.checkTopLevelWindow(window);
}
@Override
public void checkPrintJobAccess() {
this.delegate.checkPrintJobAccess();
}
@Override
public void checkSystemClipboardAccess() {
this.delegate.checkSystemClipboardAccess();
}
@Override
public void checkAwtEventQueueAccess() {
this.delegate.checkAwtEventQueueAccess();
}
@Override
public void checkPackageAccess(final String pkg) {
this.delegate.checkPackageAccess(pkg);
}
@Override
public void checkPackageDefinition(final String pkg) {
this.delegate.checkPackageDefinition(pkg);
}
@Override
public void checkSetFactory() {
this.delegate.checkSetFactory();
}
@Override
public void checkMemberAccess(final Class<?> clazz, final int which) {
this.delegate.checkMemberAccess(clazz, which);
}
@Override
public void checkSecurityAccess(final String target) {
this.delegate.checkSecurityAccess(target);
}
@Override
public ThreadGroup getThreadGroup() {
return this.delegate.getThreadGroup();
}
}
package org.neverfear.assertexit;
import static java.lang.System.getSecurityManager;
import static java.lang.System.setSecurityManager;
final class ExitContext {
private static final ExitContext INSTANCE = new ExitContext();
private boolean enabled = false;
private SecurityManager previous;
/**
*
* @return The previously set {@link SecurityManager} or null if none.
*/
public SecurityManager enable() {
this.previous = getSecurityManager();
final SecurityManager delegate;
if (this.previous != null) {
delegate = this.previous;
} else {
delegate = new PermissiveSecurityManager();
}
setSecurityManager(new ExitDeniedSecurityManager(delegate));
this.enabled = true;
return this.previous;
}
public void disable() {
if (!this.enabled) {
throw new IllegalStateException("Not enabled");
}
setSecurityManager(this.previous);
}
public static ExitContext get() {
return INSTANCE;
}
}
\ No newline at end of file
package org.neverfear.assertexit;
final class ExitDeniedSecurityException
extends SecurityException {
private static final long serialVersionUID = 618060259432415688L;
private final int status;
public ExitDeniedSecurityException(final int status) {
this.status = status;
}
public int getStatus() {
return this.status;
}
}
\ No newline at end of file
package org.neverfear.assertexit;
/**
* Used for test purposes only. Throws an {@link ExitDeniedSecurityException} when
* {@link System#exit(int)} is called containing the status code.
*
* @author doug@neverfear.org
*
*/
final class ExitDeniedSecurityManager
extends DelegateSecurityManager {
ExitDeniedSecurityManager(final SecurityManager delegate) {
super(delegate);
}
@Override
public void checkExit(final int status) {
throw new ExitDeniedSecurityException(status);
}
}
package org.neverfear.assertexit;
import static org.junit.Assert.fail;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/**
* Rule to assert that {@link System#exit(int)} will be invoked.
*
* This done by replacing the system {@link SecurityManager}. Any existing
* {@link SecurityManager} will be preserved with the exception of the
* {@link SecurityManager#checkExit(int)} check which is intercepted.
*
* The following tests pass:
*
* <pre>
*
*
* public class ExpectedExitTest {
*
* &#064;Rule
* public ExpectedExit expectedExit = ExpectedExit.noAttempt();
*
* &#064;Test
* public void doesNotInvokeExit() {
* // does nothing
* }
*
* &#064;Test
* public void invokesExitAsExpected() {
* this.expectedExit.expectExit(7);
* System.exit(7);
* }
* }
* </pre>
*
* The following tests will fail:
*
* <pre>
*
*
* public class ExpectedExitTest {
*
* &#064;Rule
* public ExpectedExit expectedExit = ExpectedExit.noAttempt();
*
* &#064;Test
* public void invokesExitUnwantedly() {
* System.exit(1);
* }
*
* &#064;Test
* public void invokesExitWantedlyButWrongCode() {
* this.expectedExit.expectExit(1);
* System.exit(2);
* }
* }
* </pre>
*
* @author doug@neverfear.org
*
*/
public class ExpectedExit
implements TestRule {
public static ExpectedExit noAttempt() {
return new ExpectedExit();
}
private boolean expectsExit = false;
private int expectedStatus = Integer.MIN_VALUE;
private ExpectedExit() {}
public void expectExit(final int expectedStatus) {
this.expectsExit = true;
this.expectedStatus = expectedStatus;
}
private class ExpectedExitStatement
extends Statement {
private final Statement next;
public ExpectedExitStatement(final Statement base) {
this.next = base;
}
@Override
public void evaluate() throws Throwable {
final ExitContext context = ExitContext.get();
context.enable();
try {
this.next.evaluate();
if (ExpectedExit.this.expectsExit) {
fail("Expected test to exit with status " + ExpectedExit.this.expectedStatus);
}
} catch (final ExitDeniedSecurityException e) {
if (!ExpectedExit.this.expectsExit) {
fail("Exit was not expected but was invoked with status " + e.getStatus());
}
final int actual = e.getStatus();
if (actual != ExpectedExit.this.expectedStatus) {
fail("Wanted " + ExpectedExit.this.expectedStatus + " but was " + actual);
}
} finally {
context.disable();
}
}
}
@Override
public Statement apply(final Statement base, final Description description) {
return new ExpectedExitStatement(base);
}
}
package org.neverfear.assertexit;
import java.io.FileDescriptor;
import java.net.InetAddress;
import java.security.Permission;
/**
* A security manager that does not deny anything.
*
* @author doug@neverfear.org
*
*/
class PermissiveSecurityManager
extends SecurityManager {
@Override
public void checkPermission(final Permission perm) {}
@Override
public void checkPermission(final Permission perm, final Object context) {}
@Override
public void checkCreateClassLoader() {}
@Override
public void checkAccess(final Thread t) {}
@Override
public void checkAccess(final ThreadGroup g) {}
@Override
public void checkExit(final int status) {}
@Override
public void checkExec(final String cmd) {}
@Override
public void checkLink(final String lib) {}
@Override
public void checkRead(final FileDescriptor fd) {}
@Override
public void checkRead(final String file) {}
@Override
public void checkRead(final String file, final Object context) {}
@Override
public void checkWrite(final FileDescriptor fd) {}
@Override
public void checkWrite(final String file) {}
@Override
public void checkDelete(final String file) {}
@Override
public void checkConnect(final String host, final int port) {}
@Override
public void checkConnect(final String host, final int port, final Object context) {}
@Override
public void checkListen(final int port) {}
@Override
public void checkAccept(final String host, final int port) {}
@Override
public void checkMulticast(final InetAddress maddr) {}
@Override
public void checkMulticast(final InetAddress maddr, final byte ttl) {}
@Override
public void checkPropertiesAccess() {}
@Override
public void checkPropertyAccess(final String key) {}
@Override
public boolean checkTopLevelWindow(final Object window) {
return true;
}
@Override
public void checkPrintJobAccess() {}
@Override
public void checkSystemClipboardAccess() {}
@Override
public void checkAwtEventQueueAccess() {}
@Override
public void checkPackageAccess(final String pkg) {}
@Override
public void checkPackageDefinition(final String pkg) {}
@Override
public void checkSetFactory() {}
@Override
public void checkMemberAccess(final Class<?> clazz, final int which) {}
@Override
public void checkSecurityAccess(final String target) {}
}
......@@ -16,19 +16,33 @@ package lu.list.itis.dkd.tui;
import java.security.Permission;
/**
* @author gilmard
* @since [major].[minor]
* @version [major].[minor].[micro]
* @author Doug Lawrie
* @since 2.0
* @version 2.0.41
*/
public class ExitDeniedSecurityManager extends SecurityManager {
/**
* @author Doug Lawrie
* @since 2.0
* @version 2.0.41
*/
public static final class ExitSecurityException extends SecurityException {
private static final long serialVersionUID = 1321581078611017533L;
private final int status;
/**
* @param status
*/
public ExitSecurityException(final int status) {
this.status = status;
}
/**
* @return the exit code
*/
public int getStatus() {
return this.status;
}
......@@ -40,5 +54,7 @@ public class ExitDeniedSecurityManager extends SecurityManager {
}
@Override
public void checkPermission(final Permission perm) {}
public void checkPermission(final Permission perm) {
// Should override every method with empty
}
}
\ No newline at end of file
......@@ -13,15 +13,13 @@
*/
package lu.list.itis.dkd.tui;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import lu.list.itis.dkd.tui.ExitDeniedSecurityManager.ExitSecurityException;
import lu.list.itis.dkd.tui.adapter.TangibleObject;
import lu.list.itis.dkd.tui.adapter.TuiAdapter;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.neverfear.assertexit.ExpectedExit;
import java.io.FileInputStream;
import java.io.FileOutputStream;
......@@ -40,97 +38,157 @@ import java.util.logging.Level;
public class TangibleApplicationTest2 {
private String propertiesLocation = "test_properties.properties"; //$NON-NLS-1$
private TangibleApplication application;
private FileInputStream inputStream;
private FileOutputStream outputStream;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
System.setSecurityManager(new ExitDeniedSecurityManager());
// nothing to setup
}
/**
* provides the ability to assert that System.exit(...) is called with the expected status code.
*/
@Rule
public ExpectedExit expectedExit = ExpectedExit.noAttempt();