diff --git a/service/frontend/version_checker.go b/service/frontend/version_checker.go index eed8c4548a..03f7096c54 100644 --- a/service/frontend/version_checker.go +++ b/service/frontend/version_checker.go @@ -120,8 +120,17 @@ func (vc *VersionChecker) performVersionCheck( } func isUpdateNeeded(metadata *persistence.GetClusterMetadataResponse) bool { - return metadata.VersionInfo == nil || (metadata.VersionInfo.LastUpdateTime != nil && - metadata.VersionInfo.LastUpdateTime.AsTime().Before(time.Now().Add(-time.Hour))) + if metadata.VersionInfo == nil { + return true + } + // Check if the server version has changed since last version check. + // This ensures upgrade notifications are cleared after cluster upgrade. + if metadata.VersionInfo.Current == nil || + metadata.VersionInfo.Current.Version != headers.ServerVersion { + return true + } + return metadata.VersionInfo.LastUpdateTime != nil && + metadata.VersionInfo.LastUpdateTime.AsTime().Before(time.Now().Add(-time.Hour)) } func (vc *VersionChecker) createVersionCheckRequest(metadata *persistence.GetClusterMetadataResponse) (*versioninfo.VersionCheckRequest, error) { diff --git a/service/frontend/version_checker_test.go b/service/frontend/version_checker_test.go new file mode 100644 index 0000000000..63d574b900 --- /dev/null +++ b/service/frontend/version_checker_test.go @@ -0,0 +1,106 @@ +package frontend + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + versionpb "go.temporal.io/api/version/v1" + persistencespb "go.temporal.io/server/api/persistence/v1" + "go.temporal.io/server/common/headers" + "go.temporal.io/server/common/persistence" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func TestIsUpdateNeeded(t *testing.T) { + tests := []struct { + name string + metadata *persistence.GetClusterMetadataResponse + want bool + }{ + { + name: "nil VersionInfo returns true", + metadata: &persistence.GetClusterMetadataResponse{ + ClusterMetadata: &persistencespb.ClusterMetadata{ + VersionInfo: nil, + }, + }, + want: true, + }, + { + name: "nil Current returns true", + metadata: &persistence.GetClusterMetadataResponse{ + ClusterMetadata: &persistencespb.ClusterMetadata{ + VersionInfo: &versionpb.VersionInfo{ + Current: nil, + LastUpdateTime: timestamppb.New(time.Now()), + }, + }, + }, + want: true, + }, + { + name: "different server version returns true", + metadata: &persistence.GetClusterMetadataResponse{ + ClusterMetadata: &persistencespb.ClusterMetadata{ + VersionInfo: &versionpb.VersionInfo{ + Current: &versionpb.ReleaseInfo{ + Version: "0.0.0-old-version", + }, + LastUpdateTime: timestamppb.New(time.Now()), + }, + }, + }, + want: true, + }, + { + name: "same version with recent LastUpdateTime returns false", + metadata: &persistence.GetClusterMetadataResponse{ + ClusterMetadata: &persistencespb.ClusterMetadata{ + VersionInfo: &versionpb.VersionInfo{ + Current: &versionpb.ReleaseInfo{ + Version: headers.ServerVersion, + }, + LastUpdateTime: timestamppb.New(time.Now()), + }, + }, + }, + want: false, + }, + { + name: "same version with old LastUpdateTime returns true", + metadata: &persistence.GetClusterMetadataResponse{ + ClusterMetadata: &persistencespb.ClusterMetadata{ + VersionInfo: &versionpb.VersionInfo{ + Current: &versionpb.ReleaseInfo{ + Version: headers.ServerVersion, + }, + LastUpdateTime: timestamppb.New(time.Now().Add(-2 * time.Hour)), + }, + }, + }, + want: true, + }, + { + name: "same version with nil LastUpdateTime returns false", + metadata: &persistence.GetClusterMetadataResponse{ + ClusterMetadata: &persistencespb.ClusterMetadata{ + VersionInfo: &versionpb.VersionInfo{ + Current: &versionpb.ReleaseInfo{ + Version: headers.ServerVersion, + }, + LastUpdateTime: nil, + }, + }, + }, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := isUpdateNeeded(tt.metadata) + require.Equal(t, tt.want, got) + }) + } +}