Skip to content

Commit 5d78296

Browse files
author
Jon Wayne Parrott
committed
Making nox skip unchanged samples. (#327)
1 parent c69d2b2 commit 5d78296

File tree

1 file changed

+100
-58
lines changed

1 file changed

+100
-58
lines changed

nox.py

Lines changed: 100 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import fnmatch
1616
import os
17+
import subprocess
1718
import tempfile
1819

1920
import nox
@@ -26,17 +27,8 @@
2627
'.coveragerc', '--cov-append', '--cov-report=']
2728

2829
# Speech is temporarily disabled.
29-
SESSION_TESTS_BLACKLIST = set(('appengine', 'testing', 'speech'))
30-
31-
32-
def session_lint(session):
33-
session.install('flake8', 'flake8-import-order')
34-
session.run(
35-
'flake8', '--builtin=gettext', '--max-complexity=10',
36-
'--import-order-style=google',
37-
'--exclude',
38-
'container_engine/django_tutorial/polls/migrations/*,.nox,.cache,env',
39-
*(session.posargs or ['.']))
30+
TESTS_BLACKLIST = set(('appengine', 'testing', 'speech'))
31+
APPENGINE_BLACKLIST = set()
4032

4133

4234
def list_files(folder, pattern):
@@ -46,18 +38,6 @@ def list_files(folder, pattern):
4638
yield os.path.join(root, filename)
4739

4840

49-
def session_reqcheck(session):
50-
session.install(REPO_TOOLS_REQ)
51-
52-
if 'update' in session.posargs:
53-
command = 'update-requirements'
54-
else:
55-
command = 'check-requirements'
56-
57-
for reqfile in list_files('.', 'requirements*.txt'):
58-
session.run('gcprepotools', command, reqfile)
59-
60-
6141
def collect_sample_dirs(start_dir, blacklist=set()):
6242
"""Recursively collects a list of dirs that contain tests."""
6343
# Collect all the directories that have tests in them.
@@ -73,37 +53,37 @@ def collect_sample_dirs(start_dir, blacklist=set()):
7353
if s[0].isalpha() and s not in blacklist]
7454

7555

76-
@nox.parametrize('interpreter', ['python2.7', 'python3.4'])
77-
def session_tests(session, interpreter, extra_pytest_args=None):
78-
session.interpreter = interpreter
79-
session.install(REPO_TOOLS_REQ)
80-
session.install('-r', 'requirements-{}-dev.txt'.format(interpreter))
56+
def get_changed_files():
57+
pr = os.environ.get('TRAVIS_PULL_REQUEST')
58+
if pr == 'false':
59+
# This is not a pull request.
60+
changed = subprocess.check_output(
61+
['git', 'show', '--pretty=format:', '--name-only',
62+
os.environ.get('TRAVIS_COMMIT_RANGE')])
63+
elif pr is not None:
64+
changed = subprocess.check_output(
65+
['git', 'diff', '--name-only',
66+
os.environ.get('TRAVIS_COMMIT'),
67+
os.environ.get('TRAVIS_BRANCH')])
68+
else:
69+
changed = ''
70+
print('Uh... where are we?')
71+
return set([x for x in changed.split('\n') if x])
8172

82-
# extra_pytest_args can be send by another session calling this session,
83-
# see session_travis.
84-
pytest_args = COMMON_PYTEST_ARGS + (extra_pytest_args or [])
8573

86-
# session.posargs is any leftover arguments from the command line, which
87-
# allows users to run a particular test instead of all of them.
88-
for sample in (session.posargs or
89-
collect_sample_dirs('.', SESSION_TESTS_BLACKLIST)):
74+
def filter_samples(sample_dirs, changed_files):
75+
result = []
76+
for sample_dir in sample_dirs:
77+
if sample_dir.startswith('./'):
78+
sample_dir = sample_dir[2:]
79+
for changed_file in changed_files:
80+
if changed_file.startswith(sample_dir):
81+
result.append(sample_dir)
9082

91-
# Install additional dependencies if they exist
92-
dirname = sample if os.path.isdir(sample) else os.path.dirname(sample)
93-
for reqfile in list_files(dirname, 'requirements*.txt'):
94-
session.install('-r', reqfile)
83+
return result
9584

96-
session.run(
97-
'py.test', sample,
98-
*pytest_args,
99-
success_codes=[0, 5]) # Treat no test collected as success.
100-
101-
102-
def session_gae(session, extra_pytest_args=None):
103-
session.interpreter = 'python2.7'
104-
session.install(REPO_TOOLS_REQ)
105-
session.install('-r', 'requirements-python2.7-dev.txt')
10685

86+
def setup_appengine(session):
10787
# Install the app engine sdk and setup import paths.
10888
gae_root = os.environ.get('GAE_ROOT', tempfile.gettempdir())
10989
session.env['PYTHONPATH'] = os.path.join(gae_root, 'google_appengine')
@@ -114,10 +94,42 @@ def session_gae(session, extra_pytest_args=None):
11494
if not os.path.exists('lib'):
11595
os.makedirs('lib')
11696

117-
pytest_args = COMMON_PYTEST_ARGS + (extra_pytest_args or [])
11897

119-
for sample in (session.posargs or collect_sample_dirs('appengine')):
98+
def run_tests_in_sesssion(
99+
session, interpreter, use_appengine=False, skip_flaky=False,
100+
changed_only=False):
101+
session.interpreter = interpreter
102+
session.install(REPO_TOOLS_REQ)
103+
session.install('-r', 'requirements-{}-dev.txt'.format(interpreter))
104+
105+
if use_appengine:
106+
setup_appengine(session)
107+
sample_root = 'appengine'
108+
else:
109+
sample_root = '.'
110+
111+
pytest_args = COMMON_PYTEST_ARGS[:]
112+
113+
if skip_flaky:
114+
pytest_args.append('-m not slow and not flaky')
120115

116+
# session.posargs is any leftover arguments from the command line, which
117+
# allows users to run a particular test instead of all of them.
118+
if session.posargs:
119+
sample_directories = session.posargs
120+
else:
121+
sample_directories = collect_sample_dirs(
122+
sample_root,
123+
TESTS_BLACKLIST if not use_appengine else APPENGINE_BLACKLIST)
124+
125+
if changed_only:
126+
changed_files = get_changed_files()
127+
sample_directories = filter_samples(
128+
sample_directories, changed_files)
129+
print('Running tests on a subset of samples: ')
130+
print('\n'.join(sample_directories))
131+
132+
for sample in sample_directories:
121133
# Install additional dependencies if they exist
122134
dirname = sample if os.path.isdir(sample) else os.path.dirname(sample)
123135
for reqfile in list_files(dirname, 'requirements*.txt'):
@@ -129,15 +141,45 @@ def session_gae(session, extra_pytest_args=None):
129141
success_codes=[0, 5]) # Treat no test collected as success.
130142

131143

144+
@nox.parametrize('interpreter', ['python2.7', 'python3.4'])
145+
def session_tests(session, interpreter):
146+
run_tests_in_sesssion(session, interpreter)
147+
148+
149+
def session_gae(session):
150+
run_tests_in_sesssion(
151+
session, 'python2.7', use_appengine=True)
152+
153+
132154
@nox.parametrize('subsession', ['gae', 'tests'])
133155
def session_travis(session, subsession):
134156
"""On travis, just run with python3.4 and don't run slow or flaky tests."""
135157
if subsession == 'tests':
136-
session_tests(
137-
session,
138-
'python3.4',
139-
extra_pytest_args=['-m not slow and not flaky'])
158+
run_tests_in_sesssion(
159+
session, 'python3.4', skip_flaky=True, changed_only=True)
160+
else:
161+
run_tests_in_sesssion(
162+
session, 'python2.7', use_appengine=True, skip_flaky=True,
163+
changed_only=True)
164+
165+
166+
def session_lint(session):
167+
session.install('flake8', 'flake8-import-order')
168+
session.run(
169+
'flake8', '--builtin=gettext', '--max-complexity=10',
170+
'--import-order-style=google',
171+
'--exclude',
172+
'container_engine/django_tutorial/polls/migrations/*,.nox,.cache,env',
173+
*(session.posargs or ['.']))
174+
175+
176+
def session_reqcheck(session):
177+
session.install(REPO_TOOLS_REQ)
178+
179+
if 'update' in session.posargs:
180+
command = 'update-requirements'
140181
else:
141-
session_gae(
142-
session,
143-
extra_pytest_args=['-m not slow and not flaky'])
182+
command = 'check-requirements'
183+
184+
for reqfile in list_files('.', 'requirements*.txt'):
185+
session.run('gcprepotools', command, reqfile)

0 commit comments

Comments
 (0)