1
- # Copyright 2024 Canonical Ltd.
1
+ # Copyright 2020 Canonical Ltd.
2
2
#
3
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
4
# you may not use this file except in compliance with the License.
15
15
"""Encapsulate CephFS testing."""
16
16
17
17
import logging
18
- import json
19
- import subprocess
20
18
import tenacity
21
- from tenacity import retry , Retrying , stop_after_attempt , wait_exponential
22
- import unittest
23
- import zaza
24
- import zaza .openstack .utilities .ceph as zaza_ceph
19
+ from tenacity import Retrying , stop_after_attempt , wait_exponential
20
+
25
21
import zaza .model as model
22
+ import zaza .openstack .charm_tests .neutron .tests as neutron_tests
23
+ import zaza .openstack .charm_tests .nova .utils as nova_utils
26
24
import zaza .openstack .charm_tests .test_utils as test_utils
27
- import zaza .openstack .utilities .openstack as zaza_openstack
25
+ import zaza .openstack .configure .guest as guest
26
+ import zaza .openstack .utilities .ceph as zaza_ceph
27
+ import zaza .openstack .utilities .openstack as openstack_utils
28
28
29
29
30
- class CephFSTests (unittest . TestCase ):
30
+ class CephFSTests (test_utils . OpenStackBaseTest ):
31
31
"""Encapsulate CephFS tests."""
32
32
33
- mounts_share = False
34
- mount_dir = '/mnt/cephfs'
35
- CEPH_MON = 'ceph-mon'
36
-
37
- def tearDown (self ):
38
- """Cleanup after running tests."""
39
- if self .mounts_share :
40
- for unit in ['ubuntu/0' , 'ubuntu/1' ]:
41
- try :
42
- zaza .utilities .generic .run_via_ssh (
43
- unit_name = unit ,
44
- cmd = 'sudo fusermount -u {0} && sudo rmdir {0}' .format (
45
- self .mount_dir ))
46
- except subprocess .CalledProcessError :
47
- logging .warning (
48
- "Failed to cleanup mounts on {}" .format (unit ))
49
-
50
- def _mount_share (self , unit_name : str ,
51
- retry : bool = True ):
52
- self ._install_dependencies (unit_name )
53
- self ._install_keyring (unit_name )
54
- ssh_cmd = (
55
- 'sudo mkdir -p {0} && '
56
- 'sudo ceph-fuse {0}' .format (self .mount_dir )
57
- )
58
- if retry :
59
- for attempt in Retrying (
60
- stop = stop_after_attempt (5 ),
61
- wait = wait_exponential (multiplier = 3 ,
62
- min = 2 , max = 10 )):
63
- with attempt :
64
- zaza .utilities .generic .run_via_ssh (
65
- unit_name = unit_name ,
66
- cmd = ssh_cmd )
67
- else :
68
- zaza .utilities .generic .run_via_ssh (
69
- unit_name = unit_name ,
70
- cmd = ssh_cmd )
71
- self .mounts_share = True
72
-
73
- def _install_keyring (self , unit_name : str ):
74
-
75
- keyring = model .run_on_leader (
76
- self .CEPH_MON , 'cat /etc/ceph/ceph.client.admin.keyring' )['Stdout' ]
77
- config = model .run_on_leader (
78
- self .CEPH_MON , 'cat /etc/ceph/ceph.conf' )['Stdout' ]
79
- commands = [
80
- 'sudo mkdir -p /etc/ceph' ,
81
- "echo '{}' | sudo tee /etc/ceph/ceph.conf" .format (config ),
82
- "echo '{}' | "
83
- 'sudo tee /etc/ceph/ceph.client.admin.keyring' .format (keyring )
84
- ]
85
- for cmd in commands :
86
- zaza .utilities .generic .run_via_ssh (
87
- unit_name = unit_name ,
88
- cmd = cmd )
89
-
90
- def _install_dependencies (self , unit : str ):
91
- zaza .utilities .generic .run_via_ssh (
92
- unit_name = unit ,
93
- cmd = 'sudo apt-get install -yq ceph-fuse' )
33
+ RESOURCE_PREFIX = 'zaza-cephfstests'
34
+ INSTANCE_USERDATA = """#cloud-config
35
+ packages:
36
+ - ceph-fuse
37
+ - python
38
+ mounts:
39
+ - [ 'none', '/mnt/cephfs', 'fuse.ceph', 'ceph.id=admin,ceph.conf=/etc/ceph/ceph.conf,_netdev,defaults', '0', '0' ]
40
+ write_files:
41
+ - content: |
42
+ {}
43
+ path: /etc/ceph/ceph.conf
44
+ - content: |
45
+ {}
46
+ path: /etc/ceph/ceph.client.admin.keyring
47
+ """ # noqa
94
48
95
49
@classmethod
96
50
def setUpClass (cls ):
97
51
"""Run class setup for running tests."""
98
52
super (CephFSTests , cls ).setUpClass ()
99
53
100
- @retry (
101
- stop = stop_after_attempt (5 ),
102
- wait = wait_exponential (multiplier = 3 , min = 2 , max = 10 ))
103
- def _write_testing_file_on_instance (self , instance_name : str ):
104
- zaza .utilities .generic .run_via_ssh (
105
- unit_name = instance_name ,
106
- cmd = 'echo -n "test" | sudo tee {}/test' .format (self .mount_dir ))
107
-
108
- @retry (
109
- stop = stop_after_attempt (5 ),
110
- wait = wait_exponential (multiplier = 3 , min = 2 , max = 10 ))
111
- def _verify_testing_file_on_instance (self , instance_name : str ):
112
- output = zaza .model .run_on_unit (
113
- instance_name , 'sudo cat {}/test' .format (self .mount_dir ))['Stdout' ]
114
- self .assertEqual ('test' , output .strip ())
115
-
116
54
def test_cephfs_share (self ):
117
55
"""Test that CephFS shares can be accessed on two instances.
118
56
@@ -122,70 +60,50 @@ def test_cephfs_share(self):
122
60
4. read it on the other
123
61
5. profit
124
62
"""
125
- self ._mount_share ('ubuntu/0' )
126
- self ._mount_share ('ubuntu/1' )
127
-
128
- self ._write_testing_file_on_instance ('ubuntu/0' )
129
- self ._verify_testing_file_on_instance ('ubuntu/1' )
130
-
131
- def test_conf (self ):
132
- """Test ceph to ensure juju config options are properly set."""
133
- self .TESTED_UNIT = 'ceph-fs/0'
134
-
135
- def _get_conf ():
136
- """get/parse ceph daemon response into dict.
137
-
138
- :returns dict: Current configuration of the Ceph MDS daemon
139
- :rtype: dict
140
- """
141
- cmd = "sudo ceph daemon mds.$HOSTNAME config show"
142
- conf = model .run_on_unit (self .TESTED_UNIT , cmd )
143
- return json .loads (conf ['Stdout' ])
144
-
145
- @retry (wait = wait_exponential (multiplier = 1 , min = 4 , max = 10 ),
146
- stop = stop_after_attempt (10 ))
147
- def _change_conf_check (mds_config ):
148
- """Change configs, then assert to ensure config was set.
149
-
150
- Doesn't return a value.
151
- """
152
- model .set_application_config ('ceph-fs' , mds_config )
153
- results = _get_conf ()
154
- self .assertEqual (
155
- results ['mds_cache_memory_limit' ],
156
- mds_config ['mds-cache-memory-limit' ])
157
- self .assertAlmostEqual (
158
- float (results ['mds_cache_reservation' ]),
159
- float (mds_config ['mds-cache-reservation' ]))
160
- self .assertAlmostEqual (
161
- float (results ['mds_health_cache_threshold' ]),
162
- float (mds_config ['mds-health-cache-threshold' ]))
163
-
164
- # ensure defaults are set
165
- mds_config = {'mds-cache-memory-limit' : '4294967296' ,
166
- 'mds-cache-reservation' : '0.05' ,
167
- 'mds-health-cache-threshold' : '1.5' }
168
- _change_conf_check (mds_config )
169
-
170
- # change defaults
171
- mds_config = {'mds-cache-memory-limit' : '8589934592' ,
172
- 'mds-cache-reservation' : '0.10' ,
173
- 'mds-health-cache-threshold' : '2' }
174
- _change_conf_check (mds_config )
175
-
176
- # Restore config to keep tests idempotent
177
- mds_config = {'mds-cache-memory-limit' : '4294967296' ,
178
- 'mds-cache-reservation' : '0.05' ,
179
- 'mds-health-cache-threshold' : '1.5' }
180
- _change_conf_check (mds_config )
181
-
182
-
183
- class CephFSWithCephProxyTests (CephFSTests ):
184
- """Extend CephFSTests to use ceph-proxy instead of ceph-mon."""
185
-
186
- # when ceph-proxy is being used it will be the one acting as a ceph-mon
187
- # for the other charms holding the admin key and ceph.conf
188
- CEPH_MON = 'ceph-proxy'
63
+ keyring = model .run_on_leader (
64
+ 'ceph-mon' , 'cat /etc/ceph/ceph.client.admin.keyring' )['Stdout' ]
65
+ conf = model .run_on_leader (
66
+ 'ceph-mon' , 'cat /etc/ceph/ceph.conf' )['Stdout' ]
67
+ # Spawn Servers
68
+ instance_1 , instance_2 = self .launch_guests (
69
+ userdata = self .INSTANCE_USERDATA .format (
70
+ _indent (conf , 8 ),
71
+ _indent (keyring , 8 )))
72
+
73
+ # Write a file on instance_1
74
+ def verify_setup (stdin , stdout , stderr ):
75
+ status = stdout .channel .recv_exit_status ()
76
+ self .assertEqual (status , 0 )
77
+
78
+ fip_1 = neutron_tests .floating_ips_from_instance (instance_1 )[0 ]
79
+ fip_2 = neutron_tests .floating_ips_from_instance (instance_2 )[0 ]
80
+ username = guest .boot_tests ['bionic' ]['username' ]
81
+ password = guest .boot_tests ['bionic' ].get ('password' )
82
+ privkey = openstack_utils .get_private_key (nova_utils .KEYPAIR_NAME )
83
+
84
+ for attempt in Retrying (
85
+ stop = stop_after_attempt (3 ),
86
+ wait = wait_exponential (multiplier = 1 , min = 2 , max = 10 )):
87
+ with attempt :
88
+ openstack_utils .ssh_command (
89
+ username , fip_1 , 'instance-1' ,
90
+ 'sudo mount -a && '
91
+ 'echo "test" | sudo tee /mnt/cephfs/test' ,
92
+ password = password , privkey = privkey , verify = verify_setup )
93
+
94
+ def verify (stdin , stdout , stderr ):
95
+ status = stdout .channel .recv_exit_status ()
96
+ self .assertEqual (status , 0 )
97
+ out = ""
98
+ for line in iter (stdout .readline , "" ):
99
+ out += line
100
+ self .assertEqual (out , "test\n " )
101
+
102
+ openstack_utils .ssh_command (
103
+ username , fip_2 , 'instance-2' ,
104
+ 'sudo mount -a && '
105
+ 'sudo cat /mnt/cephfs/test' ,
106
+ password = password , privkey = privkey , verify = verify )
189
107
190
108
191
109
def _indent (text , amount , ch = ' ' ):
@@ -220,9 +138,9 @@ def setUpClass(cls):
220
138
model .get_application (release_application )
221
139
except KeyError :
222
140
release_application = 'ceph-mon'
223
- cls .current_release = zaza_openstack .get_os_release (
141
+ cls .current_release = openstack_utils .get_os_release (
224
142
application = release_application )
225
- cls .bionic_rocky = zaza_openstack .get_os_release ('bionic_rocky' )
143
+ cls .bionic_rocky = openstack_utils .get_os_release ('bionic_rocky' )
226
144
227
145
def setUp (self ):
228
146
"""Perform common per test initialization steps."""
@@ -254,12 +172,12 @@ def _assert_pools_properties(self, pools, pools_detail,
254
172
if pd ['pool_name' ] == pool :
255
173
if 'options' in expected_properties :
256
174
for k , v in expected_properties ['options' ].items ():
257
- self .assertEqual (pd ['options' ][k ], v )
175
+ self .assertEquals (pd ['options' ][k ], v )
258
176
log_func ("['options']['{}'] == {}" .format (k , v ))
259
177
for k , v in expected_properties .items ():
260
178
if k == 'options' :
261
179
continue
262
- self .assertEqual (pd [k ], v )
180
+ self .assertEquals (pd [k ], v )
263
181
log_func ("{} == {}" .format (k , v ))
264
182
265
183
def test_configure_compression (self ):
0 commit comments