Skip to content

Commit ae56e10

Browse files
committed
test writer with stdlib tx
1 parent 3660b3c commit ae56e10

File tree

3 files changed

+191
-25
lines changed

3 files changed

+191
-25
lines changed

errors.go

+2
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@ var (
77
ErrTxUnsupportedType = errors.New("tx has unsupported type")
88

99
ErrTableEmpty = errors.New("table is empty")
10+
11+
ErrPoolNil = errors.New("pool is nil")
1012
)

reader.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package outbox
22

33
import (
44
"context"
5-
"errors"
65
"fmt"
76
"time"
87

@@ -37,7 +36,7 @@ type reader struct {
3736

3837
func NewReader(table string, pool *pgxpool.Pool, opts ...ReadOption) (Reader, error) {
3938
if pool == nil {
40-
return nil, errors.New("pool is nil")
39+
return nil, ErrPoolNil
4140
}
4241
if table == "" {
4342
return nil, ErrTableEmpty

writer_reader_test.go

+188-23
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ package outbox_test
22

33
import (
44
"context"
5+
"database/sql"
56
"encoding/json"
67
"fmt"
7-
"log/slog"
88
"os"
99
"testing"
1010

1111
"github.com/google/go-cmp/cmp"
1212
"github.com/jackc/pgx/v5"
1313
"github.com/jackc/pgx/v5/pgxpool"
14+
_ "github.com/jackc/pgx/v5/stdlib"
1415
outbox "github.com/nikolayk812/pgx-outbox"
1516
"github.com/nikolayk812/pgx-outbox/internal/containers"
1617
"github.com/nikolayk812/pgx-outbox/internal/fakes"
@@ -29,6 +30,7 @@ var ctx = context.Background()
2930
type WriterReaderTestSuite struct {
3031
suite.Suite
3132
pool *pgxpool.Pool
33+
db *sql.DB
3234
container testcontainers.Container
3335

3436
writer outbox.Writer
@@ -50,6 +52,9 @@ func (suite *WriterReaderTestSuite) SetupSuite() {
5052
suite.pool, err = pgxpool.New(ctx, connStr)
5153
suite.noError(err)
5254

55+
suite.db, err = sql.Open("pgx", connStr)
56+
suite.noError(err)
57+
5358
suite.writer, err = outbox.NewWriter(outboxTable)
5459
suite.noError(err)
5560

@@ -61,55 +66,82 @@ func (suite *WriterReaderTestSuite) TearDownSuite() {
6166
if suite.pool != nil {
6267
suite.pool.Close()
6368
}
69+
if suite.db != nil {
70+
suite.NoError(suite.db.Close())
71+
}
6472
if suite.container != nil {
65-
if err := suite.container.Terminate(ctx); err != nil {
66-
slog.Error("suite.container.Terminate", slog.Any("error", err))
67-
}
73+
suite.NoError(suite.container.Terminate(ctx))
6874
}
6975

7076
goleak.VerifyNone(suite.T())
7177
}
7278

73-
func (suite *WriterReaderTestSuite) TestWriter_New() {
79+
//nolint:dupl
80+
func (suite *WriterReaderTestSuite) TestWriter_WriteMessage() {
81+
invalidMessage := fakes.FakeMessage()
82+
invalidMessage.Broker = ""
83+
7484
tests := []struct {
7585
name string
76-
table string
77-
options []outbox.WriteOption
78-
wantErr error
86+
in []types.Message
87+
wantErr bool
7988
}{
8089
{
81-
name: "empty table",
82-
table: "",
83-
wantErr: outbox.ErrTableEmpty,
90+
name: "no messages",
91+
in: []types.Message{},
8492
},
8593
{
86-
name: "non-empty table",
87-
table: "outbox_messages",
94+
name: "single message",
95+
in: []types.Message{
96+
fakes.FakeMessage(),
97+
},
8898
},
8999
{
90-
name: "with options",
91-
table: "outbox_messages",
92-
options: []outbox.WriteOption{outbox.WithDisablePreparedBatch()},
100+
name: "multiple in",
101+
in: []types.Message{
102+
fakes.FakeMessage(),
103+
fakes.FakeMessage(),
104+
},
93105
},
106+
{
107+
name: "invalid message",
108+
in: []types.Message{
109+
invalidMessage,
110+
},
111+
wantErr: true,
112+
},
113+
// Add more test cases as needed
94114
}
95115

96116
for _, tt := range tests {
97117
suite.Run(tt.name, func() {
98118
t := suite.T()
99119

100-
writer, err := outbox.NewWriter(tt.table, tt.options...)
101-
if tt.wantErr != nil {
102-
require.ErrorIs(t, err, tt.wantErr)
103-
return
120+
// GIVEN
121+
for _, message := range tt.in {
122+
id, err := suite.write(message)
123+
if tt.wantErr {
124+
require.Error(t, err)
125+
return
126+
}
127+
require.NoError(t, err)
128+
assert.Positive(t, id)
104129
}
105130

131+
limit := maxInt(1, len(tt.in))
132+
133+
// THEN
134+
actual, err := suite.reader.Read(ctx, limit)
106135
require.NoError(t, err)
107-
assert.NotNil(t, writer)
136+
assertEqualMessages(t, tt.in, actual)
137+
138+
suite.markAll()
108139
})
109140
}
110141
}
111142

112-
func (suite *WriterReaderTestSuite) TestWriter_WriteMessage() {
143+
//nolint:dupl
144+
func (suite *WriterReaderTestSuite) TestWriter_WriteMessageStdLib() {
113145
invalidMessage := fakes.FakeMessage()
114146
invalidMessage.Broker = ""
115147

@@ -151,7 +183,7 @@ func (suite *WriterReaderTestSuite) TestWriter_WriteMessage() {
151183

152184
// GIVEN
153185
for _, message := range tt.in {
154-
id, err := suite.write(message)
186+
id, err := suite.writeStdLib(message)
155187
if tt.wantErr {
156188
require.Error(t, err)
157189
return
@@ -487,6 +519,34 @@ func (suite *WriterReaderTestSuite) beginTx(ctx context.Context) (pgx.Tx, func(e
487519
return tx, commitFunc, nil
488520
}
489521

522+
func (suite *WriterReaderTestSuite) beginTxStdLib() (*sql.Tx, func(err error) error, error) {
523+
emptyFunc := func(_ error) error { return nil }
524+
525+
tx, err := suite.db.Begin()
526+
if err != nil {
527+
return nil, emptyFunc, fmt.Errorf("db.Begin: %w", err)
528+
}
529+
530+
commitFunc := func(execErr error) error {
531+
if execErr != nil {
532+
rbErr := tx.Rollback()
533+
if rbErr != nil {
534+
return fmt.Errorf("tx.Rollback %v: %w", execErr, rbErr) //nolint:errorlint
535+
}
536+
return execErr
537+
}
538+
539+
txErr := tx.Commit()
540+
if txErr != nil {
541+
return fmt.Errorf("tx.Commit: %w", txErr)
542+
}
543+
544+
return nil
545+
}
546+
547+
return tx, commitFunc, nil
548+
}
549+
490550
func (suite *WriterReaderTestSuite) write(message types.Message) (_ int64, txErr error) {
491551
tx, commitFunc, err := suite.beginTx(ctx)
492552
if err != nil {
@@ -506,6 +566,25 @@ func (suite *WriterReaderTestSuite) write(message types.Message) (_ int64, txErr
506566
return id, nil
507567
}
508568

569+
func (suite *WriterReaderTestSuite) writeStdLib(message types.Message) (_ int64, txErr error) {
570+
tx, commitFunc, err := suite.beginTxStdLib()
571+
if err != nil {
572+
return 0, fmt.Errorf("beginTx: %w", err)
573+
}
574+
defer func() {
575+
if err := commitFunc(txErr); err != nil {
576+
txErr = fmt.Errorf("commitFunc: %w", err)
577+
}
578+
}()
579+
580+
id, err := suite.writer.Write(ctx, tx, message)
581+
if err != nil {
582+
return 0, fmt.Errorf("writer.Write: %w", err)
583+
}
584+
585+
return id, nil
586+
}
587+
509588
func (suite *WriterReaderTestSuite) writeBatch(messages []types.Message) (_ []int64, txErr error) {
510589
tx, commitFunc, err := suite.beginTx(ctx)
511590
if err != nil {
@@ -549,13 +628,54 @@ func (suite *WriterReaderTestSuite) noError(err error) {
549628
suite.Require().NoError(err)
550629
}
551630

631+
//nolint:unparam
552632
func maxInt(x, y int) int {
553633
if x > y {
554634
return x
555635
}
556636
return y
557637
}
558638

639+
// TestWriter_New is just to increase coverage.
640+
func (suite *WriterReaderTestSuite) TestWriter_New() {
641+
tests := []struct {
642+
name string
643+
table string
644+
options []outbox.WriteOption
645+
wantErr error
646+
}{
647+
{
648+
name: "empty table",
649+
table: "",
650+
wantErr: outbox.ErrTableEmpty,
651+
},
652+
{
653+
name: "non-empty table",
654+
table: "outbox_messages",
655+
},
656+
{
657+
name: "with options",
658+
table: "outbox_messages",
659+
options: []outbox.WriteOption{outbox.WithDisablePreparedBatch()},
660+
},
661+
}
662+
663+
for _, tt := range tests {
664+
suite.Run(tt.name, func() {
665+
t := suite.T()
666+
667+
writer, err := outbox.NewWriter(tt.table, tt.options...)
668+
if tt.wantErr != nil {
669+
require.ErrorIs(t, err, tt.wantErr)
670+
return
671+
}
672+
673+
require.NoError(t, err)
674+
assert.NotNil(t, writer)
675+
})
676+
}
677+
}
678+
559679
func (suite *WriterReaderTestSuite) TestWriter_WriteWithNilTx() {
560680
message := fakes.FakeMessage()
561681

@@ -599,3 +719,48 @@ func (suite *WriterReaderTestSuite) TestWriter_WriteWithNilTx() {
599719
})
600720
}
601721
}
722+
723+
// TestReader_New is just to increase coverage.
724+
func (suite *WriterReaderTestSuite) TestReader_New() {
725+
tests := []struct {
726+
name string
727+
table string
728+
pool *pgxpool.Pool
729+
option outbox.ReadOption
730+
wantErr error
731+
}{
732+
{
733+
name: "empty table",
734+
table: "",
735+
pool: suite.pool,
736+
wantErr: outbox.ErrTableEmpty,
737+
},
738+
{
739+
name: "nil pool",
740+
table: "outbox_messages",
741+
pool: nil,
742+
wantErr: outbox.ErrPoolNil,
743+
},
744+
{
745+
name: "with option",
746+
table: "outbox_messages",
747+
pool: suite.pool,
748+
option: outbox.WithReadFilter(types.MessageFilter{Brokers: []string{"broker1"}}),
749+
},
750+
}
751+
752+
for _, tt := range tests {
753+
suite.Run(tt.name, func() {
754+
t := suite.T()
755+
756+
reader, err := outbox.NewReader(tt.table, tt.pool, tt.option)
757+
if tt.wantErr != nil {
758+
require.ErrorIs(t, err, tt.wantErr)
759+
return
760+
}
761+
762+
require.NoError(t, err)
763+
assert.NotNil(t, reader)
764+
})
765+
}
766+
}

0 commit comments

Comments
 (0)