loader revisited
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
package loader
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"galaxy/client/updater"
|
||||
"galaxy/connector"
|
||||
mc "galaxy/model/client"
|
||||
"galaxy/model/report"
|
||||
"galaxy/storage"
|
||||
"galaxy/storage/fs"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type stubConnector struct {
|
||||
versions []connector.VersionInfo
|
||||
versionErr error
|
||||
downloads map[string][]byte
|
||||
downloadErr error
|
||||
}
|
||||
|
||||
func (c *stubConnector) CheckConnection() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *stubConnector) CheckVersion() ([]connector.VersionInfo, error) {
|
||||
if c.versionErr != nil {
|
||||
return nil, c.versionErr
|
||||
}
|
||||
return c.versions, nil
|
||||
}
|
||||
|
||||
func (c *stubConnector) DownloadVersion(url string) ([]byte, error) {
|
||||
if c.downloadErr != nil {
|
||||
return nil, c.downloadErr
|
||||
}
|
||||
data, ok := c.downloads[url]
|
||||
if !ok {
|
||||
return nil, errors.New("missing download payload")
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (c *stubConnector) FetchReport(mc.GameID, uint, func(report.Report, error)) {}
|
||||
|
||||
type stubRunner struct {
|
||||
paths []string
|
||||
exitCode int
|
||||
err error
|
||||
}
|
||||
|
||||
func (r *stubRunner) Run(_ context.Context, path string) (int, error) {
|
||||
r.paths = append(r.paths, path)
|
||||
return r.exitCode, r.err
|
||||
}
|
||||
|
||||
func TestRunOnceFirstLaunchDownloadsAndPromotesVersion(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := newTestStorage(t)
|
||||
payload := []byte("ui-binary-1.2.3")
|
||||
info := connector.VersionInfo{
|
||||
OS: "windows",
|
||||
Arch: "amd64",
|
||||
Kind: connector.ArtifactKindExecutable,
|
||||
Version: "1.2.3",
|
||||
URL: "https://example.com/ui-1.2.3.exe",
|
||||
Checksum: connector.NewSHA256Digest(payload),
|
||||
}
|
||||
conn := &stubConnector{
|
||||
versions: []connector.VersionInfo{info},
|
||||
downloads: map[string][]byte{info.URL: payload},
|
||||
}
|
||||
runner := &stubRunner{}
|
||||
l := &loader{
|
||||
storage: s,
|
||||
connector: conn,
|
||||
updater: updater.NewManager(s, conn, updater.WithPlatform("windows", "amd64")),
|
||||
runner: runner,
|
||||
}
|
||||
|
||||
err := l.runOnce(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
state, err := s.LoadState()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "1.2.3", state.ClientCurrentVersion)
|
||||
require.Nil(t, state.ClientNextVersion)
|
||||
|
||||
expectedPath := filepath.Join(s.StorageRoot(), updater.ArtifactPath("1.2.3", "windows", "amd64", connector.ArtifactKindExecutable))
|
||||
require.Equal(t, []string{expectedPath}, runner.paths)
|
||||
}
|
||||
|
||||
func TestRunOnceSpawnFailureClearsPendingAndKeepsCurrent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := newTestStorage(t)
|
||||
currentPath := updater.ArtifactPath("1.0.0", "windows", "amd64", connector.ArtifactKindExecutable)
|
||||
require.NoError(t, s.WriteFile(currentPath, []byte("current")))
|
||||
require.NoError(t, s.SaveState(mc.State{ClientCurrentVersion: "1.0.0"}))
|
||||
|
||||
payload := []byte("ui-binary-1.1.0")
|
||||
info := connector.VersionInfo{
|
||||
OS: "windows",
|
||||
Arch: "amd64",
|
||||
Kind: connector.ArtifactKindExecutable,
|
||||
Version: "1.1.0",
|
||||
URL: "https://example.com/ui-1.1.0.exe",
|
||||
Checksum: connector.NewSHA256Digest(payload),
|
||||
}
|
||||
conn := &stubConnector{
|
||||
versions: []connector.VersionInfo{info},
|
||||
downloads: map[string][]byte{info.URL: payload},
|
||||
}
|
||||
manager := updater.NewManager(s, conn, updater.WithPlatform("windows", "amd64"))
|
||||
require.NoError(t, manager.CheckAndPrepareLatest())
|
||||
|
||||
l := &loader{
|
||||
storage: s,
|
||||
connector: conn,
|
||||
updater: manager,
|
||||
runner: &stubRunner{
|
||||
err: errors.New("spawn failed"),
|
||||
},
|
||||
}
|
||||
|
||||
err := l.runOnce(context.Background())
|
||||
require.Error(t, err)
|
||||
|
||||
state, err := s.LoadState()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "1.0.0", state.ClientCurrentVersion)
|
||||
require.Nil(t, state.ClientNextVersion)
|
||||
|
||||
currentExists, _, err := s.FileExists(currentPath)
|
||||
require.NoError(t, err)
|
||||
require.True(t, currentExists)
|
||||
|
||||
nextExists, _, err := s.FileExists(updater.ArtifactPath("1.1.0", "windows", "amd64", connector.ArtifactKindExecutable))
|
||||
require.NoError(t, err)
|
||||
require.False(t, nextExists)
|
||||
}
|
||||
|
||||
func TestRunOnceNonZeroExitClearsPendingAndKeepsCurrent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := newTestStorage(t)
|
||||
currentPath := updater.ArtifactPath("1.0.0", "windows", "amd64", connector.ArtifactKindExecutable)
|
||||
require.NoError(t, s.WriteFile(currentPath, []byte("current")))
|
||||
require.NoError(t, s.SaveState(mc.State{ClientCurrentVersion: "1.0.0"}))
|
||||
|
||||
payload := []byte("ui-binary-1.1.0")
|
||||
info := connector.VersionInfo{
|
||||
OS: "windows",
|
||||
Arch: "amd64",
|
||||
Kind: connector.ArtifactKindExecutable,
|
||||
Version: "1.1.0",
|
||||
URL: "https://example.com/ui-1.1.0.exe",
|
||||
Checksum: connector.NewSHA256Digest(payload),
|
||||
}
|
||||
conn := &stubConnector{
|
||||
versions: []connector.VersionInfo{info},
|
||||
downloads: map[string][]byte{info.URL: payload},
|
||||
}
|
||||
manager := updater.NewManager(s, conn, updater.WithPlatform("windows", "amd64"))
|
||||
require.NoError(t, manager.CheckAndPrepareLatest())
|
||||
|
||||
l := &loader{
|
||||
storage: s,
|
||||
connector: conn,
|
||||
updater: manager,
|
||||
runner: &stubRunner{
|
||||
exitCode: 23,
|
||||
},
|
||||
}
|
||||
|
||||
err := l.runOnce(context.Background())
|
||||
require.Error(t, err)
|
||||
|
||||
state, err := s.LoadState()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "1.0.0", state.ClientCurrentVersion)
|
||||
require.Nil(t, state.ClientNextVersion)
|
||||
|
||||
nextExists, _, err := s.FileExists(updater.ArtifactPath("1.1.0", "windows", "amd64", connector.ArtifactKindExecutable))
|
||||
require.NoError(t, err)
|
||||
require.False(t, nextExists)
|
||||
}
|
||||
|
||||
func newTestStorage(t *testing.T) *testStorage {
|
||||
t.Helper()
|
||||
|
||||
root := t.TempDir()
|
||||
s, err := fs.NewFS(root)
|
||||
require.NoError(t, err)
|
||||
|
||||
return &testStorage{Storage: s, root: root}
|
||||
}
|
||||
|
||||
type testStorage struct {
|
||||
storage.Storage
|
||||
root string
|
||||
}
|
||||
|
||||
func (s *testStorage) StorageRoot() string {
|
||||
return s.root
|
||||
}
|
||||
Reference in New Issue
Block a user