Skip to content

Commit 83465f6

Browse files
Fix MS-Windows specific failures in test suite. (#688)
Hi, could you please review changes to fix the test suite to pass on MS-Windows. It fixes #687. It also enables the test suite which includes MS-Windows support to pass in #686. In addition to the document changes, the patch also - Releases file/dir before removing (monkeypatch.chdir, os/close). MS-Windows will complain about trying to remove a file that is still being used otherwise. - Add empty server to file: uri (i.e. file:///), since paths such as c:\dev, will pickup c: as the server causing the tests to fail. - Just looks for the file name in traceback texts (e.g. *test_testrunner.lpy instead of /*/test_testrunner.lpy), otherwise it will fail because the output string will be c:\*\test_testrunner.lpy on windows. The test suite currently fails to run because package dependencies have moved since it was last run. Perhaps is best to merge this after #686. Thanks --------- Co-authored-by: ikappaki <[email protected]> Co-authored-by: Chris Rink <[email protected]>
1 parent 7a0aea6 commit 83465f6

File tree

7 files changed

+58
-14
lines changed

7 files changed

+58
-14
lines changed

.github/workflows/run-tests.yml

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ concurrency:
1212

1313
jobs:
1414
run-tests:
15-
runs-on: ubuntu-latest
15+
runs-on: ${{matrix.os}}
1616
strategy:
1717
matrix:
18+
os: [ubuntu-latest]
1819
version: ['3.8', '3.9', '3.10', '3.11']
1920
include:
2021
- version: '3.8'
@@ -25,6 +26,12 @@ jobs:
2526
tox-env: py310,py310-mypy,py310-lint,safety
2627
- version: '3.11'
2728
tox-env: py311,py311-mypy,py311-lint,format,safety
29+
- os: windows-latest
30+
version: '3.11'
31+
tox-env: py311,safety
32+
- os: macos-latest
33+
version: '3.11'
34+
tox-env: py311,safety
2835
steps:
2936
- uses: actions/checkout@v3
3037
- uses: actions/setup-python@v4
@@ -41,8 +48,13 @@ jobs:
4148
~/.local/share/pypoetry
4249
key: ${{ runner.os }}-python-${{ matrix.version }}-poetry-${{ hashFiles('pyproject.toml', 'tox.ini') }}
4350
- name: Install Poetry
44-
if: steps.cache-deps.outputs.cache-hit != 'true'
51+
if: steps.cache-deps.outputs.cache-hit != 'true' && ! startsWith (matrix.os, 'windows')
4552
run: curl -sSL https://install.python-poetry.org | python3 -
53+
- name: Install Poetry (Windows)
54+
if: steps.cache-deps.outputs.cache-hit != 'true' && startsWith (matrix.os, 'windows')
55+
shell: pwsh
56+
run: |
57+
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -
4658
- name: Install Tox
4759
run: |
4860
pip install -U pip
@@ -57,6 +69,7 @@ jobs:
5769
mkdir coverage
5870
mv .coverage.* "coverage/.coverage.py${{ matrix.version }}"
5971
- name: Archive code coverage results
72+
if: "startsWith (matrix.os, 'ubuntu')"
6073
uses: actions/upload-artifact@v3
6174
with:
6275
name: code-coverage
@@ -98,4 +111,4 @@ jobs:
98111
- name: Report Combined Coverage
99112
uses: coverallsapp/github-action@v2
100113
with:
101-
file: coverage.xml
114+
file: coverage.xml

src/basilisp/io.lpy

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
interacting with the filesystem."
77
(:import
88
io
9+
os.path
910
pathlib
1011
shutil
1112
urllib.parse
@@ -31,7 +32,13 @@
3132
urllib.parse/ParseResult
3233
(as-path [f]
3334
(if (contains? #{"file" ""} (.-scheme f))
34-
(-> (.-path f) (pathlib/Path))
35+
(let [path (.-path f)]
36+
(if (= sys/platform "win32")
37+
;; On MS-Windows, extracting the path from the URL
38+
;; incorrectly adds a leading `/', .e.g. /C:\xyz.
39+
(pathlib/Path (subs path 1))
40+
41+
(pathlib/Path path)))
3542
(throw
3643
(ex-info "Cannot coerce non-File URL to pathlib.Path"
3744
{:file f})))))
@@ -121,6 +128,18 @@
121128

122129
Callers should generally prefer :lpy:fn:`output-stream` to this function."))
123130

131+
(defn- convert-to-path-or-url [f-str]
132+
"Convert ``f-str`` to a python Path or URL object based on to
133+
whether it represents an absolute path or not, respectively.
134+
135+
This fn is intended to be used with the input and output
136+
writers. Converting MS-Windows absolutely paths (such as c:\\xyz and
137+
\\\\share\\xyz) directly to URLs are likely to confuse the urllib
138+
parser. As such, they are converted to Path objects instead."
139+
(if (os.path/isabs f-str)
140+
(pathlib/Path f-str)
141+
(urllib.parse/urlparse f-str)))
142+
124143
(extend-protocol IOFactory
125144
io/TextIOBase
126145
(make-reader [f opts]
@@ -191,22 +210,22 @@
191210
python/str
192211
(make-reader [f opts]
193212
(try
194-
(make-reader (urllib.parse/urlparse f) opts)
213+
(make-reader (convert-to-path-or-url f) opts)
195214
(catch python/ValueError _
196215
(make-reader (pathlib/Path f) opts))))
197216
(make-writer [f opts]
198217
(try
199-
(make-writer (urllib.parse/urlparse f) opts)
218+
(make-writer (convert-to-path-or-url f) opts)
200219
(catch python/ValueError _
201220
(make-writer (pathlib/Path f) opts))))
202221
(make-input-stream [f opts]
203222
(try
204-
(make-input-stream (urllib.parse/urlparse f) opts)
223+
(make-input-stream (convert-to-path-or-url f) opts)
205224
(catch python/ValueError _
206225
(make-input-stream (pathlib/Path f) opts))))
207226
(make-output-stream [f opts]
208227
(try
209-
(make-output-stream (urllib.parse/urlparse f) opts)
228+
(make-output-stream (convert-to-path-or-url f) opts)
210229
(catch python/ValueError _
211230
(make-output-stream (pathlib/Path f) opts))))
212231

tests/basilisp/compiler_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5405,6 +5405,7 @@ def test_aliased_namespace_not_hidden_by_python_module(
54055405
self, lcompile: CompileFn, monkeypatch: MonkeyPatch
54065406
):
54075407
with TemporaryDirectory() as tmpdir:
5408+
cwd = os.getcwd()
54085409
monkeypatch.chdir(tmpdir)
54095410
monkeypatch.syspath_prepend(tmpdir)
54105411
monkeypatch.setattr(
@@ -5432,6 +5433,7 @@ def test_aliased_namespace_not_hidden_by_python_module(
54325433
"""
54335434
)
54345435
finally:
5436+
monkeypatch.chdir(cwd)
54355437
os.unlink(module_file_path)
54365438

54375439
def test_aliased_var_does_not_resolve(

tests/basilisp/importer_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,12 @@ def module_cache(self):
9999
@pytest.fixture
100100
def module_dir(self, monkeypatch: MonkeyPatch, module_cache):
101101
with TemporaryDirectory() as tmpdir:
102+
cwd = os.getcwd()
102103
monkeypatch.chdir(tmpdir)
103104
monkeypatch.syspath_prepend(tmpdir)
104105
monkeypatch.setattr("sys.modules", module_cache)
105106
yield tmpdir
107+
monkeypatch.chdir(cwd)
106108

107109
@pytest.fixture
108110
def make_new_module(self, module_dir):

tests/basilisp/test_core_macros.lpy

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,13 +443,14 @@
443443
(is (= #py ["A" "B" "C"] (.. "a,b,c" upper (split ",")))))
444444

445445
(deftest with-test
446-
(let [[_ filename] (tempfile/mkstemp)]
446+
(let [[fh filename] (tempfile/mkstemp)]
447447
(try
448448
(with-open [file (python/open filename "w")]
449449
(.write file "Testing text"))
450450
(with-open [file (python/open filename)]
451451
(is (= "Testing text" (.read file))))
452452
(finally
453+
(os/close fh)
453454
(os/unlink filename)))))
454455

455456
(deftest if-let-test

tests/basilisp/test_io.lpy

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
pathlib
88
tempfile
99
threading
10+
time
1011
urllib.parse
1112
urllib.request)
1213
(:require
@@ -82,12 +83,12 @@
8283
(try
8384
(spit filename "hi there")
8485
(is (= "hi there" (slurp filename)))
85-
(is (= "hi there" (slurp (str "file://" filename))))
86+
(is (= "hi there" (slurp (str "file:///" filename))))
8687
(finally
8788
(os/close fd)
8889
(os/unlink filename)))))
8990

90-
(testing "local files"
91+
(testing "local files"
9192
(let [path (bio/path *tempdir* "reader-test-local-files.txt")]
9293
(spit path "some content")
9394

@@ -111,6 +112,9 @@
111112
*http-port*
112113
"/reader-http-req.txt"))))
113114
(finally
115+
;; Give a chance to the server to release the
116+
;; file before removing it.
117+
(time/sleep 1)
114118
(os/unlink filename))))))
115119

116120
(deftest writer-test
@@ -196,7 +200,7 @@
196200
(try
197201
(spit-bytes filename "hi there")
198202
(is (= (bytes "hi there") (slurp-bytes filename)))
199-
(is (= (bytes "hi there") (slurp-bytes (str "file://" filename))))
203+
(is (= (bytes "hi there") (slurp-bytes (str "file:///" filename))))
200204
(finally
201205
(os/close fd)
202206
(os/unlink filename)))))
@@ -226,6 +230,9 @@
226230
*http-port*
227231
"/input-streams-http-req.txt"))))
228232
(finally
233+
;; Give a chance to the server to release the
234+
;; file before removing it.
235+
(time/sleep 1)
229236
(os/unlink filename))))))
230237

231238
(deftest output-stream-test

tests/basilisp/testrunner_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def test_error_repr(self, run_result: RunResult):
9494
"ERROR in (assertion-test) (test_testrunner.lpy:12)",
9595
"",
9696
"Traceback (most recent call last):",
97-
' File "/*/test_testrunner.lpy", line 12, in assertion_test',
97+
' File "*test_testrunner.lpy", line 12, in assertion_test',
9898
' (is (throw (ex-info "Uncaught exception" {}))))',
9999
"basilisp.lang.exception.ExceptionInfo: Uncaught exception {}",
100100
]
@@ -118,7 +118,7 @@ def test_error_repr(self, run_result: RunResult):
118118
[
119119
"ERROR in (error-test) (test_testrunner.lpy)",
120120
"Traceback (most recent call last):",
121-
' File "/*/test_testrunner.lpy", line 25, in error_test',
121+
' File "*test_testrunner.lpy", line 25, in error_test',
122122
" (throw",
123123
"basilisp.lang.exception.ExceptionInfo: This test will count as an error. {}",
124124
]

0 commit comments

Comments
 (0)