-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
HIVE-25667: Unify code managing JDBC databases in tests #2919
Conversation
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.
Many thanks for picking this up @mbathori-cloudera ! I went quickly over the PR and left a few comments.
import java.util.List; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
public abstract class AbstractDatabase extends ExternalResource { |
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.
Do we want to keep this dependent to ExternalResource
and junit APis in general?
@@ -0,0 +1,302 @@ | |||
package org.apache.hadoop.hive.metastore.dbinstall; |
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.
Isn't hive-testutils
module a better place for keeping these classes since they are not only used in the metastore-server
?
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.
Yes I felt that the metastore isn’t the right place for this class but didn't know where should it be, I’ll move it into the hive-testutils module.
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.
The hive-testutils
module seems to be the right place for this classes we should be careful though not to create circular dependencies between hive-testutils and metastore modules.
public void install() { | ||
createUser(); | ||
installLatest(); | ||
} | ||
|
||
public int createUser() { | ||
return new MetastoreSchemaTool().setVerbose(verbose).run(new String[] { | ||
"-createUser", | ||
"-dbType", getDbType(), | ||
"-userName", getDbRootUser(), | ||
"-passWord", getDbRootPassword(), | ||
"-hiveUser", getHiveUser(), | ||
"-hivePassword", getHivePassword(), | ||
"-hiveDb", getDb(), | ||
"-url", getInitialJdbcUrl(), | ||
"-driver", getJdbcDriver() | ||
}); | ||
} | ||
|
||
public int installLatest() { | ||
return new MetastoreSchemaTool().setVerbose(verbose).run(new String[] { | ||
"-initSchema", | ||
"-dbType", getDbType(), | ||
"-userName", getHiveUser(), | ||
"-passWord", getHivePassword(), | ||
"-url", getJdbcUrl(), | ||
"-driver", getJdbcDriver(), | ||
"-verbose" | ||
}); | ||
} | ||
|
||
public int installAVersion(String version) { | ||
return new MetastoreSchemaTool().setVerbose(verbose).run(new String[] { | ||
"-initSchemaTo", version, | ||
"-dbType", getDbType(), | ||
"-userName", getHiveUser(), | ||
"-passWord", getHivePassword(), | ||
"-url", getJdbcUrl(), | ||
"-driver", getJdbcDriver() | ||
}); | ||
} | ||
|
||
public int upgradeToLatest() { | ||
return new MetastoreSchemaTool().setVerbose(verbose).run(new String[] { | ||
"-upgradeSchema", | ||
"-dbType", getDbType(), | ||
"-userName", getHiveUser(), | ||
"-passWord", getHivePassword(), | ||
"-url", getJdbcUrl(), | ||
"-driver", getJdbcDriver() | ||
}); | ||
} | ||
|
||
public int validateSchema() { | ||
return new MetastoreSchemaTool().setVerbose(verbose).run(new String[] { | ||
"-validate", | ||
"-dbType", getDbType(), | ||
"-userName", getHiveUser(), | ||
"-passWord", getHivePassword(), | ||
"-url", getJdbcUrl(), | ||
"-driver", getJdbcDriver() | ||
}); | ||
} |
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.
Possibly we could do this in separate refactoring/jira but these methods are not necessary for all consumers of this API so we could put them in a separate class/interface.
@@ -63,7 +64,8 @@ public String getJdbcDriver() { | |||
|
|||
@Override | |||
public String getJdbcUrl(String hostAddress) { | |||
return "jdbc:sqlserver://" + hostAddress + ":1433;DatabaseName=" + HIVE_DB + ";"; | |||
//Mssql doesn't support database parameter in docker |
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.
I don't understand what the comment means. Can you elaborate more?
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.
The Mssql docker init doesn’t have database parameter for initialisation like postgres/mysql etc. so the initial jdbc connection should go to default url if the database was created with docker database argument.(microsoft/mssql-docker#2)
@Override | ||
public void before() throws Exception { | ||
launchDockerContainer(); | ||
MetastoreSchemaTool.setHomeDirForTesting(); | ||
} | ||
|
||
@Override | ||
public void after() { | ||
if ("true".equalsIgnoreCase(System.getProperty("metastore.itest.no.stop.container"))) { | ||
LOG.warn("Not stopping container " + getDockerContainerName() + " at user request, please " | ||
+ "be sure to shut it down before rerunning the test."); | ||
return; | ||
} | ||
try { | ||
cleanupDockerContainer(); | ||
} catch (InterruptedException | IOException e) { | ||
e.printStackTrace(); | ||
} | ||
} |
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.
Possibly these methods can go to those classes using this class as a rule. Another alternative would be to create a rule class which wraps an instance of AbstractDatabase
and provides these methods.
|
||
@Override | ||
public List<String> getDockerBaseArgs() { | ||
return new ArrayList(Arrays.asList("-p", "3309:3306", |
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.
Why are we wrapping into ArrayList? Are we going to modify the list? Keeping things immutable makes the code easier to understand and use.
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.
I was wrapping this because further database argumentum can be added in the AbstractDatabase class, so the list can’t be immutable. The AbstractDatabse.getDockerAdditionalArgs()
method can modify the list.
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.
I think that we could create a new list inside AbstractDatabse.getDockerAdditionalArgs()
if necessary instead of modifying those that we obtain from the getters.
@@ -42,7 +46,7 @@ public String getDockerImageName() { | |||
} | |||
|
|||
@Override | |||
public String[] getDockerAdditionalArgs() { | |||
public List<String> getDockerBaseArgs() { | |||
return null; |
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.
Effective Java Item 43: Return empty arrays or collections, not nulls
...astore-server/src/test/java/org/apache/hadoop/hive/metastore/dbinstall/AbstractDatabase.java
Outdated
Show resolved
Hide resolved
-Moved common database classes to hive-testutils -Moved metastore related parts from common database classes to wrapper class in metastore -Removed ExternalResource and refactored depending functions
@zabetak Thanks for reviewing my changes. I made a new commit where I tried to address all of your comments.
Some note for the hive-testutil pom changes: |
It seems like the metastore verify stage is failing in the pipeline because I refactored the DbInstall tests and it still tries to run the ITestDerby,ITestMysql and ITestPostgres but they don’t exist anymore. All of these tests are now running in ITestDbInstall. I’m not sure if the pipeline needs to be adjusted to the changes or should I restore the original form of these tests. |
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
Hey bot please keep this PR open! |
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
What changes were proposed in this pull request?
Currently there are two class hierarchies managing JDBC databases in tests, DatabaseRule and AbstractExternalDB. These changes meant to unify these database related functionalities and get rid of the duplicated codes.
Why are the changes needed?
The current solution is redundant, contains a lot of code duplications. The unified database handling gives easier extensibility and modification.
Does this PR introduce any user-facing change?
No
How was this patch tested?
All the previous tests that were covering the affected database functionality are passing with the same expected results.