Skip to content
This repository has been archived by the owner on Aug 12, 2022. It is now read-only.

feat(tests): Fetch only the resources required for test being run #400

Merged
merged 3 commits into from
Jul 4, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion provider/schema/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type Table struct {
AlwaysDelete bool

// IgnoreInTests is used to exclude a table from integration tests.
// By default, integration tests fetch all resources from cloudquery's test account, and verifY all tables
// By default, integration tests fetch all resources from cloudquery's test account, and verify all tables
// have at least one row.
// When IgnoreInTests is true, integration tests won't fetch from this table.
// Used when it is hard to create a reproducible environment with a row in this table.
Expand Down
89 changes: 49 additions & 40 deletions provider/testing/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import (
"testing"

sq "github.com/Masterminds/squirrel"
"github.com/cloudquery/faker/v3"
"github.com/georgysavva/scany/pgxscan"
"github.com/hashicorp/go-hclog"
"github.com/stretchr/testify/assert"

"github.com/cloudquery/cq-provider-sdk/cqproto"
"github.com/cloudquery/cq-provider-sdk/database"
"github.com/cloudquery/cq-provider-sdk/migration"
Expand All @@ -18,10 +23,6 @@ import (
"github.com/cloudquery/cq-provider-sdk/provider/execution"
"github.com/cloudquery/cq-provider-sdk/provider/schema"
"github.com/cloudquery/cq-provider-sdk/testlog"
"github.com/cloudquery/faker/v3"
"github.com/georgysavva/scany/pgxscan"
"github.com/hashicorp/go-hclog"
"github.com/stretchr/testify/assert"
)

type ResourceTestCase struct {
Expand Down Expand Up @@ -75,60 +76,68 @@ func TestResource(t *testing.T, resource ResourceTestCase) {
l.SetLevel(hclog.Info)
resource.Provider.Logger = l

for _, table := range resource.Provider.ResourceMap {
if err := dropAndCreateTable(context.Background(), conn, table); err != nil {
assert.FailNow(t, fmt.Sprintf("failed to create tables %s", table.Name), err)
}
}

if err = fetch(t, &resource); err != nil {
t.Fatal(err)
// configure provider
if resp, configErr := resource.Provider.ConfigureProvider(context.Background(), &cqproto.ConfigureProviderRequest{
CloudQueryVersion: "",
Connection: cqproto.ConnectionDetails{DSN: getEnv("DATABASE_URL",
"host=localhost user=postgres password=pass DB.name=postgres port=5432")},
Config: []byte(resource.Config),
}); configErr != nil {
t.Fatal("failed to configure provider", configErr)
} else if resp != nil && resp.Diagnostics.HasErrors() {
t.Fatal("errors while configuring provider", configErr)
}

for resourceName, table := range resource.Provider.ResourceMap {
if verifiers, ok := resource.Verifiers[resourceName]; ok {
for _, verifier := range verifiers {
verifier(t, table, conn, resource.SkipIgnoreInTest)
t.Run(table.Name, func(t *testing.T) {
testErr := testResource(t, resource, resourceName, table, conn)
if testErr != nil {
t.Errorf("Error testing %v: %v", table.Name, testErr)
}
} else {
// fallback to default verification
verifyNoEmptyColumns(t, table, conn, resource.SkipIgnoreInTest)
}
})
}
}

// fetch - fetches resources from the cloud and puts them into database. database config can be specified via DATABASE_URL env variable
func fetch(t *testing.T, resource *ResourceTestCase) error {
func testResource(t *testing.T, resource ResourceTestCase, name string, table *schema.Table, conn execution.QueryExecer) error {
t.Helper()
resourceNames := make([]string, 0, len(resource.Provider.ResourceMap))
for name, table := range resource.Provider.ResourceMap {
if !resource.SkipIgnoreInTest && table.IgnoreInTests {
t.Logf("skipping resource: %s in tests", name)
continue
}
resourceNames = append(resourceNames, name)

if createErr := dropAndCreateTable(context.Background(), conn, table); createErr != nil {
assert.FailNow(t, fmt.Sprintf("failed to create table %s", table.Name), createErr)
}

t.Logf("fetch resources %v", resourceNames)
if !resource.SkipIgnoreInTest && table.IgnoreInTests {
t.Logf("skipping fetch of resource: %s in tests", name)
} else {
if err := fetchResource(t, &resource, name); err != nil {
return err
}
}

if resp, err := resource.Provider.ConfigureProvider(context.Background(), &cqproto.ConfigureProviderRequest{
CloudQueryVersion: "",
Connection: cqproto.ConnectionDetails{DSN: getEnv("DATABASE_URL",
"host=localhost user=postgres password=pass DB.name=postgres port=5432")},
Config: []byte(resource.Config),
}); err != nil {
return err
} else if resp != nil && resp.Diagnostics.HasErrors() {
return resp.Diagnostics
if verifiers, ok := resource.Verifiers[name]; ok {
for _, verifier := range verifiers {
verifier(t, table, conn, resource.SkipIgnoreInTest)
}
} else {
// fallback to default verification
verifyNoEmptyColumns(t, table, conn, resource.SkipIgnoreInTest)
}

return nil
}

// fetchResource - fetches a resource from the cloud and puts them into database. database config can be specified via DATABASE_URL env variable
func fetchResource(t *testing.T, resource *ResourceTestCase, resourceName string) error {
t.Helper()

t.Logf("fetch resource %v", resourceName)

var resourceSender = &testResourceSender{
Errors: []string{},
}

if err := resource.Provider.FetchResources(context.Background(),
&cqproto.FetchResourcesRequest{
Resources: resourceNames,
Resources: []string{resourceName},
ParallelFetchingLimit: resource.ParallelFetchingLimit,
},
resourceSender,
Expand All @@ -137,7 +146,7 @@ func fetch(t *testing.T, resource *ResourceTestCase) error {
}

if len(resourceSender.Errors) > 0 {
return fmt.Errorf("error/s occur during test, %s", strings.Join(resourceSender.Errors, ", "))
return fmt.Errorf("error/s occurred during test, %s", strings.Join(resourceSender.Errors, ", "))
}

return nil
Expand Down