From 57e44420e8f15ef4f5e304fcfac19373fa0751b2 Mon Sep 17 00:00:00 2001 From: Rob Cresswell Date: Wed, 8 Jun 2016 12:46:47 +0100 Subject: [PATCH] Improve new Launch Instance defaults + tests commit 42a22cba55c6f9e43a9ed37f0487d9d765616641 Author: Rob Cresswell Date: Fri Jun 3 10:32:07 2016 +0100 Add missing unit tests to NG launch instance https://review.openstack.org/#/c/323623/ added a few new defaults to the Launch Instance but didn't add any tests, so the backport is blocked on coverage. Rather than lower coverage, we should just add the tests and squash the two commits in the backport. Fastest way to verify is to generate coverage in master, look at the lines added by https://review.openstack.org/#/c/323623/ (red) then apply this patch and run again. You'll see they are all white. Change-Id: I07d2f5ebcb1771a548c0066699194ea619e7461c Related-Bug: #1587681 (cherry picked from commit b3b88310e10d4315b6455f25a63d21e17100f57f) commit 883552578acb30210dcd7533e8b6224551e5785f Author: Kevin Fox Date: Tue May 31 17:00:20 2016 -0700 Set some useful default values with the new launch wizard. In Mitaka, the new launch instance wizard regresses functionality from the old launch wizard with regards to defaults. If there is only one neutron network, it is not automatically selected, if there is only one keypair, its not selected, and the default security group is not automatically selected. This patch fixes all of that. Change-Id: I23bab6998e38ba1066b926a4fe71713768d9dff4 Closes-Bug: #1587681 (cherry picked from commit d4a8023d17f672f10e83e48fab4e97dc0796af76) Change-Id: I0f5c056db62915b4b50d4accba0b4645c88bffde --- .../launch-instance-model.service.js | 15 +++ .../launch-instance-model.service.spec.js | 124 ++++++++++++------ 2 files changed, 99 insertions(+), 40 deletions(-) diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.js b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.js index 004a0e8daa..395995810a 100644 --- a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.js +++ b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.js @@ -326,6 +326,9 @@ e.keypair.id = e.keypair.name; return e.keypair; })); + if (data.data.items.length === 1) { + model.newInstanceSpec.key_pair.push(data.data.items[0].keypair); + } } function setFinalSpecKeyPairs(finalSpec) { @@ -343,6 +346,15 @@ function onGetSecurityGroups(data) { model.securityGroups.length = 0; + angular.forEach(data.data.items, function addDefault(item) { + // 'default' is a special security group in neutron. It can not be + // deleted and is guaranteed to exist. It by default contains all + // of the rules needed for an instance to reach out to the network + // so the instance can provision itself. + if (item.name === 'default') { + model.newInstanceSpec.security_groups.push(item); + } + }); push.apply(model.securityGroups, data.data.items); } @@ -368,6 +380,9 @@ function onGetNetworks(data) { model.neutronEnabled = true; model.networks.length = 0; + if (data.data.items.length === 1) { + model.newInstanceSpec.networks.push(data.data.items[0]); + } push.apply(model.networks, data.data.items); return data; } diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js index 3df402dcc9..98873a0ba6 100644 --- a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js +++ b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js @@ -71,6 +71,47 @@ } }; + var securityGroupApi = { + query: function() { + var secGroups = [ + { name: 'security-group-1' }, + { name: 'security-group-2' } + ]; + + var deferred = $q.defer(); + deferred.resolve({ data: { items: secGroups } }); + return deferred.promise; + } + }; + + var neutronApi = { + getNetworks: function() { + var networks = [ { id: 'net-1' }, { id: 'net-2' } ]; + + var deferred = $q.defer(); + deferred.resolve({ data: { items: networks } }); + + return deferred.promise; + }, + getPorts: function(network) { + var ports = { + 'net-1': [ + { name: 'port-1', device_owner: '', fixed_ips: [], admin_state: 'UP' }, + { name: 'port-2', device_owner: '', fixed_ips: [], admin_state: 'DOWN' } + ], + 'net-2': [ + { name: 'port-3', device_owner: 'owner', fixed_ips: [], admin_state: 'DOWN' }, + { name: 'port-4', device_owner: '', fixed_ips: [], admin_state: 'DOWN' } + ] + }; + + var deferred = $q.defer(); + deferred.resolve({ data: { items: ports[network.network_id] } }); + + return deferred.promise; + } + }; + beforeEach(module('horizon.dashboard.project.workflow.launch-instance')); beforeEach(module(function($provide) { @@ -110,47 +151,9 @@ $provide.value('horizon.app.core.openstack-service-api.nova', novaApi); - $provide.value('horizon.app.core.openstack-service-api.security-group', { - query: function() { - var secGroups = [ - { name: 'security-group-1' }, - { name: 'security-group-2' } - ]; + $provide.value('horizon.app.core.openstack-service-api.security-group', securityGroupApi); - var deferred = $q.defer(); - deferred.resolve({ data: { items: secGroups } }); - - return deferred.promise; - } - }); - - $provide.value('horizon.app.core.openstack-service-api.neutron', { - getNetworks: function() { - var networks = [ { id: 'net-1' }, { id: 'net-2' } ]; - - var deferred = $q.defer(); - deferred.resolve({ data: { items: networks } }); - - return deferred.promise; - }, - getPorts: function(network) { - var ports = { - 'net-1': [ - { name: 'port-1', device_owner: '', fixed_ips: [], admin_state: 'UP' }, - { name: 'port-2', device_owner: '', fixed_ips: [], admin_state: 'DOWN' } - ], - 'net-2': [ - { name: 'port-3', device_owner: 'owner', fixed_ips: [], admin_state: 'DOWN' }, - { name: 'port-4', device_owner: '', fixed_ips: [], admin_state: 'DOWN' } - ] - }; - - var deferred = $q.defer(); - deferred.resolve({ data: { items: ports[network.network_id] } }); - - return deferred.promise; - } - }); + $provide.value('horizon.app.core.openstack-service-api.neutron', neutronApi); $provide.value('horizon.app.core.openstack-service-api.cinder', { getVolumes: function() { @@ -387,6 +390,47 @@ scope.$apply(); expect(model.ports.length).toBe(1); }); + + it('should set a keypair by default if only one keypair is available', function () { + var keypair = { keypair: { name: 'key-1' } }; + spyOn(novaApi, 'getKeypairs').and.callFake(function () { + var deferred = $q.defer(); + deferred.resolve({ data: { items: [ keypair ] } }); + return deferred.promise; + }); + model.initialize(true); + scope.$apply(); + expect(model.newInstanceSpec.key_pair.length).toBe(1); + expect(model.newInstanceSpec.key_pair).toEqual( [ keypair.keypair ] ); + }); + + it('should set a security group by default if one named "default" is available', + function () { + var secGroups = [ { name: 'default' } ]; + spyOn(securityGroupApi, 'query').and.callFake(function () { + var deferred = $q.defer(); + deferred.resolve({ data: { items: secGroups } }); + return deferred.promise; + }); + model.initialize(true); + scope.$apply(); + expect(model.newInstanceSpec.security_groups.length).toBe(1); + expect(model.newInstanceSpec.security_groups).toEqual(secGroups); + } + ); + + it('should set a network by default if only one network is available', function () { + var networks = [ { id: 'net-1' } ]; + spyOn(neutronApi, 'getNetworks').and.callFake(function () { + var deferred = $q.defer(); + deferred.resolve({ data: { items: networks } }); + return deferred.promise; + }); + model.initialize(true); + scope.$apply(); + expect(model.newInstanceSpec.networks.length).toBe(1); + expect(model.newInstanceSpec.networks).toEqual(networks); + }); }); describe('Post Initialization Model - Initializing', function() {