github.com/minio/console@v1.4.1/api/admin_trace_test.go (about) 1 // This file is part of MinIO Console Server 2 // Copyright (c) 2021 MinIO, Inc. 3 // 4 // This program is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Affero General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Affero General Public License for more details. 13 // 14 // You should have received a copy of the GNU Affero General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 package api 18 19 import ( 20 "context" 21 "encoding/json" 22 "fmt" 23 "testing" 24 25 "github.com/minio/madmin-go/v3" 26 "github.com/stretchr/testify/assert" 27 ) 28 29 func TestAdminTrace(t *testing.T) { 30 assert := assert.New(t) 31 adminClient := AdminClientMock{} 32 mockWSConn := mockConn{} 33 function := "startTraceInfo(ctx, )" 34 ctx, cancel := context.WithCancel(context.Background()) 35 defer cancel() 36 37 testReceiver := make(chan shortTraceMsg, 5) 38 textToReceive := "test" 39 testStreamSize := 5 40 isClosed := false // testReceiver is closed? 41 42 // Test-1: Serve Trace with no errors until trace finishes sending 43 // define mock function behavior for minio server Trace 44 minioServiceTraceMock = func(_ context.Context, _ int64, _, _, _, _, _ bool) <-chan madmin.ServiceTraceInfo { 45 ch := make(chan madmin.ServiceTraceInfo) 46 // Only success, start a routine to start reading line by line. 47 go func(ch chan<- madmin.ServiceTraceInfo) { 48 defer close(ch) 49 lines := make([]int, testStreamSize) 50 // mocking sending 5 lines of info 51 for range lines { 52 info := madmin.TraceInfo{ 53 FuncName: textToReceive, 54 } 55 ch <- madmin.ServiceTraceInfo{Trace: info} 56 } 57 }(ch) 58 return ch 59 } 60 writesCount := 1 61 // mock connection WriteMessage() no error 62 connWriteMessageMock = func(_ int, data []byte) error { 63 // emulate that receiver gets the message written 64 var t shortTraceMsg 65 _ = json.Unmarshal(data, &t) 66 if writesCount == testStreamSize { 67 // for testing we need to close the receiver channel 68 if !isClosed { 69 close(testReceiver) 70 isClosed = true 71 } 72 return nil 73 } 74 testReceiver <- t 75 writesCount++ 76 return nil 77 } 78 if err := startTraceInfo(ctx, mockWSConn, adminClient, TraceRequest{s3: true, internal: true, storage: true, os: true, onlyErrors: false}); err != nil { 79 t.Errorf("Failed on %s:, error occurred: %s", function, err.Error()) 80 } 81 // check that the TestReceiver got the same number of data from trace. 82 for i := range testReceiver { 83 assert.Equal(textToReceive, i.FuncName) 84 } 85 86 // Test-2: if error happens while writing, return error 87 connWriteMessageMock = func(_ int, _ []byte) error { 88 return fmt.Errorf("error on write") 89 } 90 if err := startTraceInfo(ctx, mockWSConn, adminClient, TraceRequest{}); assert.Error(err) { 91 assert.Equal("error on write", err.Error()) 92 } 93 94 // Test-3: error happens on serviceTrace Minio, trace should stop 95 // and error shall be returned. 96 minioServiceTraceMock = func(_ context.Context, _ int64, _, _, _, _, _ bool) <-chan madmin.ServiceTraceInfo { 97 ch := make(chan madmin.ServiceTraceInfo) 98 // Only success, start a routine to start reading line by line. 99 go func(ch chan<- madmin.ServiceTraceInfo) { 100 defer close(ch) 101 lines := make([]int, 2) 102 // mocking sending 5 lines of info 103 for range lines { 104 info := madmin.TraceInfo{ 105 NodeName: "test", 106 } 107 ch <- madmin.ServiceTraceInfo{Trace: info} 108 } 109 ch <- madmin.ServiceTraceInfo{Err: fmt.Errorf("error on trace")} 110 }(ch) 111 return ch 112 } 113 connWriteMessageMock = func(_ int, _ []byte) error { 114 return nil 115 } 116 if err := startTraceInfo(ctx, mockWSConn, adminClient, TraceRequest{}); assert.Error(err) { 117 assert.Equal("error on trace", err.Error()) 118 } 119 }