Completed
Pull Request — master (#277)
by Gleyberson
01:52
created

TestNapps.test_remote_install()   A

Complexity

Conditions 1

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 12
nop 2
dl 0
loc 17
rs 9.8
c 0
b 0
f 0
1
"""kytos.utils.napps.NAppsManager tests."""
2
import json
3
import unittest
4
from unittest.mock import MagicMock, Mock, PropertyMock, call, patch
5
6
from kytos.utils.exceptions import KytosException
7
from kytos.utils.napps import NAppsManager
8
from kytos.utils.settings import SKEL_PATH
9
10
11
# pylint: disable=protected-access, too-many-public-methods
12
class TestNapps(unittest.TestCase):
13
    """Test the class NAppsManager."""
14
15
    def setUp(self):
16
        """Execute steps before each tests."""
17
        self.napps_manager = NAppsManager()
18
19
    @staticmethod
20
    def get_napps_response_mock(napps=None):
21
        """Get mock to napps response."""
22
        if napps is None:
23
            napps = [["kytos", "mef_eline"], ["kytos", "of_lldp"]]
24
        response = json.dumps({"napps": napps})
25
26
        mock_response = MagicMock()
27
        mock_response.getcode.return_value = 200
28
        mock_response.read.return_value = response
29
        mock_response.__enter__.return_value = mock_response
30
        return mock_response
31
32
    @patch('urllib.request.urlopen')
33
    def test_enabled_property(self, mock_urlopen):
34
        """Test enabled property."""
35
        data = MagicMock()
36
        data.read.return_value = '{"napps": "ABC", "installed_napps": "DEF"}'
37
        mock_urlopen.return_value = data
38
39
        self.assertEqual(str(self.napps_manager._enabled), 'ABC')
40
41
    def test_enabled_property__error(self):
42
        """Test enabled property to error case."""
43
44
        with self.assertRaises(SystemExit):
45
            # pylint: disable=pointless-statement
46
            self.napps_manager._enabled
47
            # pylint: enable=pointless-statement
48
49
        self.assertIsNone(self.napps_manager._NAppsManager__local_enabled)
50
51
    @patch('urllib.request.urlopen')
52
    def test_installed_property(self, mock_urlopen):
53
        """Test installed property."""
54
        data = MagicMock()
55
        data.read.return_value = '{"napps": "ABC", "installed_napps": "DEF"}'
56
        mock_urlopen.return_value = data
57
58
        self.assertEqual(str(self.napps_manager._installed), 'DEF')
59
60
    def test_installed_property__error(self):
61
        """Test installed property to error case."""
62
63
        with self.assertRaises(SystemExit):
64
            # pylint: disable=pointless-statement
65
            self.napps_manager._installed
66
            # pylint: enable=pointless-statement
67
68
        self.assertIsNone(self.napps_manager._NAppsManager__local_installed)
69
70
    def test_napp_id_property(self):
71
        """Test napp_id property."""
72
        self.napps_manager.user = 'user'
73
        self.napps_manager.napp = 'napp'
74
75
        self.assertEqual(self.napps_manager.napp_id, 'user/napp')
76
77
    def test_set_napp(self):
78
        """Test set_napp method."""
79
        self.napps_manager.set_napp('user', 'napp', 'version')
80
81
        self.assertEqual(self.napps_manager.user, 'user')
82
        self.assertEqual(self.napps_manager.napp, 'napp')
83
        self.assertEqual(self.napps_manager.version, 'version')
84
85
    def test_get_napps(self):
86
        """Test method get_napps used to find
87
        enabled and installed napps.
88
        """
89
        mock_path = Mock()
90
91
        def glob_side_effect(args):
92
            """Path.glob to mock finding paths with kytos.json file."""
93
            self.assertEqual(args, "*/*/kytos.json")
94
95
            mock_path1 = Mock()
96
            mock_path1.parts = ['kytos', 'of_core', 'kytos.json']
97
98
            mock_path2 = Mock()
99
            mock_path2.parts = ['kytos', 'of_lldp', 'kytos.json']
100
101
            return [mock_path1, mock_path2]
102
103
        mock_path.glob = glob_side_effect
104
105
        # pylint: disable=protected-access
106
        get_return = self.napps_manager._get_napps(mock_path)
107
        self.assertEqual(get_return[0][0], 'kytos')
108
        self.assertEqual(get_return[0][1], 'of_core')
109
        self.assertEqual(get_return[1][0], 'kytos')
110
        self.assertEqual(get_return[1][1], 'of_lldp')
111
112 View Code Duplication
    def test_get_enabled_local(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
113
        """Test get_enabled_local used to find
114
        enabled napps in local machine"""
115
        # Mock kytos.json path
116
        mock_path = Mock()
117
118
        def glob_side_effect(args):
119
            """Path.glob to mock finding paths with kytos.json file."""
120
            self.assertEqual(args, "*/*/kytos.json")
121
122
            mock_path1 = Mock()
123
            mock_path1.parts = ['kytos', 'of_core', 'kytos.json']
124
            return [mock_path1]
125
        mock_path.glob = glob_side_effect
126
127
        mock_prop_enabled = PropertyMock()
128
        with patch.object(NAppsManager, '_enabled', mock_prop_enabled):
129
            mock_prop_enabled.return_value = mock_path
130
131
            get_return = self.napps_manager.get_enabled_local()
132
133
            self.assertEqual(get_return[0][0], 'kytos')
134
            self.assertEqual(get_return[0][1], 'of_core')
135
            self.assertEqual(mock_prop_enabled.call_count, 1)
136
137 View Code Duplication
    def test_get_installed_local(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
138
        """Test get_installed_local used to find
139
        installed napps in local machine"""
140
        # Mock kytos.json path
141
        mock_path = Mock()
142
143
        def glob_side_effect(args):
144
            """Path.glob to mock finding paths with kytos.json file."""
145
            self.assertEqual(args, "*/*/kytos.json")
146
147
            mock_path1 = Mock()
148
            mock_path1.parts = ['kytos', 'of_core', 'kytos.json']
149
            return [mock_path1]
150
        mock_path.glob = glob_side_effect
151
152
        mock_prop_installed = PropertyMock()
153
        with patch.object(NAppsManager, '_installed', mock_prop_installed):
154
            mock_prop_installed.return_value = mock_path
155
156
            get_return = self.napps_manager.get_installed_local()
157
158
            self.assertEqual(get_return[0][0], 'kytos')
159
            self.assertEqual(get_return[0][1], 'of_core')
160
            self.assertEqual(mock_prop_installed.call_count, 1)
161
162
    @patch('urllib.request.urlopen')
163
    def test_get_installed(self, mock_urlopen):
164
        """Test method get_installed to find all installed napps."""
165
        mock_urlopen.return_value = self.get_napps_response_mock()
166
167
        installed_napps = self.napps_manager.get_installed()
168
169
        self.assertEqual(len(installed_napps), 2)
170
        self.assertEqual(installed_napps[0], ("kytos", "mef_eline"))
171
        self.assertEqual(installed_napps[1], ("kytos", "of_lldp"))
172
173
    @patch('urllib.request.urlopen')
174
    def test_get_installed__error(self, mock_urlopen):
175
        """Test method get_installed with API error."""
176
        mock_response = MagicMock()
177
        mock_response.getcode.return_value = 500
178
        mock_urlopen.return_value = mock_response
179
180
        with self.assertRaises(KytosException) as context:
181
            self.napps_manager.get_installed()
182
183
        self.assertEqual('Error calling Kytos to check installed NApps.',
184
                         str(context.exception))
185
186
    @patch('urllib.request.urlopen')
187
    def test_get_enabled(self, mock_urlopen):
188
        """Test method get_enabled to find all enabled napps."""
189
        mock_urlopen.return_value = self.get_napps_response_mock()
190
191
        installed_napps = self.napps_manager.get_enabled()
192
193
        self.assertEqual(len(installed_napps), 2)
194
        self.assertEqual(installed_napps[0], ("kytos", "mef_eline"))
195
        self.assertEqual(installed_napps[1], ("kytos", "of_lldp"))
196
197
    @patch('urllib.request.urlopen')
198
    def test_get_enabled__error(self, mock_urlopen):
199
        """Test method get_enabled with API error."""
200
        mock_response = MagicMock()
201
        mock_response.getcode.return_value = 500
202
        mock_urlopen.return_value = mock_response
203
204
        with self.assertRaises(KytosException) as context:
205
            self.napps_manager.get_enabled()
206
207
        self.assertEqual('Error calling Kytos to check enabled NApps.',
208
                         str(context.exception))
209
210
    @patch('urllib.request.urlopen')
211
    def test_is_enabled(self, mock_urlopen):
212
        """Test is_enabled method."""
213
        mock_urlopen.return_value = self.get_napps_response_mock()
214
215
        self.napps_manager.user = 'kytos'
216
        self.napps_manager.napp = 'mef_eline'
217
218
        self.assertTrue(self.napps_manager.is_enabled())
219
220
    @patch('urllib.request.urlopen')
221
    def test_is_installed(self, mock_urlopen):
222
        """Test is_installed method."""
223
        mock_urlopen.return_value = self.get_napps_response_mock()
224
225
        self.napps_manager.user = 'kytos'
226
        self.napps_manager.napp = 'mef_eline'
227
228
        self.assertTrue(self.napps_manager.is_installed())
229
230
    @patch('urllib.request.urlopen')
231
    def test_get_disabled(self, mock_urlopen):
232
        """Test get_disabled method."""
233
        enabled = [["kytos", "mef_eline"]]
234
        mock_urlopen.side_effect = [self.get_napps_response_mock(),
235
                                    self.get_napps_response_mock(enabled)]
236
237
        disabled = self.napps_manager.get_disabled()
238
239
        self.assertEqual(disabled, [('kytos', 'of_lldp')])
240
241
    @patch('urllib.request.urlopen')
242
    def test_dependencies(self, mock_urlopen):
243
        """Test dependencies method."""
244
        napps = {"napp_dependencies": ["kytos/mef_eline", "kytos/of_lldp"]}
245
        data = MagicMock()
246
        data.read.return_value = json.dumps(napps)
247
        mock_urlopen.return_value = data
248
249
        dependencies = self.napps_manager.dependencies()
250
251
        expected_dependencies = [('kytos', 'mef_eline'), ('kytos', 'of_lldp')]
252
        self.assertEqual(dependencies, expected_dependencies)
253
254
    @patch('urllib.request.urlopen')
255
    def test_get_description(self, mock_urlopen):
256
        """Test get_description method."""
257
        data = MagicMock()
258
        data.read.return_value = '{"description": "ABC"}'
259
        mock_urlopen.return_value = data
260
261
        description = self.napps_manager.get_description()
262
263
        self.assertEqual(description, 'ABC')
264
265
    @patch('urllib.request.urlopen')
266
    def test_get_version(self, mock_urlopen):
267
        """Test get_version method."""
268
        data = MagicMock()
269
        data.read.return_value = '{"version": "123"}'
270
        mock_urlopen.return_value = data
271
272
        version = self.napps_manager.get_version()
273
274
        self.assertEqual(version, '123')
275
276
    @patch('urllib.request.urlopen')
277
    def test_get_napp_key(self, mock_urlopen):
278
        """Test _get_napp_key method."""
279
        data = MagicMock()
280
        data.read.return_value = '{"key": "ABC"}'
281
        mock_urlopen.return_value = data
282
283
        self.napps_manager.user = 'kytos'
284
        self.napps_manager.napp = 'mef_eline'
285
286
        meta_key = self.napps_manager._get_napp_key('key')
287
288
        self.assertEqual(meta_key, 'ABC')
289
290
    @patch('urllib.request.urlopen')
291
    def test_disable(self, mock_urlopen):
292
        """Test disable method."""
293
        data = MagicMock()
294
        data.read.return_value = '{}'
295
        mock_urlopen.return_value = data
296
297
        self.napps_manager.user = 'kytos'
298
        self.napps_manager.napp = 'mef_eline'
299
300
        self.napps_manager.disable()
301
302
        uri = self.napps_manager._kytos_api + self.napps_manager._NAPP_DISABLE
303
        uri = uri.format('kytos', 'mef_eline')
304
305
        mock_urlopen.assert_called_with(uri)
306
307
    @patch('urllib.request.urlopen')
308
    def test_enable(self, mock_urlopen):
309
        """Test enable method."""
310
        data = MagicMock()
311
        data.read.return_value = '{}'
312
        mock_urlopen.return_value = data
313
314
        self.napps_manager.user = 'kytos'
315
        self.napps_manager.napp = 'mef_eline'
316
317
        self.napps_manager.enable()
318
319
        uri = self.napps_manager._kytos_api + self.napps_manager._NAPP_ENABLE
320
        uri = uri.format('kytos', 'mef_eline')
321
322
        mock_urlopen.assert_called_with(uri)
323
324
    @patch('urllib.request.urlopen')
325
    def test_enabled_dir(self, mock_urlopen):
326
        """Test enabled_dir method."""
327
        data = MagicMock()
328
        data.read.return_value = '{"napps": "ABC", "installed_napps": "DEF"}'
329
        mock_urlopen.return_value = data
330
331
        self.napps_manager.user = 'kytos'
332
        self.napps_manager.napp = 'mef_eline'
333
334
        enabled_dir = self.napps_manager.enabled_dir()
335
        self.assertEqual(str(enabled_dir), 'ABC/kytos/mef_eline')
336
337
    @patch('urllib.request.urlopen')
338
    def test_installed_dir(self, mock_urlopen):
339
        """Test installed_dir method."""
340
        data = MagicMock()
341
        data.read.return_value = '{"napps": "ABC", "installed_napps": "DEF"}'
342
        mock_urlopen.return_value = data
343
344
        self.napps_manager.user = 'kytos'
345
        self.napps_manager.napp = 'mef_eline'
346
347
        installed_dir = self.napps_manager.installed_dir()
348
        self.assertEqual(str(installed_dir), 'DEF/kytos/mef_eline')
349
350
    @patch('urllib.request.urlopen')
351
    def test_remote_uninstall(self, mock_urlopen):
352
        """Test remote_uninstall method."""
353
        data = MagicMock()
354
        data.read.return_value = '{}'
355
        mock_urlopen.return_value = data
356
357
        self.napps_manager.user = 'kytos'
358
        self.napps_manager.napp = 'mef_eline'
359
360
        self.napps_manager.remote_uninstall()
361
362
        uninstall_uri = self.napps_manager._NAPP_UNINSTALL
363
        uri = self.napps_manager._kytos_api + uninstall_uri
364
        uri = uri.format('kytos', 'mef_eline')
365
366
        mock_urlopen.assert_called_with(uri)
367
368
    @patch('urllib.request.urlopen')
369
    def test_remote_install(self, mock_urlopen):
370
        """Test remote_install method."""
371
        data = MagicMock()
372
        data.read.return_value = '{}'
373
        mock_urlopen.return_value = data
374
375
        self.napps_manager.user = 'kytos'
376
        self.napps_manager.napp = 'mef_eline'
377
378
        self.napps_manager.remote_install()
379
380
        install_uri = self.napps_manager._NAPP_INSTALL
381
        uri = self.napps_manager._kytos_api + install_uri
382
        uri = uri.format('kytos', 'mef_eline')
383
384
        mock_urlopen.assert_called_with(uri)
385
386
    def test_valid_name(self):
387
        """Test valid_name method."""
388
        valid_name = self.napps_manager.valid_name('username')
389
        invalid_name = self.napps_manager.valid_name('_username')
390
391
        self.assertTrue(valid_name)
392
        self.assertFalse(invalid_name)
393
394
    @patch('jinja2.Environment.get_template')
395
    def test_render_template(self, mock_get_template):
396
        """Test render_template method."""
397
        template = MagicMock()
398
        mock_get_template.return_value = template
399
400
        self.napps_manager.render_template('', 'filename', 'context')
401
402
        mock_get_template.assert_called_with('filename')
403
        template.render.assert_called_with('context')
404
405
    @patch('os.makedirs')
406
    @patch('builtins.open')
407
    @patch('builtins.input')
408
    @patch('kytos.utils.napps.NAppsManager.render_template')
409
    def test_create_napp(self, *args):
410
        """Test create_napp method."""
411
        (mock_render_template, mock_input, _, mock_mkdirs) = args
412
        mock_input.side_effect = ['username', 'napp', None]
413
414
        self.napps_manager.create_napp()
415
416
        tmpl_path = SKEL_PATH / 'napp-structure/username/napp'
417
        description = '# TODO: <<<< Insert your NApp description here >>>>'
418
        context = {'username': 'username', 'napp': 'napp',
419
                   'description': description}
420
421
        calls = []
422
        for tmp in ['__init__.py', 'main.py', '.gitignore', 'kytos.json',
423
                    'README.rst', 'settings.py']:
424
            calls.append(call(tmpl_path, '{}.template'.format(tmp), context))
425
        calls.append(call('{}/ui'.format(tmpl_path), 'README.rst.template',
426
                          context))
427
428
        mock_mkdirs.assert_has_calls([call('username', exist_ok=True),
429
                                      call('username/napp'),
430
                                      call('username/napp/ui/k-info-panel'),
431
                                      call('username/napp/ui/k-toolbar'),
432
                                      call('username/napp/ui/k-action-menu')])
433
        mock_render_template.assert_has_calls(calls, any_order=True)
434