mirror of
https://github.com/google/nomulus.git
synced 2025-07-06 03:03:34 +02:00
Prober EPP components added (#202)
* Updated issues in rebasing * Minor style change on prober/build.gradle * Fixed warnings for java compilation * Fixed files to pass all style tests * Initial Commit. * Deleted unfinished features. Added ActionHandler and its Unit Tests. * Included prober subproject in settings.gradle * Added Protocol Class and its Basic Unit Tests * Added Changes Suggested by jianglai * Fixed Gitignore to take out AutoValue generated code * Removed AutoValue java files * Added gitignore within prober * Removed all generated java * Final Changes in .gitignore * Added Ssl and WebWhois Action Handlers and their unit tests in addition to the ProbingAction class * Fixed build.gradle changes requested * Removed Files irrelevant to current pull request * Minor fixes to ActionHandler, as responded in comments, removed package-info, and updated settings.gradle * Fully Updated ActionHandler (missing updated JavaDoc) * Added changed Protocol and both Inbound and Outbound Markers * Removed AutoVaue ignore clause from .gitignore * removed unneccessary dependencies in build.gradle * Fixed Javadoc and comments for ActionHandler * Fixed comments and JavaDoc on other files * EOL added * Removed Unnecessary Files * fixed .gradle files styles * Removed outbound message from ActionHandler's fields and renamed Marker Interfaces * Fixed javadoc for Marker Interfaced * Modified Comments on ActionHandler * Removed LocalAddress from Protocol * Fixed Travis Build Issues * Rebased to Master and added in modified Handlers and ProbingAction * Fixed changes suggested by CydeWeys * Added missing license headers and JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor Style Fix * Full WebWhoIs Sequence Added * fixed build issues * Refactored by responses suggested by jianglai. * Updated build.gradle file * Modified license header dates * Updated WebWhois tests. * Refactored WebWhois to accomodate jianglai's suggested changes and modified tests to reflect this refactoring * SpotlessApply run to fix style issues * Added license header and newline where appropriate. * Javadoc style fix in tests and removed unused methods * Refactored ProbingAction to minimize number of unnecessary methods * Modified tests for WebWhois according to changes suggested by laijiang. * Removed TestProvider from TestUtils. * Rebased to Master and added in modified Handlers and ProbingAction * Fixed changes suggested by CydeWeys * Added missing license headers and JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor Style Fix * Full WebWhoIs Sequence Added * fixed build issues * Refactored by responses suggested by jianglai. * Updated build.gradle file * Modified license header dates * Updated WebWhois tests. * Refactored WebWhois to accomodate jianglai's suggested changes and modified tests to reflect this refactoring * SpotlessApply run to fix style issues * Added license header and newline where appropriate. * Javadoc style fix in tests and removed unused methods * Refactored ProbingAction to minimize number of unnecessary methods * Modified tests for WebWhois according to changes suggested by laijiang. * Removed TestProvider from TestUtils. * Rebased to master * Updated issues in rebasing * Minor style change on prober/build.gradle * Fixed warnings for java compilation * Fixed files to pass all style tests * Minor syle fixes after succesful rebase onto master * Initial Commit. * Added Protocol Class and its Basic Unit Tests * Fixed Gitignore to take out AutoValue generated code * Final Changes in .gitignore * Minor fixes to ActionHandler, as responded in comments, removed package-info, and updated settings.gradle * Removed AutoVaue ignore clause from .gitignore * Rebased to Master and added in modified Handlers and ProbingAction * Full WebWhoIs Sequence Added * fixed build issues * Refactored by responses suggested by jianglai. * Added missing license headers and JavaDoc * Minor fix in NewChannelAction JavaDoc * Refactored WebWhois to accomodate jianglai's suggested changes and modified tests to reflect this refactoring * Full WebWhoIs Sequence Added * fixed build issues * Refactored by responses suggested by jianglai. * Modified license header dates * Refactored WebWhois to accomodate jianglai's suggested changes and modified tests to reflect this refactoring * SpotlessApply run to fix style issues * Added license header and newline where appropriate. * Javadoc style fix in tests and removed unused methods * Fixed files to pass all style tests * Fixed changes suggested by CydeWeys * Rebased to Master and added in modified Handlers and ProbingAction * Added missing license headers and JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor Style Fix * Full WebWhoIs Sequence Added * Refactored by responses suggested by jianglai. * Updated build.gradle file * Modified license header dates * Updated WebWhois tests. * Refactored WebWhois to accomodate jianglai's suggested changes and modified tests to reflect this refactoring * SpotlessApply run to fix style issues * Added license header and newline where appropriate. * Javadoc style fix in tests and removed unused methods * Refactored ProbingAction to minimize number of unnecessary methods * Modified tests for WebWhois according to changes suggested by laijiang. * Removed TestProvider from TestUtils. * Rebased to Master and added in modified Handlers and ProbingAction * Fixed changes suggested by CydeWeys * Added missing license headers and JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor Style Fix * Full WebWhoIs Sequence Added * fixed build issues * Refactored by responses suggested by jianglai. * Updated build.gradle file * Modified license header dates * Updated WebWhois tests. * Added license header and newline where appropriate. * Javadoc style fix in tests and removed unused methods * Refactored ProbingAction to minimize number of unnecessary methods * Modified tests for WebWhois according to changes suggested by laijiang. * Removed TestProvider from TestUtils. * Rebased to master * Updated issues in rebasing * Added circular linked list to utils * License Header added * Refactored probing sequence to be circular linked list iterator * Modified ProbingStep tests to reflect new ProbingStep structure. * Added circular linked list to utils * Added circular linked list to utils * License Header added * License Header added * Refactored probing sequence to be circular linked list iterator * Modified ProbingStep tests to reflect new ProbingStep structure. * Added missing license header to DefaultCircularLinkedListIterator * Fixed changes suggested by CydeWeys * Rebased to Master and added in modified Handlers and ProbingAction * Added missing license headers and JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor Style Fix * Full WebWhoIs Sequence Added * fixed build issues * Refactored by responses suggested by jianglai. * Updated build.gradle file * Fixed max column length to be 100 * Rebased to Master and added in modified Handlers and ProbingAction * Modified license header dates * Updated WebWhois tests. * Refactored WebWhois to accomodate jianglai's suggested changes and modified tests to reflect this refactoring * Javadoc style fix in tests and removed unused methods * Refactored ProbingAction to minimize number of unnecessary methods * Modified tests for WebWhois according to changes suggested by laijiang. * Fixed changes suggested by CydeWeys * Added missing license headers and JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor Style Fix * Full WebWhoIs Sequence Added * fixed build issues * Refactored by responses suggested by jianglai. * Updated build.gradle file * Modified license header dates * Updated WebWhois tests. * Refactored WebWhois to accomodate jianglai's suggested changes and modified tests to reflect this refactoring * SpotlessApply run to fix style issues * Added license header and newline where appropriate. * Javadoc style fix in tests and removed unused methods * Refactored ProbingAction to minimize number of unnecessary methods * Added circular linked list to utils * Added circular linked list to utils * License Header added * License Header added * Refactored probing sequence to be circular linked list iterator * Refactored probing sequence to be circular linked list iterator * Modified tests for WebWhois according to changes suggested by laijiang. * Removed TestProvider from TestUtils. * ProbingStepTest modified to have fewer unnecessary helper methods * Updated issues in rebasing * Fixed max column length to be 100 * Minor changes to pass style tests * Successful rebase onto finished web-whois branch * Removed need for TestTokens with Mockito mocks of Tokens * Fixed style issues in DefaultCircularLinkedListIterator and AbstractCircularLinkedListIterator * Modified CircularList according to changes suggested by jianglai. * Added Protocol Class and its Basic Unit Tests * Added Ssl and WebWhois Action Handlers and their unit tests in addition to the ProbingAction class * Fixed changes suggested by CydeWeys * Fixed changes suggested by CydeWeys * Rebased to Master and added in modified Handlers and ProbingAction * Rebased to Master and added in modified Handlers and ProbingAction * Rebased to Master and added in modified Handlers and ProbingAction * Rebased to Master and added in modified Handlers and ProbingAction * Rebased to Master and added in modified Handlers and ProbingAction * Added missing license headers and JavaDoc * Minor Style Fix * Minor Style Fix * Full WebWhoIs Sequence Added * Full WebWhoIs Sequence Added * Full WebWhoIs Sequence Added * Full WebWhoIs Sequence Added * fixed build issues * Refactored by responses suggested by jianglai. * Updated build.gradle file * Updated WebWhois tests. * Added Basic EPP structure * Added Basic EPP structure * Prober Updated tests * Prober Updated tests * Fully functioning EPP sequences with modified WebWhois base. * Fully functioning EPP sequences with modified WebWhois base. * Added Modified test server infrastructure. * Added Modified test server infrastructure. * Allowed ActionHandler to pass status to next hanlder in pipeline (to be MetricsHandler). * Allowed ActionHandler to pass status to next hanlder in pipeline (to be MetricsHandler). * Javadoc on EppRequestMessage added * Javadoc on EppRequestMessage added * Updated EppServer to properly send successful Check responses. * Updated EppServer to properly send successful Check responses. * Allowed for expected failures in EPP actions. * Refactored WebWhois to accomodate jianglai's suggested changes and modified tests to reflect this refactoring * Refactored WebWhois to accomodate jianglai's suggested changes and modified tests to reflect this refactoring * Refactored WebWhois to accomodate jianglai's suggested changes and modified tests to reflect this refactoring * Refactored WebWhois to accomodate jianglai's suggested changes and modified tests to reflect this refactoring * Fully rebased branch to prober-web-whois after refactoring * Added license header and newline where appropriate. * Javadoc style fix in tests and removed unused methods * Javadoc style fix in tests and removed unused methods * Modified tests for WebWhois according to changes suggested by laijiang. * Modified tests for WebWhois according to changes suggested by laijiang. * Removed TestProvider from TestUtils. * Rebased to master * Fixed max column length to be 100 * Fixed files to pass all style tests * Minor changes to pass style tests * Successful rebase onto circular-list * Epp Refactored to accomodate circular linked list PR * Modified construction of Epp Probing Sequences to reflect CircularList change * Renamed ProberModule provided Duration * Removed unnecessary ServerSideException file * Google-Java-Format run on all prober files * Style fix on ProbingSequence and its unit tests * Removed subclasses of EppRequestMessage and EppResponseMessage and fixed style and other minor issues * Style changes implemented as suggested by jianglai * Added style fixes suggested by mindhog
This commit is contained in:
parent
86fefa9a03
commit
57975898d5
66 changed files with 6089 additions and 1083 deletions
|
@ -22,6 +22,8 @@ import static org.mockito.Mockito.doThrow;
|
|||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import google.registry.monitoring.blackbox.connection.ProbingAction;
|
||||
import google.registry.monitoring.blackbox.connection.Protocol;
|
||||
import google.registry.monitoring.blackbox.exceptions.FailureException;
|
||||
import google.registry.monitoring.blackbox.exceptions.UndeterminedStateException;
|
||||
import google.registry.monitoring.blackbox.exceptions.UnrecoverableStateException;
|
||||
|
@ -38,22 +40,20 @@ import org.mockito.Mockito;
|
|||
/**
|
||||
* Unit Tests on {@link ProbingSequence}
|
||||
*
|
||||
* <p>First tests the construction of sequences and ensures the ordering is exactly how
|
||||
* we expect it to be.</p>
|
||||
* <p>First tests the construction of sequences and ensures the ordering is exactly how we expect it
|
||||
* to be.
|
||||
*
|
||||
* <p>Then tests the execution of each step, by ensuring the methods treatment of any kind
|
||||
* of response from the {@link ProbingStep}s or {@link ProbingAction}s is what is expected.</p>
|
||||
* <p>Then tests the execution of each step, by ensuring the methods treatment of any kind of
|
||||
* response from the {@link ProbingStep}s or {@link ProbingAction}s is what is expected.
|
||||
*
|
||||
* <p>On every test that runs the sequence, in order for the sequence to stop, we throw an
|
||||
* {@link UnrecoverableStateException}, using mocks of the steps or actions, as the sequences
|
||||
* are run using the main thread (with {@link EmbeddedChannel}).</p>
|
||||
* <p>On every test that runs the sequence, in order for the sequence to stop, we throw an {@link
|
||||
* UnrecoverableStateException}, using mocks of the steps or actions, as the sequences are run using
|
||||
* the main thread (with {@link EmbeddedChannel}).
|
||||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
public class ProbingSequenceTest {
|
||||
|
||||
/**
|
||||
* Default mock {@link ProbingAction} returned when generating an action with a mockStep.
|
||||
*/
|
||||
/** Default mock {@link ProbingAction} returned when generating an action with a mockStep. */
|
||||
private ProbingAction mockAction = Mockito.mock(ProbingAction.class);
|
||||
|
||||
/**
|
||||
|
@ -62,10 +62,7 @@ public class ProbingSequenceTest {
|
|||
*/
|
||||
private ProbingStep mockStep = Mockito.mock(ProbingStep.class);
|
||||
|
||||
|
||||
/**
|
||||
* Default mock {@link Token} that is passed into each {@link ProbingSequence} tested.
|
||||
*/
|
||||
/** Default mock {@link Token} that is passed into each {@link ProbingSequence} tested. */
|
||||
private Token mockToken = Mockito.mock(Token.class);
|
||||
|
||||
/**
|
||||
|
@ -104,11 +101,12 @@ public class ProbingSequenceTest {
|
|||
ProbingStep secondStep = Mockito.mock(ProbingStep.class);
|
||||
ProbingStep thirdStep = Mockito.mock(ProbingStep.class);
|
||||
|
||||
ProbingSequence sequence = new ProbingSequence.Builder(mockToken)
|
||||
.add(firstStep)
|
||||
.add(secondStep)
|
||||
.add(thirdStep)
|
||||
.build();
|
||||
ProbingSequence sequence =
|
||||
new ProbingSequence.Builder(mockToken)
|
||||
.add(firstStep)
|
||||
.add(secondStep)
|
||||
.add(thirdStep)
|
||||
.build();
|
||||
|
||||
assertThat(sequence.get()).isEqualTo(firstStep);
|
||||
sequence = sequence.next();
|
||||
|
@ -128,12 +126,13 @@ public class ProbingSequenceTest {
|
|||
ProbingStep secondStep = Mockito.mock(ProbingStep.class);
|
||||
ProbingStep thirdStep = Mockito.mock(ProbingStep.class);
|
||||
|
||||
ProbingSequence sequence = new ProbingSequence.Builder(mockToken)
|
||||
.add(thirdStep)
|
||||
.add(secondStep)
|
||||
.markFirstRepeated()
|
||||
.add(firstStep)
|
||||
.build();
|
||||
ProbingSequence sequence =
|
||||
new ProbingSequence.Builder(mockToken)
|
||||
.add(thirdStep)
|
||||
.add(secondStep)
|
||||
.markFirstRepeated()
|
||||
.add(firstStep)
|
||||
.build();
|
||||
|
||||
assertThat(sequence.get()).isEqualTo(thirdStep);
|
||||
sequence = sequence.next();
|
||||
|
@ -145,47 +144,43 @@ public class ProbingSequenceTest {
|
|||
sequence = sequence.next();
|
||||
|
||||
assertThat(sequence.get()).isEqualTo(secondStep);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunStep_Success() throws UndeterminedStateException {
|
||||
//Always returns a succeeded future on call to mockAction.
|
||||
// Always returns a succeeded future on call to mockAction.
|
||||
doReturn(channel.newSucceededFuture()).when(mockAction).call();
|
||||
|
||||
// Has mockStep always return mockAction on call to generateAction
|
||||
// Has mockStep always return mockAction on call to generateAction.
|
||||
doReturn(mockAction).when(mockStep).generateAction(any(Token.class));
|
||||
|
||||
//Dummy step that server purpose of placeholder to test ability of ProbingSequence to move on.
|
||||
// Dummy step that server purpose of placeholder to test ability of ProbingSequence to move on.
|
||||
ProbingStep secondStep = Mockito.mock(ProbingStep.class);
|
||||
ProbingAction secondAction = Mockito.mock(ProbingAction.class);
|
||||
|
||||
doReturn(channel.newFailedFuture(new UnrecoverableStateException(""))).when(secondAction)
|
||||
doReturn(channel.newFailedFuture(new UnrecoverableStateException("")))
|
||||
.when(secondAction)
|
||||
.call();
|
||||
doReturn(secondAction).when(secondStep).generateAction(mockToken);
|
||||
|
||||
//Build testable sequence from mocked components.
|
||||
ProbingSequence sequence = new ProbingSequence.Builder(mockToken)
|
||||
.add(mockStep)
|
||||
.add(secondStep)
|
||||
.build();
|
||||
// Build testable sequence from mocked components.
|
||||
ProbingSequence sequence =
|
||||
new ProbingSequence.Builder(mockToken).add(mockStep).add(secondStep).build();
|
||||
|
||||
sequence.start();
|
||||
|
||||
// We expect to have only generated actions from mockStep once, and we expect to have called
|
||||
// this generated action only once, as when we move on to secondStep, it terminates the
|
||||
// sequence.
|
||||
verify(mockStep).generateAction(any(Token.class));
|
||||
verify(mockStep).generateAction(mockToken);
|
||||
verify(mockAction).call();
|
||||
|
||||
// Similarly, we expect to generate actions and call the action from the secondStep once, as
|
||||
// after calling it, the sequence should be terminated
|
||||
verify(secondStep).generateAction(any(Token.class));
|
||||
verify(secondStep).generateAction(mockToken);
|
||||
verify(secondAction).call();
|
||||
|
||||
//We should have modified the token's channel after the first, succeeded step.
|
||||
// We should have modified the token's channel after the first, succeeded step.
|
||||
assertThat(mockToken.channel()).isEqualTo(channel);
|
||||
}
|
||||
|
||||
|
@ -201,7 +196,7 @@ public class ProbingSequenceTest {
|
|||
ProbingStep secondStep = Mockito.mock(ProbingStep.class);
|
||||
ProbingAction secondAction = Mockito.mock(ProbingAction.class);
|
||||
|
||||
// Necessary for success of ProbingSequence runStep method as it calls get().protocol()
|
||||
// Necessary for success of ProbingSequence runStep method as it calls get().protocol().
|
||||
doReturn(mockProtocol).when(secondStep).protocol();
|
||||
|
||||
// We ensure that secondStep has necessary attributes to be successful step to pass on to
|
||||
|
@ -220,18 +215,15 @@ public class ProbingSequenceTest {
|
|||
doReturn(channel.newFailedFuture(new UnrecoverableStateException(""))).when(thirdAction).call();
|
||||
doReturn(thirdAction).when(mockStep).generateAction(secondToken);
|
||||
|
||||
//Build testable sequence from mocked components.
|
||||
ProbingSequence sequence = new ProbingSequence.Builder(mockToken)
|
||||
.add(mockStep)
|
||||
.add(secondStep)
|
||||
.build();
|
||||
// Build testable sequence from mocked components.
|
||||
ProbingSequence sequence =
|
||||
new ProbingSequence.Builder(mockToken).add(mockStep).add(secondStep).build();
|
||||
|
||||
sequence.start();
|
||||
|
||||
// We expect to have generated actions from mockStep twice (once for mockToken and once for
|
||||
// secondToken), and we expectto have called each generated action only once, as when we move
|
||||
// on to mockStep the second time, it will terminate the sequence after calling thirdAction.
|
||||
verify(mockStep, times(2)).generateAction(any(Token.class));
|
||||
verify(mockStep).generateAction(mockToken);
|
||||
verify(mockStep).generateAction(secondToken);
|
||||
verify(mockAction).call();
|
||||
|
@ -239,23 +231,22 @@ public class ProbingSequenceTest {
|
|||
|
||||
// Similarly, we expect to generate actions and call the action from the secondStep once, as
|
||||
// after calling it, we move on to mockStep again, which terminates the sequence.
|
||||
verify(secondStep).generateAction(any(Token.class));
|
||||
verify(secondStep).generateAction(mockToken);
|
||||
verify(secondAction).call();
|
||||
|
||||
//We should have modified the token's channel after the first, succeeded step.
|
||||
// We should have modified the token's channel after the first, succeeded step.
|
||||
assertThat(mockToken.channel()).isEqualTo(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for when we expect Failure within try catch block of generating and calling a
|
||||
* {@link ProbingAction}.
|
||||
* Test for when we expect Failure within try catch block of generating and calling a {@link
|
||||
* ProbingAction}.
|
||||
*
|
||||
* @throws UndeterminedStateException - necessary for having mock return anything on a call to
|
||||
* {@code generateAction}.
|
||||
* @throws UndeterminedStateException - necessary for having mock return anything on a call to
|
||||
* {@code generateAction}.
|
||||
*/
|
||||
private void testActionFailure() throws UndeterminedStateException {
|
||||
//Dummy step that server purpose of placeholder to test ability of ProbingSequence to move on.
|
||||
// Dummy step that server purpose of placeholder to test ability of ProbingSequence to move on.
|
||||
ProbingStep secondStep = Mockito.mock(ProbingStep.class);
|
||||
|
||||
// We create a second token that when used to generate an action throws an
|
||||
|
@ -264,18 +255,15 @@ public class ProbingSequenceTest {
|
|||
doReturn(secondToken).when(mockToken).next();
|
||||
doThrow(new UnrecoverableStateException("")).when(mockStep).generateAction(secondToken);
|
||||
|
||||
//Build testable sequence from mocked components.
|
||||
ProbingSequence sequence = new ProbingSequence.Builder(mockToken)
|
||||
.add(mockStep)
|
||||
.add(secondStep)
|
||||
.build();
|
||||
// Build testable sequence from mocked components.
|
||||
ProbingSequence sequence =
|
||||
new ProbingSequence.Builder(mockToken).add(mockStep).add(secondStep).build();
|
||||
|
||||
sequence.start();
|
||||
|
||||
// We expect that we have generated actions twice. First, when we actually test generateAction
|
||||
// with an actual call using mockToken, and second when we throw an
|
||||
// UnrecoverableStateException with secondToken.
|
||||
verify(mockStep, times(2)).generateAction(any(Token.class));
|
||||
verify(mockStep).generateAction(mockToken);
|
||||
verify(mockStep).generateAction(secondToken);
|
||||
|
||||
|
@ -296,17 +284,14 @@ public class ProbingSequenceTest {
|
|||
// Returns mock action on call to generate action for ProbingStep.
|
||||
doReturn(mockAction).when(mockStep).generateAction(mockToken);
|
||||
|
||||
//Tests generic behavior we expect when we fail in generating or calling an action.
|
||||
// Tests generic behavior we expect when we fail in generating or calling an action.
|
||||
testActionFailure();
|
||||
|
||||
// We only expect to have called this action once, as we only get it from one generateAction
|
||||
// call.
|
||||
verify(mockAction).call();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRunStep_FailureGenerating() throws UndeterminedStateException {
|
||||
// Create a mock first step that returns the dummy action when called to generate an action.
|
||||
|
|
|
@ -15,12 +15,14 @@
|
|||
package google.registry.monitoring.blackbox;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.monitoring.blackbox.ProbingAction.CONNECTION_FUTURE_KEY;
|
||||
import static google.registry.monitoring.blackbox.connection.ProbingAction.CONNECTION_FUTURE_KEY;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.monitoring.blackbox.connection.ProbingAction;
|
||||
import google.registry.monitoring.blackbox.connection.Protocol;
|
||||
import google.registry.monitoring.blackbox.exceptions.UndeterminedStateException;
|
||||
import google.registry.monitoring.blackbox.handlers.ActionHandler;
|
||||
import google.registry.monitoring.blackbox.handlers.ConversionHandler;
|
||||
|
@ -48,31 +50,26 @@ import org.mockito.Mockito;
|
|||
*/
|
||||
public class ProbingStepTest {
|
||||
|
||||
/**
|
||||
* Basic Constants necessary for tests
|
||||
*/
|
||||
/** Basic Constants necessary for tests */
|
||||
private static final String ADDRESS_NAME = "TEST_ADDRESS";
|
||||
|
||||
private static final String PROTOCOL_NAME = "TEST_PROTOCOL";
|
||||
private static final int PROTOCOL_PORT = 0;
|
||||
private static final String TEST_MESSAGE = "TEST_MESSAGE";
|
||||
private static final String SECONDARY_TEST_MESSAGE = "SECONDARY_TEST_MESSAGE";
|
||||
private static final LocalAddress address = new LocalAddress(ADDRESS_NAME);
|
||||
private final EventLoopGroup eventLoopGroup = new NioEventLoopGroup(1);
|
||||
private final Bootstrap bootstrap = new Bootstrap()
|
||||
.group(eventLoopGroup)
|
||||
.channel(LocalChannel.class);
|
||||
/**
|
||||
* Used for testing how well probing step can create connection to blackbox server
|
||||
*/
|
||||
@Rule
|
||||
public NettyRule nettyRule = new NettyRule(eventLoopGroup);
|
||||
|
||||
private final Bootstrap bootstrap =
|
||||
new Bootstrap().group(eventLoopGroup).channel(LocalChannel.class);
|
||||
/** Used for testing how well probing step can create connection to blackbox server */
|
||||
@Rule public NettyRule nettyRule = new NettyRule(eventLoopGroup);
|
||||
|
||||
/**
|
||||
* The two main handlers we need in any test pipeline used that connects to {@link NettyRule's
|
||||
* server}
|
||||
**/
|
||||
*/
|
||||
private ActionHandler testHandler = new TestActionHandler();
|
||||
|
||||
private ChannelHandler conversionHandler = new ConversionHandler();
|
||||
|
||||
/**
|
||||
|
@ -92,12 +89,13 @@ public class ProbingStepTest {
|
|||
@Test
|
||||
public void testProbingActionGenerate_embeddedChannel() throws UndeterminedStateException {
|
||||
// Sets up Protocol to represent existing channel connection.
|
||||
Protocol testProtocol = Protocol.builder()
|
||||
.setHandlerProviders(ImmutableList.of(() -> conversionHandler, () -> testHandler))
|
||||
.setName(PROTOCOL_NAME)
|
||||
.setPort(PROTOCOL_PORT)
|
||||
.setPersistentConnection(true)
|
||||
.build();
|
||||
Protocol testProtocol =
|
||||
Protocol.builder()
|
||||
.setHandlerProviders(ImmutableList.of(() -> conversionHandler, () -> testHandler))
|
||||
.setName(PROTOCOL_NAME)
|
||||
.setPort(PROTOCOL_PORT)
|
||||
.setPersistentConnection(true)
|
||||
.build();
|
||||
|
||||
// Sets up an embedded channel to contain the two handlers we created already.
|
||||
EmbeddedChannel channel = new EmbeddedChannel(conversionHandler, testHandler);
|
||||
|
@ -109,12 +107,13 @@ public class ProbingStepTest {
|
|||
doReturn(channel).when(testToken).channel();
|
||||
|
||||
// Sets up generic {@link ProbingStep} that we are testing.
|
||||
ProbingStep testStep = ProbingStep.builder()
|
||||
.setMessageTemplate(new TestMessage(TEST_MESSAGE))
|
||||
.setBootstrap(bootstrap)
|
||||
.setDuration(Duration.ZERO)
|
||||
.setProtocol(testProtocol)
|
||||
.build();
|
||||
ProbingStep testStep =
|
||||
ProbingStep.builder()
|
||||
.setMessageTemplate(new TestMessage(TEST_MESSAGE))
|
||||
.setBootstrap(bootstrap)
|
||||
.setDuration(Duration.ZERO)
|
||||
.setProtocol(testProtocol)
|
||||
.build();
|
||||
|
||||
ProbingAction testAction = testStep.generateAction(testToken);
|
||||
|
||||
|
@ -123,27 +122,27 @@ public class ProbingStepTest {
|
|||
assertThat(testAction.outboundMessage().toString()).isEqualTo(SECONDARY_TEST_MESSAGE);
|
||||
assertThat(testAction.host()).isEqualTo(SECONDARY_TEST_MESSAGE);
|
||||
assertThat(testAction.protocol()).isEqualTo(testProtocol);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProbingActionGenerate_newChannel() throws UndeterminedStateException {
|
||||
// Sets up Protocol for when we create a new channel.
|
||||
Protocol testProtocol = Protocol.builder()
|
||||
.setHandlerProviders(ImmutableList.of(() -> conversionHandler, () -> testHandler))
|
||||
.setName(PROTOCOL_NAME)
|
||||
.setPort(PROTOCOL_PORT)
|
||||
.setPersistentConnection(false)
|
||||
.build();
|
||||
Protocol testProtocol =
|
||||
Protocol.builder()
|
||||
.setHandlerProviders(ImmutableList.of(() -> conversionHandler, () -> testHandler))
|
||||
.setName(PROTOCOL_NAME)
|
||||
.setPort(PROTOCOL_PORT)
|
||||
.setPersistentConnection(false)
|
||||
.build();
|
||||
|
||||
// Sets up generic ProbingStep that we are testing.
|
||||
ProbingStep testStep = ProbingStep.builder()
|
||||
.setMessageTemplate(new TestMessage(TEST_MESSAGE))
|
||||
.setBootstrap(bootstrap)
|
||||
.setDuration(Duration.ZERO)
|
||||
.setProtocol(testProtocol)
|
||||
.build();
|
||||
ProbingStep testStep =
|
||||
ProbingStep.builder()
|
||||
.setMessageTemplate(new TestMessage(TEST_MESSAGE))
|
||||
.setBootstrap(bootstrap)
|
||||
.setDuration(Duration.ZERO)
|
||||
.setProtocol(testProtocol)
|
||||
.build();
|
||||
|
||||
// Sets up testToken to return arbitrary values, and no channel. Used when we create a new
|
||||
// channel.
|
||||
|
@ -162,7 +161,5 @@ public class ProbingStepTest {
|
|||
assertThat(testAction.outboundMessage().toString()).isEqualTo(ADDRESS_NAME);
|
||||
assertThat(testAction.host()).isEqualTo(ADDRESS_NAME);
|
||||
assertThat(testAction.protocol()).isEqualTo(testProtocol);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.monitoring.blackbox;
|
||||
package google.registry.monitoring.blackbox.connection;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.monitoring.blackbox.ProbingAction.CONNECTION_FUTURE_KEY;
|
||||
import static google.registry.monitoring.blackbox.connection.ProbingAction.CONNECTION_FUTURE_KEY;
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
|
@ -46,7 +46,7 @@ import org.junit.runners.JUnit4;
|
|||
* Unit tests for {@link ProbingAction} subtypes
|
||||
*
|
||||
* <p>Attempts to test how well each {@link ProbingAction} works with an {@link ActionHandler}
|
||||
* subtype when receiving to all possible types of responses</p>
|
||||
* subtype when receiving to all possible types of responses
|
||||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
public class ProbingActionTest {
|
||||
|
@ -58,53 +58,55 @@ public class ProbingActionTest {
|
|||
private static final int TEST_PORT = 0;
|
||||
|
||||
private static final EventLoopGroup eventLoopGroup = new NioEventLoopGroup(1);
|
||||
/**
|
||||
* Used for testing how well probing step can create connection to blackbox server
|
||||
*/
|
||||
@Rule
|
||||
public NettyRule nettyRule = new NettyRule(eventLoopGroup);
|
||||
|
||||
/** Used for testing how well probing step can create connection to blackbox server */
|
||||
@Rule public NettyRule nettyRule = new NettyRule(eventLoopGroup);
|
||||
|
||||
/**
|
||||
* We use custom Test {@link ActionHandler} and {@link ConversionHandler} so test depends only on
|
||||
* {@link ProbingAction}
|
||||
*/
|
||||
private ActionHandler testHandler = new TestActionHandler();
|
||||
|
||||
private ChannelHandler conversionHandler = new ConversionHandler();
|
||||
|
||||
//TODO - Currently, this test fails to receive outbound messages from the embedded channel, which
|
||||
// TODO - Currently, this test fails to receive outbound messages from the embedded channel, which
|
||||
// we will fix in a later release.
|
||||
@Ignore
|
||||
@Test
|
||||
public void testSuccess_existingChannel() {
|
||||
//setup
|
||||
// setup
|
||||
EmbeddedChannel channel = new EmbeddedChannel(conversionHandler, testHandler);
|
||||
channel.attr(CONNECTION_FUTURE_KEY).set(channel.newSucceededFuture());
|
||||
|
||||
// Sets up a Protocol corresponding to when a connection exists.
|
||||
Protocol protocol = Protocol.builder()
|
||||
.setHandlerProviders(ImmutableList.of(() -> conversionHandler, () -> testHandler))
|
||||
.setName(PROTOCOL_NAME)
|
||||
.setPort(TEST_PORT)
|
||||
.setPersistentConnection(true)
|
||||
.build();
|
||||
Protocol protocol =
|
||||
Protocol.builder()
|
||||
.setHandlerProviders(ImmutableList.of(() -> conversionHandler, () -> testHandler))
|
||||
.setName(PROTOCOL_NAME)
|
||||
.setPort(TEST_PORT)
|
||||
.setPersistentConnection(true)
|
||||
.build();
|
||||
|
||||
// Sets up a ProbingAction that creates a channel using test specified attributes.
|
||||
ProbingAction action = ProbingAction.builder()
|
||||
.setChannel(channel)
|
||||
.setProtocol(protocol)
|
||||
.setDelay(Duration.ZERO)
|
||||
.setOutboundMessage(new TestMessage(TEST_MESSAGE))
|
||||
.setHost("")
|
||||
.build();
|
||||
ProbingAction action =
|
||||
ProbingAction.builder()
|
||||
.setChannel(channel)
|
||||
.setProtocol(protocol)
|
||||
.setDelay(Duration.ZERO)
|
||||
.setOutboundMessage(new TestMessage(TEST_MESSAGE))
|
||||
.setHost("")
|
||||
.build();
|
||||
|
||||
//tests main function of ProbingAction
|
||||
// tests main function of ProbingAction
|
||||
ChannelFuture future = action.call();
|
||||
|
||||
//Obtains the outboundMessage passed through pipeline after delay
|
||||
// Obtains the outboundMessage passed through pipeline after delay
|
||||
Object msg = null;
|
||||
while (msg == null) {
|
||||
msg = channel.readOutbound();
|
||||
}
|
||||
//tests the passed message is exactly what we expect
|
||||
// tests the passed message is exactly what we expect
|
||||
assertThat(msg).isInstanceOf(ByteBuf.class);
|
||||
String request = ((ByteBuf) msg).toString(UTF_8);
|
||||
assertThat(request).isEqualTo(TEST_MESSAGE);
|
||||
|
@ -112,7 +114,8 @@ public class ProbingActionTest {
|
|||
// Ensures that we haven't marked future as done until response is received.
|
||||
assertThat(future.isDone()).isFalse();
|
||||
|
||||
//after writing inbound, we should have a success
|
||||
// After writing inbound, we should have a success as we use an EmbeddedChannel, ensuring all
|
||||
// operations happen on the main thread - i.e. synchronously.
|
||||
channel.writeInbound(Unpooled.wrappedBuffer(SECONDARY_TEST_MESSAGE.getBytes(US_ASCII)));
|
||||
assertThat(future.isSuccess()).isTrue();
|
||||
|
||||
|
@ -121,42 +124,41 @@ public class ProbingActionTest {
|
|||
|
||||
@Test
|
||||
public void testSuccess_newChannel() throws Exception {
|
||||
//setup
|
||||
// setup
|
||||
|
||||
LocalAddress address = new LocalAddress(ADDRESS_NAME);
|
||||
Bootstrap bootstrap = new Bootstrap()
|
||||
.group(eventLoopGroup)
|
||||
.channel(LocalChannel.class);
|
||||
Bootstrap bootstrap = new Bootstrap().group(eventLoopGroup).channel(LocalChannel.class);
|
||||
|
||||
// Sets up a Protocol corresponding to when a new connection is created.
|
||||
Protocol protocol = Protocol.builder()
|
||||
.setHandlerProviders(ImmutableList.of(() -> conversionHandler, () -> testHandler))
|
||||
.setName(PROTOCOL_NAME)
|
||||
.setPort(TEST_PORT)
|
||||
.setPersistentConnection(false)
|
||||
.build();
|
||||
Protocol protocol =
|
||||
Protocol.builder()
|
||||
.setHandlerProviders(ImmutableList.of(() -> conversionHandler, () -> testHandler))
|
||||
.setName(PROTOCOL_NAME)
|
||||
.setPort(TEST_PORT)
|
||||
.setPersistentConnection(false)
|
||||
.build();
|
||||
|
||||
nettyRule.setUpServer(address);
|
||||
|
||||
// Sets up a ProbingAction with existing channel using test specified attributes.
|
||||
ProbingAction action = ProbingAction.builder()
|
||||
.setBootstrap(bootstrap)
|
||||
.setProtocol(protocol)
|
||||
.setDelay(Duration.ZERO)
|
||||
.setOutboundMessage(new TestMessage(TEST_MESSAGE))
|
||||
.setHost(ADDRESS_NAME)
|
||||
.build();
|
||||
ProbingAction action =
|
||||
ProbingAction.builder()
|
||||
.setBootstrap(bootstrap)
|
||||
.setProtocol(protocol)
|
||||
.setDelay(Duration.ZERO)
|
||||
.setOutboundMessage(new TestMessage(TEST_MESSAGE))
|
||||
.setHost(ADDRESS_NAME)
|
||||
.build();
|
||||
|
||||
//tests main function of ProbingAction
|
||||
// tests main function of ProbingAction
|
||||
ChannelFuture future = action.call();
|
||||
|
||||
//Tests to see if message is properly sent to remote server
|
||||
// Tests to see if message is properly sent to remote server
|
||||
nettyRule.assertReceivedMessage(TEST_MESSAGE);
|
||||
|
||||
future = future.syncUninterruptibly();
|
||||
//Tests to see that, since server responds, we have set future to true
|
||||
// Tests to see that, since server responds, we have set future to true
|
||||
assertThat(future.isSuccess()).isTrue();
|
||||
assertThat(((TestActionHandler) testHandler).getResponse().toString()).isEqualTo(TEST_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
|
@ -31,24 +31,20 @@ import io.netty.channel.ChannelPromise;
|
|||
* {@link ChannelHandler} used in tests to convert {@link OutboundMessageType} to to {@link
|
||||
* ByteBuf}s and convert {@link ByteBuf}s to {@link InboundMessageType}
|
||||
*
|
||||
* <p>Specific type of {@link OutboundMessageType} and {@link InboundMessageType}
|
||||
* used for conversion is the {@link TestMessage} type.</p>
|
||||
* <p>Specific type of {@link OutboundMessageType} and {@link InboundMessageType} used for
|
||||
* conversion is the {@link TestMessage} type.
|
||||
*/
|
||||
public class ConversionHandler extends ChannelDuplexHandler {
|
||||
|
||||
/**
|
||||
* Handles inbound conversion
|
||||
*/
|
||||
/** Handles inbound conversion */
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||
ByteBuf buf = (ByteBuf) msg;
|
||||
ctx.fireChannelRead(new TestMessage(buf.toString(UTF_8)));
|
||||
buf.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles outbound conversion
|
||||
*/
|
||||
/** Handles outbound conversion */
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
|
||||
throws Exception {
|
||||
|
@ -57,4 +53,3 @@ public class ConversionHandler extends ChannelDuplexHandler {
|
|||
super.write(ctx, buf, promise);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License
|
||||
|
||||
package google.registry.monitoring.blackbox.handlers;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.JUnitBackports.assertThrows;
|
||||
|
||||
import google.registry.monitoring.blackbox.exceptions.EppClientException;
|
||||
import google.registry.monitoring.blackbox.exceptions.FailureException;
|
||||
import google.registry.monitoring.blackbox.exceptions.UndeterminedStateException;
|
||||
import google.registry.monitoring.blackbox.messages.EppRequestMessage;
|
||||
import google.registry.monitoring.blackbox.messages.EppResponseMessage;
|
||||
import google.registry.monitoring.blackbox.util.EppUtils;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.embedded.EmbeddedChannel;
|
||||
import java.io.IOException;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameter;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link EppActionHandler} and {@link EppMessageHandler} as well as integration
|
||||
* tests for both of them.
|
||||
*
|
||||
* <p>Attempts to test how well {@link EppActionHandler} works when responding to all possible types
|
||||
* of {@link EppResponseMessage}s with corresponding {@link EppRequestMessage} sent down channel
|
||||
* pipeline.
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class EppActionHandlerTest {
|
||||
|
||||
private static final String USER_ID = "TEST_ID";
|
||||
private static final String USER_PASSWORD = "TEST_PASSWORD";
|
||||
private static final String USER_CLIENT_TRID = "prober-localhost-1234567891011-0";
|
||||
private static final String FAILURE_TRID = "TEST_FAILURE_TRID";
|
||||
private static final String DOMAIN_NAME = "TEST_DOMAIN_NAME.test";
|
||||
private static final String SERVER_ID = "TEST_SERVER_ID";
|
||||
|
||||
@Parameter(0)
|
||||
public EppRequestMessage message;
|
||||
|
||||
private EmbeddedChannel channel;
|
||||
private EppActionHandler actionHandler = new EppActionHandler();
|
||||
private EppMessageHandler messageHandler = new EppMessageHandler(EppUtils.getGreetingResponse());
|
||||
|
||||
// We test all relevant EPP actions
|
||||
@Parameters(name = "{0}")
|
||||
public static EppRequestMessage[] data() {
|
||||
return new EppRequestMessage[] {
|
||||
EppUtils.getHelloMessage(EppUtils.getGreetingResponse()),
|
||||
EppUtils.getLoginMessage(EppUtils.getSuccessResponse(), USER_ID, USER_PASSWORD),
|
||||
EppUtils.getCreateMessage(EppUtils.getSuccessResponse()),
|
||||
EppUtils.getCreateMessage(EppUtils.getFailureResponse()),
|
||||
EppUtils.getDeleteMessage(EppUtils.getSuccessResponse()),
|
||||
EppUtils.getDeleteMessage(EppUtils.getFailureResponse()),
|
||||
EppUtils.getLogoutMessage(EppUtils.getSuccessResponse()),
|
||||
EppUtils.getCheckMessage(EppUtils.getDomainExistsResponse()),
|
||||
EppUtils.getCheckMessage(EppUtils.getDomainNotExistsResponse())
|
||||
};
|
||||
}
|
||||
|
||||
/** Setup main three handlers to be used in pipeline. */
|
||||
@Before
|
||||
public void setup() throws EppClientException {
|
||||
message.modifyMessage(USER_CLIENT_TRID, DOMAIN_NAME);
|
||||
}
|
||||
|
||||
private void setupEmbeddedChannel(ChannelHandler... handlers) {
|
||||
channel = new EmbeddedChannel(handlers);
|
||||
}
|
||||
|
||||
private Document getResponse(EppResponseMessage response, boolean fail, String clTrid)
|
||||
throws IOException, EppClientException {
|
||||
if (response.name().equals("greeting")) {
|
||||
if (fail) {
|
||||
return EppUtils.getBasicResponse(true, clTrid, SERVER_ID);
|
||||
} else {
|
||||
return EppUtils.getGreeting();
|
||||
}
|
||||
} else if (response.name().equals("domainExists")) {
|
||||
return EppUtils.getDomainCheck(!fail, clTrid, SERVER_ID, DOMAIN_NAME);
|
||||
|
||||
} else if (response.name().equals("domainNotExists")) {
|
||||
return EppUtils.getDomainCheck(fail, clTrid, SERVER_ID, DOMAIN_NAME);
|
||||
|
||||
} else if (response.name().equals("success")) {
|
||||
return EppUtils.getBasicResponse(!fail, clTrid, SERVER_ID);
|
||||
|
||||
} else {
|
||||
return EppUtils.getBasicResponse(fail, clTrid, SERVER_ID);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicAction_Success_Embedded()
|
||||
throws SAXException, IOException, EppClientException, FailureException {
|
||||
// We simply use an embedded channel in this instance
|
||||
setupEmbeddedChannel(actionHandler);
|
||||
|
||||
ChannelFuture future = actionHandler.getFinishedFuture();
|
||||
|
||||
EppResponseMessage response = message.getExpectedResponse();
|
||||
|
||||
response.getDocument(
|
||||
EppUtils.docToByteBuf(getResponse(message.getExpectedResponse(), false, USER_CLIENT_TRID)));
|
||||
|
||||
channel.writeInbound(response);
|
||||
|
||||
ChannelFuture unusedFuture = future.syncUninterruptibly();
|
||||
|
||||
assertThat(future.isSuccess()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicAction_FailCode_Embedded()
|
||||
throws SAXException, IOException, EppClientException, FailureException {
|
||||
// We simply use an embedded channel in this instance
|
||||
setupEmbeddedChannel(actionHandler);
|
||||
|
||||
ChannelFuture future = actionHandler.getFinishedFuture();
|
||||
|
||||
EppResponseMessage response = message.getExpectedResponse();
|
||||
|
||||
response.getDocument(
|
||||
EppUtils.docToByteBuf(getResponse(message.getExpectedResponse(), true, USER_CLIENT_TRID)));
|
||||
|
||||
channel.writeInbound(response);
|
||||
|
||||
assertThrows(
|
||||
FailureException.class,
|
||||
() -> {
|
||||
ChannelFuture unusedFuture = future.syncUninterruptibly();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicAction_FailTRID_Embedded()
|
||||
throws SAXException, IOException, EppClientException, FailureException {
|
||||
// We simply use an embedded channel in this instance
|
||||
setupEmbeddedChannel(actionHandler);
|
||||
|
||||
ChannelFuture future = actionHandler.getFinishedFuture();
|
||||
|
||||
EppResponseMessage response = message.getExpectedResponse();
|
||||
|
||||
response.getDocument(
|
||||
EppUtils.docToByteBuf(getResponse(message.getExpectedResponse(), false, FAILURE_TRID)));
|
||||
|
||||
channel.writeInbound(response);
|
||||
|
||||
if (message.getExpectedResponse().name().equals("greeting")) {
|
||||
ChannelFuture unusedFuture = future.syncUninterruptibly();
|
||||
assertThat(future.isSuccess()).isTrue();
|
||||
} else {
|
||||
assertThrows(
|
||||
FailureException.class,
|
||||
() -> {
|
||||
ChannelFuture unusedFuture = future.syncUninterruptibly();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegratedAction_Success_Embedded()
|
||||
throws IOException, SAXException, UndeterminedStateException {
|
||||
// We simply use an embedded channel in this instance
|
||||
setupEmbeddedChannel(messageHandler, actionHandler);
|
||||
|
||||
ChannelFuture future = actionHandler.getFinishedFuture();
|
||||
channel.writeOutbound(message);
|
||||
|
||||
channel.writeInbound(
|
||||
EppUtils.docToByteBuf(getResponse(message.getExpectedResponse(), false, USER_CLIENT_TRID)));
|
||||
|
||||
ChannelFuture unusedFuture = future.syncUninterruptibly();
|
||||
|
||||
assertThat(future.isSuccess()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegratedAction_FailCode_Embedded()
|
||||
throws IOException, SAXException, UndeterminedStateException {
|
||||
// We simply use an embedded channel in this instance
|
||||
setupEmbeddedChannel(messageHandler, actionHandler);
|
||||
|
||||
ChannelFuture future = actionHandler.getFinishedFuture();
|
||||
channel.writeOutbound(message);
|
||||
|
||||
channel.writeInbound(
|
||||
EppUtils.docToByteBuf(getResponse(message.getExpectedResponse(), true, USER_CLIENT_TRID)));
|
||||
|
||||
assertThrows(
|
||||
FailureException.class,
|
||||
() -> {
|
||||
ChannelFuture unusedFuture = future.syncUninterruptibly();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegratedAction_FailTRID_Embedded()
|
||||
throws IOException, SAXException, UndeterminedStateException {
|
||||
// We simply use an embedded channel in this instance
|
||||
setupEmbeddedChannel(messageHandler, actionHandler);
|
||||
|
||||
ChannelFuture future = actionHandler.getFinishedFuture();
|
||||
channel.writeOutbound(message);
|
||||
|
||||
channel.writeInbound(
|
||||
EppUtils.docToByteBuf(getResponse(message.getExpectedResponse(), false, FAILURE_TRID)));
|
||||
|
||||
if (message.getExpectedResponse().name().equals("greeting")) {
|
||||
ChannelFuture unusedFuture = future.syncUninterruptibly();
|
||||
assertThat(future.isSuccess()).isTrue();
|
||||
} else {
|
||||
assertThrows(
|
||||
FailureException.class,
|
||||
() -> {
|
||||
ChannelFuture unusedFuture = future.syncUninterruptibly();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,8 +16,8 @@ package google.registry.monitoring.blackbox.handlers;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.monitoring.blackbox.ProbingAction.REMOTE_ADDRESS_KEY;
|
||||
import static google.registry.monitoring.blackbox.Protocol.PROTOCOL_KEY;
|
||||
import static google.registry.monitoring.blackbox.connection.ProbingAction.REMOTE_ADDRESS_KEY;
|
||||
import static google.registry.monitoring.blackbox.connection.Protocol.PROTOCOL_KEY;
|
||||
import static google.registry.testing.JUnitBackports.assertThrows;
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
@ -25,9 +25,9 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
|||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.truth.ThrowableSubject;
|
||||
import google.registry.monitoring.blackbox.ProbingActionTest;
|
||||
import google.registry.monitoring.blackbox.ProbingStepTest;
|
||||
import google.registry.monitoring.blackbox.Protocol;
|
||||
import google.registry.monitoring.blackbox.connection.ProbingActionTest;
|
||||
import google.registry.monitoring.blackbox.connection.Protocol;
|
||||
import google.registry.monitoring.blackbox.testservers.TestServer;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
@ -51,18 +51,18 @@ import org.junit.rules.ExternalResource;
|
|||
/**
|
||||
* Helper for setting up and testing client / server connection with netty.
|
||||
*
|
||||
* <p>Code based on and almost identical to {@code NettyRule} in the proxy.
|
||||
* Used in {@link SslClientInitializerTest}, {@link ProbingActionTest}, and {@link ProbingStepTest}
|
||||
* </p>
|
||||
* <p>Code based on and almost identical to {@code NettyRule} in the proxy. Used in {@link
|
||||
* SslClientInitializerTest}, {@link ProbingActionTest}, and {@link ProbingStepTest}
|
||||
*/
|
||||
public final class NettyRule extends ExternalResource {
|
||||
|
||||
|
||||
private final EventLoopGroup eventLoopGroup;
|
||||
|
||||
// Handler attached to server's channel to record the request received.
|
||||
private EchoHandler echoHandler;
|
||||
// Handler attached to client's channel to record the response received.
|
||||
private DumpHandler dumpHandler;
|
||||
|
||||
private Channel channel;
|
||||
|
||||
// All I/O operations are done inside the single thread within this event loop group, which is
|
||||
|
@ -81,25 +81,20 @@ public final class NettyRule extends ExternalResource {
|
|||
channel.writeAndFlush(Unpooled.wrappedBuffer(data.getBytes(US_ASCII)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a server channel bound to the given local address.
|
||||
*/
|
||||
/** Sets up a server channel bound to the given local address. */
|
||||
public void setUpServer(LocalAddress localAddress, ChannelHandler... handlers) {
|
||||
checkState(echoHandler == null, "Can't call setUpServer twice");
|
||||
echoHandler = new EchoHandler();
|
||||
|
||||
new TestServer(eventLoopGroup, localAddress,
|
||||
new TestServer(
|
||||
eventLoopGroup,
|
||||
localAddress,
|
||||
ImmutableList.<ChannelHandler>builder().add(handlers).add(echoHandler).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a client channel connecting to the give local address.
|
||||
*/
|
||||
/** Sets up a client channel connecting to the give local address. */
|
||||
void setUpClient(
|
||||
LocalAddress localAddress,
|
||||
Protocol protocol,
|
||||
String host,
|
||||
ChannelHandler handler) {
|
||||
LocalAddress localAddress, Protocol protocol, String host, ChannelHandler handler) {
|
||||
checkState(echoHandler != null, "Must call setUpServer before setUpClient");
|
||||
checkState(dumpHandler == null, "Can't call setUpClient twice");
|
||||
dumpHandler = new DumpHandler();
|
||||
|
@ -128,20 +123,17 @@ public final class NettyRule extends ExternalResource {
|
|||
checkState(channel != null, "Must call setUpClient to finish NettyRule setup");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that custom setup to send message to current server sends right message
|
||||
*/
|
||||
/** Test that custom setup to send message to current server sends right message */
|
||||
public void assertReceivedMessage(String message) throws Exception {
|
||||
assertThat(echoHandler.getRequestFuture().get()).isEqualTo(message);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a message can go through, both inbound and outbound.
|
||||
*
|
||||
* <p>The client writes the message to the server, which echos it back and saves the string in
|
||||
* its promise. The client receives the echo and saves it in its promise. All these activities
|
||||
* happens in the I/O thread, and this call itself returns immediately.
|
||||
* <p>The client writes the message to the server, which echos it back and saves the string in its
|
||||
* promise. The client receives the echo and saves it in its promise. All these activities happens
|
||||
* in the I/O thread, and this call itself returns immediately.
|
||||
*/
|
||||
void assertThatMessagesWork() throws Exception {
|
||||
checkReady();
|
||||
|
@ -199,9 +191,7 @@ public final class NettyRule extends ExternalResource {
|
|||
ctx.writeAndFlush(msg).addListener(f -> requestFuture.complete(request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves any inbound error as the cause of the promise failure.
|
||||
*/
|
||||
/** Saves any inbound error as the cause of the promise failure. */
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
ChannelFuture unusedFuture =
|
||||
|
@ -209,9 +199,7 @@ public final class NettyRule extends ExternalResource {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A handler that dumps its inbound message to a promise that can be inspected later.
|
||||
*/
|
||||
/** A handler that dumps its inbound message to a promise that can be inspected later. */
|
||||
private static class DumpHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
private final CompletableFuture<String> responseFuture = new CompletableFuture<>();
|
||||
|
@ -232,13 +220,10 @@ public final class NettyRule extends ExternalResource {
|
|||
responseFuture.complete(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves any inbound error into the failure cause of the promise.
|
||||
*/
|
||||
/** Saves any inbound error into the failure cause of the promise. */
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
ctx.channel().closeFuture().addListener(f -> responseFuture.completeExceptionally(cause));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
package google.registry.monitoring.blackbox.handlers;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.monitoring.blackbox.ProbingAction.REMOTE_ADDRESS_KEY;
|
||||
import static google.registry.monitoring.blackbox.Protocol.PROTOCOL_KEY;
|
||||
import static google.registry.monitoring.blackbox.connection.ProbingAction.REMOTE_ADDRESS_KEY;
|
||||
import static google.registry.monitoring.blackbox.connection.Protocol.PROTOCOL_KEY;
|
||||
import static google.registry.monitoring.blackbox.handlers.SslInitializerTestUtils.getKeyPair;
|
||||
import static google.registry.monitoring.blackbox.handlers.SslInitializerTestUtils.setUpSslChannel;
|
||||
import static google.registry.monitoring.blackbox.handlers.SslInitializerTestUtils.signKeyPair;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.monitoring.blackbox.Protocol;
|
||||
import google.registry.monitoring.blackbox.connection.Protocol;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.embedded.EmbeddedChannel;
|
||||
|
@ -62,39 +62,33 @@ import org.junit.runners.Parameterized.Parameters;
|
|||
@RunWith(Parameterized.class)
|
||||
public class SslClientInitializerTest {
|
||||
|
||||
/**
|
||||
* Fake host to test if the SSL engine gets the correct peer host.
|
||||
*/
|
||||
/** Fake host to test if the SSL engine gets the correct peer host. */
|
||||
private static final String SSL_HOST = "www.example.tld";
|
||||
|
||||
/**
|
||||
* Fake port to test if the SSL engine gets the correct peer port.
|
||||
*/
|
||||
/** Fake port to test if the SSL engine gets the correct peer port. */
|
||||
private static final int SSL_PORT = 12345;
|
||||
/**
|
||||
* Fake protocol saved in channel attribute.
|
||||
*/
|
||||
private static final Protocol PROTOCOL = Protocol.builder()
|
||||
.setName("ssl")
|
||||
.setPort(SSL_PORT)
|
||||
.setHandlerProviders(ImmutableList.of())
|
||||
.setPersistentConnection(false)
|
||||
.build();
|
||||
@Rule
|
||||
public NettyRule nettyRule = new NettyRule();
|
||||
/** Fake protocol saved in channel attribute. */
|
||||
private static final Protocol PROTOCOL =
|
||||
Protocol.builder()
|
||||
.setName("ssl")
|
||||
.setPort(SSL_PORT)
|
||||
.setHandlerProviders(ImmutableList.of())
|
||||
.setPersistentConnection(false)
|
||||
.build();
|
||||
|
||||
@Rule public NettyRule nettyRule = new NettyRule();
|
||||
|
||||
@Parameter(0)
|
||||
public SslProvider sslProvider;
|
||||
/**
|
||||
* Saves the SNI hostname received by the server, if sent by the client.
|
||||
*/
|
||||
/** Saves the SNI hostname received by the server, if sent by the client. */
|
||||
private String sniHostReceived;
|
||||
|
||||
// We do our best effort to test all available SSL providers.
|
||||
@Parameters(name = "{0}")
|
||||
public static SslProvider[] data() {
|
||||
return OpenSsl.isAvailable()
|
||||
? new SslProvider[]{SslProvider.JDK, SslProvider.OPENSSL}
|
||||
: new SslProvider[]{SslProvider.JDK};
|
||||
? new SslProvider[] {SslProvider.JDK, SslProvider.OPENSSL}
|
||||
: new SslProvider[] {SslProvider.JDK};
|
||||
}
|
||||
|
||||
private ChannelHandler getServerHandler(PrivateKey privateKey, X509Certificate certificate)
|
||||
|
@ -170,7 +164,7 @@ public class SslClientInitializerTest {
|
|||
|
||||
// Set up the client to trust the self signed cert used to sign the cert that server provides.
|
||||
SslClientInitializer<LocalChannel> sslClientInitializer =
|
||||
new SslClientInitializer<>(sslProvider, new X509Certificate[]{ssc.cert()});
|
||||
new SslClientInitializer<>(sslProvider, new X509Certificate[] {ssc.cert()});
|
||||
|
||||
nettyRule.setUpClient(localAddress, PROTOCOL, SSL_HOST, sslClientInitializer);
|
||||
|
||||
|
@ -199,7 +193,7 @@ public class SslClientInitializerTest {
|
|||
|
||||
// Set up the client to trust the self signed cert used to sign the cert that server provides.
|
||||
SslClientInitializer<LocalChannel> sslClientInitializer =
|
||||
new SslClientInitializer<>(sslProvider, new X509Certificate[]{ssc.cert()});
|
||||
new SslClientInitializer<>(sslProvider, new X509Certificate[] {ssc.cert()});
|
||||
|
||||
nettyRule.setUpClient(localAddress, PROTOCOL, SSL_HOST, sslClientInitializer);
|
||||
|
||||
|
@ -211,4 +205,3 @@ public class SslClientInitializerTest {
|
|||
assertThat(nettyRule.getChannel().isActive()).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,9 +33,7 @@ import javax.security.auth.x500.X500Principal;
|
|||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.x509.X509V3CertificateGenerator;
|
||||
|
||||
/**
|
||||
* Utility class that provides methods used by {@link SslClientInitializerTest}
|
||||
*/
|
||||
/** Utility class that provides methods used by {@link SslClientInitializerTest} */
|
||||
public class SslInitializerTestUtils {
|
||||
|
||||
static {
|
||||
|
@ -74,10 +72,7 @@ public class SslInitializerTestUtils {
|
|||
* @param certs The certificate that the server should provide.
|
||||
* @return The SSL session in current channel, can be used for further validation.
|
||||
*/
|
||||
static SSLSession setUpSslChannel(
|
||||
Channel channel,
|
||||
X509Certificate... certs)
|
||||
throws Exception {
|
||||
static SSLSession setUpSslChannel(Channel channel, X509Certificate... certs) throws Exception {
|
||||
SslHandler sslHandler = channel.pipeline().get(SslHandler.class);
|
||||
// Wait till the handshake is complete.
|
||||
sslHandler.handshakeFuture().get();
|
||||
|
@ -92,4 +87,3 @@ public class SslInitializerTestUtils {
|
|||
return sslHandler.engine().getSession();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,4 @@ public class TestActionHandler extends ActionHandler {
|
|||
public InboundMessageType getResponse() {
|
||||
return receivedMessage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
package google.registry.monitoring.blackbox.handlers;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.monitoring.blackbox.ProbingAction.CONNECTION_FUTURE_KEY;
|
||||
import static google.registry.monitoring.blackbox.Protocol.PROTOCOL_KEY;
|
||||
import static google.registry.monitoring.blackbox.TestUtils.makeHttpGetRequest;
|
||||
import static google.registry.monitoring.blackbox.TestUtils.makeHttpResponse;
|
||||
import static google.registry.monitoring.blackbox.TestUtils.makeRedirectResponse;
|
||||
import static google.registry.monitoring.blackbox.connection.ProbingAction.CONNECTION_FUTURE_KEY;
|
||||
import static google.registry.monitoring.blackbox.connection.Protocol.PROTOCOL_KEY;
|
||||
import static google.registry.monitoring.blackbox.util.WebWhoisUtils.makeHttpGetRequest;
|
||||
import static google.registry.monitoring.blackbox.util.WebWhoisUtils.makeHttpResponse;
|
||||
import static google.registry.monitoring.blackbox.util.WebWhoisUtils.makeRedirectResponse;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.monitoring.blackbox.Protocol;
|
||||
import google.registry.monitoring.blackbox.connection.Protocol;
|
||||
import google.registry.monitoring.blackbox.exceptions.FailureException;
|
||||
import google.registry.monitoring.blackbox.messages.HttpRequestMessage;
|
||||
import google.registry.monitoring.blackbox.messages.HttpResponseMessage;
|
||||
|
@ -45,8 +45,8 @@ import org.junit.runners.JUnit4;
|
|||
/**
|
||||
* Unit tests for {@link WebWhoisActionHandler}.
|
||||
*
|
||||
* <p>Attempts to test how well {@link WebWhoisActionHandler} works
|
||||
* when responding to all possible types of responses </p>
|
||||
* <p>Attempts to test how well {@link WebWhoisActionHandler} works when responding to all possible
|
||||
* types of responses
|
||||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
public class WebWhoisActionHandlerTest {
|
||||
|
@ -55,14 +55,14 @@ public class WebWhoisActionHandlerTest {
|
|||
private static final String HTTP_REDIRECT = "http://";
|
||||
private static final String TARGET_HOST = "whois.nic.tld";
|
||||
private static final String DUMMY_URL = "__WILL_NOT_WORK__";
|
||||
private final Protocol standardProtocol = Protocol.builder()
|
||||
.setHandlerProviders(ImmutableList.of(() -> new WebWhoisActionHandler(
|
||||
null, null, null, null)))
|
||||
.setName("http")
|
||||
.setPersistentConnection(false)
|
||||
.setPort(HTTP_PORT)
|
||||
.build();
|
||||
|
||||
private final Protocol standardProtocol =
|
||||
Protocol.builder()
|
||||
.setHandlerProviders(
|
||||
ImmutableList.of(() -> new WebWhoisActionHandler(null, null, null, null)))
|
||||
.setName("http")
|
||||
.setPersistentConnection(false)
|
||||
.setPort(HTTP_PORT)
|
||||
.build();
|
||||
|
||||
private EmbeddedChannel channel;
|
||||
private ActionHandler actionHandler;
|
||||
|
@ -70,10 +70,7 @@ public class WebWhoisActionHandlerTest {
|
|||
private Protocol initialProtocol;
|
||||
private HttpRequestMessage msg;
|
||||
|
||||
|
||||
/**
|
||||
* Creates default protocol with empty list of handlers and specified other inputs
|
||||
*/
|
||||
/** Creates default protocol with empty list of handlers and specified other inputs */
|
||||
private Protocol createProtocol(String name, int port, boolean persistentConnection) {
|
||||
return Protocol.builder()
|
||||
.setName(name)
|
||||
|
@ -83,22 +80,14 @@ public class WebWhoisActionHandlerTest {
|
|||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes new WebWhoisActionHandler
|
||||
*/
|
||||
/** Initializes new WebWhoisActionHandler */
|
||||
private void setupActionHandler(Bootstrap bootstrap, HttpRequestMessage messageTemplate) {
|
||||
actionHandler = new WebWhoisActionHandler(
|
||||
bootstrap,
|
||||
standardProtocol,
|
||||
standardProtocol,
|
||||
messageTemplate
|
||||
);
|
||||
actionHandler =
|
||||
new WebWhoisActionHandler(bootstrap, standardProtocol, standardProtocol, messageTemplate);
|
||||
actionHandlerProvider = () -> actionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up testing channel with requisite attributes
|
||||
*/
|
||||
/** Sets up testing channel with requisite attributes */
|
||||
private void setupChannel(Protocol protocol) {
|
||||
channel = new EmbeddedChannel(actionHandler);
|
||||
channel.attr(PROTOCOL_KEY).set(protocol);
|
||||
|
@ -106,43 +95,39 @@ public class WebWhoisActionHandlerTest {
|
|||
}
|
||||
|
||||
private Bootstrap makeBootstrap(EventLoopGroup group) {
|
||||
return new Bootstrap()
|
||||
.group(group)
|
||||
.channel(LocalChannel.class);
|
||||
return new Bootstrap().group(group).channel(LocalChannel.class);
|
||||
}
|
||||
|
||||
|
||||
private void setup(String hostName, Bootstrap bootstrap, boolean persistentConnection) {
|
||||
msg = new HttpRequestMessage(makeHttpGetRequest(hostName, ""));
|
||||
setupActionHandler(bootstrap, msg);
|
||||
initialProtocol = createProtocol("testProtocol", 0, persistentConnection);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasic_responseOk() {
|
||||
//setup
|
||||
// setup
|
||||
setup("", null, true);
|
||||
setupChannel(initialProtocol);
|
||||
|
||||
//stores future
|
||||
// stores future
|
||||
ChannelFuture future = actionHandler.getFinishedFuture();
|
||||
channel.writeOutbound(msg);
|
||||
|
||||
FullHttpResponse response = new HttpResponseMessage(makeHttpResponse(HttpResponseStatus.OK));
|
||||
|
||||
//assesses that future listener isn't triggered yet.
|
||||
// assesses that future listener isn't triggered yet.
|
||||
assertThat(future.isDone()).isFalse();
|
||||
|
||||
channel.writeInbound(response);
|
||||
|
||||
//assesses that we successfully received good response and protocol is unchanged
|
||||
// assesses that we successfully received good response and protocol is unchanged
|
||||
assertThat(future.isSuccess()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasic_responseFailure_badRequest() {
|
||||
//setup
|
||||
// setup
|
||||
setup("", null, false);
|
||||
setupChannel(initialProtocol);
|
||||
|
||||
|
@ -150,8 +135,8 @@ public class WebWhoisActionHandlerTest {
|
|||
ChannelFuture future = actionHandler.getFinishedFuture();
|
||||
channel.writeOutbound(msg);
|
||||
|
||||
FullHttpResponse response = new HttpResponseMessage(
|
||||
makeHttpResponse(HttpResponseStatus.BAD_REQUEST));
|
||||
FullHttpResponse response =
|
||||
new HttpResponseMessage(makeHttpResponse(HttpResponseStatus.BAD_REQUEST));
|
||||
|
||||
// Assesses that future listener isn't triggered yet.
|
||||
assertThat(future.isDone()).isFalse();
|
||||
|
@ -168,23 +153,24 @@ public class WebWhoisActionHandlerTest {
|
|||
|
||||
@Test
|
||||
public void testBasic_responseFailure_badURL() {
|
||||
//setup
|
||||
// setup
|
||||
setup("", null, false);
|
||||
setupChannel(initialProtocol);
|
||||
|
||||
//stores future
|
||||
// stores future
|
||||
ChannelFuture future = actionHandler.getFinishedFuture();
|
||||
channel.writeOutbound(msg);
|
||||
|
||||
FullHttpResponse response = new HttpResponseMessage(
|
||||
makeRedirectResponse(HttpResponseStatus.MOVED_PERMANENTLY, DUMMY_URL, true));
|
||||
FullHttpResponse response =
|
||||
new HttpResponseMessage(
|
||||
makeRedirectResponse(HttpResponseStatus.MOVED_PERMANENTLY, DUMMY_URL, true));
|
||||
|
||||
//assesses that future listener isn't triggered yet.
|
||||
// assesses that future listener isn't triggered yet.
|
||||
assertThat(future.isDone()).isFalse();
|
||||
|
||||
channel.writeInbound(response);
|
||||
|
||||
//assesses that listener is triggered, and event is success
|
||||
// assesses that listener is triggered, and event is success
|
||||
assertThat(future.isDone()).isTrue();
|
||||
assertThat(future.isSuccess()).isFalse();
|
||||
|
||||
|
@ -204,7 +190,7 @@ public class WebWhoisActionHandlerTest {
|
|||
// Initializes LocalAddress with unique String.
|
||||
LocalAddress address = new LocalAddress(TARGET_HOST);
|
||||
|
||||
//stores future
|
||||
// stores future
|
||||
ChannelFuture future = actionHandler.getFinishedFuture();
|
||||
channel.writeOutbound(msg);
|
||||
|
||||
|
@ -215,18 +201,19 @@ public class WebWhoisActionHandlerTest {
|
|||
TestServer.webWhoisServer(group, address, "", TARGET_HOST, path);
|
||||
|
||||
FullHttpResponse response =
|
||||
new HttpResponseMessage(makeRedirectResponse(HttpResponseStatus.MOVED_PERMANENTLY,
|
||||
HTTP_REDIRECT + TARGET_HOST + path, true));
|
||||
new HttpResponseMessage(
|
||||
makeRedirectResponse(
|
||||
HttpResponseStatus.MOVED_PERMANENTLY, HTTP_REDIRECT + TARGET_HOST + path, true));
|
||||
|
||||
//checks that future has not been set to successful or a failure
|
||||
// checks that future has not been set to successful or a failure
|
||||
assertThat(future.isDone()).isFalse();
|
||||
|
||||
channel.writeInbound(response);
|
||||
|
||||
//makes sure old channel is shut down when attempting redirection
|
||||
// makes sure old channel is shut down when attempting redirection
|
||||
assertThat(channel.isActive()).isFalse();
|
||||
|
||||
//assesses that we successfully received good response and protocol is unchanged
|
||||
// assesses that we successfully received good response and protocol is unchanged
|
||||
assertThat(future.syncUninterruptibly().isSuccess()).isTrue();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License
|
||||
|
||||
package google.registry.monitoring.blackbox.messages;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.JUnitBackports.assertThrows;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import google.registry.monitoring.blackbox.exceptions.EppClientException;
|
||||
import google.registry.monitoring.blackbox.exceptions.FailureException;
|
||||
import google.registry.monitoring.blackbox.util.EppUtils;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class EppMessageTest {
|
||||
|
||||
private Document xmlDoc = null;
|
||||
private Document greeting = null;
|
||||
private DocumentBuilder builder = null;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
String xmlString =
|
||||
"<epp>"
|
||||
+ "<textAndAttr myAttr1='1'>text1</textAndAttr>"
|
||||
+ "<textNoAttr>text2</textNoAttr>"
|
||||
+ "<attrNoText myAttr2='2'/>"
|
||||
+ "<textAndAttrSplitRepeated>text3</textAndAttrSplitRepeated>"
|
||||
+ "<textAndAttrSplitRepeated myAttr3='3'/>"
|
||||
+ "</epp>";
|
||||
ByteArrayInputStream byteStream = new ByteArrayInputStream(xmlString.getBytes(UTF_8));
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
builder = factory.newDocumentBuilder();
|
||||
xmlDoc = builder.parse(byteStream);
|
||||
|
||||
greeting = EppUtils.getGreeting();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void xmlDocToStringSuccess() throws Exception {
|
||||
Document xml = builder.newDocument();
|
||||
Element doc = xml.createElement("doc");
|
||||
Element title = xml.createElement("title");
|
||||
title.setTextContent("test");
|
||||
Element meta = xml.createElement("meta");
|
||||
meta.setAttribute("version", "1.0");
|
||||
doc.appendChild(title);
|
||||
doc.appendChild(meta);
|
||||
xml.appendChild(doc);
|
||||
|
||||
// note that setting the version just ensures this will either be the same in the result,
|
||||
// or the result won't support the version and this will throw an exception.
|
||||
xml.setXmlVersion("1.0");
|
||||
// setting stand alone to true removes this from the processing instructions
|
||||
xml.setXmlStandalone(true);
|
||||
String expected =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
||||
+ "<doc><title>test</title><meta version=\"1.0\"/></doc>";
|
||||
String actual = EppMessage.xmlDocToString(xml);
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void xmlDoctoByteArraySuccess() throws Exception {
|
||||
Document xml = builder.newDocument();
|
||||
Element doc = xml.createElement("doc");
|
||||
Element title = xml.createElement("title");
|
||||
title.setTextContent("test");
|
||||
Element meta = xml.createElement("meta");
|
||||
meta.setAttribute("version", "1.0");
|
||||
doc.appendChild(title);
|
||||
doc.appendChild(meta);
|
||||
xml.appendChild(doc);
|
||||
|
||||
// note that setting the version just ensures this will either be the same in the result,
|
||||
// or the result won't support the version and this will throw an exception.
|
||||
xml.setXmlVersion("1.0");
|
||||
// setting stand alone to true removes this from the processing instructions
|
||||
xml.setXmlStandalone(true);
|
||||
String expected =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
||||
+ "<doc><title>test</title><meta version=\"1.0\"/></doc>";
|
||||
byte[] actual = EppMessage.xmlDocToByteArray(xml);
|
||||
assertThat(actual).isEqualTo(expected.getBytes(UTF_8));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void eppValidateSuccess() throws Exception {
|
||||
EppMessage.eppValidate(greeting);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void eppValidateFail() {
|
||||
assertThrows(SAXException.class, () -> EppMessage.eppValidate(xmlDoc));
|
||||
}
|
||||
|
||||
/**
|
||||
* These test a "success" without validating a document. This is to make it easier to test the
|
||||
* XPath part of the verify in isolation. See EppClientConnectionTest for tests that verify an
|
||||
* actual (greeting) respoonse.
|
||||
*/
|
||||
@Test
|
||||
public void verifyResponseSuccess() throws Exception {
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
list.add("epp");
|
||||
list.add("//textAndAttr[@myAttr1='1'] | //textAndAttr[child::text()='text1']");
|
||||
list.add("//textAndAttr[child::text()='text1']");
|
||||
list.add("//textAndAttr/@myAttr1");
|
||||
list.add("//textAndAttrSplitRepeated[@myAttr3='3']");
|
||||
|
||||
EppMessage.verifyEppResponse(xmlDoc, list, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyEppResponseSuccess() throws Exception {
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
list.add("*");
|
||||
list.add("/eppns:epp");
|
||||
list.add("/eppns:epp/eppns:greeting");
|
||||
list.add("//eppns:greeting");
|
||||
list.add("//eppns:svID");
|
||||
|
||||
EppMessage.verifyEppResponse(greeting, list, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyResponseMissingTextFail() {
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
list.add("epp");
|
||||
list.add("//textAndAttr[child::text()='text2']");
|
||||
|
||||
assertThrows(FailureException.class, () -> EppMessage.verifyEppResponse(xmlDoc, list, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyResponseMissingAttrFail() {
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
list.add("epp");
|
||||
list.add("//textAndAttr/@myAttr2");
|
||||
|
||||
assertThrows(FailureException.class, () -> EppMessage.verifyEppResponse(xmlDoc, list, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyResponseSplitTextAttrFail() {
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
list.add("epp");
|
||||
list.add("//textAndAttrSplitRepeated[@myAttr3='3'][child::text()='text3']");
|
||||
|
||||
assertThrows(FailureException.class, () -> EppMessage.verifyEppResponse(xmlDoc, list, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEppDocFromTemplateTest() throws Exception {
|
||||
Map<String, String> replaceMap = new HashMap<>();
|
||||
replaceMap.put("//eppns:expectedClTRID", "ABC-1234-CBA");
|
||||
replaceMap.put("//domainns:name", "foo");
|
||||
replaceMap.put("//domainns:pw", "bar");
|
||||
Document epp = EppMessage.getEppDocFromTemplate("create.xml", replaceMap);
|
||||
List<String> noList = Collections.emptyList();
|
||||
EppMessage.verifyEppResponse(epp, noList, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEppDocFromTemplateTestFail() {
|
||||
Map<String, String> replaceMap = new HashMap<>();
|
||||
replaceMap.put("//eppns:create", "ABC-1234-CBA");
|
||||
replaceMap.put("//domainns:name", "foo");
|
||||
replaceMap.put("//domainns:pw", "bar");
|
||||
assertThrows(
|
||||
EppClientException.class, () -> EppMessage.getEppDocFromTemplate("create.xml", replaceMap));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkValidDomainName() {
|
||||
String domainName = "good.tld";
|
||||
assertThat(domainName.matches(EppMessage.VALID_SLD_LABEL_REGEX)).isTrue();
|
||||
domainName = "good.tld.";
|
||||
assertThat(domainName.matches(EppMessage.VALID_SLD_LABEL_REGEX)).isTrue();
|
||||
domainName = "g-o-o-d.tld.";
|
||||
assertThat(domainName.matches(EppMessage.VALID_SLD_LABEL_REGEX)).isTrue();
|
||||
domainName = "good.cc.tld";
|
||||
assertThat(domainName.matches(EppMessage.VALID_SLD_LABEL_REGEX)).isTrue();
|
||||
domainName = "good.cc.tld.";
|
||||
assertThat(domainName.matches(EppMessage.VALID_SLD_LABEL_REGEX)).isTrue();
|
||||
domainName = "too-short";
|
||||
assertThat(domainName.matches(EppMessage.VALID_SLD_LABEL_REGEX)).isFalse();
|
||||
domainName = "too-short.";
|
||||
assertThat(domainName.matches(EppMessage.VALID_SLD_LABEL_REGEX)).isFalse();
|
||||
// TODO(rgr): sync up how many dots is actually too many
|
||||
domainName = "too.many.dots.tld.";
|
||||
assertThat(domainName.matches(EppMessage.VALID_SLD_LABEL_REGEX)).isFalse();
|
||||
domainName = "too.many.dots.tld";
|
||||
assertThat(domainName.matches(EppMessage.VALID_SLD_LABEL_REGEX)).isFalse();
|
||||
}
|
||||
}
|
|
@ -14,17 +14,22 @@
|
|||
|
||||
package google.registry.monitoring.blackbox.testservers;
|
||||
|
||||
import static google.registry.monitoring.blackbox.TestUtils.makeHttpResponse;
|
||||
import static google.registry.monitoring.blackbox.TestUtils.makeRedirectResponse;
|
||||
import static google.registry.monitoring.blackbox.util.WebWhoisUtils.makeHttpResponse;
|
||||
import static google.registry.monitoring.blackbox.util.WebWhoisUtils.makeRedirectResponse;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.monitoring.blackbox.exceptions.FailureException;
|
||||
import google.registry.monitoring.blackbox.messages.EppMessage;
|
||||
import google.registry.monitoring.blackbox.messages.HttpResponseMessage;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandler.Sharable;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.channel.local.LocalAddress;
|
||||
|
@ -34,6 +39,7 @@ import io.netty.channel.nio.NioEventLoopGroup;
|
|||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
/**
|
||||
* Mock Server Superclass whose subclasses implement specific behaviors we expect blackbox server to
|
||||
|
@ -45,18 +51,21 @@ public class TestServer {
|
|||
this(new NioEventLoopGroup(1), localAddress, handlers);
|
||||
}
|
||||
|
||||
public TestServer(EventLoopGroup eventLoopGroup, LocalAddress localAddress,
|
||||
public TestServer(
|
||||
EventLoopGroup eventLoopGroup,
|
||||
LocalAddress localAddress,
|
||||
ImmutableList<? extends ChannelHandler> handlers) {
|
||||
//Creates ChannelInitializer with handlers specified
|
||||
ChannelInitializer<LocalChannel> serverInitializer = new ChannelInitializer<LocalChannel>() {
|
||||
@Override
|
||||
protected void initChannel(LocalChannel ch) {
|
||||
for (ChannelHandler handler : handlers) {
|
||||
ch.pipeline().addLast(handler);
|
||||
}
|
||||
}
|
||||
};
|
||||
//Sets up serverBootstrap with specified initializer, eventLoopGroup, and using
|
||||
// Creates ChannelInitializer with handlers specified
|
||||
ChannelInitializer<LocalChannel> serverInitializer =
|
||||
new ChannelInitializer<LocalChannel>() {
|
||||
@Override
|
||||
protected void initChannel(LocalChannel ch) {
|
||||
for (ChannelHandler handler : handlers) {
|
||||
ch.pipeline().addLast(handler);
|
||||
}
|
||||
}
|
||||
};
|
||||
// Sets up serverBootstrap with specified initializer, eventLoopGroup, and using
|
||||
// LocalServerChannel class
|
||||
ServerBootstrap serverBootstrap =
|
||||
new ServerBootstrap()
|
||||
|
@ -65,22 +74,27 @@ public class TestServer {
|
|||
.childHandler(serverInitializer);
|
||||
|
||||
ChannelFuture unusedFuture = serverBootstrap.bind(localAddress).syncUninterruptibly();
|
||||
|
||||
}
|
||||
|
||||
public static TestServer webWhoisServer(EventLoopGroup eventLoopGroup,
|
||||
LocalAddress localAddress, String redirectInput, String destinationInput,
|
||||
public static TestServer webWhoisServer(
|
||||
EventLoopGroup eventLoopGroup,
|
||||
LocalAddress localAddress,
|
||||
String redirectInput,
|
||||
String destinationInput,
|
||||
String destinationPath) {
|
||||
return new TestServer(
|
||||
eventLoopGroup,
|
||||
localAddress,
|
||||
ImmutableList.of(new RedirectHandler(redirectInput, destinationInput, destinationPath))
|
||||
);
|
||||
ImmutableList.of(new RedirectHandler(redirectInput, destinationInput, destinationPath)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler that will wither redirect client, give successful response, or give error messge
|
||||
*/
|
||||
public static TestServer eppServer(EventLoopGroup eventLoopGroup, LocalAddress localAddress) {
|
||||
// TODO - add LengthFieldBasedFrameDecoder to handlers in pipeline if necessary for future
|
||||
// tests.
|
||||
return new TestServer(eventLoopGroup, localAddress, ImmutableList.of(new EppHandler()));
|
||||
}
|
||||
|
||||
/** Handler that will wither redirect client, give successful response, or give error messge */
|
||||
@Sharable
|
||||
static class RedirectHandler extends SimpleChannelInboundHandler<HttpRequest> {
|
||||
|
||||
|
@ -90,9 +104,9 @@ public class TestServer {
|
|||
|
||||
/**
|
||||
* @param redirectInput - Server will send back redirect to {@code destinationInput} when
|
||||
* receiving a request with this host location
|
||||
* receiving a request with this host location
|
||||
* @param destinationInput - Server will send back an {@link HttpResponseStatus} OK response
|
||||
* when receiving a request with this host location
|
||||
* when receiving a request with this host location
|
||||
*/
|
||||
public RedirectHandler(String redirectInput, String destinationInput, String destinationPath) {
|
||||
this.redirectInput = redirectInput;
|
||||
|
@ -108,8 +122,9 @@ public class TestServer {
|
|||
public void channelRead0(ChannelHandlerContext ctx, HttpRequest request) {
|
||||
HttpResponse response;
|
||||
if (request.headers().get("host").equals(redirectInput)) {
|
||||
response = new HttpResponseMessage(
|
||||
makeRedirectResponse(HttpResponseStatus.MOVED_PERMANENTLY, destinationInput, true));
|
||||
response =
|
||||
new HttpResponseMessage(
|
||||
makeRedirectResponse(HttpResponseStatus.MOVED_PERMANENTLY, destinationInput, true));
|
||||
} else if (request.headers().get("host").equals(destinationInput)
|
||||
&& request.uri().equals(destinationPath)) {
|
||||
response = new HttpResponseMessage(makeHttpResponse(HttpResponseStatus.OK));
|
||||
|
@ -117,7 +132,36 @@ public class TestServer {
|
|||
response = new HttpResponseMessage(makeHttpResponse(HttpResponseStatus.BAD_REQUEST));
|
||||
}
|
||||
ChannelFuture unusedFuture = ctx.channel().writeAndFlush(response);
|
||||
}
|
||||
}
|
||||
|
||||
private static class EppHandler extends ChannelDuplexHandler {
|
||||
|
||||
Document doc;
|
||||
private ChannelPromise future;
|
||||
|
||||
@Override
|
||||
public void handlerAdded(ChannelHandlerContext ctx) {
|
||||
// TODO - pass EppMessage into future to easily read attributes of message.
|
||||
future = ctx.newPromise();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||
ByteBuf buf = (ByteBuf) msg;
|
||||
|
||||
byte[] messageBytes = new byte[buf.readableBytes()];
|
||||
buf.readBytes(messageBytes);
|
||||
|
||||
// TODO - Break ByteBuf into multiple pieces to test how well it works with
|
||||
// LengthFieldBasedFrameDecoder.
|
||||
|
||||
try {
|
||||
doc = EppMessage.byteArrayToXmlDoc(messageBytes);
|
||||
ChannelFuture unusedFuture = future.setSuccess();
|
||||
} catch (FailureException e) {
|
||||
ChannelFuture unusedFuture = future.setFailure(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.monitoring.blackbox.tokens;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import google.registry.monitoring.blackbox.exceptions.UndeterminedStateException;
|
||||
import google.registry.monitoring.blackbox.messages.EppRequestMessage;
|
||||
import google.registry.monitoring.blackbox.util.EppUtils;
|
||||
import io.netty.channel.Channel;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
/** Unit Tests for each {@link Token} subtype (just {@link WebWhoisToken} for now) */
|
||||
@RunWith(JUnit4.class)
|
||||
public class EppTokenTest {
|
||||
|
||||
private static String TEST_HOST = "host";
|
||||
private static String TEST_TLD = "tld";
|
||||
|
||||
private EppToken persistentEppToken = new EppToken.Persistent(TEST_TLD, TEST_HOST);
|
||||
private EppToken transientEppToken = new EppToken.Transient(TEST_TLD, TEST_HOST);
|
||||
|
||||
@Test
|
||||
public void testMessageModificationSuccess_PersistentToken() throws UndeterminedStateException {
|
||||
|
||||
EppRequestMessage originalMessage = EppUtils.getCreateMessage(EppUtils.getSuccessResponse());
|
||||
String domainName = persistentEppToken.getCurrentDomainName();
|
||||
String clTrid = domainName.substring(0, domainName.indexOf('.'));
|
||||
|
||||
EppRequestMessage modifiedMessage =
|
||||
(EppRequestMessage) persistentEppToken.modifyMessage(originalMessage);
|
||||
|
||||
// ensure element values are what they should be
|
||||
assertThat(modifiedMessage.getElementValue("//domainns:name")).isEqualTo(domainName);
|
||||
assertThat(modifiedMessage.getElementValue("//eppns:clTRID")).isNotEqualTo(clTrid);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageModificationSuccess_TransientToken() throws UndeterminedStateException {
|
||||
|
||||
EppRequestMessage originalMessage = EppUtils.getCreateMessage(EppUtils.getSuccessResponse());
|
||||
String domainName = transientEppToken.getCurrentDomainName();
|
||||
String clTrid = domainName.substring(0, domainName.indexOf('.'));
|
||||
|
||||
EppRequestMessage modifiedMessage =
|
||||
(EppRequestMessage) transientEppToken.modifyMessage(originalMessage);
|
||||
|
||||
// ensure element values are what they should be
|
||||
assertThat(modifiedMessage.getElementValue("//domainns:name")).isEqualTo(domainName);
|
||||
assertThat(modifiedMessage.getElementValue("//eppns:clTRID")).isNotEqualTo(clTrid);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNext_persistentToken() {
|
||||
String domainName = persistentEppToken.getCurrentDomainName();
|
||||
Channel mockChannel = Mockito.mock(Channel.class);
|
||||
persistentEppToken.setChannel(mockChannel);
|
||||
|
||||
EppToken nextToken = (EppToken) persistentEppToken.next();
|
||||
|
||||
assertThat(nextToken.getCurrentDomainName()).isNotEqualTo(domainName);
|
||||
assertThat(nextToken.channel()).isEqualTo(mockChannel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNext_transientToken() {
|
||||
String domainName = transientEppToken.getCurrentDomainName();
|
||||
Channel mockChannel = Mockito.mock(Channel.class);
|
||||
transientEppToken.setChannel(mockChannel);
|
||||
|
||||
EppToken nextToken = (EppToken) transientEppToken.next();
|
||||
|
||||
assertThat(nextToken.getCurrentDomainName()).isNotEqualTo(domainName);
|
||||
assertThat(nextToken.channel()).isNull();
|
||||
}
|
||||
}
|
|
@ -23,9 +23,7 @@ import org.junit.Test;
|
|||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/**
|
||||
* Unit Tests for {@link WebWhoisToken}
|
||||
*/
|
||||
/** Unit Tests for {@link WebWhoisToken} */
|
||||
@RunWith(JUnit4.class)
|
||||
public class WebWhoisTokenTest {
|
||||
|
||||
|
@ -35,19 +33,17 @@ public class WebWhoisTokenTest {
|
|||
private static final String SECOND_TLD = "second_test";
|
||||
private static final String THIRD_TLD = "third_test";
|
||||
private final CircularList<String> testDomains =
|
||||
new CircularList.Builder<String>()
|
||||
.add(FIRST_TLD, SECOND_TLD, THIRD_TLD)
|
||||
.build();
|
||||
new CircularList.Builder<String>().add(FIRST_TLD, SECOND_TLD, THIRD_TLD).build();
|
||||
|
||||
public Token webToken = new WebWhoisToken(testDomains);
|
||||
|
||||
@Test
|
||||
public void testMessageModification() throws UndeterminedStateException {
|
||||
//creates Request message with header
|
||||
// creates Request message with header
|
||||
HttpRequestMessage message = new HttpRequestMessage();
|
||||
message.headers().set("host", HOST);
|
||||
|
||||
//attempts to use Token's method for modifying the method based on its stored host
|
||||
// attempts to use Token's method for modifying the method based on its stored host
|
||||
HttpRequestMessage secondMessage = (HttpRequestMessage) webToken.modifyMessage(message);
|
||||
assertThat(secondMessage.headers().get("host")).isEqualTo(PREFIX + FIRST_TLD);
|
||||
}
|
||||
|
@ -69,5 +65,4 @@ public class WebWhoisTokenTest {
|
|||
|
||||
assertThat(webToken.host()).isEqualTo(PREFIX + FIRST_TLD);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.monitoring.blackbox.util;
|
||||
|
||||
import static google.registry.monitoring.blackbox.messages.EppMessage.CLIENT_ID_KEY;
|
||||
import static google.registry.monitoring.blackbox.messages.EppMessage.CLIENT_PASSWORD_KEY;
|
||||
import static google.registry.monitoring.blackbox.messages.EppMessage.CLIENT_TRID_KEY;
|
||||
import static google.registry.monitoring.blackbox.messages.EppMessage.DOMAIN_KEY;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.monitoring.blackbox.exceptions.EppClientException;
|
||||
import google.registry.monitoring.blackbox.messages.EppMessage;
|
||||
import google.registry.monitoring.blackbox.messages.EppRequestMessage;
|
||||
import google.registry.monitoring.blackbox.messages.EppResponseMessage;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import java.io.IOException;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
/** Houses static utility functions for testing EPP components of Prober. */
|
||||
public class EppUtils {
|
||||
|
||||
/** Return a simple default greeting as a {@link Document}. */
|
||||
public static Document getGreeting() throws IOException, EppClientException {
|
||||
return EppMessage.getEppDocFromTemplate("greeting.xml", ImmutableMap.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a basic response as a {@link Document}.
|
||||
*
|
||||
* @param success specifies if response shows a success or failure
|
||||
* @param clTrid the client transaction ID
|
||||
* @param svTrid the server transaction ID
|
||||
* @return the EPP basic response as a {@link Document}.
|
||||
*/
|
||||
public static Document getBasicResponse(boolean success, String clTrid, String svTrid)
|
||||
throws IOException, EppClientException {
|
||||
|
||||
String template = success ? "success_response.xml" : "failed_response.xml";
|
||||
|
||||
return EppMessage.getEppDocFromTemplate(
|
||||
template,
|
||||
ImmutableMap.of(
|
||||
EppRequestMessage.CLIENT_TRID_KEY, clTrid, EppMessage.SERVER_TRID_KEY, svTrid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a domain check response as a {@link Document}.
|
||||
*
|
||||
* @param exists specifies if response shows that domain name exists on server or doesn't
|
||||
* @param clTrid the client transaction ID
|
||||
* @param svTrid the server transaction ID
|
||||
* @param domain the domain the check success is for
|
||||
* @return the EPP check response as a {@link Document}.
|
||||
*/
|
||||
public static Document getDomainCheck(boolean exists, String clTrid, String svTrid, String domain)
|
||||
throws IOException, EppClientException {
|
||||
|
||||
String template = exists ? "domain_exists.xml" : "domain_not_exists.xml";
|
||||
|
||||
return EppMessage.getEppDocFromTemplate(
|
||||
template,
|
||||
ImmutableMap.of(
|
||||
EppRequestMessage.CLIENT_TRID_KEY, clTrid,
|
||||
EppMessage.SERVER_TRID_KEY, svTrid,
|
||||
EppMessage.DOMAIN_KEY, domain));
|
||||
}
|
||||
|
||||
/** Converts {@link Document} to {@link ByteBuf}. */
|
||||
public static ByteBuf docToByteBuf(Document message) throws EppClientException {
|
||||
byte[] bytestream = EppMessage.xmlDocToByteArray(message);
|
||||
|
||||
ByteBuf buf = Unpooled.buffer(bytestream.length);
|
||||
|
||||
buf.writeBytes(bytestream);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/** Returns standard hello request with supplied response. */
|
||||
public static EppRequestMessage getHelloMessage(EppResponseMessage greetingResponse) {
|
||||
return new EppRequestMessage(greetingResponse, null, (a, b) -> ImmutableMap.of());
|
||||
}
|
||||
|
||||
/** Returns standard login request with supplied userId, userPassword, and response. */
|
||||
public static EppRequestMessage getLoginMessage(
|
||||
EppResponseMessage response, String userId, String userPassword) {
|
||||
return new EppRequestMessage(
|
||||
response,
|
||||
"login.xml",
|
||||
(clTrid, domain) ->
|
||||
ImmutableMap.of(
|
||||
CLIENT_TRID_KEY, clTrid,
|
||||
CLIENT_ID_KEY, userId,
|
||||
CLIENT_PASSWORD_KEY, userPassword));
|
||||
}
|
||||
|
||||
/** Returns standard create request with supplied response. */
|
||||
public static EppRequestMessage getCreateMessage(EppResponseMessage response) {
|
||||
return new EppRequestMessage(
|
||||
response,
|
||||
"create.xml",
|
||||
(clTrid, domain) ->
|
||||
ImmutableMap.of(
|
||||
CLIENT_TRID_KEY, clTrid,
|
||||
DOMAIN_KEY, domain));
|
||||
}
|
||||
|
||||
/** Returns standard delete request with supplied response. */
|
||||
public static EppRequestMessage getDeleteMessage(EppResponseMessage response) {
|
||||
return new EppRequestMessage(
|
||||
response,
|
||||
"delete.xml",
|
||||
(clTrid, domain) ->
|
||||
ImmutableMap.of(
|
||||
CLIENT_TRID_KEY, clTrid,
|
||||
DOMAIN_KEY, domain));
|
||||
}
|
||||
|
||||
/** Returns standard logout request with supplied response. */
|
||||
public static EppRequestMessage getLogoutMessage(EppResponseMessage successResponse) {
|
||||
return new EppRequestMessage(
|
||||
successResponse,
|
||||
"logout.xml",
|
||||
(clTrid, domain) -> ImmutableMap.of(CLIENT_TRID_KEY, clTrid));
|
||||
}
|
||||
|
||||
/** Returns standard check request with supplied response. */
|
||||
public static EppRequestMessage getCheckMessage(EppResponseMessage response) {
|
||||
return new EppRequestMessage(
|
||||
response,
|
||||
"check.xml",
|
||||
(clTrid, domain) ->
|
||||
ImmutableMap.of(
|
||||
CLIENT_TRID_KEY, clTrid,
|
||||
DOMAIN_KEY, domain));
|
||||
}
|
||||
|
||||
/** Returns standard success response. */
|
||||
public static EppResponseMessage getSuccessResponse() {
|
||||
return new EppResponseMessage(
|
||||
"success",
|
||||
(clTrid, domain) ->
|
||||
ImmutableList.of(
|
||||
String.format("//eppns:clTRID[.='%s']", clTrid), EppMessage.XPASS_EXPRESSION));
|
||||
}
|
||||
|
||||
/** Returns standard failure response. */
|
||||
public static EppResponseMessage getFailureResponse() {
|
||||
return new EppResponseMessage(
|
||||
"failure",
|
||||
(clTrid, domain) ->
|
||||
ImmutableList.of(
|
||||
String.format("//eppns:clTRID[.='%s']", clTrid), EppMessage.XFAIL_EXPRESSION));
|
||||
}
|
||||
|
||||
/** Returns standard domainExists response. */
|
||||
public static EppResponseMessage getDomainExistsResponse() {
|
||||
return new EppResponseMessage(
|
||||
"domainExists",
|
||||
(clTrid, domain) ->
|
||||
ImmutableList.of(
|
||||
String.format("//eppns:clTRID[.='%s']", clTrid),
|
||||
String.format("//domainns:name[@avail='false'][.='%s']", domain),
|
||||
EppMessage.XPASS_EXPRESSION));
|
||||
}
|
||||
|
||||
/** Returns standard domainNotExists response. */
|
||||
public static EppResponseMessage getDomainNotExistsResponse() {
|
||||
return new EppResponseMessage(
|
||||
"domainNotExists",
|
||||
(clTrid, domain) ->
|
||||
ImmutableList.of(
|
||||
String.format("//eppns:clTRID[.='%s']", clTrid),
|
||||
String.format("//domainns:name[@avail='true'][.='%s']", domain),
|
||||
EppMessage.XPASS_EXPRESSION));
|
||||
}
|
||||
|
||||
/** Returns standard greeting response. */
|
||||
public static EppResponseMessage getGreetingResponse() {
|
||||
return new EppResponseMessage(
|
||||
"greeting", (clTrid, domain) -> ImmutableList.of("//eppns:greeting"));
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.monitoring.blackbox;
|
||||
package google.registry.monitoring.blackbox.util;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
|
||||
|
@ -26,10 +26,8 @@ import io.netty.handler.codec.http.HttpMethod;
|
|||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
|
||||
/**
|
||||
* Utility class for various helper methods used in testing.
|
||||
*/
|
||||
public class TestUtils {
|
||||
/** Houses static utility functions for testing WebWHOIS components of Prober. */
|
||||
public class WebWhoisUtils {
|
||||
|
||||
public static FullHttpRequest makeHttpGetRequest(String host, String path) {
|
||||
FullHttpRequest request =
|
||||
|
@ -51,9 +49,7 @@ public class TestUtils {
|
|||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates HttpResponse given status, redirection location, and other necessary inputs
|
||||
*/
|
||||
/** Creates HttpResponse given status, redirection location, and other necessary inputs */
|
||||
public static FullHttpResponse makeRedirectResponse(
|
||||
HttpResponseStatus status, String location, boolean keepAlive) {
|
||||
FullHttpResponse response = makeHttpResponse("", status);
|
||||
|
@ -67,4 +63,3 @@ public class TestUtils {
|
|||
return response;
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue