Skip to content

Commit

Permalink
Add functions to get and compare PFMP version
Browse files Browse the repository at this point in the history
- Add functions to get and compare PFMP version
- Exclude IT from the new github action
  • Loading branch information
baoy1 committed Nov 15, 2024
1 parent 2bc6adc commit f849bad
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/common-workflows.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ jobs:
common:
name: Quality Checks
uses: dell/common-github-actions/.github/workflows/go-common.yml@main
with:
exclude-directory: "inttests"
102 changes: 102 additions & 0 deletions lcm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright © 2024 Dell Inc. or its subsidiaries. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package goscaleio

import (
"fmt"
"net/http"
"strconv"
"strings"
"time"

types "github.com/dell/goscaleio/types/v1"
)

// CheckPfmpVersion checks if the PFMP version is greater than the given version
// Returns -1 if PFMP version < the given version,
// Returns 1 if PFMP version > the given version,
// Returns 0 if PFMP version == the given version.
func CheckPfmpVersion(client *Client, version string) (int, error) {
defer TimeSpent("CheckPfmpVersion", time.Now())

lcmStatus, err := GetPfmpStatus(*client)
if err != nil {
return -1, fmt.Errorf("failed to get PFMP version : %v", err)
}

result, err := CompareVersion(lcmStatus.ClusterVersion, version)
if err != nil {
return -1, err
}
return result, nil
}

// GetPfmpStatus gets the PFMP status
func GetPfmpStatus(client Client) (*types.LcmStatus, error) {
defer TimeSpent("GetPfmpStatus", time.Now())

path := "/Api/V1/corelcm/status"

var status types.LcmStatus
err := client.getJSONWithRetry(
http.MethodGet, path, nil, &status)
if err != nil {
return nil, err
}

return &status, nil
}

// CompareVersion compares two version strings.
// Returns -1 if versionA < versionB,
// Returns 1 if versionA > versionB,
// Returns 0 if versionA == versionB.
func CompareVersion(versionA, versionB string) (int, error) {
partsA := strings.Split(versionA, ".")
partsB := strings.Split(versionB, ".")

maxLength := len(partsA)
if len(partsB) > maxLength {
maxLength = len(partsB)
}

// Compare each part of the versions
for i := 0; i < maxLength; i++ {
var partA, partB int
var err error

if i < len(partsA) {
partA, err = strconv.Atoi(partsA[i])
if err != nil {
err := fmt.Errorf("error parsing part PFMP version: %s", versionA)
return -1, err
}
}

if i < len(partsB) {
partB, err = strconv.Atoi(partsB[i])
if err != nil {
err := fmt.Errorf("error parsing part PFMP version: %s", versionB)
return -1, err
}
}

if partA < partB {
return -1, nil
} else if partA > partB {
return 1, nil
}
}

return 0, nil
}
149 changes: 149 additions & 0 deletions lcm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright © 2024 Dell Inc. or its subsidiaries. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package goscaleio

import (
"math"
"net/http"
"net/http/httptest"
"strings"
"testing"

"github.com/stretchr/testify/assert"
)

func Test_CheckPfmpVersion(t *testing.T) {
type checkFn func(*testing.T, int, error)
check := func(fns ...checkFn) []checkFn { return fns }

hasNoError := func(t *testing.T, _ int, err error) {
if err != nil {
t.Fatalf("expected no error")
}
}

checkVersionEqual := func(t *testing.T, result int, _ error) {
assert.Equal(t, result, 0)
}

checkVersionGreaterThan := func(t *testing.T, result int, _ error) {
assert.Equal(t, result, 1)
}

checkVersionLessThan := func(t *testing.T, result int, _ error) {
assert.Equal(t, result, -1)
}

hasError := func(t *testing.T, _ int, err error) {
if err == nil {
t.Fatalf("expected error")
}
}

tests := map[string]func(t *testing.T) (*httptest.Server, string, []checkFn){
"PFMP version == 4.6": func(t *testing.T) (*httptest.Server, string, []checkFn) {
url := "/Api/V1/corelcm/status"
responseJSON := `{
"lcmStatus": "READY",
"clusterVersion": "4.6.0.0",
"clusterBuild": "1258"
}`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet && strings.EqualFold(r.URL.Path, url) {
w.WriteHeader(http.StatusOK)
_, err := w.Write([]byte(responseJSON))
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
return
}
http.NotFound(w, r)
}))
return server, "4.6", check(hasNoError, checkVersionEqual)
},
"PFMP version > 4.6": func(t *testing.T) (*httptest.Server, string, []checkFn) {
url := "/Api/V1/corelcm/status"
responseJSON := `{
"lcmStatus": "READY",
"clusterVersion": "4.7.0.0",
"clusterBuild": "1258"
}`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet && strings.EqualFold(r.URL.Path, url) {
w.WriteHeader(http.StatusOK)
_, err := w.Write([]byte(responseJSON))
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
return
}
http.NotFound(w, r)
}))
return server, "4.6.0.0", check(hasNoError, checkVersionGreaterThan)
},
"PFMP version < 4.6": func(t *testing.T) (*httptest.Server, string, []checkFn) {
url := "/Api/V1/corelcm/status"
responseJSON := `{
"lcmStatus": "READY",
"clusterVersion": "4.5.0.0",
"clusterBuild": "1258"
}`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet && strings.EqualFold(r.URL.Path, url) {
w.WriteHeader(http.StatusOK)
_, err := w.Write([]byte(responseJSON))
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
return
}
http.NotFound(w, r)
}))
return server, "4.6", check(hasNoError, checkVersionLessThan)
},
"wrong version": func(t *testing.T) (*httptest.Server, string, []checkFn) {
url := "/Api/V1/corelcm/status"
responseJSON := `{
"lcmStatus": "READY",
"clusterVersion": "4.5.0.0",
"clusterBuild": "1258"
}`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet && strings.EqualFold(r.URL.Path, url) {
w.WriteHeader(http.StatusOK)
_, err := w.Write([]byte(responseJSON))
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
return
}
http.NotFound(w, r)
}))
return server, "4.a.b.c", check(hasError)
},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
server, version, checkFns := tc(t)
defer server.Close()

client, _ := NewClientWithArgs(server.URL, "", math.MaxInt64, true, false)
result, err := CheckPfmpVersion(client, version)

for _, checkFn := range checkFns {
checkFn(t, result, err)
}
})
}
}
7 changes: 7 additions & 0 deletions types/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2184,3 +2184,10 @@ type NvmeController struct {
IsAssigned bool `json:"isAssigned"`
ID string `json:"id"`
}

// LcmStatus defines struct for PFMP status
type LcmStatus struct {
LcmStatus string `json:"lcmStatus"`
ClusterVersion string `json:"clusterVersion"`
ClusterBuild string `json:"clusterBuild"`
}

0 comments on commit f849bad

Please sign in to comment.