This repository was archived by the owner on Aug 30, 2024. It is now read-only.
- Notifications
You must be signed in to change notification settings - Fork18
feat: Add update command to coder-cli#417
Merged
Uh oh!
There was an error while loading.Please reload this page.
Merged
Changes from1 commit
Commits
Show all changes
26 commits Select commitHold shift + click to select a range
d256581
feat: Add update command to coder-cli
johnstcn972847e
internal/cmd/update_test.go: refactor unit tests
johnstcn597afe1
fixup! internal/cmd/update_test.go: refactor unit tests
johnstcn1373e79
internal/cmd/update_test.go: more tests
johnstcn513282a
internal/cmd/update_test.go: create dirs in memfs
johnstcn5bf7f56
internal/cmd/update_test.go: test for windows
johnstcndabd178
fixup! internal/cmd/update_test.go: test for windows
johnstcndcfeec1
internal/cmd/update.go: replace semver library
johnstcn0801cfc
internal/cmd/update.go: use /api/private/version instead of sniffing …
johnstcnf6ce76f
gendocs
johnstcn6371084
internal/cmd/update.go: use os.Executable() instead of os.Args[0]
johnstcnbdb998e
internal/cmd/update.go: check path prefixes
johnstcn306686c
lint
johnstcn60a75a1
internal/cmd/update_test.go: assertCLIError helper function for clog.…
johnstcn26984a2
internal/cmd/update.go: allow explicitly specifying version
johnstcnbcaac7b
internal/cmd/update.go: validate we can exec new binary
johnstcn2002876
fixup! internal/cmd/update.go: validate we can exec new binary
johnstcn3ba1bed
internal/cmd/update.go: query github releases api for assets
johnstcn6238053
internal/cmd/update.go: handle copy error from archive
johnstcn24df4f7
internal/cmd/update.go: handle windows-specific behaviours
johnstcn21dd836
fixup! internal/cmd/update.go: handle windows-specific behaviours
johnstcne064c47
fixup! internal/cmd/update.go: handle windows-specific behaviours
johnstcneefa2f3
gofmt
johnstcn0e63d2f
internal/cmd/users_test.go: assert CICD user instead of admin
johnstcn60944f0
Revert "internal/cmd/users_test.go: assert CICD user instead of admin"
johnstcnc8943ed
Merge branch 'master' into cianjohnston/autoupdate
johnstcnFile filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
internal/cmd/update_test.go: create dirs in memfs
- Loading branch information
Uh oh!
There was an error while loading.Please reload this page.
commit513282af1c9b3ce47bdfea8446bc6579dfda9b1c
There are no files selected for viewing
83 changes: 44 additions & 39 deletionsinternal/cmd/update_test.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -9,6 +9,7 @@ import ( | ||
"net" | ||
"net/http" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
"testing" | ||
@@ -18,11 +19,11 @@ import ( | ||
) | ||
const ( | ||
fakeExePathLinux= "/home/user/bin/coder" | ||
fakeCoderURL= "https://my.cdr.dev" | ||
fakeNewVersion= "1.23.4-rc.5+678-gabcdef-12345678" | ||
fakeOldVersion= "1.22.4-rc.5+678-gabcdef-12345678" | ||
fakeReleaseURL= "https://github.com/cdr/coder-cli/releases/download/v1.23.4/coder-cli-linux-amd64.tar.gz" | ||
) | ||
func Test_updater_run(t *testing.T) { | ||
johnstcn marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
@@ -61,7 +62,7 @@ func Test_updater_run(t *testing.T) { | ||
return "", nil | ||
}, | ||
Ctx: ctx, | ||
ExecutablePath:fakeExePathLinux, | ||
Fakefs: fakefs, | ||
HttpClient: newFakeGetter(t), | ||
// This must be overridden inside run() | ||
@@ -76,51 +77,51 @@ func Test_updater_run(t *testing.T) { | ||
} | ||
run(t, "update coder - noop", func(t *testing.T, p *params) { | ||
fakeFile(t, p.Fakefs,fakeExePathLinux, 0755, fakeNewVersion) | ||
p.HttpClient.M[fakeCoderURL+"/api"] = newFakeGetterResponse([]byte{}, 401, variadicS("coder-version: "+fakeNewVersion), nil) | ||
p.VersionF = func() string { return fakeNewVersion } | ||
u := fromParams(p) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeNewVersion) | ||
err := u.Run(p.Ctx, false, fakeCoderURL) | ||
assert.Success(t, "update coder - noop", err) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeNewVersion) | ||
}) | ||
run(t, "update coder - old to new", func(t *testing.T, p *params) { | ||
fakeFile(t, p.Fakefs,fakeExePathLinux, 0755, fakeOldVersion) | ||
p.HttpClient.M[fakeCoderURL+"/api"] = newFakeGetterResponse([]byte{}, 401, variadicS("coder-version: "+fakeNewVersion), nil) | ||
p.HttpClient.M[fakeReleaseURL] = newFakeGetterResponse(fakeValidTgzBytes, 200, variadicS(), nil) | ||
p.VersionF = func() string { return fakeOldVersion } | ||
p.ConfirmF = fakeConfirmYes | ||
u := fromParams(p) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
err := u.Run(p.Ctx, false, fakeCoderURL) | ||
assert.Success(t, "update coder - old to new", err) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeNewVersion) | ||
}) | ||
run(t, "update coder - old to new forced", func(t *testing.T, p *params) { | ||
fakeFile(t, p.Fakefs,fakeExePathLinux, 0755, fakeOldVersion) | ||
p.HttpClient.M[fakeCoderURL+"/api"] = newFakeGetterResponse([]byte{}, 401, variadicS("coder-version: "+fakeNewVersion), nil) | ||
p.HttpClient.M[fakeReleaseURL] = newFakeGetterResponse(fakeValidTgzBytes, 200, variadicS(), nil) | ||
p.VersionF = func() string { return fakeOldVersion } | ||
u := fromParams(p) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
err := u.Run(p.Ctx, true, fakeCoderURL) | ||
assert.Success(t, "update coder - old to new forced", err) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeNewVersion) | ||
}) | ||
run(t, "update coder - user cancelled", func(t *testing.T, p *params) { | ||
fakeFile(t, p.Fakefs,fakeExePathLinux, 0755, fakeOldVersion) | ||
p.HttpClient.M[fakeCoderURL+"/api"] = newFakeGetterResponse([]byte{}, 401, variadicS("coder-version: "+fakeNewVersion), nil) | ||
p.VersionF = func() string { return fakeOldVersion } | ||
p.ConfirmF = fakeConfirmNo | ||
u := fromParams(p) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
err := u.Run(p.Ctx, false, fakeCoderURL) | ||
assert.ErrorContains(t, "update coder - user cancelled", err, "failed to confirm update") | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
}) | ||
run(t, "update coder - cannot stat", func(t *testing.T, p *params) { | ||
@@ -130,87 +131,87 @@ func Test_updater_run(t *testing.T) { | ||
}) | ||
run(t, "update coder - no permission", func(t *testing.T, p *params) { | ||
fakeFile(t, p.Fakefs,fakeExePathLinux, 0400, fakeOldVersion) | ||
u := fromParams(p) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
err := u.Run(p.Ctx, false, fakeCoderURL) | ||
assert.ErrorContains(t, "update coder - no permission", err, "missing write permission") | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
}) | ||
run(t, "update coder - invalid url", func(t *testing.T, p *params) { | ||
fakeFile(t, p.Fakefs,fakeExePathLinux, 0755, fakeOldVersion) | ||
p.VersionF = func() string { return fakeOldVersion } | ||
u := fromParams(p) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
err := u.Run(p.Ctx, false, "h$$p://invalid.url") | ||
assert.ErrorContains(t, "update coder - invalid url", err, "invalid coder URL") | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
}) | ||
run(t, "update coder - fetch api version failure", func(t *testing.T, p *params) { | ||
fakeFile(t, p.Fakefs,fakeExePathLinux, 0755, fakeOldVersion) | ||
p.HttpClient.M[fakeCoderURL+"/api"] = newFakeGetterResponse([]byte{}, 401, variadicS(), net.ErrClosed) | ||
p.VersionF = func() string { return fakeOldVersion } | ||
u := fromParams(p) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
err := u.Run(p.Ctx, false, fakeCoderURL) | ||
assert.ErrorContains(t, "update coder - fetch api version failure", err, "fetch api version") | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
}) | ||
run(t, "update coder - failed to fetch URL", func(t *testing.T, p *params) { | ||
fakeFile(t, p.Fakefs,fakeExePathLinux, 0755, fakeOldVersion) | ||
p.HttpClient.M[fakeCoderURL+"/api"] = newFakeGetterResponse([]byte{}, 401, variadicS("coder-version: "+fakeNewVersion), nil) | ||
p.HttpClient.M[fakeReleaseURL] = newFakeGetterResponse([]byte{}, 0, variadicS(), net.ErrClosed) | ||
p.VersionF = func() string { return fakeOldVersion } | ||
p.ConfirmF = fakeConfirmYes | ||
u := fromParams(p) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
err := u.Run(p.Ctx, false, fakeCoderURL) | ||
assert.ErrorContains(t, "update coder - release URL 404", err, "failed to fetch URL") | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
}) | ||
run(t, "update coder - release URL 404", func(t *testing.T, p *params) { | ||
fakeFile(t, p.Fakefs,fakeExePathLinux, 0755, fakeOldVersion) | ||
p.HttpClient.M[fakeCoderURL+"/api"] = newFakeGetterResponse([]byte{}, 401, variadicS("coder-version: "+fakeNewVersion), nil) | ||
p.HttpClient.M[fakeReleaseURL] = newFakeGetterResponse([]byte{}, 404, variadicS(), nil) | ||
p.VersionF = func() string { return fakeOldVersion } | ||
p.ConfirmF = fakeConfirmYes | ||
u := fromParams(p) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
err := u.Run(p.Ctx, false, fakeCoderURL) | ||
assert.ErrorContains(t, "update coder - release URL 404", err, "failed to fetch release") | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
}) | ||
run(t, "update coder - invalid archive", func(t *testing.T, p *params) { | ||
fakeFile(t, p.Fakefs,fakeExePathLinux, 0755, fakeOldVersion) | ||
p.HttpClient.M[fakeCoderURL+"/api"] = newFakeGetterResponse([]byte{}, 401, variadicS("coder-version: "+fakeNewVersion), nil) | ||
p.HttpClient.M[fakeReleaseURL] = newFakeGetterResponse([]byte{}, 200, variadicS(), nil) | ||
p.VersionF = func() string { return fakeOldVersion } | ||
p.ConfirmF = fakeConfirmYes | ||
u := fromParams(p) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
err := u.Run(p.Ctx, false, fakeCoderURL) | ||
assert.ErrorContains(t, "update coder - invalid archive", err, "failed to extract coder binary from archive") | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
}) | ||
run(t, "update coder - read-only fs", func(t *testing.T, p *params) { | ||
rwfs := p.Fakefs | ||
p.Fakefs = afero.NewReadOnlyFs(rwfs) | ||
fakeFile(t, rwfs,fakeExePathLinux, 0755, fakeOldVersion) | ||
p.HttpClient.M[fakeCoderURL+"/api"] = newFakeGetterResponse([]byte{}, 401, variadicS("coder-version: "+fakeNewVersion), nil) | ||
p.HttpClient.M[fakeReleaseURL] = newFakeGetterResponse(fakeValidTgzBytes, 200, variadicS(), nil) | ||
p.VersionF = func() string { return fakeOldVersion } | ||
p.ConfirmF = fakeConfirmYes | ||
u := fromParams(p) | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
err := u.Run(p.Ctx, false, fakeCoderURL) | ||
assert.ErrorContains(t, "update coder - read-only fs", err, "failed to create file") | ||
assertFileContent(t, p.Fakefs,fakeExePathLinux, fakeOldVersion) | ||
}) | ||
} | ||
@@ -278,6 +279,10 @@ func fakeConfirmNo(_ string) (string, error) { | ||
//nolint:unparam | ||
func fakeFile(t *testing.T, fs afero.Fs, name string, perm fs.FileMode, content string) { | ||
t.Helper() | ||
err := fs.MkdirAll(filepath.Dir(name), 0750) | ||
if err != nil { | ||
panic(err) | ||
} | ||
f, err := fs.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perm) | ||
if err != nil { | ||
panic(err) | ||
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.