github.com/PDOK/gokoala@v0.50.6/internal/ogc/features/datasources/geopackage/stmtcache_test.go (about)

     1  package geopackage
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  	"testing"
     7  
     8  	"github.com/jmoiron/sqlx"
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  func TestPreparedStatementCache(t *testing.T) {
    13  	tests := []struct {
    14  		name  string
    15  		query string
    16  	}{
    17  		{
    18  			name:  "First query is a cache miss",
    19  			query: "SELECT * FROM main.sqlite_master WHERE name = :n",
    20  		},
    21  		{
    22  			name:  "Second query is a cache hit",
    23  			query: "SELECT * FROM main.sqlite_master WHERE name = :n",
    24  		},
    25  	}
    26  	for _, tt := range tests {
    27  		t.Run(tt.name, func(t *testing.T) {
    28  			c := NewCache()
    29  			assert.NotNil(t, c)
    30  
    31  			db, err := sqlx.Connect("sqlite3", ":memory:")
    32  			assert.NoError(t, err)
    33  
    34  			stmt, err := c.Lookup(context.Background(), db, tt.query)
    35  			assert.NoError(t, err)
    36  			assert.NotNil(t, stmt)
    37  
    38  			c.Close()
    39  		})
    40  	}
    41  
    42  	t.Run("Concurrent access to the cache", func(t *testing.T) {
    43  		var wg sync.WaitGroup
    44  
    45  		c := NewCache()
    46  		assert.NotNil(t, c)
    47  
    48  		db, err := sqlx.Connect("sqlite3", ":memory:")
    49  		assert.NoError(t, err)
    50  
    51  		// Run multiple goroutines that will access the cache concurrently.
    52  		for i := 0; i < 25; i++ {
    53  			wg.Add(1)
    54  			go func() {
    55  				defer wg.Done()
    56  				stmt1, err := c.Lookup(context.Background(), db, "SELECT * FROM main.sqlite_master WHERE name = :n")
    57  				assert.NoError(t, err)
    58  				assert.NotNil(t, stmt1)
    59  
    60  				stmt2, err := c.Lookup(context.Background(), db, "SELECT * FROM main.sqlite_master WHERE type = :t")
    61  				assert.NoError(t, err)
    62  				assert.NotNil(t, stmt2)
    63  			}()
    64  		}
    65  		wg.Wait() // Wait for all goroutines to finish.
    66  
    67  		assert.Equal(t, 2, c.cache.Len())
    68  		c.Close()
    69  	})
    70  }