Problem with failing test while django's unittests and using --parallel
jedie opened this issue · comments
I didn't use pytest. Just normal unittests and Django's test runner, that implement --parallel
that used multiprocessing.pool.Pool
...
On CannotOverwriteExistingCassetteException
errors i get "cannot pickle" error like:
test_change_product_categories (FooBarTestCase) failed:
CannotOverwriteExistingCassetteException("Can't overwrite existing
cassette (PosixPath('.../foobar.vcr.yaml')) in your
current record mode ('none').\nNo match for the request (<Request
(POST) https://api.foobar.com/b2c_local/graphql>) was
found.\nNo similar requests, that have not been played, found.")
Unfortunately, the exception it raised cannot be pickled, making it impossible
for the parallel test runner to handle it cleanly.
Here's the error encountered while trying to pickle the exception:
TypeError("cannot pickle 'module' object")
You should re-run this test with the --parallel=1 option to reproduce the
failure and get a correct traceback.
I get a normal traceback running the tests without --parallel
;)
Think CannotOverwriteExistingCassetteException
can't be pickle, isn't it?
Version info:
- Python 3.10
- VCR.py v4.3.1
- Django v4.1.9
No, tblib v1.7.0 is already installed ;)
@jedie did you see my reply at #711 (comment) ?
I had another look just now, starting with an empty Django project, adding two simple VCR.py tests and using record_mode=RecordMode.NONE
as seen in the error output above. Also I checked the documentation of record mode "none". My current impression is that:
- Record mode
none
was supposed to throw an exception on new requests as documented. - Record mode
none
controls propertyCassette.write_protected
. - Exception
CannotOverwriteExistingCassetteException
may be misleading because there is no cassette file at that moment. Could potentially be improved, but a change like that may be considered a break in API. - Use of
./manage.py test --parallel=2
did not get me the errors that @jedie mentioned above, so I cannot reproduce it.
If someone would like to reproduce what I did, it's this:
# cd "$(mktemp -d)"
# python3.10 -m venv venv
# source venv/bin/activate
# pip3 install vcrpy django
# django-admin startproject issue711
# cat issue711/issue711/test_issue711.py # hand-made file
from unittest import TestCase
import urllib.request
from vcr import VCR
from vcr.record_mode import RecordMode
class TestOneTwo(TestCase):
def test_record__none__one(self):
with VCR(record_mode=RecordMode.NONE).use_cassette('one.yaml'):
response = urllib.request.urlopen('http://www.iana.org/domains/reserved').read()
assert b'Example domains' in response
def test_record__none__two(self):
with VCR(record_mode=RecordMode.NONE).use_cassette('two.yaml'):
response = urllib.request.urlopen('http://www.iana.org/domains/reserved').read()
assert b'Example domains' in response
# ( cd issue711/ && ./manage.py test --parallel=2 -v2 )
Found 2 test(s).
Skipping setup of unused database(s): default.
System check identified no issues (0 silenced).
test_record__none__one (issue711.test_issue711.TestOneTwo) ... ERROR
test_record__none__two (issue711.test_issue711.TestOneTwo) ... ERROR
======================================================================
ERROR: test_record__none__one (issue711.test_issue711.TestOneTwo)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/tmp.vt6waYAV1L/issue711/issue711/test_issue711.py", line 11, in test_record__none__one
response = urllib.request.urlopen('http://www.iana.org/domains/reserved').read()
File "/usr/lib/python3.10/urllib/request.py", line 216, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib/python3.10/urllib/request.py", line 519, in open
response = self._open(req, data)
File "/usr/lib/python3.10/urllib/request.py", line 536, in _open
result = self._call_chain(self.handle_open, protocol, protocol +
File "/usr/lib/python3.10/urllib/request.py", line 496, in _call_chain
result = func(*args)
File "/usr/lib/python3.10/urllib/request.py", line 1377, in http_open
return self.do_open(http.client.HTTPConnection, req)
File "/usr/lib/python3.10/urllib/request.py", line 1352, in do_open
r = h.getresponse()
File "/tmp/tmp.vt6waYAV1L/venv/lib/python3.10/site-packages/vcr/stubs/__init__.py", line 253, in getresponse
raise CannotOverwriteExistingCassetteException(
vcr.errors.CannotOverwriteExistingCassetteException: Can't overwrite existing cassette ('one.yaml') in your current record mode (<RecordMode.NONE: 'none'>).
No match for the request (<Request (GET) http://www.iana.org/domains/reserved>) was found.
No similar requests, that have not been played, found.
======================================================================
ERROR: test_record__none__two (issue711.test_issue711.TestOneTwo)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/tmp.vt6waYAV1L/issue711/issue711/test_issue711.py", line 16, in test_record__none__two
response = urllib.request.urlopen('http://www.iana.org/domains/reserved').read()
File "/usr/lib/python3.10/urllib/request.py", line 216, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib/python3.10/urllib/request.py", line 519, in open
response = self._open(req, data)
File "/usr/lib/python3.10/urllib/request.py", line 536, in _open
result = self._call_chain(self.handle_open, protocol, protocol +
File "/usr/lib/python3.10/urllib/request.py", line 496, in _call_chain
result = func(*args)
File "/usr/lib/python3.10/urllib/request.py", line 1377, in http_open
return self.do_open(http.client.HTTPConnection, req)
File "/usr/lib/python3.10/urllib/request.py", line 1352, in do_open
r = h.getresponse()
File "/tmp/tmp.vt6waYAV1L/venv/lib/python3.10/site-packages/vcr/stubs/__init__.py", line 253, in getresponse
raise CannotOverwriteExistingCassetteException(
vcr.errors.CannotOverwriteExistingCassetteException: Can't overwrite existing cassette ('two.yaml') in your current record mode (<RecordMode.NONE: 'none'>).
No match for the request (<Request (GET) http://www.iana.org/domains/reserved>) was found.
No similar requests, that have not been played, found.
----------------------------------------------------------------------
Ran 2 tests in 0.008s
FAILED (errors=2)
Unless someone else posts something producible, I'll close this issue as "cannot reproduce" in a few days.
@jedie please note that in general detail level and a reproducer like this will be expected for future bug reports to VCR.py if any. Thanks!
Closing for lack of a reply and minimal reproducer. Happy to re-open if someone can provide a minimal reproducer. Closing…