Apache Spark 社区使用各种资源来维护社区测试覆盖率。
GitHub Actions 在 Ubuntu 22.04 上提供以下功能。
AppVeyor 在 Windows 上提供以下功能。
Scaleway 在 MacOS 和 Apple Silicon 上提供以下功能。
Spark 的默认构建策略是汇编一个包含所有依赖项的 JAR 文件。这在进行迭代开发时可能很麻烦。在本地开发时,可以创建一个包含所有 Spark 依赖项的汇编 JAR 文件,然后在进行更改时仅重新打包 Spark 本身。
$ build/sbt clean package
$ ./bin/spark-shell
$ export SPARK_PREPEND_CLASSES=true
$ ./bin/spark-shell # Now it's using compiled classes
# ... do some local development ... #
$ build/sbt compile
$ unset SPARK_PREPEND_CLASSES
$ ./bin/spark-shell
# You can also use ~ to let sbt do incremental builds on file changes without running a new sbt session every time
$ build/sbt ~compile
例如,可以使用以下命令构建 Spark Core 模块
$ # sbt
$ build/sbt
> project core
> package
$ # or you can build the spark-core module with sbt directly using:
$ build/sbt core/package
$ # Maven
$ build/mvn package -DskipTests -pl core
在本地开发时,运行单个测试或几个测试通常比运行整个测试套件更方便。
运行单个测试的最快方法是使用 sbt
控制台。保持 sbt
控制台打开并使用它根据需要重新运行测试是最快的。例如,要运行特定项目(例如 core
)中的所有测试,可以使用以下命令
$ build/sbt
> project core
> test
可以使用 testOnly
命令运行单个测试套件。例如,要运行 DAGSchedulerSuite,可以使用以下命令
> testOnly org.apache.spark.scheduler.DAGSchedulerSuite
testOnly
命令接受通配符;例如,也可以使用以下命令运行 DAGSchedulerSuite
> testOnly *DAGSchedulerSuite
或者可以运行调度程序包中的所有测试
> testOnly org.apache.spark.scheduler.*
如果要运行 DAGSchedulerSuite
中的单个测试(例如,名称中包含“SPARK-12345”的测试),可以在 sbt 控制台中运行以下命令
> testOnly *DAGSchedulerSuite -- -z "SPARK-12345"
如果愿意,可以在命令行中运行所有这些命令(但这比使用打开的控制台运行测试要慢)。为此,需要将 testOnly
和以下参数用引号括起来
$ build/sbt "core/testOnly *DAGSchedulerSuite -- -z SPARK-12345"
有关如何使用 sbt 运行单个测试的更多信息,请参阅 sbt 文档。
使用 Maven,可以使用 -DwildcardSuites
标志运行单个 Scala 测试
build/mvn -Dtest=none -DwildcardSuites=org.apache.spark.scheduler.DAGSchedulerSuite test
需要使用 -Dtest=none
来避免运行 Java 测试。有关 ScalaTest Maven 插件的更多信息,请参阅 ScalaTest 文档。
要运行单个 Java 测试,可以使用 -Dtest
标志
build/mvn test -DwildcardSuites=none -Dtest=org.apache.spark.streaming.JavaAPISuite test
要运行单个 PySpark 测试,可以使用 python
目录下的 run-tests
脚本。测试用例位于每个 PySpark 包下的 tests
包中。请注意,如果在 Apache Spark 的 Scala 或 Python 端添加了一些更改,则需要在运行 PySpark 测试之前手动重新构建 Apache Spark,以便应用这些更改。运行 PySpark 测试脚本不会自动构建它。
另外,请注意,在 macOS High Serria+ 上使用 PySpark 时存在一个正在进行的问题。需要将 OBJC_DISABLE_INITIALIZE_FORK_SAFETY
设置为 YES
才能运行某些测试。有关更多详细信息,请参阅 PySpark 问题 和 Python 问题。
要运行特定模块中的测试用例,可以使用以下命令
$ python/run-tests --testnames pyspark.sql.tests.test_arrow
要运行特定类中的测试用例,可以使用以下命令
$ python/run-tests --testnames 'pyspark.sql.tests.test_arrow ArrowTests'
要运行特定类中的单个测试用例,可以使用以下命令
$ python/run-tests --testnames 'pyspark.sql.tests.test_arrow ArrowTests.test_null_conversion'
还可以运行特定模块中的 doctest
$ python/run-tests --testnames pyspark.sql.dataframe
最后,在同一位置还有一个名为 run-tests-with-coverage
的脚本,它会为 PySpark 测试生成覆盖率报告。它接受与 run-tests
相同的参数。
$ python/run-tests-with-coverage --testnames pyspark.sql.tests.test_arrow --python-executables=python
...
Name Stmts Miss Branch BrPart Cover
-------------------------------------------------------------------
pyspark/__init__.py 42 4 8 2 84%
pyspark/_globals.py 16 3 4 2 75%
...
Generating HTML files for PySpark coverage under /.../spark/python/test_coverage/htmlcov
可以通过 /.../spark/python/test_coverage/htmlcov
下的 HTML 文件以可视方式查看覆盖率报告。
请通过 python/run-tests[-with-coverage] --help
检查其他可用选项。
虽然 GitHub Actions 提供了 K8s 单元测试和集成测试覆盖率,但可以在本地运行它。例如,Volcano 批处理调度程序集成测试需要手动完成。有关详细信息,请参阅集成测试文档。
https://github.com/apache/spark/blob/master/resource-managers/kubernetes/integration-tests/README.md
Docker 集成测试由 GitHub Actions 涵盖。但是,可以在本地运行它以加快开发和测试速度。有关详细信息,请参阅 Docker 集成测试文档。
Apache Spark 利用 GitHub Actions,它支持持续集成和广泛的自动化。Apache Spark 存储库为开发者提供了一些 GitHub Actions 工作流程,以便在创建拉取请求之前运行它们。
Apache Spark 存储库提供了一种在 GitHub Actions 中运行基准测试的简便方法。在拉取请求中更新基准测试结果时,建议使用 GitHub Actions 运行并生成基准测试结果,以便在尽可能相同的环境中运行它们。
org.apache.spark.sql.*
。11
。true
,则会立即失败。如果为 false
,则无论成功与否都会运行所有测试。如果在运行 ScalaTest 时出现以下错误
An internal error occurred during: "Launching XYZSuite.scala".
java.lang.NullPointerException
这是由于类路径中的 Scala 库不正确造成的。要解决此问题,请执行以下操作
Build Path | Configure Build Path
添加库 | Scala 库
scala-library-2.10.4.jar - lib_managed\jars
如果出现“Could not find resource path for Web UI: org/apache/spark/ui/static”,则这是由于类路径问题造成的(一些类可能未编译)。要解决此问题,只需从命令行运行测试即可
build/sbt "testOnly org.apache.spark.rdd.SortingSuite"
为了确保二进制兼容性,Spark 使用 MiMa。
在处理问题时,最好在打开拉取请求之前检查更改是否不会引入二进制不兼容性。
可以通过运行以下命令来做到这一点
$ dev/mima
MiMa 报告的二进制不兼容性可能如下所示
[error] method this(org.apache.spark.sql.Dataset)Unit in class org.apache.spark.SomeClass does not have a correspondent in current version
[error] filter with: ProblemFilters.exclude[DirectMissingMethodProblem]("org.apache.spark.SomeClass.this")
如果认为二进制不兼容性是合理的,或者 MiMa 报告了误报(例如,报告的二进制不兼容性与非用户界面 API 有关),则可以通过在 project/MimaExcludes.scala 中添加一个排除项来过滤掉它们,该排除项包含 MiMa 报告中建议的内容以及一个包含正在处理的问题的 JIRA 编号及其标题的注释。
对于上述问题,可以添加以下内容
否则,必须在打开或更新拉取请求之前解决这些不兼容性。通常,MiMa 报告的问题是不言自明的,并且与缺少的成员(方法或字段)有关,必须添加这些成员才能保持二进制兼容性。
Git 提供了一种机制,可以将远程拉取请求提取到自己的本地存储库中。这在审查代码或在本地测试补丁时很有用。如果尚未克隆 Spark Git 存储库,请使用以下命令
$ git clone https://github.com/apache/spark.git
$ cd spark
要启用此功能,需要配置 git 远程存储库以提取拉取请求数据。为此,请修改 Spark 目录内的 .git/config
文件。如果已将远程存储库命名为其他名称,则它可能不是“origin”。
[remote "origin"]
url = [email protected]:apache/spark.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/pull/*/head:refs/remotes/origin/pr/* # Add this line
完成此操作后,可以提取远程拉取请求
# Fetch remote pull requests
$ git fetch origin
# Checkout a remote pull request
$ git checkout origin/pr/112
# Create a local branch from a remote pull request
$ git checkout origin/pr/112 -b new-branch
$ # sbt
$ build/sbt dependencyTree
$ # Maven
$ build/mvn -DskipTests install
$ build/mvn dependency:tree
可以使用 Aaron Davidson 的 IntelliJ Imports Organizer 来帮助组织代码中的导入。可以将其配置为与样式指南中的导入顺序匹配。
要格式化 Scala 代码,请在提交 PR 之前运行以下命令
$ ./dev/scalafmt
默认情况下,此脚本将格式化与 git master 不同的文件。有关更多信息,请参阅 scalafmt 文档,但请使用现有的脚本,而不是本地安装的 scalafmt 版本。
虽然许多 Spark 开发人员在命令行中使用 SBT 或 Maven,但我们最常用的 IDE 是 IntelliJ IDEA。可以免费获得社区版(Apache 提交者可以获得免费的 IntelliJ Ultimate Edition 许可证),并从 Preferences > Plugins
安装 JetBrains Scala 插件。
要为 IntelliJ 创建 Spark 项目,请执行以下操作
文件 -> 导入项目
,找到 Spark 源代码目录,并选择“Maven 项目”。-P[profile name]
启用的相同配置文件。例如,如果要为支持 YARN 的 Hadoop 2.7 开发,请启用配置文件 yarn
和 hadoop-2.7
。这些选择可以通过从“视图”菜单访问“Maven 项目”工具窗口,并展开“配置文件”部分来更改。其他提示
首选项 -> 构建、执行、部署 -> Maven -> Maven 主目录
) 重置为指向更新的 Maven 安装。您也可以使用脚本 build/mvn
首先构建 Spark。如果脚本无法找到足够新的 Maven 安装,它将下载并将最近版本的 Maven 安装到文件夹 build/apache-maven-<version>/
中。/Users/irashid/github/spark/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala
Error:(147, 9) value q is not a member of StringContext
Note: implicit class Evaluate2 is not applicable here because it comes after the application point and it lacks an explicit result type
q"""
^
本部分将向您展示如何使用 IntelliJ 远程调试 Spark。
按照运行 > 编辑配置 > + > 远程 打开默认的远程配置模板:
通常,默认值足以使用。确保您选择侦听远程 JVM 作为调试器模式,并选择正确的 JDK 版本以生成正确的远程 JVM 的命令行参数。
完成配置并保存后。您可以按照运行 > 运行 > Your_Remote_Debug_Name > 调试 启动远程调试过程,并等待 SBT 控制台连接
一般来说,有两个步骤
以下是如何使用 SBT 单元测试触发远程调试的示例。
进入 SBT 控制台
./build/sbt
切换到目标测试所在的项目,例如
sbt > project core
复制粘贴远程 JVM 的命令行参数
sbt > set javaOptions in Test += "-agentlib:jdwp=transport=dt_socket,server=n,suspend=n,address=localhost:5005"
使用 IntelliJ 设置断点,并使用 SBT 运行测试,例如
sbt > testOnly *SparkContextSuite -- -t "Only one SparkContext may be active at a time"
当您在 IntelliJ 控制台中看到“已连接到目标 VM,地址:‘localhost:5005’,传输:‘socket’”时,它应该已成功连接到 IntelliJ。然后,您可以像往常一样在 IntelliJ 中开始调试。
要退出远程调试模式(这样您就不必一直启动远程调试器),请在项目中时在 SBT 控制台中键入“session clear”。
Eclipse 可用于开发和测试 Spark。以下配置已知有效
最简单的方法是从 Scala IDE 下载页面下载 Scala IDE 捆绑包。它预装了 ScalaTest。或者,使用 Scala IDE 更新站点或 Eclipse 市场。
SBT 可以创建 Eclipse .project
和 .classpath
文件。要为每个 Spark 子项目创建这些文件,请使用以下命令
sbt/sbt eclipse
要导入特定项目,例如 spark-core,请选择 文件 | 导入 | 工作区中的现有项目
。不要选择“将项目复制到工作区”。
如果您想在 Scala 2.10 上进行开发,您需要为用于编译 Spark 的确切 Scala 版本配置 Scala 安装。由于 Scala IDE 捆绑了最新版本(目前为 2.10.5 和 2.11.8),您需要在 Eclipse 首选项 -> Scala -> 安装
中添加一个,方法是指向 Scala 2.10.5 发行版的 lib/
目录。完成此操作后,选择所有 Spark 项目并右键单击,选择 Scala -> 设置 Scala 安装
,并指向 2.10.5 安装。这应该清除所有关于无效交叉编译库的错误。现在,干净的构建应该成功。
ScalaTest 可以通过右键单击源文件并选择 以...方式运行 | Scala Test
来执行单元测试。
如果出现 Java 内存错误,可能需要增加 Eclipse 安装目录中 eclipse.ini
中的设置。根据需要增加以下设置
--launcher.XXMaxPermSize
256M
Spark 定期发布其 Maven 工件的 SNAPSHOT 版本,用于主分支和维护分支。要链接到 SNAPSHOT,您需要将 ASF 快照存储库添加到您的构建中。请注意,SNAPSHOT 工件是短暂的,可能会更改或删除。要使用这些,您必须在 https://repository.apache.org/snapshots/ 添加 ASF 快照存储库。
groupId: org.apache.spark
artifactId: spark-core_2.12
version: 3.0.0-SNAPSHOT
以下是使用 YourKit Java Profiler 分析 Spark 应用程序的说明。
/root
):unzip YourKit-JavaProfiler-2017.02-b66.zip
~/spark-ec2/copy-dir /root/YourKit-JavaProfiler-2017.02
~/spark/conf/spark-env.sh
并添加以下行来配置 Spark JVM 以使用 YourKit 分析代理SPARK_DAEMON_JAVA_OPTS+=" -agentpath:/root/YourKit-JavaProfiler-2017.02/bin/linux-x86-64/libyjpagent.so=sampling"
export SPARK_DAEMON_JAVA_OPTS
SPARK_EXECUTOR_OPTS+=" -agentpath:/root/YourKit-JavaProfiler-2017.02/bin/linux-x86-64/libyjpagent.so=sampling"
export SPARK_EXECUTOR_OPTS
~/spark-ec2/copy-dir ~/spark/conf/spark-env.sh
~/spark/bin/stop-all.sh
和 ~/spark/bin/start-all.sh
10001-10010
。要将 YourKit 桌面应用程序连接到远程分析代理,您必须在集群的 EC2 安全组中打开这些端口。为此,请登录 AWS 管理控制台。转到 EC2 部分,然后从页面左侧的“网络和安全”部分选择“安全组”。找到与您的集群相对应的安全组;如果您启动了一个名为 test_cluster
的集群,那么您将需要修改 test_cluster-slaves
和 test_cluster-master
安全组的设置。对于每个组,从列表中选择它,单击“入站”选项卡,并创建一个新的“自定义 TCP 规则”,打开端口范围 10001-10010
。最后,单击“应用规则更改”。确保对两个安全组都执行此操作。注意:默认情况下,spark-ec2
会重复使用安全组:如果您停止此集群并使用相同名称启动另一个集群,您的安全组设置将被重复使用。ec2--.compute-1.amazonaws.com
有关分析代理的完整列表,请参阅完整的 YourKit 文档 启动选项。
通过 SBT 运行 Spark 测试时,将 javaOptions in Test += "-agentpath:/path/to/yjp"
添加到 SparkBuild.scala
以启动启用了 YourKit 分析代理的测试。
分析代理的平台特定路径列在 YourKit 文档 中。
一般来说,ASF 允许使用生成式 AI 工具共同创作的贡献。但是,在提交包含生成内容的补丁时,有一些注意事项。
最重要的是,您需要披露此类工具的使用情况。此外,您有责任确保所用工具的条款和条件与在开源项目中的使用兼容,并且包含生成内容不会构成版权侵犯的风险。
有关详细信息和发展,请参阅 ASF 生成式工具指南。