# 分散ストレージに関するテスト設計 ###### tags: `テスト設計` [分散ストレージのYP](https://hackmd.io/RUzKWv6yQoK6MumW1oFWMQ?view) 見やすさを重視してjsのテスト形式で書いています。実装時は使用するプログラミング言語の形式でテストの作成をお願いします。 テスト方針 - 正常系はもちろん異常系も合わせて全て網羅する。 - カバレッジ90%以上を求める。 - テストのケースのそれぞれの目的を明瞭にすること。(itの内容およびテスト関数名をはっきりわかるように記載すること) # GlobalState > Proof、Commit、OnetimeUserStateはほぼそれぞれ同じなので、Databaseアクセス用のBaseクラスを定義する。かつそのBaseクラスで共通なものをテストすること。実装時には、Baseクラスのテストも合わせて記載すること。 ```javascript describe("GlobalState service class", () => { describe("GlobalState data structure", () => { // keyの値がaddress型であるか確認する it('"key" should be typeof address key', () => {}); // keyに対応するValueが、Number型またはBN型であるか確認する it('"value" should be typeof number of BN', () => {}); }); describe("getGlobalState", () => { // blockNumberを元にGlobalStateが返却されているかどうかを確認する // 取得したデータがGlobalStateTypeのインスタンスかどうか確認する it("should return getGlobalState that is instance of GlobalState", () => {}); // 引数であるblockNumberがIntType以外はエラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する it("should throw error for invalid arguments", () => {}); // リクエストを呼ぶcontextが認証済みでない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する // 「具体的には」request.contextのisAuthenticatedや呼び出し元のデータがない場合は、error messageおよびerror codeが適切に返却されていること it("should throw error for invalid unauthorized request", () => {}); // blockNumberを引数に取得したデータがない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する // 「具体的には」取得しようとしたデータが無い場合は、error messageおよびerror codeが適切に返却されていること it("should throw error for not found", () => {}); // DBと接続できない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する // 「具体的には」DB Connectionエラーが起きているかどうか確認する。その置きた場合にログ出力ができているかどうか。error messageおよびerror codeが適切に返却されていること it("should throw error for db connection", () => {}); }); describe("getLatestGlobalState", () => { // GlobalStateが返却されているかどうかを確認する // 取得したデータがGlobalStateTypeのインスタンスかどうか確認する it("should return getGlobalState that is instance of GlobalState", () => {}); // リクエストを呼ぶcontextが認証済み出ない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する // 「具体的には」DB Connectionエラーが起きているかどうか確認する。その置きた場合にログ出力ができているかどうか。error messageおよびerror codeが適切に返却されていること it("should throw error for invalid unauthorized request", () => {}); // DBと接続できない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する // 「具体的には」DB Connectionエラーが起きているかどうか確認する。その置きた場合にログ出力ができているかどうか。error messageおよびerror codeが適切に返却されていること it("should throw error for db connection", () => {}); // データが一つもない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する it("should throw error for not storing the data yet", () => {}); }); describe("saveGlobalState", () => { // GlobalStateが保存できているか確認する it("should save globalState", () => {}); // 引数のblockNumberがIntType以外はエラーを返す // 引数のGlobalStateが、正しいプロパティを持っているか過不足ないかどうか確認する it("should throw error for invalid arguments", () => {}); // リクエストを呼ぶcontextが認証済み出ない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する // 「具体的には」request.contextのisAuthenticatedや呼び出し元のデータがない場合は、error messageおよびerror codeが適切に返却されていること it("should throw error for invalid unauthorized request", () => {}); // DBと接続できない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する // 「具体的には」DB Connectionエラーが起きているかどうか確認する。その置きた場合にログ出力ができているかどうか。error messageおよびerror codeが適切に返却されていること it("should throw error for db connection", () => {}); // 既存のblockNumberに対応するGlobalStateに対して、新規で保存するblockNumberがincrementされるような数字でない場合は、エラーを返す // 「具体的には」不正なblockNumberに対応するGlobalStateの保存を除きたい。blockNumberが前回のGlobalStateから差分が反映されていることもvalidしたい it("blockNumber should be incremented", () => {}); }); describe("backupGlobalState", () => { // GlobalStateをバックアップストレージに送信できることを確認する //「具体的には」今保存されているGlobalStateが全て送信できることを担保したい it("should send them to backup storage", () => {}); // GlobalStateをバックアップストレージに送信できることを確認する //「具体的には」バックアップストレージへの保存が何らかの原因で失敗した場合は、再度バックアップストレージへの保存をリトライすることを確認する // 何らの原因で失敗した場合に、エラーをログ出力する it("should resend them to backup storage", () => {}); // 外部から呼べず、イベントの発火でしか起動できないことを確認する it("should be invoked by publisher", () => {}); // バックアップしようとした既存のデータが既にある場合はエラーを返す it("should not be duplicated", () => {}); }); }); ``` # BackupUserState ```javascript describe("BackupUserState service class", () => { describe("BackupUserState data structure", () => { // keyの値がaddress型であるか確認する it('"key" should be typeof address key', () => {}); // keyに対応するValueが、Number型またはBN型であるか確認する it('"value" should be typeof number of BN', () => {}); }); describe("getBackupUserState", () => { // userAddressを元にBackupUserStateが返却されているかどうかを確認する // 取得したデータがBackupUserStateTypeのインスタンスかどうか確認する it("should return BackupUserState that is instance of BackupUserState", () => {}); // 引数であるadressがaddress key以外はエラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する it("should throw error for invalid arguments", () => {}); // リクエストを呼ぶcontextが認証済み出ない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する // 「具体的には」request.contextのisAuthenticatedや呼び出し元のデータがない場合は、error messageおよびerror codeが適切に返却されていること it("should throw error for invalid unauthorized request", () => {}); // blockNumberを引数に取得したデータがない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する // 「具体的には」取得しようとしたデータが無い場合は、error messageおよびerror codeが適切に返却されていること it("should throw error for not found", () => {}); // DBと接続できない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する // 「具体的には」DB Connectionエラーが起きているかどうか確認する。その置きた場合にログ出力ができているかどうか。error messageおよびerror codeが適切に返却されていること it("should throw error for db connection", () => {}); }); describe("saveBackupUserState", () => { // BackupUserStateが保存できているか確認する it("should save backupUserState", () => {}); // 引数のuserAddressがAddressType以外はエラーを返す // 引数のBackupUserStateが、正しいプロパティを持っているか過不足ないかどうか確認する it("should throw error for invalid arguments", () => {}); // リクエストを呼ぶcontextが認証済み出ない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する // 「具体的には」request.contextのisAuthenticatedや呼び出し元のデータがない場合は、error messageおよびerror codeが適切に返却されていること it("should throw error for invalid unauthorized request", () => {}); // DBと接続できない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する // 「具体的には」DB Connectionエラーが起きているかどうか確認する。その置きた場合にログ出力ができているかどうか。error messageおよびerror codeが適切に返却されていること it("should throw error for db connection", () => {}); // 既存のuserAddressに対応するBackupUserStateに対して、更新できているかどうかを確認する。 it("blockNumber should be updated", () => {}); }); describe("backupBackupUserState", () => { // BackupUserStateをバックアップストレージに送信できることを確認する //「具体的には」今保存されているBackupUserStateが全て送信できることを担保したい it("should send them to backup storage", () => {}); // BackupUserStateをバックアップストレージに送信できることを確認する //「具体的には」バックアップストレージへの保存が何らかの原因で失敗した場合は、再度バックアップストレージへの保存をリトライすることを確認する // 何らの原因で失敗した場合に、エラーをログ出力する it("should resend them to backup storage", () => {}); // 外部から呼べず、イベントの発火でしか起動できないことを確認する it("should be invoked by publisher", () => {}); // バックアップしようとした既存のデータが既にある場合はエラーを返す it("should not be duplicated", () => {}); }); }); ``` # VerkcleDistributedStorage ```javascript= describe("VerkleTree Distributed Storage", () => { // 他のオペレータとデータについて同期できることを確認 // 他のオペレータと差分のみ同期できていることを確認 it("should sync data with another operator", () => {}); // DBと接続できない場合は、エラーを返す // エラーメッセージおよびエラーコードが合っているかどうかを確認する // 「具体的には」DB Connectionエラーが起きる。その置きた場合にログ出力ができるているかどうか。error messageおよびerror codeが適切に返却されていること it("should throw error for db connection", () => {}); // 他のoperatorと何らかの理由で通信できない、または受け取ったデータの形式が違う場合はエラーを返す // 「具体的には」error messageおよびerror codeが適切に返却されていること it("cannot send unlisted data that operator dones'nt have", () => {}); // 他のオペレータに何らかの理由でproofを要求できない、または受け取ったデータの形式が違う場合はエラーを返す // 「具体的には」error messageおよびerror codeが適切に返却されていること it("cannot request the proof", () => {}); // 他のオペレータから送れてきたProofが正しくない場合はエラーを返す // 「具体的には」error messageおよびerror codeが適切に返却されていること。また正しくない場合は、異なるオペレータと再度同期を開始する。 it("cannot verify the proof becase proof is wrong", () => {}); // 他のオペレータへ同期するデータが送信できない場合はエラーを返す it("cannot send verkle tree data because something wrong happened", () => {}); // 同期用のデータが正しくない場合はエラーを返す it("the data that is used for syncing is invalid", () => {}); }); ```