Tomas Krchnak | 536d828 | 2020-06-24 12:41:45 +0200 | [diff] [blame] | 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 2 | # not use this file except in compliance with the License. You may obtain |
| 3 | # a copy of the License at |
| 4 | # |
| 5 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 6 | # |
| 7 | # Unless required by applicable law or agreed to in writing, software |
| 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 10 | # License for the specific language governing permissions and limitations |
| 11 | # under the License. |
| 12 | |
Tomas Krchnak | 536d828 | 2020-06-24 12:41:45 +0200 | [diff] [blame] | 13 | import importlib |
Martin Kopec | e1eebfa | 2020-07-08 09:39:50 +0000 | [diff] [blame] | 14 | import tempfile |
| 15 | from unittest import mock |
Tomas Krchnak | 536d828 | 2020-06-24 12:41:45 +0200 | [diff] [blame] | 16 | |
| 17 | from tempest.lib.cmd import check_uuid |
| 18 | from tempest.tests import base |
| 19 | |
| 20 | |
| 21 | class TestSourcePatcher(base.TestCase): |
| 22 | def test_add_patch(self): |
| 23 | patcher = check_uuid.SourcePatcher() |
| 24 | fake_file = tempfile.NamedTemporaryFile("w+t", delete=False) |
| 25 | file_contents = 'first_line\nsecond_line' |
| 26 | fake_file.write(file_contents) |
| 27 | fake_file.close() |
| 28 | patcher.add_patch(fake_file.name, 'patch', 2) |
| 29 | |
| 30 | source_file = patcher.source_files[fake_file.name] |
| 31 | self.assertEqual(1, len(patcher.patches)) |
| 32 | (patch_id, patch), = patcher.patches.items() |
| 33 | self.assertEqual(patcher._quote('patch\n'), patch) |
| 34 | self.assertEqual('first_line\n{%s:s}second_line' % patch_id, |
| 35 | patcher._unquote(source_file)) |
| 36 | |
| 37 | def test_apply_patches(self): |
| 38 | fake_file = tempfile.NamedTemporaryFile("w+t") |
| 39 | patcher = check_uuid.SourcePatcher() |
| 40 | patcher.patches = {'fake-uuid': patcher._quote('patch\n')} |
| 41 | patcher.source_files = { |
| 42 | fake_file.name: patcher._quote('first_line\n') + |
| 43 | '{fake-uuid:s}second_line'} |
| 44 | with mock.patch('sys.stdout'): |
| 45 | patcher.apply_patches() |
| 46 | |
| 47 | lines = fake_file.read().split('\n') |
| 48 | fake_file.close() |
| 49 | self.assertEqual(['first_line', 'patch', 'second_line'], lines) |
| 50 | self.assertFalse(patcher.patches) |
| 51 | self.assertFalse(patcher.source_files) |
| 52 | |
| 53 | |
| 54 | class TestTestChecker(base.TestCase): |
| 55 | def _test_add_uuid_to_test(self, source_file): |
| 56 | class Fake_test_node(): |
| 57 | lineno = 1 |
| 58 | col_offset = 4 |
| 59 | patcher = check_uuid.SourcePatcher() |
| 60 | checker = check_uuid.TestChecker(importlib.import_module('tempest')) |
| 61 | fake_file = tempfile.NamedTemporaryFile("w+t", delete=False) |
| 62 | fake_file.write(source_file) |
| 63 | fake_file.close() |
| 64 | checker._add_uuid_to_test(patcher, Fake_test_node(), fake_file.name) |
| 65 | |
| 66 | self.assertEqual(1, len(patcher.patches)) |
| 67 | self.assertEqual(1, len(patcher.source_files)) |
| 68 | (patch_id, patch), = patcher.patches.items() |
| 69 | changed_source_file, = patcher.source_files.values() |
| 70 | self.assertEqual('{%s:s}%s' % (patch_id, patcher._quote(source_file)), |
| 71 | changed_source_file) |
| 72 | expected_patch_start = patcher._quote( |
| 73 | ' ' + check_uuid.DECORATOR_TEMPLATE.split('(')[0]) |
| 74 | self.assertTrue(patch.startswith(expected_patch_start)) |
| 75 | |
| 76 | def test_add_uuid_to_test_def(self): |
| 77 | source_file = (" def test_test():\n" |
| 78 | " pass") |
| 79 | self._test_add_uuid_to_test(source_file) |
| 80 | |
| 81 | def test_add_uuid_to_test_decorator(self): |
| 82 | source_file = (" @decorators.idempotent_id\n" |
| 83 | " def test_test():\n" |
| 84 | " pass") |
| 85 | self._test_add_uuid_to_test(source_file) |
| 86 | |
| 87 | def test_add_import_for_test_uuid_no_tempest(self): |
| 88 | patcher = check_uuid.SourcePatcher() |
| 89 | checker = check_uuid.TestChecker(importlib.import_module('tempest')) |
| 90 | fake_file = tempfile.NamedTemporaryFile("w+t") |
| 91 | |
| 92 | class Fake_src_parsed(): |
| 93 | body = ['test_node'] |
| 94 | checker._import_name = mock.Mock(return_value='fake_module') |
| 95 | |
| 96 | checker._add_import_for_test_uuid(patcher, Fake_src_parsed(), |
| 97 | fake_file.name) |
| 98 | (patch_id, patch), = patcher.patches.items() |
| 99 | self.assertEqual(patcher._quote('\n' + check_uuid.IMPORT_LINE + '\n'), |
| 100 | patch) |
| 101 | self.assertEqual('{%s:s}' % patch_id, |
| 102 | patcher.source_files[fake_file.name]) |
| 103 | |
| 104 | def test_add_import_for_test_uuid_tempest(self): |
| 105 | patcher = check_uuid.SourcePatcher() |
| 106 | checker = check_uuid.TestChecker(importlib.import_module('tempest')) |
| 107 | fake_file = tempfile.NamedTemporaryFile("w+t", delete=False) |
| 108 | test1 = (" def test_test():\n" |
| 109 | " pass\n") |
| 110 | test2 = (" def test_another_test():\n" |
| 111 | " pass\n") |
| 112 | source_code = test1 + test2 |
| 113 | fake_file.write(source_code) |
| 114 | fake_file.close() |
| 115 | |
| 116 | def fake_import_name(node): |
| 117 | return node.name |
| 118 | checker._import_name = fake_import_name |
| 119 | |
| 120 | class Fake_node(): |
| 121 | def __init__(self, lineno, col_offset, name): |
| 122 | self.lineno = lineno |
| 123 | self.col_offset = col_offset |
| 124 | self.name = name |
| 125 | |
| 126 | class Fake_src_parsed(): |
| 127 | body = [Fake_node(1, 4, 'tempest.a_fake_module'), |
| 128 | Fake_node(3, 4, 'another_fake_module')] |
| 129 | |
| 130 | checker._add_import_for_test_uuid(patcher, Fake_src_parsed(), |
| 131 | fake_file.name) |
| 132 | (patch_id, patch), = patcher.patches.items() |
| 133 | self.assertEqual(patcher._quote(check_uuid.IMPORT_LINE + '\n'), |
| 134 | patch) |
| 135 | expected_source = patcher._quote(test1) + '{' + patch_id + ':s}' +\ |
| 136 | patcher._quote(test2) |
| 137 | self.assertEqual(expected_source, |
| 138 | patcher.source_files[fake_file.name]) |