Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mixed-platform fixture support #28

Merged
merged 4 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion lib/device.js
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,11 @@ class DeviceManager {
} else {
platforms = this._devicePool;
}
const devs = platforms.get(platform.id);
let id = platform.id;
if (platform.mixed && Array.from(platforms.keys()).length === 1) {
id = Array.from(platforms.keys())[0];
}
const devs = platforms.get(id);
if (!devs || !devs.length) {
throw new Error('No devices available for the target platform');
}
Expand Down Expand Up @@ -756,6 +760,17 @@ class DeviceManager {
dev.setAttached(attached);
}
}

getPlatformsForFixtures(fixtures) {
const platforms = [];
for (const f of fixtures) {
const fixture = this._fixtures.get(f.name);
if (fixture) {
platforms.push(... fixture.keys());
}
}
return Array.from(new Set(platforms));
}
}

module.exports = {
Expand Down
31 changes: 26 additions & 5 deletions lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const { PlatformSuite } = require('./suite');
const { DeviceManager } = require('./device');
const { ApiClient } = require('./api');
const { Builder } = require('./build');
const { platformsForTag, isKnownPlatformTag, PLATFORMS, PLATFORM_TAGS } = require('./platform');
const { platformsForTag, isKnownPlatformTag, PLATFORMS, PLATFORM_TAGS, Platform } = require('./platform');
const { RunMode, OutputFormat, config, APP_NAME } = require('./config');
const { findTestName, shortenRight } = require('./util');
const { InternalError, isInternalError } = require('./error');
Expand Down Expand Up @@ -185,8 +185,6 @@ class Runner {
}

async _run() {
this._log.verbose('Generating test matrix');
this._initTestMatrix();
this._log.verbose('Initializing API client');
this._apiClient = new ApiClient({
log: this._log
Expand All @@ -198,6 +196,8 @@ class Runner {
log: this._log
});
await this._devMgr.init(this._enabledPlatforms);
this._log.verbose('Generating test matrix');
await this._initTestMatrix();
// Initialize the runner's context
const ctx = this._mocha.suite.ctx;
ctx.particle = {
Expand Down Expand Up @@ -401,7 +401,7 @@ class Runner {
runner.once(MochaRunner.constants.EVENT_RUN_END, runEnd);
}

_initTestMatrix() {
async _initTestMatrix() {
const suites = [];
const rootSuite = this._mocha.suite;
for (const srcSuite of rootSuite.suites) {
Expand All @@ -411,8 +411,29 @@ class Runner {
}
const file = particle.file;
const newSuite = srcSuite.clone(); // Doesn't copy tests and hooks
let platformsByFixture = this._devMgr.getPlatformsForFixtures(particle.fixtures);
let platforms = particle.platforms;
if (platformsByFixture && platformsByFixture.length > 1) {
// Mixed platforms
platformsByFixture = platforms.filter((v) => platformsByFixture.includes(v.id));
platforms = platformsByFixture;
let fakeId = 0;
const fakeName = platforms.map((v) => v.name).join('/');
const fakeDisplayName = platforms.map((v) => v.displayName).join(' / ');
const fakeTags = [... platforms.map((v) => v.tags)].flat(1);
for (let i = 0; i < platforms.length; i++) {
fakeId += platforms[i].id * (100 ** (i));
}
platforms = [new Platform({ id: fakeId, name: fakeName, displayName: fakeDisplayName, tags: fakeTags })];
// FIXME
platforms[0].mixed = true;
platforms[0].platforms = platformsByFixture;
} else if (platformsByFixture.length === 1) {
platforms = platforms.filter((v) => platformsByFixture.includes(v.id));
}

// Create a nested suite for each platform
for (const platform of particle.platforms) {
for (const platform of platforms) {
const platformSuite = MochaSuite.create(newSuite, platform.name);
platformSuite.particle = {
platform,
Expand Down
20 changes: 16 additions & 4 deletions lib/suite.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,9 @@ class PlatformSuite {
this._ctx.addDeviceTests(this._suite, tests);
}

async _flashApps() {
async _flashAppForPlatform(platform) {
const particle = this._suite.particle;
const suiteDir = path.dirname(particle.file);
const platform = particle.platform;
const apps = new Map();
// Find precompiled binaries
if (this._ctx.binaryDir) {
Expand Down Expand Up @@ -208,13 +207,15 @@ class PlatformSuite {
if (!app) {
throw new Error(`Application not found: ${appName}`);
}
devApps.push({ dev, app });
if (dev.platform.id === platform.id) {
devApps.push({ dev, app });
}
}
// Build applications
for (const devApp of devApps) {
const app = devApp.app;
if (app.build) {
this._log.verbose(`Building application: ${app.path}`);
this._log.verbose(`Building application for ${platform.name}: ${app.path}`);
app.path = await this._ctx.builder.buildApp({ appDir: app.path, platform });
app.build = false;
}
Expand Down Expand Up @@ -248,6 +249,17 @@ class PlatformSuite {
}
}

async _flashApps() {
const particle = this._suite.particle;
if (!particle.platform.mixed) {
return this._flashAppForPlatform(particle.platform);
} else {
for (const platform of particle.platform.platforms) {
await this._flashAppForPlatform(platform);
}
}
}

async _initDevices() {
this._ctx.devices = [];
this._ctx.fixtures = new Map();
Expand Down
2 changes: 1 addition & 1 deletion nyc.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
branches: 7,
lines: 10,
functions: 16,
functions: 15,
statements: 9
};
Loading