File: events_test.go

package info (click to toggle)
golang-golang-x-exp 0.0~git20250911.df92998-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental, forky, sid
  • size: 7,284 kB
  • sloc: ansic: 1,900; objc: 276; sh: 270; asm: 48; makefile: 27
file content (105 lines) | stat: -rw-r--r-- 3,246 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated by "gen.bash" from internal/trace; DO NOT EDIT.

//go:build go1.23

package tracev2_test

import (
	"golang.org/x/exp/trace/internal/tracev2"
	"iter"
	"regexp"
	"slices"
	"strings"
	"testing"
)

var argNameRegexp = regexp.MustCompile(`((?P<name>[A-Za-z]+)_)?(?P<type>[A-Za-z]+)`)

func TestSpecs(t *testing.T) {
	if tracev2.NumEvents <= 0 {
		t.Fatalf("no trace events?")
	}
	if tracev2.MaxExperimentalEvent < tracev2.MaxEvent {
		t.Fatalf("max experimental event (%d) is < max event (%d)", tracev2.MaxExperimentalEvent, tracev2.MaxEvent)
	}
	specs := tracev2.Specs()
	for ev := range allEvents() {
		spec := &specs[ev]
		if spec.Name == "" {
			t.Errorf("expected event %d to be defined in specs", ev)
			continue
		}
		if spec.IsTimedEvent && spec.Args[0] != "dt" {
			t.Errorf("%s is a timed event, but its first argument is not 'dt'", spec.Name)
		}
		if spec.HasData && spec.Name != "String" && spec.Name != "ExperimentalBatch" {
			t.Errorf("%s has data, but is not a special kind of event (unsupported, but could be)", spec.Name)
		}
		if spec.IsStack && spec.Name != "Stack" {
			t.Errorf("%s listed as being a stack, but is not the Stack event (unsupported)", spec.Name)
		}
		if spec.IsTimedEvent && len(spec.Args) > tracev2.MaxTimedEventArgs {
			t.Errorf("%s has too many timed event args: have %d, want %d at most", spec.Name, len(spec.Args), tracev2.MaxTimedEventArgs)
		}
		if ev.Experimental() && spec.Experiment == tracev2.NoExperiment {
			t.Errorf("experimental event %s must have an experiment", spec.Name)
		}

		// Check arg types.
		for _, arg := range spec.Args {
			matches := argNameRegexp.FindStringSubmatch(arg)
			if len(matches) == 0 {
				t.Errorf("malformed argument %s for event %s", arg, spec.Name)
			}
		}

		// Check stacks.
		for _, i := range spec.StackIDs {
			if !strings.HasSuffix(spec.Args[i], "stack") {
				t.Errorf("stack argument listed at %d in %s, but argument name %s does not imply stack type", i, spec.Name, spec.Args[i])
			}
		}
		for i, arg := range spec.Args {
			if !strings.HasSuffix(spec.Args[i], "stack") {
				continue
			}
			if !slices.Contains(spec.StackIDs, i) {
				t.Errorf("found stack argument %s in %s at index %d not listed in StackIDs", arg, spec.Name, i)
			}
		}

		// Check strings.
		for _, i := range spec.StringIDs {
			if !strings.HasSuffix(spec.Args[i], "string") {
				t.Errorf("string argument listed at %d in %s, but argument name %s does not imply string type", i, spec.Name, spec.Args[i])
			}
		}
		for i, arg := range spec.Args {
			if !strings.HasSuffix(spec.Args[i], "string") {
				continue
			}
			if !slices.Contains(spec.StringIDs, i) {
				t.Errorf("found string argument %s in %s at index %d not listed in StringIDs", arg, spec.Name, i)
			}
		}
	}
}

func allEvents() iter.Seq[tracev2.EventType] {
	return func(yield func(tracev2.EventType) bool) {
		for ev := tracev2.EvNone + 1; ev < tracev2.NumEvents; ev++ {
			if !yield(ev) {
				return
			}
		}
		for ev := tracev2.MaxEvent + 1; ev < tracev2.NumExperimentalEvents; ev++ {
			if !yield(ev) {
				return
			}
		}
	}
}