~hopem/charms/trusty/ceph/lp1517846

« back to all changes in this revision

Viewing changes to tests/basic_deployment.py

  • Committer: Corey Bryant
  • Date: 2015-07-02 14:38:21 UTC
  • mfrom: (106.1.18 ceph)
  • Revision ID: corey.bryant@canonical.com-20150702143821-uiyoiz1o5quxf94u
[beisner,r=corey.bryant] Amulet test updates.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/usr/bin/python
2
2
 
3
3
import amulet
 
4
import time
4
5
from charmhelpers.contrib.openstack.amulet.deployment import (
5
6
    OpenStackAmuletDeployment
6
7
)
7
8
from charmhelpers.contrib.openstack.amulet.utils import (  # noqa
8
9
    OpenStackAmuletUtils,
9
10
    DEBUG,
10
 
    ERROR
 
11
    # ERROR
11
12
)
12
13
 
13
14
# Use DEBUG to turn on debug logging
35
36
           compatible with the local charm (e.g. stable or next).
36
37
           """
37
38
        this_service = {'name': 'ceph', 'units': 3}
38
 
        other_services = [{'name': 'mysql'}, {'name': 'keystone'},
 
39
        other_services = [{'name': 'mysql'},
 
40
                          {'name': 'keystone'},
39
41
                          {'name': 'rabbitmq-server'},
40
42
                          {'name': 'nova-compute'},
41
 
                          {'name': 'glance'}, {'name': 'cinder'}]
 
43
                          {'name': 'glance'},
 
44
                          {'name': 'cinder'}]
42
45
        super(CephBasicDeployment, self)._add_services(this_service,
43
46
                                                       other_services)
44
47
 
74
77
            'fsid': '6547bd3e-1397-11e2-82e5-53567c8d32dc',
75
78
            'monitor-secret': 'AQCXrnZQwI7KGBAAiPofmKEXKxu5bUzoYLVkbQ==',
76
79
            'osd-reformat': 'yes',
77
 
            'ephemeral-unmount': '/mnt'
 
80
            'ephemeral-unmount': '/mnt',
 
81
            'osd-devices': '/dev/vdb /srv/ceph'
78
82
        }
79
 
        if self._get_openstack_release() >= self.precise_grizzly:
80
 
            ceph_config['osd-devices'] = '/dev/vdb /srv/ceph'
81
 
        else:
82
 
            ceph_config['osd-devices'] = '/dev/vdb'
83
83
 
84
84
        configs = {'keystone': keystone_config,
85
85
                   'mysql': mysql_config,
93
93
        self.mysql_sentry = self.d.sentry.unit['mysql/0']
94
94
        self.keystone_sentry = self.d.sentry.unit['keystone/0']
95
95
        self.rabbitmq_sentry = self.d.sentry.unit['rabbitmq-server/0']
96
 
        self.nova_compute_sentry = self.d.sentry.unit['nova-compute/0']
 
96
        self.nova_sentry = self.d.sentry.unit['nova-compute/0']
97
97
        self.glance_sentry = self.d.sentry.unit['glance/0']
98
98
        self.cinder_sentry = self.d.sentry.unit['cinder/0']
99
99
        self.ceph0_sentry = self.d.sentry.unit['ceph/0']
100
100
        self.ceph1_sentry = self.d.sentry.unit['ceph/1']
101
101
        self.ceph2_sentry = self.d.sentry.unit['ceph/2']
 
102
        u.log.debug('openstack release val: {}'.format(
 
103
            self._get_openstack_release()))
 
104
        u.log.debug('openstack release str: {}'.format(
 
105
            self._get_openstack_release_string()))
 
106
 
 
107
        # Let things settle a bit original moving forward
 
108
        time.sleep(30)
102
109
 
103
110
        # Authenticate admin with keystone
104
111
        self.keystone = u.authenticate_keystone_admin(self.keystone_sentry,
105
112
                                                      user='admin',
106
113
                                                      password='openstack',
107
114
                                                      tenant='admin')
108
 
 
 
115
        # Authenticate admin with cinder endpoint
 
116
        self.cinder = u.authenticate_cinder_admin(self.keystone_sentry,
 
117
                                                  username='admin',
 
118
                                                  password='openstack',
 
119
                                                  tenant='admin')
109
120
        # Authenticate admin with glance endpoint
110
121
        self.glance = u.authenticate_glance_admin(self.keystone)
111
122
 
 
123
        # Authenticate admin with nova endpoint
 
124
        self.nova = u.authenticate_nova_user(self.keystone,
 
125
                                             user='admin',
 
126
                                             password='openstack',
 
127
                                             tenant='admin')
 
128
 
112
129
        # Create a demo tenant/role/user
113
130
        self.demo_tenant = 'demoTenant'
114
131
        self.demo_role = 'demoRole'
135
152
                                                  'password',
136
153
                                                  self.demo_tenant)
137
154
 
138
 
    def _ceph_osd_id(self, index):
139
 
        """Produce a shell command that will return a ceph-osd id."""
140
 
        return "`initctl list | grep 'ceph-osd ' | awk 'NR=={} {{ print $2 }}' | grep -o '[0-9]*'`".format(index + 1)  # noqa
141
 
 
142
 
    def test_services(self):
 
155
    def test_100_ceph_processes(self):
 
156
        """Verify that the expected service processes are running
 
157
        on each ceph unit."""
 
158
 
 
159
        # Process name and quantity of processes to expect on each unit
 
160
        ceph_processes = {
 
161
            'ceph-mon': 1,
 
162
            'ceph-osd': 2
 
163
        }
 
164
 
 
165
        # Units with process names and PID quantities expected
 
166
        expected_processes = {
 
167
            self.ceph0_sentry: ceph_processes,
 
168
            self.ceph1_sentry: ceph_processes,
 
169
            self.ceph2_sentry: ceph_processes
 
170
        }
 
171
 
 
172
        actual_pids = u.get_unit_process_ids(expected_processes)
 
173
        ret = u.validate_unit_process_ids(expected_processes, actual_pids)
 
174
        if ret:
 
175
            amulet.raise_status(amulet.FAIL, msg=ret)
 
176
 
 
177
    def test_102_services(self):
143
178
        """Verify the expected services are running on the service units."""
144
 
        ceph_services = ['status ceph-mon-all',
145
 
                         'status ceph-mon id=`hostname`']
146
 
        commands = {
147
 
            self.mysql_sentry: ['status mysql'],
148
 
            self.rabbitmq_sentry: ['sudo service rabbitmq-server status'],
149
 
            self.nova_compute_sentry: ['status nova-compute'],
150
 
            self.keystone_sentry: ['status keystone'],
151
 
            self.glance_sentry: ['status glance-registry',
152
 
                                 'status glance-api'],
153
 
            self.cinder_sentry: ['status cinder-api',
154
 
                                 'status cinder-scheduler',
155
 
                                 'status cinder-volume']
 
179
 
 
180
        services = {
 
181
            self.mysql_sentry: ['mysql'],
 
182
            self.rabbitmq_sentry: ['rabbitmq-server'],
 
183
            self.nova_sentry: ['nova-compute'],
 
184
            self.keystone_sentry: ['keystone'],
 
185
            self.glance_sentry: ['glance-registry',
 
186
                                 'glance-api'],
 
187
            self.cinder_sentry: ['cinder-api',
 
188
                                 'cinder-scheduler',
 
189
                                 'cinder-volume'],
156
190
        }
157
 
        if self._get_openstack_release() >= self.precise_grizzly:
158
 
            ceph_osd0 = 'status ceph-osd id={}'.format(self._ceph_osd_id(0))
159
 
            ceph_osd1 = 'status ceph-osd id={}'.format(self._ceph_osd_id(1))
160
 
            ceph_services.extend([ceph_osd0, ceph_osd1, 'status ceph-osd-all'])
161
 
            commands[self.ceph0_sentry] = ceph_services
162
 
            commands[self.ceph1_sentry] = ceph_services
163
 
            commands[self.ceph2_sentry] = ceph_services
164
 
        else:
165
 
            ceph_osd0 = 'status ceph-osd id={}'.format(self._ceph_osd_id(0))
166
 
            ceph_services.append(ceph_osd0)
167
 
            commands[self.ceph0_sentry] = ceph_services
168
 
            commands[self.ceph1_sentry] = ceph_services
169
 
            commands[self.ceph2_sentry] = ceph_services
170
 
 
171
 
        ret = u.validate_services(commands)
 
191
 
 
192
        if self._get_openstack_release() < self.vivid_kilo:
 
193
            # For upstart systems only.  Ceph services under systemd
 
194
            # are checked by process name instead.
 
195
            ceph_services = [
 
196
                'ceph-mon-all',
 
197
                'ceph-mon id=`hostname`',
 
198
                'ceph-osd-all',
 
199
                'ceph-osd id={}'.format(u.get_ceph_osd_id_cmd(0)),
 
200
                'ceph-osd id={}'.format(u.get_ceph_osd_id_cmd(1))
 
201
            ]
 
202
            services[self.ceph0_sentry] = ceph_services
 
203
            services[self.ceph1_sentry] = ceph_services
 
204
            services[self.ceph2_sentry] = ceph_services
 
205
 
 
206
        ret = u.validate_services_by_name(services)
172
207
        if ret:
173
208
            amulet.raise_status(amulet.FAIL, msg=ret)
174
209
 
175
 
    def test_ceph_nova_client_relation(self):
 
210
    def test_200_ceph_nova_client_relation(self):
176
211
        """Verify the ceph to nova ceph-client relation data."""
 
212
        u.log.debug('Checking ceph:nova-compute ceph relation data...')
177
213
        unit = self.ceph0_sentry
178
214
        relation = ['client', 'nova-compute:ceph']
179
215
        expected = {
187
223
            message = u.relation_error('ceph to nova ceph-client', ret)
188
224
            amulet.raise_status(amulet.FAIL, msg=message)
189
225
 
190
 
    def test_nova_ceph_client_relation(self):
191
 
        """Verify the nova to ceph ceph-client relation data."""
192
 
        unit = self.nova_compute_sentry
 
226
    def test_201_nova_ceph_client_relation(self):
 
227
        """Verify the nova to ceph client relation data."""
 
228
        u.log.debug('Checking nova-compute:ceph ceph-client relation data...')
 
229
        unit = self.nova_sentry
193
230
        relation = ['ceph', 'ceph:client']
194
231
        expected = {
195
232
            'private-address': u.valid_ip
200
237
            message = u.relation_error('nova to ceph ceph-client', ret)
201
238
            amulet.raise_status(amulet.FAIL, msg=message)
202
239
 
203
 
    def test_ceph_glance_client_relation(self):
 
240
    def test_202_ceph_glance_client_relation(self):
204
241
        """Verify the ceph to glance ceph-client relation data."""
 
242
        u.log.debug('Checking ceph:glance client relation data...')
205
243
        unit = self.ceph1_sentry
206
244
        relation = ['client', 'glance:ceph']
207
245
        expected = {
215
253
            message = u.relation_error('ceph to glance ceph-client', ret)
216
254
            amulet.raise_status(amulet.FAIL, msg=message)
217
255
 
218
 
    def test_glance_ceph_client_relation(self):
219
 
        """Verify the glance to ceph ceph-client relation data."""
 
256
    def test_203_glance_ceph_client_relation(self):
 
257
        """Verify the glance to ceph client relation data."""
 
258
        u.log.debug('Checking glance:ceph client relation data...')
220
259
        unit = self.glance_sentry
221
260
        relation = ['ceph', 'ceph:client']
222
261
        expected = {
228
267
            message = u.relation_error('glance to ceph ceph-client', ret)
229
268
            amulet.raise_status(amulet.FAIL, msg=message)
230
269
 
231
 
    def test_ceph_cinder_client_relation(self):
 
270
    def test_204_ceph_cinder_client_relation(self):
232
271
        """Verify the ceph to cinder ceph-client relation data."""
 
272
        u.log.debug('Checking ceph:cinder ceph relation data...')
233
273
        unit = self.ceph2_sentry
234
274
        relation = ['client', 'cinder:ceph']
235
275
        expected = {
243
283
            message = u.relation_error('ceph to cinder ceph-client', ret)
244
284
            amulet.raise_status(amulet.FAIL, msg=message)
245
285
 
246
 
    def test_cinder_ceph_client_relation(self):
 
286
    def test_205_cinder_ceph_client_relation(self):
247
287
        """Verify the cinder to ceph ceph-client relation data."""
 
288
        u.log.debug('Checking cinder:ceph ceph relation data...')
248
289
        unit = self.cinder_sentry
249
290
        relation = ['ceph', 'ceph:client']
250
291
        expected = {
256
297
            message = u.relation_error('cinder to ceph ceph-client', ret)
257
298
            amulet.raise_status(amulet.FAIL, msg=message)
258
299
 
259
 
    def test_ceph_config(self):
 
300
    def test_300_ceph_config(self):
260
301
        """Verify the data in the ceph config file."""
 
302
        u.log.debug('Checking ceph config file data...')
261
303
        unit = self.ceph0_sentry
262
304
        conf = '/etc/ceph/ceph.conf'
263
305
        expected = {
267
309
                'log to syslog': 'false',
268
310
                'err to syslog': 'false',
269
311
                'clog to syslog': 'false',
270
 
                'mon cluster log to syslog': 'false'
 
312
                'mon cluster log to syslog': 'false',
 
313
                'auth cluster required': 'none',
 
314
                'auth service required': 'none',
 
315
                'auth client required': 'none'
271
316
            },
272
317
            'mon': {
273
318
                'keyring': '/var/lib/ceph/mon/$cluster-$id/keyring'
281
326
                'filestore xattr use omap': 'true'
282
327
            },
283
328
        }
284
 
        if self._get_openstack_release() >= self.precise_grizzly:
285
 
            expected['global']['auth cluster required'] = 'none'
286
 
            expected['global']['auth service required'] = 'none'
287
 
            expected['global']['auth client required'] = 'none'
288
 
        else:
289
 
            expected['global']['auth supported'] = 'none'
290
329
 
291
330
        for section, pairs in expected.iteritems():
292
331
            ret = u.validate_config_data(unit, conf, section, pairs)
294
333
                message = "ceph config error: {}".format(ret)
295
334
                amulet.raise_status(amulet.FAIL, msg=message)
296
335
 
297
 
    def test_restart_on_config_change(self):
298
 
        """Verify the specified services are restarted on config change."""
299
 
        # NOTE(coreycb): Test not implemented but should it be? ceph services
300
 
        #                aren't restarted by charm after config change.  Should
301
 
        #                they be restarted?
302
 
        if self._get_openstack_release() >= self.precise_essex:
303
 
            u.log.error("Test not implemented")
304
 
            return
 
336
    def test_302_cinder_rbd_config(self):
 
337
        """Verify the cinder config file data regarding ceph."""
 
338
        u.log.debug('Checking cinder (rbd) config file data...')
 
339
        unit = self.cinder_sentry
 
340
        conf = '/etc/cinder/cinder.conf'
 
341
        expected = {
 
342
            'DEFAULT': {
 
343
                'volume_driver': 'cinder.volume.drivers.rbd.RBDDriver'
 
344
            }
 
345
        }
 
346
        for section, pairs in expected.iteritems():
 
347
            ret = u.validate_config_data(unit, conf, section, pairs)
 
348
            if ret:
 
349
                message = "cinder (rbd) config error: {}".format(ret)
 
350
                amulet.raise_status(amulet.FAIL, msg=message)
 
351
 
 
352
    def test_304_glance_rbd_config(self):
 
353
        """Verify the glance config file data regarding ceph."""
 
354
        u.log.debug('Checking glance (rbd) config file data...')
 
355
        unit = self.glance_sentry
 
356
        conf = '/etc/glance/glance-api.conf'
 
357
        config = {
 
358
            'default_store': 'rbd',
 
359
            'rbd_store_ceph_conf': '/etc/ceph/ceph.conf',
 
360
            'rbd_store_user': 'glance',
 
361
            'rbd_store_pool': 'glance',
 
362
            'rbd_store_chunk_size': '8'
 
363
        }
 
364
 
 
365
        if self._get_openstack_release() >= self.trusty_kilo:
 
366
            # Kilo or later
 
367
            config['stores'] = ('glance.store.filesystem.Store,'
 
368
                                'glance.store.http.Store,'
 
369
                                'glance.store.rbd.Store')
 
370
            section = 'glance_store'
 
371
        else:
 
372
            # Juno or earlier
 
373
            section = 'DEFAULT'
 
374
 
 
375
        expected = {section: config}
 
376
        for section, pairs in expected.iteritems():
 
377
            ret = u.validate_config_data(unit, conf, section, pairs)
 
378
            if ret:
 
379
                message = "glance (rbd) config error: {}".format(ret)
 
380
                amulet.raise_status(amulet.FAIL, msg=message)
 
381
 
 
382
    def test_306_nova_rbd_config(self):
 
383
        """Verify the nova config file data regarding ceph."""
 
384
        u.log.debug('Checking nova (rbd) config file data...')
 
385
        unit = self.nova_sentry
 
386
        conf = '/etc/nova/nova.conf'
 
387
        expected = {
 
388
            'libvirt': {
 
389
                'rbd_pool': 'nova',
 
390
                'rbd_user': 'nova-compute',
 
391
                'rbd_secret_uuid': u.not_null
 
392
            }
 
393
        }
 
394
        for section, pairs in expected.iteritems():
 
395
            ret = u.validate_config_data(unit, conf, section, pairs)
 
396
            if ret:
 
397
                message = "nova (rbd) config error: {}".format(ret)
 
398
                amulet.raise_status(amulet.FAIL, msg=message)
 
399
 
 
400
    def test_400_ceph_check_osd_pools(self):
 
401
        """Check osd pools on all ceph units, expect them to be
 
402
        identical, and expect specific pools to be present."""
 
403
        u.log.debug('Checking pools on ceph units...')
 
404
 
 
405
        expected_pools = self.get_ceph_expected_pools()
 
406
        results = []
 
407
        sentries = [
 
408
            self.ceph0_sentry,
 
409
            self.ceph1_sentry,
 
410
            self.ceph2_sentry
 
411
        ]
 
412
 
 
413
        # Check for presence of expected pools on each unit
 
414
        u.log.debug('Expected pools: {}'.format(expected_pools))
 
415
        for sentry_unit in sentries:
 
416
            pools = u.get_ceph_pools(sentry_unit)
 
417
            results.append(pools)
 
418
 
 
419
            for expected_pool in expected_pools:
 
420
                if expected_pool not in pools:
 
421
                    msg = ('{} does not have pool: '
 
422
                           '{}'.format(sentry_unit.info['unit_name'],
 
423
                                       expected_pool))
 
424
                    amulet.raise_status(amulet.FAIL, msg=msg)
 
425
            u.log.debug('{} has (at least) the expected '
 
426
                        'pools.'.format(sentry_unit.info['unit_name']))
 
427
 
 
428
        # Check that all units returned the same pool name:id data
 
429
        ret = u.validate_list_of_identical_dicts(results)
 
430
        if ret:
 
431
            u.log.debug('Pool list results: {}'.format(results))
 
432
            msg = ('{}; Pool list results are not identical on all '
 
433
                   'ceph units.'.format(ret))
 
434
            amulet.raise_status(amulet.FAIL, msg=msg)
 
435
        else:
 
436
            u.log.debug('Pool list on all ceph units produced the '
 
437
                        'same results (OK).')
 
438
 
 
439
    def test_410_ceph_cinder_vol_create(self):
 
440
        """Create and confirm a ceph-backed cinder volume, and inspect
 
441
        ceph cinder pool object count as the volume is created
 
442
        and deleted."""
 
443
        sentry_unit = self.ceph0_sentry
 
444
        obj_count_samples = []
 
445
        pool_size_samples = []
 
446
        pools = u.get_ceph_pools(self.ceph0_sentry)
 
447
        cinder_pool = pools['cinder']
 
448
 
 
449
        # Check ceph cinder pool object count, disk space usage and pool name
 
450
        u.log.debug('Checking ceph cinder pool original samples...')
 
451
        pool_name, obj_count, kb_used = u.get_ceph_pool_sample(sentry_unit,
 
452
                                                               cinder_pool)
 
453
        obj_count_samples.append(obj_count)
 
454
        pool_size_samples.append(kb_used)
 
455
 
 
456
        expected = 'cinder'
 
457
        if pool_name != expected:
 
458
            msg = ('Ceph pool {} unexpected name (actual, expected): '
 
459
                   '{}. {}'.format(cinder_pool, pool_name, expected))
 
460
            amulet.raise_status(amulet.FAIL, msg=msg)
 
461
 
 
462
        # Create ceph-backed cinder volume
 
463
        cinder_vol = u.create_cinder_volume(self.cinder)
 
464
 
 
465
        # Re-check ceph cinder pool object count and disk usage
 
466
        time.sleep(10)
 
467
        u.log.debug('Checking ceph cinder pool samples after volume create...')
 
468
        pool_name, obj_count, kb_used = u.get_ceph_pool_sample(sentry_unit,
 
469
                                                               cinder_pool)
 
470
        obj_count_samples.append(obj_count)
 
471
        pool_size_samples.append(kb_used)
 
472
 
 
473
        # Delete ceph-backed cinder volume
 
474
        u.delete_resource(self.cinder.volumes, cinder_vol, msg="cinder volume")
 
475
 
 
476
        # Final check, ceph cinder pool object count and disk usage
 
477
        time.sleep(10)
 
478
        u.log.debug('Checking ceph cinder pool after volume delete...')
 
479
        pool_name, obj_count, kb_used = u.get_ceph_pool_sample(sentry_unit,
 
480
                                                               cinder_pool)
 
481
        obj_count_samples.append(obj_count)
 
482
        pool_size_samples.append(kb_used)
 
483
 
 
484
        # Validate ceph cinder pool object count samples over time
 
485
        ret = u.validate_ceph_pool_samples(obj_count_samples,
 
486
                                           "cinder pool object count")
 
487
        if ret:
 
488
            amulet.raise_status(amulet.FAIL, msg=ret)
 
489
 
 
490
        # Validate ceph cinder pool disk space usage samples over time
 
491
        ret = u.validate_ceph_pool_samples(pool_size_samples,
 
492
                                           "cinder pool disk usage")
 
493
        if ret:
 
494
            amulet.raise_status(amulet.FAIL, msg=ret)
 
495
 
 
496
    def test_412_ceph_glance_image_create_delete(self):
 
497
        """Create and confirm a ceph-backed glance image, and inspect
 
498
        ceph glance pool object count as the image is created
 
499
        and deleted."""
 
500
        sentry_unit = self.ceph0_sentry
 
501
        obj_count_samples = []
 
502
        pool_size_samples = []
 
503
        pools = u.get_ceph_pools(self.ceph0_sentry)
 
504
        glance_pool = pools['glance']
 
505
 
 
506
        # Check ceph glance pool object count, disk space usage and pool name
 
507
        u.log.debug('Checking ceph glance pool original samples...')
 
508
        pool_name, obj_count, kb_used = u.get_ceph_pool_sample(sentry_unit,
 
509
                                                               glance_pool)
 
510
        obj_count_samples.append(obj_count)
 
511
        pool_size_samples.append(kb_used)
 
512
 
 
513
        expected = 'glance'
 
514
        if pool_name != expected:
 
515
            msg = ('Ceph glance pool {} unexpected name (actual, '
 
516
                   'expected): {}. {}'.format(glance_pool,
 
517
                                              pool_name, expected))
 
518
            amulet.raise_status(amulet.FAIL, msg=msg)
 
519
 
 
520
        # Create ceph-backed glance image
 
521
        glance_img = u.create_cirros_image(self.glance, "cirros-image-1")
 
522
 
 
523
        # Re-check ceph glance pool object count and disk usage
 
524
        time.sleep(10)
 
525
        u.log.debug('Checking ceph glance pool samples after image create...')
 
526
        pool_name, obj_count, kb_used = u.get_ceph_pool_sample(sentry_unit,
 
527
                                                               glance_pool)
 
528
        obj_count_samples.append(obj_count)
 
529
        pool_size_samples.append(kb_used)
 
530
 
 
531
        # Delete ceph-backed glance image
 
532
        u.delete_resource(self.glance.images,
 
533
                          glance_img, msg="glance image")
 
534
 
 
535
        # Final check, ceph glance pool object count and disk usage
 
536
        time.sleep(10)
 
537
        u.log.debug('Checking ceph glance pool samples after image delete...')
 
538
        pool_name, obj_count, kb_used = u.get_ceph_pool_sample(sentry_unit,
 
539
                                                               glance_pool)
 
540
        obj_count_samples.append(obj_count)
 
541
        pool_size_samples.append(kb_used)
 
542
 
 
543
        # Validate ceph glance pool object count samples over time
 
544
        ret = u.validate_ceph_pool_samples(obj_count_samples,
 
545
                                           "glance pool object count")
 
546
        if ret:
 
547
            amulet.raise_status(amulet.FAIL, msg=ret)
 
548
 
 
549
        # Validate ceph glance pool disk space usage samples over time
 
550
        ret = u.validate_ceph_pool_samples(pool_size_samples,
 
551
                                           "glance pool disk usage")
 
552
        if ret:
 
553
            amulet.raise_status(amulet.FAIL, msg=ret)
 
554
 
 
555
    def test_499_ceph_cmds_exit_zero(self):
 
556
        """Check basic functionality of ceph cli commands against
 
557
        all ceph units."""
 
558
        sentry_units = [
 
559
            self.ceph0_sentry,
 
560
            self.ceph1_sentry,
 
561
            self.ceph2_sentry
 
562
        ]
 
563
        commands = [
 
564
            'sudo ceph health',
 
565
            'sudo ceph mds stat',
 
566
            'sudo ceph pg stat',
 
567
            'sudo ceph osd stat',
 
568
            'sudo ceph mon stat',
 
569
        ]
 
570
        ret = u.check_commands_on_units(commands, sentry_units)
 
571
        if ret:
 
572
            amulet.raise_status(amulet.FAIL, msg=ret)
 
573
 
 
574
    # FYI: No restart check as ceph services do not restart
 
575
    # when charm config changes, unless monitor count increases.