Test Failed
Pull Request — master (#277)
by Gleyberson
01:33
created

tests.unit.test_napps.TestNapps.test_get_napps()   A

Complexity

Conditions 1

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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