Coverage for tests/admin/test_adm_sgx.py: 100%

102 statements  

« prev     ^ index     » next       coverage.py v7.5.3, created at 2025-07-10 13:43 +0000

1# The MIT License (MIT) 

2# 

3# Copyright (c) 2021 RSK Labs Ltd 

4# 

5# Permission is hereby granted, free of charge, to any person obtaining a copy of 

6# this software and associated documentation files (the "Software"), to deal in 

7# the Software without restriction, including without limitation the rights to 

8# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 

9# of the Software, and to permit persons to whom the Software is furnished to do 

10# so, subject to the following conditions: 

11# 

12# The above copyright notice and this permission notice shall be included in all 

13# copies or substantial portions of the Software. 

14# 

15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 

16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 

17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 

18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 

19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 

20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 

21# SOFTWARE. 

22 

23import sys 

24from argparse import Namespace 

25from unittest import TestCase 

26from unittest.mock import call, patch 

27from adm_sgx import main 

28import logging 

29 

30logging.disable(logging.CRITICAL) 

31 

32 

33class TestAdmSgx(TestCase): 

34 def setUp(self): 

35 self.old_stdout = sys.stdout 

36 self.DEFAULT_OPTIONS = { 

37 "sgx_host": "localhost", 

38 "sgx_port": 7777, 

39 "any_pin": False, 

40 "new_pin": None, 

41 "no_unlock": False, 

42 "attestation_ud_source": "https://public-node.rsk.co", 

43 "attestation_certificate_file_path": None, 

44 "root_authority": None, 

45 "pubkeys_file_path": None, 

46 "operation": None, 

47 "output_file_path": None, 

48 "pin": None, 

49 "destination_sgx_port": 3333, 

50 "destination_sgx_host": "localhost", 

51 "migration_authorization_file_path": None, 

52 "verbose": False, 

53 } 

54 

55 def tearDown(self): 

56 sys.stdout = self.old_stdout 

57 

58 @patch("adm_sgx.do_unlock") 

59 def test_unlock(self, do_unlock): 

60 expected_options = { 

61 **self.DEFAULT_OPTIONS, 

62 'operation': 'unlock', 

63 'pin': 'a-pin', 

64 } 

65 expected_call_args_list = [ 

66 call(Namespace(**expected_options)), 

67 call(Namespace(**expected_options)) 

68 ] 

69 

70 with patch('sys.argv', ['adm_sgx.py', '-P', 'a-pin', 'unlock']): 

71 with self.assertRaises(SystemExit) as e: 

72 main() 

73 self.assertEqual(e.exception.code, 0) 

74 

75 with patch('sys.argv', ['adm_sgx.py', '--pin', 'a-pin', 'unlock']): 

76 with self.assertRaises(SystemExit) as e: 

77 main() 

78 self.assertEqual(e.exception.code, 0) 

79 

80 self.assertTrue(do_unlock.called) 

81 self.assertEqual(do_unlock.call_count, 2) 

82 self.assertEqual(expected_call_args_list, do_unlock.call_args_list) 

83 

84 @patch("adm_sgx.do_onboard") 

85 def test_onboard(self, do_onboard): 

86 expected_options = { 

87 **self.DEFAULT_OPTIONS, 

88 'operation': 'onboard', 

89 'pin': 'a-pin', 

90 } 

91 

92 expected_call_args_list = [ 

93 call(Namespace(**expected_options)), 

94 call(Namespace(**expected_options)) 

95 ] 

96 

97 with patch('sys.argv', 

98 ['adm_sgx.py', '-P', 'a-pin', 'onboard']): 

99 with self.assertRaises(SystemExit) as e: 

100 main() 

101 self.assertEqual(e.exception.code, 0) 

102 

103 with patch('sys.argv', 

104 ['adm_sgx.py', '--pin', 'a-pin', 'onboard']): 

105 with self.assertRaises(SystemExit) as e: 

106 main() 

107 self.assertEqual(e.exception.code, 0) 

108 

109 self.assertTrue(do_onboard.called) 

110 self.assertEqual(expected_call_args_list, do_onboard.call_args_list) 

111 

112 @patch("adm_sgx.do_get_pubkeys") 

113 def test_pubkeys(self, do_get_pubkeys): 

114 expected_options = { 

115 **self.DEFAULT_OPTIONS, 

116 'no_unlock': True, 

117 'operation': 'pubkeys', 

118 'output_file_path': 'a-path', 

119 'pin': 'a-pin', 

120 'sgx_host': '1.2.3.4', 

121 } 

122 

123 expected_call_args_list = [ 

124 call(Namespace(**expected_options)), 

125 call(Namespace(**expected_options)) 

126 ] 

127 

128 with patch('sys.argv', ['adm_sgx.py', '-P', 'a-pin', '-o', 'a-path', '-u', 

129 '-s', '1.2.3.4', 'pubkeys']): 

130 with self.assertRaises(SystemExit) as e: 

131 main() 

132 self.assertEqual(e.exception.code, 0) 

133 

134 with patch('sys.argv', 

135 ['adm_sgx.py', 

136 '--host', '1.2.3.4', 

137 '--pin', 'a-pin', 

138 '--output', 'a-path', 

139 '--nounlock', 

140 'pubkeys']): 

141 with self.assertRaises(SystemExit) as e: 

142 main() 

143 self.assertEqual(e.exception.code, 0) 

144 

145 self.assertTrue(do_get_pubkeys.called) 

146 self.assertEqual(expected_call_args_list, do_get_pubkeys.call_args_list) 

147 

148 @patch("adm_sgx.do_changepin") 

149 def test_changepin(self, do_changepin): 

150 expected_options = { 

151 **self.DEFAULT_OPTIONS, 

152 'any_pin': True, 

153 'new_pin': 'new-pin', 

154 'operation': 'changepin', 

155 'pin': 'old-pin', 

156 'sgx_port': 4567, 

157 } 

158 expected_call_args_list = [ 

159 call(Namespace(**expected_options)), 

160 call(Namespace(**expected_options)) 

161 ] 

162 

163 with patch('sys.argv', ['adm_sgx.py', '-P', 'old-pin', '-n', 'new-pin', 

164 '-p', '4567', '-a', 'changepin']): 

165 with self.assertRaises(SystemExit) as e: 

166 main() 

167 self.assertEqual(e.exception.code, 0) 

168 

169 with patch('sys.argv', ['adm_sgx.py', 

170 '--newpin', 'new-pin', '--anypin', 'changepin', 

171 '--port', '4567', '--pin', 'old-pin']): 

172 with self.assertRaises(SystemExit) as e: 

173 main() 

174 self.assertEqual(e.exception.code, 0) 

175 

176 self.assertTrue(do_changepin.called) 

177 self.assertEqual(do_changepin.call_count, 2) 

178 self.assertEqual(expected_call_args_list, do_changepin.call_args_list) 

179 

180 @patch("adm_sgx.do_attestation") 

181 def test_attestation(self, do_attestation): 

182 expected_options = { 

183 **self.DEFAULT_OPTIONS, 

184 'attestation_ud_source': 'user-defined-source', 

185 'operation': 'attestation', 

186 'output_file_path': 'out-path', 

187 'pin': 'a-pin', 

188 } 

189 expected_call_args_list = [ 

190 call(Namespace(**expected_options)), 

191 call(Namespace(**{**expected_options, "no_unlock": True})) 

192 ] 

193 

194 with patch('sys.argv', ['adm_sgx.py', 

195 '-P', 'a-pin', 

196 '-o', 'out-path', 

197 '--attudsource', 'user-defined-source', 

198 'attestation']): 

199 with self.assertRaises(SystemExit) as e: 

200 main() 

201 self.assertEqual(e.exception.code, 0) 

202 

203 with patch('sys.argv', ['adm_sgx.py', 

204 '--pin', 'a-pin', 

205 '--output', 'out-path', 

206 '--attudsource', 'user-defined-source', 

207 '--nounlock', 

208 'attestation']): 

209 with self.assertRaises(SystemExit) as e: 

210 main() 

211 self.assertEqual(e.exception.code, 0) 

212 

213 self.assertTrue(do_attestation.called) 

214 self.assertEqual(do_attestation.call_count, 2) 

215 self.assertEqual(expected_call_args_list, do_attestation.call_args_list) 

216 

217 @patch("adm_sgx.do_migrate_db") 

218 def test_migrate_db(self, do_migrate_db): 

219 expected_options = { 

220 **self.DEFAULT_OPTIONS, 

221 "operation": "migrate_db", 

222 "migration_authorization_file_path": "a-file-path", 

223 } 

224 expected_call_args_list = [ 

225 call(Namespace(**expected_options)), 

226 call(Namespace(**{ 

227 **expected_options, 

228 "destination_sgx_port": 4444, 

229 "destination_sgx_host": "another.host.com"})) 

230 ] 

231 

232 with patch("sys.argv", ["adm_sgx.py", 

233 "migrate_db", 

234 "--migauth", "a-file-path"]): 

235 with self.assertRaises(SystemExit) as e: 

236 main() 

237 self.assertEqual(e.exception.code, 0) 

238 

239 with patch("sys.argv", ["adm_sgx.py", 

240 "migrate_db", 

241 "-z", "a-file-path", 

242 "--dest-port", "4444", 

243 "--dest-host", "another.host.com"]): 

244 with self.assertRaises(SystemExit) as e: 

245 main() 

246 self.assertEqual(e.exception.code, 0) 

247 

248 self.assertTrue(do_migrate_db.called) 

249 self.assertEqual(do_migrate_db.call_count, 2) 

250 for i, call_args in enumerate(expected_call_args_list): 

251 self.assertEqual(call_args, do_migrate_db.call_args_list[i], f"Call #{i}")