Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRILL-8117: Upgrade unit tests to the cluster fixture framework #2499

Closed

Conversation

kingswanwho
Copy link
Contributor

@kingswanwho kingswanwho commented Mar 20, 2022

DRILL-8117: DRILL-8117: Upgrade unit tests to the cluster fixture framework

Description

Upgrades various unit tests to the cluster fixture framework and replaces other instances of deprecated code usage.

Methods client.alterSession() and client.alterSystem() run sql silently which would not throw exception, so it doesn't match the purpose for some test cases. And I still keep using run() here for consistence.

For TestInboundImpersonation
Because cluster fixture save client properties even client closed, use a dedicated cluster fixture for each test case to ensure the client fixture has clean properties.

For TestImpersonationMetadata
Only use one cluster from test start to the end will induce buffer overflow. So change BeforeClass to Before to start a new cluster for each test case.

Documentation

N/A

Testing

Existing unit tests.

@@ -156,22 +159,25 @@ public void unauthorizedTarget() throws Exception {

@Test
public void invalidPolicy() throws Exception {
thrownException.expect(new UserExceptionMatcher(UserBitShared.DrillPBError.ErrorType.VALIDATION,
"Invalid impersonation policies."));
String query = "ALTER SYSTEM SET `%s`='%s'";
Copy link
Contributor

Choose a reason for hiding this comment

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

We have methods that do this work: it is very common. Maybe the required clients are not available in this particular test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi Paul,
Greetings to you!
I did this because the UT code in Drill used ExpectedException thrown = ExpectedException.none();
for ExpectedException instantiation.
However the method ExpectedException.none() has been deprecated, so I replaced ExpectedException.none() by Assert.assertThrows as the deprecation notice suggested.
Could you please give some suggestions will be really appreciated.
Best,
Jingchuan

Copy link
Contributor

Choose a reason for hiding this comment

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

Just picking one test file at random, here's an example of the idea: https://github.com/apache/drill/blob/master/exec/java-exec/src/test/java/org/apache/drill/exec/compile/TestLargeFileCompilation.java#L273

It is not about the exception handling, which is fine. It's just about the busy-work of formatting the ALTER SYSTEM SET commands over and over.

Again, without looking closely, I don't know if this test happens to use one of the two clients that have these methods. If not, then you have to do things the tedious way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi Paul, it does really help! I will replace all those hard-code in my PR by client thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@paul-rogers Hi Paul, I am sorry that I dragged this PR out too long. I replaced hard-code to FixtureClient, but UT failed due to the Error:
java.lang.AssertionError: unexpected exception type thrown; expected:<org.apache.drill.common.exceptions.UserException> but was:<java.lang.IllegalStateException> at org.apache.drill.exec.impersonation.TestInboundImpersonation.invalidProxy(TestInboundImpersonation.java:186) Caused by: java.lang.IllegalStateException: org.apache.drill.common.exceptions.UserRemoteException: PERMISSION ERROR: Cannot change option exec.impersonation.inbound_policies in scope SESSION
I think the two clients cannot exist at the same time, so I changed back to the hard-code way.

@kingswanwho kingswanwho force-pushed the clean-up-deprecated-code branch 5 times, most recently from de3b187 to 20f8848 Compare April 17, 2022 18:47
@cgivre
Copy link
Contributor

cgivre commented Jul 8, 2022

Hi @kingswanwho @paul-rogers We're getting ready to release Drill 1.20.2 which is a minor bugfix release. Is this PR ready to be merged and if so should it be included?

@jnturton
Copy link
Contributor

@cgivre, looking over this PR I think it falls closer to cleanup than it does to bugfix. While it no doubt carries only a little regression risk, it also also offers no benefits to stable release users - it's we Drill devs that will benefit from it - so my vote here is that it is not backported and is merged only into master...

@cgivre
Copy link
Contributor

cgivre commented Jul 19, 2022

@cgivre, looking over this PR I think it falls closer to cleanup than it does to bugfix. While it no doubt carries only a little regression risk, it also also offers no benefits to stable release users - it's we Drill devs that will benefit from it - so my vote here is that it is not backported and is merged only into master...

@jnturton I'm fine with that. I guess my question is can we merge it?

@jnturton
Copy link
Contributor

jnturton commented Sep 8, 2022

Hi @kingswanwho everything here looks good to me, let's just see if we can replace the ALTER SYSTEMs with client.alterSystems.

@@ -156,22 +159,25 @@ public void unauthorizedTarget() throws Exception {

@Test
public void invalidPolicy() throws Exception {
thrownException.expect(new UserExceptionMatcher(UserBitShared.DrillPBError.ErrorType.VALIDATION,
"Invalid impersonation policies."));
String query = "ALTER SYSTEM SET `%s`='%s'";
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you try the following here?

client.alterSystem(...);
try {
  // run test
} finally {
  client.resetSystem(...);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jnturton Hi James, the client here inherits from BaseTestQuery, which is DrillClient but not ClientFixture in TestLargeFileCompilation as Paul suggested. DrillClient doesn't have method like client.alterSystem(). BaseTestQuery is deprecated actually, but not marked as deprecated because it is still widely used. The best choice here I think is change base test class from BaseTestQuery to ClusterTest so that we could use client.alterSystem() for clean and compact code style. There are multiple Inheritance levels here, which are TestInboundImpersonation -> BaseTestImpersonation -> PlanTestBase -> BaseTestQuery. Due to PlanTestBase involves many classes. Maybe change BaseTestImpersonation inheritance from PlanTestBase to ClusterTest directly is an easier way. However, this PR mainly focus on the deprecated clean up, but induces more modifications on UT. Is this an appropriate change here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, okay. In that case I think we can go two ways here, since upgrading this test, or family of tests, to ClusterTest could be a significant expansion of PR's scope.

  1. We can merge this as it is and leave the ClusterTest work for another PR or
  2. we can expand the scope here and you can convert BaseTestImpersonation from PlanTestBase to ClusterTest. I believe that ClusterTest offers the plan string matching features in PlanTestBase.

I leave the choice for you to make based on which way you prefer to work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi James, I would like to apply the second way, since this PR has been existing for a while, it doesn't matter to wait for a bit longer : )

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay great! Let's switch this PR to Draft mode to show that you're still busy.

@jnturton jnturton marked this pull request as draft September 13, 2022 15:36
@kingswanwho kingswanwho force-pushed the clean-up-deprecated-code branch 2 times, most recently from b888503 to dac8dff Compare December 28, 2022 10:27
@kingswanwho kingswanwho force-pushed the clean-up-deprecated-code branch 5 times, most recently from 056486a to 3ae2951 Compare January 17, 2023 03:32
@kingswanwho kingswanwho force-pushed the clean-up-deprecated-code branch 2 times, most recently from 9b9e422 to 993af0e Compare January 31, 2023 06:52
Comment on lines 135 to 186

/**
* Utility method which tests given query produces a {@link UserException} and the exception message contains
* the given message.
* @param testSqlQuery Test query
* @param expectedErrorMsg Expected error message.
*/
protected static void errorMsgTestHelper(String testSqlQuery, String expectedErrorMsg) throws Exception {
try {
run(testSqlQuery);
fail("Expected a UserException when running " + testSqlQuery);
} catch (UserException actualException) {
try {
assertThat("message of UserException when running " + testSqlQuery, actualException.getMessage(), containsString(expectedErrorMsg));
} catch (AssertionError e) {
e.addSuppressed(actualException);
throw e;
}
}
}

protected static void updateClient(Properties properties) {
if (client != null) {
client.close();
client = null;
}
ClientFixture.ClientBuilder clientBuilder = cluster.clientBuilder();
if (properties != null) {
for (final String key : properties.stringPropertyNames()) {
final String lowerCaseKey = key.toLowerCase();
clientBuilder.property(lowerCaseKey, properties.getProperty(key));
}
}
client = clientBuilder.build();
}

protected static void updateClient(final String user) {
updateClient(user, null);
}

protected static void updateClient(final String user, final String password) {
if (client != null) {
client.close();
client = null;
}
final Properties properties = new Properties();
properties.setProperty(DrillProperties.USER, user);
if (password != null) {
properties.setProperty(DrillProperties.PASSWORD, password);
}
updateClient(properties);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's move these additions to ClientFixture. It will mean that they're no longer drop-in replacements but they'll be more at home there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi James, ClientFixture doesn't have a client variable there, so that we could't close client at first and we need to change updateClient signature from void to return ClientFixture, besides due to cluster variable here is none static, we also need to change updateClient from static method to none static method, and those modifications involve lots of code change. Furthermore, there are still lots of test cases that we could just update client without restart cluster, and for those cases that do need restart cluster, we could use startCluster method to config new cluster and client at same time without using updateClient. So maybe we could still keep those code here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, yes you're right. These methods still look a bit out of place. Can errorMsgTestHelper move to ClientFixture? And can the new updateClient methods be replaced by usage of cluster.addClientFixture(Properties p) and cluster.client(int number)?

Copy link
Contributor

Choose a reason for hiding this comment

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

Let me test out a couple of things out locally. If they work I'll send a PR to you, otherwise we'll be ready to merge as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks James! I have tried cluster.addClientFixture(), due to this method doesn't copy all the client properties from ClusterFixture, so after create a new ClientFixture, it still has problem to connect with ClusterFixture. And I also tried to modify updateClient method signature to return a ClientFixture, however due to the ClusterFixture and ClientFixture started by startCluster() are hold by two static variables, and updateClient should be a non-static method to refactor into ClientFixture, seems a non-static method return a value to static variable made some errors here, and I am still figuring it out. I think the feasible way should be started ClientFixture and ClusterFixture separately in each test case, so that those two variables are both non-static. The drawback here is the code change should be a little too much, but I can submit a commit to see whether it works

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi James, I pushed a new commit which refactor updateClient from ClusterTest to ClientFixture.

@kingswanwho kingswanwho force-pushed the clean-up-deprecated-code branch 3 times, most recently from 8d3b329 to 5b5eaae Compare February 7, 2023 02:34
@kingswanwho kingswanwho force-pushed the clean-up-deprecated-code branch 5 times, most recently from 7aad70c to 829381f Compare February 13, 2023 10:15
@jnturton jnturton requested a review from cgivre February 13, 2023 10:19
@jnturton
Copy link
Contributor

I think this one is licked! I've requested a review from @cgivre to get it a once over from a pair of eyes belonging to a non-author.

@jnturton
Copy link
Contributor

Let me see what's gone awry with the Hive tests...

@cgivre
Copy link
Contributor

cgivre commented Feb 13, 2023

Let me see what's gone awry with the Hive tests...
@jnturton Did you do a rebase with DRILL-8398 and DRILL-8400?

@jnturton
Copy link
Contributor

@jnturton Did you do a rebase with DRILL-8398 and DRILL-8400?

I did think of that and now have, thanks.

@jnturton
Copy link
Contributor

The Hive unit tests are quite problematic for me locally due to more problems than you'd expect when I try to do test runs under JDK 8. Anyway, I think that I've fixed the two broken Hive impersonation tests and rebased on master in this new PR to your branch.

@kingswanwho kingswanwho force-pushed the clean-up-deprecated-code branch 2 times, most recently from e66fd2d to e1722ab Compare February 13, 2023 16:21
@kingswanwho
Copy link
Contributor Author

The Hive unit tests are quite problematic for me locally due to more problems than you'd expect when I try to do test runs under JDK 8. Anyway, I think that I've fixed the two broken Hive impersonation tests and rebased on master in this new PR to your branch.

I have merged and pushed, it should work well this time : -)

@cgivre
Copy link
Contributor

cgivre commented Feb 13, 2023

@jnturton @kingswanwho I'll review once CI passes later today. Looks good so far!

@cgivre
Copy link
Contributor

cgivre commented Feb 13, 2023

@kingswanwho Looks like we're still getting some errors on the Hive unit tests. I'm rerunning to see if it was a fluke or not.

@cgivre
Copy link
Contributor

cgivre commented Feb 14, 2023

@kingswanwho @jnturton It looks like Java 8 is still not liking the Hive unit tests.

@kingswanwho
Copy link
Contributor Author

kingswanwho commented Feb 14, 2023

Hi Charles, Thanks for the remind! Need James' help to investigate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants