1 # -*- coding: utf-8 -*-
2 from __future__
import absolute_import
7 from mock
import MagicMock
, Mock
9 from unittest
.mock
import MagicMock
, Mock
12 from . import KVStoreMockMixin
14 from ..settings
import Settings
15 from ..services
import ganesha
16 from ..services
.ganesha
import GaneshaConf
, Export
, GaneshaConfParser
19 class GaneshaConfTest(unittest
.TestCase
, KVStoreMockMixin
):
28 Attr_Expiration_Time = 0;
36 # Secret_Access_Key = "YOUR SECRET KEY HERE";
41 Clients = 192.168.0.10, 192.168.1.0/8;
47 Clients = 192.168.0.0/16;
65 squash = AllAnonymous;
69 Transports = TCP, UDP;
74 Access_Key_Id ="access_key";
75 Secret_Access_Key = "secret_key";
81 %url rados://ganesha/ns/export-2
83 %url "rados://ganesha/ns/export-1"'''
85 conf_nodeb
= '%url "rados://ganesha/ns/export-1"'
87 class RObject(object):
88 def __init__(self
, key
, raw
):
93 return self
.raw
.encode('utf-8')
96 return len(self
.raw
), None
98 def _ioctx_write_full_mock(self
, key
, content
):
99 if key
not in self
.temp_store
:
100 self
.temp_store
[key
] = GaneshaConfTest
.RObject(key
,
101 content
.decode('utf-8'))
103 self
.temp_store
[key
].raw
= content
.decode('utf-8')
105 def _ioctx_remove_mock(self
, key
):
106 del self
.temp_store
[key
]
108 def _ioctx_list_objects_mock(self
):
109 return [obj
for _
, obj
in self
.temp_store
.items()]
114 Settings
.GANESHA_CLUSTERS_RADOS_POOL_NAMESPACE
= "ganesha/ns"
117 'export-1': GaneshaConfTest
.RObject("export-1", self
.export_1
),
118 'conf-nodea': GaneshaConfTest
.RObject("conf-nodea", self
.conf_nodea
),
119 'export-2': GaneshaConfTest
.RObject("export-2", self
.export_2
),
120 'conf-nodeb': GaneshaConfTest
.RObject("conf-nodeb", self
.conf_nodeb
)
123 self
.io_mock
= MagicMock()
124 self
.io_mock
.list_objects
.side_effect
= self
._ioctx
_list
_objects
_mock
125 self
.io_mock
.write_full
.side_effect
= self
._ioctx
_write
_full
_mock
126 self
.io_mock
.remove_object
.side_effect
= self
._ioctx
_remove
_mock
128 ioctx_mock
= MagicMock()
129 ioctx_mock
.__enter
__ = Mock(return_value
=(self
.io_mock
))
130 ioctx_mock
.__exit
__ = Mock(return_value
=None)
132 mgr
.rados
= MagicMock()
133 mgr
.rados
.open_ioctx
.return_value
= ioctx_mock
135 # pylint: disable=protected-access
136 mgr
._select
_orchestrator
.side_effect
= orchestrator
.NoOrchestrator()
138 ganesha
.CephX
= MagicMock()
139 ganesha
.CephX
.list_clients
.return_value
= ['ganesha']
140 ganesha
.CephX
.get_client_key
.return_value
= 'ganesha'
142 ganesha
.CephFS
= MagicMock()
144 def test_export_parser_1(self
):
145 blocks
= GaneshaConfParser(self
.export_1
).parse()
146 self
.assertIsInstance(blocks
, list)
147 self
.assertEqual(len(blocks
), 1)
148 export
= Export
.from_export_block(blocks
[0], '_default_',
149 GaneshaConf
.ganesha_defaults({}))
151 self
.assertEqual(export
.export_id
, 1)
152 self
.assertEqual(export
.path
, "/")
153 self
.assertEqual(export
.pseudo
, "/cephfs_a")
154 self
.assertIsNone(export
.tag
)
155 self
.assertEqual(export
.access_type
, "RW")
156 self
.assertEqual(export
.squash
, "root_squash")
157 self
.assertEqual(export
.protocols
, {4}
)
158 self
.assertEqual(export
.transports
, {"TCP", "UDP"})
159 self
.assertEqual(export
.fsal
.name
, "CEPH")
160 self
.assertEqual(export
.fsal
.user_id
, "ganesha")
161 self
.assertEqual(export
.fsal
.fs_name
, "a")
162 self
.assertEqual(export
.fsal
.sec_label_xattr
, None)
163 self
.assertEqual(len(export
.clients
), 2)
164 self
.assertEqual(export
.clients
[0].addresses
,
165 ["192.168.0.10", "192.168.1.0/8"])
166 self
.assertEqual(export
.clients
[0].squash
, "no_root_squash")
167 self
.assertIsNone(export
.clients
[0].access_type
)
168 self
.assertEqual(export
.clients
[1].addresses
, ["192.168.0.0/16"])
169 self
.assertEqual(export
.clients
[1].squash
, "all_squash")
170 self
.assertEqual(export
.clients
[1].access_type
, "RO")
171 self
.assertEqual(export
.cluster_id
, '_default_')
172 self
.assertEqual(export
.attr_expiration_time
, 0)
173 self
.assertEqual(export
.security_label
, False)
175 def test_export_parser_2(self
):
176 blocks
= GaneshaConfParser(self
.export_2
).parse()
177 self
.assertIsInstance(blocks
, list)
178 self
.assertEqual(len(blocks
), 1)
179 export
= Export
.from_export_block(blocks
[0], '_default_',
180 GaneshaConf
.ganesha_defaults({}))
182 self
.assertEqual(export
.export_id
, 2)
183 self
.assertEqual(export
.path
, "/")
184 self
.assertEqual(export
.pseudo
, "/rgw")
185 self
.assertIsNone(export
.tag
)
186 self
.assertEqual(export
.access_type
, "RW")
187 self
.assertEqual(export
.squash
, "all_squash")
188 self
.assertEqual(export
.protocols
, {4, 3})
189 self
.assertEqual(export
.transports
, {"TCP", "UDP"})
190 self
.assertEqual(export
.fsal
.name
, "RGW")
191 self
.assertEqual(export
.fsal
.rgw_user_id
, "testuser")
192 self
.assertEqual(export
.fsal
.access_key
, "access_key")
193 self
.assertEqual(export
.fsal
.secret_key
, "secret_key")
194 self
.assertEqual(len(export
.clients
), 0)
195 self
.assertEqual(export
.cluster_id
, '_default_')
197 def test_daemon_conf_parser_a(self
):
198 blocks
= GaneshaConfParser(self
.conf_nodea
).parse()
199 self
.assertIsInstance(blocks
, list)
200 self
.assertEqual(len(blocks
), 2)
201 self
.assertEqual(blocks
[0]['block_name'], "%url")
202 self
.assertEqual(blocks
[0]['value'], "rados://ganesha/ns/export-2")
203 self
.assertEqual(blocks
[1]['block_name'], "%url")
204 self
.assertEqual(blocks
[1]['value'], "rados://ganesha/ns/export-1")
206 def test_daemon_conf_parser_b(self
):
207 blocks
= GaneshaConfParser(self
.conf_nodeb
).parse()
208 self
.assertIsInstance(blocks
, list)
209 self
.assertEqual(len(blocks
), 1)
210 self
.assertEqual(blocks
[0]['block_name'], "%url")
211 self
.assertEqual(blocks
[0]['value'], "rados://ganesha/ns/export-1")
213 def test_ganesha_conf(self
):
214 ganesha_conf
= GaneshaConf
.instance('_default_')
215 exports
= ganesha_conf
.exports
217 self
.assertEqual(len(exports
.items()), 2)
218 self
.assertIn(1, exports
)
219 self
.assertIn(2, exports
)
221 # export_id = 1 asserts
223 self
.assertEqual(export
.export_id
, 1)
224 self
.assertEqual(export
.path
, "/")
225 self
.assertEqual(export
.pseudo
, "/cephfs_a")
226 self
.assertIsNone(export
.tag
)
227 self
.assertEqual(export
.access_type
, "RW")
228 self
.assertEqual(export
.squash
, "root_squash")
229 self
.assertEqual(export
.protocols
, {4}
)
230 self
.assertEqual(export
.transports
, {"TCP", "UDP"})
231 self
.assertEqual(export
.fsal
.name
, "CEPH")
232 self
.assertEqual(export
.fsal
.user_id
, "ganesha")
233 self
.assertEqual(export
.fsal
.fs_name
, "a")
234 self
.assertEqual(export
.fsal
.sec_label_xattr
, None)
235 self
.assertEqual(len(export
.clients
), 2)
236 self
.assertEqual(export
.clients
[0].addresses
,
237 ["192.168.0.10", "192.168.1.0/8"])
238 self
.assertEqual(export
.clients
[0].squash
, "no_root_squash")
239 self
.assertIsNone(export
.clients
[0].access_type
)
240 self
.assertEqual(export
.clients
[1].addresses
, ["192.168.0.0/16"])
241 self
.assertEqual(export
.clients
[1].squash
, "all_squash")
242 self
.assertEqual(export
.clients
[1].access_type
, "RO")
243 self
.assertEqual(export
.attr_expiration_time
, 0)
244 self
.assertEqual(export
.security_label
, False)
246 # export_id = 2 asserts
248 self
.assertEqual(export
.export_id
, 2)
249 self
.assertEqual(export
.path
, "/")
250 self
.assertEqual(export
.pseudo
, "/rgw")
251 self
.assertIsNone(export
.tag
)
252 self
.assertEqual(export
.access_type
, "RW")
253 self
.assertEqual(export
.squash
, "all_squash")
254 self
.assertEqual(export
.protocols
, {4, 3})
255 self
.assertEqual(export
.transports
, {"TCP", "UDP"})
256 self
.assertEqual(export
.fsal
.name
, "RGW")
257 self
.assertEqual(export
.fsal
.rgw_user_id
, "testuser")
258 self
.assertEqual(export
.fsal
.access_key
, "access_key")
259 self
.assertEqual(export
.fsal
.secret_key
, "secret_key")
260 self
.assertEqual(len(export
.clients
), 0)
262 def test_config_dict(self
):
263 conf
= GaneshaConf
.instance('_default_')
264 export
= conf
.exports
[1]
265 ex_dict
= export
.to_dict()
266 self
.assertDictEqual(ex_dict
, {
267 'daemons': ['nodea', 'nodeb'],
270 'pseudo': '/cephfs_a',
271 'cluster_id': '_default_',
274 'squash': 'root_squash',
275 'security_label': False,
277 'transports': ['TCP', 'UDP'],
279 'addresses': ["192.168.0.10", "192.168.1.0/8"],
281 'squash': 'no_root_squash'
283 'addresses': ["192.168.0.0/16"],
285 'squash': 'all_squash'
289 'user_id': 'ganesha',
291 'sec_label_xattr': None
295 export
= conf
.exports
[2]
296 ex_dict
= export
.to_dict()
297 self
.assertDictEqual(ex_dict
, {
298 'daemons': ['nodea'],
302 'cluster_id': '_default_',
305 'squash': 'all_squash',
306 'security_label': False,
308 'transports': ['TCP', 'UDP'],
312 'rgw_user_id': 'testuser'
316 def test_config_from_dict(self
):
317 export
= Export
.from_dict(1, {
318 'daemons': ['nodea', 'nodeb'],
321 'cluster_id': '_default_',
322 'pseudo': '/cephfs_a',
325 'squash': 'root_squash',
326 'security_label': True,
328 'transports': ['TCP', 'UDP'],
330 'addresses': ["192.168.0.10", "192.168.1.0/8"],
332 'squash': 'no_root_squash'
334 'addresses': ["192.168.0.0/16"],
336 'squash': 'all_squash'
340 'user_id': 'ganesha',
342 'sec_label_xattr': 'security.selinux'
346 self
.assertEqual(export
.export_id
, 1)
347 self
.assertEqual(export
.path
, "/")
348 self
.assertEqual(export
.pseudo
, "/cephfs_a")
349 self
.assertIsNone(export
.tag
)
350 self
.assertEqual(export
.access_type
, "RW")
351 self
.assertEqual(export
.squash
, "root_squash")
352 self
.assertEqual(export
.protocols
, {4}
)
353 self
.assertEqual(export
.transports
, {"TCP", "UDP"})
354 self
.assertEqual(export
.fsal
.name
, "CEPH")
355 self
.assertEqual(export
.fsal
.user_id
, "ganesha")
356 self
.assertEqual(export
.fsal
.fs_name
, "a")
357 self
.assertEqual(export
.fsal
.sec_label_xattr
, 'security.selinux')
358 self
.assertEqual(len(export
.clients
), 2)
359 self
.assertEqual(export
.clients
[0].addresses
,
360 ["192.168.0.10", "192.168.1.0/8"])
361 self
.assertEqual(export
.clients
[0].squash
, "no_root_squash")
362 self
.assertIsNone(export
.clients
[0].access_type
)
363 self
.assertEqual(export
.clients
[1].addresses
, ["192.168.0.0/16"])
364 self
.assertEqual(export
.clients
[1].squash
, "all_squash")
365 self
.assertEqual(export
.clients
[1].access_type
, "RO")
366 self
.assertEqual(export
.daemons
, {"nodeb", "nodea"})
367 self
.assertEqual(export
.cluster_id
, '_default_')
368 self
.assertEqual(export
.attr_expiration_time
, 0)
369 self
.assertEqual(export
.security_label
, True)
371 export
= Export
.from_dict(2, {
372 'daemons': ['nodea'],
376 'cluster_id': '_default_',
379 'squash': 'all_squash',
380 'security_label': False,
382 'transports': ['TCP', 'UDP'],
386 'rgw_user_id': 'testuser'
390 self
.assertEqual(export
.export_id
, 2)
391 self
.assertEqual(export
.path
, "/")
392 self
.assertEqual(export
.pseudo
, "/rgw")
393 self
.assertIsNone(export
.tag
)
394 self
.assertEqual(export
.access_type
, "RW")
395 self
.assertEqual(export
.squash
, "all_squash")
396 self
.assertEqual(export
.protocols
, {4, 3})
397 self
.assertEqual(export
.transports
, {"TCP", "UDP"})
398 self
.assertEqual(export
.fsal
.name
, "RGW")
399 self
.assertEqual(export
.fsal
.rgw_user_id
, "testuser")
400 self
.assertIsNone(export
.fsal
.access_key
)
401 self
.assertIsNone(export
.fsal
.secret_key
)
402 self
.assertEqual(len(export
.clients
), 0)
403 self
.assertEqual(export
.daemons
, {"nodea"})
404 self
.assertEqual(export
.cluster_id
, '_default_')
406 def test_gen_raw_config(self
):
407 conf
= GaneshaConf
.instance('_default_')
408 # pylint: disable=W0212
409 export
= conf
.exports
[1]
411 conf
._save
_export
(export
)
412 conf
= GaneshaConf
.instance('_default_')
413 exports
= conf
.exports
414 self
.assertEqual(len(exports
.items()), 2)
415 self
.assertIn(1, exports
)
416 self
.assertIn(2, exports
)
418 # export_id = 1 asserts
420 self
.assertEqual(export
.export_id
, 1)
421 self
.assertEqual(export
.path
, "/")
422 self
.assertEqual(export
.pseudo
, "/cephfs_a")
423 self
.assertIsNone(export
.tag
)
424 self
.assertEqual(export
.access_type
, "RW")
425 self
.assertEqual(export
.squash
, "root_squash")
426 self
.assertEqual(export
.protocols
, {4}
)
427 self
.assertEqual(export
.transports
, {"TCP", "UDP"})
428 self
.assertEqual(export
.fsal
.name
, "CEPH")
429 self
.assertEqual(export
.fsal
.user_id
, "ganesha")
430 self
.assertEqual(export
.fsal
.fs_name
, "a")
431 self
.assertEqual(export
.fsal
.sec_label_xattr
, None)
432 self
.assertEqual(len(export
.clients
), 2)
433 self
.assertEqual(export
.clients
[0].addresses
,
434 ["192.168.0.10", "192.168.1.0/8"])
435 self
.assertEqual(export
.clients
[0].squash
, "no_root_squash")
436 self
.assertIsNone(export
.clients
[0].access_type
)
437 self
.assertEqual(export
.clients
[1].addresses
, ["192.168.0.0/16"])
438 self
.assertEqual(export
.clients
[1].squash
, "all_squash")
439 self
.assertEqual(export
.clients
[1].access_type
, "RO")
440 self
.assertEqual(export
.daemons
, {"nodeb", "nodea"})
441 self
.assertEqual(export
.cluster_id
, '_default_')
442 self
.assertEqual(export
.attr_expiration_time
, 0)
443 self
.assertEqual(export
.security_label
, False)
445 # export_id = 2 asserts
447 self
.assertEqual(export
.export_id
, 2)
448 self
.assertEqual(export
.path
, "/")
449 self
.assertEqual(export
.pseudo
, "/rgw")
450 self
.assertIsNone(export
.tag
)
451 self
.assertEqual(export
.access_type
, "RW")
452 self
.assertEqual(export
.squash
, "all_squash")
453 self
.assertEqual(export
.protocols
, {4, 3})
454 self
.assertEqual(export
.transports
, {"TCP", "UDP"})
455 self
.assertEqual(export
.fsal
.name
, "RGW")
456 self
.assertEqual(export
.fsal
.rgw_user_id
, "testuser")
457 self
.assertEqual(export
.fsal
.access_key
, "access_key")
458 self
.assertEqual(export
.fsal
.secret_key
, "secret_key")
459 self
.assertEqual(len(export
.clients
), 0)
460 self
.assertEqual(export
.daemons
, {"nodea"})
461 self
.assertEqual(export
.cluster_id
, '_default_')
463 def test_update_export(self
):
464 ganesha
.RgwClient
= MagicMock()
465 admin_inst_mock
= MagicMock()
466 admin_inst_mock
.get_user_keys
.return_value
= {
467 'access_key': 'access_key',
468 'secret_key': 'secret_key'
470 ganesha
.RgwClient
.admin_instance
.return_value
= admin_inst_mock
472 conf
= GaneshaConf
.instance('_default_')
475 'daemons': ["nodeb"],
477 'pseudo': '/rgw/bucket',
478 'cluster_id': '_default_',
481 'squash': 'all_squash',
482 'security_label': False,
484 'transports': ['TCP', 'UDP'],
486 'addresses': ["192.168.0.0/16"],
492 'rgw_user_id': 'testuser'
496 conf
= GaneshaConf
.instance('_default_')
497 export
= conf
.get_export(2)
498 self
.assertEqual(export
.export_id
, 2)
499 self
.assertEqual(export
.path
, "bucket")
500 self
.assertEqual(export
.pseudo
, "/rgw/bucket")
501 self
.assertEqual(export
.tag
, "bucket_tag")
502 self
.assertEqual(export
.access_type
, "RW")
503 self
.assertEqual(export
.squash
, "all_squash")
504 self
.assertEqual(export
.protocols
, {4, 3})
505 self
.assertEqual(export
.transports
, {"TCP", "UDP"})
506 self
.assertEqual(export
.fsal
.name
, "RGW")
507 self
.assertEqual(export
.fsal
.rgw_user_id
, "testuser")
508 self
.assertEqual(export
.fsal
.access_key
, "access_key")
509 self
.assertEqual(export
.fsal
.secret_key
, "secret_key")
510 self
.assertEqual(len(export
.clients
), 1)
511 self
.assertEqual(export
.clients
[0].addresses
, ["192.168.0.0/16"])
512 self
.assertIsNone(export
.clients
[0].squash
)
513 self
.assertIsNone(export
.clients
[0].access_type
)
514 self
.assertEqual(export
.daemons
, {"nodeb"})
515 self
.assertEqual(export
.cluster_id
, '_default_')
517 def test_remove_export(self
):
518 conf
= GaneshaConf
.instance('_default_')
519 conf
.remove_export(1)
520 exports
= conf
.list_exports()
521 self
.assertEqual(len(exports
), 1)
522 self
.assertEqual(2, exports
[0].export_id
)
523 export
= conf
.get_export(2)
524 self
.assertEqual(export
.export_id
, 2)
525 self
.assertEqual(export
.path
, "/")
526 self
.assertEqual(export
.pseudo
, "/rgw")
527 self
.assertIsNone(export
.tag
)
528 self
.assertEqual(export
.access_type
, "RW")
529 self
.assertEqual(export
.squash
, "all_squash")
530 self
.assertEqual(export
.protocols
, {4, 3})
531 self
.assertEqual(export
.transports
, {"TCP", "UDP"})
532 self
.assertEqual(export
.fsal
.name
, "RGW")
533 self
.assertEqual(export
.fsal
.rgw_user_id
, "testuser")
534 self
.assertEqual(export
.fsal
.access_key
, "access_key")
535 self
.assertEqual(export
.fsal
.secret_key
, "secret_key")
536 self
.assertEqual(len(export
.clients
), 0)
537 self
.assertEqual(export
.daemons
, {"nodea"})
538 self
.assertEqual(export
.cluster_id
, '_default_')
540 def test_create_export_rgw(self
):
541 ganesha
.RgwClient
= MagicMock()
542 admin_inst_mock
= MagicMock()
543 admin_inst_mock
.get_user_keys
.return_value
= {
544 'access_key': 'access_key2',
545 'secret_key': 'secret_key2'
547 ganesha
.RgwClient
.admin_instance
.return_value
= admin_inst_mock
549 conf
= GaneshaConf
.instance('_default_')
550 ex_id
= conf
.create_export({
551 'daemons': ["nodeb"],
553 'pseudo': '/rgw/bucket',
555 'cluster_id': '_default_',
557 'squash': 'all_squash',
558 'security_label': False,
560 'transports': ['TCP', 'UDP'],
562 'addresses': ["192.168.0.0/16"],
568 'rgw_user_id': 'testuser'
572 conf
= GaneshaConf
.instance('_default_')
573 exports
= conf
.list_exports()
574 self
.assertEqual(len(exports
), 3)
575 export
= conf
.get_export(ex_id
)
576 self
.assertEqual(export
.export_id
, ex_id
)
577 self
.assertEqual(export
.path
, "bucket")
578 self
.assertEqual(export
.pseudo
, "/rgw/bucket")
579 self
.assertEqual(export
.tag
, "bucket_tag")
580 self
.assertEqual(export
.access_type
, "RW")
581 self
.assertEqual(export
.squash
, "all_squash")
582 self
.assertEqual(export
.protocols
, {4, 3})
583 self
.assertEqual(export
.transports
, {"TCP", "UDP"})
584 self
.assertEqual(export
.fsal
.name
, "RGW")
585 self
.assertEqual(export
.fsal
.rgw_user_id
, "testuser")
586 self
.assertEqual(export
.fsal
.access_key
, "access_key2")
587 self
.assertEqual(export
.fsal
.secret_key
, "secret_key2")
588 self
.assertEqual(len(export
.clients
), 1)
589 self
.assertEqual(export
.clients
[0].addresses
, ["192.168.0.0/16"])
590 self
.assertIsNone(export
.clients
[0].squash
)
591 self
.assertIsNone(export
.clients
[0].access_type
)
592 self
.assertEqual(export
.daemons
, {"nodeb"})
593 self
.assertEqual(export
.cluster_id
, '_default_')
595 def test_create_export_cephfs(self
):
596 ganesha
.CephX
= MagicMock()
597 ganesha
.CephX
.list_clients
.return_value
= ["fs"]
598 ganesha
.CephX
.get_client_key
.return_value
= "fs_key"
600 ganesha
.CephFS
= MagicMock()
601 ganesha
.CephFS
.dir_exists
.return_value
= True
603 conf
= GaneshaConf
.instance('_default_')
604 ex_id
= conf
.create_export({
605 'daemons': ['nodea', 'nodeb'],
607 'pseudo': '/cephfs2',
608 'cluster_id': '_default_',
611 'squash': 'all_squash',
612 'security_label': True,
614 'transports': ['TCP'],
620 'sec_label_xattr': 'security.selinux'
624 conf
= GaneshaConf
.instance('_default_')
625 exports
= conf
.list_exports()
626 self
.assertEqual(len(exports
), 3)
627 export
= conf
.get_export(ex_id
)
628 self
.assertEqual(export
.export_id
, ex_id
)
629 self
.assertEqual(export
.path
, "/")
630 self
.assertEqual(export
.pseudo
, "/cephfs2")
631 self
.assertIsNone(export
.tag
)
632 self
.assertEqual(export
.access_type
, "RW")
633 self
.assertEqual(export
.squash
, "all_squash")
634 self
.assertEqual(export
.protocols
, {4}
)
635 self
.assertEqual(export
.transports
, {"TCP"})
636 self
.assertEqual(export
.fsal
.name
, "CEPH")
637 self
.assertEqual(export
.fsal
.user_id
, "fs")
638 self
.assertEqual(export
.fsal
.cephx_key
, "fs_key")
639 self
.assertEqual(export
.fsal
.sec_label_xattr
, "security.selinux")
640 self
.assertIsNone(export
.fsal
.fs_name
)
641 self
.assertEqual(len(export
.clients
), 0)
642 self
.assertEqual(export
.daemons
, {"nodeb", "nodea"})
643 self
.assertEqual(export
.cluster_id
, '_default_')
644 self
.assertEqual(export
.attr_expiration_time
, 0)
645 self
.assertEqual(export
.security_label
, True)