mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-07-02 21:44:56 +02:00
BinaryManager support for libraries and downloading from github release assets
This commit is contained in:
parent
ee53086444
commit
329e9c9eb2
4 changed files with 574 additions and 639 deletions
|
@ -6,6 +6,7 @@ const which = require('../../../server/libs/which')
|
|||
const ffbinaries = require('../../../server/libs/ffbinaries')
|
||||
const path = require('path')
|
||||
const BinaryManager = require('../../../server/managers/BinaryManager')
|
||||
const { Binary } = require('../../../server/managers/BinaryManager')
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
|
@ -38,7 +39,7 @@ describe('BinaryManager', () => {
|
|||
|
||||
it('should not install binaries if they are already found', async () => {
|
||||
findStub.resolves([])
|
||||
|
||||
|
||||
await binaryManager.init()
|
||||
|
||||
expect(installStub.called).to.be.false
|
||||
|
@ -49,10 +50,14 @@ describe('BinaryManager', () => {
|
|||
})
|
||||
|
||||
it('should install missing binaries', async () => {
|
||||
const missingBinaries = ['ffmpeg', 'ffprobe']
|
||||
const ffmpegBinary = new Binary('ffmpeg', 'executable', 'FFMPEG_PATH', ['5.1'], ffbinaries)
|
||||
const ffprobeBinary = new Binary('ffprobe', 'executable', 'FFPROBE_PATH', ['5.1'], ffbinaries)
|
||||
const requiredBinaries = [ffmpegBinary, ffprobeBinary]
|
||||
const missingBinaries = [ffprobeBinary]
|
||||
const missingBinariesAfterInstall = []
|
||||
findStub.onFirstCall().resolves(missingBinaries)
|
||||
findStub.onSecondCall().resolves(missingBinariesAfterInstall)
|
||||
binaryManager.requiredBinaries = requiredBinaries
|
||||
|
||||
await binaryManager.init()
|
||||
|
||||
|
@ -64,8 +69,11 @@ describe('BinaryManager', () => {
|
|||
})
|
||||
|
||||
it('exit if binaries are not found after installation', async () => {
|
||||
const missingBinaries = ['ffmpeg', 'ffprobe']
|
||||
const missingBinariesAfterInstall = ['ffmpeg', 'ffprobe']
|
||||
const ffmpegBinary = new Binary('ffmpeg', 'executable', 'FFMPEG_PATH', ['5.1'], ffbinaries)
|
||||
const ffprobeBinary = new Binary('ffprobe', 'executable', 'FFPROBE_PATH', ['5.1'], ffbinaries)
|
||||
const requiredBinaries = [ffmpegBinary, ffprobeBinary]
|
||||
const missingBinaries = [ffprobeBinary]
|
||||
const missingBinariesAfterInstall = [ffprobeBinary]
|
||||
findStub.onFirstCall().resolves(missingBinaries)
|
||||
findStub.onSecondCall().resolves(missingBinariesAfterInstall)
|
||||
|
||||
|
@ -80,14 +88,15 @@ describe('BinaryManager', () => {
|
|||
})
|
||||
})
|
||||
|
||||
|
||||
describe('findRequiredBinaries', () => {
|
||||
let findBinaryStub
|
||||
let ffmpegBinary
|
||||
|
||||
beforeEach(() => {
|
||||
const requiredBinaries = [{ name: 'ffmpeg', envVariable: 'FFMPEG_PATH' }]
|
||||
ffmpegBinary = new Binary('ffmpeg', 'executable', 'FFMPEG_PATH', ['5.1'], ffbinaries)
|
||||
const requiredBinaries = [ffmpegBinary]
|
||||
binaryManager = new BinaryManager(requiredBinaries)
|
||||
findBinaryStub = sinon.stub(binaryManager, 'findBinary')
|
||||
findBinaryStub = sinon.stub(ffmpegBinary, 'find')
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -108,8 +117,8 @@ describe('BinaryManager', () => {
|
|||
})
|
||||
|
||||
it('should add missing binaries to result', async () => {
|
||||
const missingBinaries = ['ffmpeg']
|
||||
delete process.env.FFMPEG_PATH
|
||||
const missingBinaries = [ffmpegBinary]
|
||||
delete process.env.FFMPEG_PATH
|
||||
findBinaryStub.resolves(null)
|
||||
|
||||
const result = await binaryManager.findRequiredBinaries()
|
||||
|
@ -119,22 +128,25 @@ describe('BinaryManager', () => {
|
|||
expect(process.env.FFMPEG_PATH).to.be.undefined
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('install', () => {
|
||||
let isWritableStub
|
||||
let downloadBinariesStub
|
||||
let downloadBinaryStub
|
||||
let ffmpegBinary
|
||||
|
||||
beforeEach(() => {
|
||||
binaryManager = new BinaryManager()
|
||||
ffmpegBinary = new Binary('ffmpeg', 'executable', 'FFMPEG_PATH', ['5.1'], ffbinaries)
|
||||
const requiredBinaries = [ffmpegBinary]
|
||||
binaryManager = new BinaryManager(requiredBinaries)
|
||||
isWritableStub = sinon.stub(fileUtils, 'isWritable')
|
||||
downloadBinariesStub = sinon.stub(ffbinaries, 'downloadBinaries')
|
||||
binaryManager.mainInstallPath = '/path/to/main/install'
|
||||
binaryManager.altInstallPath = '/path/to/alt/install'
|
||||
downloadBinaryStub = sinon.stub(ffmpegBinary, 'download')
|
||||
binaryManager.mainInstallDir = '/path/to/main/install'
|
||||
binaryManager.altInstallDir = '/path/to/alt/install'
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
isWritableStub.restore()
|
||||
downloadBinariesStub.restore()
|
||||
downloadBinaryStub.restore()
|
||||
})
|
||||
|
||||
it('should not install binaries if no binaries are passed', async () => {
|
||||
|
@ -143,240 +155,302 @@ describe('BinaryManager', () => {
|
|||
await binaryManager.install(binaries)
|
||||
|
||||
expect(isWritableStub.called).to.be.false
|
||||
expect(downloadBinariesStub.called).to.be.false
|
||||
expect(downloadBinaryStub.called).to.be.false
|
||||
})
|
||||
|
||||
it('should install binaries in main install path if has access', async () => {
|
||||
const binaries = ['ffmpeg']
|
||||
const destination = binaryManager.mainInstallPath
|
||||
const binaries = [ffmpegBinary]
|
||||
const destination = binaryManager.mainInstallDir
|
||||
isWritableStub.withArgs(destination).resolves(true)
|
||||
downloadBinariesStub.resolves()
|
||||
|
||||
downloadBinaryStub.resolves()
|
||||
|
||||
await binaryManager.install(binaries)
|
||||
|
||||
expect(isWritableStub.calledOnce).to.be.true
|
||||
expect(downloadBinariesStub.calledOnce).to.be.true
|
||||
expect(downloadBinariesStub.calledWith(binaries, sinon.match({ destination: destination }))).to.be.true
|
||||
expect(downloadBinaryStub.calledOnce).to.be.true
|
||||
expect(downloadBinaryStub.calledWith(destination)).to.be.true
|
||||
})
|
||||
|
||||
it('should install binaries in alt install path if has no access to main', async () => {
|
||||
const binaries = ['ffmpeg']
|
||||
const mainDestination = binaryManager.mainInstallPath
|
||||
const destination = binaryManager.altInstallPath
|
||||
const binaries = [ffmpegBinary]
|
||||
const mainDestination = binaryManager.mainInstallDir
|
||||
const destination = binaryManager.altInstallDir
|
||||
isWritableStub.withArgs(mainDestination).resolves(false)
|
||||
downloadBinariesStub.resolves()
|
||||
|
||||
downloadBinaryStub.resolves()
|
||||
|
||||
await binaryManager.install(binaries)
|
||||
|
||||
expect(isWritableStub.calledOnce).to.be.true
|
||||
expect(downloadBinariesStub.calledOnce).to.be.true
|
||||
expect(downloadBinariesStub.calledWith(binaries, sinon.match({ destination: destination }))).to.be.true
|
||||
expect(downloadBinaryStub.calledOnce).to.be.true
|
||||
expect(downloadBinaryStub.calledWith(destination)).to.be.true
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('findBinary', () => {
|
||||
let binaryManager
|
||||
let isBinaryGoodStub
|
||||
let whichSyncStub
|
||||
let mainInstallPath
|
||||
let altInstallPath
|
||||
describe('Binary', () => {
|
||||
describe('find', () => {
|
||||
let binary
|
||||
let isGoodStub
|
||||
let whichSyncStub
|
||||
let mainInstallPath
|
||||
let altInstallPath
|
||||
|
||||
const name = 'ffmpeg'
|
||||
const envVariable = 'FFMPEG_PATH'
|
||||
const defaultPath = '/path/to/ffmpeg'
|
||||
const executable = name + (process.platform == 'win32' ? '.exe' : '')
|
||||
const whichPath = '/usr/bin/ffmpeg'
|
||||
const name = 'ffmpeg'
|
||||
const envVariable = 'FFMPEG_PATH'
|
||||
const defaultPath = '/path/to/ffmpeg'
|
||||
const executable = name + (process.platform == 'win32' ? '.exe' : '')
|
||||
const whichPath = '/usr/bin/ffmpeg'
|
||||
|
||||
beforeEach(() => {
|
||||
binary = new Binary(name, 'executable', envVariable, ['5.1'], ffbinaries)
|
||||
isGoodStub = sinon.stub(binary, 'isGood')
|
||||
whichSyncStub = sinon.stub(which, 'sync')
|
||||
binary.mainInstallDir = '/path/to/main/install'
|
||||
mainInstallPath = path.join(binary.mainInstallDir, executable)
|
||||
binary.altInstallDir = '/path/to/alt/install'
|
||||
altInstallPath = path.join(binary.altInstallDir, executable)
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
binaryManager = new BinaryManager()
|
||||
isBinaryGoodStub = sinon.stub(binaryManager, 'isBinaryGood')
|
||||
whichSyncStub = sinon.stub(which, 'sync')
|
||||
binaryManager.mainInstallPath = '/path/to/main/install'
|
||||
mainInstallPath = path.join(binaryManager.mainInstallPath, executable)
|
||||
binaryManager.altInstallPath = '/path/to/alt/install'
|
||||
altInstallPath = path.join(binaryManager.altInstallPath, executable)
|
||||
afterEach(() => {
|
||||
isGoodStub.restore()
|
||||
whichSyncStub.restore()
|
||||
})
|
||||
|
||||
it('should return the defaultPath if it exists and is a good binary', async () => {
|
||||
process.env[envVariable] = defaultPath
|
||||
isGoodStub.withArgs(defaultPath).resolves(true)
|
||||
|
||||
const result = await binary.find(binary.mainInstallDir, binary.altInstallDir)
|
||||
|
||||
expect(result).to.equal(defaultPath)
|
||||
expect(isGoodStub.calledOnce).to.be.true
|
||||
expect(isGoodStub.calledWith(defaultPath)).to.be.true
|
||||
})
|
||||
|
||||
it('should return the whichPath if it exists and is a good binary', async () => {
|
||||
delete process.env[envVariable]
|
||||
isGoodStub.withArgs(undefined).resolves(false)
|
||||
whichSyncStub.returns(whichPath)
|
||||
isGoodStub.withArgs(whichPath).resolves(true)
|
||||
|
||||
const result = await binary.find(binary.mainInstallDir, binary.altInstallDir)
|
||||
|
||||
expect(result).to.equal(whichPath)
|
||||
expect(isGoodStub.calledTwice).to.be.true
|
||||
expect(isGoodStub.calledWith(undefined)).to.be.true
|
||||
expect(isGoodStub.calledWith(whichPath)).to.be.true
|
||||
})
|
||||
|
||||
it('should return the mainInstallPath if it exists and is a good binary', async () => {
|
||||
delete process.env[envVariable]
|
||||
isGoodStub.withArgs(undefined).resolves(false)
|
||||
whichSyncStub.returns(null)
|
||||
isGoodStub.withArgs(null).resolves(false)
|
||||
isGoodStub.withArgs(mainInstallPath).resolves(true)
|
||||
|
||||
const result = await binary.find(binary.mainInstallDir, binary.altInstallDir)
|
||||
|
||||
expect(result).to.equal(mainInstallPath)
|
||||
expect(isGoodStub.callCount).to.be.equal(3)
|
||||
expect(isGoodStub.calledWith(undefined)).to.be.true
|
||||
expect(isGoodStub.calledWith(null)).to.be.true
|
||||
expect(isGoodStub.calledWith(mainInstallPath)).to.be.true
|
||||
})
|
||||
|
||||
it('should return the altInstallPath if it exists and is a good binary', async () => {
|
||||
delete process.env[envVariable]
|
||||
isGoodStub.withArgs(undefined).resolves(false)
|
||||
whichSyncStub.returns(null)
|
||||
isGoodStub.withArgs(null).resolves(false)
|
||||
isGoodStub.withArgs(mainInstallPath).resolves(false)
|
||||
isGoodStub.withArgs(altInstallPath).resolves(true)
|
||||
|
||||
const result = await binary.find(binary.mainInstallDir, binary.altInstallDir)
|
||||
|
||||
expect(result).to.equal(altInstallPath)
|
||||
expect(isGoodStub.callCount).to.be.equal(4)
|
||||
expect(isGoodStub.calledWith(undefined)).to.be.true
|
||||
expect(isGoodStub.calledWith(null)).to.be.true
|
||||
expect(isGoodStub.calledWith(mainInstallPath)).to.be.true
|
||||
expect(isGoodStub.calledWith(altInstallPath)).to.be.true
|
||||
})
|
||||
|
||||
it('should return null if no good binary is found', async () => {
|
||||
delete process.env[envVariable]
|
||||
isGoodStub.withArgs(undefined).resolves(false)
|
||||
whichSyncStub.returns(null)
|
||||
isGoodStub.withArgs(null).resolves(false)
|
||||
isGoodStub.withArgs(mainInstallPath).resolves(false)
|
||||
isGoodStub.withArgs(altInstallPath).resolves(false)
|
||||
|
||||
const result = await binary.find(binary.mainInstallDir, binary.altInstallDir)
|
||||
|
||||
expect(result).to.be.null
|
||||
expect(isGoodStub.callCount).to.be.equal(4)
|
||||
expect(isGoodStub.calledWith(undefined)).to.be.true
|
||||
expect(isGoodStub.calledWith(null)).to.be.true
|
||||
expect(isGoodStub.calledWith(mainInstallPath)).to.be.true
|
||||
expect(isGoodStub.calledWith(altInstallPath)).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
isBinaryGoodStub.restore()
|
||||
whichSyncStub.restore()
|
||||
describe('isGood', () => {
|
||||
let binary
|
||||
let fsPathExistsStub
|
||||
let execStub
|
||||
|
||||
const binaryPath = '/path/to/binary'
|
||||
const execCommand = '"' + binaryPath + '"' + ' -version'
|
||||
const goodVersions = ['5.1', '6']
|
||||
|
||||
beforeEach(() => {
|
||||
binary = new Binary('ffmpeg', 'executable', 'FFMPEG_PATH', goodVersions, ffbinaries)
|
||||
fsPathExistsStub = sinon.stub(fs, 'pathExists')
|
||||
execStub = sinon.stub(binary, 'exec')
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
fsPathExistsStub.restore()
|
||||
execStub.restore()
|
||||
})
|
||||
|
||||
it('should return false if binaryPath is falsy', async () => {
|
||||
fsPathExistsStub.resolves(true)
|
||||
|
||||
const result = await binary.isGood(null)
|
||||
|
||||
expect(result).to.be.false
|
||||
expect(fsPathExistsStub.called).to.be.false
|
||||
expect(execStub.called).to.be.false
|
||||
})
|
||||
|
||||
it('should return false if binaryPath does not exist', async () => {
|
||||
fsPathExistsStub.resolves(false)
|
||||
|
||||
const result = await binary.isGood(binaryPath)
|
||||
|
||||
expect(result).to.be.false
|
||||
expect(fsPathExistsStub.calledOnce).to.be.true
|
||||
expect(fsPathExistsStub.calledWith(binaryPath)).to.be.true
|
||||
expect(execStub.called).to.be.false
|
||||
})
|
||||
|
||||
it('should return false if failed to check version of binary', async () => {
|
||||
fsPathExistsStub.resolves(true)
|
||||
execStub.rejects(new Error('Failed to execute command'))
|
||||
|
||||
const result = await binary.isGood(binaryPath)
|
||||
|
||||
expect(result).to.be.false
|
||||
expect(fsPathExistsStub.calledOnce).to.be.true
|
||||
expect(fsPathExistsStub.calledWith(binaryPath)).to.be.true
|
||||
expect(execStub.calledOnce).to.be.true
|
||||
expect(execStub.calledWith(execCommand)).to.be.true
|
||||
})
|
||||
|
||||
it('should return false if version is not found', async () => {
|
||||
const stdout = 'Some output without version'
|
||||
fsPathExistsStub.resolves(true)
|
||||
execStub.resolves({ stdout })
|
||||
|
||||
const result = await binary.isGood(binaryPath)
|
||||
|
||||
expect(result).to.be.false
|
||||
expect(fsPathExistsStub.calledOnce).to.be.true
|
||||
expect(fsPathExistsStub.calledWith(binaryPath)).to.be.true
|
||||
expect(execStub.calledOnce).to.be.true
|
||||
expect(execStub.calledWith(execCommand)).to.be.true
|
||||
})
|
||||
|
||||
it('should return false if version is found but does not match a good version', async () => {
|
||||
const stdout = 'version 1.2.3'
|
||||
fsPathExistsStub.resolves(true)
|
||||
execStub.resolves({ stdout })
|
||||
|
||||
const result = await binary.isGood(binaryPath)
|
||||
|
||||
expect(result).to.be.false
|
||||
expect(fsPathExistsStub.calledOnce).to.be.true
|
||||
expect(fsPathExistsStub.calledWith(binaryPath)).to.be.true
|
||||
expect(execStub.calledOnce).to.be.true
|
||||
expect(execStub.calledWith(execCommand)).to.be.true
|
||||
})
|
||||
|
||||
it('should return true if version is found and matches a good version', async () => {
|
||||
const stdout = 'version 6.1.2'
|
||||
fsPathExistsStub.resolves(true)
|
||||
execStub.resolves({ stdout })
|
||||
|
||||
const result = await binary.isGood(binaryPath)
|
||||
|
||||
expect(result).to.be.true
|
||||
expect(fsPathExistsStub.calledOnce).to.be.true
|
||||
expect(fsPathExistsStub.calledWith(binaryPath)).to.be.true
|
||||
expect(execStub.calledOnce).to.be.true
|
||||
expect(execStub.calledWith(execCommand)).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
it('should return the defaultPath if it exists and is a good binary', async () => {
|
||||
process.env[envVariable] = defaultPath
|
||||
isBinaryGoodStub.withArgs(defaultPath).resolves(true)
|
||||
|
||||
const result = await binaryManager.findBinary(name, envVariable)
|
||||
|
||||
expect(result).to.equal(defaultPath)
|
||||
expect(isBinaryGoodStub.calledOnce).to.be.true
|
||||
expect(isBinaryGoodStub.calledWith(defaultPath)).to.be.true
|
||||
|
||||
describe('getFileName', () => {
|
||||
let originalPlatform
|
||||
|
||||
const mockPlatform = (platform) => {
|
||||
Object.defineProperty(process, 'platform', { value: platform })
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
// Save the original process.platform descriptor
|
||||
originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform')
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
// Restore the original process.platform descriptor
|
||||
Object.defineProperty(process, 'platform', originalPlatform)
|
||||
})
|
||||
|
||||
it('should return the executable file name with .exe extension on Windows', () => {
|
||||
const binary = new Binary('ffmpeg', 'executable', 'FFMPEG_PATH', ['5.1'], ffbinaries)
|
||||
mockPlatform('win32')
|
||||
|
||||
const result = binary.getFileName()
|
||||
|
||||
expect(result).to.equal('ffmpeg.exe')
|
||||
})
|
||||
|
||||
it('should return the executable file name without extension on linux', () => {
|
||||
const binary = new Binary('ffmpeg', 'executable', 'FFMPEG_PATH', ['5.1'], ffbinaries)
|
||||
mockPlatform('linux')
|
||||
|
||||
const result = binary.getFileName()
|
||||
|
||||
expect(result).to.equal('ffmpeg')
|
||||
})
|
||||
|
||||
it('should return the library file name with .dll extension on Windows', () => {
|
||||
const binary = new Binary('ffmpeg', 'library', 'FFMPEG_PATH', ['5.1'], ffbinaries)
|
||||
mockPlatform('win32')
|
||||
|
||||
const result = binary.getFileName()
|
||||
|
||||
expect(result).to.equal('ffmpeg.dll')
|
||||
})
|
||||
|
||||
it('should return the library file name with .so extension on linux', () => {
|
||||
const binary = new Binary('ffmpeg', 'library', 'FFMPEG_PATH', ['5.1'], ffbinaries)
|
||||
mockPlatform('linux')
|
||||
|
||||
const result = binary.getFileName()
|
||||
|
||||
expect(result).to.equal('ffmpeg.so')
|
||||
})
|
||||
|
||||
it('should return the file name without extension for other types', () => {
|
||||
const binary = new Binary('ffmpeg', 'other', 'FFMPEG_PATH', ['5.1'], ffbinaries)
|
||||
mockPlatform('win32')
|
||||
|
||||
const result = binary.getFileName()
|
||||
|
||||
expect(result).to.equal('ffmpeg')
|
||||
})
|
||||
})
|
||||
|
||||
it('should return the whichPath if it exists and is a good binary', async () => {
|
||||
delete process.env[envVariable]
|
||||
isBinaryGoodStub.withArgs(undefined).resolves(false)
|
||||
isBinaryGoodStub.withArgs(whichPath).resolves(true)
|
||||
whichSyncStub.returns(whichPath)
|
||||
|
||||
const result = await binaryManager.findBinary(name, envVariable)
|
||||
|
||||
expect(result).to.equal(whichPath)
|
||||
expect(isBinaryGoodStub.calledTwice).to.be.true
|
||||
expect(isBinaryGoodStub.calledWith(undefined)).to.be.true
|
||||
expect(isBinaryGoodStub.calledWith(whichPath)).to.be.true
|
||||
})
|
||||
|
||||
it('should return the mainInstallPath if it exists and is a good binary', async () => {
|
||||
delete process.env[envVariable]
|
||||
isBinaryGoodStub.withArgs(undefined).resolves(false)
|
||||
isBinaryGoodStub.withArgs(null).resolves(false)
|
||||
isBinaryGoodStub.withArgs(mainInstallPath).resolves(true)
|
||||
whichSyncStub.returns(null)
|
||||
|
||||
const result = await binaryManager.findBinary(name, envVariable)
|
||||
|
||||
expect(result).to.equal(mainInstallPath)
|
||||
expect(isBinaryGoodStub.callCount).to.be.equal(3)
|
||||
expect(isBinaryGoodStub.calledWith(undefined)).to.be.true
|
||||
expect(isBinaryGoodStub.calledWith(null)).to.be.true
|
||||
expect(isBinaryGoodStub.calledWith(mainInstallPath)).to.be.true
|
||||
})
|
||||
|
||||
it('should return the altInstallPath if it exists and is a good binary', async () => {
|
||||
delete process.env[envVariable]
|
||||
isBinaryGoodStub.withArgs(undefined).resolves(false)
|
||||
isBinaryGoodStub.withArgs(null).resolves(false)
|
||||
isBinaryGoodStub.withArgs(mainInstallPath).resolves(false)
|
||||
isBinaryGoodStub.withArgs(altInstallPath).resolves(true)
|
||||
whichSyncStub.returns(null)
|
||||
|
||||
const result = await binaryManager.findBinary(name, envVariable)
|
||||
|
||||
expect(result).to.equal(altInstallPath)
|
||||
expect(isBinaryGoodStub.callCount).to.be.equal(4)
|
||||
expect(isBinaryGoodStub.calledWith(undefined)).to.be.true
|
||||
expect(isBinaryGoodStub.calledWith(null)).to.be.true
|
||||
expect(isBinaryGoodStub.calledWith(mainInstallPath)).to.be.true
|
||||
expect(isBinaryGoodStub.calledWith(altInstallPath)).to.be.true
|
||||
})
|
||||
|
||||
it('should return null if no good binary is found', async () => {
|
||||
delete process.env[envVariable]
|
||||
isBinaryGoodStub.withArgs(undefined).resolves(false)
|
||||
isBinaryGoodStub.withArgs(null).resolves(false)
|
||||
isBinaryGoodStub.withArgs(mainInstallPath).resolves(false)
|
||||
isBinaryGoodStub.withArgs(altInstallPath).resolves(false)
|
||||
whichSyncStub.returns(null)
|
||||
|
||||
const result = await binaryManager.findBinary(name, envVariable)
|
||||
|
||||
expect(result).to.be.null
|
||||
expect(isBinaryGoodStub.callCount).to.be.equal(4)
|
||||
expect(isBinaryGoodStub.calledWith(undefined)).to.be.true
|
||||
expect(isBinaryGoodStub.calledWith(null)).to.be.true
|
||||
expect(isBinaryGoodStub.calledWith(mainInstallPath)).to.be.true
|
||||
expect(isBinaryGoodStub.calledWith(altInstallPath)).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
describe('isBinaryGood', () => {
|
||||
let binaryManager
|
||||
let fsPathExistsStub
|
||||
let execStub
|
||||
let loggerInfoStub
|
||||
let loggerErrorStub
|
||||
|
||||
const binaryPath = '/path/to/binary'
|
||||
const execCommand = '"' + binaryPath + '"' + ' -version'
|
||||
const goodVersions = ['5.1', '6']
|
||||
|
||||
beforeEach(() => {
|
||||
binaryManager = new BinaryManager()
|
||||
fsPathExistsStub = sinon.stub(fs, 'pathExists')
|
||||
execStub = sinon.stub(binaryManager, 'exec')
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
fsPathExistsStub.restore()
|
||||
execStub.restore()
|
||||
})
|
||||
|
||||
it('should return false if binaryPath is falsy', async () => {
|
||||
fsPathExistsStub.resolves(true)
|
||||
|
||||
const result = await binaryManager.isBinaryGood(null, goodVersions)
|
||||
|
||||
expect(result).to.be.false
|
||||
expect(fsPathExistsStub.called).to.be.false
|
||||
expect(execStub.called).to.be.false
|
||||
})
|
||||
|
||||
it('should return false if binaryPath does not exist', async () => {
|
||||
fsPathExistsStub.resolves(false)
|
||||
|
||||
const result = await binaryManager.isBinaryGood(binaryPath, goodVersions)
|
||||
|
||||
expect(result).to.be.false
|
||||
expect(fsPathExistsStub.calledOnce).to.be.true
|
||||
expect(fsPathExistsStub.calledWith(binaryPath)).to.be.true
|
||||
expect(execStub.called).to.be.false
|
||||
})
|
||||
|
||||
it('should return false if failed to check version of binary', async () => {
|
||||
fsPathExistsStub.resolves(true)
|
||||
execStub.rejects(new Error('Failed to execute command'))
|
||||
|
||||
const result = await binaryManager.isBinaryGood(binaryPath, goodVersions)
|
||||
|
||||
expect(result).to.be.false
|
||||
expect(fsPathExistsStub.calledOnce).to.be.true
|
||||
expect(fsPathExistsStub.calledWith(binaryPath)).to.be.true
|
||||
expect(execStub.calledOnce).to.be.true
|
||||
expect(execStub.calledWith(execCommand)).to.be.true
|
||||
})
|
||||
|
||||
it('should return false if version is not found', async () => {
|
||||
const stdout = 'Some output without version'
|
||||
fsPathExistsStub.resolves(true)
|
||||
execStub.resolves({ stdout })
|
||||
|
||||
const result = await binaryManager.isBinaryGood(binaryPath, goodVersions)
|
||||
|
||||
expect(result).to.be.false
|
||||
expect(fsPathExistsStub.calledOnce).to.be.true
|
||||
expect(fsPathExistsStub.calledWith(binaryPath)).to.be.true
|
||||
expect(execStub.calledOnce).to.be.true
|
||||
expect(execStub.calledWith(execCommand)).to.be.true
|
||||
})
|
||||
|
||||
it('should return false if version is found but does not match a good version', async () => {
|
||||
const stdout = 'version 1.2.3'
|
||||
fsPathExistsStub.resolves(true)
|
||||
execStub.resolves({ stdout })
|
||||
|
||||
const result = await binaryManager.isBinaryGood(binaryPath, goodVersions)
|
||||
|
||||
expect(result).to.be.false
|
||||
expect(fsPathExistsStub.calledOnce).to.be.true
|
||||
expect(fsPathExistsStub.calledWith(binaryPath)).to.be.true
|
||||
expect(execStub.calledOnce).to.be.true
|
||||
expect(execStub.calledWith(execCommand)).to.be.true
|
||||
})
|
||||
|
||||
it('should return true if version is found and matches a good version', async () => {
|
||||
const stdout = 'version 6.1.2'
|
||||
fsPathExistsStub.resolves(true)
|
||||
execStub.resolves({ stdout })
|
||||
|
||||
const result = await binaryManager.isBinaryGood(binaryPath, goodVersions)
|
||||
|
||||
expect(result).to.be.true
|
||||
expect(fsPathExistsStub.calledOnce).to.be.true
|
||||
expect(fsPathExistsStub.calledWith(binaryPath)).to.be.true
|
||||
expect(execStub.calledOnce).to.be.true
|
||||
expect(execStub.calledWith(execCommand)).to.be.true
|
||||
})
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue