@@ -55,6 +55,232 @@ func TestCreatePostRequest(t *testing.T) {
5555}
5656
5757// formatPostRequest emulates the behavior of the githubpost package.
58+ func TestCreateRegressionPostRequestBasic (t * testing.T ) {
59+ regressions := []regressionInfo {
60+ {
61+ benchmarkName : "BenchmarkScan" ,
62+ metricUnit : "ns/op" ,
63+ percentChange : 25.5 ,
64+ formattedDelta : "+1.2ms" ,
65+ },
66+ {
67+ benchmarkName : "BenchmarkInsert" ,
68+ metricUnit : "ns/op" ,
69+ percentChange : 30.0 ,
70+ formattedDelta : "+500µs" ,
71+ },
72+ }
73+
74+ formatter , req := createRegressionPostRequest (
75+ "pkg/sql" ,
76+ regressions ,
77+ "https://docs.google.com/spreadsheets/d/test123" ,
78+ "master -> release-24.1" ,
79+ )
80+
81+ // Verify labels
82+ expectedLabels := []string {"O-microbench" , "C-performance" }
83+ for _ , label := range expectedLabels {
84+ found := false
85+ for _ , l := range req .Labels {
86+ if l == label {
87+ found = true
88+ break
89+ }
90+ }
91+ if ! found {
92+ t .Errorf ("Expected label %q not found in %v" , label , req .Labels )
93+ }
94+ }
95+
96+ // Verify title contains package name
97+ data := issues.TemplateData {
98+ PostRequest : req ,
99+ Parameters : req .ExtraParams ,
100+ CondensedMessage : issues .CondensedMessage (req .Message ),
101+ PackageNameShort : req .PackageName ,
102+ }
103+ title := formatter .Title (data )
104+ if ! strings .Contains (title , "pkg/sql" ) {
105+ t .Errorf ("Title should contain package name: %s" , title )
106+ }
107+ if ! strings .Contains (title , "performance regression" ) {
108+ t .Errorf ("Title should contain 'performance regression': %s" , title )
109+ }
110+
111+ // Verify message contains key information
112+ if ! strings .Contains (req .Message , "pkg/sql" ) {
113+ t .Error ("Message should contain package name" )
114+ }
115+ if ! strings .Contains (req .Message , "BenchmarkScan" ) {
116+ t .Error ("Message should contain benchmark name" )
117+ }
118+ if ! strings .Contains (req .Message , "25.5%" ) {
119+ t .Error ("Message should contain percentage" )
120+ }
121+ if ! strings .Contains (req .Message , "https://docs.google.com/spreadsheets/d/test123" ) {
122+ t .Error ("Message should contain sheet link" )
123+ }
124+ if ! strings .Contains (req .Message , "master -> release-24.1" ) {
125+ t .Error ("Message should contain comparison description" )
126+ }
127+ }
128+
129+ func TestCreateRegressionPostRequestMultiple (t * testing.T ) {
130+ // Test with multiple regressions
131+ regressions := make ([]regressionInfo , 15 )
132+ for i := 0 ; i < 15 ; i ++ {
133+ regressions [i ] = regressionInfo {
134+ benchmarkName : fmt .Sprintf ("Benchmark%d" , i ),
135+ metricUnit : "ns/op" ,
136+ percentChange : 20.0 + float64 (i ),
137+ formattedDelta : fmt .Sprintf ("+%dµs" , i * 100 ),
138+ }
139+ }
140+
141+ _ , req := createRegressionPostRequest (
142+ "pkg/kv" ,
143+ regressions ,
144+ "https://docs.google.com/spreadsheets/d/test456" ,
145+ "baseline -> experiment" ,
146+ )
147+
148+ // Should mention total count
149+ if ! strings .Contains (req .Message , "15 benchmark(s)" ) {
150+ t .Error ("Message should contain total regression count" )
151+ }
152+
153+ // Should truncate to 10 and show "... and 5 more"
154+ if ! strings .Contains (req .Message , "5 more regression(s)" ) {
155+ t .Errorf ("Message should indicate truncation. Got: %s" , req .Message )
156+ }
157+
158+ // First regression should be present
159+ if ! strings .Contains (req .Message , "Benchmark0" ) {
160+ t .Error ("Message should contain first benchmark" )
161+ }
162+
163+ // 11th regression should not be listed individually
164+ if strings .Contains (req .Message , "Benchmark10" ) {
165+ t .Error ("Message should not list 11th benchmark individually" )
166+ }
167+ }
168+
169+ func TestCreateRegressionPostRequestTruncation (t * testing.T ) {
170+ // Test the exact boundary at 10 regressions
171+ regressions := make ([]regressionInfo , 10 )
172+ for i := 0 ; i < 10 ; i ++ {
173+ regressions [i ] = regressionInfo {
174+ benchmarkName : fmt .Sprintf ("Benchmark%d" , i ),
175+ metricUnit : "ns/op" ,
176+ percentChange : 20.0 ,
177+ formattedDelta : "+100µs" ,
178+ }
179+ }
180+
181+ _ , req := createRegressionPostRequest (
182+ "pkg/storage" ,
183+ regressions ,
184+ "https://docs.google.com/spreadsheets/d/test" ,
185+ "test comparison" ,
186+ )
187+
188+ // All 10 should be listed
189+ for i := 0 ; i < 10 ; i ++ {
190+ if ! strings .Contains (req .Message , fmt .Sprintf ("Benchmark%d" , i )) {
191+ t .Errorf ("Message should contain Benchmark%d" , i )
192+ }
193+ }
194+
195+ // Should not show truncation message for exactly 10
196+ if strings .Contains (req .Message , "more regression(s)" ) {
197+ t .Error ("Should not show truncation message for exactly 10 regressions" )
198+ }
199+ }
200+
201+ func TestCreateRegressionPostRequestFormat (t * testing.T ) {
202+ // Test the full formatted output of a regression issue
203+ regressions := []regressionInfo {
204+ {
205+ benchmarkName : "BenchmarkScan/rows=1000" ,
206+ metricUnit : "ns/op" ,
207+ percentChange : 25.5 ,
208+ formattedDelta : "+1.2ms" ,
209+ },
210+ {
211+ benchmarkName : "BenchmarkInsert/batch=100" ,
212+ metricUnit : "B/op" ,
213+ percentChange : 30.0 ,
214+ formattedDelta : "+5.0KB" ,
215+ },
216+ }
217+
218+ formatter , req := createRegressionPostRequest (
219+ "pkg/sql/exec" ,
220+ regressions ,
221+ "https://docs.google.com/spreadsheets/d/example123" ,
222+ "v24.1.0 -> v24.2.0" ,
223+ )
224+
225+ // Verify the full formatted message structure
226+ output , err := formatPostRequest (formatter , req )
227+ if err != nil {
228+ t .Fatalf ("Failed to format post request: %v" , err )
229+ }
230+
231+ // Check title format
232+ data := issues.TemplateData {
233+ PostRequest : req ,
234+ Parameters : req .ExtraParams ,
235+ CondensedMessage : issues .CondensedMessage (req .Message ),
236+ PackageNameShort : req .PackageName ,
237+ }
238+ title := formatter .Title (data )
239+
240+ // Verify title structure
241+ if ! strings .Contains (title , "pkg/sql/exec" ) {
242+ t .Errorf ("Title should contain package name, got: %s" , title )
243+ }
244+ if ! strings .Contains (title , "performance regression" ) {
245+ t .Errorf ("Title should contain 'performance regression', got: %s" , title )
246+ }
247+
248+ // Verify formatted output contains all key elements
249+ expectedElements := []string {
250+ "Performance regressions detected in package pkg/sql/exec" ,
251+ "Comparison: v24.1.0 -> v24.2.0" ,
252+ "Found 2 benchmark(s) with regressions ≥20%" ,
253+ "BenchmarkScan/rows=1000" ,
254+ "(ns/op): +1.2ms (25.5%)" ,
255+ "BenchmarkInsert/batch=100" ,
256+ "(B/op): +5.0KB (30.0%)" ,
257+ "Detailed comparison: https://docs.google.com/spreadsheets/d/example123" ,
258+ }
259+
260+ for _ , expected := range expectedElements {
261+ if ! strings .Contains (output , expected ) {
262+ t .Errorf ("Formatted output should contain %q\n Got:\n %s" , expected , output )
263+ }
264+ }
265+
266+ // Verify labels are correct
267+ if ! containsLabel (req .Labels , "O-microbench" ) {
268+ t .Errorf ("Should have O-microbench label, got: %v" , req .Labels )
269+ }
270+ if ! containsLabel (req .Labels , "C-performance" ) {
271+ t .Errorf ("Should have C-performance label, got: %v" , req .Labels )
272+ }
273+ }
274+
275+ func containsLabel (labels []string , label string ) bool {
276+ for _ , l := range labels {
277+ if l == label {
278+ return true
279+ }
280+ }
281+ return false
282+ }
283+
58284func formatPostRequest (formatter issues.IssueFormatter , req issues.PostRequest ) (string , error ) {
59285 // These fields can vary based on the test env so we set them to arbitrary
60286 // values here.
0 commit comments