| // Copyright 2021 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package main |
| |
| import ( |
| "bytes" |
| "chromiumos/test/dut/cmd/dutserver/dutssh/mock_dutssh" |
| "context" |
| "errors" |
| "io" |
| "log" |
| "net" |
| "strings" |
| "testing" |
| |
| "github.com/golang/mock/gomock" |
| "go.chromium.org/chromiumos/config/go/test/api" |
| "golang.org/x/crypto/ssh" |
| "google.golang.org/grpc" |
| ) |
| |
| // Tests if DutServiceServer can handle empty request without problem. |
| func TestDutServiceServer_Empty(t *testing.T) { |
| ctrl := gomock.NewController(t) |
| defer ctrl.Finish() |
| |
| mci := mock_dutssh.NewMockClientInterface(ctrl) |
| mci.EXPECT().Close() |
| |
| var logBuf bytes.Buffer |
| l, err := net.Listen("tcp", ":0") |
| if err != nil { |
| t.Fatal("Failed to create a net listener: ", err) |
| } |
| |
| ctx := context.Background() |
| srv, destructor := newDutServiceServer(l, log.New(&logBuf, "", log.LstdFlags|log.LUTC), mci, "", 0, "dutname", "wiringaddress") |
| defer destructor() |
| if err != nil { |
| t.Fatalf("Failed to start DutServiceServer: %v", err) |
| } |
| go srv.Serve(l) |
| defer srv.Stop() |
| |
| conn, err := grpc.Dial(l.Addr().String(), grpc.WithInsecure()) |
| if err != nil { |
| t.Fatalf("Failed to dial: %v", err) |
| } |
| defer conn.Close() |
| |
| cl := api.NewDutServiceClient(conn) |
| if _, err := cl.ExecCommand(ctx, &api.ExecCommandRequest{}); err != nil { |
| t.Fatalf("Failed at api.ExecCommand: %v", err) |
| } |
| } |
| |
| // Tests that a command executes successfully |
| func TestDutServiceServer_CommandWorks(t *testing.T) { |
| ctrl := gomock.NewController(t) |
| defer ctrl.Finish() |
| |
| mci := mock_dutssh.NewMockClientInterface(ctrl) |
| msi := mock_dutssh.NewMockSessionInterface(ctrl) |
| |
| var so io.Writer |
| var se io.Writer |
| |
| gomock.InOrder( |
| mci.EXPECT().NewSession().Return(msi, nil), |
| msi.EXPECT().SetStdout(gomock.Any()).Do(func(arg io.Writer) { so = arg }), |
| msi.EXPECT().SetStderr(gomock.Any()).Do(func(arg io.Writer) { se = arg }), |
| msi.EXPECT().Run(gomock.Eq("command arg1 arg2")).DoAndReturn( |
| func(arg string) error { |
| so.Write([]byte("success!")) |
| se.Write([]byte("not failed!")) |
| return nil |
| }, |
| ), |
| msi.EXPECT().Close(), |
| mci.EXPECT().Close(), |
| ) |
| var logBuf bytes.Buffer |
| l, err := net.Listen("tcp", ":0") |
| if err != nil { |
| t.Fatal("Failed to create a net listener: ", err) |
| } |
| |
| ctx := context.Background() |
| srv, destructor := newDutServiceServer(l, log.New(&logBuf, "", log.LstdFlags|log.LUTC), mci, "", 0, "dutname", "wiringaddress") |
| defer destructor() |
| if err != nil { |
| t.Fatalf("Failed to start DutServiceServer: %v", err) |
| } |
| go srv.Serve(l) |
| defer srv.Stop() |
| |
| conn, err := grpc.Dial(l.Addr().String(), grpc.WithInsecure()) |
| if err != nil { |
| t.Fatalf("Failed to dial: %v", err) |
| } |
| defer conn.Close() |
| |
| cl := api.NewDutServiceClient(conn) |
| stream, err := cl.ExecCommand(ctx, &api.ExecCommandRequest{ |
| Command: "command", |
| Args: []string{"arg1", "arg2"}, |
| Stdin: []byte{}, |
| Stdout: api.Output_OUTPUT_PIPE, |
| Stderr: api.Output_OUTPUT_PIPE, |
| }) |
| if err != nil { |
| t.Fatalf("Failed at api.ExecCommand: %v", err) |
| } |
| |
| resp := &api.ExecCommandResponse{} |
| err = stream.RecvMsg(resp) |
| if err != nil { |
| t.Fatalf("Failed at api.ExecCommand: %v", err) |
| } |
| |
| if resp.ExitInfo.Status != 0 { |
| t.Fatalf("Expecting return type to be 0, instead got: %v", resp.ExitInfo.Status) |
| } |
| |
| if string(resp.Stderr) != "not failed!" { |
| t.Fatalf("Expecting stderr to be \"not failed!\", instead got %v", string(resp.Stderr)) |
| } |
| |
| if string(resp.Stdout) != "success!" { |
| t.Fatalf("Expecting stderr to be \"success!\", instead got %v", string(resp.Stdout)) |
| } |
| |
| if resp.ExitInfo.Signaled { |
| t.Fatalf("Signalled should not be set!") |
| } |
| |
| if !resp.ExitInfo.Started { |
| t.Fatalf("Started should be set!") |
| } |
| } |
| |
| // Tests that a command executes successfully |
| func TestDutServiceServer_CommandOptionCombineWorks(t *testing.T) { |
| ctrl := gomock.NewController(t) |
| defer ctrl.Finish() |
| |
| mci := mock_dutssh.NewMockClientInterface(ctrl) |
| msi := mock_dutssh.NewMockSessionInterface(ctrl) |
| |
| var so io.Writer |
| var se io.Writer |
| |
| gomock.InOrder( |
| mci.EXPECT().NewSession().Return(msi, nil), |
| msi.EXPECT().SetStdout(gomock.Any()).Do(func(arg io.Writer) { so = arg }), |
| msi.EXPECT().SetStderr(gomock.Any()).Do(func(arg io.Writer) { se = arg }), |
| msi.EXPECT().Run(gomock.Eq("command arg1 arg2")).DoAndReturn( |
| func(arg string) error { |
| so.Write([]byte("success!")) |
| se.Write([]byte("not failed!")) |
| return nil |
| }, |
| ), |
| msi.EXPECT().Close(), |
| mci.EXPECT().Close(), |
| ) |
| |
| var logBuf bytes.Buffer |
| l, err := net.Listen("tcp", ":0") |
| if err != nil { |
| t.Fatal("Failed to create a net listener: ", err) |
| } |
| |
| ctx := context.Background() |
| srv, destructor := newDutServiceServer(l, log.New(&logBuf, "", log.LstdFlags|log.LUTC), mci, "", 0, "dutname", "wiringaddress") |
| defer destructor() |
| if err != nil { |
| t.Fatalf("Failed to start DutServiceServer: %v", err) |
| } |
| go srv.Serve(l) |
| defer srv.Stop() |
| |
| conn, err := grpc.Dial(l.Addr().String(), grpc.WithInsecure()) |
| if err != nil { |
| t.Fatalf("Failed to dial: %v", err) |
| } |
| defer conn.Close() |
| |
| cl := api.NewDutServiceClient(conn) |
| stream, err := cl.ExecCommand(ctx, &api.ExecCommandRequest{ |
| Command: "command", |
| Args: []string{"arg1", "arg2"}, |
| Stdin: []byte{}, |
| Stdout: api.Output_OUTPUT_PIPE, |
| Stderr: api.Output_OUTPUT_STDOUT, |
| }) |
| if err != nil { |
| t.Fatalf("Failed at api.ExecCommand: %v", err) |
| } |
| |
| resp := &api.ExecCommandResponse{} |
| err = stream.RecvMsg(resp) |
| if err != nil { |
| t.Fatalf("Failed at api.ExecCommand: %v", err) |
| } |
| |
| if string(resp.Stderr) != "" { |
| t.Fatalf("Expecting stderr to be empty, instead got %v", string(resp.Stderr)) |
| } |
| |
| if string(resp.Stdout) != "success!not failed!" { |
| t.Fatalf("Expecting stderr to be \"success!not failed!\", instead got %v", string(resp.Stdout)) |
| } |
| } |
| |
| // Tests that a command does not execute successfully |
| func TestDutServiceServer_CommandFails(t *testing.T) { |
| ctrl := gomock.NewController(t) |
| defer ctrl.Finish() |
| |
| mci := mock_dutssh.NewMockClientInterface(ctrl) |
| msi := mock_dutssh.NewMockSessionInterface(ctrl) |
| |
| var so io.Writer |
| var se io.Writer |
| |
| gomock.InOrder( |
| mci.EXPECT().NewSession().Return(msi, nil), |
| msi.EXPECT().SetStdout(gomock.Any()).Do(func(arg io.Writer) { so = arg }), |
| msi.EXPECT().SetStderr(gomock.Any()).Do(func(arg io.Writer) { se = arg }), |
| msi.EXPECT().Run(gomock.Eq("command arg1 arg2")).DoAndReturn( |
| func(arg string) error { |
| so.Write([]byte("not success!")) |
| se.Write([]byte("failure!")) |
| wm := ssh.Waitmsg{} |
| return &ssh.ExitError{ |
| Waitmsg: wm, |
| } |
| }, |
| ), |
| msi.EXPECT().Close(), |
| mci.EXPECT().Close(), |
| ) |
| |
| var logBuf bytes.Buffer |
| l, err := net.Listen("tcp", ":0") |
| if err != nil { |
| t.Fatal("Failed to create a net listener: ", err) |
| } |
| |
| ctx := context.Background() |
| srv, destructor := newDutServiceServer(l, log.New(&logBuf, "", log.LstdFlags|log.LUTC), mci, "", 0, "dutname", "wiringaddress") |
| defer destructor() |
| if err != nil { |
| t.Fatalf("Failed to start DutServiceServer: %v", err) |
| } |
| go srv.Serve(l) |
| defer srv.Stop() |
| |
| conn, err := grpc.Dial(l.Addr().String(), grpc.WithInsecure()) |
| if err != nil { |
| t.Fatalf("Failed to dial: %v", err) |
| } |
| defer conn.Close() |
| |
| cl := api.NewDutServiceClient(conn) |
| stream, err := cl.ExecCommand(ctx, &api.ExecCommandRequest{ |
| Command: "command", |
| Args: []string{"arg1", "arg2"}, |
| Stdin: []byte{}, |
| Stdout: api.Output_OUTPUT_PIPE, |
| Stderr: api.Output_OUTPUT_PIPE, |
| }) |
| if err != nil { |
| t.Fatalf("Failed at api.ExecCommand: %v", err) |
| } |
| |
| resp := &api.ExecCommandResponse{} |
| err = stream.RecvMsg(resp) |
| if err != nil { |
| t.Fatalf("Failed at api.ExecCommand: %v", err) |
| } |
| |
| if string(resp.Stderr) != "failure!" { |
| t.Fatalf("Expecting stderr to be \"failure\", instead got %v", string(resp.Stderr)) |
| } |
| |
| if string(resp.Stdout) != "not success!" { |
| t.Fatalf("Expecting stdout to be \"not success\", instead got %v", string(resp.Stdout)) |
| } |
| |
| if !resp.ExitInfo.Signaled { |
| t.Fatalf("Signalled should be set!") |
| } |
| |
| if !resp.ExitInfo.Started { |
| t.Fatalf("Started should be set!") |
| } |
| } |
| |
| // Tests that a command does not execute |
| func TestDutServiceServer_PreCommandFails(t *testing.T) { |
| ctrl := gomock.NewController(t) |
| defer ctrl.Finish() |
| |
| mci := mock_dutssh.NewMockClientInterface(ctrl) |
| msi := mock_dutssh.NewMockSessionInterface(ctrl) |
| |
| var so io.Writer |
| var se io.Writer |
| |
| gomock.InOrder( |
| mci.EXPECT().NewSession().Return(msi, nil), |
| msi.EXPECT().SetStdout(gomock.Any()).Do(func(arg io.Writer) { so = arg }), |
| msi.EXPECT().SetStderr(gomock.Any()).Do(func(arg io.Writer) { se = arg }), |
| msi.EXPECT().Run(gomock.Eq("command arg1 arg2")).DoAndReturn( |
| func(arg string) error { |
| so.Write([]byte("")) |
| se.Write([]byte("")) |
| return &ssh.ExitMissingError{} |
| }, |
| ), |
| msi.EXPECT().Close(), |
| mci.EXPECT().Close(), |
| ) |
| var logBuf bytes.Buffer |
| l, err := net.Listen("tcp", ":0") |
| if err != nil { |
| t.Fatal("Failed to create a net listener: ", err) |
| } |
| |
| ctx := context.Background() |
| srv, destructor := newDutServiceServer(l, log.New(&logBuf, "", log.LstdFlags|log.LUTC), mci, "", 0, "dutname", "wiringaddress") |
| defer destructor() |
| if err != nil { |
| t.Fatalf("Failed to start DutServiceServer: %v", err) |
| } |
| go srv.Serve(l) |
| defer srv.Stop() |
| |
| conn, err := grpc.Dial(l.Addr().String(), grpc.WithInsecure()) |
| if err != nil { |
| t.Fatalf("Failed to dial: %v", err) |
| } |
| defer conn.Close() |
| |
| cl := api.NewDutServiceClient(conn) |
| stream, err := cl.ExecCommand(ctx, &api.ExecCommandRequest{ |
| Command: "command", |
| Args: []string{"arg1", "arg2"}, |
| Stdin: []byte{}, |
| Stdout: api.Output_OUTPUT_PIPE, |
| Stderr: api.Output_OUTPUT_PIPE, |
| }) |
| if err != nil { |
| t.Fatalf("Failed at api.ExecCommand: %v", err) |
| } |
| |
| resp := &api.ExecCommandResponse{} |
| err = stream.RecvMsg(resp) |
| if err != nil { |
| t.Fatalf("Failed at api.ExecCommand: %v", err) |
| } |
| |
| if string(resp.Stderr) != "" { |
| t.Fatalf("Expecting stderr to be empty, instead got %v", string(resp.Stderr)) |
| } |
| |
| if string(resp.Stdout) != "" { |
| t.Fatalf("Expecting stderr to be empty, instead got %v", string(resp.Stderr)) |
| } |
| |
| if resp.ExitInfo.Signaled { |
| t.Fatalf("Signalled should not be set!") |
| } |
| |
| if resp.ExitInfo.Started { |
| t.Fatalf("Started should not be set!") |
| } |
| } |
| |
| // Tests that a session fails |
| func TestDutServiceServer_NewSessionFails(t *testing.T) { |
| ctrl := gomock.NewController(t) |
| defer ctrl.Finish() |
| |
| mci := mock_dutssh.NewMockClientInterface(ctrl) |
| |
| gomock.InOrder( |
| mci.EXPECT().NewSession().Return(nil, errors.New("Session failed.")), |
| mci.EXPECT().Close(), |
| ) |
| var logBuf bytes.Buffer |
| l, err := net.Listen("tcp", ":0") |
| if err != nil { |
| t.Fatal("Failed to create a net listener: ", err) |
| } |
| |
| ctx := context.Background() |
| srv, destructor := newDutServiceServer(l, log.New(&logBuf, "", log.LstdFlags|log.LUTC), mci, "", 0, "dutname", "wiringaddress") |
| defer destructor() |
| if err != nil { |
| t.Fatalf("Failed to start DutServiceServer: %v", err) |
| } |
| go srv.Serve(l) |
| defer srv.Stop() |
| |
| conn, err := grpc.Dial(l.Addr().String(), grpc.WithInsecure()) |
| if err != nil { |
| t.Fatalf("Failed to dial: %v", err) |
| } |
| defer conn.Close() |
| |
| cl := api.NewDutServiceClient(conn) |
| stream, err := cl.ExecCommand(ctx, &api.ExecCommandRequest{ |
| Command: "command", |
| Args: []string{"arg1", "arg2"}, |
| Stdin: []byte{}, |
| Stdout: api.Output_OUTPUT_PIPE, |
| Stderr: api.Output_OUTPUT_PIPE, |
| }) |
| if err != nil { |
| t.Fatalf("Failed at api.ExecCommand: %v", err) |
| } |
| |
| resp := &api.ExecCommandResponse{} |
| err = stream.RecvMsg(resp) |
| if err != nil { |
| t.Fatalf("Failed at api.ExecCommand: %v", err) |
| } |
| |
| if string(resp.Stderr) != "" { |
| t.Fatalf("Expecting stderr to be empty, instead got %v", string(resp.Stderr)) |
| } |
| |
| if string(resp.Stdout) != "" { |
| t.Fatalf("Expecting stdout to be empty, instead got %v", string(resp.Stdout)) |
| } |
| |
| if resp.ExitInfo.Signaled { |
| t.Fatalf("Signalled should not be set!") |
| } |
| |
| if resp.ExitInfo.Started { |
| t.Fatalf("Started should not be set!") |
| } |
| |
| if resp.ExitInfo.ErrorMessage != "Session failed." { |
| t.Fatalf("Error message should be session failed, instead got %v", resp.ExitInfo.ErrorMessage) |
| } |
| } |
| |
| // Tests that a path exist command fails |
| func TestDutServiceServer_FetchCrasesPathExistsFails(t *testing.T) { |
| ctrl := gomock.NewController(t) |
| defer ctrl.Finish() |
| |
| mci := mock_dutssh.NewMockClientInterface(ctrl) |
| msi := mock_dutssh.NewMockSessionInterface(ctrl) |
| |
| gomock.InOrder( |
| mci.EXPECT().NewSession().Return(msi, nil), |
| msi.EXPECT().Output(gomock.Eq("[ -e serializer_path ] && echo -n 1 || echo -n 0")).Return(nil, errors.New("command failed!")), |
| msi.EXPECT().Close(), |
| mci.EXPECT().Close(), |
| ) |
| var logBuf bytes.Buffer |
| l, err := net.Listen("tcp", ":0") |
| if err != nil { |
| t.Fatal("Failed to create a net listener: ", err) |
| } |
| |
| ctx := context.Background() |
| srv, destructor := newDutServiceServer(l, log.New(&logBuf, "", log.LstdFlags|log.LUTC), mci, "serializer_path", 0, "dutname", "wiringaddress") |
| defer destructor() |
| if err != nil { |
| t.Fatalf("Failed to start DutServiceServer: %v", err) |
| } |
| go srv.Serve(l) |
| defer srv.Stop() |
| |
| conn, err := grpc.Dial(l.Addr().String(), grpc.WithInsecure()) |
| if err != nil { |
| t.Fatalf("Failed to dial: %v", err) |
| } |
| defer conn.Close() |
| |
| cl := api.NewDutServiceClient(conn) |
| stream, err := cl.FetchCrashes(ctx, &api.FetchCrashesRequest{}) |
| if err != nil { |
| t.Fatalf("Failed at api.FetchCrashes: %v", err) |
| } |
| |
| resp := &api.FetchCrashesResponse{} |
| err = stream.RecvMsg(resp) |
| if err.Error() != "rpc error: code = FailedPrecondition desc = Failed to check crash_serializer existence: command failed!" { |
| t.Fatalf("Command failure should have caused an error: %v", err) |
| } |
| |
| } |
| |
| // Tests that a path exist command returns command missing |
| func TestDutServiceServer_FetchCrasesPathExistsMissing(t *testing.T) { |
| ctrl := gomock.NewController(t) |
| defer ctrl.Finish() |
| |
| mci := mock_dutssh.NewMockClientInterface(ctrl) |
| msi := mock_dutssh.NewMockSessionInterface(ctrl) |
| |
| gomock.InOrder( |
| mci.EXPECT().NewSession().Return(msi, nil), |
| msi.EXPECT().Output(gomock.Eq("[ -e serializer_path ] && echo -n 1 || echo -n 0")).Return([]byte("0"), nil), |
| msi.EXPECT().Close(), |
| mci.EXPECT().Close(), |
| ) |
| var logBuf bytes.Buffer |
| l, err := net.Listen("tcp", ":0") |
| if err != nil { |
| t.Fatal("Failed to create a net listener: ", err) |
| } |
| |
| ctx := context.Background() |
| srv, destructor := newDutServiceServer(l, log.New(&logBuf, "", log.LstdFlags|log.LUTC), mci, "serializer_path", 0, "dutname", "wiringaddress") |
| defer destructor() |
| if err != nil { |
| t.Fatalf("Failed to start DutServiceServer: %v", err) |
| } |
| go srv.Serve(l) |
| defer srv.Stop() |
| |
| conn, err := grpc.Dial(l.Addr().String(), grpc.WithInsecure()) |
| if err != nil { |
| t.Fatalf("Failed to dial: %v", err) |
| } |
| defer conn.Close() |
| |
| cl := api.NewDutServiceClient(conn) |
| stream, err := cl.FetchCrashes(ctx, &api.FetchCrashesRequest{}) |
| if err != nil { |
| t.Fatalf("Failed at api.FetchCrashes: %v", err) |
| } |
| |
| resp := &api.FetchCrashesResponse{} |
| err = stream.RecvMsg(resp) |
| if err.Error() != "rpc error: code = NotFound desc = crash_serializer not present on device." { |
| t.Fatalf("Path missing should have caused an error: %v", err) |
| } |
| |
| } |
| |
| // Tests that a new session failure fails |
| func TestDutServiceServer_FetchCrasesNewSessionFailure(t *testing.T) { |
| ctrl := gomock.NewController(t) |
| defer ctrl.Finish() |
| |
| mci := mock_dutssh.NewMockClientInterface(ctrl) |
| |
| gomock.InOrder( |
| mci.EXPECT().NewSession().Return(nil, errors.New("Session failed.")), |
| mci.EXPECT().Close(), |
| ) |
| var logBuf bytes.Buffer |
| l, err := net.Listen("tcp", ":0") |
| if err != nil { |
| t.Fatal("Failed to create a net listener: ", err) |
| } |
| |
| ctx := context.Background() |
| srv, destructor := newDutServiceServer(l, log.New(&logBuf, "", log.LstdFlags|log.LUTC), mci, "serializer_path", 0, "dutname", "wiringaddress") |
| defer destructor() |
| if err != nil { |
| t.Fatalf("Failed to start DutServiceServer: %v", err) |
| } |
| go srv.Serve(l) |
| defer srv.Stop() |
| |
| conn, err := grpc.Dial(l.Addr().String(), grpc.WithInsecure()) |
| if err != nil { |
| t.Fatalf("Failed to dial: %v", err) |
| } |
| defer conn.Close() |
| |
| cl := api.NewDutServiceClient(conn) |
| stream, err := cl.FetchCrashes(ctx, &api.FetchCrashesRequest{}) |
| if err != nil { |
| t.Fatalf("Failed at api.FetchCrashes: %v", err) |
| } |
| |
| resp := &api.FetchCrashesResponse{} |
| err = stream.RecvMsg(resp) |
| if err.Error() != "rpc error: code = FailedPrecondition desc = Failed to check crash_serializer existence: Session failed." { |
| t.Fatalf("Session Failure should have failed: %v", err) |
| } |
| |
| } |
| |
| // Tests that a path exist command returns command missing |
| func TestDutServiceServer_FetchCrasesSessionStartFailure(t *testing.T) { |
| ctrl := gomock.NewController(t) |
| defer ctrl.Finish() |
| |
| mci := mock_dutssh.NewMockClientInterface(ctrl) |
| msi := mock_dutssh.NewMockSessionInterface(ctrl) |
| |
| gomock.InOrder( |
| mci.EXPECT().NewSession().Return(msi, nil), |
| msi.EXPECT().Output(gomock.Eq("[ -e serializer_path ] && echo -n 1 || echo -n 0")).Return([]byte("1"), nil), |
| msi.EXPECT().Close(), |
| mci.EXPECT().NewSession().Return(msi, nil), |
| msi.EXPECT().StdoutPipe().Return(strings.NewReader("stdout"), nil), |
| msi.EXPECT().StderrPipe().Return(strings.NewReader("stderr"), nil), |
| msi.EXPECT().Start(gomock.Eq("serializer_path --chunk_size=0 --fetch_coredumps")).Return(errors.New("Session Start Failure.")), |
| msi.EXPECT().Close(), |
| mci.EXPECT().Close(), |
| ) |
| var logBuf bytes.Buffer |
| l, err := net.Listen("tcp", ":0") |
| if err != nil { |
| t.Fatal("Failed to create a net listener: ", err) |
| } |
| |
| ctx := context.Background() |
| srv, destructor := newDutServiceServer(l, log.New(&logBuf, "", log.LstdFlags|log.LUTC), mci, "serializer_path", 0, "dutname", "wiringaddress") |
| defer destructor() |
| if err != nil { |
| t.Fatalf("Failed to start DutServiceServer: %v", err) |
| } |
| go srv.Serve(l) |
| defer srv.Stop() |
| |
| conn, err := grpc.Dial(l.Addr().String(), grpc.WithInsecure()) |
| if err != nil { |
| t.Fatalf("Failed to dial: %v", err) |
| } |
| defer conn.Close() |
| |
| cl := api.NewDutServiceClient(conn) |
| stream, err := cl.FetchCrashes(ctx, &api.FetchCrashesRequest{ |
| FetchCore: true, |
| }) |
| if err != nil { |
| t.Fatalf("Failed at api.FetchCrashes: %v", err) |
| } |
| |
| resp := &api.FetchCrashesResponse{} |
| err = stream.RecvMsg(resp) |
| if err.Error() != "rpc error: code = FailedPrecondition desc = Failed to run serializer: Session Start Failure." { |
| t.Fatalf("Session Start Failure should have caused an error: %v", err) |
| } |
| |
| } |
| |
| // Tests that a path exist command returns command missing |
| func TestDutServiceServer_FetchCrasesPipeFailure(t *testing.T) { |
| ctrl := gomock.NewController(t) |
| defer ctrl.Finish() |
| |
| mci := mock_dutssh.NewMockClientInterface(ctrl) |
| msi := mock_dutssh.NewMockSessionInterface(ctrl) |
| |
| gomock.InOrder( |
| mci.EXPECT().NewSession().Return(msi, nil), |
| msi.EXPECT().Output(gomock.Eq("[ -e serializer_path ] && echo -n 1 || echo -n 0")).Return([]byte("1"), nil), |
| msi.EXPECT().Close(), |
| mci.EXPECT().NewSession().Return(msi, nil), |
| msi.EXPECT().StdoutPipe().Return(strings.NewReader("stdout"), errors.New("stdout failure.")), |
| msi.EXPECT().Close(), |
| mci.EXPECT().Close(), |
| ) |
| var logBuf bytes.Buffer |
| l, err := net.Listen("tcp", ":0") |
| if err != nil { |
| t.Fatal("Failed to create a net listener: ", err) |
| } |
| |
| ctx := context.Background() |
| srv, destructor := newDutServiceServer(l, log.New(&logBuf, "", log.LstdFlags|log.LUTC), mci, "serializer_path", 0, "dutname", "wiringaddress") |
| defer destructor() |
| if err != nil { |
| t.Fatalf("Failed to start DutServiceServer: %v", err) |
| } |
| go srv.Serve(l) |
| defer srv.Stop() |
| |
| conn, err := grpc.Dial(l.Addr().String(), grpc.WithInsecure()) |
| if err != nil { |
| t.Fatalf("Failed to dial: %v", err) |
| } |
| defer conn.Close() |
| |
| cl := api.NewDutServiceClient(conn) |
| stream, err := cl.FetchCrashes(ctx, &api.FetchCrashesRequest{}) |
| if err != nil { |
| t.Fatalf("Failed at api.FetchCrashes: %v", err) |
| } |
| |
| resp := &api.FetchCrashesResponse{} |
| err = stream.RecvMsg(resp) |
| if err.Error() != "rpc error: code = FailedPrecondition desc = Failed to get stdout: stdout failure." { |
| t.Fatalf("Standard Out Failure should have caused an error: %v", err) |
| } |
| |
| } |
| |
| // TestRestart tests that a Restart command works |
| func TestRestart(t *testing.T) { |
| ctrl := gomock.NewController(t) |
| defer ctrl.Finish() |
| |
| mci := mock_dutssh.NewMockClientInterface(ctrl) |
| msi := mock_dutssh.NewMockSessionInterface(ctrl) |
| |
| gomock.InOrder( |
| mci.EXPECT().NewSession().Return(msi, nil), |
| msi.EXPECT().Output(gomock.Eq("reboot some args")).Return([]byte("reboot output"), nil), |
| msi.EXPECT().Close(), |
| mci.EXPECT().Close(), |
| ) |
| |
| mci.EXPECT().Wait().Return(nil) |
| |
| var logBuf bytes.Buffer |
| l, err := net.Listen("tcp", ":0") |
| if err != nil { |
| t.Fatal("Failed to create a net listener: ", err) |
| } |
| |
| ctx := context.Background() |
| srv, destructor := newDutServiceServer(l, log.New(&logBuf, "", log.LstdFlags|log.LUTC), mci, "serializer_path", 0, "dutname", "wiringaddress") |
| defer destructor() |
| if err != nil { |
| t.Fatalf("Failed to start DutServiceServer: %v", err) |
| } |
| go srv.Serve(l) |
| defer srv.Stop() |
| |
| conn, err := grpc.Dial(l.Addr().String(), grpc.WithInsecure()) |
| if err != nil { |
| t.Fatalf("Failed to dial: %v", err) |
| } |
| defer conn.Close() |
| |
| cl := api.NewDutServiceClient(conn) |
| _, err = cl.Restart(ctx, &api.RestartRequest{ |
| Args: []string{"some", "args"}, |
| }) |
| // technically if we get to the reconnect step, we did everything right, so |
| // rather than mock the reconnect step, we assume that if we got there, we are |
| // successful |
| if !strings.Contains(err.Error(), "connection error") { |
| t.Fatalf("Failed at api.Restart: %v", err) |
| } |
| } |