Skip to content

Commit

Permalink
Add support for sdt
Browse files Browse the repository at this point in the history
  • Loading branch information
baoy1 committed Nov 6, 2024
1 parent dee1fb6 commit 02b95d6
Show file tree
Hide file tree
Showing 8 changed files with 1,600 additions and 2 deletions.
6 changes: 5 additions & 1 deletion inttests/GOSCALEIO_TEST.env_example
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,8 @@ GOSCALEIO_REPLICATION_TARGET_NAME=replication-target
GATEWAY_ENDPOINT=https://1.2.3.4:443
GATEWAY_USERNAME=admin
GATEWAY_PASSWORD=Password123
GATEWAY_INSECURE=true
GATEWAY_INSECURE=true

# SDT Variables
NVME_TARGET_IP1=
NVME_TARGET_IP2=
6 changes: 6 additions & 0 deletions inttests/nvme_host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ func TestNvmeHost(t *testing.T) {
assert.Nil(t, err)
})

t.Run("Get Host NVMe Controllers", func(t *testing.T) {
controllers, err := system.GetHostNvmeControllers(types.NvmeHost{ID: hostID})
assert.Nil(t, err)
assert.NotNil(t, controllers)
})

t.Cleanup(func() {
err := system.DeleteNvmeHost(hostID)
assert.Nil(t, err)
Expand Down
121 changes: 121 additions & 0 deletions inttests/sdt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// 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 inttests

import (
"fmt"
"os"
"testing"
"time"

types "github.com/dell/goscaleio/types/v1"
"github.com/stretchr/testify/assert"
)

func TestSdt(t *testing.T) {
system := getSystem()
name := fmt.Sprintf("example-sdt_%v", randString(5))
newName := fmt.Sprintf("example-sdt_%v", randString(10))
var sdtID string

t.Run("Create sdt", func(t *testing.T) {
assert.NotNil(t, system)
pd := getProtectionDomain(t)
assert.NotNil(t, pd)
targetIP1 := os.Getenv("NVME_TARGET_IP1")
targetIP2 := os.Getenv("NVME_TARGET_IP2")
sdtParam := &types.SdtParam{
Name: name,
IPList: []*types.SdtIP{{IP: targetIP1, Role: "StorageAndHost"}, {IP: targetIP2, Role: "StorageAndHost"}},
StoragePort: 12200,
NvmePort: 4420,
DiscoveryPort: 8009,
ProtectionDomainID: pd.ProtectionDomain.ID,
}
resp, err := pd.CreateSdt(sdtParam)
assert.Nil(t, err)
assert.NotNil(t, resp.ID)
sdtID = resp.ID
})

t.Run("Remove Sdt Target IP", func(t *testing.T) {
targetIP := os.Getenv("NVME_TARGET_IP2")
err := system.RemoveSdtTargetIP(sdtID, targetIP)
assert.Nil(t, err)
})

t.Run("Add Sdt Target IP", func(t *testing.T) {
targetIP := os.Getenv("NVME_TARGET_IP2")
err := system.AddSdtTargetIP(sdtID, targetIP, "StorageAndHost")
assert.Nil(t, err)
})

t.Run("Get All Sdt", func(t *testing.T) {
hosts, err := system.GetAllSdts()
assert.Nil(t, err)
assert.NotNil(t, hosts)
})

t.Run("Get Sdt By ID", func(t *testing.T) {
host, err := system.GetSdtByID(sdtID)
assert.Nil(t, err)
assert.NotNil(t, host)
})

t.Run("Rename Sdt", func(t *testing.T) {
err := system.RenameSdt(sdtID, newName)
assert.Nil(t, err)
})

t.Run("Set Sdt NvmePort", func(t *testing.T) {
err := system.SetSdtNvmePort(sdtID, 4422)
assert.Nil(t, err)
})

t.Run("Set Sdt StoragePort", func(t *testing.T) {
err := system.SetSdtStoragePort(sdtID, 12300)
assert.Nil(t, err)
})

t.Run("Set Sdt DiscoveryPort", func(t *testing.T) {
err := system.SetSdtDiscoveryPort(sdtID, 8010)
assert.Nil(t, err)
})

t.Run("Modify Sdt IP and Role", func(t *testing.T) {
targetIP := os.Getenv("NVME_TARGET_IP2")
err := system.ModifySdtIPRole(sdtID, targetIP, "StorageOnly")
assert.Nil(t, err)
})

t.Run("Rollback Sdt StoragePort", func(t *testing.T) {
err := system.SetSdtStoragePort(sdtID, 12200)
assert.Nil(t, err)
})

t.Run("Enter Sdt Maintenance Mode", func(t *testing.T) {
err := system.EnterSdtMaintenanceMode(sdtID)
assert.Nil(t, err)
})

t.Run("Exit Sdt Maintenance Mode", func(t *testing.T) {
err := system.ExitSdtMaintenanceMode(sdtID)
assert.Nil(t, err)
time.Sleep(5 * time.Second)
})

t.Cleanup(func() {
err := system.DeleteNvmeHost(sdtID)
assert.Nil(t, err)
})
}
11 changes: 11 additions & 0 deletions nvme_host.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,14 @@ func (s *System) DeleteNvmeHost(id string) error {
}
return nil
}

// GetHostNvmeControllers returns all attached NVMe controllers
func (s *System) GetHostNvmeControllers(host types.NvmeHost) ([]types.NvmeController, error) {
defer TimeSpent("GetHostNvmeControllers", time.Now())
path := fmt.Sprintf("api/instances/Host::%v/relationships/NvmeController", host.ID)

var nvmeControllers []types.NvmeController
err := s.client.getJSONWithRetry(
http.MethodGet, path, nil, &nvmeControllers)
return nvmeControllers, err
}
118 changes: 117 additions & 1 deletion nvme_host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ func Test_ChangeNvmeHostMaxNumSysPorts(t *testing.T) {
}
}

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

Expand Down Expand Up @@ -606,3 +606,119 @@ func Test_RemoveNvmeHost(t *testing.T) {
})
}
}

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

responseJSON := `[
{
"name": null,
"isConnected": true,
"sdtId": "cd16ff4300000000",
"hostIp": null,
"hostId": "4d2a627100010000",
"controllerId": 1,
"sysPortId": 2,
"sysPortIp": "10.0.0.22",
"subsystem": "Io",
"isAssigned": true,
"id": "cc00000001000011",
"links": [
{
"rel": "self",
"href": "/api/instances/NvmeController::cc00000001000011"
}
]
}]`

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

checkLength := func(length int) func(t *testing.T, slice []types.NvmeController, err error) {
return func(t *testing.T, slice []types.NvmeController, _ error) {
assert.Equal(t, length, len(slice))
}
}

checkSdtID := func(index int, id string) func(t *testing.T, slice []types.NvmeController, err error) {
return func(t *testing.T, slice []types.NvmeController, _ error) {
assert.Equal(t, slice[index].SdtID, id)
}
}

checkHostID := func(index int, id string) func(t *testing.T, slice []types.NvmeController, err error) {
return func(t *testing.T, slice []types.NvmeController, _ error) {
assert.Equal(t, slice[index].HostID, id)
}
}

checkConnected := func(index int, connected bool) func(t *testing.T, slice []types.NvmeController, err error) {
return func(t *testing.T, slice []types.NvmeController, _ error) {
assert.Equal(t, slice[index].IsConnected, connected)
}
}

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

tests := map[string]func(t *testing.T) (*httptest.Server, types.System, []checkFn){
"success": func(_ *testing.T) (*httptest.Server, types.System, []checkFn) {
systemID := "mock-system-id"
id := "mock-id"
url := fmt.Sprintf("/api/instances/Host::%v/relationships/NvmeController", id)
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)
}))
system := types.System{
ID: systemID,
}
return server, system, check(hasNoError, checkLength(1), checkSdtID(0, "cd16ff4300000000"), checkHostID(0, "4d2a627100010000"), checkConnected(0, true))
},
"error response": func(_ *testing.T) (*httptest.Server, types.System, []checkFn) {
systemID := "mock-system-id"
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
http.Error(w, "Server Error", http.StatusInternalServerError)
}))
system := types.System{
ID: systemID,
}
return server, system, check(hasError)
},
}

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

client, _ := NewClientWithArgs(server.URL, "", math.MaxInt64, true, false)
system := System{
System: &sys,
client: client,
}
host := types.NvmeHost{
ID: "mock-id",
}
nvmeHostControllers, err := system.GetHostNvmeControllers(host)

for _, checkFn := range checkFns {
checkFn(t, nvmeHostControllers, err)
}
})
}
}
Loading

0 comments on commit 02b95d6

Please sign in to comment.