Class ComparingInvocationHandler<T>

java.lang.Object
google.registry.util.ComparingInvocationHandler<T>
All Implemented Interfaces:
InvocationHandler
Direct Known Subclasses:
ComparatorKeyring

public abstract class ComparingInvocationHandler<T> extends Object implements InvocationHandler
Abstract InvocationHandler comparing two implementations of some interface.

Given an interface, and two instances of that interface (the "original" instance we know works, and a "second" instance we wish to test), creates an InvocationHandler that acts like an exact proxy to the "original" instance.

In addition, it will log any differences in return values or thrown exception between the "original" and "second" instances.

This can be used to create an exact proxy to the original instance that can be placed in any code, while live testing the second instance.

  • Constructor Details

    • ComparingInvocationHandler

      public ComparingInvocationHandler(Class<T> interfaceClass, T actualImplementation, T secondImplementation)
      Creates a new InvocationHandler for the given interface.
      Parameters:
      interfaceClass - the interface we want to create.
      actualImplementation - the resulting proxy will be an exact proxy to this object
      secondImplementation - Only used to log difference compared to actualImplementation. Otherwise has no effect on the resulting proxy's behavior.
  • Method Details

    • makeProxy

      public final T makeProxy()
      Returns the proxy to the actualImplementation.

      The return value is a drop-in replacement to the actualImplementation, but will log any difference with the secondImplementation during normal execution.

    • log

      protected abstract void log(Method method, String message)
      Called when there was a difference between the implementations.
      Parameters:
      method - the method where the difference was found
      message - human readable description of the difference found
    • stringifyResult

      protected String stringifyResult(Method method, @Nullable Object object)
      Implements toString for specific types.

      By default objects are logged using their .toString. If .toString isn't implemented for some relevant classes (or if we want to use a different version), override this method with the desired implementation.

      Parameters:
      method - the method whose return value is given
      object - the object returned by a call to method
    • compareResults

      protected boolean compareResults(Method method, @Nullable Object actual, @Nullable Object second)
      Checks whether the method results are as similar as we expect.

      By default objects are compared using their .equals. If .equals isn't implemented for some relevant classes (or if we want change what is considered "not equal"), override this method with the desired implementation.

      Parameters:
      method - the method whose return value is given
      actual - the object returned by a call to method for the "actual" implementation
      second - the object returned by a call to method for the "second" implementation
    • compareThrown

      protected boolean compareThrown(Method method, Throwable actual, Throwable second)
      Checks whether the thrown exceptions are as similar as we expect.

      By default this returns 'true' for any input: all we check by default is that both implementations threw something. Override if you need to actually compare both throwables.

      Parameters:
      method - the method whose return value is given
      actual - the exception thrown by a call to method for the "actual" implementation
      second - the exception thrown by a call to method for the "second" implementation
    • stringifyThrown

      protected String stringifyThrown(Method method, Throwable throwable)
      Implements toString for thrown exceptions.

      By default exceptions are logged using their .toString. If more data is needed (part of stack trace for example), override this method with the desired implementation.

      Parameters:
      method - the method whose return value is given
      throwable - the exception thrown by a call to method
    • invoke

      public final Object invoke(Object proxy, Method method, Object[] args) throws Throwable
      Specified by:
      invoke in interface InvocationHandler
      Throws:
      Throwable