Unc*_*air 9 unit-testing hive derby scalatest
我在Scala 2.11中使用spark-hive 2.3.0,并设置了一个单元测试框架。spark-hive附带了TestHiveContext,TestHiveSparkSession可以方便地从单元测试中调用Hive,而无需运行Hadoop,Spark或集群,这非常适合自动化测试。
Hive需要一个用于其metastore的数据库,以这种方式运行时,它会将Derby用作嵌入式数据库javax.jdo.option.ConnectionURL,默认配置为jdbc:derby:;databaseName=<file-path>;create=true。该<file-path>是在本地文件系统中的位置,是运行德比一个选项。
另一个选择是在内存中运行Derby,通常就像将此URL更改为一样容易jdbc:derby:memory:databaseName;create=true。但是,Hive无法做到这一点,因为配置是在内部HiveUtils类中进行的,并且不能被覆盖。我曾尝试在Spark Session Builder中对其进行更改,但后来HiveUtils创建我的时,所做的更改就被淹没了TestHiveContext。
在我的情况下,最好使用内存数据库,因为我们的开发人员在Windows上运行(肯定不是我/我们的选择),并且在创建这些文件时,经常会出现诸如权限或文件名中的无效字符之类的问题(因为从未真正打算使用Hadoop)才能在Windows上使用),并且由于无法清理(由于这些问题),这些文件通常会被丢弃。我们希望测试是完全独立的,以便它们可以运行和完成而没有副作用,因此可以在多种环境(开发人员,CI,Jenkins,AWS等)中运行。
有趣的是,我在TestHive.scala:
{ // set the metastore temporary configuration
val metastoreTempConf = HiveUtils.newTemporaryConfiguration(useInMemoryDerby = false) ++ Map(
Run Code Online (Sandbox Code Playgroud)
因此,存在使用内存数据库的标志,但这是不可配置的,并且没有将其设置为的代码路径true。
有什么方法可以配置或编写此文件,以便TestHiveDerby可以在内存中吗?尝试设置的值javax.jdo.option.ConnectionURL通过任蜂房的site.xml或HDFS-site.xml中不工作,我认为这是因为如何TestHive,TestHiveContext和TestHiveSparkSession被初始化,他们有自己的代码路径从非测试路径分开。他们提供的功能对测试框架非常有帮助,但显然没有提供覆盖此值和其他设置的方法。
到目前为止,我能看到的最好的选择是重写或编写我自己的TestHiveContext类,该类从该类中借鉴了很多功能并覆盖了我需要的部分,但是对于我认为可以通过简单配置完成的工作来说,这是一个相对较大的工作更改。
我最终想出了解决方法,并希望分享答案,以防其他人尝试做同样的事情。
我的测试类使用SharedSparkContexttrait,它SparkContext通过var 提供参考sc。
在初始化SparkContext之后(我使用了测试框架中beforeAll可用的钩子scalatest),我创建了一个TestHiveContext类似的代码:
hc = new TestHiveContext(sc, false)
Run Code Online (Sandbox Code Playgroud)
然后紧接着,我可以javax.jdo.option.ConnectionURL像这样设置大概还有其他一些Hadoop和Hive配置:
sc.hadoopConfiguration.set("javax.jdo.option.ConnectionURL",
"jdbc:derby:memory:db;create=true")
Run Code Online (Sandbox Code Playgroud)
Hive使用了此配置参数,但显然必须将其添加到用于构建Hive测试上下文的Hadoop配置中。
诀窍在于时机,必须在Hadoop和Hive初始化自身之后(使用配置文件和诸如此类的东西),同时还要初始化scalatest框架,最后在初始化TestHive框架之后但在运行任何测试之前完成此操作。 。在其他初始化之前尝试设置此参数意味着您的设置将在测试运行之前被覆盖。
| 归档时间: |
|
| 查看次数: |
1052 次 |
| 最近记录: |