py-sdl2 icon indicating copy to clipboard operation
py-sdl2 copied to clipboard

ValueError: NULL pointer access while running the test suite

Open mcepl opened this issue 3 years ago • 15 comments

When packaging the package (from tarball 0.9.13 from PyPI) I get these errors when running the test suite:

[   40s] ==================================== ERRORS ====================================
[   40s] ___________________ ERROR at setup of test_Mix_GetMusicType ____________________
[   40s] 
[   40s] with_sdl_mixer = None
[   40s] 
[   40s]     @pytest.fixture
[   40s]     def with_music(with_sdl_mixer):
[   40s]         fpath = _get_sound_path("mp3")
[   40s]         mus = sdlmixer.Mix_LoadMUS(fpath.encode("utf-8"))
[   40s]         err = sdlmixer.Mix_GetError()
[   40s]         sdlmixer.Mix_ClearError()
[   40s] >       assert isinstance(mus.contents, sdlmixer.Mix_Music)
[   40s] E       ValueError: NULL pointer access
[   40s] 
[   40s] sdl2/test/sdlmixer_test.py:58: ValueError
[   40s] ___________________ ERROR at setup of test_Mix_GetMusicTitle ___________________
[   40s] 
[   40s] with_sdl_mixer = None
[   40s] 
[   40s]     @pytest.fixture
[   40s]     def with_music(with_sdl_mixer):
[   40s]         fpath = _get_sound_path("mp3")
[   40s]         mus = sdlmixer.Mix_LoadMUS(fpath.encode("utf-8"))
[   40s]         err = sdlmixer.Mix_GetError()
[   40s]         sdlmixer.Mix_ClearError()
[   40s] >       assert isinstance(mus.contents, sdlmixer.Mix_Music)
[   40s] E       ValueError: NULL pointer access
[   40s] 
[   40s] sdl2/test/sdlmixer_test.py:58: ValueError
[   40s] _________________ ERROR at setup of test_Mix_GetMusicTitleTag __________________
[   40s] 
[   40s] with_sdl_mixer = None
[   40s] 
[   40s]     @pytest.fixture
[   40s]     def with_music(with_sdl_mixer):
[   40s]         fpath = _get_sound_path("mp3")
[   40s]         mus = sdlmixer.Mix_LoadMUS(fpath.encode("utf-8"))
[   40s]         err = sdlmixer.Mix_GetError()
[   40s]         sdlmixer.Mix_ClearError()
[   40s] >       assert isinstance(mus.contents, sdlmixer.Mix_Music)
[   40s] E       ValueError: NULL pointer access
[   40s] 
[   40s] sdl2/test/sdlmixer_test.py:58: ValueError
[   40s] _________________ ERROR at setup of test_Mix_GetMusicArtistTag _________________
[   40s] 
[   40s] with_sdl_mixer = None
[   40s] 
[   40s]     @pytest.fixture
[   40s]     def with_music(with_sdl_mixer):
[   40s]         fpath = _get_sound_path("mp3")
[   40s]         mus = sdlmixer.Mix_LoadMUS(fpath.encode("utf-8"))
[   40s]         err = sdlmixer.Mix_GetError()
[   40s]         sdlmixer.Mix_ClearError()
[   40s] >       assert isinstance(mus.contents, sdlmixer.Mix_Music)
[   40s] E       ValueError: NULL pointer access
[   40s] 
[   40s] sdl2/test/sdlmixer_test.py:58: ValueError
[   40s] _________________ ERROR at setup of test_Mix_GetMusicAlbumTag __________________
[   40s] 
[   40s] with_sdl_mixer = None
[   40s] 
[   40s]     @pytest.fixture
[   40s]     def with_music(with_sdl_mixer):
[   40s]         fpath = _get_sound_path("mp3")
[   40s]         mus = sdlmixer.Mix_LoadMUS(fpath.encode("utf-8"))
[   40s]         err = sdlmixer.Mix_GetError()
[   40s]         sdlmixer.Mix_ClearError()
[   40s] >       assert isinstance(mus.contents, sdlmixer.Mix_Music)
[   40s] E       ValueError: NULL pointer access
[   40s] 
[   40s] sdl2/test/sdlmixer_test.py:58: ValueError
[   40s] _______________ ERROR at setup of test_Mix_GetMusicCopyrightTag ________________
[   40s] 
[   40s] with_sdl_mixer = None
[   40s] 
[   40s]     @pytest.fixture
[   40s]     def with_music(with_sdl_mixer):
[   40s]         fpath = _get_sound_path("mp3")
[   40s]         mus = sdlmixer.Mix_LoadMUS(fpath.encode("utf-8"))
[   40s]         err = sdlmixer.Mix_GetError()
[   40s]         sdlmixer.Mix_ClearError()
[   40s] >       assert isinstance(mus.contents, sdlmixer.Mix_Music)
[   40s] E       ValueError: NULL pointer access
[   40s] 
[   40s] sdl2/test/sdlmixer_test.py:58: ValueError
[   40s] ___________________ ERROR at setup of test_Mix_MusicDuration ___________________
[   40s] 
[   40s] with_sdl_mixer = None
[   40s] 
[   40s]     @pytest.fixture
[   40s]     def with_music(with_sdl_mixer):
[   40s]         fpath = _get_sound_path("mp3")
[   40s]         mus = sdlmixer.Mix_LoadMUS(fpath.encode("utf-8"))
[   40s]         err = sdlmixer.Mix_GetError()
[   40s]         sdlmixer.Mix_ClearError()
[   40s] >       assert isinstance(mus.contents, sdlmixer.Mix_Music)
[   40s] E       ValueError: NULL pointer access
[   40s] 
[   40s] sdl2/test/sdlmixer_test.py:58: ValueError
[   40s] =================================== FAILURES ===================================
[   40s] _____________________________ test_Mix_LoadFreeWAV _____________________________
[   40s] 
[   40s] with_sdl_mixer = None
[   40s] 
[   40s]     def test_Mix_LoadFreeWAV(with_sdl_mixer):
[   40s]         fpath = _get_sound_path("mp3")
[   40s]         chk = sdlmixer.Mix_LoadWAV(fpath.encode("utf-8"))
[   40s] >       assert isinstance(chk.contents, sdlmixer.Mix_Chunk)
[   40s] E       ValueError: NULL pointer access
[   40s] 
[   40s] sdl2/test/sdlmixer_test.py:145: ValueError
[   40s] _____________________________ test_Mix_LoadWAV_RW ______________________________
[   40s] 
[   40s] with_sdl_mixer = None
[   40s] 
[   40s]     def test_Mix_LoadWAV_RW(with_sdl_mixer):
[   40s]         fpath = _get_sound_path("mp3")
[   40s]         rw = sdl2.SDL_RWFromFile(fpath.encode("utf-8"), b"r")
[   40s]         chk = sdlmixer.Mix_LoadWAV_RW(rw, 1)
[   40s] >       assert isinstance(chk.contents, sdlmixer.Mix_Chunk)
[   40s] E       ValueError: NULL pointer access
[   40s] 
[   40s] sdl2/test/sdlmixer_test.py:153: ValueError
[   40s] _____________________________ test_Mix_LoadFreeMUS _____________________________
[   40s] 
[   40s] with_sdl_mixer = None
[   40s] 
[   40s]     def test_Mix_LoadFreeMUS(with_sdl_mixer):
[   40s]         fpath = _get_sound_path("mp3")
[   40s]         mus = sdlmixer.Mix_LoadMUS(fpath.encode("utf-8"))
[   40s] >       assert isinstance(mus.contents, sdlmixer.Mix_Music)
[   40s] E       ValueError: NULL pointer access
[   40s] 
[   40s] sdl2/test/sdlmixer_test.py:160: ValueError
[   40s] _____________________________ test_Mix_LoadMUS_RW ______________________________
[   40s] 
[   40s] with_sdl_mixer = None
[   40s] 
[   40s]     def test_Mix_LoadMUS_RW(with_sdl_mixer):
[   40s]         fpath = _get_sound_path("mp3")
[   40s]         rw = sdl2.SDL_RWFromFile(fpath.encode("utf-8"), b"r")
[   40s]         mus = sdlmixer.Mix_LoadMUS_RW(rw, 1)
[   40s] >       assert isinstance(mus.contents, sdlmixer.Mix_Music)
[   40s] E       ValueError: NULL pointer access
[   40s] 
[   40s] sdl2/test/sdlmixer_test.py:168: ValueError
[   40s] =========================== short test summary info ============================

Complete build log with all versions of packages used and steps taken.

Platform (if relevant):

  • OS: [e.g. Windows 10 64-bit, Manjaro Linux ARM] Linux/openSUSE/Tumbleweed (i.e., a rolling distro as of 2022-07-29)
  • Python Version: Python 3.8, 3.9, 3.10
  • SDL2 Version: [e.g. 2.0.14] libSDL2-2_0-0-2.0.22
  • Using pysdl2-dll: [Yes / No] #N/A

mcepl avatar Jul 29 '22 12:07 mcepl

Hey @mcepl, it's not 100% clear from the build logs since pytest isn't set to report captured print() output (a few tests print messages describing feature support in the linked SDL2 binaries), but this looks like SDL2_mixer either a) wasn't built with MP3 support, or b) has MP3 support broken for whatever reason.

I can make a patch to skip the MP3-dependent tests if MP3 support is absent in a given Mixer binary, but you may also want to check on openSUSE's current Mixer package to make sure MP3 support isn't unexpectedly broken.

a-hurst avatar Jul 29 '22 16:07 a-hurst

Hmm, I am really not a specialist on SDL2 (I work on Python packages for SUSE), so I am not sure what to think about this ./configure line of SDL2_mixer:

./configure --host=x86_64-suse-linux-gnu --build=x86_64-suse-linux-gnu
    --program-prefix= --disable-dependency-tracking --prefix=/usr
    --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc
    --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib64
    --libexecdir=/usr/libexec --localstatedir=/var --sharedstatedir=/var/lib
    --mandir=/usr/share/man --infodir=/usr/share/info --disable-music-ogg-stb
    --enable-music-ogg-vorbis --disable-music-flac-drflac
    --enable-music-flac-libflac --disable-music-mp3-drmp3 --enable-music-mp3-mpg123
    --disable-music-mod-modplug --enable-music-mod-xmp
    --disable-music-mod-xmp-shared --disable-music-midi-fluidsynth-shared
    --disable-music-ogg-shared --disable-music-flac-shared
    --enable-music-mp3-mpg123-shared --disable-static

mcepl avatar Jul 29 '22 17:07 mcepl

@mcepl Thanks, that helps a lot! That tells me Mixer is being built with dynamic support for libmpg123 as an MP3 decoder backend, but I can't find a reference to that library in the build log so it's probably a question of Mixer being unable to read MP3 files without that library.

Since I guess it's perfectly valid for a given distro to make mp3 support dynamic/optional, I'll count this as a valid bug in PySDL2's test suite. Here's a patch that should fix this for now, and I'll make sure it's addressed in the next release!

mixer_tests_fix.patch.txt

a-hurst avatar Jul 29 '22 17:07 a-hurst

Hmm, I don’t know what’s wrong, but it seems your patch didn’t help at all

_log.txt

mcepl avatar Jul 29 '22 18:07 mcepl

@mcepl Sorry for the delay, been taking some time off! Can you run the tests locally with pytest -vl -rxXP sdl2/test/sdlmixer_test.py and send me the logs? That'll give me a much more informative look at what actually's going wrong with those tests so I can make a proper fix.

a-hurst avatar Jul 31 '22 15:07 a-hurst

pytest-run-log.txt

Interesting, so it is missing video, not audio device. And yes, I have my serious doubts that we have any video devices accessible in our build machines. Or is it some missing library supporting video?

mcepl avatar Jul 31 '22 21:07 mcepl

@mcepl Looks like some tests are failing in that last log that were working fine in your earlier ones: can you try re-running with the following environment variables set? These are what I use for headless CI testing:

SDL_VIDEODRIVER=dummy
SDL_AUDIODRIVER=dummy
SDL_RENDER_DRIVER=software

Also, based on the output I was right that MP3 support is missing, so unless I missed something the patch I made should detect that and skip all MP3-requiring tests (the ones that were failing in the original log).

a-hurst avatar Jul 31 '22 23:07 a-hurst

SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy SDL_RENDER_DRIVER=software

Actually, I had these variables set in my SPEC file (so you should see them in the log from this comment), but when I set in the build environment and run your command again, I got pretty much the same

pytest-run-log.txt

mcepl avatar Aug 01 '22 09:08 mcepl

Ahhh I see, I wrote my patch wrong: apparently Mix_Init still indicates that MP3 support is loaded correctly even if the required dynamic library isn't available. I rewrote the "check for MP3 support" logic to hopefully be more reliable, let me know if this works!

mixer_test_fix_v2.patch.txt

a-hurst avatar Aug 01 '22 15:08 a-hurst

Yes, that helped. I don’t need to skip those few tests.

mcepl avatar Aug 01 '22 15:08 mcepl

Great, so it's fully working now? Or are there any other issues to fix?

a-hurst avatar Aug 01 '22 17:08 a-hurst

Yes, this problem is gone. We are still skipping plenty of tests. See our SPEC file from line 73 onwards, but I guess it is mostly given some old libs we use or weird architectures you don’t support.

mcepl avatar Aug 02 '22 07:08 mcepl

@mcepl Glad to hear it! Also, some of those skipped tests (apart from the PowerInfo segfault) look like bugs that have been fixed in the past few PySDL2 releases (e.g. certain tests failing on big-endian, I actually set up Void PPC64 on my old PowerMac G5 to sort that out), so you may be able to remove those lines if you want. There could be bugs I haven't caught yet, though.

a-hurst avatar Aug 02 '22 14:08 a-hurst

@mcepl Glad to hear it! Also, some of those skipped tests (apart from the PowerInfo segfault) look like bugs that have been fixed in the past few PySDL2 releases (e.g. certain tests failing on big-endian, I actually set up Void PPC64 on my old PowerMac G5 to sort that out), so you may be able to remove those lines if you want. There could be bugs I haven't caught yet, though.

And what do you think? I don’t have to exclude ANY test and it still passes. Thank you, very much.

Just a nit:

[  109s] python310-PySDL2.noarch: W: hidden-file-or-dir /usr/share/doc/packages/python310-PySDL2/doc/.DS_Store

I don’t think you want to leave these around.

mcepl avatar Aug 02 '22 15:08 mcepl

@mcepl Ah yep, whoops! I thought I set up things to exclude those, but apparently it didn't work. I'll try to fix that for future releases.

a-hurst avatar Aug 02 '22 17:08 a-hurst

Fix included in PySDL2 0.9.14, closing this!

a-hurst avatar Sep 03 '22 17:09 a-hurst