2021-09-27 05:53:36 +08:00
import gc
2016-04-27 08:00:58 -07:00
import os
2022-08-30 19:47:26 +01:00
import re
2021-09-27 05:53:36 +08:00
import time
2016-04-27 08:00:58 -07:00
2022-03-14 14:27:03 +00:00
import pytest
2016-04-27 08:00:58 -07:00
import gym
2021-09-27 05:53:36 +08:00
from gym . wrappers . monitoring . video_recorder import VideoRecorder
2016-04-27 08:00:58 -07:00
2021-07-29 02:26:34 +02:00
2022-08-08 22:41:15 +01:00
class BrokenRecordableEnv ( gym . Env ) :
2022-09-01 14:06:42 +01:00
metadata = { " render_modes " : [ " rgb_array_list " ] }
2016-04-27 08:00:58 -07:00
2022-09-01 14:06:42 +01:00
def __init__ ( self , render_mode = " rgb_array_list " ) :
2022-06-08 00:20:56 +02:00
self . render_mode = render_mode
2022-08-22 17:21:08 +02:00
def render ( self ) :
2016-04-27 08:00:58 -07:00
pass
2021-07-29 02:26:34 +02:00
2022-08-08 22:41:15 +01:00
class UnrecordableEnv ( gym . Env ) :
2022-02-28 15:54:03 -05:00
metadata = { " render_modes " : [ None ] }
2016-04-27 08:00:58 -07:00
2022-06-08 00:20:56 +02:00
def __init__ ( self , render_mode = None ) :
self . render_mode = render_mode
2022-08-22 17:21:08 +02:00
def render ( self ) :
2016-04-27 08:00:58 -07:00
pass
2021-07-29 02:26:34 +02:00
2016-08-30 01:12:29 +02:00
def test_record_simple ( ) :
2022-09-01 14:06:42 +01:00
env = gym . make (
" CartPole-v1 " , render_mode = " rgb_array_list " , disable_env_checker = True
)
2016-08-30 01:12:29 +02:00
rec = VideoRecorder ( env )
env . reset ( )
rec . capture_frame ( )
2021-09-27 05:53:36 +08:00
2016-08-30 01:12:29 +02:00
rec . close ( )
2021-09-27 05:53:36 +08:00
2016-08-30 01:12:29 +02:00
assert not rec . broken
assert os . path . exists ( rec . path )
f = open ( rec . path )
assert os . fstat ( f . fileno ( ) ) . st_size > 100
2016-04-27 08:00:58 -07:00
2021-07-29 02:26:34 +02:00
2021-08-26 23:48:18 +08:00
def test_autoclose ( ) :
def record ( ) :
2022-09-01 14:06:42 +01:00
env = gym . make (
" CartPole-v1 " , render_mode = " rgb_array_list " , disable_env_checker = True
)
2021-08-26 23:48:18 +08:00
rec = VideoRecorder ( env )
env . reset ( )
rec . capture_frame ( )
rec_path = rec . path
# The function ends without an explicit `rec.close()` call
# The Python interpreter will implicitly do `del rec` on garbage cleaning
2022-08-22 17:21:08 +02:00
return rec_path
2021-08-26 23:48:18 +08:00
2022-08-22 17:21:08 +02:00
rec_path = record ( )
2021-09-27 05:53:36 +08:00
gc . collect ( ) # do explicit garbage collection for test
time . sleep ( 5 ) # wait for subprocess exiting
2021-08-26 23:48:18 +08:00
assert os . path . exists ( rec_path )
f = open ( rec_path )
assert os . fstat ( f . fileno ( ) ) . st_size > 100
2016-04-27 08:00:58 -07:00
def test_no_frames ( ) :
env = BrokenRecordableEnv ( )
rec = VideoRecorder ( env )
rec . close ( )
assert rec . functional
assert not os . path . exists ( rec . path )
2021-07-29 02:26:34 +02:00
2016-04-27 08:00:58 -07:00
def test_record_unrecordable_method ( ) :
2022-08-30 19:47:26 +01:00
with pytest . warns (
UserWarning ,
2022-09-01 14:06:42 +01:00
match = re . escape (
" \x1b [33mWARN: Disabling video recorder because environment <UnrecordableEnv instance> was not initialized with any compatible video mode between `rgb_array` and `rgb_array_list` \x1b [0m "
) ,
2022-08-30 19:47:26 +01:00
) :
env = UnrecordableEnv ( )
rec = VideoRecorder ( env )
assert not rec . enabled
rec . close ( )
2016-04-27 08:00:58 -07:00
2021-07-29 02:26:34 +02:00
2016-04-27 08:00:58 -07:00
def test_record_breaking_render_method ( ) :
2022-08-30 19:47:26 +01:00
with pytest . warns (
UserWarning ,
match = re . escape (
" Env returned None on `render()`. Disabling further rendering for video recorder by marking as disabled: "
) ,
) :
env = BrokenRecordableEnv ( )
rec = VideoRecorder ( env )
rec . capture_frame ( )
rec . close ( )
assert rec . broken
assert not os . path . exists ( rec . path )
2016-04-27 08:00:58 -07:00
2021-07-29 02:26:34 +02:00
2016-04-27 08:00:58 -07:00
def test_text_envs ( ) :
2022-09-01 14:06:42 +01:00
env = gym . make (
" FrozenLake-v1 " , render_mode = " rgb_array_list " , disable_env_checker = True
)
2016-04-27 08:00:58 -07:00
video = VideoRecorder ( env )
try :
env . reset ( )
video . capture_frame ( )
video . close ( )
finally :
os . remove ( video . path )