Show More
@@ -27,6 +27,7 b' from IPython.utils.path import compress_user' | |||||
27 | from IPython.utils.py3compat import decode |
|
27 | from IPython.utils.py3compat import decode | |
28 | from IPython.utils.sysinfo import get_sys_info |
|
28 | from IPython.utils.sysinfo import get_sys_info | |
29 | from IPython.utils.tempdir import TemporaryDirectory |
|
29 | from IPython.utils.tempdir import TemporaryDirectory | |
|
30 | from pathlib import Path | |||
30 |
|
31 | |||
31 | class TestController: |
|
32 | class TestController: | |
32 | """Run tests in a subprocess |
|
33 | """Run tests in a subprocess | |
@@ -138,13 +139,14 b' class PyTestController(TestController):' | |||||
138 | self.env['TMPDIR'] = workingdir.name |
|
139 | self.env['TMPDIR'] = workingdir.name | |
139 |
|
140 | |||
140 | # Add a non-accessible directory to PATH (see gh-7053) |
|
141 | # Add a non-accessible directory to PATH (see gh-7053) | |
141 |
noaccess = |
|
142 | noaccess = Path(self.workingdir.name) / "_no_access_" | |
142 | self.noaccess = noaccess |
|
143 | self.noaccess = noaccess.resolve() | |
143 | os.mkdir(noaccess, 0) |
|
144 | ||
|
145 | noaccess.mkdir(0, exist_ok=True) | |||
144 |
|
146 | |||
145 | PATH = os.environ.get('PATH', '') |
|
147 | PATH = os.environ.get('PATH', '') | |
146 | if PATH: |
|
148 | if PATH: | |
147 |
PATH = noaccess |
|
149 | PATH = noaccess / PATH | |
148 | else: |
|
150 | else: | |
149 | PATH = noaccess |
|
151 | PATH = noaccess | |
150 | self.env['PATH'] = PATH |
|
152 | self.env['PATH'] = PATH | |
@@ -162,7 +164,7 b' class PyTestController(TestController):' | |||||
162 | Make the non-accessible directory created in setup() accessible |
|
164 | Make the non-accessible directory created in setup() accessible | |
163 | again, otherwise deleting the workingdir will fail. |
|
165 | again, otherwise deleting the workingdir will fail. | |
164 | """ |
|
166 | """ | |
165 |
os.chmod( |
|
167 | self.noaccess.chmod(stat.S_IRWXU) | |
166 | TestController.cleanup(self) |
|
168 | TestController.cleanup(self) | |
167 |
|
169 | |||
168 | @property |
|
170 | @property | |
@@ -173,26 +175,26 b' class PyTestController(TestController):' | |||||
173 | return True |
|
175 | return True | |
174 |
|
176 | |||
175 | def add_xunit(self): |
|
177 | def add_xunit(self): | |
176 |
xunit_file = |
|
178 | xunit_file = Path(f"{self.section}.xunit.xml") | |
177 |
self.cmd.extend([ |
|
179 | self.cmd.extend(["--with-xunit", "--xunit-file", xunit_file.absolute()]) | |
178 |
|
180 | |||
179 | def add_coverage(self): |
|
181 | def add_coverage(self): | |
180 | try: |
|
182 | try: | |
181 | sources = test_sections[self.section].includes |
|
183 | sources = test_sections[self.section].includes | |
182 | except KeyError: |
|
184 | except KeyError: | |
183 |
sources = [ |
|
185 | sources = ["IPython"] | |
184 |
|
186 | |||
185 |
coverage_rc = ( |
|
187 | coverage_rc = ( | |
186 |
|
|
188 | "[run]\n" "data_file = {data_file}\n" "source =\n" " {source}\n" | |
187 | "source =\n" |
|
189 | ).format( | |
188 | " {source}\n" |
|
190 | data_file=Path(f".coverage.{self.section}").absolute(), | |
189 | ).format(data_file=os.path.abspath('.coverage.'+self.section), |
|
191 | source="\n ".join(sources), | |
190 | source="\n ".join(sources)) |
|
192 | ) | |
191 |
config_file = |
|
193 | config_file = Path(self.workingdir.name) / ".coveragerc" | |
192 | with open(config_file, 'w') as f: |
|
194 | config_file.touch(exist_ok=True) | |
193 |
|
|
195 | config_file.write_text(coverage_rc) | |
194 |
|
196 | |||
195 |
self.env[ |
|
197 | self.env["COVERAGE_PROCESS_START"] = config_file.resolve() | |
196 | self.pycmd = "import coverage; coverage.process_startup(); " + self.pycmd |
|
198 | self.pycmd = "import coverage; coverage.process_startup(); " + self.pycmd | |
197 |
|
199 | |||
198 | def launch(self, buffer_output=False): |
|
200 | def launch(self, buffer_output=False): | |
@@ -464,10 +466,10 b' def main():' | |||||
464 | # iptest doesn't work correctly if the working directory is the |
|
466 | # iptest doesn't work correctly if the working directory is the | |
465 | # root of the IPython source tree. Tell the user to avoid |
|
467 | # root of the IPython source tree. Tell the user to avoid | |
466 | # frustration. |
|
468 | # frustration. | |
467 | if os.path.exists(os.path.join(os.getcwd(), |
|
469 | main_file = Path.cwd() / Path("IPython/testing/__main__.py") | |
468 | 'IPython', 'testing', '__main__.py')): |
|
470 | ||
469 | print("Don't run iptest from the IPython source directory", |
|
471 | if main_file.exists(): | |
470 | file=sys.stderr) |
|
472 | print("Don't run iptest from the IPython source directory", file=sys.stderr) | |
471 | sys.exit(1) |
|
473 | sys.exit(1) | |
472 | # Arguments after -- should be passed through to nose. Argparse treats |
|
474 | # Arguments after -- should be passed through to nose. Argparse treats | |
473 | # everything after -- as regular positional arguments, so we separate them |
|
475 | # everything after -- as regular positional arguments, so we separate them |
General Comments 0
You need to be logged in to leave comments.
Login now