Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion internal/version/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io"
"net/http"
"os"
"sort"
"time"

Expand Down Expand Up @@ -101,7 +102,7 @@ func CheckLatestVersionOfCli(_ bool) (string, error) {
}

if latestVersion.GreaterThan(currentVersion) {
fmt.Printf("A new version (%s) is available. Update with: coolify update\n", latestVersion.String())
_, _ = fmt.Fprintf(os.Stderr, "A new version (%s) is available. Update with: coolify update\n", latestVersion.String())
}
return latestVersion.String(), nil
}
174 changes: 113 additions & 61 deletions internal/version/checker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,39 @@ import (
"testing"
)

func captureOutput(t *testing.T, fn func()) (string, string) {
t.Helper()

oldStdout := os.Stdout
oldStderr := os.Stderr

stdoutR, stdoutW, err := os.Pipe()
if err != nil {
t.Fatalf("os.Pipe() stdout error = %v", err)
}
stderrR, stderrW, err := os.Pipe()
if err != nil {
t.Fatalf("os.Pipe() stderr error = %v", err)
}

os.Stdout = stdoutW
os.Stderr = stderrW

fn()

_ = stdoutW.Close()
_ = stderrW.Close()
os.Stdout = oldStdout
os.Stderr = oldStderr

var stdoutBuf bytes.Buffer
var stderrBuf bytes.Buffer
_, _ = io.Copy(&stdoutBuf, stdoutR)
_, _ = io.Copy(&stderrBuf, stderrR)

return stdoutBuf.String(), stderrBuf.String()
}

func TestGetVersion(t *testing.T) {
v := GetVersion()
if v == "" {
Expand Down Expand Up @@ -42,19 +75,11 @@ func TestCheckLatestVersionOfCli_UpdateAvailable(t *testing.T) {

GitHubAPIURL = server.URL

// Capture stdout to check for update message
oldStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w

latestVersion, err := CheckLatestVersionOfCli(false)

_ = w.Close()
os.Stdout = oldStdout

var buf bytes.Buffer
_, _ = io.Copy(&buf, r)
output := buf.String()
var latestVersion string
var err error
stdout, stderr := captureOutput(t, func() {
latestVersion, err = CheckLatestVersionOfCli(false)
})

if err != nil {
t.Errorf("CheckLatestVersionOfCli() error = %v, want nil", err)
Expand All @@ -64,10 +89,15 @@ func TestCheckLatestVersionOfCli_UpdateAvailable(t *testing.T) {
t.Errorf("CheckLatestVersionOfCli() latestVersion = %q, want %q", latestVersion, "2.0.0")
}

// Should print update message
// Should not write anything to stdout
if stdout != "" {
t.Errorf("CheckLatestVersionOfCli() stdout = %q, want empty string", stdout)
}

// Should print update message to stderr
expectedMsg := "A new version (2.0.0) is available. Update with: coolify update\n"
if output != expectedMsg {
t.Errorf("CheckLatestVersionOfCli() output = %q, want %q", output, expectedMsg)
if stderr != expectedMsg {
t.Errorf("CheckLatestVersionOfCli() stderr = %q, want %q", stderr, expectedMsg)
}
}

Expand All @@ -92,19 +122,11 @@ func TestCheckLatestVersionOfCli_NoUpdate(t *testing.T) {

GitHubAPIURL = server.URL

// Capture stdout
oldStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w

latestVersion, err := CheckLatestVersionOfCli(false)

_ = w.Close()
os.Stdout = oldStdout

var buf bytes.Buffer
_, _ = io.Copy(&buf, r)
output := buf.String()
var latestVersion string
var err error
stdout, stderr := captureOutput(t, func() {
latestVersion, err = CheckLatestVersionOfCli(false)
})

if err != nil {
t.Errorf("CheckLatestVersionOfCli() error = %v, want nil", err)
Expand All @@ -116,8 +138,12 @@ func TestCheckLatestVersionOfCli_NoUpdate(t *testing.T) {
}

// Should NOT print any message when already on latest (current v99.99.99 > latest v2.0.0)
if output != "" {
t.Errorf("CheckLatestVersionOfCli() should not print anything when on latest version, got: %q", output)
if stdout != "" {
t.Errorf("CheckLatestVersionOfCli() should not write to stdout when on latest version, got: %q", stdout)
}

if stderr != "" {
t.Errorf("CheckLatestVersionOfCli() should not write to stderr when on latest version, got: %q", stderr)
}
}

Expand All @@ -137,19 +163,11 @@ func TestCheckLatestVersionOfCli_APIError_SilentFail(t *testing.T) {

GitHubAPIURL = server.URL

// Capture stdout
oldStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w

latestVersion, err := CheckLatestVersionOfCli(false)

_ = w.Close()
os.Stdout = oldStdout

var buf bytes.Buffer
_, _ = io.Copy(&buf, r)
output := buf.String()
var latestVersion string
var err error
stdout, stderr := captureOutput(t, func() {
latestVersion, err = CheckLatestVersionOfCli(false)
})

// Should return empty string and nil error (silent fail)
if err != nil {
Expand All @@ -161,8 +179,12 @@ func TestCheckLatestVersionOfCli_APIError_SilentFail(t *testing.T) {
}

// Should NOT print anything on error
if output != "" {
t.Errorf("CheckLatestVersionOfCli() should not print anything on API error, got: %q", output)
if stdout != "" {
t.Errorf("CheckLatestVersionOfCli() should not print anything to stdout on API error, got: %q", stdout)
}

if stderr != "" {
t.Errorf("CheckLatestVersionOfCli() should not print anything to stderr on API error, got: %q", stderr)
}
}

Expand All @@ -176,19 +198,11 @@ func TestCheckLatestVersionOfCli_NetworkError_SilentFail(t *testing.T) {
// Use invalid URL to cause network error
GitHubAPIURL = "http://localhost:1" // Port 1 should fail to connect

// Capture stdout
oldStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w

latestVersion, err := CheckLatestVersionOfCli(false)

_ = w.Close()
os.Stdout = oldStdout

var buf bytes.Buffer
_, _ = io.Copy(&buf, r)
output := buf.String()
var latestVersion string
var err error
stdout, stderr := captureOutput(t, func() {
latestVersion, err = CheckLatestVersionOfCli(false)
})

// Should return empty string and nil error (silent fail)
if err != nil {
Expand All @@ -200,8 +214,46 @@ func TestCheckLatestVersionOfCli_NetworkError_SilentFail(t *testing.T) {
}

// Should NOT print anything on error
if output != "" {
t.Errorf("CheckLatestVersionOfCli() should not print anything on network error, got: %q", output)
if stdout != "" {
t.Errorf("CheckLatestVersionOfCli() should not print anything to stdout on network error, got: %q", stdout)
}

if stderr != "" {
t.Errorf("CheckLatestVersionOfCli() should not print anything to stderr on network error, got: %q", stderr)
}
}

func TestCheckLatestVersionOfCli_UpdateAvailable_LeavesStdoutAvailableForJSON(t *testing.T) {
originalURL := GitHubAPIURL
originalVersion := version
defer func() {
GitHubAPIURL = originalURL
version = originalVersion
}()

version = "v0.0.1"

server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`[{"ref":"refs/tags/v2.0.0"}]`))
}))
defer server.Close()

GitHubAPIURL = server.URL

stdout, stderr := captureOutput(t, func() {
_, _ = CheckLatestVersionOfCli(false)
_, _ = os.Stdout.WriteString(`[{"uuid":"demo"}]` + "\n")
})

expectedStdout := `[{"uuid":"demo"}]` + "\n"
if stdout != expectedStdout {
t.Fatalf("stdout = %q, want %q", stdout, expectedStdout)
}

expectedStderr := "A new version (2.0.0) is available. Update with: coolify update\n"
if stderr != expectedStderr {
t.Fatalf("stderr = %q, want %q", stderr, expectedStderr)
}
}

Expand Down
Loading