github.com/minio/console@v1.3.0/api/admin_profiling_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 "bytes" 21 "context" 22 "errors" 23 "io" 24 "net/http" 25 "net/url" 26 "testing" 27 28 "github.com/minio/madmin-go/v3" 29 "github.com/stretchr/testify/assert" 30 ) 31 32 // Implementing fake closingBuffer to mock stopProfiling() (io.ReadCloser, error) 33 type ClosingBuffer struct { 34 *bytes.Buffer 35 } 36 37 // Implementing a fake Close function for io.ReadCloser 38 func (cb *ClosingBuffer) Close() error { 39 return nil 40 } 41 42 func TestStartProfiling(t *testing.T) { 43 ctx, cancel := context.WithCancel(context.Background()) 44 defer cancel() 45 assert := assert.New(t) 46 adminClient := AdminClientMock{} 47 mockWSConn := mockConn{} 48 function := "startProfiling()" 49 testOptions := &profileOptions{ 50 Types: "cpu", 51 } 52 53 // Test-1 : startProfiling() Get response from MinIO server with one profiling object without errors 54 // mock function response from startProfiling() 55 minioStartProfiling = func(_ madmin.ProfilerType) ([]madmin.StartProfilingResult, error) { 56 return []madmin.StartProfilingResult{ 57 { 58 NodeName: "http://127.0.0.1:9000/", 59 Success: true, 60 Error: "", 61 }, 62 { 63 NodeName: "http://127.0.0.1:9001/", 64 Success: true, 65 Error: "", 66 }, 67 }, nil 68 } 69 // mock function response from stopProfiling() 70 minioStopProfiling = func() (io.ReadCloser, error) { 71 return &ClosingBuffer{bytes.NewBufferString("In memory string eaeae")}, nil 72 } 73 // mock function response from mockConn.writeMessage() 74 connWriteMessageMock = func(_ int, _ []byte) error { 75 return nil 76 } 77 err := startProfiling(ctx, mockWSConn, adminClient, testOptions) 78 if err != nil { 79 t.Errorf("Failed on %s:, error occurred: %s", function, err.Error()) 80 } 81 assert.Equal(err, nil) 82 83 // Test-2 : startProfiling() Correctly handles errors returned by MinIO 84 // mock function response from startProfiling() 85 minioStartProfiling = func(_ madmin.ProfilerType) ([]madmin.StartProfilingResult, error) { 86 return nil, errors.New("error") 87 } 88 err = startProfiling(ctx, mockWSConn, adminClient, testOptions) 89 if assert.Error(err) { 90 assert.Equal("error", err.Error()) 91 } 92 93 // Test-3: getProfileOptionsFromReq() correctly returns profile options from request 94 u, _ := url.Parse("ws://localhost/ws/profile?types=cpu,mem,block,mutex,trace,threads,goroutines") 95 req := &http.Request{ 96 URL: u, 97 } 98 opts, err := getProfileOptionsFromReq(req) 99 if assert.NoError(err) { 100 expectedOptions := profileOptions{ 101 Types: "cpu,mem,block,mutex,trace,threads,goroutines", 102 } 103 assert.Equal(expectedOptions.Types, opts.Types) 104 } 105 }