Flamenco/internal/worker/command_blender_test.go
Sybren A. Stüvel 81968610ed Worker: blender-render command, make the blendfile parameter optional
Only include the `blendfile` parameter if it is not empty. This makes it
possible to pass a Python script that loads/constructs the blend file,
instead of loading one directly.
2024-02-25 23:09:11 +01:00

121 lines
4.0 KiB
Go

package worker
import (
"context"
"testing"
"github.com/golang/mock/gomock"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/stretchr/testify/assert"
"projects.blender.org/studio/flamenco/pkg/api"
)
// SPDX-License-Identifier: GPL-3.0-or-later
func TestCmdBlenderSimpleCliArgs(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
ce, mocks := testCommandExecutor(t, mockCtrl)
taskID := "1d54c6fe-1242-4c8f-bd63-5a09e358d7b6"
cmd := api.Command{
Name: "blender",
Parameters: map[string]interface{}{
"exe": "/path/to/blender",
"argsBefore": []string{"--background"},
"blendfile": "file.blend",
"args": []string{"--render-output", "/frames"},
},
}
cliArgs := []string{"--background", "file.blend", "--render-output", "/frames"}
mocks.cli.EXPECT().CommandContext(gomock.Any(), "/path/to/blender", cliArgs).Return(nil)
err := ce.cmdBlenderRender(context.Background(), zerolog.Nop(), taskID, cmd)
assert.Equal(t, ErrNoExecCmd, err, "nil *exec.Cmd should result in ErrNoExecCmd")
}
func TestCmdBlenderCliArgsInExeParameter(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
ce, mocks := testCommandExecutor(t, mockCtrl)
// Just use backslashes even when we're testing on Linux/macOS. Backslashes
// are always causing issues, so it's better to test with those on other
// platforms as well. Even when the resulting command cannot be run, every
// platform should be able to at least make the backslashes survive any
// processing.
exe := `D:\Blender_3.2_stable\blender.exe`
taskID := "1d54c6fe-1242-4c8f-bd63-5a09e358d7b6"
cmd := api.Command{
Name: "blender",
Parameters: map[string]interface{}{
"exe": exe,
// This intentionally starts with a space (should be ignored) and has
// quoted text within quoted text:
"exeArgs": ` --factory-startup --python-expr "import bpy; print(\"hello world\")"`,
"argsBefore": []string{"-no-audio"},
"blendfile": "file with spaces.blend",
"args": []string{"--debug"},
},
}
mocks.cli.EXPECT().CommandContext(gomock.Any(),
exe, // from 'exe'
"--factory-startup", // from 'exeArgs'
"--python-expr", // from 'exeArgs'
`import bpy; print("hello world")`, // from 'exeArgs'
"-no-audio", // from 'argsBefore'
"file with spaces.blend", // from 'blendfile'
"--debug", // from 'args'
).Return(nil)
err := ce.cmdBlenderRender(context.Background(), zerolog.Nop(), taskID, cmd)
assert.Equal(t, ErrNoExecCmd, err, "nil *exec.Cmd should result in ErrNoExecCmd")
}
func TestCmdBlenderNoBlendfile(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
ce, mocks := testCommandExecutor(t, mockCtrl)
taskID := "1d54c6fe-1242-4c8f-bd63-5a09e358d7b6"
cmd := api.Command{
Name: "blender",
Parameters: map[string]interface{}{
"exe": "/path/to/blender",
"argsBefore": []string{"--background"},
"blendfile": "", // Empty blendfile should be skipped.
"args": []string{"--render-output", "/frames"},
},
}
cliArgs := []string{"--background", "--render-output", "/frames"}
mocks.cli.EXPECT().CommandContext(gomock.Any(), "/path/to/blender", cliArgs).Return(nil)
err := ce.cmdBlenderRender(context.Background(), zerolog.Nop(), taskID, cmd)
assert.Equal(t, ErrNoExecCmd, err, "nil *exec.Cmd should result in ErrNoExecCmd")
}
func TestProcessLineBlender(t *testing.T) {
ctx := context.Background()
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
ce, mocks := testCommandExecutor(t, mockCtrl)
taskID := "c194ea21-1fda-46f6-bc9a-34bd302cfb19"
// This shouldn't call anything on the mocks.
ce.processLineBlender(ctx, log.Logger, taskID, "starting Blender")
// This should be recognised as produced output.
mocks.listener.EXPECT().OutputProduced(ctx, taskID, "/path/to/file.exr")
ce.processLineBlender(ctx, log.Logger, taskID, "Saved: '/path/to/file.exr'")
}