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

111 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2024-04-05 20:41 +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 import main, DEFAULT_ATT_UD_SOURCE 

28import logging 

29 

30logging.disable(logging.CRITICAL) 

31 

32 

33class TestAdm(TestCase): 

34 def setUp(self): 

35 self.old_stderr = sys.stderr 

36 # sys.stderr = Mock() 

37 self.old_stdout = sys.stdout 

38 # sys.stdout = Mock() 

39 self.DEFAULT_OPTIONS = { 

40 "any_pin": False, 

41 "attestation_certificate_file_path": None, 

42 "attestation_ud_source": DEFAULT_ATT_UD_SOURCE, 

43 "new_pin": None, 

44 "no_exec": False, 

45 "no_unlock": False, 

46 "operation": None, 

47 "output_file_path": None, 

48 "pin": None, 

49 "pubkeys_file_path": None, 

50 "root_authority": None, 

51 "signer_authorization_file_path": None, 

52 "verbose": False, 

53 } 

54 

55 def tearDown(self): 

56 sys.stderr = self.old_stderr 

57 sys.stdout = self.old_stdout 

58 

59 @patch("adm.do_unlock") 

60 def test_unlock(self, do_unlock): 

61 expected_options = { 

62 **self.DEFAULT_OPTIONS, 

63 'operation': 'unlock', 

64 'pin': 'a-pin', 

65 } 

66 expected_call_args_list = [ 

67 call(Namespace(**expected_options)), 

68 call(Namespace(**expected_options)) 

69 ] 

70 

71 with patch('sys.argv', ['adm.py', '-p', 'a-pin', 'unlock']): 

72 with self.assertRaises(SystemExit) as e: 

73 main() 

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

75 

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

77 with self.assertRaises(SystemExit) as e: 

78 main() 

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

80 

81 self.assertTrue(do_unlock.called) 

82 self.assertEqual(do_unlock.call_count, 2) 

83 self.assertEqual(expected_call_args_list, do_unlock.call_args_list) 

84 

85 @patch("adm.do_onboard") 

86 def test_onboard(self, do_onboard): 

87 expected_options = { 

88 **self.DEFAULT_OPTIONS, 

89 'operation': 'onboard', 

90 'output_file_path': 'a-path', 

91 'pin': 'a-pin', 

92 } 

93 

94 expected_call_args_list = [ 

95 call(Namespace(**expected_options)), 

96 call(Namespace(**expected_options)) 

97 ] 

98 

99 with patch('sys.argv', ['adm.py', '-p', 'a-pin', '-o', 'a-path', 'onboard']): 

100 with self.assertRaises(SystemExit) as e: 

101 main() 

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

103 

104 with patch('sys.argv', 

105 ['adm.py', '--pin', 'a-pin', '--output', 'a-path', 'onboard']): 

106 with self.assertRaises(SystemExit) as e: 

107 main() 

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

109 

110 self.assertTrue(do_onboard.called) 

111 self.assertEqual(expected_call_args_list, do_onboard.call_args_list) 

112 

113 @patch("adm.do_get_pubkeys") 

114 def test_pubkeys(self, do_get_pubkeys): 

115 expected_options = { 

116 **self.DEFAULT_OPTIONS, 

117 'no_unlock': True, 

118 'operation': 'pubkeys', 

119 'output_file_path': 'a-path', 

120 'pin': 'a-pin', 

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.py', '-p', 'a-pin', '-o', 'a-path', '-u', 

129 '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.py', 

136 '--pin', 'a-pin', 

137 '--output', 'a-path', 

138 '--nounlock', 

139 'pubkeys']): 

140 with self.assertRaises(SystemExit) as e: 

141 main() 

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

143 

144 self.assertTrue(do_get_pubkeys.called) 

145 self.assertEqual(expected_call_args_list, do_get_pubkeys.call_args_list) 

146 

147 @patch("adm.do_changepin") 

148 def test_changepin(self, do_changepin): 

149 expected_options = { 

150 **self.DEFAULT_OPTIONS, 

151 'any_pin': True, 

152 'new_pin': 'new-pin', 

153 'operation': 'changepin', 

154 'pin': 'old-pin', 

155 } 

156 expected_call_args_list = [ 

157 call(Namespace(**expected_options)), 

158 call(Namespace(**expected_options)) 

159 ] 

160 

161 with patch('sys.argv', ['adm.py', '-p', 'old-pin', '-n', 'new-pin', 

162 '-a', 'changepin']): 

163 with self.assertRaises(SystemExit) as e: 

164 main() 

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

166 

167 with patch('sys.argv', ['adm.py', 

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

169 '--pin', 'old-pin']): 

170 with self.assertRaises(SystemExit) as e: 

171 main() 

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

173 

174 self.assertTrue(do_changepin.called) 

175 self.assertEqual(do_changepin.call_count, 2) 

176 self.assertEqual(expected_call_args_list, do_changepin.call_args_list) 

177 

178 @patch("adm.do_attestation") 

179 def test_attestation(self, do_attestation): 

180 expected_options = { 

181 **self.DEFAULT_OPTIONS, 

182 'attestation_certificate_file_path': 'certification-path', 

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

184 'operation': 'attestation', 

185 'output_file_path': 'out-path', 

186 'pin': 'a-pin', 

187 } 

188 expected_call_args_list = [ 

189 call(Namespace(**expected_options)), 

190 call(Namespace(**expected_options)) 

191 ] 

192 

193 with patch('sys.argv', ['adm.py', 

194 '-p', 'a-pin', 

195 '-o', 'out-path', 

196 '-t', 'certification-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.py', 

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

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

206 '--attcert', 'certification-path', 

207 '--attudsource', 'user-defined-source', 

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.do_verify_attestation") 

218 def test_verify_attestation(self, do_verify_attestation): 

219 expected_options = { 

220 **self.DEFAULT_OPTIONS, 

221 'attestation_certificate_file_path': 'certification-path', 

222 'operation': 'verify_attestation', 

223 'pin': 'a-pin', 

224 'pubkeys_file_path': 'pubkeys-path', 

225 'root_authority': 'root-authority', 

226 } 

227 expected_call_args_list = [ 

228 call(Namespace(**expected_options)), 

229 call(Namespace(**expected_options)) 

230 ] 

231 

232 with patch('sys.argv', ['adm.py', 

233 '-p', 'a-pin', 

234 '-t', 'certification-path', 

235 '-r', 'root-authority', 

236 '-b', 'pubkeys-path', 

237 'verify_attestation']): 

238 with self.assertRaises(SystemExit) as e: 

239 main() 

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

241 

242 with patch('sys.argv', ['adm.py', 

243 '--pin', 'a-pin', 

244 '--attcert', 'certification-path', 

245 '--root', 'root-authority', 

246 '--pubkeys', 'pubkeys-path', 

247 'verify_attestation']): 

248 with self.assertRaises(SystemExit) as e: 

249 main() 

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

251 

252 self.assertTrue(do_verify_attestation.called) 

253 self.assertEqual(do_verify_attestation.call_count, 2) 

254 self.assertEqual(expected_call_args_list, do_verify_attestation.call_args_list) 

255 

256 @patch("adm.do_authorize_signer") 

257 def test_authorize_signer(self, do_authorize_signer): 

258 expected_options = { 

259 **self.DEFAULT_OPTIONS, 

260 'operation': 'authorize_signer', 

261 'pin': 'a-pin', 

262 'signer_authorization_file_path': 'a-file-path', 

263 } 

264 expected_call_args_list = [ 

265 call(Namespace(**expected_options)), 

266 call(Namespace(**expected_options)) 

267 ] 

268 

269 with patch('sys.argv', ['adm.py', 

270 '-p', 'a-pin', 

271 '-z', 'a-file-path', 

272 'authorize_signer']): 

273 with self.assertRaises(SystemExit) as e: 

274 main() 

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

276 

277 with patch('sys.argv', ['adm.py', 

278 '--pin', 'a-pin', 

279 '--signauth', 'a-file-path', 

280 'authorize_signer']): 

281 with self.assertRaises(SystemExit) as e: 

282 main() 

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

284 

285 self.assertTrue(do_authorize_signer.called) 

286 self.assertEqual(do_authorize_signer.call_count, 2) 

287 self.assertEqual(expected_call_args_list, do_authorize_signer.call_args_list)