flamenco/pkg/shaman/checkout/manager_test.go
Sybren A. Stüvel 02fac6a4df Change Go package name from git.blender.org to projects.blender.org
Change the package base name of the Go code, from
`git.blender.org/flamenco` to `projects.blender.org/studio/flamenco`.

The old location, `git.blender.org`, has no longer been use since the
[migration to Gitea][1]. The new package names now reflect the actual
location where Flamenco is hosted.

[1]: https://code.blender.org/2023/02/new-blender-development-infrastructure/
2023-08-01 12:42:31 +02:00

153 lines
5.6 KiB
Go

/* (c) 2019, Blender Foundation - Sybren A. Stüvel
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package checkout
import (
"context"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"projects.blender.org/studio/flamenco/pkg/api"
"projects.blender.org/studio/flamenco/pkg/shaman/config"
"projects.blender.org/studio/flamenco/pkg/shaman/filestore"
)
func createTestManager() (*Manager, func()) {
conf, confCleanup := config.CreateTestConfig()
fileStore := filestore.New(conf)
manager := NewManager(conf, fileStore)
return manager, confCleanup
}
func TestSymlinkToCheckout(t *testing.T) {
manager, cleanup := createTestManager()
defer cleanup()
// Fake an older file.
blobPath := filepath.Join(manager.checkoutBasePath, "jemoeder.blob")
err := ioutil.WriteFile(blobPath, []byte("op je hoofd"), 0600)
assert.NoError(t, err)
wayBackWhen := time.Now().Add(-time.Hour * 24 * 100)
err = os.Chtimes(blobPath, wayBackWhen, wayBackWhen)
assert.NoError(t, err)
symlinkRelativePath := "path/to/jemoeder.txt"
err = manager.SymlinkToCheckout(blobPath, manager.checkoutBasePath, symlinkRelativePath)
assert.NoError(t, err)
err = manager.SymlinkToCheckout(blobPath, manager.checkoutBasePath, symlinkRelativePath)
assert.NoError(t, err, "symlinking a file twice should not be an issue")
// Wait for touch() calls to be done.
manager.wg.Wait()
// The blob should have been touched to indicate it was referenced just now.
stat, err := os.Stat(blobPath)
assert.NoError(t, err)
assert.True(t,
stat.ModTime().After(wayBackWhen),
"File must be touched (%v must be later than %v)", stat.ModTime(), wayBackWhen)
symlinkPath := filepath.Join(manager.checkoutBasePath, symlinkRelativePath)
stat, err = os.Lstat(symlinkPath)
assert.NoError(t, err)
assert.True(t, stat.Mode()&os.ModeType == os.ModeSymlink,
"%v should be a symlink", symlinkPath)
}
func TestPrepareCheckout(t *testing.T) {
manager, cleanup := createTestManager()
defer cleanup()
requestedCheckoutPath := "some-path/that is/unique/at first"
// On first call, this path should be unique.
resolved, err := manager.PrepareCheckout(requestedCheckoutPath)
require.NoError(t, err)
assert.Equal(t, requestedCheckoutPath, resolved.RelativePath)
// At the second call, it already exists and thus should be altered with a random suffix.
resolved, err = manager.PrepareCheckout(requestedCheckoutPath)
require.NoError(t, err)
assert.NotEqual(t, requestedCheckoutPath, resolved.RelativePath)
assert.True(t, strings.HasPrefix(resolved.RelativePath, requestedCheckoutPath+"-"))
}
func TestEraseCheckout(t *testing.T) {
manager, cleanup := createTestManager()
defer cleanup()
ctx := context.Background()
filestore.LinkTestFileStore(manager.fileStore.BasePath())
// Create a few checkouts to test with.
checkout1 := api.ShamanCheckout{
CheckoutPath: "á hausinn á þér",
Files: []api.ShamanFileSpec{
{Sha: "590c148428d5c35fab3ebad2f3365bb469ab9c531b60831f3e826c472027a0b9", Size: 3367, Path: "subdir/replacer.py"},
{Sha: "80b749c27b2fef7255e7e7b3c2029b03b31299c75ff1f1c72732081c70a713a3", Size: 7488, Path: "feed.py"},
{Sha: "914853599dd2c351ab7b82b219aae6e527e51518a667f0ff32244b0c94c75688", Size: 486, Path: "httpstuff.py"},
{Sha: "d6fc7289b5196cc96748ea72f882a22c39b8833b457fe854ef4c03a01f5db0d3", Size: 7217, Path: "много ликова.py"},
},
}
checkoutID1, err := manager.Checkout(ctx, checkout1)
require.NoError(t, err)
checkout2 := checkout1
checkout2.CheckoutPath = "één ander pad"
checkoutID2, err := manager.Checkout(ctx, checkout2)
require.NoError(t, err)
// Check that removing one works, without deleting the other.
require.NoError(t, manager.EraseCheckout(checkoutID1))
checkoutPath1, err := manager.pathForCheckout(checkoutID1)
require.NoError(t, err)
checkoutPath2, err := manager.pathForCheckout(checkoutID2)
require.NoError(t, err)
assert.NoDirExists(t, checkoutPath1.absolutePath, "actual checkout path should have been erased")
assert.DirExists(t, checkoutPath2.absolutePath, "the other checkout path should have been kept")
assert.DirExists(t, manager.fileStore.StoragePath(), "Shaman storage path should be kept")
// Check that non-checkout paths should be refused.
require.Error(t, manager.EraseCheckout(manager.fileStore.BasePath()))
}
func TestEraseCheckoutNonExisting(t *testing.T) {
manager, cleanup := createTestManager()
defer cleanup()
filestore.LinkTestFileStore(manager.fileStore.BasePath())
// Erasing a non-existing checkout should return a specific error.
require.Error(t, manager.EraseCheckout("não existe"))
}