1//go:build linux
2
3package main
4
5import "time"
6
7const (
8 minimumDuration = 30 * time.Second
9 minimumRepetitions = 10
10 minimumInIntervalEventSamples = 10
11 measuredEventCadence = time.Second
12)
13
14type options struct {
15 vevBin, manifest, out string
16 scenario string
17 warmup, duration time.Duration
18 repetitions int
19}
20
21type manifest struct {
22 Schema uint16 `json:"schema"`
23 Topologies []topology `json:"topologies"`
24 Workloads []string `json:"workloads"`
25 Transports []transport `json:"transports"`
26 Scenarios []scenario `json:"scenarios"`
27}
28
29type topology struct {
30 ID string `json:"id"`
31 Geometry string `json:"geometry"`
32 RowsPerPane int `json:"rows_per_pane"`
33}
34
35type transport struct {
36 ID string `json:"id"`
37 Kind string `json:"kind"`
38 RTTMS int `json:"rtt_ms,omitempty"`
39 LossPercent int `json:"loss_percent,omitempty"`
40}
41
42type scenario struct {
43 ID string `json:"id"`
44 Topology string `json:"topology"`
45 Workload string `json:"workload"`
46 Transport string `json:"transport"`
47 Roles []string `json:"roles"`
48 InapplicableReason string `json:"inapplicable_reason,omitempty"`
49}
50
51type processMapping struct {
52 ProcessID string `json:"process_id"`
53 ClockDomain string `json:"clock_domain"`
54 TracePath string `json:"trace_path"`
55 Role string `json:"role"`
56 Scenario string `json:"scenario"`
57 Run int `json:"run"`
58 Identity string `json:"identity"`
59}
60
61type runManifest struct {
62 Scenario string `json:"scenario"`
63 Run int `json:"run"`
64 Processes []processMapping `json:"processes"`
65}
66
67// measuredInterval belongs solely to the harness clock domain. A paired event
68// is eligible only when both owned boundaries fall inside this interval.
69type measuredInterval struct {
70 Start int64
71 End int64
72}
73
74type eventSample struct {
75 Sequence uint64 `json:"sequence"`
76 Injected int64 `json:"injected_tick"`
77 Flushed int64 `json:"flushed_tick"`
78 Latency int64 `json:"latency_nanos"`
79}
80
81type span struct {
82 Component, Name string
83 Samples []int64
84}
85
86type runResult struct {
87 Spans []span `json:"process_local_spans"`
88 Scenario string `json:"scenario"`
89 Run int `json:"run"`
90 Samples int `json:"samples"`
91 EndToEnd []int64 `json:"end_to_end_nanos"`
92 Event distribution `json:"event_end_to_end"`
93 Cadence distribution `json:"event_cadence_nanos"`
94 CadenceSamples []int64 `json:"-"`
95 MaxGap int64 `json:"event_max_gap_nanos"`
96 Processes []processMapping `json:"processes"`
97}
98
99type summary struct {
100 Schema uint16 `json:"schema"`
101 GitSHA string `json:"git_sha"`
102 VevGitSHA string `json:"vev_git_sha"`
103 Warmup string `json:"warmup"`
104 Duration string `json:"duration"`
105 Repetitions int `json:"repetitions"`
106 EndToEnd distribution `json:"harness_end_to_end"`
107 Cadence distribution `json:"harness_event_cadence_nanos"`
108 MaxGap int64 `json:"harness_event_max_gap_nanos"`
109 RunP50Dispersion distribution `json:"run_p50_dispersion"`
110 Spans []spanSummary `json:"process_local_spans"`
111 Runs int `json:"runs"`
112}
113
114type distribution struct {
115 Count int `json:"count"`
116 P50 int64 `json:"p50"`
117 P95 int64 `json:"p95"`
118 P99 int64 `json:"p99"`
119 Max int64 `json:"max"`
120}
121
122type spanSummary struct {
123 Component string `json:"component"`
124 Name string `json:"name"`
125 Distribution distribution `json:"distribution"`
126}
127
128type clock interface {
129 Now() int64
130 Sleep(time.Duration)
131}
132
133type systemClock struct{ start time.Time }
134
135var spanPairs = []spanPair{{"capture_start", "capture_end", "capture_duration"}, {"compose_start", "compose_end", "compose_duration"}, {"diff_start", "diff_end", "diff_duration"}, {"queue_enqueued", "queue_dequeued", "queue_wait"}, {"ack_blocked_start", "ack_blocked_end", "ack_blocked_interval"}, {"emit_start", "emit_end", "emit_duration"}, {"adapter_send_start", "adapter_send_end", "adapter_send_duration"}, {"adapter_receive_start", "adapter_receive_end", "adapter_receive_duration"}}