github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/datastore/postgres/snapshot_test.go (about)

     1  package postgres
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/jackc/pgx/v5/pgtype"
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  func TestSnapshotDecodeEncode(t *testing.T) {
    12  	testCases := []struct {
    13  		snapshot    string
    14  		expected    pgSnapshot
    15  		expectError bool
    16  	}{
    17  		{"415:415:", snap(415, 415), false},
    18  		{"123:456:124,126,168", snap(123, 456, 124, 126, 168), false},
    19  
    20  		{"", invalidSnapshot, true},
    21  		{"123", invalidSnapshot, true},
    22  		{"123:456", invalidSnapshot, true},
    23  		{"123:456:789:10", invalidSnapshot, true},
    24  		{"abc:456:124,126,168", invalidSnapshot, true},
    25  	}
    26  
    27  	for _, tc := range testCases {
    28  		tc := tc
    29  		t.Run(tc.snapshot, func(t *testing.T) {
    30  			require := require.New(t)
    31  
    32  			var decoded pgSnapshot
    33  			err := decoded.ScanText(pgtype.Text{String: tc.snapshot, Valid: true})
    34  			if tc.expectError {
    35  				require.Error(err)
    36  				return
    37  			}
    38  			require.NoError(err)
    39  			require.Equal(tc.expected, decoded)
    40  
    41  			reEncoded, err := decoded.TextValue()
    42  			require.NoError(err)
    43  			require.Equal(tc.snapshot, reEncoded.String)
    44  		})
    45  	}
    46  }
    47  
    48  func TestMarkComplete(t *testing.T) {
    49  	testCases := []struct {
    50  		snapshot pgSnapshot
    51  		toMark   uint64
    52  		expected pgSnapshot
    53  	}{
    54  		{snap(0, 0), 0, snap(1, 1)},
    55  		{snap(0, 5, 0, 3), 3, snap(0, 5, 0)},
    56  		{snap(3, 5, 3), 3, snap(5, 5)},
    57  		{snap(0, 0), 5, snap(0, 6, 0, 1, 2, 3, 4)},
    58  		{snap(5, 5), 4, snap(5, 5)},
    59  	}
    60  
    61  	for _, tc := range testCases {
    62  		tc := tc
    63  		t.Run(fmt.Sprintf("%s+%d=>%s", tc.snapshot, tc.toMark, tc.expected), func(t *testing.T) {
    64  			require := require.New(t)
    65  			completed := tc.snapshot.markComplete(tc.toMark)
    66  			require.Equal(tc.expected, completed, "%s != %s", tc.expected, completed)
    67  		})
    68  	}
    69  }
    70  
    71  func TestMarkInProgress(t *testing.T) {
    72  	testCases := []struct {
    73  		snapshot pgSnapshot
    74  		toMark   uint64
    75  		expected pgSnapshot
    76  	}{
    77  		{snap(1, 1), 0, snap(0, 0)},
    78  		{snap(0, 5, 0), 3, snap(0, 5, 0, 3)},
    79  		{snap(5, 5), 3, snap(3, 5, 3)},
    80  		{snap(0, 6, 0, 1, 2, 3, 4), 5, snap(0, 0)},
    81  		{snap(5, 5), 4, snap(4, 4)},
    82  		{snap(5, 5), 10, snap(5, 5)},
    83  	}
    84  
    85  	for _, tc := range testCases {
    86  		tc := tc
    87  		t.Run(fmt.Sprintf("%s-%d=>%s", tc.snapshot, tc.toMark, tc.expected), func(t *testing.T) {
    88  			require := require.New(t)
    89  			withInProgress := tc.snapshot.markInProgress(tc.toMark)
    90  			require.Equal(tc.expected, withInProgress, "%s != %s", tc.expected, withInProgress)
    91  		})
    92  	}
    93  }
    94  
    95  func snap(xmin, xmax uint64, xips ...uint64) pgSnapshot {
    96  	return pgSnapshot{
    97  		xmin, xmax, xips,
    98  	}
    99  }
   100  
   101  var invalidSnapshot = snap(0, 0)