Skip to content

JAVA-3076: NullSavingStrategyIT sometimes fails with ProtocolError: M…#1669

Merged
hhughes merged 1 commit into4.xfrom
JAVA-3076
Aug 21, 2023
Merged

JAVA-3076: NullSavingStrategyIT sometimes fails with ProtocolError: M…#1669
hhughes merged 1 commit into4.xfrom
JAVA-3076

Conversation

@hhughes
Copy link
Contributor

@hhughes hhughes commented Jun 29, 2023

…ust not send frame with WARNING flag for native protocol version < 4

NullSavingStrategyIT.java:

  • Remove V3 protocol configuration from class SessionRule
  • Create new session configured with V3 protocol in @BeforeClass method to use in tests

// latest protocol version for SessionRule set-up (i.e. creating a keyspace which could result in
// warning about too many keyspaces) and then create a new client for the tests to use in a
// separate @BeforeClass method. This client is torn down in @AfterClass method #teardown().
private static CqlSession v3Session;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused as to why we're keeping this session around as a static reference when we really only need it for a one-off operation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to close this session at the end of the test class, for SESSION_RULE this is handled automatically by junit which calls SessionRule#after() (and subsequently session.close()) because it's a @ClassRule

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the comments could be clearer here - this session instance is being used in all the tests via the mapper object so we need to keep it around until after they've all finished

mapper = new NullSavingStrategyIT_InventoryMapperBuilder(session).build();
// Use V3 client in the InventoryMapper used in the tests
mapper = new NullSavingStrategyIT_InventoryMapperBuilder(v3Session).build();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per my comment above... doesn't this accomplish exactly the same thing without requiring a new field (or a teardown method)?

  @BeforeClass
  public static void setup() {
    
    // JAVA-3076: Perform setup using a one-off v5 session to avoid any errors when using v3
    DriverConfigLoader setupSessionLoader = DriverConfigLoader.programmaticBuilder()
            .withString(DefaultDriverOption.PROTOCOL_VERSION, "V5")
            .build());
    try (CqlSession setupSession = SessionUtils.newSession(CCM_RULE, SESSION_RULE.keyspace(), setupSessionLoader)) {

      setupSession.execute(
              SimpleStatement.builder(
                              "CREATE TABLE product_simple(id uuid PRIMARY KEY, description text)")
                      .setExecutionProfile(SESSION_RULE.slowProfile())
                      .build());
    }

    // JAVA-3076: Actual test should continue to use v3 just like it always has
    mapper = new NullSavingStrategyIT_InventoryMapperBuilder(SESSION_RULE.session()).build();
  }

The code snippet above assumes that SESSION_RULE remains identical to what it current is in 4.x.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error isn't coming from the table create in the setup() call but the keyspace creation SessionRule#before() - which is invoked by junit as part of @ClassRule - so I don't the snippet fixes this issue. I'll rework the comments in this file to make that clearer

v3Session =
SessionUtils.newSession(
CCM_RULE,
SESSION_RULE.keyspace(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An interesting question (that I genuinely don't know the answer to)... is this always safe? We're accessing a static field from a static method which presumes that the field will always be initialized before the method is called... even though both are static. This isn't a change in behaviour (the old code did it too)... just something I wondered about.

Copy link
Contributor Author

@hhughes hhughes Jun 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It depends on the junit runner. In this case we're using the default which ends up being ParentRunner. Jumping into the debugger that uses this classBlock() method to determine the order of operation:

If there are any children remaining after filtering and ignoring, construct a statement that will:

  • Apply all ClassRules on the test-class and superclasses.
  • Run all non-overridden @BeforeClass methods on the test-class and superclasses; if any throws an Exception, stop execution and pass the exception on.
  • Run all remaining tests on the test-class.
  • Run all non-overridden @AfterClass methods on the test-class and superclasses: exceptions thrown by previous steps are combined, if necessary, with exceptions from AfterClass methods into a [MultipleFailureException]

https://junit.org/junit4/javadoc/4.13/org/junit/runners/ParentRunner.html#classBlock(org.junit.runner.notification.RunNotifier)

So the order will be CcmRule#before() > SessionRule#before() > NullSavingStrategyIT#setup()

…ust not send frame with WARNING flag for native protocol version < 4

NullSavingStrategyIT.java:
- Remove V3 protocol configuration from class SessionRule
- Create new session configured with V3 protocol in @BeforeClass method to use in tests
Copy link
Contributor

@absurdfarce absurdfarce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems quite a bit clearer with the additional comments providing context... thanks!

@hhughes hhughes merged commit ff4e003 into 4.x Aug 21, 2023
@hhughes hhughes deleted the JAVA-3076 branch August 21, 2023 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants