mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-06-05 17:11:39 +00:00
Add volume tests and fix test fixture setup for applications
Change-type: patch Signed-off-by: Cameron Diver <cameron@balena.io>
This commit is contained in:
parent
3304825216
commit
050c10dbb0
@ -12,6 +12,7 @@ DeviceState = require '../src/device-state'
|
|||||||
{ Config } = require('../src/config')
|
{ Config } = require('../src/config')
|
||||||
{ Service } = require '../src/compose/service'
|
{ Service } = require '../src/compose/service'
|
||||||
{ Network } = require '../src/compose/network'
|
{ Network } = require '../src/compose/network'
|
||||||
|
{ Volume } = require '../src/compose/volume'
|
||||||
|
|
||||||
appDBFormatNormalised = {
|
appDBFormatNormalised = {
|
||||||
appId: 1234
|
appId: 1234
|
||||||
@ -160,7 +161,7 @@ describe 'ApplicationManager', ->
|
|||||||
return appCloned
|
return appCloned
|
||||||
.then (normalisedApps) ->
|
.then (normalisedApps) ->
|
||||||
currentCloned = _.cloneDeep(current)
|
currentCloned = _.cloneDeep(current)
|
||||||
currentCloned.local.apps = normalisedApps
|
currentCloned.local.apps = _.keyBy(normalisedApps, 'appId')
|
||||||
return currentCloned
|
return currentCloned
|
||||||
|
|
||||||
@normaliseTarget = (target, available) =>
|
@normaliseTarget = (target, available) =>
|
||||||
@ -178,6 +179,7 @@ describe 'ApplicationManager', ->
|
|||||||
service.config.image = img.dockerImageId
|
service.config.image = img.dockerImageId
|
||||||
return service
|
return service
|
||||||
return app
|
return app
|
||||||
|
targetCloned.local.apps = _.keyBy(targetCloned.local.apps, 'appId')
|
||||||
return targetCloned
|
return targetCloned
|
||||||
@db.init()
|
@db.init()
|
||||||
.then =>
|
.then =>
|
||||||
@ -199,8 +201,8 @@ describe 'ApplicationManager', ->
|
|||||||
steps = @applications._inferNextSteps(false, availableImages[0], [], true, current, target, false, {})
|
steps = @applications._inferNextSteps(false, availableImages[0], [], true, current, target, false, {})
|
||||||
expect(steps).to.eventually.deep.equal([{
|
expect(steps).to.eventually.deep.equal([{
|
||||||
action: 'start'
|
action: 'start'
|
||||||
current: current.local.apps[0].services[1]
|
current: current.local.apps['1234'].services[1]
|
||||||
target: target.local.apps[0].services[1]
|
target: target.local.apps['1234'].services[1]
|
||||||
serviceId: 24
|
serviceId: 24
|
||||||
appId: 1234
|
appId: 1234
|
||||||
options: {}
|
options: {}
|
||||||
@ -215,7 +217,7 @@ describe 'ApplicationManager', ->
|
|||||||
steps = @applications._inferNextSteps(false, availableImages[0], [], true, current, target, false, {})
|
steps = @applications._inferNextSteps(false, availableImages[0], [], true, current, target, false, {})
|
||||||
expect(steps).to.eventually.deep.equal([{
|
expect(steps).to.eventually.deep.equal([{
|
||||||
action: 'kill'
|
action: 'kill'
|
||||||
current: current.local.apps[0].services[1]
|
current: current.local.apps['1234'].services[1]
|
||||||
target: null
|
target: null
|
||||||
serviceId: 24
|
serviceId: 24
|
||||||
appId: 1234
|
appId: 1234
|
||||||
@ -231,7 +233,7 @@ describe 'ApplicationManager', ->
|
|||||||
steps = @applications._inferNextSteps(false, availableImages[0], [], true, current, target, false, {})
|
steps = @applications._inferNextSteps(false, availableImages[0], [], true, current, target, false, {})
|
||||||
expect(steps).to.eventually.deep.equal([{
|
expect(steps).to.eventually.deep.equal([{
|
||||||
action: 'fetch'
|
action: 'fetch'
|
||||||
image: @applications.imageForService(target.local.apps[0].services[1])
|
image: @applications.imageForService(target.local.apps['1234'].services[1])
|
||||||
serviceId: 24
|
serviceId: 24
|
||||||
appId: 1234
|
appId: 1234
|
||||||
serviceName: 'anotherService'
|
serviceName: 'anotherService'
|
||||||
@ -243,7 +245,7 @@ describe 'ApplicationManager', ->
|
|||||||
@normaliseCurrent(currentState[0])
|
@normaliseCurrent(currentState[0])
|
||||||
@normaliseTarget(targetState[2], availableImages[0])
|
@normaliseTarget(targetState[2], availableImages[0])
|
||||||
(current, target) =>
|
(current, target) =>
|
||||||
steps = @applications._inferNextSteps(false, availableImages[0], [ target.local.apps[0].services[1].imageId ], true, current, target, false, {})
|
steps = @applications._inferNextSteps(false, availableImages[0], [ target.local.apps['1234'].services[1].imageId ], true, current, target, false, {})
|
||||||
expect(steps).to.eventually.deep.equal([{ action: 'noop', appId: 1234 }])
|
expect(steps).to.eventually.deep.equal([{ action: 'noop', appId: 1234 }])
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -255,8 +257,8 @@ describe 'ApplicationManager', ->
|
|||||||
steps = @applications._inferNextSteps(false, availableImages[0], [], true, current, target, false, {})
|
steps = @applications._inferNextSteps(false, availableImages[0], [], true, current, target, false, {})
|
||||||
expect(steps).to.eventually.deep.equal([{
|
expect(steps).to.eventually.deep.equal([{
|
||||||
action: 'kill'
|
action: 'kill'
|
||||||
current: current.local.apps[0].services[1]
|
current: current.local.apps['1234'].services[1]
|
||||||
target: target.local.apps[0].services[1]
|
target: target.local.apps['1234'].services[1]
|
||||||
serviceId: 24
|
serviceId: 24
|
||||||
appId: 1234
|
appId: 1234
|
||||||
options: {}
|
options: {}
|
||||||
@ -271,7 +273,7 @@ describe 'ApplicationManager', ->
|
|||||||
steps = @applications._inferNextSteps(false, availableImages[2], [], true, current, target, false, {})
|
steps = @applications._inferNextSteps(false, availableImages[2], [], true, current, target, false, {})
|
||||||
expect(steps).to.eventually.have.deep.members([{
|
expect(steps).to.eventually.have.deep.members([{
|
||||||
action: 'fetch'
|
action: 'fetch'
|
||||||
image: @applications.imageForService(target.local.apps[0].services[0])
|
image: @applications.imageForService(target.local.apps['1234'].services[0])
|
||||||
serviceId: 23
|
serviceId: 23
|
||||||
appId: 1234,
|
appId: 1234,
|
||||||
serviceName: 'aservice'
|
serviceName: 'aservice'
|
||||||
@ -287,16 +289,16 @@ describe 'ApplicationManager', ->
|
|||||||
expect(steps).to.eventually.have.deep.members([
|
expect(steps).to.eventually.have.deep.members([
|
||||||
{
|
{
|
||||||
action: 'kill'
|
action: 'kill'
|
||||||
current: current.local.apps[0].services[0]
|
current: current.local.apps['1234'].services[0]
|
||||||
target: target.local.apps[0].services[0]
|
target: target.local.apps['1234'].services[0]
|
||||||
serviceId: 23
|
serviceId: 23
|
||||||
appId: 1234
|
appId: 1234
|
||||||
options: {}
|
options: {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
action: 'kill'
|
action: 'kill'
|
||||||
current: current.local.apps[0].services[1]
|
current: current.local.apps['1234'].services[1]
|
||||||
target: target.local.apps[0].services[1]
|
target: target.local.apps['1234'].services[1]
|
||||||
serviceId: 24
|
serviceId: 24
|
||||||
appId: 1234
|
appId: 1234
|
||||||
options: {}
|
options: {}
|
||||||
@ -314,7 +316,7 @@ describe 'ApplicationManager', ->
|
|||||||
{
|
{
|
||||||
action: 'start'
|
action: 'start'
|
||||||
current: null
|
current: null
|
||||||
target: target.local.apps[0].services[0]
|
target: target.local.apps['1234'].services[0]
|
||||||
serviceId: 23
|
serviceId: 23
|
||||||
appId: 1234
|
appId: 1234
|
||||||
options: {}
|
options: {}
|
||||||
@ -332,7 +334,7 @@ describe 'ApplicationManager', ->
|
|||||||
{
|
{
|
||||||
action: 'start'
|
action: 'start'
|
||||||
current: null
|
current: null
|
||||||
target: target.local.apps[0].services[1]
|
target: target.local.apps['1234'].services[1]
|
||||||
serviceId: 24
|
serviceId: 24
|
||||||
appId: 1234
|
appId: 1234
|
||||||
options: {}
|
options: {}
|
||||||
@ -349,7 +351,7 @@ describe 'ApplicationManager', ->
|
|||||||
expect(steps).to.eventually.have.deep.members([
|
expect(steps).to.eventually.have.deep.members([
|
||||||
{
|
{
|
||||||
action: 'kill'
|
action: 'kill'
|
||||||
current: current.local.apps[0].services[0]
|
current: current.local.apps['1234'].services[0]
|
||||||
target: null
|
target: null
|
||||||
serviceId: 23
|
serviceId: 23
|
||||||
appId: 1234
|
appId: 1234
|
||||||
@ -358,7 +360,7 @@ describe 'ApplicationManager', ->
|
|||||||
{
|
{
|
||||||
action: 'start'
|
action: 'start'
|
||||||
current: null
|
current: null
|
||||||
target: target.local.apps[0].services[1]
|
target: target.local.apps['1234'].services[1]
|
||||||
serviceId: 24
|
serviceId: 24
|
||||||
appId: 1234
|
appId: 1234
|
||||||
options: {}
|
options: {}
|
||||||
@ -387,3 +389,37 @@ describe 'ApplicationManager', ->
|
|||||||
it 'converts a dependent app in DB format into state format', ->
|
it 'converts a dependent app in DB format into state format', ->
|
||||||
app = @applications.proxyvisor.normaliseDependentAppFromDB(dependentDBFormat)
|
app = @applications.proxyvisor.normaliseDependentAppFromDB(dependentDBFormat)
|
||||||
expect(app).to.eventually.deep.equal(dependentStateFormatNormalised)
|
expect(app).to.eventually.deep.equal(dependentStateFormatNormalised)
|
||||||
|
|
||||||
|
describe 'Volumes', ->
|
||||||
|
|
||||||
|
before ->
|
||||||
|
stub(@applications, 'removeAllVolumesForApp').returns(Promise.resolve([{
|
||||||
|
action: 'removeVolume',
|
||||||
|
current: Volume.fromComposeObject('my_volume', 12, {}, { docker: null, logger: null })
|
||||||
|
}]))
|
||||||
|
|
||||||
|
after ->
|
||||||
|
@applications.removeAllVolumesForApp.restore()
|
||||||
|
|
||||||
|
it 'should not remove volumes when they are no longer referenced', ->
|
||||||
|
Promise.join(
|
||||||
|
@normaliseCurrent(currentState[6]),
|
||||||
|
@normaliseTarget(targetState[0], availableImages[0])
|
||||||
|
(current, target) =>
|
||||||
|
@applications._inferNextSteps(false, availableImages[0], [], true, current, target, false, {}).then (steps) ->
|
||||||
|
expect(
|
||||||
|
_.every(steps, (s) -> s.action != 'removeVolume'),
|
||||||
|
'Volumes from current app should not be removed'
|
||||||
|
).to.be.true
|
||||||
|
)
|
||||||
|
|
||||||
|
it 'should remove volumes from previous applications', ->
|
||||||
|
Promise.join(
|
||||||
|
@normaliseCurrent(currentState[5])
|
||||||
|
@normaliseTarget(targetState[6], [])
|
||||||
|
(current, target) =>
|
||||||
|
@applications._inferNextSteps(false, [], [], true, current, target, false, {}).then (steps) ->
|
||||||
|
expect(steps).to.have.length(1)
|
||||||
|
expect(steps[0]).to.have.property('action').that.equals('removeVolume')
|
||||||
|
expect(steps[0].current).to.have.property('appId').that.equals(12)
|
||||||
|
)
|
||||||
|
@ -305,6 +305,26 @@ targetState[5] = {
|
|||||||
dependent: { apps: [], devices: [] }
|
dependent: { apps: [], devices: [] }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
targetState[6] = {
|
||||||
|
local: {
|
||||||
|
name: 'volumeTest'
|
||||||
|
config: {
|
||||||
|
}
|
||||||
|
apps: [
|
||||||
|
{
|
||||||
|
appId: 12345
|
||||||
|
name: 'volumeApp'
|
||||||
|
commit: 'asd'
|
||||||
|
releaseId: 3
|
||||||
|
services: {}
|
||||||
|
volumes: {}
|
||||||
|
networks: {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
dependent: { apps: [], devices: [] }
|
||||||
|
}
|
||||||
|
|
||||||
exports.currentState = currentState = []
|
exports.currentState = currentState = []
|
||||||
currentState[0] = {
|
currentState[0] = {
|
||||||
local: {
|
local: {
|
||||||
@ -619,6 +639,124 @@ currentState[4] = {
|
|||||||
dependent: { apps: [], devices: [] }
|
dependent: { apps: [], devices: [] }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentState[5] = {
|
||||||
|
local: {
|
||||||
|
name: 'volumeTest'
|
||||||
|
config: {}
|
||||||
|
apps: [
|
||||||
|
{
|
||||||
|
appId: 12345
|
||||||
|
name: 'volumeApp'
|
||||||
|
commit: 'asd'
|
||||||
|
releaseId: 3
|
||||||
|
services: []
|
||||||
|
volumes: {}
|
||||||
|
networks: { default: {} }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
appId: 12,
|
||||||
|
name: 'previous-app',
|
||||||
|
commit: '123',
|
||||||
|
releaseId: 10
|
||||||
|
services: [],
|
||||||
|
networks: {},
|
||||||
|
volumes: {
|
||||||
|
my_volume: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
dependent: { apps: [], devices: [] }
|
||||||
|
}
|
||||||
|
|
||||||
|
currentState[6] = {
|
||||||
|
local: {
|
||||||
|
name: 'aDeviceWithDifferentName'
|
||||||
|
config: {
|
||||||
|
'RESIN_HOST_CONFIG_gpu_mem': '512'
|
||||||
|
'RESIN_HOST_LOG_TO_DISPLAY': '1'
|
||||||
|
}
|
||||||
|
apps: [
|
||||||
|
{
|
||||||
|
appId: 1234
|
||||||
|
name: 'superapp'
|
||||||
|
commit: 'afafafa'
|
||||||
|
releaseId: 2
|
||||||
|
services: [
|
||||||
|
{
|
||||||
|
appId: 1234
|
||||||
|
serviceId: 23
|
||||||
|
releaseId: 2
|
||||||
|
commit: 'afafafa'
|
||||||
|
serviceName: 'aservice'
|
||||||
|
imageId: 12345
|
||||||
|
image: 'id1'
|
||||||
|
environment: {
|
||||||
|
'FOO': 'bar'
|
||||||
|
'ADDITIONAL_ENV_VAR': 'foo'
|
||||||
|
|
||||||
|
}
|
||||||
|
privileged: false
|
||||||
|
restart: 'always'
|
||||||
|
volumes: [
|
||||||
|
'/tmp/balena-supervisor/services/1234/aservice:/tmp/resin',
|
||||||
|
'/tmp/balena-supervisor/services/1234/aservice:/tmp/balena'
|
||||||
|
]
|
||||||
|
labels: {
|
||||||
|
'io.resin.app-id': '1234'
|
||||||
|
'io.resin.service-id': '23'
|
||||||
|
'io.resin.supervised': 'true'
|
||||||
|
'io.resin.service-name': 'aservice'
|
||||||
|
}
|
||||||
|
running: true
|
||||||
|
createdAt: new Date()
|
||||||
|
containerId: '1'
|
||||||
|
networkMode: 'default'
|
||||||
|
networks: { 'default': { aliases: [ 'aservice' ] } }
|
||||||
|
command: [ 'someCommand' ]
|
||||||
|
entrypoint: [ 'theEntrypoint' ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
appId: 1234
|
||||||
|
serviceId: 24
|
||||||
|
releaseId: 2
|
||||||
|
commit: 'afafafa'
|
||||||
|
serviceName: 'anotherService'
|
||||||
|
imageId: 12346
|
||||||
|
image: 'id0'
|
||||||
|
environment: {
|
||||||
|
'FOO': 'bro'
|
||||||
|
'ADDITIONAL_ENV_VAR': 'foo'
|
||||||
|
}
|
||||||
|
volumes: [
|
||||||
|
'/tmp/balena-supervisor/services/1234/anotherService:/tmp/resin',
|
||||||
|
'/tmp/balena-supervisor/services/1234/anotherService:/tmp/balena'
|
||||||
|
]
|
||||||
|
privileged: false
|
||||||
|
restart: 'always'
|
||||||
|
labels: {
|
||||||
|
'io.resin.app-id': '1234'
|
||||||
|
'io.resin.service-id': '24'
|
||||||
|
'io.resin.supervised': 'true'
|
||||||
|
'io.resin.service-name': 'anotherService'
|
||||||
|
}
|
||||||
|
running: true
|
||||||
|
createdAt: new Date()
|
||||||
|
containerId: '2'
|
||||||
|
networkMode: 'default'
|
||||||
|
networks: { 'default': { aliases: [ 'anotherService' ] } }
|
||||||
|
command: [ 'someCommand' ]
|
||||||
|
entrypoint: [ 'theEntrypoint' ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
volumes: {}
|
||||||
|
networks: { default: {} }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
dependent: { apps: [], devices: [] }
|
||||||
|
}
|
||||||
|
|
||||||
exports.availableImages = availableImages = []
|
exports.availableImages = availableImages = []
|
||||||
availableImages[0] = [
|
availableImages[0] = [
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user