我有一个简单的火花功能来测试DF窗口:
import org.apache.spark.sql.{DataFrame, SparkSession}
object ScratchPad {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().master("local[*]").getOrCreate()
spark.sparkContext.setLogLevel("ERROR")
get_data_frame(spark).show()
}
def get_data_frame(spark: SparkSession): DataFrame = {
import spark.sqlContext.implicits._
val hr = spark.sparkContext.parallelize(List(
("Steinbeck", "Sales", 100),
("Woolf", "IT", 99),
("Wodehouse", "Sales", 250),
("Hemingway", "IT", 349)
)
).toDF("emp", "dept", "sal")
import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.functions._
val windowspec = Window.partitionBy($"dept").orderBy($"sal".desc)
hr.withColumn("rank", row_number().over(windowspec))
}
}
我写了这样的测试:
import com.holdenkarau.spark.testing.DataFrameSuiteBase
import org.apache.spark.sql.Row
import org.apache.spark.sql.types._
import org.scalatest.FunSuite
class TestDF extends FunSuite with DataFrameSuiteBase {
test ("DFs equal") {
val expected=sc.parallelize(List(
Row("Wodehouse","Sales",250,1),
Row("Steinbeck","Sales",100,2),
Row("Hemingway","IT",349,1),
Row("Woolf","IT",99,2)
))
val schema=StructType(
List(
StructField("emp",StringType,true),
StructField("dept",StringType,true),
StructField("sal",IntegerType,false),
StructField("rank",IntegerType,true)
)
)
val e2=sqlContext.createDataFrame(expected,schema)
val actual=ScratchPad.get_data_frame(sqlContext.sparkSession)
assertDataFrameEquals(e2,actual)
}
}
当我右键单击Intellij中的课程时,可以正常工作,然后单击"运行"。当我使用" SBT测试"进行相同的测试时,它会失败以下:
java.security.AccessControlException: access denied
org.apache.derby.security.SystemPermission( "engine",
"usederbyinternals" )
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
at java.security.AccessController.checkPermission(AccessController.java:884)
at org.apache.derby.iapi.security.SecurityUtil.checkDerbyInternalsPrivilege(Unknown Source)
...
这是我的SBT脚本,没有什么可以构成Hive依赖性的,否则测试不会编译:
name := "WindowingTest"
version := "0.1"
scalaVersion := "2.11.5"
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.2.1"
libraryDependencies += "org.apache.spark" %% "spark-sql" % "2.2.1"
libraryDependencies += "org.apache.spark" %% "spark-hive" % "2.2.1"
libraryDependencies += "com.holdenkarau" %% "spark-testing-base" % "2.2.0_0.8.0" % "test"
Google搜索指出我指向Derby-6648(https://db.apache.org/derby/releases/release-10.12.1.1.cgi)
说:需要更改应用程序在安全管理器下运行德比的用户必须编辑策略文件,并将以下其他权限授予derby.jar,derbynet.jar和derbyoptionaltools.jar:
许可org.apache.derby.security.security.systempermisser"引擎","二手byinternals";
由于我没有明确安装derby(可能由Spark内部使用),我该怎么做?
快速而肮脏的黑客解决问题
System.setSecurityManager(null)
无论如何,它与自动测试有关,也许毕竟不是那么问题;)
如果您正在寻找一种更清洁的方式,则在build.sbt
中:
test in Test := {
System.setSecurityManager(null) // SPARK-22918
(test in Test).value
}
这将应用于所有文件中的所有测试,而无需触摸测试代码。
默认情况下使用两个metastores首先使用一个meta商店服务,其次是默认情况下调用的数据库,并使用derby。因此,我认为您必须使用Hive安装和配置Derby。但是我还没有在您的代码中看到Hive的使用。希望我的答案能帮助您
在测试类中添加此行以禁用Hive为我工作
override implicit def enableHiveSupport: Boolean = false
在这里得到它:
https://github.com/holdenk/spark-testing-base/issues/148
我通过排除了错误的德比版本解决了这个问题,并在 build.sbt
中包括权利:
project.settings(libraryDependencies ++= Seq(
"org.apache.derby" % "derby" % "10.11.1.1" % Test)
.map {
case module if module.name.contains("spark") => module.excludeAll(
ExclusionRule(organization = "org.apache.derby"))
case module => module
})
它不使用黑客。只是手动依赖分辨率。