Francesco Siddi 9948fdab71 Rename First Time Wizard to Setup Assistant
This commit does not introduce functional changes, besides renaming
every mention of 'wizard' with 'setup assistant'. In order to run the
manager setup assistant use:

./flamenco-manager -setup-assistant

The change was introduced to favor more neutral and descriptive working
for this functionality. Thanks to Sybren for helping to get this done!
2022-07-25 17:17:04 +02:00

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 TestSaveSetupAssistantConfig(t *testing.T) {
mf, finish := metaTestFixtures(t)
defer finish()
doTest := func(body api.SetupAssistantConfig) 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.SaveSetupAssistantConfig(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.SetupAssistantConfig{
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.SetupAssistantConfig{
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.SetupAssistantConfig{
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
}