From daaf837ffc807e1fc4682d7713db0e0132b00f64 Mon Sep 17 00:00:00 2001 From: Boris Glimcher Date: Wed, 4 Jan 2023 05:48:41 +0200 Subject: [PATCH] tests: implement TestFrontEnd_GetNVMeNamespace Signed-off-by: Boris Glimcher --- frontend.go | 2 +- frontend_test.go | 145 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 135 insertions(+), 12 deletions(-) diff --git a/frontend.go b/frontend.go index 7a39107f..f4801c4c 100644 --- a/frontend.go +++ b/frontend.go @@ -426,7 +426,7 @@ func (s *server) GetNVMeNamespace(ctx context.Context, in *pb.GetNVMeNamespaceRe for i := range result.Namespaces { r := &result.Namespaces[i] if r.Nsid == int(namespace.Spec.HostNsid) { - return &pb.NVMeNamespace{Spec: &pb.NVMeNamespaceSpec{HostNsid: int32(r.Nsid)}}, nil + return &pb.NVMeNamespace{Spec: &pb.NVMeNamespaceSpec{HostNsid: int32(r.Nsid)}, Status: &pb.NVMeNamespaceStatus{PciState: 2, PciOperState: 1}}, nil } } msg := fmt.Sprintf("Could not find HostNsid: %d", namespace.Spec.HostNsid) diff --git a/frontend_test.go b/frontend_test.go index ad97191b..08203c85 100644 --- a/frontend_test.go +++ b/frontend_test.go @@ -1174,7 +1174,7 @@ func TestFrontEnd_CreateNVMeNamespace(t *testing.T) { Spec: &pb.NVMeNamespaceSpec{ Id: &pc.ObjectKey{Value: "namespace-test"}, SubsystemId: &pc.ObjectKey{Value: "subsystem-test"}, - HostNsid: 0, + HostNsid: 22, VolumeId: &pc.ObjectKey{Value: "Malloc1"}, Uuid: &pc.Uuid{Value: "1b4e28ba-2fa1-11d2-883f-b9a761bde3fb"}, Nguid: "1b4e28ba-2fa1-11d2-883f-b9a761bde3fb", @@ -1185,7 +1185,7 @@ func TestFrontEnd_CreateNVMeNamespace(t *testing.T) { Spec: &pb.NVMeNamespaceSpec{ Id: &pc.ObjectKey{Value: "namespace-test"}, SubsystemId: &pc.ObjectKey{Value: "subsystem-test"}, - HostNsid: 0, + HostNsid: 22, VolumeId: &pc.ObjectKey{Value: "Malloc1"}, Uuid: &pc.Uuid{Value: "1b4e28ba-2fa1-11d2-883f-b9a761bde3fb"}, Nguid: "1b4e28ba-2fa1-11d2-883f-b9a761bde3fb", @@ -1362,13 +1362,6 @@ func TestFrontEnd_ListNVMeNamespaces(t *testing.T) { { "valid request with valid SPDK responce", "subsystem-test", - // Id: &pc.ObjectKey{Value: "namespace-test"}, - // SubsystemId: &pc.ObjectKey{Value: "subsystem-test"}, - // HostNsid: 0, - // VolumeId: &pc.ObjectKey{Value: "Malloc1"}, - // Uuid: &pc.Uuid{Value: "1b4e28ba-2fa1-11d2-883f-b9a761bde3fb"}, - // Nguid: "1b4e28ba-2fa1-11d2-883f-b9a761bde3fb", - // Eui64: 1967554867335598546, []*pb.NVMeNamespace{ { Spec: &pb.NVMeNamespaceSpec{ @@ -1393,11 +1386,11 @@ func TestFrontEnd_ListNVMeNamespaces(t *testing.T) { }, { "valid request with unknown key", - "unknown-subsystem-id", + "unknown-namespace-id", nil, []string{""}, codes.Unknown, - fmt.Sprintf("unable to find key %v", "unknown-subsystem-id"), + fmt.Sprintf("unable to find key %v", "unknown-namespace-id"), false, }, } @@ -1450,6 +1443,136 @@ func TestFrontEnd_ListNVMeNamespaces(t *testing.T) { } func TestFrontEnd_GetNVMeNamespace(t *testing.T) { + tests := []struct { + name string + in string + out *pb.NVMeNamespace + spdk []string + errCode codes.Code + errMsg string + start bool + }{ + { + "valid request with invalid SPDK responce", + "namespace-test", + nil, + []string{`{"id":%d,"error":{"code":0,"message":""},"result":{"name":"","cntlid":17,"Namespaces":null}}`}, + codes.InvalidArgument, + fmt.Sprintf("Could not find HostNsid: %v", "22"), + true, + }, + { + "valid request with invalid marshal SPDK responce", + "namespace-test", + nil, + []string{`{"id":%d,"error":{"code":0,"message":""},"result":[]}`}, + codes.Unknown, + fmt.Sprintf("controller_nvme_namespace_list: %v", "json: cannot unmarshal array into Go struct field .result of type main.NvdaControllerNvmeNamespaceListResult"), + true, + }, + { + "valid request with empty SPDK responce", + "namespace-test", + nil, + []string{""}, + codes.Unknown, + fmt.Sprintf("controller_nvme_namespace_list: %v", "EOF"), + true, + }, + { + "valid request with ID mismatch SPDK responce", + "namespace-test", + nil, + []string{`{"id":0,"error":{"code":0,"message":""},"result":{"name":"","cntlid":0,"Namespaces":null}}`}, + codes.Unknown, + fmt.Sprintf("controller_nvme_namespace_list: %v", "json response ID mismatch"), + true, + }, + { + "valid request with error code from SPDK responce", + "namespace-test", + nil, + []string{`{"id":%d,"error":{"code":1,"message":"myopierr"}}`}, + codes.Unknown, + fmt.Sprintf("controller_nvme_namespace_list: %v", "json response error: myopierr"), + true, + }, + { + "valid request with valid SPDK responce", + "namespace-test", + &pb.NVMeNamespace{ + Spec: &pb.NVMeNamespaceSpec{ + HostNsid: 22, + }, + Status: &pb.NVMeNamespaceStatus{ + PciState: 2, + PciOperState: 1, + }, + }, + []string{`{"id":%d,"error":{"code":0,"message":""},"result":{"name": "NvmeEmu0pf1", "cntlid": 1, "Namespaces": [{"nsid": 11, "bdev": "Malloc0", "bdev_type": "spdk", "qn": "", "protocol": ""},{"nsid": 22, "bdev": "Malloc1", "bdev_type": "spdk", "qn": "", "protocol": ""},{"nsid": 13, "bdev": "Malloc2", "bdev_type": "spdk", "qn": "", "protocol": ""}]}}`}, + codes.OK, + "", + true, + }, + { + "valid request with unknown key", + "unknown-subsystem-id", + nil, + []string{""}, + codes.Unknown, + fmt.Sprintf("unable to find key %v", "unknown-subsystem-id"), + false, + }, + } + + // start GRPC mockup server + ctx := context.Background() + conn, err := grpc.DialContext(ctx, "", grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithContextDialer(dialer())) + if err != nil { + log.Fatal(err) + } + defer conn.Close() + client := pb.NewFrontendNvmeServiceClient(conn) + + // start SPDK mockup server + if err := os.RemoveAll(*rpcSock); err != nil { + log.Fatal(err) + } + ln, err := net.Listen("unix", *rpcSock) + if err != nil { + log.Fatal("listen error:", err) + } + defer ln.Close() + + // run tests + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.start { + go spdkMockServer(ln, tt.spdk) + } + request := &pb.GetNVMeNamespaceRequest{Name: tt.in} + response, err := client.GetNVMeNamespace(ctx, request) + if response != nil { + if !reflect.DeepEqual(response.Spec, tt.out.Spec) { + t.Error("response: expected", tt.out.GetSpec(), "received", response.GetSpec()) + } + if !reflect.DeepEqual(response.Status, tt.out.Status) { + t.Error("response: expected", tt.out.GetStatus(), "received", response.GetStatus()) + } + } + + if err != nil { + if er, ok := status.FromError(err); ok { + if er.Code() != tt.errCode { + t.Error("error code: expected", codes.InvalidArgument, "received", er.Code()) + } + if er.Message() != tt.errMsg { + t.Error("error message: expected", tt.errMsg, "received", er.Message()) + } + } + } + }) + } } func TestFrontEnd_NVMeNamespaceStats(t *testing.T) {