14
14
15
15
import fnmatch
16
16
import os
17
+ import subprocess
17
18
import tempfile
18
19
19
20
import nox
26
27
'.coveragerc' , '--cov-append' , '--cov-report=' ]
27
28
28
29
# 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 ()
40
32
41
33
42
34
def list_files (folder , pattern ):
@@ -46,18 +38,6 @@ def list_files(folder, pattern):
46
38
yield os .path .join (root , filename )
47
39
48
40
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
-
61
41
def collect_sample_dirs (start_dir , blacklist = set ()):
62
42
"""Recursively collects a list of dirs that contain tests."""
63
43
# Collect all the directories that have tests in them.
@@ -73,37 +53,37 @@ def collect_sample_dirs(start_dir, blacklist=set()):
73
53
if s [0 ].isalpha () and s not in blacklist ]
74
54
75
55
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 ])
81
72
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 [])
85
73
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 )
90
82
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
95
84
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' )
106
85
86
+ def setup_appengine (session ):
107
87
# Install the app engine sdk and setup import paths.
108
88
gae_root = os .environ .get ('GAE_ROOT' , tempfile .gettempdir ())
109
89
session .env ['PYTHONPATH' ] = os .path .join (gae_root , 'google_appengine' )
@@ -114,10 +94,42 @@ def session_gae(session, extra_pytest_args=None):
114
94
if not os .path .exists ('lib' ):
115
95
os .makedirs ('lib' )
116
96
117
- pytest_args = COMMON_PYTEST_ARGS + (extra_pytest_args or [])
118
97
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' )
120
115
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 :
121
133
# Install additional dependencies if they exist
122
134
dirname = sample if os .path .isdir (sample ) else os .path .dirname (sample )
123
135
for reqfile in list_files (dirname , 'requirements*.txt' ):
@@ -129,15 +141,45 @@ def session_gae(session, extra_pytest_args=None):
129
141
success_codes = [0 , 5 ]) # Treat no test collected as success.
130
142
131
143
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
+
132
154
@nox .parametrize ('subsession' , ['gae' , 'tests' ])
133
155
def session_travis (session , subsession ):
134
156
"""On travis, just run with python3.4 and don't run slow or flaky tests."""
135
157
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'
140
181
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