go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

pg_test.go (7349B)


      1 package postgres
      2 
      3 import (
      4 	"bytes"
      5 	"context"
      6 	"testing"
      7 
      8 	"github.com/jackc/pgx/v5/pgconn"
      9 	"github.com/jackc/pgx/v5/pgtype"
     10 	pgxmock "github.com/pashagolub/pgxmock/v4"
     11 
     12 	"git.defalsify.org/vise.git/db"
     13 	"git.defalsify.org/vise.git/db/dbtest"
     14 )
     15 
     16 var (
     17 	typMap = pgtype.NewMap()
     18 
     19 	mockVfd = pgconn.FieldDescription{
     20 		Name:        "value",
     21 		DataTypeOID: pgtype.ByteaOID,
     22 		Format:      typMap.FormatCodeForOID(pgtype.ByteaOID),
     23 	}
     24 )
     25 
     26 func TestCasesPg(t *testing.T) {
     27 	ctx := context.Background()
     28 
     29 	t.Skip("implement expects in all cases")
     30 
     31 	mock, err := pgxmock.NewPool()
     32 	if err != nil {
     33 		t.Fatal(err)
     34 	}
     35 	defer mock.Close()
     36 
     37 	store := NewPgDb().WithConnection(mock).WithSchema("vvise")
     38 
     39 	err = dbtest.RunTests(t, ctx, store)
     40 	if err != nil {
     41 		t.Fatal(err)
     42 	}
     43 }
     44 
     45 func TestPutGetPg(t *testing.T) {
     46 	var dbi db.Db
     47 	ses := "xyzzy"
     48 
     49 	mock, err := pgxmock.NewPool()
     50 	if err != nil {
     51 		t.Fatal(err)
     52 	}
     53 	defer mock.Close()
     54 
     55 	store := NewPgDb().WithConnection(mock).WithSchema("vvise")
     56 	store.SetPrefix(db.DATATYPE_USERDATA)
     57 	store.SetSession(ses)
     58 	ctx := context.Background()
     59 
     60 	dbi = store
     61 	_ = dbi
     62 
     63 	k := []byte("foo")
     64 	ks := append([]byte{db.DATATYPE_USERDATA}, []byte(ses)...)
     65 	ks = append(ks, []byte(".")...)
     66 	ks = append(ks, k...)
     67 	v := []byte("bar")
     68 	resInsert := pgxmock.NewResult("UPDATE", 1)
     69 	mock.ExpectBegin()
     70 	mock.ExpectExec("INSERT INTO vvise.kv_vise").WithArgs(ks, v).WillReturnResult(resInsert)
     71 	mock.ExpectCommit()
     72 	err = store.Put(ctx, k, v)
     73 	if err != nil {
     74 		t.Fatal(err)
     75 	}
     76 
     77 	row := pgxmock.NewRowsWithColumnDefinition(mockVfd)
     78 	row = row.AddRow(v)
     79 	mock.ExpectBegin()
     80 	mock.ExpectQuery("SELECT value FROM vvise.kv_vise").WithArgs(ks).WillReturnRows(row)
     81 	mock.ExpectCommit()
     82 	b, err := store.Get(ctx, k)
     83 	if err != nil {
     84 		t.Fatal(err)
     85 	}
     86 
     87 	// TODO: implement as pgtype map instead, and btw also ask why getting base64 here
     88 	if !bytes.Equal(b, v) {
     89 		t.Fatalf("expected 'bar', got %x", b)
     90 	}
     91 
     92 	v = []byte("plugh")
     93 	mock.ExpectBegin()
     94 	mock.ExpectExec("INSERT INTO vvise.kv_vise").WithArgs(ks, v).WillReturnResult(resInsert)
     95 	mock.ExpectCommit()
     96 	err = store.Put(ctx, k, v)
     97 	if err != nil {
     98 		t.Fatal(err)
     99 	}
    100 
    101 	mock.ExpectBegin()
    102 	mock.ExpectExec("INSERT INTO vvise.kv_vise").WithArgs(ks, v).WillReturnResult(resInsert)
    103 	mock.ExpectCommit()
    104 	err = store.Put(ctx, k, v)
    105 	if err != nil {
    106 		t.Fatal(err)
    107 	}
    108 
    109 	row = pgxmock.NewRowsWithColumnDefinition(mockVfd)
    110 	row = row.AddRow(v)
    111 	mock.ExpectBegin()
    112 	mock.ExpectQuery("SELECT value FROM vvise.kv_vise").WithArgs(ks).WillReturnRows(row)
    113 	mock.ExpectCommit()
    114 	b, err = store.Get(ctx, k)
    115 	if err != nil {
    116 		t.Fatal(err)
    117 	}
    118 
    119 	if !bytes.Equal(b, v) {
    120 		t.Fatalf("expected 'plugh', got %x", b)
    121 	}
    122 
    123 }
    124 
    125 func TestPostgresTxAbort(t *testing.T) {
    126 	var dbi db.Db
    127 	ses := "xyzzy"
    128 
    129 	mock, err := pgxmock.NewPool()
    130 	if err != nil {
    131 		t.Fatal(err)
    132 	}
    133 	defer mock.Close()
    134 
    135 	store := NewPgDb().WithConnection(mock).WithSchema("vvise")
    136 	store.SetPrefix(db.DATATYPE_USERDATA)
    137 	store.SetSession(ses)
    138 	ctx := context.Background()
    139 
    140 	dbi = store
    141 	_ = dbi
    142 
    143 	resInsert := pgxmock.NewResult("UPDATE", 1)
    144 	k := []byte("foo")
    145 	ks := append([]byte{db.DATATYPE_USERDATA}, []byte(ses)...)
    146 	ks = append(ks, []byte(".")...)
    147 	ks = append(ks, k...)
    148 	v := []byte("bar")
    149 	//mock.ExpectBegin()
    150 	mock.ExpectBeginTx(defaultTxOptions)
    151 	mock.ExpectExec("INSERT INTO vvise.kv_vise").WithArgs(ks, v).WillReturnResult(resInsert)
    152 	mock.ExpectRollback()
    153 	err = store.Start(ctx)
    154 	if err != nil {
    155 		t.Fatal(err)
    156 	}
    157 	err = store.Put(ctx, k, v)
    158 	if err != nil {
    159 		t.Fatal(err)
    160 	}
    161 	store.Abort(ctx)
    162 }
    163 
    164 func TestPostgresTxCommitOnClose(t *testing.T) {
    165 	var dbi db.Db
    166 	ses := "xyzzy"
    167 
    168 	mock, err := pgxmock.NewPool()
    169 	if err != nil {
    170 		t.Fatal(err)
    171 	}
    172 	defer mock.Close()
    173 
    174 	store := NewPgDb().WithConnection(mock).WithSchema("vvise")
    175 	store.SetPrefix(db.DATATYPE_USERDATA)
    176 	store.SetSession(ses)
    177 	ctx := context.Background()
    178 
    179 	dbi = store
    180 	_ = dbi
    181 
    182 	resInsert := pgxmock.NewResult("UPDATE", 1)
    183 	k := []byte("foo")
    184 	ks := append([]byte{db.DATATYPE_USERDATA}, []byte(ses)...)
    185 	ks = append(ks, []byte(".")...)
    186 	ks = append(ks, k...)
    187 	v := []byte("bar")
    188 
    189 	ktwo := []byte("blinky")
    190 	kstwo := append([]byte{db.DATATYPE_USERDATA}, []byte(ses)...)
    191 	kstwo = append(kstwo, []byte(".")...)
    192 	kstwo = append(kstwo, ktwo...)
    193 	vtwo := []byte("clyde")
    194 
    195 	mock.ExpectBeginTx(defaultTxOptions)
    196 	mock.ExpectExec("INSERT INTO vvise.kv_vise").WithArgs(ks, v).WillReturnResult(resInsert)
    197 	mock.ExpectExec("INSERT INTO vvise.kv_vise").WithArgs(kstwo, vtwo).WillReturnResult(resInsert)
    198 	mock.ExpectCommit()
    199 
    200 	err = store.Start(ctx)
    201 	if err != nil {
    202 		t.Fatal(err)
    203 	}
    204 	err = store.Put(ctx, k, v)
    205 	if err != nil {
    206 		t.Fatal(err)
    207 	}
    208 	err = store.Put(ctx, ktwo, vtwo)
    209 	if err != nil {
    210 		t.Fatal(err)
    211 	}
    212 	err = store.Close(ctx)
    213 	if err != nil {
    214 		t.Fatal(err)
    215 	}
    216 
    217 	row := pgxmock.NewRowsWithColumnDefinition(mockVfd)
    218 	row = row.AddRow(v)
    219 	mock.ExpectBeginTx(defaultTxOptions)
    220 	mock.ExpectQuery("SELECT value FROM vvise.kv_vise").WithArgs(ks).WillReturnRows(row)
    221 	mock.ExpectCommit()
    222 	row = pgxmock.NewRowsWithColumnDefinition(mockVfd)
    223 	row = row.AddRow(vtwo)
    224 	mock.ExpectBeginTx(defaultTxOptions)
    225 	mock.ExpectQuery("SELECT value FROM vvise.kv_vise").WithArgs(kstwo).WillReturnRows(row)
    226 	mock.ExpectCommit()
    227 
    228 	store = NewPgDb().WithConnection(mock).WithSchema("vvise")
    229 	store.SetPrefix(db.DATATYPE_USERDATA)
    230 	store.SetSession(ses)
    231 	v, err = store.Get(ctx, k)
    232 	if err != nil {
    233 		if !db.IsNotFound(err) {
    234 			t.Fatalf("get key one: %x", k)
    235 		}
    236 	}
    237 	v, err = store.Get(ctx, ktwo)
    238 	if err != nil {
    239 		if !db.IsNotFound(err) {
    240 			t.Fatalf("get key two: %x", ktwo)
    241 		}
    242 	}
    243 }
    244 
    245 func TestPostgresTxStartStop(t *testing.T) {
    246 	var dbi db.Db
    247 	ses := "xyzzy"
    248 
    249 	mock, err := pgxmock.NewPool()
    250 	if err != nil {
    251 		t.Fatal(err)
    252 	}
    253 	defer mock.Close()
    254 
    255 	store := NewPgDb().WithConnection(mock).WithSchema("vvise")
    256 	store.SetPrefix(db.DATATYPE_USERDATA)
    257 	store.SetSession(ses)
    258 	ctx := context.Background()
    259 
    260 	dbi = store
    261 	_ = dbi
    262 
    263 	resInsert := pgxmock.NewResult("UPDATE", 1)
    264 	k := []byte("inky")
    265 	ks := append([]byte{db.DATATYPE_USERDATA}, []byte(ses)...)
    266 	ks = append(ks, []byte(".")...)
    267 	ks = append(ks, k...)
    268 	v := []byte("pinky")
    269 
    270 	ktwo := []byte("blinky")
    271 	kstwo := append([]byte{db.DATATYPE_USERDATA}, []byte(ses)...)
    272 	kstwo = append(kstwo, []byte(".")...)
    273 	kstwo = append(kstwo, ktwo...)
    274 	vtwo := []byte("clyde")
    275 	mock.ExpectBeginTx(defaultTxOptions)
    276 	mock.ExpectExec("INSERT INTO vvise.kv_vise").WithArgs(ks, v).WillReturnResult(resInsert)
    277 	mock.ExpectExec("INSERT INTO vvise.kv_vise").WithArgs(kstwo, vtwo).WillReturnResult(resInsert)
    278 	mock.ExpectCommit()
    279 
    280 	row := pgxmock.NewRowsWithColumnDefinition(mockVfd)
    281 	row = row.AddRow(v)
    282 	mock.ExpectBeginTx(defaultTxOptions)
    283 	mock.ExpectQuery("SELECT value FROM vvise.kv_vise").WithArgs(ks).WillReturnRows(row)
    284 	row = pgxmock.NewRowsWithColumnDefinition(mockVfd)
    285 	row = row.AddRow(vtwo)
    286 	mock.ExpectQuery("SELECT value FROM vvise.kv_vise").WithArgs(kstwo).WillReturnRows(row)
    287 	mock.ExpectCommit()
    288 
    289 	err = store.Start(ctx)
    290 	if err != nil {
    291 		t.Fatal(err)
    292 	}
    293 	err = store.Put(ctx, k, v)
    294 	if err != nil {
    295 		t.Fatal(err)
    296 	}
    297 	err = store.Put(ctx, ktwo, vtwo)
    298 	if err != nil {
    299 		t.Fatal(err)
    300 	}
    301 	err = store.Stop(ctx)
    302 	if err != nil {
    303 		t.Fatal(err)
    304 	}
    305 
    306 	v, err = store.Get(ctx, k)
    307 	if err != nil {
    308 		t.Fatal(err)
    309 	}
    310 	v, err = store.Get(ctx, ktwo)
    311 	if err != nil {
    312 		t.Fatal(err)
    313 	}
    314 	err = store.Close(ctx)
    315 	if err != nil {
    316 		t.Fatal(err)
    317 	}
    318 }