Merge "Add unit tests for creating and editing ports"
This commit is contained in:
commit
7d4f5688d6
@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Cray Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
describe('horizon.dashboard.admin.ironic.base-port', function () {
|
||||||
|
var uibModalInstance, ironicBackendMockService, ironicAPI;
|
||||||
|
var ctrl = {};
|
||||||
|
|
||||||
|
beforeEach(module('horizon.framework.util'));
|
||||||
|
|
||||||
|
beforeEach(module('horizon.dashboard.admin.ironic'));
|
||||||
|
|
||||||
|
beforeEach(module(function($provide) {
|
||||||
|
$provide.value('horizon.framework.widgets.toast.service', {
|
||||||
|
add: function() {}
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(module('horizon.app.core.openstack-service-api'));
|
||||||
|
|
||||||
|
beforeEach(module(function($provide) {
|
||||||
|
$provide.value('$uibModal', {});
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(module(function($provide) {
|
||||||
|
uibModalInstance = {
|
||||||
|
dismiss: jasmine.createSpy()
|
||||||
|
};
|
||||||
|
$provide.value('$uibModalInstance', uibModalInstance);
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(inject(function($injector) {
|
||||||
|
ironicBackendMockService =
|
||||||
|
$injector.get('horizon.dashboard.admin.ironic.backend-mock.service');
|
||||||
|
ironicBackendMockService.init();
|
||||||
|
|
||||||
|
ironicAPI =
|
||||||
|
$injector.get('horizon.app.core.openstack-service-api.ironic');
|
||||||
|
|
||||||
|
ironicAPI.createNode(
|
||||||
|
{driver: ironicBackendMockService.params.defaultDriver})
|
||||||
|
.then(function(response) {
|
||||||
|
var node = response.data;
|
||||||
|
var controller = $injector.get('$controller');
|
||||||
|
controller('BasePortController', {ctrl: ctrl,
|
||||||
|
node: node});
|
||||||
|
});
|
||||||
|
ironicBackendMockService.flush();
|
||||||
|
}));
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
ironicBackendMockService.postTest();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('controller should be defined', function () {
|
||||||
|
expect(ctrl).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('base construction', function () {
|
||||||
|
expect(Object.getOwnPropertyNames(ctrl).sort()).toEqual(
|
||||||
|
BASE_PORT_CONTROLLER_PROPERTIES.sort());
|
||||||
|
|
||||||
|
angular.forEach(
|
||||||
|
['address', 'pxeEnabled', 'portgroup_uuid'],
|
||||||
|
function(propertyName) {
|
||||||
|
expect(Object.keys(ctrl[propertyName])).toContain('value');
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(Object.keys(ctrl.extra)).toContain('properties');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('localLinkConnectionMgr', function () {
|
||||||
|
var props = ['port_id', 'switch_id', 'switch_info'];
|
||||||
|
angular.forEach(
|
||||||
|
props,
|
||||||
|
function(propertyName) {
|
||||||
|
expect(ctrl.localLinkConnection[propertyName].constructor.name)
|
||||||
|
.toBe('FormField');
|
||||||
|
expect(Object.keys(ctrl.localLinkConnection[propertyName]))
|
||||||
|
.toContain('value');
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(Object.keys(ctrl.localLinkConnection.fields).sort())
|
||||||
|
.toEqual(props.sort());
|
||||||
|
|
||||||
|
angular.forEach(
|
||||||
|
props,
|
||||||
|
function(propertyName) {
|
||||||
|
expect(ctrl.localLinkConnection[propertyName])
|
||||||
|
.toEqual(ctrl.localLinkConnection.fields[propertyName]);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(ctrl.localLinkConnection.update).toBeDefined();
|
||||||
|
expect(ctrl.localLinkConnection.toPortAttr).toBeDefined();
|
||||||
|
expect(ctrl.localLinkConnection.setValues).toBeDefined();
|
||||||
|
expect(ctrl.localLinkConnection.disable).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('localLinkConnectionMgr.update', function () {
|
||||||
|
ctrl.localLinkConnection.update();
|
||||||
|
expect(ctrl.localLinkConnection.port_id.required).toBe(false);
|
||||||
|
expect(ctrl.localLinkConnection.switch_id.required).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('localLinkConnectionMgr.setValues', function () {
|
||||||
|
var values = {port_id: 'port-id',
|
||||||
|
switch_id: '00:00:00:00:00:00',
|
||||||
|
switch_info: 'switch-info'};
|
||||||
|
ctrl.localLinkConnection.setValues(values);
|
||||||
|
angular.forEach(
|
||||||
|
Object.keys(values),
|
||||||
|
function(value, key) {
|
||||||
|
if (ctrl.localLinkConnection.hasOwnProperty(key)) {
|
||||||
|
expect(ctrl.localLinkConnection[key].value).toEqual(values[key]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('localLinkConnectionMgr.update - port_id has value', function () {
|
||||||
|
ctrl.localLinkConnection.setValues({port_id: 'port-id'});
|
||||||
|
ctrl.localLinkConnection.update();
|
||||||
|
expect(ctrl.localLinkConnection.port_id.required).toBe(true);
|
||||||
|
expect(ctrl.localLinkConnection.switch_id.required).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('localLinkConnectionMgr.update - switch_id has value', function () {
|
||||||
|
ctrl.localLinkConnection.setValues({switch_id: '00:00:00:00:00:00'});
|
||||||
|
ctrl.localLinkConnection.update();
|
||||||
|
expect(ctrl.localLinkConnection.port_id.required).toBe(true);
|
||||||
|
expect(ctrl.localLinkConnection.switch_id.required).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('localLinkConnectionMgr.toPortAttr - no values', function () {
|
||||||
|
expect(ctrl.localLinkConnection.toPortAttr()).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('localLinkConnectionMgr.toPortAttr - values', function () {
|
||||||
|
var values = {port_id: 'port-id',
|
||||||
|
switch_id: '00:00:00:00:00:00',
|
||||||
|
switch_info: 'switch-info'};
|
||||||
|
ctrl.localLinkConnection.setValues(values);
|
||||||
|
expect(ctrl.localLinkConnection.toPortAttr()).toEqual(values);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('localLinkConnectionMgr.disable', function () {
|
||||||
|
function validateDisabled(state) {
|
||||||
|
angular.forEach(
|
||||||
|
['port_id', 'switch_id', 'switch_info'],
|
||||||
|
function(propertyName) {
|
||||||
|
expect(ctrl.localLinkConnection[propertyName]).
|
||||||
|
toEqual(jasmine.objectContaining({disabled: state}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
validateDisabled(false);
|
||||||
|
ctrl.localLinkConnection.disable();
|
||||||
|
validateDisabled(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('cancel', function () {
|
||||||
|
ctrl.cancel();
|
||||||
|
expect(uibModalInstance.dismiss).toHaveBeenCalledWith('cancel');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
@ -56,7 +56,7 @@
|
|||||||
ctrl.createPort = function() {
|
ctrl.createPort = function() {
|
||||||
var port = {
|
var port = {
|
||||||
extra: ctrl.extra.properties,
|
extra: ctrl.extra.properties,
|
||||||
node_uuid: node.id,
|
node_uuid: node.uuid,
|
||||||
address: ctrl.address.value
|
address: ctrl.address.value
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Cray Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
describe('horizon.dashboard.admin.ironic.create-port', function () {
|
||||||
|
var ironicBackendMockService, uibModalInstance, ironicAPI, controller,
|
||||||
|
rootScope, ironicEvents;
|
||||||
|
|
||||||
|
beforeEach(module('horizon.dashboard.admin.ironic'));
|
||||||
|
|
||||||
|
beforeEach(module('horizon.framework.util'));
|
||||||
|
|
||||||
|
beforeEach(module(function($provide) {
|
||||||
|
$provide.value('$uibModal', {});
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(module(function($provide) {
|
||||||
|
uibModalInstance = {};
|
||||||
|
$provide.value('$uibModalInstance', uibModalInstance);
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(module(function($provide) {
|
||||||
|
$provide.value('horizon.framework.widgets.toast.service', {
|
||||||
|
add: function() {}
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(module('horizon.app.core.openstack-service-api'));
|
||||||
|
|
||||||
|
beforeEach(inject(function($injector) {
|
||||||
|
ironicBackendMockService =
|
||||||
|
$injector.get('horizon.dashboard.admin.ironic.backend-mock.service');
|
||||||
|
ironicBackendMockService.init();
|
||||||
|
|
||||||
|
ironicAPI =
|
||||||
|
$injector.get('horizon.app.core.openstack-service-api.ironic');
|
||||||
|
|
||||||
|
controller = $injector.get('$controller');
|
||||||
|
rootScope = $injector.get('$rootScope');
|
||||||
|
ironicEvents = $injector.get('horizon.dashboard.admin.ironic.events');
|
||||||
|
}));
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
ironicBackendMockService.postTest();
|
||||||
|
});
|
||||||
|
|
||||||
|
function createController() {
|
||||||
|
return ironicAPI.createNode({
|
||||||
|
driver: ironicBackendMockService.params.defaultDriver})
|
||||||
|
.then(function(response) {
|
||||||
|
var node = response.data;
|
||||||
|
return {node: response.data,
|
||||||
|
ctrl: controller('CreatePortController',
|
||||||
|
{node: node})};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
it('controller should be defined', function () {
|
||||||
|
createController()
|
||||||
|
.then(function(data) {
|
||||||
|
expect(data.ctrl).toBeDefined();
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
fail();
|
||||||
|
});
|
||||||
|
ironicBackendMockService.flush();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('base construction', function () {
|
||||||
|
createController()
|
||||||
|
.then(function(data) {
|
||||||
|
var ctrl = data.ctrl;
|
||||||
|
var properties = angular.copy(BASE_PORT_CONTROLLER_PROPERTIES);
|
||||||
|
properties.push('modalTitle');
|
||||||
|
properties.push('submitButtonTitle');
|
||||||
|
properties.push('createPort');
|
||||||
|
properties.push('submit');
|
||||||
|
expect(Object.getOwnPropertyNames(ctrl).sort()).toEqual(
|
||||||
|
properties.sort());
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
fail();
|
||||||
|
});
|
||||||
|
ironicBackendMockService.flush();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('submit - success', function () {
|
||||||
|
var portParams = {
|
||||||
|
address: '00:00:00:00:00:00'
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(ironicAPI, 'createPort').and.callThrough();
|
||||||
|
spyOn(rootScope, '$emit');
|
||||||
|
|
||||||
|
uibModalInstance.close = function(port) {
|
||||||
|
expect(port.address).toEqual(portParams.address);
|
||||||
|
expect(port).toEqual(
|
||||||
|
ironicBackendMockService.getPort(port.uuid));
|
||||||
|
expect(rootScope.$emit)
|
||||||
|
.toHaveBeenCalledWith(ironicEvents.CREATE_PORT_SUCCESS);
|
||||||
|
};
|
||||||
|
|
||||||
|
createController()
|
||||||
|
.then(function(data) {
|
||||||
|
var ctrl = data.ctrl;
|
||||||
|
angular.forEach(
|
||||||
|
portParams,
|
||||||
|
function(value, param) {
|
||||||
|
ctrl[param].value = value;
|
||||||
|
});
|
||||||
|
ctrl.submit();
|
||||||
|
expect(ironicAPI.createPort).toHaveBeenCalled();
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
fail();
|
||||||
|
});
|
||||||
|
ironicBackendMockService.flush();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
@ -105,9 +105,12 @@
|
|||||||
patcher.buildPatch(port.pxe_enabled ? 'True' : 'False',
|
patcher.buildPatch(port.pxe_enabled ? 'True' : 'False',
|
||||||
ctrl.pxeEnabled.value,
|
ctrl.pxeEnabled.value,
|
||||||
"/pxe_enabled");
|
"/pxe_enabled");
|
||||||
|
var attr = ctrl.localLinkConnection.toPortAttr();
|
||||||
|
if (attr) {
|
||||||
patcher.buildPatch(port.local_link_connection,
|
patcher.buildPatch(port.local_link_connection,
|
||||||
ctrl.localLinkConnection.toPortAttr(),
|
attr,
|
||||||
"/local_link_connection");
|
"/local_link_connection");
|
||||||
|
}
|
||||||
patcher.buildPatch(port.extra, ctrl.extra.properties, "/extra");
|
patcher.buildPatch(port.extra, ctrl.extra.properties, "/extra");
|
||||||
patcher.buildPatch(port.portgroup_uuid,
|
patcher.buildPatch(port.portgroup_uuid,
|
||||||
ctrl.portgroup_uuid.value,
|
ctrl.portgroup_uuid.value,
|
||||||
|
@ -0,0 +1,250 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Cray Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
describe('horizon.dashboard.admin.ironic.edit-port', function () {
|
||||||
|
var ironicBackendMockService, uibModalInstance, ironicAPI, controller,
|
||||||
|
rootScope, ironicEvents;
|
||||||
|
|
||||||
|
beforeEach(module('horizon.dashboard.admin.ironic'));
|
||||||
|
|
||||||
|
beforeEach(module('horizon.framework.util'));
|
||||||
|
|
||||||
|
beforeEach(module(function($provide) {
|
||||||
|
$provide.value('$uibModal', {});
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(module(function($provide) {
|
||||||
|
uibModalInstance = {};
|
||||||
|
$provide.value('$uibModalInstance', uibModalInstance);
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(module(function($provide) {
|
||||||
|
$provide.value('horizon.framework.widgets.toast.service', {
|
||||||
|
add: function() {}
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(module('horizon.app.core.openstack-service-api'));
|
||||||
|
|
||||||
|
beforeEach(inject(function($injector) {
|
||||||
|
ironicBackendMockService =
|
||||||
|
$injector.get('horizon.dashboard.admin.ironic.backend-mock.service');
|
||||||
|
ironicBackendMockService.init();
|
||||||
|
|
||||||
|
ironicAPI =
|
||||||
|
$injector.get('horizon.app.core.openstack-service-api.ironic');
|
||||||
|
|
||||||
|
controller = $injector.get('$controller');
|
||||||
|
rootScope = $injector.get('$rootScope');
|
||||||
|
ironicEvents = $injector.get('horizon.dashboard.admin.ironic.events');
|
||||||
|
}));
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
ironicBackendMockService.postTest();
|
||||||
|
});
|
||||||
|
|
||||||
|
function createController(nodeParams) {
|
||||||
|
if (angular.isUndefined(nodeParams)) {
|
||||||
|
nodeParams = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (angular.isUndefined(nodeParams.driver)) {
|
||||||
|
nodeParams.driver = ironicBackendMockService.params.defaultDriver;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ironicAPI.createNode(nodeParams)
|
||||||
|
.then(function(response) {
|
||||||
|
return response.data;
|
||||||
|
})
|
||||||
|
.then(function(node) {
|
||||||
|
return ironicAPI.createPort({address:'00:00:00:00:00:00',
|
||||||
|
node_uuid: node.uuid})
|
||||||
|
.then(function(port) {
|
||||||
|
return {node: node, port: port};
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(function(data) {
|
||||||
|
return {node: data.node,
|
||||||
|
port: data.port,
|
||||||
|
ctrl: controller('EditPortController',
|
||||||
|
{node: data.node,
|
||||||
|
port: data.port})};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
it('controller should be defined', function () {
|
||||||
|
createController()
|
||||||
|
.then(function(data) {
|
||||||
|
expect(data.ctrl).toBeDefined();
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
fail();
|
||||||
|
});
|
||||||
|
ironicBackendMockService.flush();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('base construction', function () {
|
||||||
|
createController()
|
||||||
|
.then(function(data) {
|
||||||
|
var ctrl = data.ctrl;
|
||||||
|
var properties = angular.copy(BASE_PORT_CONTROLLER_PROPERTIES);
|
||||||
|
properties.push('modalTitle');
|
||||||
|
properties.push('submitButtonTitle');
|
||||||
|
properties.push('updatePort');
|
||||||
|
properties.push('submit');
|
||||||
|
expect(Object.getOwnPropertyNames(ctrl).sort()).toEqual(
|
||||||
|
properties.sort());
|
||||||
|
expect(ctrl.address.disabled).toBe(false);
|
||||||
|
expect(ctrl.pxeEnabled.disabled).toBe(false);
|
||||||
|
angular.forEach(ctrl.localLinkConnection.fields,
|
||||||
|
function(field) {
|
||||||
|
expect(field.disabled).toBe(false);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
fail();
|
||||||
|
});
|
||||||
|
ironicBackendMockService.flush();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('node in enroll state', function () {
|
||||||
|
createController()
|
||||||
|
.then(function(data) {
|
||||||
|
var ctrl = data.ctrl;
|
||||||
|
expect(data.node.provision_state).toBe('enroll');
|
||||||
|
expect(ctrl.address.disabled).toBe(false);
|
||||||
|
expect(ctrl.pxeEnabled.disabled).toBe(false);
|
||||||
|
angular.forEach(ctrl.localLinkConnection.fields,
|
||||||
|
function(field) {
|
||||||
|
expect(field.disabled).toBe(false);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
fail();
|
||||||
|
});
|
||||||
|
ironicBackendMockService.flush();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('node in active state', function () {
|
||||||
|
createController({provision_state: 'active'})
|
||||||
|
.then(function(data) {
|
||||||
|
var ctrl = data.ctrl;
|
||||||
|
expect(data.node.provision_state).toBe('active');
|
||||||
|
expect(ctrl.address.disabled).toBe(true);
|
||||||
|
expect(ctrl.pxeEnabled.disabled).toBe(true);
|
||||||
|
angular.forEach(ctrl.localLinkConnection.fields,
|
||||||
|
function(field) {
|
||||||
|
expect(field.disabled).toBe(true);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
fail();
|
||||||
|
});
|
||||||
|
ironicBackendMockService.flush();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('node in available state', function () {
|
||||||
|
createController({provision_state: 'available'})
|
||||||
|
.then(function(data) {
|
||||||
|
var ctrl = data.ctrl;
|
||||||
|
expect(data.node.provision_state).toBe('available');
|
||||||
|
expect(ctrl.address.disabled).toBe(false);
|
||||||
|
expect(ctrl.pxeEnabled.disabled).toBe(true);
|
||||||
|
angular.forEach(ctrl.localLinkConnection.fields,
|
||||||
|
function(field) {
|
||||||
|
expect(field.disabled).toBe(true);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
fail();
|
||||||
|
});
|
||||||
|
ironicBackendMockService.flush();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('node in maintenance mode', function () {
|
||||||
|
createController({provision_state: 'active',
|
||||||
|
maintenance: true})
|
||||||
|
.then(function(data) {
|
||||||
|
var ctrl = data.ctrl;
|
||||||
|
expect(data.node.provision_state).toBe('active');
|
||||||
|
expect(data.node.maintenance).toBe(true);
|
||||||
|
expect(ctrl.address.disabled).toBe(false);
|
||||||
|
expect(ctrl.pxeEnabled.disabled).toBe(false);
|
||||||
|
angular.forEach(ctrl.localLinkConnection.fields,
|
||||||
|
function(field) {
|
||||||
|
expect(field.disabled).toBe(false);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
fail();
|
||||||
|
});
|
||||||
|
ironicBackendMockService.flush();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updatePort - no change', function () {
|
||||||
|
createController()
|
||||||
|
.then(function(data) {
|
||||||
|
spyOn(ironicAPI, 'updatePort').and.callThrough();
|
||||||
|
spyOn(rootScope, '$emit');
|
||||||
|
|
||||||
|
uibModalInstance.close = function(port) {
|
||||||
|
expect(port.address).toEqual(data.port.address);
|
||||||
|
expect(port).toEqual(
|
||||||
|
ironicBackendMockService.getPort(port.uuid));
|
||||||
|
expect(rootScope.$emit)
|
||||||
|
.toHaveBeenCalledWith(ironicEvents.EDIT_PORT_SUCCESS);
|
||||||
|
};
|
||||||
|
|
||||||
|
var ctrl = data.ctrl;
|
||||||
|
ctrl.updatePort();
|
||||||
|
expect(ironicAPI.updatePort)
|
||||||
|
.toHaveBeenCalledWith(data.port.uuid, []);
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
fail();
|
||||||
|
});
|
||||||
|
ironicBackendMockService.flush();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('submit - change MAC address', function () {
|
||||||
|
var newAddress = '12:12:12:12:12:12';
|
||||||
|
|
||||||
|
createController()
|
||||||
|
.then(function(data) {
|
||||||
|
spyOn(ironicAPI, 'updatePort').and.callThrough();
|
||||||
|
spyOn(rootScope, '$emit');
|
||||||
|
|
||||||
|
uibModalInstance.close = function(port) {
|
||||||
|
expect(port.address).toEqual(newAddress);
|
||||||
|
expect(port).toEqual(
|
||||||
|
ironicBackendMockService.getPort(port.uuid));
|
||||||
|
expect(rootScope.$emit)
|
||||||
|
.toHaveBeenCalledWith(ironicEvents.EDIT_PORT_SUCCESS);
|
||||||
|
};
|
||||||
|
|
||||||
|
var ctrl = data.ctrl;
|
||||||
|
ctrl.address.value = newAddress;
|
||||||
|
ctrl.submit();
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
fail();
|
||||||
|
});
|
||||||
|
ironicBackendMockService.flush();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
@ -421,46 +421,76 @@
|
|||||||
return [status, ""];
|
return [status, ""];
|
||||||
});
|
});
|
||||||
|
|
||||||
function _addItem(node, path, value) {
|
function _addItem(obj, path, value) {
|
||||||
var parts = path.substring(1).split("/");
|
var pathNames = path.substring(1).split("/");
|
||||||
var leaf = parts.pop();
|
var leaf = pathNames.pop();
|
||||||
var obj = node;
|
var part = obj;
|
||||||
for (var i = 0; i < parts.length; i++) {
|
for (var i = 0; i < pathNames.length; i++) {
|
||||||
var part = parts[i];
|
var name = pathNames[i];
|
||||||
if (angular.isUndefined(obj[part])) {
|
if (angular.isUndefined(part[name])) {
|
||||||
obj[part] = {};
|
part[name] = {};
|
||||||
}
|
}
|
||||||
obj = obj[part];
|
part = part[name];
|
||||||
}
|
}
|
||||||
obj[leaf] = value;
|
part[leaf] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _removeItem(node, path) {
|
function _removeItem(obj, path) {
|
||||||
var parts = path.substring(1).split("/");
|
var pathNames = path.substring(1).split("/");
|
||||||
var leaf = parts.pop();
|
var leaf = pathNames.pop();
|
||||||
var obj = node;
|
var part = obj;
|
||||||
for (var i = 0; i < parts.length; i++) {
|
for (var i = 0; i < pathNames.length; i++) {
|
||||||
obj = obj[parts[i]];
|
part = part[pathNames[i]];
|
||||||
}
|
}
|
||||||
delete obj[leaf];
|
delete part[leaf];
|
||||||
}
|
}
|
||||||
|
|
||||||
function _replaceItem(node, path, value) {
|
function _replaceItem(obj, path, value, collection) {
|
||||||
if (path === "/name" &&
|
// Special handling for changing the name of an object
|
||||||
node.name !== null) {
|
// that is stored in a name-indexed collection.
|
||||||
delete nodes[node.name];
|
if (path === "/name" && obj.name !== null) {
|
||||||
|
if (angular.isDefined(collection)) {
|
||||||
|
delete collection[obj.name];
|
||||||
if (value !== null) {
|
if (value !== null) {
|
||||||
nodes[value] = node;
|
collection[value] = obj;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var parts = path.substring(1).split("/");
|
var pathNames = path.substring(1).split("/");
|
||||||
var leaf = parts.pop();
|
var leaf = pathNames.pop();
|
||||||
var obj = node;
|
var part = obj;
|
||||||
for (var i = 0; i < parts.length; i++) {
|
for (var i = 0; i < pathNames.length; i++) {
|
||||||
obj = obj[parts[i]];
|
part = part[pathNames[i]];
|
||||||
}
|
}
|
||||||
obj[leaf] = value;
|
part[leaf] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Apply a patch to a specified object.
|
||||||
|
*
|
||||||
|
* @param {object} obj - Object to be patched, e.g. node, port, ...
|
||||||
|
* @param {object} patch - Patch object.
|
||||||
|
* @param {object} collection - Optional. Collection to which the
|
||||||
|
* object belongs. Only required if the collection indexes the
|
||||||
|
* object by name.
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
function patchObject(obj, patch, collection) {
|
||||||
|
angular.forEach(patch, function(operation) {
|
||||||
|
switch (operation.op) {
|
||||||
|
case "add":
|
||||||
|
_addItem(obj, operation.path, operation.value);
|
||||||
|
break;
|
||||||
|
case "remove":
|
||||||
|
_removeItem(obj, operation.path);
|
||||||
|
break;
|
||||||
|
case "replace":
|
||||||
|
_replaceItem(obj, operation.path, operation.value, collection);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update node
|
// Update node
|
||||||
@ -472,21 +502,7 @@
|
|||||||
var status = responseCode.RESOURCE_NOT_FOUND;
|
var status = responseCode.RESOURCE_NOT_FOUND;
|
||||||
var node = service.getNode(params.nodeId);
|
var node = service.getNode(params.nodeId);
|
||||||
if (angular.isDefined(node)) {
|
if (angular.isDefined(node)) {
|
||||||
var patch = JSON.parse(data).patch;
|
patchObject(node, JSON.parse(data).patch, nodes);
|
||||||
angular.forEach(patch, function(operation) {
|
|
||||||
switch (operation.op) {
|
|
||||||
case "add":
|
|
||||||
_addItem(node, operation.path, operation.value);
|
|
||||||
break;
|
|
||||||
case "remove":
|
|
||||||
_removeItem(node, operation.path);
|
|
||||||
break;
|
|
||||||
case "replace":
|
|
||||||
_replaceItem(node, operation.path, operation.value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
});
|
|
||||||
status = responseCode.SUCCESS;
|
status = responseCode.SUCCESS;
|
||||||
}
|
}
|
||||||
return [status, node];
|
return [status, node];
|
||||||
@ -539,9 +555,9 @@
|
|||||||
['nodeId'])
|
['nodeId'])
|
||||||
.respond(function(method, url, data, headers, params) {
|
.respond(function(method, url, data, headers, params) {
|
||||||
if (angular.isDefined(nodes[params.nodeId])) {
|
if (angular.isDefined(nodes[params.nodeId])) {
|
||||||
return [200, nodes[params.nodeId].bootDevice];
|
return [responseCode.SUCCESS, nodes[params.nodeId].bootDevice];
|
||||||
} else {
|
} else {
|
||||||
return [400, null];
|
return [responseCode.BAD_QUERY, null];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -552,9 +568,10 @@
|
|||||||
['nodeId'])
|
['nodeId'])
|
||||||
.respond(function(method, url, data, headers, params) {
|
.respond(function(method, url, data, headers, params) {
|
||||||
if (angular.isDefined(nodes[params.nodeId])) {
|
if (angular.isDefined(nodes[params.nodeId])) {
|
||||||
return [200, nodes[params.nodeId].supportedBootDevices];
|
return [responseCode.SUCCESS,
|
||||||
|
nodes[params.nodeId].supportedBootDevices];
|
||||||
} else {
|
} else {
|
||||||
return [400, null];
|
return [responseCode.BAD_QUERY, null];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -565,7 +582,7 @@
|
|||||||
['nodeId'])
|
['nodeId'])
|
||||||
.respond(function(method, url, data, headers, params) {
|
.respond(function(method, url, data, headers, params) {
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
var status = 404;
|
var status = responseCode.RESOURCE_NOT_FOUND;
|
||||||
if (angular.isDefined(nodes[params.nodeId])) {
|
if (angular.isDefined(nodes[params.nodeId])) {
|
||||||
var node = nodes[params.nodeId];
|
var node = nodes[params.nodeId];
|
||||||
if (node.supportedBootDevices.indexOf(data.boot_device) !== -1) {
|
if (node.supportedBootDevices.indexOf(data.boot_device) !== -1) {
|
||||||
@ -573,7 +590,7 @@
|
|||||||
if (angular.isDefined(data.persistent)) {
|
if (angular.isDefined(data.persistent)) {
|
||||||
node.bootDevice.persistent = data.persistent;
|
node.bootDevice.persistent = data.persistent;
|
||||||
}
|
}
|
||||||
status = 200;
|
status = responseCode.SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [status, null];
|
return [status, null];
|
||||||
@ -617,6 +634,21 @@
|
|||||||
return [status, ""];
|
return [status, ""];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Update port
|
||||||
|
$httpBackend.whenPATCH(/\/api\/ironic\/ports\/([^\/]+)$/,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
['portId'])
|
||||||
|
.respond(function(method, url, data, headers, params) {
|
||||||
|
var status = responseCode.RESOURCE_NOT_FOUND;
|
||||||
|
var port = service.getPort(params.portId);
|
||||||
|
if (angular.isDefined(port)) {
|
||||||
|
patchObject(port, JSON.parse(data).patch);
|
||||||
|
status = responseCode.SUCCESS;
|
||||||
|
}
|
||||||
|
return [status, port];
|
||||||
|
});
|
||||||
|
|
||||||
// Get ports
|
// Get ports
|
||||||
$httpBackend.whenGET(/\/api\/ironic\/ports\//)
|
$httpBackend.whenGET(/\/api\/ironic\/ports\//)
|
||||||
.respond(function(method, url, data, header, params) {
|
.respond(function(method, url, data, header, params) {
|
||||||
|
@ -41,7 +41,18 @@ var BASE_NODE_CONTROLLER_PROPERTIES = [
|
|||||||
'submitButtonTitle',
|
'submitButtonTitle',
|
||||||
'validHostNameRegex'];
|
'validHostNameRegex'];
|
||||||
|
|
||||||
|
/* exported BASE_PORT_CONTROLLER_PROPERTIES */
|
||||||
|
|
||||||
|
var BASE_PORT_CONTROLLER_PROPERTIES = [
|
||||||
|
'address',
|
||||||
|
'cancel',
|
||||||
|
'extra',
|
||||||
|
'localLinkConnection',
|
||||||
|
'pxeEnabled',
|
||||||
|
'portgroup_uuid'];
|
||||||
|
|
||||||
/* exported BASE_PORTGROUP_CONTROLLER_PROPERTIES */
|
/* exported BASE_PORTGROUP_CONTROLLER_PROPERTIES */
|
||||||
|
|
||||||
var BASE_PORTGROUP_CONTROLLER_PROPERTIES = [
|
var BASE_PORTGROUP_CONTROLLER_PROPERTIES = [
|
||||||
'address',
|
'address',
|
||||||
'cancel',
|
'cancel',
|
||||||
|
Loading…
Reference in New Issue
Block a user