Skip to content

Commit 79c194d

Browse files
committed
Make all tests work offline
Relying only on local resources results in more reliable test results and enables development without reliable internet access. Signed-off-by: Scott K Logan <[email protected]>
1 parent 75727e7 commit 79c194d

17 files changed

+366
-150
lines changed

test/__init__.py

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
"""Fixtures and utilities for testing vcs2l."""
2+
3+
import os
4+
import shutil
5+
import subprocess
6+
import tarfile
7+
import unittest
8+
import zipfile
9+
from shutil import which
10+
from tempfile import TemporaryDirectory
11+
from urllib.parse import urljoin
12+
from urllib.request import pathname2url
13+
14+
import yaml
15+
16+
17+
def to_file_url(path):
18+
return urljoin('file:', pathname2url(path))
19+
20+
21+
class StagedReposFile(unittest.TestCase):
22+
"""Fixture for testing git, tar, and zip clients."""
23+
24+
_git = which('git')
25+
_git_env = {
26+
**os.environ,
27+
'GIT_AUTHOR_NAME': 'vcs2l',
28+
'GIT_AUTHOR_DATE': '2005-01-01T00:00:00-06:00',
29+
'GIT_AUTHOR_EMAIL': '[email protected]',
30+
'GIT_COMMITTER_NAME': 'vcs2l',
31+
'GIT_COMMITTER_DATE': '2005-01-01T00:00:00-06:00',
32+
'GIT_COMMITTER_EMAIL': '[email protected]',
33+
'GIT_CONFIG_GLOBAL': os.path.join(os.path.dirname(__file__), '.gitconfig'),
34+
'LANG': 'en_US.UTF-8',
35+
}
36+
_commit_date = '2005-01-01T00:00:00'
37+
38+
temp_dir = None
39+
repos_file_path = None
40+
41+
@classmethod
42+
def setUpClass(cls):
43+
if not cls._git:
44+
raise unittest.SkipTest('`git` was not found')
45+
46+
cls.temp_dir = TemporaryDirectory(suffix='.vcstmp')
47+
48+
# Create the staged git repository
49+
gitrepo_path = os.path.join(cls.temp_dir.name, 'gitrepo')
50+
os.mkdir(gitrepo_path)
51+
shutil.copy(
52+
os.path.join(os.path.dirname(os.path.dirname(__file__)), 'LICENSE'),
53+
gitrepo_path,
54+
)
55+
for command in (
56+
('init', '--quiet', '.'),
57+
('commit', '--quiet', '--allow-empty', '-m', '0.1.26'),
58+
('tag', '0.1.26'),
59+
('checkout', '--quiet', '-b', 'license'),
60+
('add', 'LICENSE'),
61+
('commit', '--quiet', '-m', 'Add LICENSE'),
62+
('checkout', '--quiet', 'main'),
63+
('merge', '--no-ff', '--quiet', 'license', '-m', "Merge branch 'license'"),
64+
('branch', '--quiet', '-D', 'license'),
65+
('commit', '--quiet', '--allow-empty', '-m', 'update changelog'),
66+
('commit', '--quiet', '--allow-empty', '-m', '0.1.27'),
67+
('tag', '0.1.27'),
68+
('commit', '--quiet', '--allow-empty', '-m', "codin' codin' codin'"),
69+
):
70+
subprocess.check_call(
71+
[
72+
cls._git,
73+
*command,
74+
],
75+
cwd=gitrepo_path,
76+
env=cls._git_env,
77+
)
78+
79+
# Create the archive stage
80+
archive_path = os.path.join(cls.temp_dir.name, 'archive_dir')
81+
os.mkdir(archive_path)
82+
with open(os.path.join(archive_path, 'file_name.txt'), 'wb') as f:
83+
f.write(b'Lorem Ipsum\n')
84+
85+
# Create a tar file
86+
tarball_path = os.path.join(cls.temp_dir.name, 'archive.tar.gz')
87+
with tarfile.TarFile.open(tarball_path, 'w:gz') as f:
88+
f.add(archive_path, 'archive_dir')
89+
90+
# Create a zip file
91+
zip_path = os.path.join(cls.temp_dir.name, 'archive.zip')
92+
with zipfile.ZipFile(zip_path, mode='w') as f:
93+
f.write(
94+
os.path.join(archive_path, 'file_name.txt'),
95+
os.path.join('archive_dir', 'file_name.txt'),
96+
)
97+
98+
# Populate the staged.repos file
99+
repos = {
100+
'immutable/hash': {
101+
'type': 'git',
102+
'url': to_file_url(gitrepo_path),
103+
'version': '5b3504594f7354121cf024dc734bf79e270cffd3',
104+
},
105+
'immutable/hash_tar': {
106+
'type': 'tar',
107+
'url': to_file_url(tarball_path),
108+
'version': 'archive_dir',
109+
},
110+
'immutable/hash_zip': {
111+
'type': 'zip',
112+
'url': to_file_url(zip_path),
113+
'version': 'archive_dir',
114+
},
115+
'immutable/tag': {
116+
'type': 'git',
117+
'url': to_file_url(gitrepo_path),
118+
'version': 'tags/0.1.27',
119+
},
120+
'vcs2l': {
121+
'type': 'git',
122+
'url': to_file_url(gitrepo_path),
123+
'version': 'heads/main',
124+
},
125+
'without_version': {
126+
'type': 'git',
127+
'url': to_file_url(gitrepo_path),
128+
},
129+
}
130+
131+
cls.repos_file_path = os.path.join(cls.temp_dir.name, 'staged.repos')
132+
with open(cls.repos_file_path, 'wb') as f:
133+
yaml.safe_dump({'repositories': repos}, f, encoding='utf-8')
134+
135+
@classmethod
136+
def tearDownClass(cls):
137+
cls.repos_file_path = None
138+
if cls.temp_dir:
139+
cls.temp_dir.cleanup()
140+
cls.temp_dir = None
141+
142+
143+
class StagedReposFile2(unittest.TestCase):
144+
"""Fixture for testing subversion and mercurial clients."""
145+
146+
_svn = which('svn')
147+
_svnadmin = which('svnadmin')
148+
_hg = which('hg')
149+
_hg_env = {
150+
**os.environ,
151+
'HGUSER': 'vcs2l',
152+
'EMAIL': '[email protected]',
153+
}
154+
_commit_date = '2005-01-01T00:00:00-06:00'
155+
156+
temp_dir = None
157+
repos_file_path = None
158+
159+
@classmethod
160+
def setUpClass(cls):
161+
if not cls._svn:
162+
raise unittest.SkipTest('`svn` was not found')
163+
if not cls._svnadmin:
164+
raise unittest.SkipTest('`svnadmin` was not found')
165+
if not cls._hg:
166+
raise unittest.SkipTest('`hg` was not found')
167+
try:
168+
# check if the svn executable is usable (on macOS)
169+
# and not only exists to state that the program is not installed
170+
subprocess.check_call([cls._svn, '--version'], stdout=subprocess.DEVNULL)
171+
except subprocess.CalledProcessError as e:
172+
raise unittest.SkipTest('`svn` was not found') from e
173+
174+
cls.temp_dir = TemporaryDirectory(suffix='.vcstmp')
175+
176+
# Create the staged subversion repository
177+
svnrepo_path = os.path.join(cls.temp_dir.name, 'svnrepo')
178+
os.mkdir(svnrepo_path)
179+
subprocess.check_call(
180+
[
181+
'svnadmin',
182+
'create',
183+
'.',
184+
],
185+
cwd=svnrepo_path,
186+
)
187+
188+
svnclone_path = os.path.join(cls.temp_dir.name, 'svnclone')
189+
os.mkdir(svnclone_path)
190+
shutil.copy(
191+
os.path.join(os.path.dirname(os.path.dirname(__file__)), 'LICENSE'),
192+
svnclone_path,
193+
)
194+
for command in (
195+
('checkout', to_file_url(svnrepo_path), '.', '--quiet'),
196+
('add', 'LICENSE', '--quiet'),
197+
('commit', 'LICENSE', '-m', 'Initial commit', '--quiet'),
198+
):
199+
subprocess.check_call(
200+
[
201+
cls._svn,
202+
*command,
203+
],
204+
cwd=svnclone_path,
205+
)
206+
207+
# Create the staged mercurial repository
208+
hgrepo_path = os.path.join(cls.temp_dir.name, 'hgrepo')
209+
os.mkdir(hgrepo_path)
210+
for command in (
211+
('init', '.'),
212+
('branch', '--quiet', 'stable'),
213+
('commit', '-m', 'Initial commit', '-d', cls._commit_date),
214+
('tag', '-d', cls._commit_date, '5.8'),
215+
):
216+
subprocess.check_call(
217+
[
218+
cls._hg,
219+
*command,
220+
],
221+
cwd=hgrepo_path,
222+
env=cls._hg_env,
223+
)
224+
225+
# Populate the staged.repos file
226+
repos = {
227+
'hg/branch': {
228+
'type': 'hg',
229+
'url': to_file_url(hgrepo_path),
230+
'version': 'stable',
231+
},
232+
'hg/hash': {
233+
'type': 'hg',
234+
'url': to_file_url(hgrepo_path),
235+
'version': '9bd654917508',
236+
},
237+
'hg/tag': {
238+
'type': 'hg',
239+
'url': to_file_url(hgrepo_path),
240+
'version': '5.8',
241+
},
242+
'svn/rev': {
243+
'type': 'svn',
244+
'url': to_file_url(svnrepo_path),
245+
'version': '1',
246+
},
247+
}
248+
249+
cls.repos_file_path = os.path.join(cls.temp_dir.name, 'staged.repos')
250+
with open(cls.repos_file_path, 'wb') as f:
251+
yaml.safe_dump({'repositories': repos}, f, encoding='utf-8')
252+
253+
@classmethod
254+
def tearDownClass(cls):
255+
cls.repos_file_path = None
256+
if cls.temp_dir:
257+
cls.temp_dir.cleanup()
258+
cls.temp_dir = None

test/branch.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
....
22
=== ./immutable/hash (git) ===
3-
(HEAD detached at 377d5b3)
3+
(HEAD detached at 5b35045)
44
=== ./immutable/tag (git) ===
55
(HEAD detached at 0.1.27)
66
=== ./vcs2l (git) ===

test/export_exact.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
repositories:
22
hash:
33
type: git
4-
url: https://github.com/ros-infrastructure/vcs2l.git
5-
version: 377d5b3d03c212f015cc832fdb368f4534d0d583
4+
url: file:///vcstmp/gitrepo
5+
version: 5b3504594f7354121cf024dc734bf79e270cffd3
66
tag:
77
type: git
8-
url: https://github.com/ros-infrastructure/vcs2l.git
9-
version: bf9ca56de693a02b93ed423bcef589259d75eb0f
8+
url: file:///vcstmp/gitrepo
9+
version: 8087b72504968800cdf54759b11e0b753ec90736

test/export_exact_with_tags.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
repositories:
22
hash:
33
type: git
4-
url: https://github.com/ros-infrastructure/vcs2l.git
5-
version: 377d5b3d03c212f015cc832fdb368f4534d0d583
4+
url: file:///vcstmp/gitrepo
5+
version: 5b3504594f7354121cf024dc734bf79e270cffd3
66
tag:
77
type: git
8-
url: https://github.com/ros-infrastructure/vcs2l.git
8+
url: file:///vcstmp/gitrepo
99
version: 0.1.27

test/import.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
......
22
=== ./immutable/hash (git) ===
33
Cloning into '.'...
4-
Note: switching to '377d5b3d03c212f015cc832fdb368f4534d0d583'.
4+
Note: switching to '5b3504594f7354121cf024dc734bf79e270cffd3'.
55

66
You are in 'detached HEAD' state. You can look around, make experimental
77
changes and commit them, and you can discard any commits you make in this
@@ -18,11 +18,11 @@ Or undo this operation with:
1818

1919
Turn off this advice by setting config variable advice.detachedHead to false
2020

21-
HEAD is now at 377d5b3... update changelog
21+
HEAD is now at 5b35045... update changelog
2222
=== ./immutable/hash_tar (tar) ===
23-
Downloaded tarball from 'https://github.com/ros-infrastructure/vcs2l/archive/377d5b3d03c212f015cc832fdb368f4534d0d583.tar.gz' and unpacked it
23+
Downloaded tarball from 'file:///vcstmp/archive.tar.gz' and unpacked it
2424
=== ./immutable/hash_zip (zip) ===
25-
Downloaded zipfile from 'https://github.com/ros-infrastructure/vcs2l/archive/377d5b3d03c212f015cc832fdb368f4534d0d583.zip' and unpacked it
25+
Downloaded zipfile from 'file:///vcstmp/archive.zip' and unpacked it
2626
=== ./immutable/tag (git) ===
2727
Cloning into '.'...
2828
Note: switching to 'tags/0.1.27'.
@@ -42,7 +42,7 @@ Or undo this operation with:
4242

4343
Turn off this advice by setting config variable advice.detachedHead to false
4444

45-
HEAD is now at bf9ca56... 0.1.27
45+
HEAD is now at 8087b72... 0.1.27
4646
=== ./vcs2l (git) ===
4747
Cloning into '.'...
4848
=== ./without_version (git) ===

test/import_shallow.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
=== ./immutable/hash (git) ===
33
Initialized empty Git repository in ./immutable/hash/.git/
44

5-
From https://github.com/ros-infrastructure/vcs2l
6-
* branch 377d5b3d03c212f015cc832fdb368f4534d0d583 -> FETCH_HEAD
7-
Note: switching to '377d5b3d03c212f015cc832fdb368f4534d0d583'.
5+
From file:///vcstmp/gitrepo
6+
* branch 5b3504594f7354121cf024dc734bf79e270cffd3 -> FETCH_HEAD
7+
Note: switching to '5b3504594f7354121cf024dc734bf79e270cffd3'.
88

99
You are in 'detached HEAD' state. You can look around, make experimental
1010
changes and commit them, and you can discard any commits you make in this
@@ -21,15 +21,15 @@ Or undo this operation with:
2121

2222
Turn off this advice by setting config variable advice.detachedHead to false
2323

24-
HEAD is now at 377d5b3... update changelog
24+
HEAD is now at 5b35045... update changelog
2525
=== ./immutable/hash_tar (tar) ===
26-
Downloaded tarball from 'https://github.com/ros-infrastructure/vcs2l/archive/377d5b3d03c212f015cc832fdb368f4534d0d583.tar.gz' and unpacked it
26+
Downloaded tarball from 'file:///vcstmp/archive.tar.gz' and unpacked it
2727
=== ./immutable/hash_zip (zip) ===
28-
Downloaded zipfile from 'https://github.com/ros-infrastructure/vcs2l/archive/377d5b3d03c212f015cc832fdb368f4534d0d583.zip' and unpacked it
28+
Downloaded zipfile from 'file:///vcstmp/archive.zip' and unpacked it
2929
=== ./immutable/tag (git) ===
3030
Initialized empty Git repository in ./immutable/tag/.git/
3131

32-
From https://github.com/ros-infrastructure/vcs2l
32+
From file:///vcstmp/gitrepo
3333
* [new tag] 0.1.27 -> 0.1.27
3434
Note: switching to 'tags/0.1.27'.
3535

@@ -48,7 +48,7 @@ Or undo this operation with:
4848

4949
Turn off this advice by setting config variable advice.detachedHead to false
5050

51-
HEAD is now at bf9ca56... 0.1.27
51+
HEAD is now at 8087b72... 0.1.27
5252
=== ./vcs2l (git) ===
5353
Cloning into '.'...
5454
=== ./without_version (git) ===

test/list.repos

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)