Skip to content

Commit a5e335b

Browse files
Vishalghyvrpl
authored andcommittedJul 20, 2020
fix: Cleanup old web-ext run artifacts dir when we are connecting to an android device
1 parent 29798cb commit a5e335b

File tree

6 files changed

+223
-1
lines changed

6 files changed

+223
-1
lines changed
 

‎src/cmd/run.js

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export type CmdRunParams = {|
4545
adbPort?: string,
4646
adbDevice?: string,
4747
adbDiscoveryTimeout?: number,
48+
adbCleanArtifacts?: boolean,
4849
firefoxApk?: string,
4950
firefoxApkComponent?: string,
5051

@@ -87,6 +88,7 @@ export default async function run(
8788
adbPort,
8889
adbDevice,
8990
adbDiscoveryTimeout,
91+
adbCleanArtifacts,
9092
firefoxApk,
9193
firefoxApkComponent,
9294
// Chromium CLI options.
@@ -165,6 +167,7 @@ export default async function run(
165167
adbPort,
166168
adbBin,
167169
adbDiscoveryTimeout,
170+
adbCleanArtifacts,
168171

169172
// Injected dependencies.
170173
firefoxApp,

‎src/extension-runners/firefox-android.js

+28
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export type FirefoxAndroidExtensionRunnerParams = {|
7171
adbPort?: string,
7272
adbDevice?: string,
7373
adbDiscoveryTimeout?: number,
74+
adbCleanArtifacts?: boolean,
7475
firefoxApk?: string,
7576
firefoxApkComponent?: string,
7677

@@ -384,6 +385,30 @@ export class FirefoxAndroidExtensionRunner {
384385
await adbUtils.amForceStopAPK(selectedAdbDevice, selectedFirefoxApk);
385386
}
386387

388+
async adbOldArtifactsDir(removeArtifacts?: boolean) {
389+
const {
390+
adbUtils,
391+
selectedAdbDevice,
392+
} = this;
393+
394+
const foundDirectories = await adbUtils.checkOrCleanArtifacts(
395+
selectedAdbDevice, removeArtifacts
396+
);
397+
398+
if (!foundDirectories) {
399+
return;
400+
}
401+
if (removeArtifacts) {
402+
log.info('Old web-ext artifacts have been found and removed ' +
403+
`from ${selectedAdbDevice} device`);
404+
} else {
405+
log.warn(
406+
`Old artifacts directories have been found on ${selectedAdbDevice} ` +
407+
'device. Use --adb-clean-artifacts to remove them automatically.'
408+
);
409+
}
410+
}
411+
387412
async adbCheckRuntimePermissions() {
388413
const {
389414
adbUtils,
@@ -441,6 +466,9 @@ export class FirefoxAndroidExtensionRunner {
441466
customPrefs,
442467
});
443468

469+
//Checking for older artifacts
470+
await this.adbOldArtifactsDir(this.params.adbCleanArtifacts);
471+
444472
// Choose a artifacts dir name for the assets pushed to the
445473
// Android device.
446474
this.selectedArtifactsDir = await adbUtils.getOrCreateArtifactsDir(

‎src/program.js

+5
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,11 @@ Example: $0 --help run.
663663
type: 'number',
664664
requiresArg: true,
665665
},
666+
'adb-clean-artifacts': {
667+
describe: 'Remove old artifact directories from the adb device',
668+
demandOption: false,
669+
type: 'boolean',
670+
},
666671
'firefox-apk': {
667672
describe: (
668673
'Run a specific Firefox for Android APK. ' +

‎src/util/adb.js

+41-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
} from '../errors';
99
import {createLogger} from '../util/logger';
1010

11+
const DEVICE_DIR_BASE = '/sdcard';
12+
const ARTIFACTS_DIR_PREFIX = '/web-ext-artifacts';
1113
const log = createLogger(__filename);
1214

1315
export type ADBUtilsParams = {|
@@ -195,7 +197,7 @@ export default class ADBUtils {
195197
return artifactsDir;
196198
}
197199

198-
artifactsDir = `/sdcard/web-ext-artifacts-${Date.now()}`;
200+
artifactsDir = `${DEVICE_DIR_BASE}${ARTIFACTS_DIR_PREFIX}-${Date.now()}`;
199201

200202
const testDirOut = (await this.runShellCommand(
201203
deviceId, `test -d ${artifactsDir} ; echo $?`
@@ -215,6 +217,44 @@ export default class ADBUtils {
215217
return artifactsDir;
216218
}
217219

220+
async checkOrCleanArtifacts(
221+
deviceId: string, remove?: boolean
222+
): Promise<boolean> {
223+
const {adbClient} = this;
224+
225+
let found = false;
226+
log.debug('Finding older artifacts');
227+
228+
return wrapADBCall(async () => {
229+
const files = await adbClient.readdir(deviceId, DEVICE_DIR_BASE);
230+
231+
for (const file of files) {
232+
if (!file.isDirectory() ||
233+
!file.name.startsWith('web-ext-artifacts-')) {
234+
continue;
235+
}
236+
237+
if (!remove) {
238+
return true;
239+
}
240+
241+
found = true;
242+
243+
const artifactsDir = `${DEVICE_DIR_BASE}/${file.name}`;
244+
245+
log.debug(
246+
`Removing ${artifactsDir} artifacts directory on ${deviceId} device`
247+
);
248+
249+
await this.runShellCommand(deviceId, [
250+
'rm', '-rf', artifactsDir,
251+
]);
252+
}
253+
254+
return found;
255+
});
256+
}
257+
218258
async clearArtifactsDir(deviceId: string): Promise<void> {
219259
const artifactsDir = this.artifactsDirMap.get(deviceId);
220260

‎tests/unit/test-extension-runners/test.firefox-android.js

+76
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ function prepareSelectedDeviceAndAPKParams(
130130
startFirefoxAPK: sinon.spy(() => Promise.resolve()),
131131
setupForward: sinon.spy(() => Promise.resolve()),
132132
clearArtifactsDir: sinon.spy(() => Promise.resolve()),
133+
checkOrCleanArtifacts: sinon.spy(
134+
() => Promise.resolve(true)
135+
),
133136
setUserAbortDiscovery: sinon.spy(() => {}),
134137
ensureRequiredAPKRuntimePermissions: sinon.spy(() => Promise.resolve()),
135138
...adbOverrides,
@@ -357,6 +360,79 @@ describe('util/extension-runners/firefox-android', () => {
357360
);
358361
});
359362

363+
it('check for older artifacts', async () => {
364+
const adbOverrides = {
365+
getOrCreateArtifactsDir: sinon.spy(
366+
() => Promise.resolve('/sdcard/web-ext-dir')
367+
),
368+
};
369+
const overriddenProperties = {
370+
params: {
371+
adbDevice: 'emulator-1',
372+
firefoxApk: 'org.mozilla.firefox',
373+
buildSourceDir: sinon.spy(() => Promise.resolve({
374+
extensionPath: fakeBuiltExtensionPath,
375+
})),
376+
adbCleanArtifacts: false,
377+
},
378+
};
379+
const {
380+
params, fakeADBUtils,
381+
} = prepareSelectedDeviceAndAPKParams(
382+
overriddenProperties, adbOverrides
383+
);
384+
385+
const runnerInstance = new FirefoxAndroidExtensionRunner(params);
386+
await runnerInstance.run();
387+
388+
sinon.assert.calledWithMatch(
389+
fakeADBUtils.checkOrCleanArtifacts,
390+
'emulator-1',
391+
false,
392+
);
393+
394+
sinon.assert.callOrder(
395+
fakeADBUtils.amForceStopAPK,
396+
fakeADBUtils.checkOrCleanArtifacts
397+
);
398+
});
399+
it('remove plausible older artifacts', async () => {
400+
const adbOverrides = {
401+
getOrCreateArtifactsDir: sinon.spy(
402+
() => Promise.resolve('/sdcard/web-ext-dir')
403+
),
404+
};
405+
const overriddenProperties = {
406+
params: {
407+
adbDevice: 'emulator-1',
408+
firefoxApk: 'org.mozilla.firefox',
409+
buildSourceDir: sinon.spy(() => Promise.resolve({
410+
extensionPath: fakeBuiltExtensionPath,
411+
})),
412+
adbCleanArtifacts: true,
413+
},
414+
};
415+
const {
416+
params, fakeADBUtils,
417+
} = prepareSelectedDeviceAndAPKParams(
418+
overriddenProperties, adbOverrides
419+
);
420+
421+
const runnerInstance = new FirefoxAndroidExtensionRunner(params);
422+
await runnerInstance.run();
423+
424+
sinon.assert.calledWithMatch(
425+
fakeADBUtils.checkOrCleanArtifacts,
426+
'emulator-1',
427+
true,
428+
);
429+
430+
sinon.assert.callOrder(
431+
fakeADBUtils.amForceStopAPK,
432+
fakeADBUtils.checkOrCleanArtifacts
433+
);
434+
});
435+
360436
it('does run a specific apk component if specific', async () => {
361437
const {
362438
params, fakeADBUtils,

‎tests/unit/test-util/test.adb.js

+70
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ function getFakeADBKit(
6464
return [];
6565
}),
6666
shell: sinon.spy(() => Promise.resolve('')),
67+
readdir: sinon.spy(() => Promise.resolve([])),
6768
startActivity: sinon.spy(() => {}),
6869
forward: sinon.spy(() => {}),
6970
push: sinon.spy(() => {
@@ -622,6 +623,75 @@ describe('utils/adb', () => {
622623
});
623624
});
624625

626+
describe('checkOrCleanArtifacts', () => {
627+
const artifactDir = `web-ext-artifacts-${Date.now()}`;
628+
function makeFakeArtifact(artifactName, isDirectory) {
629+
return {
630+
name: artifactName,
631+
isDirectory: () => {
632+
return isDirectory;
633+
},
634+
};
635+
}
636+
const files = [
637+
makeFakeArtifact(artifactDir.concat('fake-dir1'), true),
638+
makeFakeArtifact(artifactDir.concat('fake-dir2'), true),
639+
makeFakeArtifact(artifactDir.concat('fake-file1'), false),
640+
makeFakeArtifact('not-web-ext-artifacts-dir', true),
641+
];
642+
643+
it('checks old artifacts', async () => {
644+
const adb = getFakeADBKit({
645+
adbClient: {
646+
readdir: sinon.spy(() => Promise.resolve(files)),
647+
shell: sinon.spy(() => Promise.resolve('')),
648+
},
649+
adbkitUtil: {
650+
readAll: sinon.spy(() => Promise.resolve(Buffer.from('1\n'))),
651+
},
652+
});
653+
const adbUtils = new ADBUtils({adb});
654+
655+
const promise = adbUtils.checkOrCleanArtifacts('device1', false);
656+
const result = await assert.isFulfilled(promise);
657+
assert.equal(result, true);
658+
659+
sinon.assert.calledOnce(adb.fakeADBClient.readdir);
660+
//While checking of files shell shoudln't be called
661+
sinon.assert.notCalled(adb.fakeADBClient.shell);
662+
});
663+
664+
it('removes plausible artifacts directory', async () => {
665+
const adb = getFakeADBKit({
666+
adbClient: {
667+
readdir: sinon.spy(() => Promise.resolve(files)),
668+
shell: sinon.spy(() => Promise.resolve('')),
669+
},
670+
adbkitUtil: {
671+
readAll: sinon.spy(() => Promise.resolve(Buffer.from('1\n'))),
672+
},
673+
});
674+
const adbUtils = new ADBUtils({adb});
675+
const artifactDirFullPath1 = `/sdcard/${artifactDir}fake-dir1`;
676+
const artifactDirFullPath2 = `/sdcard/${artifactDir}fake-dir2`;
677+
678+
const promise = adbUtils.checkOrCleanArtifacts('device1', true);
679+
const result = await assert.isFulfilled(promise);
680+
assert.equal(result, true);
681+
682+
sinon.assert.calledOnce(adb.fakeADBClient.readdir);
683+
sinon.assert.calledTwice(adb.fakeADBClient.shell);
684+
sinon.assert.calledWithMatch(
685+
adb.fakeADBClient.shell, 'device1',
686+
['rm', '-rf', artifactDirFullPath1]
687+
);
688+
sinon.assert.calledWithMatch(
689+
adb.fakeADBClient.shell, 'device1',
690+
['rm', '-rf', artifactDirFullPath2]
691+
);
692+
});
693+
});
694+
625695
describe('pushFile', () => {
626696
it('rejects an UsageError on adb binary not found', async () => {
627697
const adb = await testSpawnADBUsageError({

0 commit comments

Comments
 (0)
Please sign in to comment.