FreeCAD

Форк
0
177 строк · 7.3 Кб
1
# SPDX-License-Identifier: LGPL-2.1-or-later
2
# ***************************************************************************
3
# *                                                                         *
4
# *   Copyright (c) 2022 FreeCAD Project Association                        *
5
# *                                                                         *
6
# *   This file is part of FreeCAD.                                         *
7
# *                                                                         *
8
# *   FreeCAD is free software: you can redistribute it and/or modify it    *
9
# *   under the terms of the GNU Lesser General Public License as           *
10
# *   published by the Free Software Foundation, either version 2.1 of the  *
11
# *   License, or (at your option) any later version.                       *
12
# *                                                                         *
13
# *   FreeCAD is distributed in the hope that it will be useful, but        *
14
# *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
15
# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      *
16
# *   Lesser General Public License for more details.                       *
17
# *                                                                         *
18
# *   You should have received a copy of the GNU Lesser General Public      *
19
# *   License along with FreeCAD. If not, see                               *
20
# *   <https://www.gnu.org/licenses/>.                                      *
21
# *                                                                         *
22
# ***************************************************************************
23

24

25
import unittest
26
import os
27
import shutil
28
import stat
29
import tempfile
30
import time
31
from zipfile import ZipFile
32
import FreeCAD
33

34
from addonmanager_git import GitManager, NoGitFound, GitFailed
35

36
try:
37
    git_manager = GitManager()
38
except NoGitFound:
39
    git_manager = None
40

41

42
@unittest.skipIf(git_manager is None, "No git executable -- not running git-based tests")
43
class TestGit(unittest.TestCase):
44

45
    MODULE = "test_git"  # file name without extension
46

47
    def setUp(self):
48
        """Set up the test case: called by the unit test system"""
49
        self.cwd = os.getcwd()
50
        test_data_dir = os.path.join(
51
            FreeCAD.getHomePath(), "Mod", "AddonManager", "AddonManagerTest", "data"
52
        )
53
        git_repo_zip = os.path.join(test_data_dir, "test_repo.zip")
54
        self.test_dir = os.path.join(
55
            tempfile.gettempdir(), "FreeCADTesting", "AddonManagerTests", "Git"
56
        )
57
        os.makedirs(self.test_dir, exist_ok=True)
58
        self.test_repo_remote = os.path.join(self.test_dir, "TEST_REPO_REMOTE")
59
        if os.path.exists(self.test_repo_remote):
60
            # Make sure any old copy that got left around is deleted
61
            self._rmdir(self.test_repo_remote)
62

63
        if not os.path.exists(git_repo_zip):
64
            self.skipTest("Can't find test repo")
65
            return
66

67
        with ZipFile(git_repo_zip, "r") as zip_repo:
68
            zip_repo.extractall(self.test_repo_remote)
69
        self.test_repo_remote = os.path.join(self.test_repo_remote, "test_repo")
70

71
        self.git = git_manager
72

73
    def tearDown(self):
74
        """Clean up after the test"""
75
        os.chdir(self.cwd)
76
        # self._rmdir(self.test_dir)
77
        os.rename(self.test_dir, self.test_dir + ".old." + str(time.time()))
78

79
    def test_clone(self):
80
        """Test git clone"""
81
        checkout_dir = self._clone_test_repo()
82
        self.assertTrue(os.path.exists(checkout_dir))
83
        self.assertTrue(os.path.exists(os.path.join(checkout_dir, ".git")))
84
        self.assertEqual(os.getcwd(), self.cwd, "We should be left in the same CWD we started")
85

86
    def test_checkout(self):
87
        """Test git checkout"""
88
        checkout_dir = self._clone_test_repo()
89

90
        self.git.checkout(checkout_dir, "HEAD~1")
91
        status = self.git.status(checkout_dir).strip()
92
        expected_status = "## HEAD (no branch)"
93
        self.assertEqual(status, expected_status)
94

95
        self.assertEqual(os.getcwd(), self.cwd, "We should be left in the same CWD we started")
96

97
    def test_update(self):
98
        """Test using git to update the local repo"""
99
        checkout_dir = self._clone_test_repo()
100

101
        self.git.reset(checkout_dir, ["--hard", "HEAD~1"])
102
        self.assertTrue(self.git.update_available(checkout_dir))
103
        self.git.update(checkout_dir)
104
        self.assertFalse(self.git.update_available(checkout_dir))
105
        self.assertEqual(os.getcwd(), self.cwd, "We should be left in the same CWD we started")
106

107
    def test_tag_and_branch(self):
108
        """Test checking the currently checked-out tag"""
109
        checkout_dir = self._clone_test_repo()
110

111
        expected_tag = "TestTag"
112
        self.git.checkout(checkout_dir, expected_tag)
113
        found_tag = self.git.current_tag(checkout_dir)
114
        self.assertEqual(found_tag, expected_tag)
115
        self.assertFalse(self.git.update_available(checkout_dir))
116

117
        expected_branch = "TestBranch"
118
        self.git.checkout(checkout_dir, expected_branch)
119
        found_branch = self.git.current_branch(checkout_dir)
120
        self.assertEqual(found_branch, expected_branch)
121
        self.assertFalse(self.git.update_available(checkout_dir))
122

123
        expected_branch = "main"
124
        self.git.checkout(checkout_dir, expected_branch)
125
        found_branch = self.git.current_branch(checkout_dir)
126
        self.assertEqual(found_branch, expected_branch)
127
        self.assertFalse(self.git.update_available(checkout_dir))
128

129
        self.assertEqual(os.getcwd(), self.cwd, "We should be left in the same CWD we started")
130

131
    def test_get_remote(self):
132
        """Test getting the remote location"""
133
        checkout_dir = self._clone_test_repo()
134
        expected_remote = self.test_repo_remote
135
        returned_remote = self.git.get_remote(checkout_dir)
136
        self.assertEqual(expected_remote, returned_remote)
137
        self.assertEqual(os.getcwd(), self.cwd, "We should be left in the same CWD we started")
138

139
    def test_repair(self):
140
        """Test the repair feature (and some exception throwing)"""
141
        checkout_dir = self._clone_test_repo()
142
        remote = self.git.get_remote(checkout_dir)
143
        git_dir = os.path.join(checkout_dir, ".git")
144
        self.assertTrue(os.path.exists(git_dir))
145
        self._rmdir(git_dir)
146

147
        # Make sure that we've truly broken the install
148
        with self.assertRaises(GitFailed):
149
            self.git.status(checkout_dir)
150

151
        self.git.repair(remote, checkout_dir)
152
        status = self.git.status(checkout_dir)
153
        self.assertEqual(status, "## main...origin/main\n")
154
        self.assertEqual(os.getcwd(), self.cwd, "We should be left in the same CWD we started")
155

156
    def _rmdir(self, path):
157
        try:
158
            shutil.rmtree(path, onerror=self._remove_readonly)
159
        except Exception as e:
160
            print(e)
161

162
    def _remove_readonly(self, func, path, _) -> None:
163
        """Remove a read-only file."""
164

165
        os.chmod(path, stat.S_IWRITE)
166
        func(path)
167

168
    def _clone_test_repo(self) -> str:
169
        checkout_dir = os.path.join(self.test_dir, "test_repo")
170
        try:
171
            # Git won't clone to an existing directory, so make sure to remove it first
172
            if os.path.exists(checkout_dir):
173
                self._rmdir(checkout_dir)
174
            self.git.clone(self.test_repo_remote, checkout_dir)
175
        except GitFailed as e:
176
            self.fail(str(e))
177
        return checkout_dir
178

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.