Coverage for tests/admin/test_adm_ledger.py: 100%
118 statements
« prev ^ index » next coverage.py v7.5.3, created at 2025-07-10 13:43 +0000
« 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.
23import sys
24from argparse import Namespace
25from unittest import TestCase
26from unittest.mock import call, patch
27from adm_ledger import main, DEFAULT_ATT_UD_SOURCE
28import logging
30logging.disable(logging.CRITICAL)
33class TestAdmLedger(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 }
55 def tearDown(self):
56 sys.stderr = self.old_stderr
57 sys.stdout = self.old_stdout
59 @patch("adm_ledger.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 ]
71 with patch('sys.argv', ['adm_ledger.py', '-p', 'a-pin', 'unlock']):
72 with self.assertRaises(SystemExit) as e:
73 main()
74 self.assertEqual(e.exception.code, 0)
76 with patch('sys.argv', ['adm_ledger.py', '--pin', 'a-pin', 'unlock']):
77 with self.assertRaises(SystemExit) as e:
78 main()
79 self.assertEqual(e.exception.code, 0)
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)
85 @patch("adm_ledger.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 }
94 expected_call_args_list = [
95 call(Namespace(**expected_options)),
96 call(Namespace(**expected_options))
97 ]
99 with patch('sys.argv',
100 ['adm_ledger.py', '-p', 'a-pin', '-o', 'a-path', 'onboard']):
101 with self.assertRaises(SystemExit) as e:
102 main()
103 self.assertEqual(e.exception.code, 0)
105 with patch('sys.argv',
106 ['adm_ledger.py', '--pin', 'a-pin', '--output', 'a-path', 'onboard']):
107 with self.assertRaises(SystemExit) as e:
108 main()
109 self.assertEqual(e.exception.code, 0)
111 self.assertTrue(do_onboard.called)
112 self.assertEqual(expected_call_args_list, do_onboard.call_args_list)
114 @patch("adm_ledger.do_get_pubkeys")
115 def test_pubkeys(self, do_get_pubkeys):
116 expected_options = {
117 **self.DEFAULT_OPTIONS,
118 'no_unlock': True,
119 'operation': 'pubkeys',
120 'output_file_path': 'a-path',
121 'pin': 'a-pin',
122 }
124 expected_call_args_list = [
125 call(Namespace(**expected_options)),
126 call(Namespace(**expected_options))
127 ]
129 with patch('sys.argv', ['adm_ledger.py', '-p', 'a-pin', '-o', 'a-path', '-u',
130 'pubkeys']):
131 with self.assertRaises(SystemExit) as e:
132 main()
133 self.assertEqual(e.exception.code, 0)
135 with patch('sys.argv',
136 ['adm_ledger.py',
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)
145 self.assertTrue(do_get_pubkeys.called)
146 self.assertEqual(expected_call_args_list, do_get_pubkeys.call_args_list)
148 @patch("adm_ledger.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 }
157 expected_call_args_list = [
158 call(Namespace(**expected_options)),
159 call(Namespace(**expected_options))
160 ]
162 with patch('sys.argv', ['adm_ledger.py', '-p', 'old-pin', '-n', 'new-pin',
163 '-a', 'changepin']):
164 with self.assertRaises(SystemExit) as e:
165 main()
166 self.assertEqual(e.exception.code, 0)
168 with patch('sys.argv', ['adm_ledger.py',
169 '--newpin', 'new-pin', '--anypin', 'changepin',
170 '--pin', 'old-pin']):
171 with self.assertRaises(SystemExit) as e:
172 main()
173 self.assertEqual(e.exception.code, 0)
175 self.assertTrue(do_changepin.called)
176 self.assertEqual(do_changepin.call_count, 2)
177 self.assertEqual(expected_call_args_list, do_changepin.call_args_list)
179 @patch("adm_ledger.do_attestation")
180 def test_attestation(self, do_attestation):
181 expected_options = {
182 **self.DEFAULT_OPTIONS,
183 'attestation_certificate_file_path': 'certification-path',
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))
192 ]
194 with patch('sys.argv', ['adm_ledger.py',
195 '-p', 'a-pin',
196 '-o', 'out-path',
197 '-t', 'certification-path',
198 '--attudsource', 'user-defined-source',
199 'attestation']):
200 with self.assertRaises(SystemExit) as e:
201 main()
202 self.assertEqual(e.exception.code, 0)
204 with patch('sys.argv', ['adm_ledger.py',
205 '--pin', 'a-pin',
206 '--output', 'out-path',
207 '--attcert', 'certification-path',
208 '--attudsource', 'user-defined-source',
209 'attestation']):
210 with self.assertRaises(SystemExit) as e:
211 main()
212 self.assertEqual(e.exception.code, 0)
214 self.assertTrue(do_attestation.called)
215 self.assertEqual(do_attestation.call_count, 2)
216 self.assertEqual(expected_call_args_list, do_attestation.call_args_list)
218 @patch("adm_ledger.do_verify_attestation")
219 def test_verify_attestation(self, do_verify_attestation):
220 expected_options = {
221 **self.DEFAULT_OPTIONS,
222 'attestation_certificate_file_path': 'certification-path',
223 'operation': 'verify_attestation',
224 'pin': 'a-pin',
225 'pubkeys_file_path': 'pubkeys-path',
226 'root_authority': 'root-authority',
227 }
228 expected_call_args_list = [
229 call(Namespace(**expected_options)),
230 call(Namespace(**expected_options))
231 ]
233 with patch('sys.argv', ['adm_ledger.py',
234 '-p', 'a-pin',
235 '-t', 'certification-path',
236 '-r', 'root-authority',
237 '-b', 'pubkeys-path',
238 'verify_attestation']):
239 with self.assertRaises(SystemExit) as e:
240 main()
241 self.assertEqual(e.exception.code, 0)
243 with patch('sys.argv', ['adm_ledger.py',
244 '--pin', 'a-pin',
245 '--attcert', 'certification-path',
246 '--root', 'root-authority',
247 '--pubkeys', 'pubkeys-path',
248 'verify_attestation']):
249 with self.assertRaises(SystemExit) as e:
250 main()
251 self.assertEqual(e.exception.code, 0)
253 self.assertTrue(do_verify_attestation.called)
254 self.assertEqual(do_verify_attestation.call_count, 2)
255 self.assertEqual(expected_call_args_list, do_verify_attestation.call_args_list)
257 @patch("adm_ledger.do_authorize_signer")
258 def test_authorize_signer(self, do_authorize_signer):
259 expected_options = {
260 **self.DEFAULT_OPTIONS,
261 'operation': 'authorize_signer',
262 'pin': 'a-pin',
263 'signer_authorization_file_path': 'a-file-path',
264 }
265 expected_call_args_list = [
266 call(Namespace(**expected_options)),
267 call(Namespace(**expected_options))
268 ]
270 with patch('sys.argv', ['adm_ledger.py',
271 '-p', 'a-pin',
272 '-z', 'a-file-path',
273 'authorize_signer']):
274 with self.assertRaises(SystemExit) as e:
275 main()
276 self.assertEqual(e.exception.code, 0)
278 with patch('sys.argv', ['adm_ledger.py',
279 '--pin', 'a-pin',
280 '--signauth', 'a-file-path',
281 'authorize_signer']):
282 with self.assertRaises(SystemExit) as e:
283 main()
284 self.assertEqual(e.exception.code, 0)
286 self.assertTrue(do_authorize_signer.called)
287 self.assertEqual(do_authorize_signer.call_count, 2)
288 self.assertEqual(expected_call_args_list, do_authorize_signer.call_args_list)