mirror of
https://github.com/turbot/steampipe.git
synced 2025-12-19 09:58:53 -05:00
* Add test for #4716: sort() should be safe for concurrent calls * Fix #4716: Add mutex protection to autoCompleteSuggestions.sort() Adds sync.RWMutex to prevent data race during concurrent sort() calls. Changes sort() from value receiver to pointer receiver to support locking. The mutex ensures thread-safe access when multiple goroutines call sort() simultaneously during autocomplete initialization.
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
package interactive
|
||||
|
||||
import (
|
||||
"github.com/c-bata/go-prompt"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/c-bata/go-prompt"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -15,6 +17,7 @@ const (
|
||||
)
|
||||
|
||||
type autoCompleteSuggestions struct {
|
||||
mu sync.RWMutex
|
||||
schemas []prompt.Suggest
|
||||
unqualifiedTables []prompt.Suggest
|
||||
unqualifiedQueries []prompt.Suggest
|
||||
@@ -72,7 +75,10 @@ func (s *autoCompleteSuggestions) setQueriesForMod(modName string, queries []pro
|
||||
s.queriesByMod[modName] = queries
|
||||
}
|
||||
|
||||
func (s autoCompleteSuggestions) sort() {
|
||||
func (s *autoCompleteSuggestions) sort() {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
sortSuggestions := func(s []prompt.Suggest) {
|
||||
sort.Slice(s, func(i, j int) bool {
|
||||
return s[i].Text < s[j].Text
|
||||
|
||||
64
pkg/interactive/autocomplete_suggestions_test.go
Normal file
64
pkg/interactive/autocomplete_suggestions_test.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package interactive
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/c-bata/go-prompt"
|
||||
)
|
||||
|
||||
// TestAutoCompleteSuggestions_ConcurrentSort tests that sort() can be called
|
||||
// concurrently without triggering data races.
|
||||
// This test reproduces the race condition reported in issue #4716.
|
||||
func TestAutoCompleteSuggestions_ConcurrentSort(t *testing.T) {
|
||||
// Create a populated autoCompleteSuggestions instance
|
||||
suggestions := newAutocompleteSuggestions()
|
||||
|
||||
// Populate with test data
|
||||
suggestions.schemas = []prompt.Suggest{
|
||||
{Text: "public"},
|
||||
{Text: "aws"},
|
||||
{Text: "github"},
|
||||
}
|
||||
|
||||
suggestions.unqualifiedTables = []prompt.Suggest{
|
||||
{Text: "table1"},
|
||||
{Text: "table2"},
|
||||
{Text: "table3"},
|
||||
}
|
||||
|
||||
suggestions.unqualifiedQueries = []prompt.Suggest{
|
||||
{Text: "query1"},
|
||||
{Text: "query2"},
|
||||
{Text: "query3"},
|
||||
}
|
||||
|
||||
suggestions.tablesBySchema["public"] = []prompt.Suggest{
|
||||
{Text: "users"},
|
||||
{Text: "accounts"},
|
||||
}
|
||||
|
||||
suggestions.queriesByMod["aws"] = []prompt.Suggest{
|
||||
{Text: "aws_query1"},
|
||||
{Text: "aws_query2"},
|
||||
}
|
||||
|
||||
// Call sort() concurrently from multiple goroutines
|
||||
// This should trigger a race condition if the sort() method is not thread-safe
|
||||
var wg sync.WaitGroup
|
||||
numGoroutines := 10
|
||||
|
||||
for i := 0; i < numGoroutines; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
suggestions.sort()
|
||||
}()
|
||||
}
|
||||
|
||||
// Wait for all goroutines to complete
|
||||
wg.Wait()
|
||||
|
||||
// If we get here without panicking or race detector errors, the test passes
|
||||
// Note: This test will fail when run with -race flag if sort() is not thread-safe
|
||||
}
|
||||
Reference in New Issue
Block a user