Coverage for manila/tests/utils.py: 82%

61 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2026-02-18 22:19 +0000

1# Copyright 2011 OpenStack LLC 

2# Copyright 2015 Mirantic, Inc. 

3# All Rights Reserved. 

4# 

5# Licensed under the Apache License, Version 2.0 (the "License"); you may 

6# not use this file except in compliance with the License. You may obtain 

7# a copy of the License at 

8# 

9# http://www.apache.org/licenses/LICENSE-2.0 

10# 

11# Unless required by applicable law or agreed to in writing, software 

12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 

13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 

14# License for the specific language governing permissions and limitations 

15# under the License. 

16 

17import fixtures 

18import functools 

19import os 

20 

21from oslo_config import cfg 

22 

23from manila import context 

24from manila import utils 

25 

26CONF = cfg.CONF 

27 

28 

29class NamedBinaryStr(bytes): 

30 

31 """Wrapper for bytes to facilitate overriding __name__.""" 

32 

33 

34class NamedUnicodeStr(str): 

35 

36 """Unicode string look-alike to facilitate overriding __name__.""" 

37 

38 def __init__(self, value): 

39 self._value = value 

40 

41 def __str__(self): 

42 return self._value 

43 

44 def encode(self, enc): 

45 return self._value.encode(enc) 

46 

47 def __format__(self, formatstr): 

48 """Workaround for ddt bug. 

49 

50 DDT will always call __format__ even when __name__ exists, 

51 which blows up for Unicode strings under Py2. 

52 """ 

53 return '' 

54 

55 

56class NamedDict(dict): 

57 

58 """Wrapper for dict to facilitate overriding __name__.""" 

59 

60 

61class NamedTuple(tuple): 

62 

63 """Wrapper for dict to facilitate overriding __name__.""" 

64 

65 

66def annotated(test_name, test_input): 

67 if isinstance(test_input, dict): 

68 annotated_input = NamedDict(test_input) 

69 elif isinstance(test_input, str): 69 ↛ 70line 69 didn't jump to line 70 because the condition on line 69 was never true

70 annotated_input = NamedUnicodeStr(test_input) 

71 elif isinstance(test_input, tuple): 71 ↛ 74line 71 didn't jump to line 74 because the condition on line 71 was always true

72 annotated_input = NamedTuple(test_input) 

73 else: 

74 annotated_input = NamedBinaryStr(test_input) 

75 

76 setattr(annotated_input, '__name__', test_name) 

77 return annotated_input 

78 

79 

80def get_test_admin_context(): 

81 return context.get_admin_context() 

82 

83 

84def is_manila_installed(): 

85 if os.path.exists('../../manila.manila.egg-info'): 

86 return True 

87 else: 

88 return False 

89 

90 

91def set_timeout(timeout): 

92 """Timeout decorator for unit test methods. 

93 

94 Use this decorator for tests that are expected to pass in very specific 

95 amount of time, not common for all other tests. 

96 It can have either big or small value. 

97 """ 

98 

99 def _decorator(f): 

100 

101 @functools.wraps(f) 

102 def _wrapper(self, *args, **kwargs): 

103 self.useFixture(fixtures.Timeout(timeout, gentle=True)) 

104 return f(self, *args, **kwargs) 

105 

106 return _wrapper 

107 

108 return _decorator 

109 

110 

111class create_temp_config_with_opts(object): 

112 """Creates temporary config file with provided opts and values. 

113 

114 usage: 

115 data = {'FOO_GROUP': {'foo_opt': 'foo_value'}} 

116 assert CONF.FOO_GROUP.foo_opt != 'foo_value' 

117 with create_temp_config_with_opts(data): 

118 assert CONF.FOO_GROUP.foo_opt == 'foo_value' 

119 assert CONF.FOO_GROUP.foo_opt != 'foo_value' 

120 

121 :param data: dict -- expected dict with two layers, first is name of 

122 config group and second is opts with values. Example: 

123 {'DEFAULT': {'foo_opt': 'foo_v'}, 'BAR_GROUP': {'bar_opt': 'bar_v'}} 

124 """ 

125 

126 def __init__(self, data): 

127 self.data = data 

128 

129 def __enter__(self): 

130 config_filename = 'fake_config' 

131 with utils.tempdir() as tmpdir: 

132 tmpfilename = os.path.join(tmpdir, '%s.conf' % config_filename) 

133 with open(tmpfilename, "w") as configfile: 

134 for group, opts in self.data.items(): 

135 configfile.write("""[%s]\n""" % group) 

136 for opt, value in opts.items(): 

137 configfile.write( 

138 """%(k)s = %(v)s\n""" % {'k': opt, 'v': value}) 

139 configfile.write("""\n""") 

140 

141 # Add config file with updated opts 

142 CONF.default_config_files = [configfile.name] 

143 

144 # Reload config instance to use redefined opts 

145 CONF.reload_config_files() 

146 return CONF 

147 

148 def __exit__(self, exc_type, exc_value, exc_traceback): 

149 return False # do not suppress errors