]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/internal/trace/gc_test.go
internal/trace: implement MutatorUtilizationV2
[gostls13.git] / src / internal / trace / gc_test.go
index 4f9c77041a942bee05136190790a34c3b09b58da..2bdcfef006f29d7f221c97516f53248366a480aa 100644 (file)
@@ -6,8 +6,9 @@ package trace
 
 import (
        "bytes"
-       "io/ioutil"
+       "internal/trace/v2/testtrace"
        "math"
+       "os"
        "testing"
        "time"
 )
@@ -83,54 +84,70 @@ func TestMMUTrace(t *testing.T) {
                // test input too big for all.bash
                t.Skip("skipping in -short mode")
        }
+       check := func(t *testing.T, mu [][]MutatorUtil) {
+               mmuCurve := NewMMUCurve(mu)
 
-       data, err := ioutil.ReadFile("testdata/stress_1_10_good")
-       if err != nil {
-               t.Fatalf("failed to read input file: %v", err)
-       }
-       _, events, err := parse(bytes.NewReader(data), "")
-       if err != nil {
-               t.Fatalf("failed to parse trace: %s", err)
-       }
-       mu := MutatorUtilization(events.Events, UtilSTW|UtilBackground|UtilAssist)
-       mmuCurve := NewMMUCurve(mu)
-
-       // Test the optimized implementation against the "obviously
-       // correct" implementation.
-       for window := time.Nanosecond; window < 10*time.Second; window *= 10 {
-               want := mmuSlow(mu[0], window)
-               got := mmuCurve.MMU(window)
-               if !aeq(want, got) {
-                       t.Errorf("want %f, got %f mutator utilization in window %s", want, got, window)
+               // Test the optimized implementation against the "obviously
+               // correct" implementation.
+               for window := time.Nanosecond; window < 10*time.Second; window *= 10 {
+                       want := mmuSlow(mu[0], window)
+                       got := mmuCurve.MMU(window)
+                       if !aeq(want, got) {
+                               t.Errorf("want %f, got %f mutator utilization in window %s", want, got, window)
+                       }
                }
-       }
 
-       // Test MUD with band optimization against MUD without band
-       // optimization. We don't have a simple testing implementation
-       // of MUDs (the simplest implementation is still quite
-       // complex), but this is still a pretty good test.
-       defer func(old int) { bandsPerSeries = old }(bandsPerSeries)
-       bandsPerSeries = 1
-       mmuCurve2 := NewMMUCurve(mu)
-       quantiles := []float64{0, 1 - .999, 1 - .99}
-       for window := time.Microsecond; window < time.Second; window *= 10 {
-               mud1 := mmuCurve.MUD(window, quantiles)
-               mud2 := mmuCurve2.MUD(window, quantiles)
-               for i := range mud1 {
-                       if !aeq(mud1[i], mud2[i]) {
-                               t.Errorf("for quantiles %v at window %v, want %v, got %v", quantiles, window, mud2, mud1)
-                               break
+               // Test MUD with band optimization against MUD without band
+               // optimization. We don't have a simple testing implementation
+               // of MUDs (the simplest implementation is still quite
+               // complex), but this is still a pretty good test.
+               defer func(old int) { bandsPerSeries = old }(bandsPerSeries)
+               bandsPerSeries = 1
+               mmuCurve2 := NewMMUCurve(mu)
+               quantiles := []float64{0, 1 - .999, 1 - .99}
+               for window := time.Microsecond; window < time.Second; window *= 10 {
+                       mud1 := mmuCurve.MUD(window, quantiles)
+                       mud2 := mmuCurve2.MUD(window, quantiles)
+                       for i := range mud1 {
+                               if !aeq(mud1[i], mud2[i]) {
+                                       t.Errorf("for quantiles %v at window %v, want %v, got %v", quantiles, window, mud2, mud1)
+                                       break
+                               }
                        }
                }
        }
+       t.Run("V1", func(t *testing.T) {
+               data, err := os.ReadFile("testdata/stress_1_10_good")
+               if err != nil {
+                       t.Fatalf("failed to read input file: %v", err)
+               }
+               events, err := Parse(bytes.NewReader(data), "")
+               if err != nil {
+                       t.Fatalf("failed to parse trace: %s", err)
+               }
+               check(t, MutatorUtilization(events.Events, UtilSTW|UtilBackground|UtilAssist))
+       })
+       t.Run("V2", func(t *testing.T) {
+               testPath := "v2/testdata/tests/go122-gc-stress.test"
+               r, _, err := testtrace.ParseFile(testPath)
+               if err != nil {
+                       t.Fatalf("malformed test %s: bad trace file: %v", testPath, err)
+               }
+               // Pass the trace through MutatorUtilizationV2.
+               mu, err := MutatorUtilizationV2(r, UtilSTW|UtilBackground|UtilAssist)
+               if err != nil {
+                       t.Fatalf("failed to compute mutator utilization or parse trace: %v", err)
+               }
+               check(t, mu)
+       })
 }
 
 func BenchmarkMMU(b *testing.B) {
-       data, err := ioutil.ReadFile("testdata/stress_1_10_good")
+       data, err := os.ReadFile("testdata/stress_1_10_good")
        if err != nil {
                b.Fatalf("failed to read input file: %v", err)
        }
-       _, events, err := parse(bytes.NewReader(data), "")
+       events, err := Parse(bytes.NewReader(data), "")
        if err != nil {
                b.Fatalf("failed to parse trace: %s", err)
        }