source: trunk/src/allmydata/test/cli/test_status.py

Last change on this file was fec97256, checked in by Alexandre Detiste <alexandre.detiste@…>, at 2025-01-06T21:51:37Z

trim Python2 syntax

  • Property mode set to 100644
File size: 7.4 KB
Line 
1"""
2Ported to Python 3.
3"""
4
5import os
6import tempfile
7from io import BytesIO, StringIO
8from os.path import join
9
10from twisted.trial import unittest
11from twisted.internet import defer
12
13from allmydata.mutable.publish import MutableData
14from allmydata.scripts.common_http import BadResponse
15from allmydata.scripts.tahoe_status import _handle_response_for_fragment
16from allmydata.scripts.tahoe_status import _get_request_parameters_for_fragment
17from allmydata.scripts.tahoe_status import pretty_progress
18from allmydata.scripts.tahoe_status import do_status
19from allmydata.web.status import marshal_json
20
21from allmydata.immutable.upload import UploadStatus
22from allmydata.immutable.downloader.status import DownloadStatus
23from allmydata.mutable.publish import PublishStatus
24from allmydata.mutable.retrieve import RetrieveStatus
25from allmydata.mutable.servermap import UpdateStatus
26from allmydata.util import jsonbytes as json
27
28from ..no_network import GridTestMixin
29from ..common_web import do_http
30from .common import CLITestMixin
31
32
33class FakeStatus:
34    def __init__(self):
35        self.status = []
36
37    def setServiceParent(self, p):
38        pass
39
40    def get_status(self):
41        return self.status
42
43    def get_storage_index(self):
44        return None
45
46    def get_size(self):
47        return None
48
49
50class ProgressBar(unittest.TestCase):
51
52    def test_ascii0(self):
53        prog = pretty_progress(80.0, size=10, output_ascii=True)
54        self.assertEqual('########. ', prog)
55
56    def test_ascii1(self):
57        prog = pretty_progress(10.0, size=10, output_ascii=True)
58        self.assertEqual('#.        ', prog)
59
60    def test_ascii2(self):
61        prog = pretty_progress(13.0, size=10, output_ascii=True)
62        self.assertEqual('#o        ', prog)
63
64    def test_ascii3(self):
65        prog = pretty_progress(90.0, size=10, output_ascii=True)
66        self.assertEqual('#########.', prog)
67
68    def test_unicode0(self):
69        self.assertEqual(
70            pretty_progress(82.0, size=10, output_ascii=False),
71            u'\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258e ',
72        )
73
74    def test_unicode1(self):
75        self.assertEqual(
76            pretty_progress(100.0, size=10, output_ascii=False),
77            u'\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588',
78        )
79
80
81class _FakeOptions(dict):
82    def __init__(self):
83        self._tmp = tempfile.mkdtemp()
84        os.mkdir(join(self._tmp, 'private'), 0o777)
85        with open(join(self._tmp, 'private', 'api_auth_token'), 'w') as f:
86            f.write('a' * 32)
87        with open(join(self._tmp, 'node.url'), 'w') as f:
88            f.write('localhost:9000')
89
90        self['node-directory'] = self._tmp
91        self['verbose'] = True
92        self.stdout = StringIO()
93        self.stderr = StringIO()
94
95
96class Integration(GridTestMixin, CLITestMixin, unittest.TestCase):
97
98    @defer.inlineCallbacks
99    def setUp(self):
100        yield super(Integration, self).setUp()
101        self.basedir = "cli/status"
102        self.set_up_grid()
103
104        # upload something
105        c0 = self.g.clients[0]
106        data = MutableData(b"data" * 100)
107        filenode = yield c0.create_mutable_file(data)
108        self.uri = filenode.get_uri()
109
110        # make sure our web-port is actually answering
111        yield do_http("get", 'http://127.0.0.1:{}/status?t=json'.format(self.client_webports[0]))
112
113    def test_simple(self):
114        d = self.do_cli('status')# '--verbose')
115
116        def _check(ign):
117            code, stdout, stderr = ign
118            self.assertEqual(code, 0, stderr)
119            self.assertTrue('Skipped 1' in stdout)
120        d.addCallback(_check)
121        return d
122
123    @defer.inlineCallbacks
124    def test_help(self):
125        rc, _, _ = yield self.do_cli('status', '--help')
126        self.assertEqual(rc, 0)
127
128
129class CommandStatus(unittest.TestCase):
130    """
131    These tests just exercise the renderers and ensure they don't
132    catastrophically fail.
133    """
134
135    def setUp(self):
136        self.options = _FakeOptions()
137
138    def test_no_operations(self):
139        values = [
140            StringIO(json.dumps({
141                "active": [],
142                "recent": [],
143            })),
144            StringIO(json.dumps({
145                "counters": {
146                    "bytes_downloaded": 0,
147                },
148                "stats": {
149                    "node.uptime": 0,
150                }
151            })),
152        ]
153        def do_http(*args, **kw):
154            return values.pop(0)
155        do_status(self.options, do_http)
156
157    def test_simple(self):
158        recent_items = active_items = [
159            UploadStatus(),
160            DownloadStatus(b"abcd", 12345),
161            PublishStatus(),
162            RetrieveStatus(),
163            UpdateStatus(),
164            FakeStatus(),
165        ]
166        values = [
167            BytesIO(json.dumps({
168                "active": list(
169                    marshal_json(item)
170                    for item
171                    in active_items
172                ),
173                "recent": list(
174                    marshal_json(item)
175                    for item
176                    in recent_items
177                ),
178            }).encode("utf-8")),
179            BytesIO(json.dumps({
180                "counters": {
181                    "bytes_downloaded": 0,
182                },
183                "stats": {
184                    "node.uptime": 0,
185                }
186            }).encode("utf-8")),
187        ]
188        def do_http(*args, **kw):
189            return values.pop(0)
190        do_status(self.options, do_http)
191
192    def test_fetch_error(self):
193        def do_http(*args, **kw):
194            raise RuntimeError("boom")
195        do_status(self.options, do_http)
196
197
198class JsonHelpers(unittest.TestCase):
199
200    def test_bad_response(self):
201        def do_http(*args, **kw):
202            return
203        with self.assertRaises(RuntimeError) as ctx:
204            _handle_response_for_fragment(
205                BadResponse('the url', 'some err'),
206                'http://localhost:1234',
207            )
208        self.assertIn(
209            "Failed to get",
210            str(ctx.exception),
211        )
212
213    def test_happy_path(self):
214        resp = _handle_response_for_fragment(
215            StringIO('{"some": "json"}'),
216            'http://localhost:1234/',
217        )
218        self.assertEqual(resp, dict(some='json'))
219
220    def test_happy_path_post(self):
221        resp = _handle_response_for_fragment(
222            StringIO('{"some": "json"}'),
223            'http://localhost:1234/',
224        )
225        self.assertEqual(resp, dict(some='json'))
226
227    def test_no_data_returned(self):
228        with self.assertRaises(RuntimeError) as ctx:
229            _handle_response_for_fragment(StringIO('null'), 'http://localhost:1234')
230        self.assertIn('No data from', str(ctx.exception))
231
232    def test_no_post_args(self):
233        with self.assertRaises(ValueError) as ctx:
234            _get_request_parameters_for_fragment(
235                {'node-url': 'http://localhost:1234'},
236                '/fragment',
237                method='POST',
238                post_args=None,
239            )
240        self.assertIn(
241            "Must pass post_args",
242            str(ctx.exception),
243        )
244
245    def test_post_args_for_get(self):
246        with self.assertRaises(ValueError) as ctx:
247            _get_request_parameters_for_fragment(
248                {'node-url': 'http://localhost:1234'},
249                '/fragment',
250                method='GET',
251                post_args={'foo': 'bar'}
252            )
253        self.assertIn(
254            "only valid for POST",
255            str(ctx.exception),
256        )
Note: See TracBrowser for help on using the repository browser.