212 lines
5.4 KiB
Go
212 lines
5.4 KiB
Go
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
|
|
}
|