1414
1515import fnmatch
1616import os
17+ import subprocess
1718import tempfile
1819
1920import nox
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
4234def 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-
6141def 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' ])
133155def 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