github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/profiler_test.go (about)

     1  package goja
     2  
     3  import (
     4  	"sync/atomic"
     5  	"testing"
     6  	"time"
     7  )
     8  
     9  func TestProfiler(t *testing.T) {
    10  
    11  	err := StartProfile(nil)
    12  	if err != nil {
    13  		t.Fatal(err)
    14  	}
    15  
    16  	vm := New()
    17  	go func() {
    18  		_, err := vm.RunScript("test123.js", `
    19  			const a = 2 + 2;
    20  			function loop() {
    21  				for(;;) {}
    22  			}
    23  			loop();
    24  		`)
    25  		if err != nil {
    26  			if _, ok := err.(*InterruptedError); !ok {
    27  				panic(err)
    28  			}
    29  		}
    30  	}()
    31  
    32  	time.Sleep(200 * time.Millisecond)
    33  
    34  	atomic.StoreInt32(&globalProfiler.enabled, 0)
    35  	pr := globalProfiler.p.stop()
    36  
    37  	if len(pr.Sample) == 0 {
    38  		t.Fatal("No samples were recorded")
    39  	}
    40  
    41  	var running bool
    42  	for i := 0; i < 10; i++ {
    43  		time.Sleep(10 * time.Millisecond)
    44  		globalProfiler.p.mu.Lock()
    45  		running = globalProfiler.p.running
    46  		globalProfiler.p.mu.Unlock()
    47  		if !running {
    48  			break
    49  		}
    50  	}
    51  	if running {
    52  		t.Fatal("The profiler is still running")
    53  	}
    54  	vm.Interrupt(nil)
    55  }
    56  
    57  func TestProfiler1(t *testing.T) {
    58  	t.Skip("This test takes too long with race detector enabled and is non-deterministic. It's left here mostly for documentation purposes.")
    59  
    60  	err := StartProfile(nil)
    61  	if err != nil {
    62  		t.Fatal(err)
    63  	}
    64  
    65  	go func() {
    66  		sleep := func() {
    67  			time.Sleep(1 * time.Second)
    68  		}
    69  		// Spawn new vms faster than once every 10ms (the profiler interval) and make sure they don't finish too soon.
    70  		// This means (*profiler).run() won't be fast enough to collect the samples, so they must be collected
    71  		// after the profiler is stopped.
    72  		for i := 0; i < 500; i++ {
    73  			go func() {
    74  				vm := New()
    75  				vm.Set("sleep", sleep)
    76  				_, err := vm.RunScript("test123.js", `
    77  				function loop() {
    78  					for (let i = 0; i < 50000; i++) {
    79  						const a = Math.pow(Math.Pi, Math.Pi);
    80  					}
    81  				}
    82  				loop();
    83  				sleep();
    84  				`)
    85  				if err != nil {
    86  					if _, ok := err.(*InterruptedError); !ok {
    87  						panic(err)
    88  					}
    89  				}
    90  			}()
    91  			time.Sleep(1 * time.Millisecond)
    92  		}
    93  	}()
    94  
    95  	time.Sleep(500 * time.Millisecond)
    96  	atomic.StoreInt32(&globalProfiler.enabled, 0)
    97  	pr := globalProfiler.p.stop()
    98  
    99  	if len(pr.Sample) == 0 {
   100  		t.Fatal("No samples were recorded")
   101  	}
   102  }