测试Azure WASB客户端

该模块包含单元测试和集成测试。单元测试可以独立运行,无需连接Azure存储服务;而集成测试则需要有效连接以与容器交互。单元测试套件遵循命名规范Test*.java,集成测试则遵循ITest*.java命名规范。

影响hadoop-azure模块的补丁提交策略

Apache Jenkins基础设施不运行任何云集成测试,因为需要确保凭证安全。

任何补丁的提交者都需要运行所有集成测试,并声明他们使用的Azure区域。

重要提示:未包含此声明的补丁将被忽略

该策略已被证明是保证代码变更完全回归测试的唯一机制。为什么需要声明区域?有两个原因

  1. 它帮助我们识别仅针对特定端点出现的回归问题。
  2. 它迫使提交者在测试方面更加诚实。撒谎说"是的,我测试过这个"很容易。但要说"是的,我在Azure美国西部区域测试过这个"就是个更具体的谎言,更难编造。而且,如果被发现撒谎:你在项目中的所有信誉都会丧失。

您无需从Azure基础设施内的虚拟机进行测试,只需提供凭据即可。

运行测试既不困难也不昂贵;如果你不能运行测试,就无法保证你的补丁有效。评审人员已经有足够多的工作要做,没有时间进行这些测试,尤其是每次失败都会导致开发迭代变得缓慢。

Please: run the tests. And if you don’t, we are sorry for declining your patch, but we have to.

如果测试出现间歇性故障怎么办?

某些测试会间歇性失败,特别是在并行运行时。如果发生这种情况,可以尝试单独运行该测试以查看是否成功。

如果仍然失败,请在您的声明中包含这一事实。我们知道某些测试偶尔不可靠。

如果测试因网络连接超时或失败怎么办?

这些测试设计为可配置不同的超时时间。如果您发现问题且此配置无效,这表明配置机制尚不完善。如果在生产代码中出现这种情况,可能预示着在长距离连接中会出现问题。请帮助我们识别并修复这些问题——尤其是您最适合验证修复是否有效。

设置测试

测试 hadoop-azure 模块

hadoop-azure模块包含完整的单元测试套件。许多测试只需运行mvn test即可执行,无需额外配置。这包括针对模拟存储的测试,即Azure Storage的内存模拟实现。

集成测试旨在直接针对Azure存储服务进行测试,需要账户和凭证才能运行。

这通过创建文件到src/test/resources/azure-auth-keys.xml并设置存储账户名称及其访问密钥来完成。

例如:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>fs.azure.wasb.account.name</name>
    <value>{ACCOUNTNAME}.blob.core.windows.net</value>
  </property>
  <property>
    <name>fs.azure.account.key.{ACCOUNTNAME}.blob.core.windows.net</name>
    <value>{ACCOUNT ACCESS KEY}</value>
  </property>
</configuration>

要运行合约测试,请在src/test/resources/azure-auth-keys.xml中设置WASB文件系统URI和账户访问密钥。例如:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>fs.contract.test.fs.wasb</name>
    <value>wasb://{CONTAINERNAME}@{ACCOUNTNAME}.blob.core.windows.net</value>
    <description>The name of the azure file system for testing.</description>
  </property>
  <property>
    <name>fs.azure.account.key.{ACCOUNTNAME}.blob.core.windows.net</name>
    <value>{ACCOUNT ACCESS KEY}</value>
  </property>
</configuration>

总体而言,要使用mvn test运行所有测试,示例azure-auth-keys.xml如下所示:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>fs.azure.wasb.account.name</name>
    <value>{ACCOUNTNAME}.blob.core.windows.net</value>
  </property>
  <property>
    <name>fs.azure.account.key.{ACCOUNTNAME}.blob.core.windows.net</name>
    <value>{ACCOUNT ACCESS KEY}</value>
  </property>
  <property>
    <name>fs.contract.test.fs.wasb</name>
    <value>wasb://{CONTAINERNAME}@{ACCOUNTNAME}.blob.core.windows.net</value>
  </property>
</configuration>

请勿将azure-auth-keys.xml添加到版本控制系统中。您的Azure存储账户密钥属于机密信息,严禁共享。

运行测试

完成配置后,通过Maven执行测试运行。

mvn -T 1C clean verify

还可以通过在命令行传递parallel-tests=wasb|abfs|both属性来并行执行多个测试套件。这些测试大部分时间都阻塞在网络I/O上,因此并行运行往往能更快完成完整的测试运行。

mvn -T 1C -Dparallel-tests=both clean verify
mvn -T 1C -Dparallel-tests=wasb clean verify
mvn -T 1C -Dparallel-tests=abfs clean verify

-Dparallel-tests=wasb 运行来自azure目录的WASB相关集成测试
-Dparallel-tests=abfs 运行来自azurebfs目录的ABFS相关集成测试
-Dparallel-tests=both 同时运行来自azure和azurebfs目录的所有集成测试

某些测试必须独占访问存储容器运行,因此即使设置了parallel-tests属性,多个测试套件仍将在并行测试完成后,在单独的Maven执行步骤中串行运行。

默认情况下,parallel-tests会并行运行4个测试套件。可以通过传递testsThreadCount属性来调整这个数值。

mvn -T 1C -Dparallel-tests -DtestsThreadCount=8 clean verify
mvn -T 1C clean test

mvn -T 1C -Dparallel-tests clean test

mvn -T 1C -Dparallel-tests -DtestsThreadCount=8 clean test

要仅运行特定命名的测试子集,对于单元测试请传递test属性,对于集成测试请传递it.test属性。

mvn -T 1C clean test -Dtest=TestRollingWindowAverage

mvn -T 1C clean verify -Dscale -Dit.test=ITestFileSystemOperationExceptionMessage -Dtest=none

mvn -T 1C clean verify -Dtest=none -Dit.test=ITest*

注意

  1. 当运行特定的测试子集时,传入testit.test的模式会覆盖配置中关于哪些测试需要在单独的串行阶段隔离运行的要求(如上所述)。这可能导致不可预测的结果,因此建议避免同时传递parallel-teststestit.test。如果您确定只指定了可以安全并行运行的测试,那么它将正常工作。对于宽泛的模式,如上面所示的ITest*,可能会导致不可预测的测试失败。

  2. 命令行shell可能会尝试扩展测试模式中的“*”符号,有时还包括“#”符号。在这种情况下,需要使用“\”前缀进行转义。例如:

      mvn -T 1C clean verify -Dtest=none -Dit.test=ITest\*
    

查看结果

Integration test results and logs are stored in target/failsafe-reports/. An HTML report can be generated during site generation, or with the surefire-report plugin:

# for the unit tests
mvn -T 1C surefire-report:report-only

# for the integration tests
mvn -T 1C surefire-report:failsafe-report-only

# all reports for this module
mvn -T 1C site:site

规模测试

有一组专门用于测试文件系统客户端在大规模下的可扩展性和性能的测试,称为规模测试。测试内容包括:创建和遍历目录树、上传大文件、重命名文件、删除文件、在文件中查找定位、执行随机IO操作等。这使得它们成为基准测试的基础组成部分。

从本质上讲,它们速度很慢。而且,由于它们的执行时间通常受限于运行测试的计算机与Azure端点之间的带宽,并行执行并不能加快这些测试的速度。

启用规模测试

如果Maven构建中设置了scale属性,则会启用测试,无论是否使用了并行测试配置文件都可以这样做

mvn -T 1C verify -Dscale

mvn -T 1C verify -Dparallel-tests -Dscale -DtestsThreadCount=8

最占用带宽的测试(那些上传数据的测试)总是按顺序运行;由于HTTPS设置成本或服务器端操作而较慢的测试则包含在并行测试集中。

规模测试调优选项

部分测试可以通过Maven构建或运行测试时使用的配置文件进行调整。

mvn -T 1C verify -Dparallel-tests -Dscale -DtestsThreadCount=8 -Dfs.azure.scale.test.huge.filesize=128M

该算法是

  1. 该值从配置文件中查询,如果未设置则使用默认值。
  2. 该值是从JVM系统属性中查询获取的,由maven传递下来。
  3. 如果系统属性为null、空字符串或其值为unset,则使用配置值。unset选项用于解决maven属性传播中的一个特殊问题

只有少数属性可以通过这种方式设置;未来会添加更多。

属性 含义
fs.azure.scale.test.huge.filesize Size for huge file uploads
fs.azure.scale.test.huge.huge.partitionsize Size for partitions in huge file uploads

文件和分区大小是带有k/m/g/t/p后缀的数值,具体取决于所需大小。例如:128M、128m、2G、2G、4T甚至1P。

规模测试配置选项

一些规模测试会执行多项操作(例如创建多个目录)。

要执行的操作的确切数量可在选项scale.test.operation.count中配置

<property>
  <name>scale.test.operation.count</name>
  <value>10</value>
</property>

较大的值会产生更大的负载,建议在本地测试或批量运行时使用。

较小的值会加快测试运行速度,尤其是当对象存储距离较远时。

对目录进行操作的功能有一个单独的选项:用于控制创建递归目录时的测试宽度和深度。数值越大,创建的目录数量会呈指数级增长,从而影响性能。

<property>
  <name>scale.test.directory.count</name>
  <value>2</value>
</property>

针对Azure支持的DistCp测试支持可配置的文件大小。默认值为10 MB,但配置值以KB表示,以便可以调整得更小以实现更快的测试运行。

<property>
  <name>scale.test.distcp.file.size.kb</name>
  <value>10240</value>
</property>

Azure特定的扩展测试属性包括

fs.azure.scale.test.huge.filesize: "大文件测试"的大小,单位为MB。

Huge File测试验证了Azure存储处理大文件的能力——属性fs.azure.scale.test.huge.filesize声明了要使用的文件大小。

<property>
  <name>fs.azure.scale.test.huge.filesize</name>
  <value>200M</value>
</property>

这种规模的测试速度较慢:最好从运行在存储端点所在的云基础设施中的主机上执行。

使用模拟器

可以选择针对Azure Storage Emulator运行一系列测试,该模拟器能高度逼真地模拟实时Azure存储环境。该模拟器足以进行高可信度的测试。该模拟器是一个可在本地机器上运行的Windows可执行程序。

要使用模拟器,请安装Azure SDK 2.3并启动存储模拟器。然后编辑src/test/resources/azure-test.xml并添加以下属性:

<property>
  <name>fs.azure.test.emulator</name>
  <value>true</value>
</property>

在使用模拟器运行测试时存在一个已知问题。您可能会看到以下失败消息:

com.microsoft.windowsazure.storage.StorageException: The value for one of the HTTP headers is not in the correct format.

要解决此问题,请重新启动Azure模拟器。确保其版本为3.2或更高。

调试测试失败

在调试级别记录日志是提供更多诊断输出的标准方法;设置后重新运行测试

log4j.logger.org.apache.hadoop.fs.azure=DEBUG

添加新测试

我们始终欢迎新的测试。请记住,我们需要控制成本和测试时间,这可以通过以下方式实现

  • 不重复测试。
  • 高效利用Hadoop API调用。
  • 将大型/慢速测试隔离到“scale”测试组中。
  • 设计所有测试以并行执行(在可能的情况下)。
  • 在现有测试中谨慎添加新的探针和谓词。

禁止重复:如果一个操作已在其他测试中验证过,则无需重复测试。这一原则既适用于元数据操作,也适用于批量IO操作。如果新增的测试用例能完全替代现有测试,在确保测试覆盖率不受影响的前提下,可以移除旧测试。

高效: 优先使用getFileStatus()并检查结果,而不是调用exists()isFile()等方法。

失败时提供有用信息: 在发生故障时尽可能提供详细的诊断信息。使用org.apache.hadoop.fs.contract.ContractTestUtils来对文件系统状态进行断言验证会很有帮助。

隔离式规模测试。任何执行大量IO操作的测试都必须继承AbstractAzureScaleTest类,这样只有在构建时定义了scale参数才会运行,并支持用户可配置的测试超时设置。规模测试还应支持对象实际大小/操作次数的可配置性,以便验证不同规模下的行为表现。

专为并行执行设计。这里的一个关键需求是每个测试套件都能在文件系统的独立部分工作。AbstractWasbTestBase的子类应该使用path()methodpath()blobpath()方法来构建隔离路径。测试绝不能假设它们对存储桶拥有独占访问权限。

在适当情况下扩展现有测试。这一建议与常规测试最佳实践"每个方法只测试一项内容"相悖。但由于创建目录树或上传大文件的操作极其耗时,我们无法遵循常规原则。所有针对真实端点的测试都属于集成测试,在这些测试中共享测试准备和清理环节能显著节省时间和成本。

一种标准做法是通过添加一些额外的断言来扩展现有测试,而不是编写新的测试用例。在进行此操作时,请确保新增的断言在失败时能提供有意义的诊断信息,这样就能从测试日志中轻松调试任何新出现的问题。

新测试的要求

这正是我们对新测试的期望;它们是对常规Hadoop需求的扩展,基于需要与远程服务器协作的场景——这些服务器的使用需要密钥凭证,测试可能较慢,并且仅凭测试输出来诊断故障原因至关重要。

继承现有的共享基类

有一组基类应该被扩展用于Azure测试和集成测试。

org.apache.hadoop.fs.azure.AbstractWasbTestWithTimeout

这扩展了junit的Assert类,增加了线程名称和超时功能,默认超时时间设置为AzureTestConstants.AZURE_TEST_TIMEOUT中的十分钟。设置线程名称有助于分析测试的堆栈跟踪:可以使用jstack调用来

org.apache.hadoop.fs.azure.AbstractWasbTestBase

使用AzureBlobStorageTestAccount创建模拟或真实Azure客户端的测试基类;在测试拆卸阶段会尝试清理存储状态。

  1. 该类要求子类实现createTestAccount()方法来创建模拟或真实的测试账户。

  2. 用于创建测试账户的配置应当来自createConfiguration();子类可以扩展此配置以调整设置。

org.apache.hadoop.fs.azure.integration.AbstractAzureScaleTest

这扩展了AbstractWasbTestBase用于规模测试;这些测试仅在通过-Dscale选择"scale"配置文件时运行。这些测试设置了30分钟的超时时间,以支持较慢的测试运行。

共享基类有助于减少未来的维护工作。请使用它们。

安全

切勿记录凭证。凭证测试特意避免提供有意义的日志或断言消息,正是为了防止这种情况。

高效的时间与金钱利用

这意味着在测试设置/拆卸方面高效,并且理想情况下利用现有的公共数据集以节省设置时间和测试人员成本。

参考示例是ITestAzureHugeFiles:该测试套件被标记为@FixMethodOrder(MethodSorters.NAME_ASCENDING),然后对测试用例进行排序,使得每个测试用例都期望前一个测试已完成(此处指:上传文件、重命名文件等)。这为报告提供了独立的测试,同时仍允许有序的操作序列。请注意使用Assume.assume()来检测单个测试用例的先决条件是否未满足,因此测试会被跳过,而不是因实际上是误报的跟踪而失败。

适用于长距离链路

除了使文件大小和操作计数可扩展外,这还包括设置适当的测试超时时间。规模测试使其可配置;在AbstractAzureIntegrationTest()中硬编码为十分钟;子类可以通过重写getTestTimeoutMillis()来更改此设置。

同样重要的是:支持代理,因为一些测试人员需要它们。

提供诊断和计时信息

  1. 创建日志,记录事件。
  2. 你可以在这里使用AbstractWasbTestBase.describe(format-string, args);它会添加一些换行符以便更容易被发现。
  3. 使用ContractTestUtils.NanoTimer来测量操作持续时间,并记录输出日志。

有意义地失败

ContractTestUtils 类包含一整套断言方法,用于对文件系统的预期状态进行声明,例如 assertPathExists(FS, path)assertPathDoesNotExists(FS, path) 等。这些方法会尽力在失败时提供有意义的诊断信息(如目录列表、文件状态等),从而帮助更轻松地理解故障原因。

至少,不要在没有包含错误信息的情况下使用assertTrue()assertFalse()

清理后续工作

降低成本。

  1. 不仅要在测试用例成功完成时进行清理;测试套件的拆卸也必须完成清理。
  2. 在清理之前,该拆卸代码必须检查文件系统和其他字段是否为null。为什么?如果测试设置失败,拆卸方法仍然会被调用。

稳定可靠运行

我们对此深表感激——您也会的。

提示

如何确保您的凭证真正安全

尽管auth-keys.xml文件在git和subversion中被标记为忽略,但它仍然存在于您的源代码树中,始终存在泄露的风险。

您可以通过将密钥保留在源代码树之外并使用绝对XInclude引用来避免这种情况。

<configuration>

  <include xmlns="http://www.w3.org/2001/XInclude"
    href="file:///users/qe/.auth-keys.xml" />

</configuration>

清理容器

Azure测试会创建前缀为"wasbtests-"的容器,并在测试运行后删除它们。如果测试运行被中断,这些容器可能不会被删除。有一个特殊的测试用例可以手动调用来列出和删除这些容器,CleanupTestContainers

mvn test -Dtest=CleanupTestContainers

这将删除容器;测试运行的输出日志将提供操作的详细信息和摘要。

测试Azure ABFS客户端

Azure Data Lake Storage Gen 2 (ADLS Gen 2) 是一组专为大数据分析构建的功能集,基于Azure Blob Storage开发。ABFS和ABFSS方案针对ADLS Gen 2 REST API,而WASB和WASBS方案则针对Azure Blob Storage REST API。ADLS Gen 2提供了更优异的性能和可扩展性。当存储账户启用分层命名空间时,ADLS Gen 2还提供与Hadoop分布式文件系统权限模型兼容的身份验证和授权机制。此外,ADLS Gen 2 REST API生成的元数据和数据可以被Blob REST API使用,反之亦然。

为各种配置组合生成测试运行配置和测试触发器

为了简化针对PR必须的各种认证和功能组合的测试,应使用脚本dev-support/testrun-scripts/runtests.sh。该脚本更新了针对不同测试组合的相关配置设置后,将:1. 自动生成针对每个测试组合的特定配置 2. 运行所有组合的测试 3. 汇总所有测试组合运行的结果。

以下是需要遵循的前置步骤: 1. 将 ./src/test/resources/azure-auth-keys.xml.template 复制到 ./src/test/resources/azure-auth-keys.xml 1. 更新XML文件中2个属性里用于HNS和非HNS组合测试运行的账户名称(账户名不应包含域名部分),即 1. fs.azure.hnsTestAccountName: 指定启用HNS的账户 2. fs.azure.nonHnsTestAccountName: 指定禁用HNS的账户

注意:azure-auth-keys.xml文件已列入.gitignore中,可防止任何意外的账户名泄露。

```
XInclude is supported, so for extra security secrets may be
kept out of the source tree then referenced through an XInclude element:

      <include xmlns="http://www.w3.org/2001/XInclude"
        href="/users/self/.secrets/auth-keys.xml" />
```
  1. 在文件夹中创建账户配置文件(每个账户一个配置文件):
    ./src/test/resources/accountSettings/
    

按照模板文件开头的说明操作

    accountName_settings.xml.template

在创建账户配置文件时,位于accountSettings文件夹内。accountSettings文件夹中新建的文件会被列入.gitignore,以防止意外泄露凭据。

您已准备好运行测试脚本。

运行PR验证: 执行命令 * dev-support/testrun-scripts/runtests.sh 将显示如下提示:

Choose action:
[Note - SET_ACTIVE_TEST_CONFIG will help activate the config for IDE/single test class runs]
1) SET_ACTIVE_TEST_CONFIG               4) SET_OR_CHANGE_TEST_ACCOUNT
2) RUN_TEST                             5) PRINT_LOG4J_LOG_PATHS_FROM_LAST_RUN
3) CLEAN_UP_OLD_TEST_CONTAINERS
#? 2

输入1:用于为IDE测试运行/单个mvn测试类运行设置活动组合。

输入2:选择用于mvn完整测试套件的组合。

输入3:用于清理任何意外终止的测试,这些测试会在账户上留下自动生成的测试容器。

输入4:创建/修改配置文件,该文件决定用于特定测试组合的账户。

输入5:打印上次测试运行的log4j路径。

在下一个提示中,将提供当前可供选择的组合列表。以Run_TEST动作为例:

Enter parallel test run process count [default - 8]: 4
Set the active test combination to run the action:
1) HNS-OAuth               3) nonHNS-SharedKey        5) AllCombinationsTestRun
2) HNS-SharedKey           4) AppendBlob-HNS-OAuth    6) Quit
#? 1

============================================================
HNS-OAuth
============================================================
Combination specific property setting: [ key=fs.azure.account.auth.type , value=OAuth ]

Activated [src/test/resources/abfs-combination-test-configs.xml] - for account: snvijayacontracttest for combination HNS-OAuth
Running test for combination HNS-OAuth on account snvijayacontracttest [ProcessCount=4]
Test run report can be seen in dev-support/testlogs/2022-10-07_05-23-22/Test-Logs-HNS-OAuth.txt

为首先选择的动作提供选项。

测试日志: 测试运行将在dev-support/testlogs目录下创建一个文件夹用于保存测试日志。文件夹名称将以测试开始时间戳命名。每个组合的mvn verify命令行日志将被保存为该文件夹下的Test-Logs-$combination.txt文件。如果出现任何失败情况,该文件将包含失败异常堆栈信息。测试运行结束时,所有组合运行的汇总结果将被保存为同一文件夹下的Test-Results.log文件。当用于PR验证时,需要将汇总的测试结果粘贴到PR评论部分。

聚合测试结果: Test-Results.txt 文件将以以下格式显示脚本运行的所有组合的聚合结果

    ============================================================
    HNS-OAuth
    ============================================================
    [ERROR] testAbfsHttpSendStatistics(org.apache.hadoop.fs.azurebfs.ITestAbfsNetworkStatistics)  Time elapsed: 3.137 s  <<< FAILURE!
    [ERROR] testBlobDataContributor(org.apache.hadoop.fs.azurebfs.ITestAzureBlobFileSystemOauth)  Time elapsed: 4.154 s  <<< ERROR!

    [WARNING] Tests run: 137, Failures: 0, Errors: 0, Skipped: 2
    [ERROR] Tests run: 623, Failures: 1, Errors: 0, Skipped: 73
    [ERROR] Tests run: 340, Failures: 0, Errors: 1, Skipped: 55

    ============================================================
    HNS-SharedKey
    ============================================================
    [ERROR] testAbfsHttpSendStatistics(org.apache.hadoop.fs.azurebfs.ITestAbfsNetworkStatistics)  Time elapsed: 2.175 s  <<< FAILURE!

    [WARNING] Tests run: 137, Failures: 0, Errors: 0, Skipped: 3
    [ERROR] Tests run: 623, Failures: 1, Errors: 0, Skipped: 42
    [WARNING] Tests run: 340, Failures: 0, Errors: 0, Skipped: 41

    ============================================================
    NonHNS-SharedKey
    ============================================================
    [ERROR] testNonRecursiveDeleteWithPagination(org.apache.hadoop.fs.azurebfs.services.ITestAbfsPaginatedDelete)  Time elapsed: 0.85 s  <<< ERROR!

    [WARNING] Tests run: 137, Failures: 0, Errors: 0, Skipped: 9
    [ERROR] Tests run: 607, Failures: 1, Errors: 1, Skipped: 269
    [WARNING] Tests run: 340, Failures: 0, Errors: 0, Skipped: 44

    ============================================================
    AppendBlob-HNS-OAuth
    ============================================================

    [WARNING] Tests run: 137, Failures: 0, Errors: 0, Skipped: 2
    [ERROR] Tests run: 623, Failures: 0, Errors: 0, Skipped: 73
    [ERROR] Tests run: 340, Failures: 0, Errors: 0, Skipped: 79

添加新测试组合的方法: PR验证所需的强制测试组合模板位于dev-support/testrun-scripts/runtests.sh中。如需新增组合,请在该文件中添加组合(可参考脚本中SECTION: COMBINATION DEFINITIONS AND TRIGGERSECTION: TEST COMBINATION METHODS部分现有的活跃组合)。

测试配置详情:

请注意,ABFS测试包含兼容性测试,这些测试除了需要ABFS凭证外,还需要WASB凭证。

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
  <property>
    <name>fs.azure.abfs.account.name</name>
    <value>{ACCOUNT_NAME}.dfs.core.windows.net</value>
  </property>

  <property>
    <name>fs.azure.account.key.{ACCOUNT_NAME}.dfs.core.windows.net</name>
    <value>{ACCOUNT_ACCESS_KEY}</value>
  </property>

  <property>
    <name>fs.azure.wasb.account.name</name>
    <value>{ACCOUNT_NAME}.blob.core.windows.net</value>
  </property>

  <property>
    <name>fs.azure.account.key.{ACCOUNT_NAME}.blob.core.windows.net</name>
    <value>{ACCOUNT_ACCESS_KEY}</value>
  </property>

  <property>
    <name>fs.contract.test.fs.abfs</name>
    <value>abfs://{CONTAINER_NAME}@{ACCOUNT_NAME}.dfs.core.windows.net</value>
    <description>A file system URI to be used by the contract tests.</description>
  </property>

  <property>
    <name>fs.contract.test.fs.wasb</name>
    <value>wasb://{CONTAINER_NAME}@{ACCOUNT_NAME}.blob.core.windows.net</value>
    <description>A file system URI to be used by the contract tests.</description>
  </property>
</configuration>

要运行OAuth和ACL测试用例,您必须使用启用了分层命名空间的存储账户,并设置以下配置项:

<!--=========================== AUTHENTICATION  OPTIONS ===================-->
<!--ATTENTION:
      TO RUN ABFS & WASB COMPATIBILITY TESTS, YOU MUST SET AUTH TYPE AS SharedKey.
      OAUTH IS INTRODUCED TO ABFS ONLY.-->
<property>
  <name>fs.azure.account.auth.type.{YOUR_ABFS_ACCOUNT_NAME}</name>
  <value>{AUTH TYPE}</value>
  <description>The authorization type can be SharedKey, OAuth, Custom or SAS. The
  default is SharedKey.</description>
</property>

<!--=============================   FOR OAUTH   ===========================-->
<!--IF AUTH TYPE IS SET AS OAUTH, FOLLOW THE STEPS BELOW-->
<!--NOTICE: AAD client and tenant related properties can be obtained through Azure Portal-->

  <!--1. UNCOMMENT BELOW AND CHOOSE YOUR OAUTH PROVIDER TYPE -->

  <!--
  <property>
    <name>fs.azure.account.oauth.provider.type.{ABFS_ACCOUNT_NAME}</name>
    <value>org.apache.hadoop.fs.azurebfs.oauth2.{Token Provider Class name}</value>
    <description>The full name of token provider class name.</description>
  </property>
 -->

  <!--2. UNCOMMENT BELOW AND SET CREDENTIALS ACCORDING TO THE PROVIDER TYPE-->

  <!--2.1. If "ClientCredsTokenProvider" is set as key provider, uncomment below and
           set auth endpoint, client id and secret below-->
  <!--
   <property>
    <name>fs.azure.account.oauth2.client.endpoint.{ABFS_ACCOUNT_NAME}</name>
    <value>https://login.microsoftonline.com/{TENANTID}/oauth2/token</value>
    <description>Token end point, this can be found through Azure portal</description>
  </property>

   <property>
     <name>fs.azure.account.oauth2.client.id.{ABFS_ACCOUNT_NAME}</name>
     <value>{client id}</value>
     <description>AAD client id.</description>
   </property>

   <property>
     <name>fs.azure.account.oauth2.client.secret.{ABFS_ACCOUNT_NAME}</name>
     <value>{client secret}</value>
   </property>
 -->

  <!--2.2. If "UserPasswordTokenProvider" is set as key provider, uncomment below and
           set auth endpoint, use name and password-->
  <!--
   <property>
    <name>fs.azure.account.oauth2.client.endpoint.{ABFS_ACCOUNT_NAME}</name>
    <value>https://login.microsoftonline.com/{TENANTID}/oauth2/token</value>
    <description>Token end point, this can be found through Azure portal</description>
  </property>

   <property>
     <name>fs.azure.account.oauth2.user.name.{ABFS_ACCOUNT_NAME}</name>
     <value>{user name}</value>
   </property>

   <property>
     <name>fs.azure.account.oauth2.user.password.{ABFS_ACCOUNT_NAME}</name>
     <value>{user password}</value>
   </property>
 -->

  <!--2.3. If "MsiTokenProvider" is set as key provider, uncomment below and
           set tenantGuid and client id.-->
  <!--
   <property>
     <name>fs.azure.account.oauth2.msi.tenant.{ABFS_ACCOUNT_NAME}</name>
     <value>{tenantGuid}</value>
     <description>msi tenantGuid.</description>
   </property>

   <property>
     <name>fs.azure.account.oauth2.client.id.{ABFS_ACCOUNT_NAME}</name>
     <value>{client id}</value>
     <description>AAD client id.</description>
   </property>
  -->

  <!--2.4. If "RefreshTokenBasedTokenProvider" is set as key provider, uncomment below and
           set refresh token and client id.-->
  <!--
   <property>
     <name>fs.azure.account.oauth2.refresh.token.{ABFS_ACCOUNT_NAME}</name>
     <value>{refresh token}</value>
     <description>refresh token.</description>
   </property>

   <property>
     <name>fs.azure.account.oauth2.client.id.{ABFS_ACCOUNT_NAME}</name>
     <value>{client id}</value>
     <description>AAD client id.</description>
   </property>
  -->

  <!--2.5. If "WorkloadIdentityTokenProvider" is set as key provider, uncomment below and
           set tenant, client id and token file path.

           All service principals must have federated identity credentials for Kubernetes.
           See Azure docs: https://learn.microsoft.com/en-us/azure/active-directory/workload-identities/workload-identity-federation-create-trust?pivots=identity-wif-apps-methods-azp#kubernetes

           Retrieve the Azure identity token from kubernetes:
           1. Create AKS cluster with Workload Identity: https://learn.microsoft.com/en-us/azure/aks/workload-identity-deploy-cluster
           2. Create the pod:
              kubectl apply -f src/test/resources/workload-identity-pod.yaml
           3. After the pod is running, retrieve the identity token from the pod logs:
              kubectl logs pod/workload-identity
           4. Save the identity token to the token file path specified below.

           The Azure identity token expires after 1 hour.
  -->
  <!--
   <property>
     <name>fs.azure.account.oauth2.msi.tenant.{ABFS_ACCOUNT_NAME}</name>
     <value>{tenantGuid}</value>
     <description>msi tenantGuid.</description>
   </property>

   <property>
     <name>fs.azure.account.oauth2.client.id.{ABFS_ACCOUNT_NAME}</name>
     <value>{client id}</value>
     <description>AAD client id.</description>
   </property>

   <property>
     <name>fs.azure.account.oauth2.client.token.file.{ABFS_ACCOUNT_NAME}</name>
     <value>{token file path}</value>
     <description>Azure identity token file path.</description>
   </property>
  -->

  <!--
    <property>
        <name>fs.azure.identity.transformer.enable.short.name</name>
        <value>true/false</value>
        <description>
          User principal names (UPNs) have the format “{alias}@{domain}”.
          If true, only {alias} is included when a UPN would otherwise appear in the output
          of APIs like getFileStatus, getOwner, getAclStatus, etc, default is false.
        </description>
    </property>

    <property>
        <name>fs.azure.identity.transformer.domain.name</name>
        <value>domain name of the user's upn</value>
        <description>
          If the domain name is specified and “fs.azure.identity.transformer.enable.short.name”
          is true, then the {alias} part of a UPN can be specified as input to APIs like setOwner,
          setAcl, modifyAclEntries, or removeAclEntries, and it will be transformed to a UPN by appending @ and the domain specified by
          this configuration property.
        </description>
    </property>

    <property>
        <name>fs.azure.identity.transformer.service.principal.id</name>
        <value>service principal object id</value>
        <description>
          An Azure Active Directory object ID (oid) used as the replacement for names contained
          in the list specified by “fs.azure.identity.transformer.service.principal.substitution.list”.
          Notice that instead of setting oid, you can also set $superuser here.
        </description>
    </property>

    <property>
        <name>fs.azure.identity.transformer.skip.superuser.replacement</name>
        <value>true/false</value>
        <description>
          If false, “$superuser” is replaced with the current user when it appears as the owner
          or owning group of a file or directory. The default is false.
        </description>
    </property>

    <property>
        <name>fs.azure.identity.transformer.service.principal.substitution.list</name>
        <value>mapred,hdfs,yarn,hive,tez</value>
        <description>
           A comma separated list of names to be replaced with the service principal ID specified by
           “fs.azure.identity.transformer.service.principal.id”.  This substitution occurs
           when setOwner, setAcl, modifyAclEntries, or removeAclEntries are invoked with identities
           contained in the substitution list. Notice that when in non-secure cluster, asterisk symbol *
           can be used to match all user/group.
        </description>
    </property>
   -->

要运行委托SAS测试用例,您必须使用启用了分层命名空间的存储帐户,并设置以下配置:

<!--=========================== AUTHENTICATION  OPTIONS ===================-->
<!--=============================   FOR SAS   ===========================-->
<!-- To run ABFS Delegation SAS tests, you must register an app, create the
     necessary role assignments, and set the configuration discussed below:

    1) Register an app:
      a) Login to https://portal.azure.com, select your AAD directory and search for app registrations.
      b) Click "New registration".
      c) Provide a display name, such as "abfs-app".
      d) Set the account type to "Accounts in this organizational directory only ({YOUR_Tenant} only - Single tenant)".
      e) For Redirect URI select Web and enter "http://localhost".
      f) Click Register.

    2)  Create necessary role assignments:
      a) Login to https://portal.azure.com and find the Storage account with hierarchical namespace enabled
         that you plan to run the tests against.
      b) Select "Access Control (IAM)".
      c) Select Role Assignments
      d) Click Add and select "Add role assignments"
      e) For Role and enter "Storage Blob Data Owner".
      f) Under Select enter the name of the app you registered in step 1 and select it.
      g) Click Save.
      h) Repeat above steps to create a second role assignment for the app but this time for
         the "Storage Blob Delegator" role.

    3) Generate a new client secret for the application:
      a) Login to https://portal.azure.com and find the app registered in step 1.
      b) Select "Certificates and secrets".
      c) Click "New client secret".
      d) Enter a description (eg. Secret1)
      e) Set expiration period.  Expires in 1 year is good.
      f) Click Add
      g) Copy the secret and expiration to a safe location.

    4) Set the following configuration values:
-->

  <property>
    <name>fs.azure.sas.token.provider.type</name>
    <value>org.apache.hadoop.fs.azurebfs.extensions.MockDelegationSASTokenProvider</value>
    <description>The fully qualified class name of the SAS token provider implementation.</description>
  </property>

  <property>
    <name>fs.azure.test.app.service.principal.tenant.id</name>
    <value>{TID}</value>
    <description>Tenant ID for the application's service principal.</description>
  </property>

  <property>
    <name>fs.azure.test.app.service.principal.object.id</name>
    <value>{OID}</value>
    <description>Object ID for the application's service principal.</description>
  </property>

  <property>
    <name>fs.azure.test.app.id</name>
    <value>{app id}</value>
    <description>The application's ID, also known as the client id.</description>
  </property>

   <property>
     <name>fs.azure.test.app.secret</name>
     <value>{client secret}</value>
     <description>The application's secret, also known as the client secret.</description>
   </property>


要运行CheckAccess测试用例,您必须注册一个没有RBAC的应用程序并设置以下配置。

<!--===========================   FOR CheckAccess =========================-->
<!-- To run ABFS CheckAccess SAS tests, you must register an app, with no role
 assignments, and set the configuration discussed below:

    1) Register a new app with no RBAC
    2) As part of the test configs you need to provide the guid for the above
created app. Please follow the below steps to fetch the guid.
      a) Get an access token with the above created app. Please refer the
 following documentation for the same. https://docs.microsoft
.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#get-a-token
      b) Decode the token fetched with the above step. You may use https
://jwt.ms/ to decode the token
      d) The oid field in the decoded string is the guid.
    3) Set the following configurations:
-->

  <property>
    <name>fs.azure.enable.check.access</name>
    <value>true</value>
    <description>By default the check access will be on. Checkaccess can
    be turned off by changing this flag to false.</description>
  </property>
  <property>
    <name>fs.azure.account.test.oauth2.client.id</name>
    <value>{client id}</value>
    <description>The client id(app id) for the app created on step 1
    </description>
  </property>
  <property>
    <name>fs.azure.account.test.oauth2.client.secret</name>
    <value>{client secret}</value>
    <description>
The client secret(application's secret) for the app created on step 1
    </description>
  </property>
  <property>
    <name>fs.azure.check.access.testuser.guid</name>
    <value>{guid}</value>
    <description>The guid fetched on step 2</description>
  </property>
  <property>
    <name>fs.azure.account.oauth2.client.endpoint.{account name}.dfs.core
.windows.net</name>
    <value>https://login.microsoftonline.com/{TENANTID}/oauth2/token</value>
    <description>
Token end point. This can be found through Azure portal. As part of CheckAccess
test cases. The access will be tested for an FS instance created with the
above mentioned client credentials. So this configuration is necessary to
create the test FS instance.
    </description>
  </property>

如果针对使用URL格式http[s]://[ip]:[port]/[account]/[filesystem]而非http[s]://[account][domain-suffix]/[filesystem]的端点运行测试,请使用以下内容:

<property>
  <name>fs.azure.abfs.endpoint</name>
  <value>{IP}:{PORT}</value>
</property>