forked from mirrors/gecko-dev
MozReview-Commit-ID: 7pYfD6Ax5VX Differential Revision: https://phabricator.services.mozilla.com/D2971 --HG-- extra : moz-landing-system : lando
204 lines
5.1 KiB
JavaScript
204 lines
5.1 KiB
JavaScript
"use strict";
|
|
|
|
ChromeUtils.import("resource://normandy/actions/BaseAction.jsm", this);
|
|
ChromeUtils.import("resource://normandy/lib/Uptake.jsm", this);
|
|
|
|
class NoopAction extends BaseAction {
|
|
_run(recipe) {
|
|
// does nothing
|
|
}
|
|
}
|
|
|
|
class FailPreExecutionAction extends BaseAction {
|
|
constructor() {
|
|
super();
|
|
this._testRunFlag = false;
|
|
this._testFinalizeFlag = false;
|
|
}
|
|
|
|
_preExecution() {
|
|
throw new Error("Test error");
|
|
}
|
|
|
|
_run() {
|
|
this._testRunFlag = true;
|
|
}
|
|
|
|
_finalize() {
|
|
this._testFinalizeFlag = true;
|
|
}
|
|
}
|
|
|
|
class FailRunAction extends BaseAction {
|
|
constructor() {
|
|
super();
|
|
this._testRunFlag = false;
|
|
this._testFinalizeFlag = false;
|
|
}
|
|
|
|
_run(recipe) {
|
|
throw new Error("Test error");
|
|
}
|
|
|
|
_finalize() {
|
|
this._testFinalizeFlag = true;
|
|
}
|
|
}
|
|
|
|
class FailFinalizeAction extends BaseAction {
|
|
_run(recipe) {
|
|
// does nothing
|
|
}
|
|
|
|
_finalize() {
|
|
throw new Error("Test error");
|
|
}
|
|
}
|
|
|
|
let _recipeId = 1;
|
|
function recipeFactory(overrides) {
|
|
let defaults = {
|
|
id: _recipeId++,
|
|
arguments: {},
|
|
};
|
|
Object.assign(defaults, overrides);
|
|
return defaults;
|
|
}
|
|
|
|
// Test that per-recipe uptake telemetry is recorded
|
|
decorate_task(
|
|
withStub(Uptake, "reportRecipe"),
|
|
async function(reportRecipeStub) {
|
|
const action = new NoopAction();
|
|
const recipe = recipeFactory();
|
|
await action.runRecipe(recipe);
|
|
Assert.deepEqual(
|
|
reportRecipeStub.args,
|
|
[[recipe.id, Uptake.RECIPE_SUCCESS]],
|
|
"per-recipe uptake telemetry should be reported",
|
|
);
|
|
},
|
|
);
|
|
|
|
// Finalize causes action telemetry to be recorded
|
|
decorate_task(
|
|
withStub(Uptake, "reportAction"),
|
|
async function(reportActionStub) {
|
|
const action = new NoopAction();
|
|
await action.finalize();
|
|
ok(action.finalized, "Action should be marked as finalized");
|
|
Assert.deepEqual(
|
|
reportActionStub.args,
|
|
[[action.name, Uptake.ACTION_SUCCESS]],
|
|
"action uptake telemetry should be reported",
|
|
);
|
|
},
|
|
);
|
|
|
|
// Recipes can't be run after finalize is called
|
|
decorate_task(
|
|
withStub(Uptake, "reportRecipe"),
|
|
async function(reportRecipeStub) {
|
|
const action = new NoopAction();
|
|
const recipe1 = recipeFactory();
|
|
const recipe2 = recipeFactory();
|
|
|
|
await action.runRecipe(recipe1);
|
|
await action.finalize();
|
|
|
|
await Assert.rejects(
|
|
action.runRecipe(recipe2),
|
|
/^Error: Action has already been finalized$/,
|
|
"running recipes after finalization is an error",
|
|
);
|
|
|
|
Assert.deepEqual(
|
|
reportRecipeStub.args,
|
|
[[recipe1.id, Uptake.RECIPE_SUCCESS]],
|
|
"Only recipes executed prior to finalizer should report uptake telemetry",
|
|
);
|
|
},
|
|
);
|
|
|
|
// Test an action with a failing pre-execution step
|
|
decorate_task(
|
|
withStub(Uptake, "reportRecipe"),
|
|
withStub(Uptake, "reportAction"),
|
|
async function(reportRecipeStub, reportActionStub) {
|
|
const recipe = recipeFactory();
|
|
const action = new FailPreExecutionAction();
|
|
ok(action.failed, "Action should fail during pre-execution fail");
|
|
|
|
// Should not throw, even though the action is in a failed state.
|
|
await action.runRecipe(recipe);
|
|
|
|
// Should not throw, even though the action is in a failed state.
|
|
await action.finalize();
|
|
|
|
is(action._testRunFlag, false, "_run should not have been caled");
|
|
is(action._testFinalizeFlag, false, "_finalize should not have been caled");
|
|
|
|
Assert.deepEqual(
|
|
reportRecipeStub.args,
|
|
[[recipe.id, Uptake.RECIPE_ACTION_DISABLED]],
|
|
"Recipe should report recipe status as action disabled",
|
|
);
|
|
|
|
Assert.deepEqual(
|
|
reportActionStub.args,
|
|
[[action.name, Uptake.ACTION_PRE_EXECUTION_ERROR]],
|
|
"Action should report pre execution error",
|
|
);
|
|
},
|
|
);
|
|
|
|
// Test an action with a failing recipe step
|
|
decorate_task(
|
|
withStub(Uptake, "reportRecipe"),
|
|
withStub(Uptake, "reportAction"),
|
|
async function(reportRecipeStub, reportActionStub) {
|
|
const recipe = recipeFactory();
|
|
const action = new FailRunAction();
|
|
await action.runRecipe(recipe);
|
|
await action.finalize();
|
|
ok(!action.failed, "Action should not be marked as failed due to a recipe failure");
|
|
|
|
ok(action._testFinalizeFlag, "_finalize should have been called");
|
|
|
|
Assert.deepEqual(
|
|
reportRecipeStub.args,
|
|
[[recipe.id, Uptake.RECIPE_EXECUTION_ERROR]],
|
|
"Recipe should report recipe execution error",
|
|
);
|
|
|
|
Assert.deepEqual(
|
|
reportActionStub.args,
|
|
[[action.name, Uptake.ACTION_SUCCESS]],
|
|
"Action should report success",
|
|
);
|
|
},
|
|
);
|
|
|
|
// Test an action with a failing finalize step
|
|
decorate_task(
|
|
withStub(Uptake, "reportRecipe"),
|
|
withStub(Uptake, "reportAction"),
|
|
async function(reportRecipeStub, reportActionStub) {
|
|
const recipe = recipeFactory();
|
|
const action = new FailFinalizeAction();
|
|
await action.runRecipe(recipe);
|
|
await action.finalize();
|
|
|
|
Assert.deepEqual(
|
|
reportRecipeStub.args,
|
|
[[recipe.id, Uptake.RECIPE_SUCCESS]],
|
|
"Recipe should report success",
|
|
);
|
|
|
|
Assert.deepEqual(
|
|
reportActionStub.args,
|
|
[[action.name, Uptake.ACTION_POST_EXECUTION_ERROR]],
|
|
"Action should report post execution error",
|
|
);
|
|
},
|
|
);
|