profiler_test.go 2.0 KB

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