2019-04-13 06:40:15 +08:00
|
|
|
package store
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2024-10-18 19:28:45 +08:00
|
|
|
"github.com/docker/buildx/util/confutil"
|
2019-04-13 06:40:15 +08:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestEmptyStartup(t *testing.T) {
|
|
|
|
t.Parallel()
|
2022-03-10 08:46:06 +08:00
|
|
|
tmpdir, err := os.MkdirTemp("", "buildx-store")
|
2019-04-13 06:40:15 +08:00
|
|
|
require.NoError(t, err)
|
|
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
|
2024-10-18 19:28:45 +08:00
|
|
|
s, err := New(confutil.NewConfig(nil, confutil.WithDir(tmpdir)))
|
2019-04-13 06:40:15 +08:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2023-10-19 18:31:24 +08:00
|
|
|
txn, release, err := s.Txn()
|
2019-04-13 06:40:15 +08:00
|
|
|
require.NoError(t, err)
|
2023-10-19 18:31:24 +08:00
|
|
|
defer release()
|
2019-04-13 06:40:15 +08:00
|
|
|
|
|
|
|
ng, err := txn.Current("foo")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Nil(t, ng)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestNodeLocking(t *testing.T) {
|
|
|
|
t.Parallel()
|
2022-03-10 08:46:06 +08:00
|
|
|
tmpdir, err := os.MkdirTemp("", "buildx-store")
|
2019-04-13 06:40:15 +08:00
|
|
|
require.NoError(t, err)
|
|
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
|
2024-10-18 19:28:45 +08:00
|
|
|
s, err := New(confutil.NewConfig(nil, confutil.WithDir(tmpdir)))
|
2019-04-13 06:40:15 +08:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
_, release, err := s.Txn()
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
ready := make(chan struct{})
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
_, release, err := s.Txn()
|
|
|
|
require.NoError(t, err)
|
|
|
|
release()
|
|
|
|
close(ready)
|
|
|
|
}()
|
|
|
|
|
|
|
|
select {
|
|
|
|
case <-time.After(100 * time.Millisecond):
|
|
|
|
case <-ready:
|
|
|
|
require.Fail(t, "transaction should have waited")
|
|
|
|
}
|
|
|
|
|
|
|
|
release()
|
|
|
|
select {
|
|
|
|
case <-time.After(200 * time.Millisecond):
|
|
|
|
require.Fail(t, "transaction should have completed")
|
|
|
|
case <-ready:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestNodeManagement(t *testing.T) {
|
|
|
|
t.Parallel()
|
2022-03-10 08:46:06 +08:00
|
|
|
tmpdir, err := os.MkdirTemp("", "buildx-store")
|
2019-04-13 06:40:15 +08:00
|
|
|
require.NoError(t, err)
|
|
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
|
2024-10-18 19:28:45 +08:00
|
|
|
s, err := New(confutil.NewConfig(nil, confutil.WithDir(tmpdir)))
|
2019-04-13 06:40:15 +08:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
txn, release, err := s.Txn()
|
|
|
|
require.NoError(t, err)
|
|
|
|
defer release()
|
|
|
|
|
|
|
|
err = txn.Save(&NodeGroup{
|
|
|
|
Name: "foo/bar",
|
|
|
|
Driver: "driver",
|
|
|
|
})
|
|
|
|
require.Error(t, err)
|
|
|
|
require.Contains(t, err.Error(), "invalid name")
|
|
|
|
|
|
|
|
err = txn.Save(&NodeGroup{
|
|
|
|
Name: "mybuild",
|
|
|
|
Driver: "mydriver",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
ng, err := txn.NodeGroupByName("mybuild")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, "mybuild", ng.Name)
|
|
|
|
require.Equal(t, "mydriver", ng.Driver)
|
2022-12-07 18:44:33 +08:00
|
|
|
require.True(t, !ng.LastActivity.IsZero())
|
2019-04-13 06:40:15 +08:00
|
|
|
|
|
|
|
_, err = txn.NodeGroupByName("mybuild2")
|
|
|
|
require.Error(t, err)
|
|
|
|
require.True(t, os.IsNotExist(errors.Cause(err)))
|
|
|
|
|
|
|
|
err = txn.Save(&NodeGroup{
|
|
|
|
Name: "mybuild2",
|
|
|
|
Driver: "mydriver2",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
ng, err = txn.NodeGroupByName("mybuild2")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, "mybuild2", ng.Name)
|
|
|
|
require.Equal(t, "mydriver2", ng.Driver)
|
|
|
|
|
|
|
|
// update existing
|
|
|
|
err = txn.Save(&NodeGroup{
|
|
|
|
Name: "mybuild",
|
|
|
|
Driver: "mydriver-mod",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
ng, err = txn.NodeGroupByName("mybuild")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, "mybuild", ng.Name)
|
|
|
|
require.Equal(t, "mydriver-mod", ng.Driver)
|
|
|
|
|
|
|
|
ngs, err := txn.List()
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, 2, len(ngs))
|
|
|
|
|
|
|
|
// test setting current
|
|
|
|
err = txn.SetCurrent("foo", "mybuild", false, false)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
ng, err = txn.Current("foo")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, ng)
|
|
|
|
require.Equal(t, "mybuild", ng.Name)
|
|
|
|
|
|
|
|
ng, err = txn.Current("foo")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, ng)
|
|
|
|
require.Equal(t, "mybuild", ng.Name)
|
|
|
|
|
|
|
|
ng, err = txn.Current("bar")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Nil(t, ng)
|
|
|
|
|
|
|
|
ng, err = txn.Current("foo")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Nil(t, ng)
|
|
|
|
|
|
|
|
// set with default
|
|
|
|
err = txn.SetCurrent("foo", "mybuild", false, true)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
ng, err = txn.Current("foo")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, ng)
|
|
|
|
require.Equal(t, "mybuild", ng.Name)
|
|
|
|
|
|
|
|
ng, err = txn.Current("bar")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Nil(t, ng)
|
|
|
|
|
|
|
|
ng, err = txn.Current("foo")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, ng)
|
|
|
|
require.Equal(t, "mybuild", ng.Name)
|
|
|
|
|
|
|
|
err = txn.SetCurrent("foo", "mybuild2", false, true)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
ng, err = txn.Current("foo")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, ng)
|
|
|
|
require.Equal(t, "mybuild2", ng.Name)
|
|
|
|
|
|
|
|
err = txn.SetCurrent("bar", "mybuild", false, false)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
ng, err = txn.Current("bar")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, ng)
|
|
|
|
require.Equal(t, "mybuild", ng.Name)
|
|
|
|
|
|
|
|
ng, err = txn.Current("foo")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, ng)
|
|
|
|
require.Equal(t, "mybuild2", ng.Name)
|
|
|
|
|
|
|
|
// set global
|
|
|
|
err = txn.SetCurrent("foo", "mybuild2", true, false)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
ng, err = txn.Current("foo")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, ng)
|
|
|
|
require.Equal(t, "mybuild2", ng.Name)
|
|
|
|
|
|
|
|
ng, err = txn.Current("bar")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, ng)
|
|
|
|
require.Equal(t, "mybuild2", ng.Name)
|
|
|
|
|
|
|
|
err = txn.SetCurrent("bar", "mybuild", false, false)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
ng, err = txn.Current("bar")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, ng)
|
|
|
|
require.Equal(t, "mybuild", ng.Name)
|
|
|
|
|
|
|
|
ng, err = txn.Current("foo")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Nil(t, ng)
|
|
|
|
|
|
|
|
err = txn.SetCurrent("bar", "mybuild", false, true)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
err = txn.SetCurrent("foo", "mybuild2", false, false)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// test removal
|
|
|
|
err = txn.Remove("mybuild2")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
_, err = txn.NodeGroupByName("mybuild2")
|
|
|
|
require.Error(t, err)
|
|
|
|
require.True(t, os.IsNotExist(errors.Cause(err)))
|
|
|
|
|
|
|
|
ng, err = txn.Current("foo")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Nil(t, ng)
|
|
|
|
|
|
|
|
ng, err = txn.Current("bar")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, ng)
|
|
|
|
require.Equal(t, "mybuild", ng.Name)
|
|
|
|
}
|
2023-06-14 18:07:31 +08:00
|
|
|
|
|
|
|
func TestNodeInvalidName(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
tmpdir := t.TempDir()
|
|
|
|
|
2024-10-18 19:28:45 +08:00
|
|
|
s, err := New(confutil.NewConfig(nil, confutil.WithDir(tmpdir)))
|
2023-06-14 18:07:31 +08:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
txn, release, err := s.Txn()
|
|
|
|
require.NoError(t, err)
|
|
|
|
defer release()
|
|
|
|
|
|
|
|
_, err = txn.NodeGroupByName("123builder")
|
|
|
|
require.Error(t, err)
|
|
|
|
require.True(t, IsErrInvalidName(err))
|
|
|
|
|
|
|
|
err = txn.Save(&NodeGroup{
|
|
|
|
Name: "123builder",
|
|
|
|
Driver: "mydriver",
|
|
|
|
})
|
|
|
|
require.Error(t, err)
|
|
|
|
require.True(t, IsErrInvalidName(err))
|
|
|
|
}
|