@@ -22,6 +22,7 @@ import org.scalatest.BeforeAndAfterEach
2222import org .apache .spark .SparkFunSuite
2323import org .apache .spark .sql .AnalysisException
2424import org .apache .spark .sql .catalyst .{FunctionIdentifier , TableIdentifier }
25+ import org .apache .spark .util .Utils
2526
2627
2728/**
@@ -30,23 +31,10 @@ import org.apache.spark.sql.catalyst.{FunctionIdentifier, TableIdentifier}
3031 * Implementations of the [[ExternalCatalog ]] interface can create test suites by extending this.
3132 */
3233abstract class CatalogTestCases extends SparkFunSuite with BeforeAndAfterEach {
33- private lazy val storageFormat = CatalogStorageFormat (
34- locationUri = None ,
35- inputFormat = Some (tableInputFormat),
36- outputFormat = Some (tableOutputFormat),
37- serde = None ,
38- serdeProperties = Map .empty)
39- private lazy val part1 = CatalogTablePartition (Map (" a" -> " 1" , " b" -> " 2" ), storageFormat)
40- private lazy val part2 = CatalogTablePartition (Map (" a" -> " 3" , " b" -> " 4" ), storageFormat)
41- private lazy val part3 = CatalogTablePartition (Map (" a" -> " 5" , " b" -> " 6" ), storageFormat)
42- private val funcClass = " org.apache.spark.myFunc"
43-
44- // Things subclasses should override
45- protected val tableInputFormat : String = " org.apache.park.serde.MyInputFormat"
46- protected val tableOutputFormat : String = " org.apache.park.serde.MyOutputFormat"
47- protected def newUriForDatabase (): String = " uri"
34+ protected val utils : CatalogTestUtils
35+ import utils ._
36+
4837 protected def resetState (): Unit = { }
49- protected def newEmptyCatalog (): ExternalCatalog
5038
5139 // Clear all state after each test
5240 override def afterEach (): Unit = {
@@ -57,63 +45,6 @@ abstract class CatalogTestCases extends SparkFunSuite with BeforeAndAfterEach {
5745 }
5846 }
5947
60- /**
61- * Creates a basic catalog, with the following structure:
62- *
63- * default
64- * db1
65- * db2
66- * - tbl1
67- * - tbl2
68- * - part1
69- * - part2
70- * - func1
71- */
72- private def newBasicCatalog (): ExternalCatalog = {
73- val catalog = newEmptyCatalog()
74- // When testing against a real catalog, the default database may already exist
75- catalog.createDatabase(newDb(" default" ), ignoreIfExists = true )
76- catalog.createDatabase(newDb(" db1" ), ignoreIfExists = false )
77- catalog.createDatabase(newDb(" db2" ), ignoreIfExists = false )
78- catalog.createTable(" db2" , newTable(" tbl1" , " db2" ), ignoreIfExists = false )
79- catalog.createTable(" db2" , newTable(" tbl2" , " db2" ), ignoreIfExists = false )
80- catalog.createPartitions(" db2" , " tbl2" , Seq (part1, part2), ignoreIfExists = false )
81- catalog.createFunction(" db2" , newFunc(" func1" , Some (" db2" )))
82- catalog
83- }
84-
85- private def newFunc (): CatalogFunction = newFunc(" funcName" )
86-
87- private def newDb (name : String ): CatalogDatabase = {
88- CatalogDatabase (name, name + " description" , newUriForDatabase(), Map .empty)
89- }
90-
91- private def newTable (name : String , db : String ): CatalogTable = {
92- CatalogTable (
93- name = TableIdentifier (name, Some (db)),
94- tableType = CatalogTableType .EXTERNAL_TABLE ,
95- storage = storageFormat,
96- schema = Seq (CatalogColumn (" col1" , " int" ), CatalogColumn (" col2" , " string" )),
97- partitionColumns = Seq (CatalogColumn (" a" , " int" ), CatalogColumn (" b" , " string" )))
98- }
99-
100- private def newFunc (name : String , database : Option [String ] = None ): CatalogFunction = {
101- CatalogFunction (FunctionIdentifier (name, database), funcClass)
102- }
103-
104- /**
105- * Whether the catalog's table partitions equal the ones given.
106- * Note: Hive sets some random serde things, so we just compare the specs here.
107- */
108- private def catalogPartitionsEqual (
109- catalog : ExternalCatalog ,
110- db : String ,
111- table : String ,
112- parts : Seq [CatalogTablePartition ]): Boolean = {
113- catalog.listPartitions(db, table).map(_.spec).toSet == parts.map(_.spec).toSet
114- }
115-
116-
11748 // --------------------------------------------------------------------------
11849 // Databases
11950 // --------------------------------------------------------------------------
@@ -556,3 +487,86 @@ abstract class CatalogTestCases extends SparkFunSuite with BeforeAndAfterEach {
556487 }
557488
558489}
490+
491+
492+ /**
493+ * A collection of utility fields and methods for tests related to the [[ExternalCatalog ]].
494+ */
495+ abstract class CatalogTestUtils {
496+
497+ // Unimplemented methods
498+ val tableInputFormat : String
499+ val tableOutputFormat : String
500+ def newEmptyCatalog (): ExternalCatalog
501+
502+ // These fields must be lazy because they rely on fields that are not implemented yet
503+ lazy val storageFormat = CatalogStorageFormat (
504+ locationUri = None ,
505+ inputFormat = Some (tableInputFormat),
506+ outputFormat = Some (tableOutputFormat),
507+ serde = None ,
508+ serdeProperties = Map .empty)
509+ lazy val part1 = CatalogTablePartition (Map (" a" -> " 1" , " b" -> " 2" ), storageFormat)
510+ lazy val part2 = CatalogTablePartition (Map (" a" -> " 3" , " b" -> " 4" ), storageFormat)
511+ lazy val part3 = CatalogTablePartition (Map (" a" -> " 5" , " b" -> " 6" ), storageFormat)
512+ lazy val funcClass = " org.apache.spark.myFunc"
513+
514+ /**
515+ * Creates a basic catalog, with the following structure:
516+ *
517+ * default
518+ * db1
519+ * db2
520+ * - tbl1
521+ * - tbl2
522+ * - part1
523+ * - part2
524+ * - func1
525+ */
526+ def newBasicCatalog (): ExternalCatalog = {
527+ val catalog = newEmptyCatalog()
528+ // When testing against a real catalog, the default database may already exist
529+ catalog.createDatabase(newDb(" default" ), ignoreIfExists = true )
530+ catalog.createDatabase(newDb(" db1" ), ignoreIfExists = false )
531+ catalog.createDatabase(newDb(" db2" ), ignoreIfExists = false )
532+ catalog.createTable(" db2" , newTable(" tbl1" , " db2" ), ignoreIfExists = false )
533+ catalog.createTable(" db2" , newTable(" tbl2" , " db2" ), ignoreIfExists = false )
534+ catalog.createPartitions(" db2" , " tbl2" , Seq (part1, part2), ignoreIfExists = false )
535+ catalog.createFunction(" db2" , newFunc(" func1" , Some (" db2" )))
536+ catalog
537+ }
538+
539+ def newFunc (): CatalogFunction = newFunc(" funcName" )
540+
541+ def newUriForDatabase (): String = Utils .createTempDir().getAbsolutePath
542+
543+ def newDb (name : String ): CatalogDatabase = {
544+ CatalogDatabase (name, name + " description" , newUriForDatabase(), Map .empty)
545+ }
546+
547+ def newTable (name : String , db : String ): CatalogTable = {
548+ CatalogTable (
549+ name = TableIdentifier (name, Some (db)),
550+ tableType = CatalogTableType .EXTERNAL_TABLE ,
551+ storage = storageFormat,
552+ schema = Seq (CatalogColumn (" col1" , " int" ), CatalogColumn (" col2" , " string" )),
553+ partitionColumns = Seq (CatalogColumn (" a" , " int" ), CatalogColumn (" b" , " string" )))
554+ }
555+
556+ def newFunc (name : String , database : Option [String ] = None ): CatalogFunction = {
557+ CatalogFunction (FunctionIdentifier (name, database), funcClass)
558+ }
559+
560+ /**
561+ * Whether the catalog's table partitions equal the ones given.
562+ * Note: Hive sets some random serde things, so we just compare the specs here.
563+ */
564+ def catalogPartitionsEqual (
565+ catalog : ExternalCatalog ,
566+ db : String ,
567+ table : String ,
568+ parts : Seq [CatalogTablePartition ]): Boolean = {
569+ catalog.listPartitions(db, table).map(_.spec).toSet == parts.map(_.spec).toSet
570+ }
571+
572+ }
0 commit comments