blob: 612a5a28b0967aac011f214db9763782cb1733f8 [file] [log] [blame]
Adam Gandelman4a48a602014-03-20 18:23:18 -07001#
2# Copyright 2014 Hewlett-Packard Development Company, L.P.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
Doug Hellmann583ce2c2015-03-11 14:55:46 +000016from oslo_log import log as logging
17
Adam Gandelman4a48a602014-03-20 18:23:18 -070018from tempest import config
Adam Gandelman4a48a602014-03-20 18:23:18 -070019from tempest.scenario import manager
20from tempest import test
21
22CONF = config.CONF
23
24LOG = logging.getLogger(__name__)
25
26
David Shrewsbury02719362014-05-20 14:10:03 -040027class BaremetalBasicOps(manager.BaremetalScenarioTest):
Adam Gandelman4a48a602014-03-20 18:23:18 -070028 """
29 This smoke test tests the pxe_ssh Ironic driver. It follows this basic
30 set of operations:
31 * Creates a keypair
32 * Boots an instance using the keypair
33 * Monitors the associated Ironic node for power and
34 expected state transitions
Adam Gandelman4a48a602014-03-20 18:23:18 -070035 * Validates Ironic node's port data has been properly updated
36 * Verifies SSH connectivity using created keypair via fixed IP
37 * Associates a floating ip
38 * Verifies SSH connectivity using created keypair via floating IP
David Shrewsbury02719362014-05-20 14:10:03 -040039 * Verifies instance rebuild with ephemeral partition preservation
Adam Gandelman4a48a602014-03-20 18:23:18 -070040 * Deletes instance
41 * Monitors the associated Ironic node for power and
42 expected state transitions
43 """
David Shrewsbury02719362014-05-20 14:10:03 -040044 def rebuild_instance(self, preserve_ephemeral=False):
Adam Gandelmanc78c7572014-08-28 18:38:55 -070045 self.rebuild_server(server_id=self.instance['id'],
David Shrewsbury02719362014-05-20 14:10:03 -040046 preserve_ephemeral=preserve_ephemeral,
47 wait=False)
48
Adam Gandelmanc78c7572014-08-28 18:38:55 -070049 node = self.get_node(instance_id=self.instance['id'])
David Shrewsbury02719362014-05-20 14:10:03 -040050
51 # We should remain on the same node
Adam Gandelmanc78c7572014-08-28 18:38:55 -070052 self.assertEqual(self.node['uuid'], node['uuid'])
David Shrewsbury02719362014-05-20 14:10:03 -040053 self.node = node
54
Adam Gandelmanc78c7572014-08-28 18:38:55 -070055 self.servers_client.wait_for_server_status(
56 server_id=self.instance['id'],
57 status='REBUILD',
58 ready_wait=False)
59 self.servers_client.wait_for_server_status(
60 server_id=self.instance['id'],
61 status='ACTIVE')
David Shrewsbury02719362014-05-20 14:10:03 -040062
63 def create_remote_file(self, client, filename):
64 """Create a file on the remote client connection.
65
66 After creating the file, force a filesystem sync. Otherwise,
67 if we issue a rebuild too quickly, the file may not exist.
68 """
69 client.exec_command('sudo touch ' + filename)
70 client.exec_command('sync')
71
72 def verify_partition(self, client, label, mount, gib_size):
73 """Verify a labeled partition's mount point and size."""
74 LOG.info("Looking for partition %s mounted on %s" % (label, mount))
75
76 # Validate we have a device with the given partition label
77 cmd = "/sbin/blkid | grep '%s' | cut -d':' -f1" % label
78 device = client.exec_command(cmd).rstrip('\n')
79 LOG.debug("Partition device is %s" % device)
80 self.assertNotEqual('', device)
81
82 # Validate the mount point for the device
83 cmd = "mount | grep '%s' | cut -d' ' -f3" % device
84 actual_mount = client.exec_command(cmd).rstrip('\n')
85 LOG.debug("Partition mount point is %s" % actual_mount)
86 self.assertEqual(actual_mount, mount)
87
88 # Validate the partition size matches what we expect
89 numbers = '0123456789'
90 devnum = device.replace('/dev/', '')
91 cmd = "cat /sys/block/%s/%s/size" % (devnum.rstrip(numbers), devnum)
92 num_bytes = client.exec_command(cmd).rstrip('\n')
93 num_bytes = int(num_bytes) * 512
94 actual_gib_size = num_bytes / (1024 * 1024 * 1024)
95 LOG.debug("Partition size is %d GiB" % actual_gib_size)
96 self.assertEqual(actual_gib_size, gib_size)
97
98 def get_flavor_ephemeral_size(self):
99 """Returns size of the ephemeral partition in GiB."""
Adam Gandelmanc78c7572014-08-28 18:38:55 -0700100 f_id = self.instance['flavor']['id']
David Kranz2fa77b22015-02-09 11:39:50 -0500101 flavor = self.flavors_client.get_flavor_details(f_id)
Adam Gandelmanc78c7572014-08-28 18:38:55 -0700102 ephemeral = flavor.get('OS-FLV-EXT-DATA:ephemeral')
103 if not ephemeral or ephemeral == 'N/A':
104 return None
105 return int(ephemeral)
David Shrewsbury02719362014-05-20 14:10:03 -0400106
Adam Gandelman4a48a602014-03-20 18:23:18 -0700107 def add_floating_ip(self):
David Kranze4e3b412015-02-10 10:50:42 -0500108 floating_ip = self.floating_ips_client.create_floating_ip()
Adam Gandelmanc78c7572014-08-28 18:38:55 -0700109 self.floating_ips_client.associate_floating_ip_to_server(
110 floating_ip['ip'], self.instance['id'])
111 return floating_ip['ip']
Adam Gandelman4a48a602014-03-20 18:23:18 -0700112
Adam Gandelman4a48a602014-03-20 18:23:18 -0700113 def validate_ports(self):
Adam Gandelmanc78c7572014-08-28 18:38:55 -0700114 for port in self.get_ports(self.node['uuid']):
115 n_port_id = port['extra']['vif_port_id']
David Kranz34e88122014-12-11 15:24:05 -0500116 body = self.network_client.show_port(n_port_id)
Adam Gandelmanc78c7572014-08-28 18:38:55 -0700117 n_port = body['port']
118 self.assertEqual(n_port['device_id'], self.instance['id'])
119 self.assertEqual(n_port['mac_address'], port['address'])
Adam Gandelman4a48a602014-03-20 18:23:18 -0700120
Chris Hoge7579c1a2015-02-26 14:12:15 -0800121 @test.idempotent_id('549173a5-38ec-42bb-b0e2-c8b9f4a08943')
Adam Gandelman4a48a602014-03-20 18:23:18 -0700122 @test.services('baremetal', 'compute', 'image', 'network')
123 def test_baremetal_server_ops(self):
David Shrewsbury02719362014-05-20 14:10:03 -0400124 test_filename = '/mnt/rebuild_test.txt'
Adam Gandelman4a48a602014-03-20 18:23:18 -0700125 self.add_keypair()
126 self.boot_instance()
Adam Gandelman4a48a602014-03-20 18:23:18 -0700127 self.validate_ports()
128 self.verify_connectivity()
129 floating_ip = self.add_floating_ip()
130 self.verify_connectivity(ip=floating_ip)
David Shrewsbury02719362014-05-20 14:10:03 -0400131
132 vm_client = self.get_remote_client(self.instance)
133
134 # We expect the ephemeral partition to be mounted on /mnt and to have
135 # the same size as our flavor definition.
136 eph_size = self.get_flavor_ephemeral_size()
Jim Rollenhagena170b532014-09-11 08:33:39 -0700137 if eph_size > 0:
138 preserve_ephemeral = True
David Shrewsbury02719362014-05-20 14:10:03 -0400139
Jim Rollenhagena170b532014-09-11 08:33:39 -0700140 self.verify_partition(vm_client, 'ephemeral0', '/mnt', eph_size)
141 # Create the test file
142 self.create_remote_file(vm_client, test_filename)
143 else:
144 preserve_ephemeral = False
David Shrewsbury02719362014-05-20 14:10:03 -0400145
Jim Rollenhagena170b532014-09-11 08:33:39 -0700146 # Rebuild and preserve the ephemeral partition if it exists
147 self.rebuild_instance(preserve_ephemeral)
David Shrewsbury02719362014-05-20 14:10:03 -0400148 self.verify_connectivity()
149
150 # Check that we maintained our data
Jim Rollenhagena170b532014-09-11 08:33:39 -0700151 if eph_size > 0:
152 vm_client = self.get_remote_client(self.instance)
153 self.verify_partition(vm_client, 'ephemeral0', '/mnt', eph_size)
154 vm_client.exec_command('ls ' + test_filename)
David Shrewsbury02719362014-05-20 14:10:03 -0400155
Adam Gandelman4a48a602014-03-20 18:23:18 -0700156 self.terminate_instance()