Skip to content

Conversation

@wangyum
Copy link
Member

@wangyum wangyum commented Aug 7, 2019

What changes were proposed in this pull request?

This PR build a test framework that directly re-run all the tests in SQLQueryTestSuite via Thrift Server. But it's a little different from SQLQueryTestSuite:

  1. Can not support UDF testing.
  2. Can not support DESC command and SHOW command because SQLQueryTestSuite formatted the output.

When building this framework, found two bug:
SPARK-28624: make_date is inconsistent when reading from table
SPARK-28611: Histogram's height is different

found two features that ThriftServer can not support:
SPARK-28636: ThriftServer can not support decimal type with negative scale
SPARK-28637: ThriftServer can not support interval type

Also, found two inconsistent behavior:
SPARK-28620: Double type returned for float type in Beeline/JDBC
SPARK-28619: The golden result file is different when tested by bin/spark-sql

How was this patch tested?

N/A

@SparkQA
Copy link

SparkQA commented Aug 7, 2019

Test build #108749 has finished for PR 25373 at commit 699b4db.

  • This patch fails due to an unknown error code, -9.
  • This patch merges cleanly.
  • This patch adds no public classes.

@wangyum
Copy link
Member Author

wangyum commented Aug 7, 2019

retest this please

@SparkQA
Copy link

SparkQA commented Aug 7, 2019

Test build #108752 has finished for PR 25373 at commit 699b4db.

  • This patch fails Spark unit tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented Aug 7, 2019

Test build #108760 has finished for PR 25373 at commit 908cdc3.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@wangyum
Copy link
Member Author

wangyum commented Aug 7, 2019

@gatorsmile
Copy link
Member

Can we add the new test suite using their own forked JVMs? I found it is slow. 15 minutes!

@SparkQA
Copy link

SparkQA commented Aug 8, 2019

Test build #108826 has finished for PR 25373 at commit 3f21189.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

Copy link
Contributor

@juliuszsompolski juliuszsompolski left a comment

Choose a reason for hiding this comment

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

@gatorsmile - I assume that starting a new session/connection for every test is intentional for test isolation? It's likely responsible for a big part of the cost of this suite (and original SQLSuite), but I reckon it's necessary to not have it flaky.


private var hiveServer2: HiveThriftServer2 = _

override def beforeEach(): Unit = {
Copy link
Contributor

Choose a reason for hiding this comment

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

How long does it take to start thriftserver?
Would it be possible to start it once in beforeAll?

Copy link
Member Author

Choose a reason for hiding this comment

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

The first time is very slow:

[info] ThriftServerQueryTestSuite:
[info] - group-by.sql !!! IGNORED !!!
Start ThriftServer time: 5599
[info] - natural-join.sql (8 seconds, 404 milliseconds)
Start ThriftServer time: 44
[info] - csv-functions.sql (1 second, 30 milliseconds)
Start ThriftServer time: 34
[info] - except.sql (8 seconds, 354 milliseconds)
Start ThriftServer time: 38
[info] - string-functions.sql (1 second, 281 milliseconds)
Start ThriftServer time: 39
[info] - describe-table-column.sql (2 seconds, 434 milliseconds)
Start ThriftServer time: 81
[info] - random.sql (621 milliseconds)
Start ThriftServer time: 30
[info] - tablesample-negative.sql (485 milliseconds)
Start ThriftServer time: 30
[info] - window.sql (25 seconds, 601 milliseconds)
Start ThriftServer time: 32
[info] - join-empty-relation.sql (632 milliseconds)
Start ThriftServer time: 35
[info] - null-propagation.sql (310 milliseconds)
Start ThriftServer time: 33
[info] - operators.sql (1 second, 683 milliseconds)
Start ThriftServer time: 33
[info] - change-column.sql (504 milliseconds)
Start ThriftServer time: 33
[info] - count.sql (2 seconds, 125 milliseconds)
[info] - decimalArithmeticOperations.sql !!! IGNORED !!!
Start ThriftServer time: 31
[info] - group-analytics.sql (16 seconds, 295 milliseconds)
Start ThriftServer time: 34
[info] - inline-table.sql (430 milliseconds)
Start ThriftServer time: 29
[info] - comparator.sql (240 milliseconds)
Start ThriftServer time: 27

Copy link
Member Author

Choose a reason for hiding this comment

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

hiveServer2 = HiveThriftServer2.startWithContext(sqlContext)
}

private def withJdbcStatement(fs: (Statement => Unit)*) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we keep the connection open, to not have to start a sessopm amd reload the test data into temp views each time?
We could open the connection with conn = DriverManager.getConnection(jdbcUri, user, "") in beforeAll, load the test data there, and then have withJDBCStatement just create new statements, finally closing the connection in afterAll.

However, it seems that opening new connection/session may be by design here, for test isolation. Then we'll have to leave it as is, but I think we should still be able to avoid starting the ThriftServer beforeEach.

Copy link
Member Author

Choose a reason for hiding this comment

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

If move loadTestData to beforeAll. Some tests will fail:
image

@wangyum wangyum changed the title [SPARK-28527][SQL][TEST] Directly re-run all the tests in SQLQueryTestSuite via Thrift Server [SPARK-28527][SQL][TEST] Re-run all the tests in SQLQueryTestSuite via Thrift Server Aug 13, 2019
@SparkQA
Copy link

SparkQA commented Aug 13, 2019

Test build #109036 has finished for PR 25373 at commit 5802888.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

Copy link
Contributor

@juliuszsompolski juliuszsompolski left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks. This really improves coverage and has flushed multiple issues already. Let's get it in :-).
cc @gatorsmile

@gatorsmile
Copy link
Member

Thanks! Merged to master.

@wangyum wangyum deleted the SPARK-28527 branch August 18, 2019 02:42
@dongjoon-hyun
Copy link
Member

dongjoon-hyun commented Aug 18, 2019

Hi, Guys.

This seems to add a new flaky test suite in Maven with hadoop-3.2 profile.

ThriftServerQueryTestSuite:
org.apache.spark.sql.hive.thriftserver.ThriftServerQueryTestSuite *** ABORTED ***
  java.lang.RuntimeException: Unable to load a Suite class that was discovered in the runpath: org.apache.spark.sql.hive.thriftserver.ThriftServerQueryTestSuite

In general, hadoop-3.2 profile is not a blocker, but we are working on a JDK11 PR with Hadoop-3.2. And, it fails due to this. Could you take a look at this?

cc @wangyum, @srowen , @HyukjinKwon .

I'm monitoring the next Jenkins run. If the next run fails consecutively, we had better revert this first and merge this later after testing with Maven with hadoop-3.2 profile.

@dongjoon-hyun
Copy link
Member

I found that this also breaks hadoop-2.7 profile.

ThriftServerQueryTestSuite:
org.apache.spark.sql.hive.thriftserver.ThriftServerQueryTestSuite *** ABORTED ***
  java.lang.RuntimeException: Unable to load a Suite class that was discovered in the runpath: 

Since this breaks all Maven profiles, I'll revert this. Sorry, @wangyum and @gatorsmile . Please make another PR and test with Maven Hadoop-2.7/Hadoop-3.2.

@HyukjinKwon
Copy link
Member

+1 for reverting for now.

@wangyum
Copy link
Member Author

wangyum commented Aug 19, 2019

The reason is that the path is different:
maven:

path: /root/opensource/spark/sql/hive-thriftserver/file:/root/opensource/spark/sql/core/target/spark-sql_2.12-3.0.0-SNAPSHOT-tests.jar!/sql-tests/inputs

sbt:

path: /root/opensource/spark/sql/core/target/scala-2.12/test-classes/sql-tests/inputs
path: /root/opensource/spark/sql/core/target/scala-2.12/test-classes/sql-tests/inputs/subquery
ppath: /root/opensource/spark/sql/core/target/scala-2.12/test-classes/sql-tests/inputs/subquery/negative-cases
path: /root/opensource/spark/sql/core/target/scala-2.12/test-classes/sql-tests/inputs/subquery/exists-subquery
path: /root/opensource/spark/sql/core/target/scala-2.12/test-classes/sql-tests/inputs/subquery/in-subquery
path: /root/opensource/spark/sql/core/target/scala-2.12/test-classes/sql-tests/inputs/subquery/scalar-subquery
path: /root/opensource/spark/sql/core/target/scala-2.12/test-classes/sql-tests/inputs/typeCoercion
path: /root/opensource/spark/sql/core/target/scala-2.12/test-classes/sql-tests/inputs/typeCoercion/native
path: /root/opensource/spark/sql/core/target/scala-2.12/test-classes/sql-tests/inputs/pgSQL
path: /root/opensource/spark/sql/core/target/scala-2.12/test-classes/sql-tests/inputs/ansi
path: /root/opensource/spark/sql/core/target/scala-2.12/test-classes/sql-tests/inputs/udf
path: /root/opensource/spark/sql/core/target/scala-2.12/test-classes/sql-tests/inputs/udf/pgSQL

@srowen
Copy link
Member

srowen commented Aug 19, 2019

PS there is more to the failure:

  Cause: java.lang.NullPointerException:
  at scala.collection.mutable.ArrayOps$ofRef$.newBuilder$extension(ArrayOps.scala:202)
...
  at scala.collection.mutable.ArrayOps$ofRef.partition(ArrayOps.scala:198)
  at org.apache.spark.sql.SQLQueryTestSuite.listFilesRecursively(SQLQueryTestSuite.scala:453)
  at org.apache.spark.sql.hive.thriftserver.ThriftServerQueryTestSuite.listTestCases(ThriftServerQueryTestSuite.scala:207)
...

It does sorta look like it can't list a directory because it's 'empty'? that is listFiles() is null. The subdirs of sql-tests/ are packaged into that -tests JAR though.

Comments in SQLQueryTestSuite suggest that it's known that SBT will have these resources as local files in the classpath (not in the JAR) -- see the comment on baseResourcePath. So, hm, has SBT always worked differently in this regard?

But then I don't know how Maven builds have ever worked for SQLQueryTestSuite as they should use the exact same mechanism? It appears to be running in the failed build, of course.

Weirder still is that it doesn't happen consistently?

Well yeah I think we'd have to revert for now.

@juliuszsompolski
Copy link
Contributor

juliuszsompolski commented Aug 22, 2019

@dongjoon-hyun @srowen @HyukjinKwon @wangyum
Do we have any idea how to fix it?
I personally never used maven build, always sbt, so I have no idea.

@juliuszsompolski
Copy link
Contributor

Just guessing: can it be an issue that for SQLQueryTestSuite, these files were resources in the same project jar, while for ThriftServerQueryTestSuite it needs to pull them from a dependency?

A guess based on https://stackoverflow.com/questions/5292283/use-a-dependencys-resources: maybe changing https://github.com/apache/spark/blob/master/sql/core/src/test/scala/org/apache/spark/sql/SQLQueryTestSuite.scala#L117
getClass.getClassLoader.getResource("sql-tests") to SQLQueryTestSuite.class.getClassLoader.getResource("sql-tests") will work here?

@srowen
Copy link
Member

srowen commented Aug 22, 2019

I doubt those two would be in different classloaders, but, I also don't know what the issue is.

@wangyum
Copy link
Member Author

wangyum commented Aug 22, 2019

Could we skip this test when testing with maven?

   override def listTestCases(): Seq[TestCase] = {
-    listFilesRecursively(new File(inputFilePath)).flatMap { file =>
-      val resultFile = file.getAbsolutePath.replace(inputFilePath, goldenFilePath) + ".out"
-      val absPath = file.getAbsolutePath
-      val testCaseName = absPath.stripPrefix(inputFilePath).stripPrefix(File.separator)
+    // Maven can not get the correct baseResourcePath
+    if (baseResourcePath.exists()) {
+      listFilesRecursively(new File(inputFilePath)).flatMap { file =>
+        val resultFile = file.getAbsolutePath.replace(inputFilePath, goldenFilePath) + ".out"
+        val absPath = file.getAbsolutePath
+        val testCaseName = absPath.stripPrefix(inputFilePath).stripPrefix(File.separator)
 
-      if (file.getAbsolutePath.startsWith(s"$inputFilePath${File.separator}udf")) {
-        Seq.empty
-      } else if (file.getAbsolutePath.startsWith(s"$inputFilePath${File.separator}pgSQL")) {
-        PgSQLTestCase(testCaseName, absPath, resultFile) :: Nil
-      } else {
-        RegularTestCase(testCaseName, absPath, resultFile) :: Nil
+        if (file.getAbsolutePath.startsWith(s"$inputFilePath${File.separator}udf")) {
+          Seq.empty
+        } else if (file.getAbsolutePath.startsWith(s"$inputFilePath${File.separator}pgSQL")) {
+          PgSQLTestCase(testCaseName, absPath, resultFile) :: Nil
+        } else {
+          RegularTestCase(testCaseName, absPath, resultFile) :: Nil
+        }
       }
+    } else {
+      Seq.empty[TestCase]
     }
   }

@dongjoon-hyun
Copy link
Member

Ur, @wangyum . AFAIK, Apache Maven is the official primary Apache Spark project build system. We support sbt, but sbt is not the main.

Could you confirm this, @srowen ?

@srowen
Copy link
Member

srowen commented Aug 22, 2019

Yeah, Maven is the 'build of reference' so I'd hesitate to have any SBT-only tests. I think we'd have to debug and fix it, though I expect this one is subtle and I couldn't figure it out in an hour

HyukjinKwon pushed a commit to HyukjinKwon/spark that referenced this pull request Aug 25, 2019
…a Thrift Server

## What changes were proposed in this pull request?

This PR build a test framework that directly re-run all the tests in `SQLQueryTestSuite` via Thrift Server. But it's a little different from `SQLQueryTestSuite`:
1. Can not support [UDF testing](https://github.com/apache/spark/blob/44e607e9213bdceab970606fb15292db2fe157c2/sql/core/src/test/scala/org/apache/spark/sql/SQLQueryTestSuite.scala#L293-L297).
2. Can not support `DESC` command and `SHOW` command because `SQLQueryTestSuite` [formatted the output](https://github.com/apache/spark/blob/1882912cca4921d3d8c8632b3bb34e69e8119791/sql/core/src/main/scala/org/apache/spark/sql/execution/HiveResult.scala#L38-L50.).

When building this framework, found two bug:
[SPARK-28624](https://issues.apache.org/jira/browse/SPARK-28624): `make_date` is inconsistent when reading from table
[SPARK-28611](https://issues.apache.org/jira/browse/SPARK-28611): Histogram's height is different

found two features that ThriftServer can not support:
[SPARK-28636](https://issues.apache.org/jira/browse/SPARK-28636): ThriftServer can not support decimal type with negative scale
[SPARK-28637](https://issues.apache.org/jira/browse/SPARK-28637): ThriftServer can not support interval type

Also, found two inconsistent behavior:
[SPARK-28620](https://issues.apache.org/jira/browse/SPARK-28620): Double type returned for float type in Beeline/JDBC
[SPARK-28619](https://issues.apache.org/jira/browse/SPARK-28619):  The golden result file is different when tested by `bin/spark-sql`

## How was this patch tested?

N/A

Closes apache#25373 from wangyum/SPARK-28527.

Authored-by: Yuming Wang <[email protected]>
Signed-off-by: gatorsmile <[email protected]>
@HyukjinKwon
Copy link
Member

Thanks for pinging me @juliuszsompolski. One possible solution might be just always users sql-tests from the source by Spark home which is set by default. Seems similar way is already used when SPARK_GENERATE_GOLDEN_FILES is enabled.

Referring spark.home property or SPARK_HOME is a proper way to detect some paths too. I think it's not crazy to use this way. Let me open a PR

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.

7 participants