diff --git a/lib/gui/app/app.js b/lib/gui/app/app.js index ff8ced9f..13676d24 100644 --- a/lib/gui/app/app.js +++ b/lib/gui/app/app.js @@ -182,15 +182,20 @@ app.run(() => { } const currentFlashState = flashState.getFlashState() + const stateType = !currentFlashState.flashing && currentFlashState.verifying + ? `Verifying ${currentFlashState.verifying}` + : `Flashing ${currentFlashState.flashing}` // NOTE: There is usually a short time period between the `isFlashing()` // property being set, and the flashing actually starting, which // might cause some non-sense flashing state logs including // `undefined` values. analytics.logDebug( - `Progress (${currentFlashState.type}): ` + + `${stateType} devices, ` + `${currentFlashState.percentage}% at ${currentFlashState.speed} MB/s ` + - `(eta ${currentFlashState.eta}s)` + `(total ${currentFlashState.totalSpeed} MB/s) ` + + `eta in ${currentFlashState.eta}s ` + + `with ${currentFlashState.failed} failed devices` ) windowProgress.set(currentFlashState) diff --git a/lib/shared/models/flash-state.js b/lib/shared/models/flash-state.js index e5a3aa2f..68c598e7 100644 --- a/lib/shared/models/flash-state.js +++ b/lib/shared/models/flash-state.js @@ -114,36 +114,29 @@ exports.unsetFlashingFlag = (results) => { * }); */ exports.setProgressState = (state) => { - const { - flashing, - verifying, - succeeded, - failed, - percentage, - eta, - speed - } = state - const data = { - flashing, - verifying, - succeeded, - failed, - - percentage: _.isNumber(percentage) && !_.isNaN(percentage) - ? Math.floor(percentage) - : percentage, - eta, + // Preserve only one decimal place + const PRECISION = 1 + const data = _.assign({}, state, { + percentage: _.isFinite(state.percentage) + ? Math.floor(state.percentage) + : state.percentage, speed: _.attempt(() => { - if (_.isNumber(speed) && !_.isNaN(speed)) { - // Preserve only two decimal places - const PRECISION = 2 - return _.round(units.bytesToMegabytes(speed), PRECISION) + if (_.isFinite(state.speed)) { + return _.round(units.bytesToMegabytes(state.speed), PRECISION) + } + + return null + }), + + totalSpeed: _.attempt(() => { + if (_.isFinite(state.totalSpeed)) { + return _.round(units.bytesToMegabytes(state.totalSpeed), PRECISION) } return null }) - } + }) store.dispatch({ type: store.Actions.SET_FLASH_STATE, diff --git a/lib/shared/store.js b/lib/shared/store.js index 1a7a52e8..9170e29b 100644 --- a/lib/shared/store.js +++ b/lib/shared/store.js @@ -59,7 +59,8 @@ const verifyNoNilFields = (object, fields, name) => { const flashStateNoNilFields = [ 'percentage', 'eta', - 'speed' + 'speed', + 'totalSpeed' ] /** @@ -92,7 +93,8 @@ const DEFAULT_STATE = Immutable.fromJS({ succeeded: 0, failed: 0, percentage: 0, - speed: 0 + speed: 0, + totalSpeed: 0 }, settings: { unsafeMode: false, diff --git a/tests/gui/pages/main.spec.js b/tests/gui/pages/main.spec.js index bfce1b10..131e492d 100644 --- a/tests/gui/pages/main.spec.js +++ b/tests/gui/pages/main.spec.js @@ -247,7 +247,8 @@ describe('Browser: MainPage', function () { failed: 0, percentage: 85, eta: 15, - speed: 1000 + speed: 1000, + totalSpeed: 2000 }) m.chai.expect(controller.getProgressButtonLabel()).to.equal('85% Flashing') }) diff --git a/tests/shared/models/flash-state.spec.js b/tests/shared/models/flash-state.spec.js index 9590f05f..6e600a56 100644 --- a/tests/shared/models/flash-state.spec.js +++ b/tests/shared/models/flash-state.spec.js @@ -29,10 +29,15 @@ describe('Model: flashState', function () { it('should be able to reset the progress state', function () { flashState.setFlashingFlag() flashState.setProgressState({ + flashing: 0, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', percentage: 50, eta: 15, - speed: 100000000000 + speed: 100000000000, + totalSpeed: 200000000000 }) flashState.resetState() @@ -43,7 +48,8 @@ describe('Model: flashState', function () { succeeded: 0, failed: 0, percentage: 0, - speed: 0 + speed: 0, + totalSpeed: 0 }) }) @@ -90,10 +96,15 @@ describe('Model: flashState', function () { m.chai.expect(function () { flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', percentage: 50, eta: 15, - speed: 100000000000 + speed: 100000000000, + totalSpeed: 200000000000 }) }).to.throw('Can\'t set the flashing state when not flashing') }) @@ -102,10 +113,15 @@ describe('Model: flashState', function () { flashState.setFlashingFlag() m.chai.expect(function () { flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', percentage: 0, eta: 15, - speed: 100000000000 + speed: 100000000000, + totalSpeed: 200000000000 }) }).to.not.throw('Missing flash fields: percentage') }) @@ -114,9 +130,14 @@ describe('Model: flashState', function () { flashState.setFlashingFlag() m.chai.expect(function () { flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', eta: 15, - speed: 100000000000 + speed: 100000000000, + totalSpeed: 200000000000 }) }).to.throw('Missing flash fields: percentage') }) @@ -125,10 +146,15 @@ describe('Model: flashState', function () { flashState.setFlashingFlag() m.chai.expect(function () { flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', percentage: '50', eta: 15, - speed: 100000000000 + speed: 100000000000, + totalSpeed: 200000000000 }) }).to.throw('Invalid state percentage: 50') }) @@ -137,10 +163,15 @@ describe('Model: flashState', function () { flashState.setFlashingFlag() m.chai.expect(function () { flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', percentage: 101, eta: 15, - speed: 0 + speed: 0, + totalSpeed: 1 }) }).to.throw('Invalid state percentage: 101') }) @@ -149,10 +180,15 @@ describe('Model: flashState', function () { flashState.setFlashingFlag() m.chai.expect(function () { flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', percentage: -1, eta: 15, - speed: 0 + speed: 0, + totalSpeed: 1 }) }).to.throw('Invalid state percentage: -1') }) @@ -161,9 +197,14 @@ describe('Model: flashState', function () { flashState.setFlashingFlag() m.chai.expect(function () { flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', percentage: 50, - speed: 100000000000 + speed: 100000000000, + totalSpeed: 200000000000 }) }).to.throw('Missing flash fields: eta') }) @@ -172,10 +213,15 @@ describe('Model: flashState', function () { flashState.setFlashingFlag() m.chai.expect(function () { flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', percentage: 50, eta: 0, - speed: 100000000000 + speed: 100000000000, + totalSpeed: 200000000000 }) }).to.not.throw('Missing flash field eta') }) @@ -184,10 +230,15 @@ describe('Model: flashState', function () { flashState.setFlashingFlag() m.chai.expect(function () { flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', percentage: 50, eta: '15', - speed: 100000000000 + speed: 100000000000, + totalSpeed: 200000000000 }) }).to.throw('Invalid state eta: 15') }) @@ -196,9 +247,14 @@ describe('Model: flashState', function () { flashState.setFlashingFlag() m.chai.expect(function () { flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', percentage: 50, - eta: 15 + eta: 15, + totalSpeed: 1 }) }).to.throw('Missing flash fields: speed') }) @@ -207,21 +263,64 @@ describe('Model: flashState', function () { flashState.setFlashingFlag() m.chai.expect(function () { flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', percentage: 50, eta: 15, - speed: 0 + speed: 0, + totalSpeed: 1 }) }).to.not.throw('Missing flash fields: speed') }) + it('should throw if totalSpeed is missing', function () { + flashState.setFlashingFlag() + m.chai.expect(function () { + flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, + type: 'write', + percentage: 50, + eta: 15, + speed: 1 + }) + }).to.throw('Missing flash fields: totalSpeed') + }) + + it('should not throw if totalSpeed is 0', function () { + flashState.setFlashingFlag() + m.chai.expect(function () { + flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, + type: 'write', + percentage: 50, + eta: 15, + speed: 0, + totalSpeed: 0 + }) + }).to.not.throw('Missing flash fields: totalSpeed') + }) + it('should floor the percentage number', function () { flashState.setFlashingFlag() flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', percentage: 50.253559459485, eta: 15, - speed: 0 + speed: 0, + totalSpeed: 1 }) m.chai.expect(flashState.getFlashState().percentage).to.equal(50) @@ -253,7 +352,8 @@ describe('Model: flashState', function () { succeeded: 0, failed: 0, percentage: 0, - speed: 0 + speed: 0, + totalSpeed: 0 }) }) @@ -265,7 +365,8 @@ describe('Model: flashState', function () { failed: 0, percentage: 50, eta: 15, - speed: 0 + speed: 0, + totalSpeed: 0 } flashState.setFlashingFlag() @@ -278,7 +379,8 @@ describe('Model: flashState', function () { failed: 0, percentage: 50, eta: 15, - speed: 0 + speed: 0, + totalSpeed: 0 }) }) }) @@ -366,19 +468,25 @@ describe('Model: flashState', function () { flashState.setFlashingFlag() flashState.setProgressState({ + flashing: 2, + verifying: 0, + succeeded: 0, + failed: 0, type: 'write', percentage: 50, eta: 15, - speed: 100000000000 + speed: 100000000000, + totalSpeed: 200000000000 }) m.chai.expect(flashState.getFlashState()).to.not.deep.equal({ - flashing: 0, + flashing: 2, verifying: 0, succeeded: 0, failed: 0, percentage: 0, - speed: 0 + speed: 0, + totalSpeed: 0 }) flashState.unsetFlashingFlag({ @@ -392,7 +500,8 @@ describe('Model: flashState', function () { succeeded: 0, failed: 0, percentage: 0, - speed: 0 + speed: 0, + totalSpeed: 0 }) })