package build import ( "bytes" "os" "runtime/debug" "strings" "testing" "time" "github.com/stretchr/testify/assert" ) func TestGetVersionUnixTimestamp(t *testing.T) { t1 := GetVersionUnixTimestamp() assert.NotZero(t, t1) time.Sleep(time.Millisecond * 100) t2 := GetVersionUnixTimestamp() assert.Equal(t, t1, t2) } func TestIsValidUnixVersion(t *testing.T) { assert.NotNil(t, IsValidUnixVersion(0)) assert.NotNil(t, IsValidUnixVersion(time.Now().Add(time.Second).UnixMilli())) assert.Nil(t, IsValidUnixVersion(1)) } func TestGetVersionTimestamp(t *testing.T) { // Test 1: First call should set the timestamp t1 := GetVersionTimestamp() if t1.IsZero() { t.Error("GetVersionTimestamp returned zero time") } // Test 2: Second call should return exactly the same time time.Sleep(time.Millisecond * 100) // Small delay to ensure time would be different if not cached t2 := GetVersionTimestamp() if !t1.Equal(t2) { t.Errorf("Timestamps should be identical but got t1=%v, t2=%v", t1, t2) } // Test 3: Even after a longer delay, should still return the same time time.Sleep(time.Second) // Longer delay t3 := GetVersionTimestamp() if !t1.Equal(t3) { t.Errorf("Timestamp changed after delay: original=%v, new=%v", t1, t3) } // Test 4: Returned time should not be in the future if t1.After(time.Now().UTC()) { t.Errorf("Timestamp is in the future: %v", t1) } } func TestGetStartTime(t *testing.T) { injectedTime := time.Now().UTC() injectTime := func() time.Time { return injectedTime } vcsTime := time.Now().UTC() t.Run("vcs time", func(t *testing.T) { var tt time.Time f := getStartTime(&tt, func() (info *debug.BuildInfo, ok bool) { return &debug.BuildInfo{ Settings: []debug.BuildSetting{ { Key: "vcs.time", Value: vcsTime.Format(time.RFC3339), }, }, }, true }, injectTime) assert.NotNil(t, f) f() assert.Equal(t, vcsTime.Truncate(time.Second), tt) }) t.Run("vcs time - invalid format", func(t *testing.T) { var tt time.Time // to make the test less likely to fail due to non deterministic temporal issues. f := getStartTime(&tt, func() (info *debug.BuildInfo, ok bool) { return &debug.BuildInfo{ Settings: []debug.BuildSetting{ { Key: "vcs.time", Value: "invalid", }, }, }, true }, injectTime) assert.NotNil(t, f) f() assert.Equal(t, injectedTime, tt) }) t.Run("vcs time - not available", func(t *testing.T) { var tt time.Time // to make the test less likely to fail due to non deterministic temporal issues. f := getStartTime(&tt, func() (info *debug.BuildInfo, ok bool) { return &debug.BuildInfo{ Settings: []debug.BuildSetting{ { Key: "vcs.time", Value: "invalid", }, }, }, true }, injectTime) assert.NotNil(t, f) f() assert.Equal(t, injectedTime, tt) }) } func TestGetVersion(t *testing.T) { // Test 1: Basic call version := GetVersion() if version == "" { t.Error("Version should not be empty") } // Test 2: Should either be "unknown" or follow semver-like pattern if version != "unknown" { // This is a loose check - you might want to make it more strict if len(version) < 3 { t.Errorf("Version '%s' seems too short to be valid", version) } } // Test 3: Multiple calls should be consistent version2 := GetVersion() if version != version2 { t.Errorf("Version not consistent between calls: '%s' != '%s'", version, version2) } } func TestGetGitCommit(t *testing.T) { // Test that GetGitCommit returns a non-empty string commit := GetGitCommit() if commit == "" { t.Error("Git commit should not be empty") } // In test environment, it should return the default value if commit != "unknown" && commit != gitCommit { t.Errorf("Unexpected commit value: %s", commit) } } func TestGetBuildTime(t *testing.T) { // Test that GetBuildTime returns a non-empty string bt := GetBuildTime() if bt == "" { t.Error("Build time should not be empty") } // In test environment, it should return the default value if bt != "unknown" && bt != buildTime { t.Errorf("Unexpected build time value: %s", bt) } } func TestPrintVersionInfo(t *testing.T) { // Save original stderr oldStderr := os.Stderr defer func() { os.Stderr = oldStderr }() // Create a pipe to capture stderr r, w, _ := os.Pipe() os.Stderr = w // Test 1: PrintVersionInfo with default values (devel) t.Run("with devel version", func(t *testing.T) { // Save original values originalVersion := version originalCommit := gitCommit originalBuildTime := buildTime // Set test values version = "(devel)" gitCommit = "testcommit" buildTime = "testtime" // Call PrintVersionInfo PrintVersionInfo("testService") // Close writer and read output w.Close() var buf bytes.Buffer _, err := buf.ReadFrom(r) if err != nil { t.Fatalf("Failed to read from pipe: %v", err) } output := buf.String() // Check output contains expected parts if !strings.Contains(output, "Starting testService") { t.Errorf("Output should contain service name, got: %s", output) } if !strings.Contains(output, "version=") { t.Errorf("Output should contain version, got: %s", output) } // Restore original values version = originalVersion gitCommit = originalCommit buildTime = originalBuildTime }) // Create new pipe for second test r2, w2, _ := os.Pipe() os.Stderr = w2 // Test 2: PrintVersionInfo with custom values t.Run("with custom version", func(t *testing.T) { // Save original values originalVersion := version originalCommit := gitCommit originalBuildTime := buildTime // Set test values version = "20231201.123456-abc123" gitCommit = "abc123def456" buildTime = "2023-12-01T12:34:56Z" // Call PrintVersionInfo PrintVersionInfo("customService") // Close writer and read output w2.Close() var buf bytes.Buffer _, err := buf.ReadFrom(r2) if err != nil { t.Fatalf("Failed to read from pipe: %v", err) } output := buf.String() // Check output contains all expected parts if !strings.Contains(output, "Starting customService") { t.Errorf("Output should contain service name, got: %s", output) } if !strings.Contains(output, "version=20231201.123456-abc123") { t.Errorf("Output should contain version, got: %s", output) } if !strings.Contains(output, "buildTime=2023-12-01T12:34:56Z") { t.Errorf("Output should contain build time, got: %s", output) } if !strings.Contains(output, "commit=abc123def456") { t.Errorf("Output should contain commit, got: %s", output) } // Restore original values version = originalVersion gitCommit = originalCommit buildTime = originalBuildTime }) }