Skip to content

Commit

Permalink
Dont use context in failed tests relaunch
Browse files Browse the repository at this point in the history
  • Loading branch information
schipiga committed Jul 26, 2018
1 parent 5ea1488 commit 7bc36a1
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 170 deletions.
13 changes: 12 additions & 1 deletion lib/config.js
Expand Up @@ -131,6 +131,12 @@ const args = config.args;

if (U.config.__testmode) config = {}; // not affect global config in test mode

config.counters = U.defVal(config.counters, {});
config.counters.testId = 0;
config.counters.chunkId = 0;
config.counters.curChunkId = null;
config.counters.passedChunkIds = [];

config.session = U.defVal(config.session, {});
const date = new Date();
config.session.name = U.defVal(args.sessionName, `Session ${date.toLocaleString()}`);
Expand All @@ -145,7 +151,6 @@ expect([ "log", "fail", "mocha" ],
"Invalid `--uncaught` option").include(config.session.uncaughtException);
if (args.rootConftest) config.session.rootConftest = path.resolve(U.cwd, args.rootConftest);
if (args.killProcs) config.session.killProcs = U.splitBy(args.killProcs, ",");
config.session.__passedChunkIds = [];

const get_targets = () => {
let tt;
Expand Down Expand Up @@ -197,6 +202,12 @@ config.filter.grep = args.g || args.grep;
config.filter.precise = args.precise || false;
if (args.include) config.filter.include = tests_filter(args.include);
if (args.exclude) config.filter.exclude = tests_filter(args.exclude);
if (config.filter.include) {
for (const include of config.filter.include) {
if (!include.passed_chunk_ids) continue;
config.counters.passedChunkIds = config.counters.passedChunkIds.concat(include.passed_chunk_ids);
}
}

config.xunit = U.defVal(config.xunit, {});
config.xunit.use = U.defVal(args.xunit, false);
Expand Down
16 changes: 6 additions & 10 deletions lib/globals/chunk.js
Expand Up @@ -67,24 +67,20 @@ var chunk = (name, opts, func) => {
name = name || "";
opts = opts || {};

CONF.test.__chunkId[1]++;
const chunkId = CONF.test.__chunkId.join("_");
if (CONF.session.__passedChunkIds.includes(chunkId)) return;
CONF.counters.chunkId++;
const chunkId = CONF.counters.testId + "_" + CONF.counters.chunkId;
if (CONF.counters.passedChunkIds.includes(chunkId)) return;

const func_ = () => {
CONF.test.__curChunkId = chunkId;
return func();
};

it(name, _chunkCb(name, opts, func_));
it(name, _chunkCb(name, chunkId, opts, func));
};

/**
* Chunk callback.
* @ignore
*/
var _chunkCb = (name, opts, func) => function () {
var _chunkCb = (name, chunkId, opts, func) => function () {
CONF.test.curCase.addChunk(name);
CONF.counters.curChunkId = chunkId;

if (opts.retry) this.retries(opts.retry);
if (opts.timeout) this.timeout(opts.timeout * 1000);
Expand Down
20 changes: 9 additions & 11 deletions lib/globals/forEachLanguage.js
Expand Up @@ -27,11 +27,11 @@ var CONF = require("../config");
* });
* });
*/
var forEachLanguage = (ctx, opts, fixtures, func) => {
var forEachLanguage = (name, opts, fixtures, func) => {

if (ctx instanceof Function) {
func = ctx;
ctx = {};
if (name instanceof Function) {
func = name;
name = null;
opts = {};
fixtures = [];
}
Expand All @@ -47,18 +47,16 @@ var forEachLanguage = (ctx, opts, fixtures, func) => {
fixtures = [];
}

ctx = ctx || {};
name = name || null;
opts = opts || {};
fixtures = fixtures || [];

var languages = ctx.language ? [ctx.language]
: (opts.languages || CONF.test.languages);

languages.forEach(_langCb(fixtures, func));
(opts.languages || CONF.test.languages).forEach(_langCb(name, fixtures, func));
};

var _langCb = (fixtures, func) => lang => {
scope(`for language "${lang}"`, () => {
var _langCb = (name, fixtures, func) => lang => {
name = name || "for language";
scope(`${name} "${lang}"`, () => {
before(() => {
if (CONF.test.curCase) {
CONF.test.curCase.testParams.language = lang;
Expand Down
34 changes: 8 additions & 26 deletions lib/globals/test.js
Expand Up @@ -13,6 +13,8 @@ const ScopeType = require("../testing").ScopeType;
const retryTests = require("./session").retryTests;
const _scope = require("./scope");

let GID = 0;

/**
* Helper to set actual log file.
*
Expand Down Expand Up @@ -50,14 +52,15 @@ setLog(); // Set log immediately.
*/
const baseTest = (names => {
return (name, opts, fixtures, func) => {
GID++;

const o = {};

if (CONF.filter.include) {
let isIncluded = false;
for (const include of CONF.filter.include) {
if (isFilterMatched(name, include.name)) {
isIncluded = true;
o.ctxs = include.params;
break;
}
}
Expand Down Expand Up @@ -98,7 +101,7 @@ const baseTest = (names => {
o.testOpts.chunkRetry = U.defVal(opts.chunkRetry, CONF.test.chunkRetries, 0);
o.testOpts.chunkTimeout = U.defVal(opts.chunkTimeout);

o.testCase = new TestCase(name);
o.testCase = new TestCase(name, GID);
CONF.test.cases.push(o.testCase);

if (skip) {
Expand All @@ -112,28 +115,17 @@ const baseTest = (names => {
})([]);

const testFunc = o => {
if (o.func.__testId) {
CONF.test.__chunkId[0] = o.func.__testId;
} else {
CONF.test.__chunkId[0]++;
o.func.__testId = CONF.test.__chunkId[0];
}
CONF.test.__chunkId[1] = 0;
CONF.counters.testId = o.testCase.id;
CONF.counters.chunkId = 0;

o.ctxs = o.ctxs || [{}];
_scope(new ScopeType(o.name).setType("test"), o.testOpts, () => {
before(beforeCb(o));
U.wrap(o.fixtures, wrapCb(o))();
U.wrap(o.fixtures, o.func)();
after(afterCb(o));
});
};

const beforeCb = o => () => {
if (o.testCase.hasFailedParams()) {
o.failedParams = o.testCase.failedParams;
} else {
o.failedParams = o.ctxs;
}
o.testCase.reset();
o.testCase.start();
CONF.test.curCase = o.testCase;
Expand All @@ -154,19 +146,9 @@ const afterCb = o => () => {
return;
}
o.retries--;

if (!o.testCase.hasFailedParams()) {
o.testCase.failedParams = o.failedParams;
}

o.ctxs = o.testCase.failedParams;
retryTests.push({ func: testFunc, args: o });
};

const wrapCb = o => () => {
for (const ctx of o.ctxs) o.func(ctx);
};

/**
* Executes test case.
*
Expand Down
12 changes: 8 additions & 4 deletions lib/reporter/base.js
Expand Up @@ -98,8 +98,14 @@ const GlaceReporter = function (runner) {
});

runner.on("pass", mochaTest => {
if (!CONF.session.__passedChunkIds.includes(CONF.test.__curChunkId)) {
CONF.session.__passedChunkIds.push(CONF.test.__curChunkId);
if (CONF.counters.curChunkId &&
!CONF.counters.passedChunkIds.includes(CONF.counters.curChunkId)) {
CONF.counters.passedChunkIds.push(CONF.counters.curChunkId);

if (CONF.test.curCase) {
CONF.test.curCase.addPassedChunkId(CONF.counters.curChunkId);
}
CONF.counters.curChunkId = null;
}

if (CONF.test.curCase && CONF.test.curCase.skipChunk === mochaTest.title) {
Expand Down Expand Up @@ -132,8 +138,6 @@ const GlaceReporter = function (runner) {
}

CONF.test.curCase.addError(errMsg);
CONF.test.curCase.addFailedParams(
_.clone(CONF.test.curCase.testParams));
} else {
sessErrsNum++;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/reporter/stdout.js
Expand Up @@ -116,8 +116,8 @@ const epilogue = () => {
stdout(err.red.bold);
}
const data = { name: testCase.name };
if (!_.isEmpty(testCase.failedParams[0])) {
data.params = testCase.failedParams;
if (!_.isEmpty(testCase.passedChunkIds)) {
data.passed_chunk_ids = testCase.passedChunkIds;
}
failedTestsJson.push(data);
}
Expand Down
28 changes: 8 additions & 20 deletions lib/testing.js
Expand Up @@ -5,7 +5,6 @@
* @module
*/

var _ = require("lodash");
var expect = require("chai").expect;
/**
* Test case data structure.
Expand All @@ -21,15 +20,16 @@ var expect = require("chai").expect;
* @prop {string[]} [videos=[]] - List of test video paths.
* @prop {string[]} [errors=[]] - List of test errors.
* @prop {string[]} [rawInfo=[]] - List of additional test details.
* @prop {object[]} [failedParams=[]] - List of test failed parameters.
* @prop {object} [testParams={}] - Dict of test parameters.
*/
var TestCase = module.exports.TestCase = function (name) {
var TestCase = module.exports.TestCase = function (name, id) {
this.duration = 0;
this.name = name;
this.id = id;
this.status = TestCase.NOT_STARTED;
this.skipChunk = null;
this.chunks = [];
this.passedChunkIds = [];
this.reset();
};
/**
Expand Down Expand Up @@ -68,20 +68,17 @@ TestCase.prototype.reset = function () {
this.videos = [];
this.errors = [];
this.rawInfo = [];
this.failedParams = [];
this.testParams = {};
};
/**
* Adds failed params if they don't exist.
* Adds passed chunk id.
*
* @method
* @arg {object} params - Parameters which test was failed with.
* @arg {string} chunk_id - Chunk id.
*/
TestCase.prototype.addFailedParams = function (params) {
for (var failed of this.failedParams) {
if (_.isEqual(params, failed)) return;
}
this.failedParams.push(params);
TestCase.prototype.addPassedChunkId = function (chunkId) {
if (!chunkId || this.passedChunkIds.includes(chunkId)) return;
this.passedChunkIds.push(chunkId);
};
/**
* Adds error to test case.
Expand Down Expand Up @@ -128,15 +125,6 @@ TestCase.prototype.addDetails = function (info) {
TestCase.prototype.addChunk = function (chunkName) {
this.chunks.push(chunkName);
};
/**
* Defines if test case has failed params or no.
*
* @method
* @returns {boolean}
*/
TestCase.prototype.hasFailedParams = function () {
return !((this.failedParams.length < 2) && _.isEmpty(this.failedParams[0]));
};

TestCase.NOT_STARTED = "not started";
TestCase.IN_PROGRESS = "in progress";
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/testRetryWithInclude.js
Expand Up @@ -4,7 +4,7 @@ CONF.test.languages = ["en", "ru", "ee"];

var i = 0;

test("retry only include params", ctx => {
test("retry only include params", () => {

before(() => {
i++;
Expand All @@ -13,7 +13,7 @@ test("retry only include params", ctx => {
}
});

forEachLanguage(ctx, () => {
forEachLanguage(() => {
chunk(() => {});
});
});

0 comments on commit 7bc36a1

Please sign in to comment.