github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/module/profiler/profiler_test.go (about)

     1  package profiler_test
     2  
     3  import (
     4  	"os"
     5  	"strings"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/rs/zerolog"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/onflow/flow-go/module/profiler"
    13  	"github.com/onflow/flow-go/utils/unittest"
    14  )
    15  
    16  func TestProfiler(t *testing.T) {
    17  	// profiler depends on the shared state, hence only one enabled=true test can run at a time.
    18  	t.Run("profilerEnabled", func(t *testing.T) {
    19  		unittest.RunWithTempDir(t, func(tempDir string) {
    20  			p, err := profiler.New(
    21  				zerolog.Nop(),
    22  				&profiler.NoopUploader{},
    23  				profiler.ProfilerConfig{
    24  					Enabled:  false,
    25  					Dir:      tempDir,
    26  					Interval: time.Hour,
    27  					Duration: 100 * time.Millisecond,
    28  				})
    29  			require.NoError(t, err)
    30  
    31  			unittest.AssertClosesBefore(t, p.Ready(), 5*time.Second)
    32  
    33  			err = p.SetEnabled(true)
    34  			require.NoError(t, err)
    35  
    36  			require.Eventually(t, func() bool { return p.TriggerRun(time.Millisecond*100) == nil }, 1*time.Second, 10*time.Millisecond)
    37  
    38  			// Fail if profiling is already running
    39  			err = p.TriggerRun(0)
    40  			require.ErrorContains(t, err, "profiling is already in progress")
    41  
    42  			t.Logf("profiler ready %s", tempDir)
    43  
    44  			require.Eventuallyf(t, func() bool {
    45  				dirEnts, err := os.ReadDir(tempDir)
    46  				require.NoError(t, err)
    47  
    48  				foundPtypes := make(map[string]bool)
    49  				for _, pType := range []string{"heap", "allocs", "goroutine", "cpu", "block"} {
    50  					foundPtypes[pType] = false
    51  				}
    52  
    53  				for pName := range foundPtypes {
    54  					for _, ent := range dirEnts {
    55  						if strings.Contains(ent.Name(), pName) {
    56  							foundPtypes[pName] = true
    57  						}
    58  					}
    59  				}
    60  
    61  				for pName, found := range foundPtypes {
    62  					if !found {
    63  						t.Logf("profiler %s not found", pName)
    64  						return false
    65  					}
    66  				}
    67  				return true
    68  			}, time.Second*5, time.Millisecond*100, "profiler did not generate any profiles in %v", tempDir)
    69  
    70  			unittest.AssertClosesBefore(t, p.Done(), 5*time.Second)
    71  		})
    72  	})
    73  }