通常のHadoopテスト実行では、ローカルファイルシステムを介してローカルでテストできるファイルシステムがテストされます。これは通常、file://
とその基盤となるLocalFileSystem
、およびHDFS MiniClusterを介したhdfs://
を意味します。
ファイルシステムへの特定の構成がリモートサーバーに提供されていない限り、他のファイルシステムはスキップされます。
これらのファイルシステムバインディングは、通常hadoop-common-project/hadoop-common/src/test/resources/contract-test-options.xml
にあるXML構成ファイルで定義する必要があります。このファイルは除外されており、チェックインしないでください。
contract-test-options.xml
では、ファイルシステム名はプロパティfs.contract.test.fs.ftp
で定義する必要があります。次に、FTPサーバーに接続するための具体的なログインオプションを指定する必要があります。
テストディレクトリへのパスも、オプションfs.contract.test.ftp.testdir
で指定する必要があります。これは、操作が行われるディレクトリです。
例
<configuration> <property> <name>fs.contract.test.fs.ftp</name> <value>ftp://server1/</value> </property> <property> <name>fs.ftp.user.server1</name> <value>testuser</value> </property> <property> <name>fs.contract.test.ftp.testdir</name> <value>/home/testuser/test</value> </property> <property> <name>fs.ftp.password.server1</name> <value>secret-login</value> </property> </configuration>
契約テストに新しいファイルシステムを追加するコアは、新しい契約クラスを追加し、テストするすべてのテストスイートに対して新しい非抽象テストクラスを作成することです。
contract
下に、ファイルとテスト用のパッケージを作成します。AbstractFSContract
をサブクラス化します。Test
とファイルシステムの名前で始まる非抽象サブクラスを作成します。例: TestHDFSRenameContract
。createContract()
を実装する必要があります。src/test/resources/contract-test-options.xml
ファイルで定義する必要があるファイルシステムバインディングを特定し、文書化します。例として、ローカルファイルシステムのcreate()
テストの実装を次に示します。
package org.apache.hadoop.fs.contract.localfs; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.contract.AbstractCreateContractTest; import org.apache.hadoop.fs.contract.AbstractFSContract; public class TestLocalCreateContract extends AbstractCreateContractTest { @Override protected AbstractFSContract createContract(Configuration conf) { return new LocalFSContract(conf); } }
AbstractFSContract
のサブクラスの標準的な実装手法は、テストリソースツリーに格納されているHadoop XML構成ファイルによって完全に駆動されることです。最適な方法は、ファイルシステムの名前(例:contract/localfs.xml
)を使用して/contract
下に格納することです。XMLファイルですべてのファイルシステムオプションを定義することで、ファイルシステムの動作の一覧をすぐに表示できます。
LocalFSContract
はこれの特別なケースであり、実行中のOSに基づいて大文字と小文字の区別ポリシーを調整する必要があります。WindowsとOS/Xの両方で、ファイルシステムは大文字と小文字を区別しないため、ContractOptions.IS_CASE_SENSITIVE
オプションをfalseに設定する必要があります。さらに、WindowsファイルシステムはUnixファイルおよびディレクトリの権限をサポートしないため、関連するフラグも設定する必要があります。これは、リソースツリーからXML契約ファイルをロードした後、ロード済みの構成オプションを更新するだけで行われます。
getConf().setBoolean(getConfKey(ContractOptions.SUPPORTS_UNIX_PERMISSIONS), false);
新しいFileSystem
のテストケースが契約テストの1つに失敗した場合、どうすればよいでしょうか?
問題は原因によって異なります。
FileSystem
サブクラスが仕様を正しく実装していません。修正してください。FileSystem
サブクラスで違いを隠してみてください。hdfs-dev
メーリングリストで報告してください。ファイルシステムテストはHadoopのコアコードベースに存在しますが、ファイルシステム仕様とその付属のテストを所有しているのはHDFSチームであることに注意してください。機能がサポートされていないためにテストをスキップする必要がある場合は、ContractOptions
クラスで既存の構成オプションを探します。メソッドがない場合、短期的な修正はメソッドをオーバーライドし、ContractTestUtils.skip()
メッセージを使用してテストがスキップされたことをログに記録することです。このメソッドを使用すると、メッセージがログに出力され、テストランナーにテストがスキップされたことが伝えられます。これにより、問題が強調表示されます。
推奨される戦略は、スーパークラスを呼び出し、例外をキャッチし、例外クラスとエラー文字列の一部が現在の実装によって発生したものと一致することを確認することです。スーパークラスが実際に成功した場合(つまり、実装が現在行っていない方法で失敗した場合)もfail()
する必要があります。これにより、テストパスが実行され続け、テストの他の失敗(おそらく回帰)が検出されます。そして、機能が実装された場合、その変更が検出されます。
長期的な解決策は、基本テストを拡張して新しいオプション機能キーを追加することです。これには、hdfs-dev
メーリングリストの開発者との協力が必要です。
契約テストには、厳格な例外と寛容な例外の概念が含まれています。*厳格な*例外レポートとは、FileNotFoundException
、EOFException
など、IOException
の特定のサブクラスを使用して失敗を報告することを意味します。*寛容な*レポートとは、IOException
をスローすることを意味します。
ファイルシステムはより厳格な例外を発生させるべきですが、できない理由がある場合があります。寛容な例外が発生しても許可されますが、ユーザーアプリケーションでの失敗の診断が妨げられるだけです。ファイルシステムがより厳格な例外をサポートしていないことを宣言するには、オプションfs.contract.supports-strict-exceptions
をfalseに設定します。
リモートファイルシステムに対するテストでは、ファイルシステムのURLを指定する必要があります。ログイン情報が必要なリモートファイルシステムに対するテストでは、ユーザー名/IDとパスワードが必要です。
これらの情報はすべて、ファイル`src/test/resources/contract-test-options.xml`に配置する必要があります。また、SCMツールを構成して、このファイルをSubversion、Git、または同等のシステムにコミットしないようにしてください。さらに、ビルドを構成して、生成される`-test`アーティファクトにこのファイルをバンドルしないようにする必要があります。Hadoopビルドでは、JARファイルから`src/test/**/*.xml`を除外することでこれを実現しています。さらに、`src/test/resources/auth-keys.xml`を作成する必要があります。これは`contract-test-options.xml`のコピーでも構いません。`AbstractFSContract`クラスは、存在する場合、このリソースファイルを読み込みます。特定のテストケースに対する特定のキーを追加できます。
例として、S3Aテストキーを以下に示します。
<configuration> <property> <name>fs.contract.test.fs.s3a</name> <value>s3a://tests3contract</value> </property> <property> <name>fs.s3a.access.key</name> <value>DONOTPCOMMITTHISKEYTOSCM</value> </property> <property> <name>fs.s3a.secret.key</name> <value>DONOTEVERSHARETHISSECRETKEY!</value> </property> </configuration>
`AbstractBondedFSContract`は、プロパティ`fs.contract.test.fs.%s`にファイルシステムのURLが定義されていない場合、テストスイートを自動的にスキップします。ここで`%s`はファイルシステムのスキーマ名に一致します。
テストを実行する際には、デフォルトでこれらのテストではtrueである`maven.test.skip`をオフにする必要があります。これは、`mvn test -Ptests-on`のようなコマンドで実行できます。
すべてのファイルシステムコントラクトテストに合格しても、ファイルシステムを「HDFSと互換性がある」と記述できるわけではありません。テストでは、各操作の独立した機能に注目し、各アクションの前提条件と事後条件に焦点を当てています。カバーされていないコア領域には、分散システム全体での同時実行と障害の側面があります。
ファイルシステムAPIの使用に関する特定の側面もあります。
これらの動作を確認するテストは大歓迎です。
一部のテストはルートファイルシステムに対して直接動作し、「/」の名前変更など、同様のアクションを実行しようとします。ルートディレクトリは「特殊」であり、特にオブジェクトストアなどの非POSIXファイルシステムでこれらをテストすることが重要です。これらのテストはネイティブファイルシステムに対して非常に破壊的な可能性があるため、注意が必要です。
テストを`AbstractRootDirectoryContractTest`に追加するか、(a) タイトルに「Root」が含まれ、(b) ルートテストが無効になっている場合にテストをスキップするチェックがセットアップメソッドにある新しいテストを作成します。
skipIfUnsupported(TEST_ROOT_TESTS_ENABLED);
ローカルFSに対して実行するこのテストスイートの実装は提供しないでください。
スケーラブルな負荷を生成するように設計されたテスト(多数の小さなファイルと少数の大きなファイルの両方を含む)は、構成可能であるように設計する必要があります。これにより、テストスイートのユーザーはファイルの数とサイズを構成できます。
オブジェクトストアでは、ディレクトリの名前変更操作は通常`O(files)*O(data)`であるのに対し、削除操作は`O(files)`です。後者は、ディレクトリのクリーンアップ操作でも時間がかかり、タイムアウトする可能性があることを意味します。すべての操作で遅延の可能性があるリモートファイルシステムに対して動作するテストを設計することが重要です。
仕様は不完全です。ファイルシステムクラスの完全なカバレッジがなく、既存の指定クラスの一部がカバーされていない可能性があります。