Skip to content
Open
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
88 changes: 57 additions & 31 deletions chaoscenter/graphql/server/pkg/chaos_infrastructure/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/json"
"fmt"
"log"
"math"
"net/http"
"net/url"
"strconv"
Expand Down Expand Up @@ -906,53 +905,80 @@ func (in *infraService) GetVersionDetails() (*model.InfraVersionDetails, error)
return &model.InfraVersionDetails{}, fmt.Errorf("failed to parse InfraCompatibleVersions config: %w", err)
}

// To find the latest compatible version
compatibleMap := make(map[int]string)

// To store the compatible versions in int format
var compatibleArrayInt []int
latestVersion := ""
for _, version := range compatibleArray {
if latestVersion == "" {
latestVersion = version
continue
}

for _, versionStr := range compatibleArray {
versionInt, err := updateVersionFormat(versionStr)
comparison, err := compareInfraVersions(version, latestVersion)
if err != nil {
return &model.InfraVersionDetails{}, err
}

compatibleArrayInt = append(compatibleArrayInt, versionInt)
compatibleMap[versionInt] = versionStr
if comparison > 0 {
latestVersion = version
}
}

// Fetching the latest version
latestVersion := fetchLatestVersion(compatibleMap)
return &model.InfraVersionDetails{LatestVersion: compatibleMap[latestVersion], CompatibleVersions: compatibleArray}, nil
return &model.InfraVersionDetails{LatestVersion: latestVersion, CompatibleVersions: compatibleArray}, nil
}

// fetchLatestVersion returns the latest version available
func fetchLatestVersion(versions map[int]string) int {
var latestVersion int
for k := range versions {
if k > latestVersion {
latestVersion = k
func compareInfraVersions(version, otherVersion string) (int, error) {
if version == CIVersion && otherVersion == CIVersion {
return 0, nil
}
if version == CIVersion {
return -1, nil
}
if otherVersion == CIVersion {
return 1, nil
}

parsedVersion, err := parseInfraVersion(version)
if err != nil {
return 0, err
}

parsedOtherVersion, err := parseInfraVersion(otherVersion)
if err != nil {
return 0, err
}

for i := range parsedVersion {
if parsedVersion[i] > parsedOtherVersion[i] {
return 1, nil
}
if parsedVersion[i] < parsedOtherVersion[i] {
return -1, nil
}
}
return latestVersion

return 0, nil
}

// updateVersionFormat converts string array to int by removing decimal points, 1.0.0 will be returned as 100, 0.1.0 will be returned as 10, 0.0.1 will be returned as 1
func updateVersionFormat(str string) (int, error) {
if str == CIVersion {
return 0, nil
func parseInfraVersion(version string) ([3]int, error) {
version = strings.TrimSpace(version)
if version == CIVersion {
return [3]int{}, nil
}

versionParts := strings.Split(version, ".")
if len(versionParts) != 3 {
return [3]int{}, fmt.Errorf("invalid infra version %q: expected major.minor.patch", version)
}
var versionInt int
versionSlice := strings.Split(str, ".")
for i, val := range versionSlice {
x, err := strconv.Atoi(val)

var parsedVersion [3]int
for i, part := range versionParts {
versionPart, err := strconv.Atoi(strings.TrimSpace(part))
if err != nil {
return -1, err
return [3]int{}, fmt.Errorf("invalid infra version %q: %w", version, err)
}
Comment thread
immanuwell marked this conversation as resolved.
versionInt += x * int(math.Pow(10, float64(2-i)))
parsedVersion[i] = versionPart
}
return versionInt, nil

return parsedVersion, nil
}

// QueryServerVersion is used to fetch the version of the server
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package chaos_infrastructure

import (
"testing"

"github.com/litmuschaos/litmus/chaoscenter/graphql/server/utils"
)

func TestGetVersionDetailsSelectsLatestSemanticVersion(t *testing.T) {
previousCompatibleVersions := utils.Config.InfraCompatibleVersions
t.Cleanup(func() {
utils.Config.InfraCompatibleVersions = previousCompatibleVersions
})

utils.Config.InfraCompatibleVersions = `["3.29.0","4.0.0"]`

service := NewChaosInfrastructureService(nil, nil, nil)
versionDetails, err := service.GetVersionDetails()
if err != nil {
t.Fatalf("GetVersionDetails returned error: %v", err)
}

if versionDetails.LatestVersion != "4.0.0" {
t.Fatalf("expected latest version 4.0.0, got %q", versionDetails.LatestVersion)
}
}

func TestGetVersionDetailsTreatsCIVersionAsLowestVersion(t *testing.T) {
previousCompatibleVersions := utils.Config.InfraCompatibleVersions
t.Cleanup(func() {
utils.Config.InfraCompatibleVersions = previousCompatibleVersions
})
Comment thread
immanuwell marked this conversation as resolved.

utils.Config.InfraCompatibleVersions = `["ci","3.10.0"]`

service := NewChaosInfrastructureService(nil, nil, nil)
versionDetails, err := service.GetVersionDetails()
if err != nil {
t.Fatalf("GetVersionDetails returned error: %v", err)
}

if versionDetails.LatestVersion != "3.10.0" {
t.Fatalf("expected latest version 3.10.0, got %q", versionDetails.LatestVersion)
}
}

func TestGetVersionDetailsTreatsCIVersionAsLowerThanZeroVersion(t *testing.T) {
previousCompatibleVersions := utils.Config.InfraCompatibleVersions
t.Cleanup(func() {
utils.Config.InfraCompatibleVersions = previousCompatibleVersions
})

utils.Config.InfraCompatibleVersions = `["ci","0.0.0"]`

service := NewChaosInfrastructureService(nil, nil, nil)
versionDetails, err := service.GetVersionDetails()
if err != nil {
t.Fatalf("GetVersionDetails returned error: %v", err)
}

if versionDetails.LatestVersion != "0.0.0" {
t.Fatalf("expected latest version 0.0.0, got %q", versionDetails.LatestVersion)
}
}
Loading