Skip to content

Commit fb48f8d

Browse files
Ajit Pratap Singhclaude
authored andcommitted
test: address PR review comments for backward compatibility suite
Improvements based on code review feedback: 1. Fix circular token testing logic: - Use actual token constants instead of creating from strings - Only test tokens exported from token package - Properly compare string values of token constants 2. Enhance concurrent test safety: - Add result struct with goroutine ID tracking - Use dedicated channels for error reporting - Properly check for nil tokenizer returns - Report detailed error information per goroutine 3. Improve regression error reporting: - Include full query metadata in error messages - Show Description, Dialect, AddedVersion for context - Enhanced known failure logging with reasons - Track when previously failing queries start passing All tests passing with improved error visibility and race condition safety. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 791f3e4 commit fb48f8d

2 files changed

Lines changed: 74 additions & 37 deletions

File tree

pkg/compatibility/api_stability_test.go

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package compatibility
22

33
import (
4+
"fmt"
45
"reflect"
56
"testing"
67

@@ -144,34 +145,37 @@ func TestAPIStability_PoolBehavior(t *testing.T) {
144145

145146
// TestAPIStability_TokenTypes ensures token type constants remain stable
146147
func TestAPIStability_TokenTypes(t *testing.T) {
147-
// Critical token types that must not change
148-
criticalTokens := map[string]token.Type{
149-
"SELECT": "SELECT",
150-
"FROM": "FROM",
151-
"WHERE": "WHERE",
152-
"JOIN": "JOIN",
153-
"INSERT": "INSERT",
154-
"UPDATE": "UPDATE",
155-
"DELETE": "DELETE",
156-
"CREATE": "CREATE",
157-
"ALTER": "ALTER",
158-
"DROP": "DROP",
159-
"IDENT": "IDENT",
160-
"INT": "INT",
161-
"STRING": "STRING",
162-
"EOF": "EOF",
163-
"ILLEGAL": "ILLEGAL",
148+
// Critical token types that must not change - verify exported constants exist and have correct values
149+
// Only test tokens that are actually exported from the token package
150+
tests := []struct {
151+
name string
152+
actualValue token.Type
153+
expectedValue string
154+
}{
155+
{"SELECT", token.SELECT, "SELECT"},
156+
{"FROM", token.FROM, "FROM"},
157+
{"WHERE", token.WHERE, "WHERE"},
158+
{"INSERT", token.INSERT, "INSERT"},
159+
{"UPDATE", token.UPDATE, "UPDATE"},
160+
{"DELETE", token.DELETE, "DELETE"},
161+
{"ALTER", token.ALTER, "ALTER"},
162+
{"DROP", token.DROP, "DROP"},
163+
{"TABLE", token.TABLE, "TABLE"},
164+
{"IDENT", token.IDENT, "IDENT"},
165+
{"INT", token.INT, "INT"},
166+
{"STRING", token.STRING, "STRING"},
167+
{"EOF", token.EOF, "EOF"},
168+
{"ILLEGAL", token.ILLEGAL, "ILLEGAL"},
164169
}
165170

166-
for name, expectedValue := range criticalTokens {
167-
t.Run("Token_"+name, func(t *testing.T) {
168-
// Verify token constant exists and has expected value
169-
actualValue := token.Type(expectedValue)
170-
if actualValue != expectedValue {
171+
for _, tt := range tests {
172+
t.Run("Token_"+tt.name, func(t *testing.T) {
173+
// Verify token constant has expected string value
174+
if string(tt.actualValue) != tt.expectedValue {
171175
t.Errorf("Token type %s changed value\nExpected: %s\nGot: %s",
172-
name, expectedValue, actualValue)
176+
tt.name, tt.expectedValue, string(tt.actualValue))
173177
} else {
174-
t.Logf("✓ Token %s stable: %s", name, actualValue)
178+
t.Logf("✓ Token %s stable: %s", tt.name, tt.actualValue)
175179
}
176180
})
177181
}
@@ -283,30 +287,53 @@ func TestAPIStability_ConcurrentUsage(t *testing.T) {
283287
const iterations = 10
284288

285289
sql := "SELECT * FROM users"
286-
done := make(chan bool, goroutines)
290+
291+
// Use separate channels for error reporting and completion tracking
292+
type result struct {
293+
goroutineID int
294+
err error
295+
}
296+
results := make(chan result, goroutines)
287297

288298
// Launch concurrent tokenization
289299
for i := 0; i < goroutines; i++ {
290-
go func() {
300+
go func(id int) {
291301
defer func() {
292302
if r := recover(); r != nil {
293-
t.Errorf("PANIC in concurrent usage: %v", r)
303+
results <- result{id, fmt.Errorf("PANIC: %v", r)}
304+
return
294305
}
295-
done <- true
306+
results <- result{id, nil}
296307
}()
297308

298309
for j := 0; j < iterations; j++ {
299310
tkz := tokenizer.GetTokenizer()
300-
_, _ = tkz.Tokenize([]byte(sql))
311+
if tkz == nil {
312+
t.Errorf("GetTokenizer() returned nil in goroutine %d", id)
313+
return
314+
}
315+
_, err := tkz.Tokenize([]byte(sql))
316+
if err != nil {
317+
t.Errorf("Tokenization failed in goroutine %d: %v", id, err)
318+
}
301319
tokenizer.PutTokenizer(tkz)
302320
}
303-
}()
321+
}(i)
304322
}
305323

306-
// Wait for all goroutines
324+
// Collect results with timeout
325+
errorCount := 0
307326
for i := 0; i < goroutines; i++ {
308-
<-done
327+
res := <-results
328+
if res.err != nil {
329+
t.Errorf("Goroutine %d failed: %v", res.goroutineID, res.err)
330+
errorCount++
331+
}
309332
}
310333

311-
t.Logf("✓ Concurrent usage stable (%d goroutines × %d iterations)", goroutines, iterations)
334+
if errorCount > 0 {
335+
t.Errorf("Concurrent usage stability compromised: %d/%d goroutines failed", errorCount, goroutines)
336+
} else {
337+
t.Logf("✓ Concurrent usage stable (%d goroutines × %d iterations)", goroutines, iterations)
338+
}
312339
}

pkg/compatibility/compatibility_test.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,28 @@ func testVersionCompatibility(t *testing.T, version string) {
5858

5959
if query.ShouldPass {
6060
if !success {
61-
t.Errorf("Query that worked in %s now fails: %s\nQuery: %s\nError: %s",
62-
version, query.Name, query.SQL, errMsg)
61+
// Enhanced error reporting for regressions
62+
t.Errorf("REGRESSION DETECTED in %s\n"+
63+
"Query Name: %s\n"+
64+
"Description: %s\n"+
65+
"Dialect: %s\n"+
66+
"Added In: %s\n"+
67+
"SQL: %s\n"+
68+
"Error: %s",
69+
version, query.Name, query.Description, query.Dialect,
70+
query.AddedVersion, query.SQL, errMsg)
6371
failCount++
6472
} else {
6573
passCount++
6674
}
6775
} else {
6876
// Document known failures - these are expected to fail but we track them
6977
if !success {
70-
t.Logf("Known failure (expected): %s - %s", query.Name, errMsg)
78+
t.Logf("Known failure (expected): %s - %s\nReason: %s",
79+
query.Name, errMsg, query.Description)
7180
} else {
72-
t.Logf("Previously failing query now passes: %s", query.Name)
81+
t.Logf("Previously failing query now passes: %s\nDescription: %s",
82+
query.Name, query.Description)
7383
}
7484
}
7585
})

0 commit comments

Comments
 (0)