[英]azure function unit test cases for retry scenario - nodejs
我已經使用 NodeJs 構建了一個 azure function。 我正在使用 Jest 進行測試。
場景: function撥打API,如果3rd返回Timeout,我需要重試1次后退出。 當實時並且服務器按預期自動重試時,這工作正常。
我未能編寫測試用例,因為出現 Jest Timeout 錯誤。
邏輯:
function.json
"retry": {
"strategy": "exponentialBackoff",
"maxRetryCount": 1,
"minimumInterval": "00:00:10",
"maximumInterval": "00:00:40"
}
index.js - 在 try/catch 下
catch (err) {
let errorCode = err.errorCode || err.code || 500;
let errorMessage = err.message|| err.errorMessage;
if (errorMessage && errorMessage.indexOf("ETIMEDOUT") >= 0 ) {
errorCode = 429; //setting errorCode as 429 to retry automatically from azure function
let retryError = new Error("retrying requests");
retryError.code = 429;
throw retryError;
}else{
context.done();
}
};
索引.test.js
測試套件無法運行重試請求
一旦從主 class 拋出錯誤,測試 class 將在“ let retryError = new Error("retrying requests"); ”這一行中斷。
那么,如果服務器重試耗盡,仍然響應429,如何編寫測試用例?
我正在按照這個文檔在 Nodejs Azure function 中實現自動化測試。 步驟如下:
要在 VS 代碼擴展中測試 Azure function,請使用 Jest。
使用npm i jest
更新package.json以用以下命令替換現有的測試命令
"scripts": {
"test": "jest"
}
對於自動化測試,您可以創建一個模塊來運行測試。 創建一個您喜歡的新文件夾 ( testing ) 在創建的文件夾中添加一個新文件 ( defaultContext.js ) 並添加以下命令以記錄 function 默認執行上下文。
module.exports = {
log: jest.fn()
};
之后在 HTTP function 觸發器文件夾中添加一個新文件index.test.js
並添加以下代碼
const httpFunction = require('./index');
const context = require('../testing/defaultContext')
test('Http trigger should return known text', async () => {
const request = {
query: { name: 'Bill' }
};
await httpFunction(context, request);
expect(context.log.mock.calls.length).toBe(1);
expect(context.res.body).toEqual('Hello Bill');
});
使用npm test
命令運行單元測試。
嘗試在 azure function 中添加重試策略
在您的觸發器中添加重試策略function.json使用固定延遲或指數退避
{
"disabled": false,
"bindings": [
{
....
}
],
"retry": {
"strategy": "exponentialBackoff",
"maxRetryCount": 5,
"minimumInterval": "00:00:10",
"maximumInterval": "00:15:00"
}
}
使用npm test
添加所有運行測試后,我可以看到結果:
重試限制:
在消費計划中,
在重試隊列中的最終消息時,應用程序可能會縮小到零。 &
執行重試時,應用程序可能會縮小。 選擇重試間隔<= 00:01:00和<= 5次重試以獲得更好的結果。
警告不建議將服務總線隊列等觸發器的傳遞計數設置為 1,這意味着消息將在單個 function 重試周期后立即被死信。 這是因為觸發器通過重試提供彈性,而 function 重試策略是盡最大努力,可能會導致重試總數少於所需的總數。
參考這里
剛剛修改了結構以捕獲每個錯誤,如下所示:
try {
await retry(
async(bail) => {
api_attempt++;
console.log('correlationId:' + correlationId + ' api_attempt:' + api_attempt);
let api_Resp = await myAPI(correlationId, payload)
.catch((error) => {
console.error("correlationId:" + correlationId + " myAPI caught error::", JSON.stringify(error));
let errorCode = error.statusCode;
let errorMessage = error.errorMessage;
let errorDescription = error.errorDescription;
console.log("correlationId:" + correlationId + " myAPI errorCode::" + errorCode);
if (errorCode === 429 ||
(errorMessage && (errorMessage.indexOf("ETIMEDOUT") >= 0 || errorMessage.indexOf("ECONNREFUSED") >= 0 || errorMessage.indexOf("Timeout") >= 0)) ||
(errorDescription && (errorDescription.indexOf("ETIMEDOUT") >= 0 || errorDescription.indexOf("ECONNREFUSED") >= 0 || errorDescription.indexOf("Timeout") >= 0 || errorDescription.indexOf("retries exhausted") >= 0))
) {
console.log("correlationId:" + correlationId + " retrying myAPI");
throw error; //to retry
} else if (errorCode === 500) {
console.log("correlationId:" + correlationId + " exiting myAPI and not writing to db");
return; //don't bail and don't write to DB (as 3Party writes to DB for 500 status)
} else {
// don't retry by bailing error
console.log("correlationId:" + correlationId + " not attempting myAPI retry..");
bail(error);
return;
}
})
}, retryOptions);
} catch (err) {
console.error("correlationId:" + correlationId + " myAPI final error::api_attempt:" + api_attempt + " - retries exhausted while calling API::", JSON.stringify(err));
let errorCode = err.statusCode || 500;
let errorMessage = err.code || err.errorMessage || err.message || err;
let errorDescription = err.statusMessage || err.errorDescription || errorMessage || "Unknown Error at 3Party Single API";
//writing errors to db
callDB(false, correlationId, payload, 'AzureFunction', 'Request failed at 3Party', errorCode, errorMessage, errorDescription);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.