mirror of
https://github.com/google/nomulus.git
synced 2025-07-06 03:03:34 +02:00
Prober circular list (#218)
* Fixed changes suggested by CydeWeys * 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 * 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. * Minor Style Fixes * 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 * Initial Commit. * 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 Protocol Class and its Basic Unit Tests * Added Changes Suggested by jianglai * Fixed Gitignore to take out AutoValue generated code * Fixed Gitignore to take out AutoValue generated code * Removed AutoValue java files * Added gitignore within prober * Removed all generated java * Final Changes in .gitignore * 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 * Fixed changes suggested by CydeWeys * Fixed changes suggested by CydeWeys * Fixed changes suggested by CydeWeys * Fixed changes suggested by CydeWeys * Minor fixes to ActionHandler, as responded in comments, removed package-info, and updated settings.gradle * 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 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 * 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 * Added missing license headers and JavaDoc * Added missing license headers and JavaDoc * Added missing license headers and JavaDoc * Added missing license headers and JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor Style Fix * Minor Style Fix * Minor Style Fix * Minor Style Fix * Full WebWhoIs Sequence Added * Full WebWhoIs Sequence Added * Full WebWhoIs Sequence Added * Full WebWhoIs Sequence Added * Full WebWhoIs Sequence Added * Full WebWhoIs Sequence Added * fixed build issues * fixed build issues * fixed build issues * fixed build issues * fixed build issues * Refactored by responses suggested by jianglai. * Refactored by responses suggested by jianglai. * Refactored by responses suggested by jianglai. * Refactored by responses suggested by jianglai. * Refactored by responses suggested by jianglai. * Refactored by responses suggested by jianglai. * Minor Style Fixes * Minor Style Fixes * Minor Style Fixes * Minor Style Fixes * Minor Style Fixes * Updated build.gradle file * Updated build.gradle file * Updated build.gradle file * Updated build.gradle file * Modified license header dates * Modified license header dates * Modified license header dates * Modified license header dates * Modified license header dates * Updated WebWhois tests. * Updated WebWhois tests. * Updated WebWhois tests. * Updated WebWhois tests. * 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 * 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 * SpotlessApply run to fix style issues * SpotlessApply run to fix style issues * SpotlessApply run to fix style issues * SpotlessApply run to fix style issues * SpotlessApply run to fix style issues * Added license header and newline where appropriate. * Added license header and newline where appropriate. * Added license header and newline where appropriate. * Added license header and newline where appropriate. * 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 * Javadoc style fix in tests and removed unused methods * Javadoc style fix in tests and removed unused methods * Javadoc style fix in tests and removed unused methods * Refactored ProbingAction to minimize number of unnecessary methods * Refactored ProbingAction to minimize number of unnecessary methods * Refactored ProbingAction to minimize number of unnecessary methods * Refactored ProbingAction to minimize number of unnecessary methods * Modified tests for WebWhois according to changes suggested by laijiang. * Modified tests for WebWhois according to changes suggested by laijiang. * Modified tests for WebWhois according to changes suggested by laijiang. * Modified tests for WebWhois according to changes suggested by laijiang. * Modified tests for WebWhois according to changes suggested by laijiang. * Removed TestProvider from TestUtils. * Removed TestProvider from TestUtils. * Removed TestProvider from TestUtils. * Removed TestProvider from TestUtils. * Removed TestProvider from TestUtils. * Rebased to master * Rebased to master * Updated issues in rebasing * Updated issues in rebasing * Minor style change on prober/build.gradle * Minor style change on prober/build.gradle * Fixed warnings for java compilation * Fixed warnings for java compilation * Fixed files to pass all style tests * Fixed files to pass all style tests * Fixed files to pass all style tests * Minor syle fixes after succesful rebase onto master * Fixed changes suggested by CydeWeys * 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 * Added missing license headers and JavaDoc * Added missing license headers and JavaDoc * Added missing license headers and JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor fix in NewChannelAction JavaDoc * Minor Style Fix * Minor Style Fix * Minor Style Fix * Full WebWhoIs Sequence Added * Full WebWhoIs Sequence Added * Full WebWhoIs Sequence Added * fixed build issues * fixed build issues * fixed build issues * Refactored by responses suggested by jianglai. * Refactored by responses suggested by jianglai. * Refactored by responses suggested by jianglai. * Minor Style Fixes * Minor Style Fixes * Updated build.gradle file * Updated build.gradle file * Updated build.gradle file * Modified license header dates * Modified license header dates * Modified license header dates * Updated WebWhois tests. * Updated WebWhois tests. * Updated WebWhois tests. * 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 * SpotlessApply run to fix style issues * Added circular linked list to utils * Added circular linked list to utils * Added circular linked list to utils * Added circular linked list to utils * Added circular linked list to utils * License Header added * License Header added * License Header added * License Header added * License Header added * Added license header and newline where appropriate. * Added license header and newline where appropriate. * Refactored probing sequence to be circular linked list iterator * Refactored probing sequence to be circular linked list iterator * Refactored probing sequence to be circular linked list iterator * Refactored probing sequence to be circular linked list iterator * Javadoc style fix in tests and removed unused methods * Javadoc style fix in tests and removed unused methods * Javadoc style fix in tests and removed unused methods * Modified ProbingStep tests to reflect new ProbingStep structure. * Modified ProbingStep tests to reflect new ProbingStep structure. * Refactored ProbingAction to minimize number of unnecessary methods * Refactored ProbingAction to minimize number of unnecessary methods * Refactored ProbingAction to minimize number of unnecessary methods * Modified tests for WebWhois according to changes suggested by laijiang. * Modified tests for WebWhois according to changes suggested by laijiang. * Modified tests for WebWhois according to changes suggested by laijiang. * Removed TestProvider from TestUtils. * Removed TestProvider from TestUtils. * Rebased to master * ProbingStepTest modified to have fewer unnecessary helper methods * ProbingStepTest modified to have fewer unnecessary helper methods * Updated issues in rebasing * Updated issues in rebasing * Added missing license header to DefaultCircularLinkedListIterator * Fixed max column length to be 100 * 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. * Merge branch 'master' into prober-circular-list * Modified ProbingSequenceTest to not expect unnecessary NullPointerException * ProbingSequence and tests modified to reflect addition of UnrecoverableStateException and restarts on failures * Modified ProbingSequence and its tests to reflect action generation and calling being put in the same try catch block
This commit is contained in:
parent
89a44f176c
commit
df5f450435
10 changed files with 697 additions and 281 deletions
|
@ -17,76 +17,304 @@ package google.registry.monitoring.blackbox;
|
|||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doCallRealMethod;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import google.registry.monitoring.blackbox.exceptions.FailureException;
|
||||
import google.registry.monitoring.blackbox.exceptions.UndeterminedStateException;
|
||||
import google.registry.monitoring.blackbox.exceptions.UnrecoverableStateException;
|
||||
import google.registry.monitoring.blackbox.tokens.Token;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.embedded.EmbeddedChannel;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
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>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>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>
|
||||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
public class ProbingSequenceTest {
|
||||
|
||||
private ProbingStep firstStep;
|
||||
private ProbingStep secondStep;
|
||||
private ProbingStep thirdStep;
|
||||
/**
|
||||
* Default mock {@link ProbingAction} returned when generating an action with a mockStep.
|
||||
*/
|
||||
private ProbingAction mockAction = Mockito.mock(ProbingAction.class);
|
||||
|
||||
private Token testToken;
|
||||
/**
|
||||
* Default mock {@link ProbingStep} that will usually return a {@code mockAction} on call to
|
||||
* generate action.
|
||||
*/
|
||||
private ProbingStep mockStep = Mockito.mock(ProbingStep.class);
|
||||
|
||||
private ProbingStep setupMockStep() {
|
||||
ProbingStep mock = Mockito.mock(ProbingStep.class);
|
||||
doCallRealMethod().when(mock).nextStep(any(ProbingStep.class));
|
||||
doCallRealMethod().when(mock).nextStep();
|
||||
return mock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default mock {@link Token} that is passed into each {@link ProbingSequence} tested.
|
||||
*/
|
||||
private Token mockToken = Mockito.mock(Token.class);
|
||||
|
||||
/**
|
||||
* Default mock {@link Protocol} returned {@code mockStep} and occasionally, other mock {@link
|
||||
* ProbingStep}s.
|
||||
*/
|
||||
private Protocol mockProtocol = Mockito.mock(Protocol.class);
|
||||
|
||||
/**
|
||||
* {@link EmbeddedChannel} used to create new {@link ChannelPromise} objects returned by mock
|
||||
* {@link ProbingAction}s on their {@code call} methods.
|
||||
*/
|
||||
private EmbeddedChannel channel = new EmbeddedChannel();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
firstStep = setupMockStep();
|
||||
secondStep = setupMockStep();
|
||||
thirdStep = setupMockStep();
|
||||
// To avoid a NullPointerException, we must have a protocol return persistent connection as
|
||||
// false.
|
||||
doReturn(true).when(mockProtocol).persistentConnection();
|
||||
|
||||
testToken = Mockito.mock(Token.class);
|
||||
// In order to avoid a NullPointerException, we must have the protocol returned that stores
|
||||
// persistent connection as false.
|
||||
doReturn(mockProtocol).when(mockStep).protocol();
|
||||
|
||||
// Allows for test if channel is accurately set.
|
||||
doCallRealMethod().when(mockToken).setChannel(any(Channel.class));
|
||||
doCallRealMethod().when(mockToken).channel();
|
||||
|
||||
// Allows call to mockAction to retrieve mocked channel.
|
||||
doReturn(channel).when(mockAction).channel();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSequenceBasicConstruction_Success() {
|
||||
ProbingStep firstStep = Mockito.mock(ProbingStep.class);
|
||||
ProbingStep secondStep = Mockito.mock(ProbingStep.class);
|
||||
ProbingStep thirdStep = Mockito.mock(ProbingStep.class);
|
||||
|
||||
ProbingSequence sequence = new ProbingSequence.Builder(testToken)
|
||||
.addStep(firstStep)
|
||||
.addStep(secondStep)
|
||||
.addStep(thirdStep)
|
||||
ProbingSequence sequence = new ProbingSequence.Builder(mockToken)
|
||||
.add(firstStep)
|
||||
.add(secondStep)
|
||||
.add(thirdStep)
|
||||
.build();
|
||||
|
||||
assertThat(firstStep.nextStep()).isEqualTo(secondStep);
|
||||
assertThat(secondStep.nextStep()).isEqualTo(thirdStep);
|
||||
assertThat(thirdStep.nextStep()).isEqualTo(firstStep);
|
||||
assertThat(sequence.get()).isEqualTo(firstStep);
|
||||
sequence = sequence.next();
|
||||
|
||||
sequence.start();
|
||||
assertThat(sequence.get()).isEqualTo(secondStep);
|
||||
sequence = sequence.next();
|
||||
|
||||
verify(firstStep, times(1)).accept(testToken);
|
||||
assertThat(sequence.get()).isEqualTo(thirdStep);
|
||||
sequence = sequence.next();
|
||||
|
||||
assertThat(sequence.get()).isEqualTo(firstStep);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSequenceAdvancedConstruction_Success() {
|
||||
ProbingStep firstStep = Mockito.mock(ProbingStep.class);
|
||||
ProbingStep secondStep = Mockito.mock(ProbingStep.class);
|
||||
ProbingStep thirdStep = Mockito.mock(ProbingStep.class);
|
||||
|
||||
ProbingSequence sequence = new ProbingSequence.Builder(testToken)
|
||||
.addStep(thirdStep)
|
||||
.addStep(secondStep)
|
||||
ProbingSequence sequence = new ProbingSequence.Builder(mockToken)
|
||||
.add(thirdStep)
|
||||
.add(secondStep)
|
||||
.markFirstRepeated()
|
||||
.addStep(firstStep)
|
||||
.add(firstStep)
|
||||
.build();
|
||||
|
||||
assertThat(firstStep.nextStep()).isEqualTo(secondStep);
|
||||
assertThat(secondStep.nextStep()).isEqualTo(firstStep);
|
||||
assertThat(thirdStep.nextStep()).isEqualTo(secondStep);
|
||||
assertThat(sequence.get()).isEqualTo(thirdStep);
|
||||
sequence = sequence.next();
|
||||
|
||||
assertThat(sequence.get()).isEqualTo(secondStep);
|
||||
sequence = sequence.next();
|
||||
|
||||
assertThat(sequence.get()).isEqualTo(firstStep);
|
||||
sequence = sequence.next();
|
||||
|
||||
assertThat(sequence.get()).isEqualTo(secondStep);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunStep_Success() throws UndeterminedStateException {
|
||||
//Always returns a succeeded future on call to mockAction.
|
||||
doReturn(channel.newSucceededFuture()).when(mockAction).call();
|
||||
|
||||
// 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.
|
||||
ProbingStep secondStep = Mockito.mock(ProbingStep.class);
|
||||
ProbingAction secondAction = Mockito.mock(ProbingAction.class);
|
||||
|
||||
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();
|
||||
|
||||
sequence.start();
|
||||
|
||||
verify(thirdStep, times(1)).accept(testToken);
|
||||
// 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.
|
||||
assertThat(mockToken.channel()).isEqualTo(channel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunLoop_Success() throws UndeterminedStateException {
|
||||
// Always returns a succeeded future on call to mockAction.
|
||||
doReturn(channel.newSucceededFuture()).when(mockAction).call();
|
||||
|
||||
// Has mockStep always return mockAction on call to generateAction
|
||||
doReturn(mockAction).when(mockStep).generateAction(mockToken);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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
|
||||
// mockStep once more.
|
||||
doReturn(channel.newSucceededFuture()).when(secondAction).call();
|
||||
doReturn(secondAction).when(secondStep).generateAction(mockToken);
|
||||
|
||||
// We get a secondToken that is returned when we are on our second loop in the sequence. This
|
||||
// will inform mockStep on when to generate a different ProbingAction.
|
||||
Token secondToken = Mockito.mock(Token.class);
|
||||
doReturn(secondToken).when(mockToken).next();
|
||||
|
||||
// The thirdAction we use is made so that when it is called, it will halt the ProbingSequence
|
||||
// by returning an UnrecoverableStateException.
|
||||
ProbingAction thirdAction = Mockito.mock(ProbingAction.class);
|
||||
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();
|
||||
|
||||
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();
|
||||
verify(thirdAction).call();
|
||||
|
||||
// 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.
|
||||
assertThat(mockToken.channel()).isEqualTo(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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}.
|
||||
*/
|
||||
private void testActionFailure() throws UndeterminedStateException {
|
||||
//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
|
||||
// UnrecoverableStateException to terminate the sequence
|
||||
Token secondToken = Mockito.mock(Token.class);
|
||||
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();
|
||||
|
||||
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);
|
||||
|
||||
// We should never reach the step where we modify the channel, as it should have failed by then
|
||||
assertThat(mockToken.channel()).isNull();
|
||||
assertThat(secondToken.channel()).isNull();
|
||||
|
||||
// We should never reach the second step, since we fail on the first step, then terminate on
|
||||
// the first step after retrying.
|
||||
verify(secondStep, times(0)).generateAction(any(Token.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunStep_FailureRunning() throws UndeterminedStateException {
|
||||
// Returns a failed future when calling the generated mock action.
|
||||
doReturn(channel.newFailedFuture(new FailureException(""))).when(mockAction).call();
|
||||
|
||||
// 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.
|
||||
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.
|
||||
doThrow(UndeterminedStateException.class).when(mockStep).generateAction(mockToken);
|
||||
|
||||
testActionFailure();
|
||||
|
||||
// We expect to have never called this action, as we fail each time whenever generating actions.
|
||||
verify(mockAction, times(0)).call();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,13 +16,9 @@ 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 java.nio.charset.StandardCharsets.US_ASCII;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.monitoring.blackbox.exceptions.UndeterminedStateException;
|
||||
|
@ -34,8 +30,7 @@ import google.registry.monitoring.blackbox.messages.OutboundMessageType;
|
|||
import google.registry.monitoring.blackbox.messages.TestMessage;
|
||||
import google.registry.monitoring.blackbox.tokens.Token;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.embedded.EmbeddedChannel;
|
||||
|
@ -43,7 +38,6 @@ import io.netty.channel.local.LocalAddress;
|
|||
import io.netty.channel.local.LocalChannel;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import org.joda.time.Duration;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
@ -62,14 +56,11 @@ public class ProbingStepTest {
|
|||
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 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
|
||||
*/
|
||||
|
@ -91,13 +82,53 @@ public class ProbingStepTest {
|
|||
private Token testToken(String host) throws UndeterminedStateException {
|
||||
Token token = Mockito.mock(Token.class);
|
||||
doReturn(host).when(token).host();
|
||||
doAnswer(answer -> answer.getArgument(0)).when(token)
|
||||
doAnswer(answer -> ((OutboundMessageType) answer.getArgument(0)).modifyMessage(host))
|
||||
.when(token)
|
||||
.modifyMessage(any(OutboundMessageType.class));
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewChannel() throws Exception {
|
||||
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();
|
||||
|
||||
// Sets up an embedded channel to contain the two handlers we created already.
|
||||
EmbeddedChannel channel = new EmbeddedChannel(conversionHandler, testHandler);
|
||||
channel.attr(CONNECTION_FUTURE_KEY).set(channel.newSucceededFuture());
|
||||
|
||||
// Sets up testToken to return arbitrary value, and the embedded channel. Used for when the
|
||||
// ProbingStep generates an ExistingChannelAction.
|
||||
Token testToken = testToken(SECONDARY_TEST_MESSAGE);
|
||||
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();
|
||||
|
||||
ProbingAction testAction = testStep.generateAction(testToken);
|
||||
|
||||
assertThat(testAction.channel()).isEqualTo(channel);
|
||||
assertThat(testAction.delay()).isEqualTo(Duration.ZERO);
|
||||
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))
|
||||
|
@ -106,97 +137,32 @@ public class ProbingStepTest {
|
|||
.setPersistentConnection(false)
|
||||
.build();
|
||||
|
||||
// Sets up our main step (firstStep) and throwaway step (dummyStep).
|
||||
ProbingStep firstStep = ProbingStep.builder()
|
||||
// Sets up generic ProbingStep that we are testing.
|
||||
ProbingStep testStep = ProbingStep.builder()
|
||||
.setMessageTemplate(new TestMessage(TEST_MESSAGE))
|
||||
.setBootstrap(bootstrap)
|
||||
.setDuration(Duration.ZERO)
|
||||
.setMessageTemplate(new TestMessage(TEST_MESSAGE))
|
||||
.setProtocol(testProtocol)
|
||||
.build();
|
||||
|
||||
//Sets up mock dummy step that returns succeeded promise when we successfully reach it.
|
||||
ProbingStep dummyStep = Mockito.mock(ProbingStep.class);
|
||||
|
||||
firstStep.nextStep(dummyStep);
|
||||
|
||||
// Sets up testToken to return arbitrary values, and no channel. Used when we create a new
|
||||
// channel.
|
||||
Token testToken = testToken(ADDRESS_NAME);
|
||||
|
||||
//Set up blackbox server that receives our messages then echoes them back to us
|
||||
nettyRule.setUpServer(ADDRESS);
|
||||
// Sets up server listening at LocalAddress so generated action can have successful connection.
|
||||
nettyRule.setUpServer(address);
|
||||
|
||||
//checks that the ProbingSteps are appropriately pointing to each other
|
||||
assertThat(firstStep.nextStep()).isEqualTo(dummyStep);
|
||||
ProbingAction testAction = testStep.generateAction(testToken);
|
||||
|
||||
//Call accept on the first step, which should send our message to the server, which will then be
|
||||
//echoed back to us, causing us to move to the next step
|
||||
firstStep.accept(testToken);
|
||||
ChannelFuture connectionFuture = testAction.channel().attr(CONNECTION_FUTURE_KEY).get();
|
||||
connectionFuture = connectionFuture.syncUninterruptibly();
|
||||
|
||||
//checks that we have appropriately sent the write message to server
|
||||
nettyRule.assertReceivedMessage(TEST_MESSAGE);
|
||||
assertThat(connectionFuture.isSuccess()).isTrue();
|
||||
assertThat(testAction.delay()).isEqualTo(Duration.ZERO);
|
||||
assertThat(testAction.outboundMessage().toString()).isEqualTo(ADDRESS_NAME);
|
||||
assertThat(testAction.host()).isEqualTo(ADDRESS_NAME);
|
||||
assertThat(testAction.protocol()).isEqualTo(testProtocol);
|
||||
|
||||
//checks that when the future is successful, we pass down the requisite token
|
||||
verify(dummyStep, times(1)).accept(any(Token.class));
|
||||
}
|
||||
|
||||
//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 testWithSequence_ExistingChannel() throws Exception {
|
||||
// Sets up Protocol for when a channel already exists.
|
||||
Protocol testProtocol = Protocol.builder()
|
||||
.setHandlerProviders(ImmutableList.of(() -> conversionHandler, () -> testHandler))
|
||||
.setName(PROTOCOL_NAME)
|
||||
.setPort(PROTOCOL_PORT)
|
||||
.setPersistentConnection(true)
|
||||
.build();
|
||||
|
||||
// Sets up our main step (firstStep) and throwaway step (dummyStep).
|
||||
ProbingStep firstStep = ProbingStep.builder()
|
||||
.setBootstrap(bootstrap)
|
||||
.setDuration(Duration.ZERO)
|
||||
.setMessageTemplate(new TestMessage(TEST_MESSAGE))
|
||||
.setProtocol(testProtocol)
|
||||
.build();
|
||||
|
||||
//Sets up mock dummy step that returns succeeded promise when we successfully reach it.
|
||||
ProbingStep dummyStep = Mockito.mock(ProbingStep.class);
|
||||
|
||||
firstStep.nextStep(dummyStep);
|
||||
|
||||
// Sets up an embedded channel to contain the two handlers we created already.
|
||||
EmbeddedChannel channel = new EmbeddedChannel(conversionHandler, testHandler);
|
||||
|
||||
//Assures that the channel has a succeeded connectionFuture.
|
||||
channel.attr(CONNECTION_FUTURE_KEY).set(channel.newSucceededFuture());
|
||||
|
||||
// Sets up testToken to return arbitrary value, and the embedded channel. Used for when the
|
||||
// ProbingStep generates an ExistingChannelAction.
|
||||
Token testToken = testToken("");
|
||||
doReturn(channel).when(testToken).channel();
|
||||
|
||||
//checks that the ProbingSteps are appropriately pointing to each other
|
||||
assertThat(firstStep.nextStep()).isEqualTo(dummyStep);
|
||||
|
||||
//Call accept on the first step, which should send our message through the EmbeddedChannel
|
||||
// pipeline
|
||||
firstStep.accept(testToken);
|
||||
|
||||
Object msg = channel.readOutbound();
|
||||
|
||||
while (msg == null) {
|
||||
msg = channel.readOutbound();
|
||||
}
|
||||
//Ensures the accurate message is sent down the pipeline
|
||||
assertThat(((ByteBuf) channel.readOutbound()).toString(UTF_8)).isEqualTo(TEST_MESSAGE);
|
||||
|
||||
//Write response to our message down EmbeddedChannel pipeline
|
||||
channel.writeInbound(Unpooled.wrappedBuffer(SECONDARY_TEST_MESSAGE.getBytes(US_ASCII)));
|
||||
|
||||
//At this point, we should have received the message, so the future obtained should be marked
|
||||
// as a success
|
||||
verify(dummyStep, times(1)).accept(any(Token.class));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ package google.registry.monitoring.blackbox.tokens;
|
|||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.monitoring.blackbox.exceptions.UndeterminedStateException;
|
||||
import google.registry.monitoring.blackbox.messages.HttpRequestMessage;
|
||||
import google.registry.util.CircularList;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
@ -29,15 +29,17 @@ import org.junit.runners.JUnit4;
|
|||
@RunWith(JUnit4.class)
|
||||
public class WebWhoisTokenTest {
|
||||
|
||||
private static String PREFIX = "whois.nic.";
|
||||
private static String HOST = "starter";
|
||||
private static String FIRST_TLD = "first_test";
|
||||
private static String SECOND_TLD = "second_test";
|
||||
private static String THIRD_TLD = "third_test";
|
||||
private static ImmutableList<String> TEST_DOMAINS = ImmutableList.of(FIRST_TLD, SECOND_TLD,
|
||||
THIRD_TLD);
|
||||
private static final String PREFIX = "whois.nic.";
|
||||
private static final String HOST = "starter";
|
||||
private static final String FIRST_TLD = "first_test";
|
||||
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();
|
||||
|
||||
public Token webToken = new WebWhoisToken(TEST_DOMAINS);
|
||||
public Token webToken = new WebWhoisToken(testDomains);
|
||||
|
||||
@Test
|
||||
public void testMessageModification() throws UndeterminedStateException {
|
||||
|
@ -47,7 +49,7 @@ public class WebWhoisTokenTest {
|
|||
|
||||
//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 + TEST_DOMAINS.get(0));
|
||||
assertThat(secondMessage.headers().get("host")).isEqualTo(PREFIX + FIRST_TLD);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,6 +65,9 @@ public class WebWhoisTokenTest {
|
|||
webToken = webToken.next();
|
||||
|
||||
assertThat(webToken.host()).isEqualTo(PREFIX + THIRD_TLD);
|
||||
webToken = webToken.next();
|
||||
|
||||
assertThat(webToken.host()).isEqualTo(PREFIX + FIRST_TLD);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue