Skip to content

Commit 57e25b3

Browse files
committedMar 31, 2020
test(migrations): add tests for api provider and
requires migrations
1 parent 1a45513 commit 57e25b3

File tree

8 files changed

+345
-84
lines changed

8 files changed

+345
-84
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
annotations:
22
operators.operatorframework.io.bundle.package.v1: "prometheus"
33
operators.operatorframework.io.bundle.channels.v1: "preview,stable"
4-
operators.operatorframework.io.bundle.channel.default.v1: "preview"
4+
operators.operatorframework.io.bundle.channel.default.v1: "preview"

‎pkg/containertools/labelreader_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import (
44
"fmt"
55
"testing"
66

7-
"github.com/operator-framework/operator-registry/pkg/containertools"
8-
"github.com/operator-framework/operator-registry/pkg/containertools/containertoolsfakes"
9-
107
"github.com/sirupsen/logrus"
118
"github.com/stretchr/testify/require"
9+
10+
"github.com/operator-framework/operator-registry/pkg/containertools"
11+
"github.com/operator-framework/operator-registry/pkg/containertools/containertoolsfakes"
1212
)
1313

1414
func TestReadDockerLabels(t *testing.T) {

‎pkg/registry/bundle.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func (b *Bundle) Replaces() (string, error) {
9898

9999
func (b *Bundle) Skips() ([]string, error) {
100100
if err := b.cache(); err != nil {
101-
return []string{}, err
101+
return nil, err
102102
}
103103
return b.csv.GetSkips()
104104
}

‎pkg/sqlite/graphloader_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ package sqlite
33
import (
44
"context"
55
"database/sql"
6-
"github.com/operator-framework/operator-registry/pkg/registry"
76
"testing"
87

98
"github.com/stretchr/testify/require"
9+
10+
"github.com/operator-framework/operator-registry/pkg/registry"
1011
)
1112

1213
func createLoadedTestDb(t *testing.T) (*sql.DB, func()) {

‎pkg/sqlite/load.go

+10-6
Original file line numberDiff line numberDiff line change
@@ -453,17 +453,17 @@ func (s *SQLLoader) addAPIs(tx *sql.Tx, bundle *registry.Bundle) error {
453453
}
454454
defer addAPI.Close()
455455

456-
addApiProvider, err := tx.Prepare("insert into api_provider(group_name, version, kind, operatorbundle_name, operatorbundle_version, operatorbundle_path) values(?, ?, ?, ?, ?, ?)")
456+
addAPIProvider, err := tx.Prepare("insert into api_provider(group_name, version, kind, operatorbundle_name, operatorbundle_version, operatorbundle_path) values(?, ?, ?, ?, ?, ?)")
457457
if err != nil {
458458
return err
459459
}
460-
defer addApiProvider.Close()
460+
defer addAPIProvider.Close()
461461

462-
addApiRequirer, err := tx.Prepare("insert into api_requirer(group_name, version, kind, operatorbundle_name, operatorbundle_version, operatorbundle_path) values(?, ?, ?, ?, ?, ?)")
462+
addAPIRequirer, err := tx.Prepare("insert into api_requirer(group_name, version, kind, operatorbundle_name, operatorbundle_version, operatorbundle_path) values(?, ?, ?, ?, ?, ?)")
463463
if err != nil {
464464
return err
465465
}
466-
defer addApiRequirer.Close()
466+
defer addAPIRequirer.Close()
467467

468468
providedApis, err := bundle.ProvidedAPIs()
469469
if err != nil {
@@ -477,12 +477,16 @@ func (s *SQLLoader) addAPIs(tx *sql.Tx, bundle *registry.Bundle) error {
477477
if err != nil {
478478
return err
479479
}
480+
481+
sqlString := func(s string) sql.NullString {
482+
return sql.NullString{String: s, Valid: s != ""}
483+
}
480484
for api := range providedApis {
481485
if _, err := addAPI.Exec(api.Group, api.Version, api.Kind, api.Plural); err != nil {
482486
return err
483487
}
484488

485-
if _, err := addApiProvider.Exec(api.Group, api.Version, api.Kind, bundle.Name, bundleVersion, bundle.BundleImage); err != nil {
489+
if _, err := addAPIProvider.Exec(api.Group, api.Version, api.Kind, bundle.Name, sqlString(bundleVersion), sqlString(bundle.BundleImage)); err != nil {
486490
return err
487491
}
488492
}
@@ -491,7 +495,7 @@ func (s *SQLLoader) addAPIs(tx *sql.Tx, bundle *registry.Bundle) error {
491495
return err
492496
}
493497

494-
if _, err := addApiRequirer.Exec(api.Group, api.Version, api.Kind, bundle.Name, bundleVersion, bundle.BundleImage); err != nil {
498+
if _, err := addAPIRequirer.Exec(api.Group, api.Version, api.Kind, bundle.Name, sqlString(bundleVersion), sqlString(bundle.BundleImage)); err != nil {
495499
return err
496500
}
497501
}

‎pkg/sqlite/migrations/006_associate_apis_with_bundle.go

+160-60
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ var bundleApiMigration = &Migration{
4747
FOREIGN KEY(operatorbundle_name, operatorbundle_version, operatorbundle_path) REFERENCES operatorbundle(name, version, bundlepath) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
4848
FOREIGN KEY(group_name, version, kind) REFERENCES api(group_name, version, kind) ON DELETE CASCADE
4949
);
50+
-- these three fields are used as the target of a foreign key, so they need an index
5051
CREATE UNIQUE INDEX pk ON operatorbundle(name, version, bundlepath);
5152
`
5253
_, err := tx.ExecContext(ctx, createNew)
@@ -57,7 +58,7 @@ var bundleApiMigration = &Migration{
5758
insertProvided := `INSERT INTO api_provider_new(group_name, version, kind, operatorbundle_name, operatorbundle_version, operatorbundle_path) VALUES (?, ?, ?, ?, ?, ?)`
5859
insertRequired := `INSERT INTO api_requirer_new(group_name, version, kind, operatorbundle_name, operatorbundle_version, operatorbundle_path) VALUES (?, ?, ?, ?, ?, ?)`
5960

60-
bundleApis, err := getApisForBundles(ctx, tx)
61+
bundleApis, err := mapBundlesToApisFromOldSchema(ctx, tx)
6162
if err != nil {
6263
return err
6364
}
@@ -90,18 +91,79 @@ var bundleApiMigration = &Migration{
9091
return err
9192
},
9293
Down: func(ctx context.Context, tx *sql.Tx) error {
93-
// TODO
94-
return nil
94+
createOld := `
95+
CREATE TABLE api_provider_old (
96+
group_name TEXT,
97+
version TEXT,
98+
kind TEXT,
99+
channel_entry_id INTEGER,
100+
FOREIGN KEY(channel_entry_id) REFERENCES channel_entry(entry_id),
101+
FOREIGN KEY(group_name, version, kind) REFERENCES api(group_name, version, kind) ON DELETE CASCADE
102+
);
103+
CREATE TABLE api_requirer_old (
104+
group_name TEXT,
105+
version TEXT,
106+
kind TEXT,
107+
channel_entry_id INTEGER,
108+
FOREIGN KEY(channel_entry_id) REFERENCES channel_entry(entry_id),
109+
FOREIGN KEY(group_name, version, kind) REFERENCES api(group_name, version, kind) ON DELETE CASCADE
110+
);
111+
`
112+
_, err := tx.ExecContext(ctx, createOld)
113+
if err != nil {
114+
return err
115+
}
116+
117+
insertProvided := `INSERT INTO api_provider_old(group_name, version, kind, channel_entry_id) VALUES (?, ?, ?, ?)`
118+
insertRequired := `INSERT INTO api_requirer_old(group_name, version, kind, channel_entry_id) VALUES (?, ?, ?, ?)`
119+
120+
entryApis, err := mapChannelEntryToApisFromNewSchema(ctx, tx)
121+
if err != nil {
122+
return err
123+
}
124+
for entry, apis := range entryApis {
125+
for provided := range apis.provided {
126+
_, err := tx.ExecContext(ctx, insertProvided, provided.Group, provided.Version, provided.Kind, entry)
127+
if err != nil {
128+
return err
129+
}
130+
}
131+
for required := range apis.required {
132+
_, err := tx.ExecContext(ctx, insertRequired, required.Group, required.Version, required.Kind, entry)
133+
if err != nil {
134+
return err
135+
}
136+
}
137+
}
138+
139+
renameOldAndDrop := `
140+
DROP TABLE api_provider;
141+
DROP TABLE api_requirer;
142+
ALTER TABLE api_provider_old RENAME TO api_provider;
143+
ALTER TABLE api_requirer_old RENAME TO api_requirer;
144+
`
145+
_, err = tx.ExecContext(ctx, renameOldAndDrop)
146+
if err != nil {
147+
return err
148+
}
149+
150+
return err
95151
},
96152
}
97153

154+
type bundleKey struct {
155+
BundlePath sql.NullString
156+
Version sql.NullString
157+
CsvName sql.NullString
158+
}
159+
98160
type apis struct {
99161
provided map[registry.APIKey]struct{}
100162
required map[registry.APIKey]struct{}
101163
}
102164

103-
func getApisForBundles(ctx context.Context, tx *sql.Tx) (map[registry.BundleKey]apis, error) {
104-
bundles := map[registry.BundleKey]apis{}
165+
func mapBundlesToApisFromOldSchema(ctx context.Context, tx *sql.Tx) (map[bundleKey]apis, error) {
166+
bundles := map[bundleKey]apis{}
105167

106168
providedQuery := `SELECT api_provider.group_name, api_provider.version, api_provider.kind, operatorbundle.name, operatorbundle.version, operatorbundle.bundlepath
107169
FROM api_provider
@@ -118,22 +180,18 @@ func getApisForBundles(ctx context.Context, tx *sql.Tx) (map[registry.BundleKey]
118180
return nil, err
119181
}
120182
for providedRows.Next() {
121-
var group sql.NullString
122-
var apiVersion sql.NullString
123-
var kind sql.NullString
124-
var name sql.NullString
125-
var bundleVersion sql.NullString
126-
var path sql.NullString
183+
var group, apiVersion, kind, name, bundleVersion, path sql.NullString
184+
127185
if err = providedRows.Scan(&group, &apiVersion, &kind, &name, &bundleVersion, &path); err != nil {
128186
return nil, err
129187
}
130-
if !group.Valid || !apiVersion.Valid || !kind.Valid || !name.Valid || !bundleVersion.Valid || !path.Valid {
188+
if !group.Valid || !apiVersion.Valid || !kind.Valid || !name.Valid {
131189
continue
132190
}
133-
key := registry.BundleKey{
134-
BundlePath: path.String,
135-
Version: bundleVersion.String,
136-
CsvName: name.String,
191+
key := bundleKey{
192+
BundlePath: path,
193+
Version: bundleVersion,
194+
CsvName: name,
137195
}
138196
bundleApis, ok := bundles[key]
139197
if !ok {
@@ -166,13 +224,13 @@ func getApisForBundles(ctx context.Context, tx *sql.Tx) (map[registry.BundleKey]
166224
if err = requiredRows.Scan(&group, &apiVersion, &kind, &name, &bundleVersion, &path); err != nil {
167225
return nil, err
168226
}
169-
if !group.Valid || !apiVersion.Valid || !kind.Valid || !name.Valid || !bundleVersion.Valid || !path.Valid {
227+
if !group.Valid || !apiVersion.Valid || !kind.Valid || !name.Valid {
170228
continue
171229
}
172-
key := registry.BundleKey{
173-
BundlePath: path.String,
174-
Version: bundleVersion.String,
175-
CsvName: name.String,
230+
key := bundleKey{
231+
BundlePath: path,
232+
Version: bundleVersion,
233+
CsvName: name,
176234
}
177235
bundleApis, ok := bundles[key]
178236
if !ok {
@@ -194,42 +252,84 @@ func getApisForBundles(ctx context.Context, tx *sql.Tx) (map[registry.BundleKey]
194252
return bundles, nil
195253
}
196254

197-
// OLD queries
198-
//
199-
//func GetChannelEntriesThatProvide(ctx context.Context, group, version, kind string) (entries []*registry.ChannelEntry, err error) {
200-
// query := `SELECT DISTINCT channel_entry.package_name, channel_entry.channel_name, channel_entry.operatorbundle_name, replaces.operatorbundle_name
201-
// FROM channel_entry
202-
// INNER JOIN api_provider ON channel_entry.entry_id = api_provider.channel_entry_id
203-
// LEFT OUTER JOIN channel_entry replaces ON channel_entry.replaces = replaces.entry_id
204-
// WHERE api_provider.group_name = ? AND api_provider.version = ? AND api_provider.kind = ?`
205-
//
206-
// rows, err := s.db.QueryContext(ctx, query, group, version, kind)
207-
// if err != nil {
208-
// return
209-
// }
210-
// defer rows.Close()
211-
//
212-
// entries = []*registry.ChannelEntry{}
213-
//
214-
// for rows.Next() {
215-
// var pkgNameSQL sql.NullString
216-
// var channelNameSQL sql.NullString
217-
// var bundleNameSQL sql.NullString
218-
// var replacesSQL sql.NullString
219-
// if err = rows.Scan(&pkgNameSQL, &channelNameSQL, &bundleNameSQL, &replacesSQL); err != nil {
220-
// return
221-
// }
222-
//
223-
// entries = append(entries, &registry.ChannelEntry{
224-
// PackageName: pkgNameSQL.String,
225-
// ChannelName: channelNameSQL.String,
226-
// BundleName: bundleNameSQL.String,
227-
// Replaces: replacesSQL.String,
228-
// })
229-
// }
230-
// if len(entries) == 0 {
231-
// err = fmt.Errorf("no channel entries found that provide %s %s %s", group, version, kind)
232-
// return
233-
// }
234-
// return
235-
//}
255+
func mapChannelEntryToApisFromNewSchema(ctx context.Context, tx *sql.Tx) (map[int64]apis, error) {
256+
bundles := map[int64]apis{}
257+
258+
providedQuery := `SELECT api_provider.group_name, api_provider.version, api_provider.kind, channel_entry.entry_id
259+
FROM api_provider
260+
INNER JOIN operatorbundle ON operatorbundle.name = channel_entry.operatorbundle_name
261+
INNER JOIN channel_entry ON channel_entry.operatorbundle_name = api_provider.operatorbundle_name`
262+
263+
requiredQuery := `SELECT api_requirer.group_name, api_requirer.version, api_requirer.kind, channel_entry.entry_id
264+
FROM api_requirer
265+
INNER JOIN channel_entry ON channel_entry.operatorbundle_name = api_requirer.operatorbundle_name
266+
INNER JOIN operatorbundle ON operatorbundle.name = channel_entry.operatorbundle_name`
267+
268+
providedRows, err := tx.QueryContext(ctx, providedQuery)
269+
if err != nil {
270+
return nil, err
271+
}
272+
for providedRows.Next() {
273+
var (
274+
group, apiVersion, kind sql.NullString
275+
entryID sql.NullInt64
276+
)
277+
if err = providedRows.Scan(&group, &apiVersion, &kind, &entryID); err != nil {
278+
return nil, err
279+
}
280+
if !group.Valid || !apiVersion.Valid || !kind.Valid {
281+
continue
282+
}
283+
284+
bundleApis, ok := bundles[entryID.Int64]
285+
if !ok {
286+
bundleApis = apis{
287+
provided: map[registry.APIKey]struct{}{},
288+
required: map[registry.APIKey]struct{}{},
289+
}
290+
}
291+
292+
bundleApis.provided[registry.APIKey{
293+
Group: group.String,
294+
Version: apiVersion.String,
295+
Kind: kind.String,
296+
}] = struct{}{}
297+
298+
bundles[entryID.Int64] = bundleApis
299+
}
300+
301+
requiredRows, err := tx.QueryContext(ctx, requiredQuery)
302+
if err != nil {
303+
return nil, err
304+
}
305+
for requiredRows.Next() {
306+
var (
307+
group, apiVersion, kind sql.NullString
308+
entryID sql.NullInt64
309+
)
310+
if err = providedRows.Scan(&group, &apiVersion, &kind, &entryID); err != nil {
311+
return nil, err
312+
}
313+
if !group.Valid || !apiVersion.Valid || !kind.Valid {
314+
continue
315+
}
316+
317+
bundleApis, ok := bundles[entryID.Int64]
318+
if !ok {
319+
bundleApis = apis{
320+
provided: map[registry.APIKey]struct{}{},
321+
required: map[registry.APIKey]struct{}{},
322+
}
323+
}
324+
325+
bundleApis.required[registry.APIKey{
326+
Group: group.String,
327+
Version: apiVersion.String,
328+
Kind: kind.String,
329+
}] = struct{}{}
330+
331+
bundles[entryID.Int64] = bundleApis
332+
}
333+
334+
return bundles, nil
335+
}

0 commit comments

Comments
 (0)
Please sign in to comment.