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
Conversation
a14dfba
to
e996f17
Compare
901f77c
to
2536a09
Compare
@@ -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'"; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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.
de3b187
to
20f8848
Compare
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? |
@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? |
Hi @kingswanwho everything here looks good to me, let's just see if we can replace the |
@@ -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'"; |
There was a problem hiding this comment.
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(...);
}
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
- We can merge this as it is and leave the ClusterTest work for another PR or
- 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.
There was a problem hiding this comment.
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 : )
There was a problem hiding this comment.
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.
222488f
to
b757afc
Compare
b757afc
to
f9e4988
Compare
b888503
to
dac8dff
Compare
056486a
to
3ae2951
Compare
9b9e422
to
993af0e
Compare
|
||
/** | ||
* 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); | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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)?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
8d3b329
to
5b5eaae
Compare
7aad70c
to
829381f
Compare
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. |
Let me see what's gone awry with the Hive tests... |
|
I did think of that and now have, thanks. |
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. |
e66fd2d
to
e1722ab
Compare
I have merged and pushed, it should work well this time : -) |
e1722ab
to
b3bc923
Compare
@jnturton @kingswanwho I'll review once CI passes later today. Looks good so far! |
@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. |
@kingswanwho @jnturton It looks like Java 8 is still not liking the Hive unit tests. |
Hi Charles, Thanks for the remind! Need James' help to investigate. |
b3bc923
to
a0855aa
Compare
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.