Skip to content

Commit 963cac6

Browse files
committed
add coverage
1 parent dcf0a40 commit 963cac6

3 files changed

Lines changed: 99 additions & 15 deletions

File tree

internal/pgengine/bootstrap_test.go

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ import (
1717
"github.com/stretchr/testify/assert"
1818
)
1919

20+
func anyArgs(i int) []any {
21+
args := make([]any, i)
22+
for j := range i {
23+
args[j] = pgxmock.AnyArg()
24+
}
25+
return args
26+
}
27+
2028
func TestExecuteSchemaScripts(t *testing.T) {
2129
initmockdb(t)
2230
defer mockPool.Close()
@@ -146,6 +154,87 @@ func TestTryLockClientName(t *testing.T) {
146154
})
147155
}
148156

157+
func TestCreateChainFromYamlErrors(t *testing.T) {
158+
initmockdb(t)
159+
defer mockPool.Close()
160+
mockpge := pgengine.NewDB(mockPool, "pgengine_unit_test")
161+
162+
t.Run("Database error during chain creation", func(t *testing.T) {
163+
mockPool.ExpectQuery(`INSERT INTO timetable.chain`).
164+
WithArgs(anyArgs(9)...).
165+
WillReturnError(fmt.Errorf("simulated DB error"))
166+
_, err := mockpge.CreateChainFromYaml(ctx, &pgengine.YamlChain{})
167+
assert.Error(t, err)
168+
assert.NoError(t, mockPool.ExpectationsWereMet())
169+
})
170+
171+
t.Run("Database error during task creation", func(t *testing.T) {
172+
mockPool.ExpectQuery(`INSERT INTO timetable.chain`).
173+
WithArgs(anyArgs(9)...).
174+
WillReturnRows(pgxmock.NewRows([]string{"chain_id"}).AddRow(1))
175+
mockPool.ExpectQuery(`INSERT INTO timetable.task`).
176+
WithArgs(anyArgs(10)...).
177+
WillReturnError(fmt.Errorf("simulated DB error on task"))
178+
179+
_, err := mockpge.CreateChainFromYaml(ctx, &pgengine.YamlChain{
180+
Chain: pgengine.Chain{ChainName: "test-chain"},
181+
Schedule: "0 0 * * *",
182+
Tasks: []pgengine.YamlTask{
183+
{ChainTask: pgengine.ChainTask{Command: "SELECT 1", Kind: "SQL"}},
184+
},
185+
})
186+
assert.Error(t, err)
187+
assert.NoError(t, mockPool.ExpectationsWereMet())
188+
})
189+
190+
t.Run("Database error during parameter unmarshalling", func(t *testing.T) {
191+
mockPool.ExpectQuery(`INSERT INTO timetable.chain`).
192+
WithArgs(anyArgs(9)...).
193+
WillReturnRows(pgxmock.NewRows([]string{"chain_id"}).AddRow(1))
194+
mockPool.ExpectQuery(`INSERT INTO timetable.task`).
195+
WithArgs(anyArgs(10)...).
196+
WillReturnRows(pgxmock.NewRows([]string{"task_id"}).AddRow(1))
197+
198+
_, err := mockpge.CreateChainFromYaml(ctx, &pgengine.YamlChain{
199+
Chain: pgengine.Chain{ChainName: "test-chain"},
200+
Schedule: "0 0 * * *",
201+
Tasks: []pgengine.YamlTask{
202+
{
203+
ChainTask: pgengine.ChainTask{Command: "SELECT 1", Kind: "SQL"},
204+
Parameters: []any{func() {}}, // functions cannot be marshalled to JSON
205+
},
206+
},
207+
})
208+
assert.Error(t, err)
209+
assert.NoError(t, mockPool.ExpectationsWereMet())
210+
})
211+
212+
t.Run("Database error during parameter creation", func(t *testing.T) {
213+
mockPool.ExpectQuery(`INSERT INTO timetable.chain`).
214+
WithArgs(anyArgs(9)...).
215+
WillReturnRows(pgxmock.NewRows([]string{"chain_id"}).AddRow(1))
216+
mockPool.ExpectQuery(`INSERT INTO timetable.task`).
217+
WithArgs(anyArgs(10)...).
218+
WillReturnRows(pgxmock.NewRows([]string{"task_id"}).AddRow(1))
219+
mockPool.ExpectExec(`INSERT INTO timetable.parameter`).
220+
WithArgs(anyArgs(3)...).
221+
WillReturnError(fmt.Errorf("simulated DB error on parameter"))
222+
223+
_, err := mockpge.CreateChainFromYaml(ctx, &pgengine.YamlChain{
224+
Chain: pgengine.Chain{ChainName: "test-chain"},
225+
Schedule: "0 0 * * *",
226+
Tasks: []pgengine.YamlTask{
227+
{
228+
ChainTask: pgengine.ChainTask{Command: "SELECT 1", Kind: "SQL"},
229+
Parameters: []any{"foo"},
230+
},
231+
},
232+
})
233+
assert.Error(t, err)
234+
assert.NoError(t, mockPool.ExpectationsWereMet())
235+
})
236+
}
237+
149238
func TestExecuteFileScript(t *testing.T) {
150239
initmockdb(t)
151240
defer mockPool.Close()
@@ -154,14 +243,6 @@ func TestExecuteFileScript(t *testing.T) {
154243
// Create temporary directory for test files
155244
tmpDir := t.TempDir()
156245

157-
anyArgs := func(i int) []any {
158-
args := make([]any, i)
159-
for j := range i {
160-
args[j] = pgxmock.AnyArg()
161-
}
162-
return args
163-
}
164-
165246
t.Run("SQL file execution", func(t *testing.T) {
166247
// Create temporary SQL file
167248
sqlFile := filepath.Join(tmpDir, "test.sql")

internal/pgengine/yaml.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func (pge *PgEngine) LoadYamlChains(ctx context.Context, filePath string, replac
5959
}
6060

6161
// Multi-task chain - use direct SQL
62-
chainID, err := pge.createChainFromYaml(ctx, &yamlChain)
62+
chainID, err := pge.CreateChainFromYaml(ctx, &yamlChain)
6363
if err != nil {
6464
return fmt.Errorf("failed to create multi-task chain %s: %w", yamlChain.ChainName, err)
6565
}
@@ -70,8 +70,8 @@ func (pge *PgEngine) LoadYamlChains(ctx context.Context, filePath string, replac
7070
return nil
7171
}
7272

73-
// createChainFromYaml creates a multi-task chain using direct SQL inserts
74-
func (pge *PgEngine) createChainFromYaml(ctx context.Context, yamlChain *YamlChain) (int64, error) {
73+
// CreateChainFromYaml creates a multi-task chain using direct SQL inserts
74+
func (pge *PgEngine) CreateChainFromYaml(ctx context.Context, yamlChain *YamlChain) (int64, error) {
7575
// Insert chain
7676
var chainID int64
7777
err := pge.ConfigDb.QueryRow(ctx, `INSERT INTO timetable.chain (
@@ -121,13 +121,13 @@ func (pge *PgEngine) createChainFromYaml(ctx context.Context, yamlChain *YamlCha
121121
if len(task.Parameters) > 0 {
122122
for paramIndex, param := range task.Parameters {
123123
orderID := paramIndex + 1
124-
124+
125125
// Convert parameter to JSON for JSONB storage
126126
jsonValue, err := json.Marshal(param)
127127
if err != nil {
128128
return 0, fmt.Errorf("failed to marshal parameter %d to JSON: %w", orderID, err)
129129
}
130-
130+
131131
_, err = pge.ConfigDb.Exec(ctx,
132132
"INSERT INTO timetable.parameter (task_id, order_id, value) VALUES ($1, $2, $3::jsonb)",
133133
taskID, orderID, string(jsonValue))
@@ -258,5 +258,3 @@ func ParseYamlFile(filePath string) (*YamlConfig, error) {
258258

259259
return &config, nil
260260
}
261-
262-

internal/pgengine/yaml_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,11 @@ func TestParseYamlFile(t *testing.T) {
254254
assert.Contains(t, err.Error(), "file not found")
255255
})
256256

257+
t.Run("File cannot be read", func(t *testing.T) {
258+
_, err := pgengine.ParseYamlFile(".")
259+
assert.Error(t, err)
260+
})
261+
257262
t.Run("Invalid YAML syntax", func(t *testing.T) {
258263
invalidYaml := `chains:
259264
- name: "test"

0 commit comments

Comments
 (0)