Skip to content

Commit e0fb8d8

Browse files
committed
t2 run/push: insert os or firmware version request into pipeline
Signed-off-by: Rick Waldron <[email protected]>
1 parent a34f744 commit e0fb8d8

File tree

7 files changed

+166
-16
lines changed

7 files changed

+166
-16
lines changed

lib/tessel/deploy.js

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ Tessel.prototype.memoryInfo = function() {
118118
* @return {Promise}
119119
*/
120120
Tessel.prototype.deploy = function(opts) {
121-
121+
/* istanbul ignore else */
122122
if (typeof opts.tessel === 'undefined') {
123123
opts.tessel = this;
124124
}
@@ -136,6 +136,7 @@ Tessel.prototype.deploy = function(opts) {
136136
return this.simpleExec(commands.app.stop())
137137
.catch(error => {
138138
// This _must_ be inline
139+
/* istanbul ignore else */
139140
if (error.length > 0) {
140141
throw new Error(`Remote command: ${commands.app.stop().join(' ')} failed.`);
141142
}
@@ -217,6 +218,7 @@ Tessel.prototype.restart = function(opts) {
217218
}
218219
})
219220
.catch((error) => {
221+
/* istanbul ignore else */
220222
if (error.message.includes('No such file or directory')) {
221223
error = `"${opts.entryPoint}" not found on ${this.name}`;
222224
}
@@ -256,11 +258,13 @@ exportables.findProject = function(opts) {
256258
// exist. The cost of the try/catch is negligible.
257259
isDirectory = fs.lstatSync(file).isDirectory();
258260
} catch (error) {
261+
/* istanbul ignore else */
259262
if (opts.lang.meta.isFile) {
260263
reject(error.message);
261264
}
262265
}
263266

267+
/* istanbul ignore if */
264268
if (isDirectory && single) {
265269
return reject('You can only push a single file, not a directory');
266270
}
@@ -280,6 +284,7 @@ exportables.findProject = function(opts) {
280284
relpath = path.join(path.basename(pushdir), relpath);
281285
pushdir = path.dirname(pushdir);
282286

287+
/* istanbul ignore if */
283288
if (pushdir === undefined) {
284289
pushdir = '';
285290
}
@@ -351,6 +356,7 @@ exportables.sendBundle = function(tessel, opts) {
351356

352357
// Calling receive to know when the process closes
353358
tessel.receive(remoteProcess, (err) => {
359+
/* istanbul ignore if */
354360
if (err) {
355361
return reject(err);
356362
} else {
@@ -389,6 +395,7 @@ exportables.run = function(tessel, options) {
389395
commands[lang.meta.extname].execute(Tessel.REMOTE_RUN_PATH, options.resolvedEntryPoint, options.subargs), {
390396
pty: true
391397
}, (error, remoteProcess) => {
398+
/* istanbul ignore if */
392399
if (error) {
393400
return reject(error);
394401
}
@@ -413,6 +420,7 @@ exportables.run = function(tessel, options) {
413420

414421
exportables.push = function(tessel, opts) {
415422
// Write the node start file
423+
/* istanbul ignore if */
416424
if (opts.resolvedEntryPoint === undefined) {
417425
opts.resolvedEntryPoint = opts.entryPoint;
418426
}
@@ -431,16 +439,18 @@ exportables.push = function(tessel, opts) {
431439
exportables.createShellScript = function(tessel, opts) {
432440
return new Promise((resolve, reject) => {
433441
// Open a stdin pipe tp the file
434-
tessel.connection.exec(commands.openStdinToFile(PUSH_START_SH_SCRIPT), (err, remoteProcess) => {
435-
if (err) {
436-
return reject(err);
442+
tessel.connection.exec(commands.openStdinToFile(PUSH_START_SH_SCRIPT), (error, remoteProcess) => {
443+
/* istanbul ignore if */
444+
if (error) {
445+
return reject(error);
437446
}
438447
// When the remote process finishes
439448
remoteProcess.once('close', () => {
440449
// Set the perimissions on the file to be executable
441-
tessel.connection.exec(commands.chmod('+x', PUSH_START_SH_SCRIPT), (err, remoteProcess) => {
442-
if (err) {
443-
return reject(err);
450+
tessel.connection.exec(commands.chmod('+x', PUSH_START_SH_SCRIPT), (error, remoteProcess) => {
451+
/* istanbul ignore if */
452+
if (error) {
453+
return reject(error);
444454
}
445455
// When that process completes
446456
remoteProcess.once('close', () => {

lib/tessel/deployment/javascript.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ var log = require('../../log');
2727
var provision = require('../provision'); // jshint ignore:line
2828
var remote = require('../../remote');
2929
var Tessel = require('../tessel');
30+
var updates = require('../../update-fetch');
3031

3132
var binaryModulesUsed = new Map();
3233
var isWindows = process.platform.startsWith('win');
@@ -210,6 +211,7 @@ exportables.resolveBinaryModules = function(opts) {
210211
// Unless there is a specific `binary.module_path`.
211212
// Checking this only matters when the glob patterns
212213
// didn't turn up a .node binary.
214+
/* istanbul ignore if */
213215
if (packageJson.binary && packageJson.binary.module_path) {
214216
buildPath = path.normalize(packageJson.binary.module_path);
215217
if (buildPath[0] === '.') {
@@ -285,7 +287,8 @@ exportables.resolveBinaryModules = function(opts) {
285287
path: details.extractPath,
286288
});
287289

288-
gunzip.on('error', function(error) {
290+
gunzip.on('error', (error) => {
291+
/* istanbul ignore else */
289292
if (error.code === 'Z_DATA_ERROR') {
290293
details.resolved = false;
291294

@@ -406,11 +409,16 @@ exportables.injectBinaryModules = function(globRoot, tempBundlePath, options) {
406409
};
407410

408411
exportables.preBundle = function(options) {
409-
return options.tessel.fetchNodeProcessVersions()
410-
.then(versions => {
411-
options.tessel.versions = versions;
412-
return exportables.resolveBinaryModules(options);
412+
return Promise.all([
413+
updates.requestBuildList(),
414+
options.tessel.fetchCurrentBuildInfo(),
415+
options.tessel.fetchNodeProcessVersions(),
416+
]).then(responses => {
417+
options.tessel.versions = Object.assign(responses[2], {
418+
build: updates.findBuild(responses[0], 'sha', responses[1]),
413419
});
420+
return exportables.resolveBinaryModules(options);
421+
});
414422
};
415423

416424
exportables.tarBundle = function(options) {
@@ -797,6 +805,7 @@ exportables.compress = function(source, options) {
797805
ast.compute_char_frequency(mangle);
798806
ast.mangle_names(mangle);
799807

808+
/* istanbul ignore if */
800809
if (special.rescope_after_mangle) {
801810
ast.figure_out_scope(mangle);
802811
}
@@ -807,6 +816,7 @@ exportables.compress = function(source, options) {
807816

808817
return stream.toString();
809818
} catch (error) {
819+
/* istanbul ignore next */
810820
return source;
811821
}
812822
};

lib/tessel/update.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@ var remoteVersioningFile = '/etc/tessel-version';
2121
Tessel.prototype.fetchCurrentBuildInfo = function() {
2222
// Read the version file
2323
return this.simpleExec(commands.readFile(remoteVersioningFile))
24-
.then(function fileRead(fileContents) {
25-
// Trim the file new line and return
26-
return fileContents.trim();
27-
});
24+
.then(fileContents => fileContents.trim());
2825
};
2926

3027
Tessel.prototype.update = function(opts, newImage) {

test/.jshintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
"tags": true,
9999
"tar": true,
100100
"Tessel": true,
101+
"tesselBuilds": true,
101102
"TesselSeeker": true,
102103
"TesselSimulator": true,
103104
"toml": true,

test/common/bootstrap.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,13 @@ global.processVersions = {
208208
modules: '46',
209209
openssl: '1.0.2d',
210210
};
211+
212+
global.tesselBuilds = [{
213+
released: '2016-09-21T19:40:32.992Z',
214+
sha: '40b2b46a62a34b5a26170c75f7e717cea673d1eb',
215+
version: '0.0.16'
216+
}, {
217+
sha: '9a85c84f5a03c715908921baaaa9e7397985bc7f',
218+
released: '2017-05-12T03:01:57.856Z',
219+
version: '0.0.17'
220+
}];

test/unit/deploy.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,9 @@ exports['Tessel.prototype.deploy'] = {
133133
this.tessel = TesselSimulator();
134134
this.end = sandbox.spy(this.tessel._rps.stdin, 'end');
135135

136+
this.fetchCurrentBuildInfo = sandbox.stub(this.tessel, 'fetchCurrentBuildInfo').returns(Promise.resolve('40b2b46a62a34b5a26170c75f7e717cea673d1eb'));
136137
this.fetchNodeProcessVersions = sandbox.stub(this.tessel, 'fetchNodeProcessVersions').returns(Promise.resolve(processVersions));
138+
this.requestBuildList = sandbox.stub(updates, 'requestBuildList').returns(Promise.resolve(tesselBuilds));
137139

138140
this.pWrite = sandbox.stub(Preferences, 'write').returns(Promise.resolve());
139141

test/unit/deployment/javascript.js

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ exports['Deployment: JavaScript'] = {
3838
this.tessel = TesselSimulator();
3939
this.end = sandbox.spy(this.tessel._rps.stdin, 'end');
4040

41+
this.fetchCurrentBuildInfo = sandbox.stub(this.tessel, 'fetchCurrentBuildInfo').returns(Promise.resolve('40b2b46a62a34b5a26170c75f7e717cea673d1eb'));
4142
this.fetchNodeProcessVersions = sandbox.stub(this.tessel, 'fetchNodeProcessVersions').returns(Promise.resolve(processVersions));
43+
this.requestBuildList = sandbox.stub(updates, 'requestBuildList').returns(Promise.resolve(tesselBuilds));
4244

4345
this.pWrite = sandbox.stub(Preferences, 'write').returns(Promise.resolve());
4446

@@ -1802,7 +1804,10 @@ exports['deploy.findProject'] = {
18021804
exports['deploy.sendBundle, error handling'] = {
18031805
setUp: function(done) {
18041806
this.tessel = TesselSimulator();
1807+
this.fetchCurrentBuildInfo = sandbox.stub(this.tessel, 'fetchCurrentBuildInfo').returns(Promise.resolve('40b2b46a62a34b5a26170c75f7e717cea673d1eb'));
18051808
this.fetchNodeProcessVersions = sandbox.stub(this.tessel, 'fetchNodeProcessVersions').returns(Promise.resolve(processVersions));
1809+
this.requestBuildList = sandbox.stub(updates, 'requestBuildList').returns(Promise.resolve(tesselBuilds));
1810+
18061811

18071812
this.pathResolve = sandbox.stub(path, 'resolve');
18081813
this.failure = 'FAIL';
@@ -1882,7 +1887,10 @@ exports['deployment.js.preBundle'] = {
18821887
callback();
18831888
});
18841889

1890+
this.fetchCurrentBuildInfo = sandbox.stub(this.tessel, 'fetchCurrentBuildInfo').returns(Promise.resolve('40b2b46a62a34b5a26170c75f7e717cea673d1eb'));
18851891
this.fetchNodeProcessVersions = sandbox.stub(this.tessel, 'fetchNodeProcessVersions').returns(Promise.resolve(processVersions));
1892+
this.requestBuildList = sandbox.stub(updates, 'requestBuildList').returns(Promise.resolve(tesselBuilds));
1893+
18861894

18871895
this.findProject = sandbox.stub(deploy, 'findProject').returns(Promise.resolve({
18881896
pushdir: '',
@@ -1916,6 +1924,44 @@ exports['deployment.js.preBundle'] = {
19161924
});
19171925
},
19181926

1927+
preBundleCallsfetchCurrentBuildInfoAndForwardsResult(test) {
1928+
test.expect(4);
1929+
1930+
deploy.sendBundle(this.tessel, {
1931+
target: '/',
1932+
entryPoint: 'foo.js',
1933+
lang: deployment.js
1934+
}).then(() => {
1935+
test.equal(this.fetchCurrentBuildInfo.callCount, 1);
1936+
test.equal(this.resolveBinaryModules.callCount, 1);
1937+
1938+
var args = this.resolveBinaryModules.lastCall.args[0];
1939+
1940+
test.equal(args.tessel, this.tessel);
1941+
test.equal(args.tessel.versions, processVersions);
1942+
test.done();
1943+
});
1944+
},
1945+
1946+
preBundleCallsrequestBuildListAndForwardsResult(test) {
1947+
test.expect(4);
1948+
1949+
deploy.sendBundle(this.tessel, {
1950+
target: '/',
1951+
entryPoint: 'foo.js',
1952+
lang: deployment.js
1953+
}).then(() => {
1954+
test.equal(this.requestBuildList.callCount, 1);
1955+
test.equal(this.resolveBinaryModules.callCount, 1);
1956+
1957+
var args = this.resolveBinaryModules.lastCall.args[0];
1958+
1959+
test.equal(args.tessel, this.tessel);
1960+
test.equal(args.tessel.versions, processVersions);
1961+
test.done();
1962+
});
1963+
},
1964+
19191965
preBundleCallsfetchNodeProcessVersionsAndForwardsResult(test) {
19201966
test.expect(4);
19211967

@@ -2364,6 +2410,80 @@ exports['deployment.js.resolveBinaryModules'] = {
23642410
test.done();
23652411
});
23662412
},
2413+
2414+
requestsRemoteGunzipErrors: function(test) {
2415+
test.expect(9);
2416+
2417+
this.removeSync = sandbox.stub(fs, 'removeSync');
2418+
this.exists = sandbox.stub(fs, 'existsSync', () => false);
2419+
this.mkdirp = sandbox.stub(fs, 'mkdirp', (dir, handler) => {
2420+
handler();
2421+
});
2422+
2423+
this.transform = new Transform();
2424+
this.transform.stubsUsed = [];
2425+
this.rstream = null;
2426+
2427+
this.pipe = sandbox.stub(stream.Stream.prototype, 'pipe', () => {
2428+
// After the second transform is piped, emit the end
2429+
// event on the request stream;
2430+
if (this.pipe.callCount === 2) {
2431+
process.nextTick(() => this.rstream.emit('end'));
2432+
}
2433+
return this.rstream;
2434+
});
2435+
2436+
this.createGunzip = sandbox.stub(zlib, 'createGunzip', () => {
2437+
this.transform.stubsUsed.push('createGunzip');
2438+
return this.transform;
2439+
});
2440+
2441+
this.Extract = sandbox.stub(tar, 'Extract', () => {
2442+
this.transform.stubsUsed.push('Extract');
2443+
return this.transform;
2444+
});
2445+
2446+
this.request = sandbox.stub(request, 'Request', (opts) => {
2447+
this.rstream = new Request(opts);
2448+
return this.rstream;
2449+
});
2450+
2451+
// Hook into the ifReachable call to trigger an error at the gunzip stream
2452+
this.ifReachable.restore();
2453+
this.ifReachable = sandbox.stub(remote, 'ifReachable', () => {
2454+
this.transform.emit('error', {
2455+
code: 'Z_DATA_ERROR',
2456+
});
2457+
return Promise.resolve();
2458+
});
2459+
2460+
deployment.js.resolveBinaryModules({
2461+
target: this.target,
2462+
tessel: {
2463+
versions: {
2464+
modules: 46
2465+
},
2466+
},
2467+
}).then(() => {
2468+
test.equal(this.globFiles.callCount, 1);
2469+
test.equal(this.exists.callCount, 1);
2470+
test.equal(this.mkdirp.callCount, 1);
2471+
test.equal(this.mkdirp.lastCall.args[0].endsWith(path.normalize('.tessel/binaries/release-1.1.1-Release-node-v46-linux-mipsel')), true);
2472+
2473+
// The result of gunzip emitting an error:
2474+
test.equal(this.removeSync.callCount, 1);
2475+
test.equal(this.removeSync.lastCall.args[0].endsWith(path.normalize('.tessel/binaries/release-1.1.1-Release-node-v46-linux-mipsel')), true);
2476+
2477+
test.equal(this.request.callCount, 1);
2478+
test.equal(this.createGunzip.callCount, 1);
2479+
test.deepEqual(this.transform.stubsUsed, ['createGunzip', 'Extract']);
2480+
2481+
test.done();
2482+
}).catch(error => {
2483+
test.ok(false, error.toString());
2484+
test.done();
2485+
});
2486+
},
23672487
};
23682488

23692489
exports['deployment.js.injectBinaryModules'] = {

0 commit comments

Comments
 (0)