Skip to content

Commit 362598b

Browse files
committed
Create resolvers_test.go
1 parent 991676d commit 362598b

1 file changed

Lines changed: 96 additions & 0 deletions

File tree

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package resolvers
2+
3+
import (
4+
"context"
5+
"errors"
6+
"testing"
7+
8+
"github.com/apache/arrow-go/v18/arrow"
9+
"github.com/cloudquery/plugin-sdk/v4/caser"
10+
"github.com/cloudquery/plugin-sdk/v4/scheduler/metrics"
11+
"github.com/cloudquery/plugin-sdk/v4/schema"
12+
"github.com/rs/zerolog"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
type testClient struct{}
17+
18+
func (testClient) ID() string { return "test" }
19+
20+
var _ schema.ClientMeta = testClient{}
21+
22+
// TestResolveResourcesChunk_PreResourceResolverPartialFailure verifies that a
23+
// PreResourceResolver error on a single resource only drops that resource from
24+
// the batch, while the remaining resources are still resolved and returned.
25+
func TestResolveResourcesChunk_PreResourceResolverPartialFailure(t *testing.T) {
26+
for _, tc := range []struct {
27+
name string
28+
failItems map[int]bool
29+
expectedItems []int
30+
}{
31+
{
32+
name: "no failures keeps all resources",
33+
failItems: nil,
34+
expectedItems: []int{0, 1, 2, 3, 4},
35+
},
36+
{
37+
name: "single failure drops only that resource",
38+
failItems: map[int]bool{2: true},
39+
expectedItems: []int{0, 1, 3, 4},
40+
},
41+
{
42+
name: "multiple failures drop only the failing resources",
43+
failItems: map[int]bool{0: true, 3: true},
44+
expectedItems: []int{1, 2, 4},
45+
},
46+
{
47+
name: "all failures drop the whole batch but do not panic",
48+
failItems: map[int]bool{0: true, 1: true, 2: true, 3: true, 4: true},
49+
expectedItems: []int{},
50+
},
51+
} {
52+
t.Run(tc.name, func(t *testing.T) {
53+
table := &schema.Table{
54+
Name: "test_table",
55+
PreResourceResolver: func(_ context.Context, _ schema.ClientMeta, resource *schema.Resource) error {
56+
if tc.failItems[resource.Item.(int)] {
57+
return errors.New("pre resource resolver boom")
58+
}
59+
return nil
60+
},
61+
Columns: []schema.Column{
62+
{
63+
Name: "test_column",
64+
Type: arrow.PrimitiveTypes.Int64,
65+
Resolver: func(_ context.Context, _ schema.ClientMeta, resource *schema.Resource, c schema.Column) error {
66+
return resource.Set(c.Name, int64(resource.Item.(int)))
67+
},
68+
},
69+
},
70+
}
71+
72+
client := testClient{}
73+
m := metrics.NewMetrics()
74+
m.InitWithClients(table, []schema.ClientMeta{client})
75+
76+
chunk := []any{0, 1, 2, 3, 4}
77+
logger := zerolog.New(zerolog.NewTestWriter(t))
78+
79+
resources := ResolveResourcesChunk(context.Background(), logger, m, table, client, nil, chunk, caser.New())
80+
81+
gotItems := make([]int, len(resources))
82+
for i, r := range resources {
83+
gotItems[i] = r.Item.(int)
84+
// surviving resources should have been fully resolved through the column resolvers
85+
col := r.Get("test_column")
86+
require.True(t, col.IsValid(), "surviving resource should have its column resolved")
87+
require.Equal(t, int64(r.Item.(int)), col.Get(), "resolved column value should match the item")
88+
}
89+
require.ElementsMatch(t, tc.expectedItems, gotItems)
90+
91+
selector := m.NewSelector(client.ID(), table.Name)
92+
require.Equal(t, uint64(len(tc.failItems)), m.GetErrors(selector), "expected one error per failing resource")
93+
require.Equal(t, uint64(len(tc.expectedItems)), m.GetResources(selector), "only surviving resources should be counted")
94+
})
95+
}
96+
}

0 commit comments

Comments
 (0)