
* Replace "OK!" with "successfully" Remove exclamation mark since there is no need to call for attention. Use "successfully" as it is more descriptive in this case than OK, which can have other meanings.
238 lines
7.1 KiB
Go
238 lines
7.1 KiB
Go
package api_impl
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
import (
|
|
"io/fs"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"git.blender.org/flamenco/internal/manager/config"
|
|
"git.blender.org/flamenco/pkg/api"
|
|
"github.com/golang/mock/gomock"
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestGetVariables(t *testing.T) {
|
|
mockCtrl := gomock.NewController(t)
|
|
defer mockCtrl.Finish()
|
|
|
|
mf := newMockedFlamenco(mockCtrl)
|
|
|
|
// Test Linux Worker.
|
|
{
|
|
resolvedVarsLinuxWorker := make(map[string]config.ResolvedVariable)
|
|
resolvedVarsLinuxWorker["jobs"] = config.ResolvedVariable{
|
|
IsTwoWay: true,
|
|
Value: "Linux value",
|
|
}
|
|
resolvedVarsLinuxWorker["blender"] = config.ResolvedVariable{
|
|
IsTwoWay: false,
|
|
Value: "/usr/local/blender",
|
|
}
|
|
|
|
mf.config.EXPECT().
|
|
ResolveVariables(config.VariableAudienceWorkers, config.VariablePlatformLinux).
|
|
Return(resolvedVarsLinuxWorker)
|
|
|
|
echoCtx := mf.prepareMockedRequest(nil)
|
|
err := mf.flamenco.GetVariables(echoCtx, api.ManagerVariableAudienceWorkers, "linux")
|
|
assert.NoError(t, err)
|
|
assertResponseJSON(t, echoCtx, http.StatusOK, api.ManagerVariables{
|
|
AdditionalProperties: map[string]api.ManagerVariable{
|
|
"blender": {Value: "/usr/local/blender", IsTwoway: false},
|
|
"jobs": {Value: "Linux value", IsTwoway: true},
|
|
},
|
|
})
|
|
}
|
|
|
|
// Test unknown platform User.
|
|
{
|
|
resolvedVarsUnknownPlatform := make(map[string]config.ResolvedVariable)
|
|
mf.config.EXPECT().
|
|
ResolveVariables(config.VariableAudienceUsers, config.VariablePlatform("troll")).
|
|
Return(resolvedVarsUnknownPlatform)
|
|
|
|
echoCtx := mf.prepareMockedRequest(nil)
|
|
err := mf.flamenco.GetVariables(echoCtx, api.ManagerVariableAudienceUsers, "troll")
|
|
assert.NoError(t, err)
|
|
assertResponseJSON(t, echoCtx, http.StatusOK, api.ManagerVariables{})
|
|
}
|
|
}
|
|
|
|
func TestCheckSharedStoragePath(t *testing.T) {
|
|
mf, finish := metaTestFixtures(t)
|
|
defer finish()
|
|
|
|
doTest := func(path string) echo.Context {
|
|
echoCtx := mf.prepareMockedJSONRequest(
|
|
api.PathCheckInput{Path: path})
|
|
err := mf.flamenco.CheckSharedStoragePath(echoCtx)
|
|
if !assert.NoError(t, err) {
|
|
t.FailNow()
|
|
}
|
|
return echoCtx
|
|
}
|
|
|
|
// Test empty path.
|
|
echoCtx := doTest("")
|
|
assertResponseJSON(t, echoCtx, http.StatusOK, api.PathCheckResult{
|
|
Path: "",
|
|
IsUsable: false,
|
|
Cause: "An empty path is not suitable as shared storage",
|
|
})
|
|
|
|
// Test usable path (well, at least readable & writable; it may not be shared via Samba/NFS).
|
|
echoCtx = doTest(mf.tempdir)
|
|
assertResponseJSON(t, echoCtx, http.StatusOK, api.PathCheckResult{
|
|
Path: mf.tempdir,
|
|
IsUsable: true,
|
|
Cause: "Directory checked successfully",
|
|
})
|
|
files, err := filepath.Glob(filepath.Join(mf.tempdir, "*"))
|
|
if assert.NoError(t, err) {
|
|
assert.Empty(t, files, "After a query, there should not be any leftovers")
|
|
}
|
|
|
|
// Test inaccessible path.
|
|
// For some reason, this doesn't work on Windows, and creating a file in
|
|
// that directory is still allowed. The Explorer's properties panel of the
|
|
// directory also shows "Read Only (only applies to files)", so at least
|
|
// that seems consistent.
|
|
// FIXME: find another way to test with unwritable directories on Windows.
|
|
if runtime.GOOS != "windows" {
|
|
parentPath := filepath.Join(mf.tempdir, "deep")
|
|
testPath := filepath.Join(parentPath, "nesting")
|
|
if err := os.Mkdir(parentPath, fs.ModePerm); !assert.NoError(t, err) {
|
|
t.FailNow()
|
|
}
|
|
if err := os.Mkdir(testPath, fs.FileMode(0)); !assert.NoError(t, err) {
|
|
t.FailNow()
|
|
}
|
|
echoCtx := doTest(testPath)
|
|
result := api.PathCheckResult{}
|
|
getResponseJSON(t, echoCtx, http.StatusOK, &result)
|
|
assert.Equal(t, testPath, result.Path)
|
|
assert.False(t, result.IsUsable)
|
|
assert.Contains(t, result.Cause, "Unable to create a file")
|
|
}
|
|
}
|
|
|
|
func TestSaveWizardConfig(t *testing.T) {
|
|
mf, finish := metaTestFixtures(t)
|
|
defer finish()
|
|
|
|
doTest := func(body api.WizardConfig) config.Conf {
|
|
// Always start the test with a clean configuration.
|
|
originalConfig := config.DefaultConfig(func(c *config.Conf) {
|
|
c.SharedStoragePath = ""
|
|
})
|
|
var savedConfig config.Conf
|
|
|
|
// Mock the loading & saving of the config.
|
|
mf.config.EXPECT().Get().Return(&originalConfig)
|
|
mf.config.EXPECT().Save().Do(func() error {
|
|
savedConfig = originalConfig
|
|
return nil
|
|
})
|
|
|
|
// Call the API.
|
|
echoCtx := mf.prepareMockedJSONRequest(body)
|
|
err := mf.flamenco.SaveWizardConfig(echoCtx)
|
|
if !assert.NoError(t, err) {
|
|
t.FailNow()
|
|
}
|
|
|
|
assertResponseNoContent(t, echoCtx)
|
|
return savedConfig
|
|
}
|
|
|
|
// Test situation where file association with .blend files resulted in a blender executable.
|
|
{
|
|
savedConfig := doTest(api.WizardConfig{
|
|
StorageLocation: mf.tempdir,
|
|
BlenderExecutable: api.BlenderPathCheckResult{
|
|
IsUsable: true,
|
|
Input: "",
|
|
Path: "/path/to/blender",
|
|
Source: api.BlenderPathSourceFileAssociation,
|
|
},
|
|
})
|
|
assert.Equal(t, mf.tempdir, savedConfig.SharedStoragePath)
|
|
expectBlenderVar := config.Variable{
|
|
Values: config.VariableValues{
|
|
{Platform: "linux", Value: "blender " + config.DefaultBlenderArguments},
|
|
{Platform: "windows", Value: "blender " + config.DefaultBlenderArguments},
|
|
{Platform: "darwin", Value: "blender " + config.DefaultBlenderArguments},
|
|
},
|
|
}
|
|
assert.Equal(t, expectBlenderVar, savedConfig.Variables["blender"])
|
|
}
|
|
|
|
// Test situation where the given command could be found on $PATH.
|
|
{
|
|
savedConfig := doTest(api.WizardConfig{
|
|
StorageLocation: mf.tempdir,
|
|
BlenderExecutable: api.BlenderPathCheckResult{
|
|
IsUsable: true,
|
|
Input: "kitty",
|
|
Path: "/path/to/kitty",
|
|
Source: api.BlenderPathSourcePathEnvvar,
|
|
},
|
|
})
|
|
assert.Equal(t, mf.tempdir, savedConfig.SharedStoragePath)
|
|
expectBlenderVar := config.Variable{
|
|
Values: config.VariableValues{
|
|
{Platform: "linux", Value: "kitty " + config.DefaultBlenderArguments},
|
|
{Platform: "windows", Value: "kitty " + config.DefaultBlenderArguments},
|
|
{Platform: "darwin", Value: "kitty " + config.DefaultBlenderArguments},
|
|
},
|
|
}
|
|
assert.Equal(t, expectBlenderVar, savedConfig.Variables["blender"])
|
|
}
|
|
|
|
// Test a custom command given with the full path.
|
|
{
|
|
savedConfig := doTest(api.WizardConfig{
|
|
StorageLocation: mf.tempdir,
|
|
BlenderExecutable: api.BlenderPathCheckResult{
|
|
IsUsable: true,
|
|
Input: "/bin/cat",
|
|
Path: "/bin/cat",
|
|
Source: api.BlenderPathSourceInputPath,
|
|
},
|
|
})
|
|
assert.Equal(t, mf.tempdir, savedConfig.SharedStoragePath)
|
|
expectBlenderVar := config.Variable{
|
|
Values: config.VariableValues{
|
|
{Platform: "linux", Value: "/bin/cat " + config.DefaultBlenderArguments},
|
|
{Platform: "windows", Value: "/bin/cat " + config.DefaultBlenderArguments},
|
|
{Platform: "darwin", Value: "/bin/cat " + config.DefaultBlenderArguments},
|
|
},
|
|
}
|
|
assert.Equal(t, expectBlenderVar, savedConfig.Variables["blender"])
|
|
}
|
|
}
|
|
|
|
func metaTestFixtures(t *testing.T) (mockedFlamenco, func()) {
|
|
mockCtrl := gomock.NewController(t)
|
|
mf := newMockedFlamenco(mockCtrl)
|
|
|
|
tempdir, err := os.MkdirTemp("", "test-temp-dir")
|
|
if !assert.NoError(t, err) {
|
|
t.FailNow()
|
|
}
|
|
mf.tempdir = tempdir
|
|
|
|
finish := func() {
|
|
mockCtrl.Finish()
|
|
os.RemoveAll(tempdir)
|
|
}
|
|
|
|
return mf, finish
|
|
}
|