Skip to content

Commit

Permalink
fix: adaptor wheel error dialog and unit test coverage
Browse files Browse the repository at this point in the history
Signed-off-by: Ting Cheng <36546476+tincheng@users.noreply.github.com>
  • Loading branch information
tincheng committed Sep 18, 2023
1 parent 84dc17f commit bb64033
Show file tree
Hide file tree
Showing 9 changed files with 1,036 additions and 2 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,4 @@ source = [

[tool.coverage.report]
show_missing = true
fail_under = 61
fail_under = 75
2 changes: 1 addition & 1 deletion src/deadline/nuke_submitter/deadline_submitter_for_nuke.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def _get_job_template(settings: RenderSubmitterUISettings) -> dict[str, Any]:

# Read DEVELOPMENT.md for instructions to create the wheels directory.
wheels_path = Path(__file__).parent.parent.parent.parent / "wheels"
if not wheels_path.exists() and wheels_path.is_dir():
if not wheels_path.is_dir():
raise RuntimeError(
"The Developer Option 'Include Adaptor Wheels' is enabled, but the wheels directory does not exist:\n"
+ str(wheels_path)
Expand Down
88 changes: 88 additions & 0 deletions test/deadline_adaptor_for_nuke/unit/NukeAdaptor/test_adaptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,29 @@ def test_on_cleanup_server_not_graceful_shutdown(
mock_logger.error.assert_called_once_with("Failed to shutdown the Nuke Adaptor server.")
mock_server_thread.join.assert_called_once_with(timeout=0.01)

@patch("time.sleep")
@patch("deadline.nuke_adaptor.NukeAdaptor.adaptor._logger")
def test_on_cleanup_server_thread_shutdown(
self, mock_logger: Mock, mock_sleep: Mock, init_data: dict
) -> None:
"""Tests that on_cleanup reports when the server does not shutdown"""
# GIVEN
adaptor = NukeAdaptor(init_data)

with patch(
"deadline.nuke_adaptor.NukeAdaptor.adaptor.NukeAdaptor._nuke_is_running",
new_callable=lambda: False,
), patch.object(adaptor, "_SERVER_END_TIMEOUT_SECONDS", 0.01), patch.object(
adaptor, "_server_thread"
) as mock_server_thread:
mock_server_thread.is_alive.side_effect = [True, False]
# WHEN
adaptor.on_cleanup()

# THEN
mock_logger.error.assert_not_called()
mock_server_thread.join.assert_called_once_with(timeout=0.01)

@patch("time.sleep")
@patch("deadline.nuke_adaptor.NukeAdaptor.adaptor.ActionsQueue.__len__", return_value=0)
@patch("deadline.nuke_adaptor.NukeAdaptor.adaptor.LoggingSubprocess")
Expand Down Expand Up @@ -573,6 +596,40 @@ def test_handle_progress(
("Eddy[ERROR] - Something terrible happened", 3),
]

@pytest.mark.parametrize("regex_index, stdout, expected_progress", handle_progess_params)
@patch("deadline.nuke_adaptor.NukeAdaptor.adaptor.NukeAdaptor.update_status")
@patch.object(NukeAdaptor, "_is_rendering", new_callable=PropertyMock(return_value=False))
def test_handle_progress_not_rendering(
self,
mock_is_rendering: Mock,
mock_update_status: Mock,
regex_index: tuple[int, int],
stdout: tuple[str, str],
expected_progress: tuple[float, float],
init_data: dict,
) -> None:
# GIVEN
adaptor = NukeAdaptor(init_data)

regex_callbacks = adaptor.regex_callbacks
progress_index, output_complete_index = regex_index
output_complete_regex = regex_callbacks[output_complete_index].regex_list[0]

# WHEN
if output_complete_match := output_complete_regex.search(stdout[1]):
adaptor._handle_output_complete(output_complete_match)

# THEN
assert output_complete_match is not None
mock_update_status.assert_not_called()

handle_error_params = [
("ERROR: Something terrible happened", 0),
("Error: Something terrible happened", 1),
("Error : Something terrible happened", 2),
("Eddy[ERROR] - Something terrible happened", 3),
]

@pytest.mark.parametrize("continue_on_error", [True, False])
@pytest.mark.parametrize("stdout, regex_index", handle_error_params)
@patch("deadline.nuke_adaptor.NukeAdaptor.adaptor.NukeAdaptor.update_status")
Expand Down Expand Up @@ -671,3 +728,34 @@ def test_does_nothing_if_nuke_not_running(
# THEN
assert "CANCEL REQUESTED" in caplog.text
assert "Nothing to cancel because Nuke is not running" in caplog.text


class TestNukeAdaptor_get_major_minor_version:
"""Tests for static method _get_major_minor_version"""

@patch("deadline.nuke_adaptor.NukeAdaptor.adaptor._logger")
def test_whole_version(self, mock_logger, init_data):
adaptor = NukeAdaptor(init_data)

# THEN
assert "13.2" == adaptor._get_major_minor_version("13.2v4")
mock_logger.info.assert_called_once_with("Using 13.2 to find Nuke executable")

@patch("deadline.nuke_adaptor.NukeAdaptor.adaptor._logger")
def test_major_minor(self, mock_logger, init_data):
adaptor = NukeAdaptor(init_data)

# THEN
assert "13.2" == adaptor._get_major_minor_version("13.2")
mock_logger.info.assert_called_once_with("Using 13.2 to find Nuke executable")

@patch("deadline.nuke_adaptor.NukeAdaptor.adaptor._logger")
def test_no_major_minor_version(self, mock_logger, init_data):
adaptor = NukeAdaptor(init_data)

# THEN
assert "13" == adaptor._get_major_minor_version("13")
mock_logger.warning.assert_called_once_with(
"Could not find major.minor information from '13',"
" using '13' to find the Nuke executable"
)
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,19 @@ def test_set_write_nodes(self, write_nodes: List[MockNode], nukehandler: NukeHan
# THEN
assert nukehandler.write_nodes == write_nodes

def test_set_write_nodes_all_write_nodes(
self, write_nodes: List[MockNode], nukehandler: NukeHandler
):
# GIVEN
all_write_nodes = ["All Write Nodes"]
data = {"write_nodes": all_write_nodes}

# WHEN
nukehandler.set_write_nodes(data)

# THEN
assert nukehandler.write_nodes == write_nodes

missing_nodes_params = [
(
SortedList(["these", "do", "not", "exist"]),
Expand Down
20 changes: 20 additions & 0 deletions test/deadline_submitter_for_nuke/unit/test_assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import nuke
import pytest

from deadline.client.exceptions import DeadlineOperationError
from deadline.nuke_submitter.assets import (
find_all_write_nodes,
get_node_file_knob_paths,
Expand Down Expand Up @@ -75,6 +76,25 @@ def test_get_scene_asset_references(
assert all(asset in results.input_filenames for asset in expected_assets)


@patch("os.path.isfile", return_value=False)
@patch("deadline.nuke_submitter.assets.get_nuke_script_file", return_value="/this/scriptfile.nk")
def test_get_scene_asset_references_script_not_saved(
mock_get_nuke_script_file: Mock, mock_path_isfile: Mock
):
# GIVEN
nuke.allNodes.return_value = []

# WHEN
with pytest.raises(DeadlineOperationError) as exc_info:
get_scene_asset_references()

# THEN
error_msg = (
"The Nuke Script is not saved to disk. Please save it before opening the submitter dialog."
)
assert str(exc_info.value) == error_msg


def test_find_all_write_nodes():
# GIVEN
nuke.allNodes.return_value = []
Expand Down
Loading

0 comments on commit bb64033

Please sign in to comment.