Skip to content

Commit a9d384d

Browse files
committed
[update-checkout] Add a simple mock update-checkout test that makes sure that we can clone.
This commit is not meant to completely test update-checkout, but rather create some scaffolding for testing update-checkout so we can create starter bugs to fill out the rest of the functionality. Once we have enough testing in place, we can start refactoring/simplifying update-checkout. Design ------ This is just a standard python unittest test suite except that the tests expect an environment variable (UPDATECHECKOUT_TEST_WORKSPACE_DIR) to be set that specifies the directory that the unittests have for creating mock git repos during setup/teardown. lit invokes the test by calling the unittests with the environment variable set to the appropriate temporary directory. In this temporary directory, each test creates a pristine set of "fake" remote repos and a test-config.json file that can be passed to update-checkout to work with these "fake" remote repos. This allows each test that we write to test various update-checkout functionalities against a pristime set of git repos. I choose the git clone test, just b/c it was really simple. NOTE: One can also run the tests locally using the script test_update_checkout.sh that uses /tmp/workspace as the workspace directory.
1 parent e8ad320 commit a9d384d

File tree

4 files changed

+202
-9
lines changed

4 files changed

+202
-9
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6+
7+
# If the user did not specify a workspace dir, create one in /tmp/workspace and
8+
# export it for the tests.
9+
if [[ -n "${1}" ]]; then
10+
export UPDATECHECKOUT_TEST_WORKSPACE_DIR="${1}"
11+
echo "Using ${UPDATECHECKOUT_TEST_WORKSPACE_DIR}"
12+
else
13+
export UPDATECHECKOUT_TEST_WORKSPACE_DIR=/tmp/workspace
14+
echo "No preset workspace dir! Using ${UPDATECHECKOUT_TEST_WORKSPACE_DIR}"
15+
fi
16+
17+
python -m unittest discover -s $DIR
18+
19+
set +e
20+
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# ===--- SchemeMock.py ----------------------------------------------------===#
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See https:#swift.org/LICENSE.txt for license information
9+
# See https:#swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# ===----------------------------------------------------------------------===#
12+
"""This file defines objects for mocking an update-checkout scheme. It creates
13+
a json .config file and a series of .git repos with "fake commits".
14+
"""
15+
16+
import json
17+
import os
18+
import subprocess
19+
import unittest
20+
21+
# For now we only use a config with a single scheme. We should add support for
22+
# handling multiple schemes.
23+
MOCK_REMOTE = {
24+
'repo1': [
25+
# This is a series of changes to repo1. (File, NewContents)
26+
('A.txt', 'A'),
27+
('B.txt', 'B'),
28+
('A.txt', 'a'),
29+
],
30+
'repo2': [
31+
# This is a series of changes to repo1. (File, NewContents)
32+
('X.txt', 'X'),
33+
('Y.txt', 'Y'),
34+
('X.txt', 'z'),
35+
],
36+
}
37+
38+
MOCK_CONFIG = {
39+
# We reset this value with our remote path when we process
40+
'https-clone-pattern': '',
41+
'repos': {
42+
'repo1': {
43+
'remote': {'id': 'repo1'},
44+
},
45+
'repo2': {
46+
'remote': {'id': 'repo2'},
47+
},
48+
},
49+
'default-branch-scheme': 'master',
50+
'branch-schemes': {
51+
'master': {
52+
'aliases': ['master'],
53+
'repos': {
54+
'repo1': 'master',
55+
'repo2': 'master',
56+
}
57+
}
58+
}
59+
}
60+
61+
62+
def call_quietly(*args, **kwargs):
63+
with open(os.devnull, 'w') as f:
64+
kwargs['stdout'] = f
65+
kwargs['stderr'] = f
66+
subprocess.check_call(*args, **kwargs)
67+
68+
69+
def create_dir(d):
70+
if not os.path.isdir(d):
71+
os.makedirs(d)
72+
73+
74+
def teardown_mock_remote(base_dir):
75+
call_quietly(['rm', '-rf', base_dir])
76+
77+
78+
def get_config_path(base_dir):
79+
return os.path.join(base_dir, 'test-config.json')
80+
81+
82+
def setup_mock_remote(base_dir):
83+
create_dir(base_dir)
84+
85+
# We use local as a workspace for creating commits.
86+
LOCAL_PATH = os.path.join(base_dir, 'local')
87+
# We use remote as a directory that simulates our remote unchecked out
88+
# repo.
89+
REMOTE_PATH = os.path.join(base_dir, 'remote')
90+
91+
create_dir(REMOTE_PATH)
92+
create_dir(LOCAL_PATH)
93+
94+
for (k, v) in MOCK_REMOTE.items():
95+
local_repo_path = os.path.join(LOCAL_PATH, k)
96+
remote_repo_path = os.path.join(REMOTE_PATH, k)
97+
create_dir(remote_repo_path)
98+
create_dir(local_repo_path)
99+
call_quietly(['git', 'init', '--bare', remote_repo_path])
100+
call_quietly(['git', 'clone', '-l', remote_repo_path, local_repo_path])
101+
for (i, (filename, contents)) in enumerate(v):
102+
filename_path = os.path.join(local_repo_path, filename)
103+
with open(filename_path, 'w') as f:
104+
f.write(contents)
105+
call_quietly(['git', 'add', filename], cwd=local_repo_path)
106+
call_quietly(['git', 'commit', '-m', 'Commit %d' % i],
107+
cwd=local_repo_path)
108+
call_quietly(['git', 'push', 'origin', 'master'],
109+
cwd=local_repo_path)
110+
111+
base_config = MOCK_CONFIG
112+
https_clone_pattern = os.path.join('file://%s' % REMOTE_PATH, '%s')
113+
base_config['https-clone-pattern'] = https_clone_pattern
114+
115+
with open(get_config_path(base_dir), 'w') as f:
116+
json.dump(base_config, f)
117+
118+
119+
BASEDIR_ENV_VAR = 'UPDATECHECKOUT_TEST_WORKSPACE_DIR'
120+
CURRENT_FILE_DIR = os.path.dirname(os.path.abspath(__file__))
121+
UPDATE_CHECKOUT_PATH = os.path.abspath(os.path.join(CURRENT_FILE_DIR,
122+
os.path.pardir,
123+
os.path.pardir,
124+
'update-checkout'))
125+
126+
127+
class SchemeMockTestCase(unittest.TestCase):
128+
129+
def __init__(self, *args, **kwargs):
130+
super(SchemeMockTestCase, self).__init__(*args, **kwargs)
131+
132+
self.workspace = os.getenv(BASEDIR_ENV_VAR)
133+
if self.workspace is None:
134+
raise RuntimeError('Misconfigured test suite! Environment '
135+
'variable %s must be set!' % BASEDIR_ENV_VAR)
136+
self.config_path = get_config_path(self.workspace)
137+
self.update_checkout_path = UPDATE_CHECKOUT_PATH
138+
if not os.access(self.update_checkout_path, os.X_OK):
139+
raise RuntimeError('Error! Could not find executable '
140+
'update-checkout at path: %s'
141+
% self.update_checkout_path)
142+
self.source_root = os.path.join(self.workspace, 'source_root')
143+
144+
def setUp(self):
145+
create_dir(self.source_root)
146+
setup_mock_remote(self.workspace)
147+
148+
def tearDown(self):
149+
teardown_mock_remote(self.workspace)
150+
151+
def call(self, *args, **kwargs):
152+
kwargs['cwd'] = self.source_root
153+
call_quietly(*args, **kwargs)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# ===--- test_clone.py ----------------------------------------------------===#
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See https:#swift.org/LICENSE.txt for license information
9+
# See https:#swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# ===----------------------------------------------------------------------===#
12+
13+
import scheme_mock
14+
15+
16+
class CloneTestCase(scheme_mock.SchemeMockTestCase):
17+
18+
def __init__(self, *args, **kwargs):
19+
super(CloneTestCase, self).__init__(*args, **kwargs)
20+
21+
def test_simple_clone(self):
22+
self.call([self.update_checkout_path,
23+
'--config', self.config_path,
24+
'--source-root', self.source_root,
25+
'--clone'])
Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
# RUN: %{python} -m unittest discover -s %swift_src_root/utils/update_checkout
1+
# RUN: %empty-directory(%t)
2+
# RUN: %swift_src_root/utils/update_checkout/test_update_checkout.sh %t
23

3-
# Do not run this when doing simulator or device testing on darwin.
4-
#
5-
# Otherwise, we are running these unittests multiple times without providing
6-
# value. We want to still run this on linux though.
7-
#
8-
# UNSUPPORTED: OS=ios
9-
# UNSUPPORTED: OS=watchos
10-
# UNSUPPORTED: OS=tvos
4+
# For now, only run this on macosx.
5+
# REQUIRES: OS=macosx

0 commit comments

Comments
 (0)