66# the same Cinema4DAdaptor action queue, which can cause race conditions and
77# test failures when tests run in parallel across multiple workers.
88import json
9+ import logging
910from pathlib import Path
1011from unittest .mock import Mock , PropertyMock , patch
1112
@@ -71,8 +72,6 @@ class TestCinema4DAdaptor_errors_on_cleanup:
7172 [
7273 # Critical stops should not fail the job.
7374 ("CRITICAL: Stop [ge_file.cpp(1172)]" , False ),
74- # Any string with substring "Error:" should fail the job
75- ("Redshift Error: Maxon licensing error: User not logged in (7)" , True ),
7675 # This error can be printed but the jobs are still successful.
7776 # Hence, this should not fail the job.
7877 ("CRITICAL: nullptr [text_object.cpp(1082)] [objectbase1.hxx(549)]" , False ),
@@ -84,12 +83,8 @@ class TestCinema4DAdaptor_errors_on_cleanup:
8483 ("Rendering failed" , True ),
8584 ("Asset missing" , True ),
8685 ("Asset Error" , True ),
87- ("Invalid License" , True ),
88- ("License Check error" , True ),
8986 ("Files cannot be written" , True ),
90- ("Enter Registration Data" , True ),
9187 ("Unable to write file" , True ),
92- ("[rlm] abort_on_license_fail enabled" , True ),
9388 ("RenderDocument failed with return code" , True ),
9489 ("Frame rendering aborted" , True ),
9590 ("Rendering was internally aborted" , True ),
@@ -364,6 +359,66 @@ def test__wait_for_socket(
364359 # THEN
365360 assert mock_sleep .call_count == 3
366361
362+ @pytest .mark .parametrize (
363+ "license_error" ,
364+ [
365+ "Redshift Error: Maxon licensing error: User not logged in (7)" ,
366+ "Invalid License" ,
367+ "License Check error" ,
368+ "Enter Registration Data" ,
369+ "[rlm] abort_on_license_fail enabled" ,
370+ "17:44:34 No license found" ,
371+ "18:38:54 No available licenses to choose" ,
372+ ],
373+ )
374+ def test_license_failure_from_stdout_interrupts_startup (
375+ self , init_data : dict , license_error : str
376+ ) -> None :
377+ """Tests that a licensing prompt fails startup without waiting for the timeout."""
378+ # General error checking is optional, but a licensing prompt cannot recover
379+ # without interactive input and must always stop the worker.
380+ init_data ["activate_error_checking" ] = "0"
381+ adaptor = Cinema4DAdaptor (init_data )
382+ expected_error = (
383+ "Cinema 4D failed to acquire a license.\n "
384+ "If you are using bring your own license (BYOL), check your license configuration "
385+ "and availability.\n "
386+ "If you are using usage-based licensing (UBL) from AWS Deadline Cloud and need a "
387+ "higher 'License sessions per license endpoint' limit, contact the AWS Deadline Cloud "
388+ "team to request an increase.\n "
389+ f"Error: { license_error } "
390+ )
391+
392+ def emit_license_error (* args , ** kwargs ):
393+ kwargs ["stdout_handler" ].emit (
394+ logging .LogRecord (
395+ name = "cinema4d" ,
396+ level = logging .ERROR ,
397+ pathname = "" ,
398+ lineno = 0 ,
399+ msg = license_error ,
400+ args = (),
401+ exc_info = None ,
402+ )
403+ )
404+ process = Mock ()
405+ process .is_running = True
406+ return process
407+
408+ with (
409+ patch .object (adaptor , "_initialize_maxon_assets_db_connection" ),
410+ patch .object (adaptor , "_start_cinema4d_server_thread" ),
411+ patch .object (adaptor , "_populate_action_queue" ),
412+ patch (
413+ "deadline.cinema4d_adaptor.Cinema4DAdaptor.adaptor.LoggingSubprocess" ,
414+ side_effect = emit_license_error ,
415+ ),
416+ pytest .raises (RuntimeError ) as exc_info ,
417+ ):
418+ adaptor .on_start ()
419+
420+ assert str (exc_info .value ) == expected_error
421+
367422
368423@pytest .mark .xdist_group (name = "adaptor_tests" )
369424class TestCinema4DAdaptor_on_run :
0 commit comments