Skip to content

Commit 2660676

Browse files
Merge pull request #856 from browserstack/use_unzipper_fallback_with_decompress
Use unzipper fallback with decompress
2 parents 839e6c7 + e9fcb29 commit 2660676

File tree

4 files changed

+91
-15
lines changed

4 files changed

+91
-15
lines changed

bin/helpers/buildArtifacts.js

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const logger = require('./logger').winstonLogger,
1010

1111
const request = require('request');
1212
const decompress = require('decompress');
13-
13+
const unzipper = require("unzipper");
1414

1515
let BUILD_ARTIFACTS_TOTAL_COUNT = 0;
1616
let BUILD_ARTIFACTS_FAIL_COUNT = 0;
@@ -121,13 +121,15 @@ const downloadAndUnzip = async (filePath, fileName, url) => {
121121
reject(err);
122122
});
123123
writer.on('close', async () => {
124-
if (!error) {
125-
await unzipFile(filePath, fileName);
126-
fs.unlinkSync(tmpFilePath);
127-
resolve(true);
124+
try {
125+
if (!error) {
126+
await unzipFile(filePath, fileName);
127+
fs.unlinkSync(tmpFilePath);
128+
}
129+
} catch (error) {
130+
reject(error);
128131
}
129-
//no need to call the reject here, as it will have been called in the
130-
//'error' stream;
132+
resolve(true);
131133
});
132134
}
133135
});
@@ -136,13 +138,25 @@ const downloadAndUnzip = async (filePath, fileName, url) => {
136138

137139
const unzipFile = async (filePath, fileName) => {
138140
return new Promise( async (resolve, reject) => {
139-
await decompress(path.join(filePath, fileName), filePath)
140-
.then((files) => {
141+
try {
142+
await decompress(path.join(filePath, fileName), filePath);
141143
resolve();
142-
})
143-
.catch((error) => {
144-
reject(error);
145-
});
144+
} catch (error) {
145+
logger.debug(`Error unzipping with decompress, trying with unzipper. Stacktrace: ${error}.`);
146+
try {
147+
fs.createReadStream(path.join(filePath, fileName))
148+
.pipe(unzipper.Extract({ path: filePath }))
149+
.on("close", () => {
150+
resolve();
151+
})
152+
.on("error", (err) => {
153+
reject(err);
154+
});
155+
} catch (unzipperError) {
156+
logger.debug(`Unzipper package error: ${unzipperError}`);
157+
reject(Constants.userMessages.BUILD_ARTIFACTS_UNZIP_FAILURE);
158+
}
159+
}
146160
});
147161
}
148162

bin/helpers/constants.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ const userMessages = {
123123
CYPRESS_PORT_WARNING:
124124
"The requested port number <x> is ignored. The default BrowserStack port will be used for this execution",
125125
CYPRESS_INTERACTIVE_SESSION_CONFLICT_VALUES:
126-
"Conflicting values (True & False) were found for the interactive_debugging capability. Please resolve this issue to proceed further."
126+
"Conflicting values (True & False) were found for the interactive_debugging capability. Please resolve this issue to proceed further.",
127+
BUILD_ARTIFACTS_UNZIP_FAILURE: "Failed to unzip build artifacts.",
127128
};
128129

129130
const validationMessages = {

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
"windows-release": "^5.1.0",
3535
"winston": "2.4.4",
3636
"yargs": "14.2.3",
37-
"decompress": "4.2.1"
37+
"decompress": "4.2.1",
38+
"unzipper": "^0.12.3"
3839
},
3940
"repository": {
4041
"type": "git",
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
const { expect } = require("chai");
2+
const chai = require("chai"),
3+
chaiAsPromised = require("chai-as-promised"),
4+
sinon = require('sinon'),
5+
rewire = require('rewire');
6+
7+
const logger = require("../../../../bin/helpers/logger").winstonLogger;
8+
9+
chai.use(chaiAsPromised);
10+
logger.transports["console.info"].silent = true;
11+
12+
describe('unzipFile', () => {
13+
let unzipFile;
14+
let decompressStub;
15+
let createReadStreamStub;
16+
let unzipperStub;
17+
let loggerStub;
18+
let pathJoinStub;
19+
let Constants;
20+
21+
const filePath = '/some/path';
22+
const fileName = 'file.zip';
23+
24+
beforeEach(() => {
25+
const unzipFileModule = rewire('../../../../bin/helpers/buildArtifacts');
26+
27+
decompressStub = sinon.stub();
28+
createReadStreamStub = sinon.stub();
29+
unzipperStub = {
30+
Extract: sinon.stub(),
31+
};
32+
loggerStub = { debug: sinon.stub() };
33+
pathJoinStub = sinon.stub().returns(`${filePath}/${fileName}`);
34+
35+
Constants = {
36+
userMessages: {
37+
BUILD_ARTIFACTS_UNZIP_FAILURE: 'Unzip failed',
38+
},
39+
};
40+
41+
// Injecting the dependencies
42+
unzipFileModule.__set__('decompress', decompressStub);
43+
unzipFileModule.__set__('fs.createReadStream', createReadStreamStub);
44+
unzipFileModule.__set__('unzipper', unzipperStub);
45+
unzipFileModule.__set__('logger', loggerStub);
46+
unzipFileModule.__set__('path.join', pathJoinStub);
47+
unzipFileModule.__set__('Constants', Constants);
48+
49+
unzipFile = unzipFileModule.__get__('unzipFile');
50+
});
51+
52+
it('should successfully unzip using decompress', async () => {
53+
decompressStub.resolves();
54+
55+
await unzipFile(filePath, fileName);
56+
57+
expect(decompressStub.calledWith(`${filePath}/${fileName}`, filePath)).to.be.true;
58+
});
59+
60+
});

0 commit comments

Comments
 (0)