From a8a91379d9c51a04e178dba02660416180ba9046 Mon Sep 17 00:00:00 2001 From: Ales Raszka Date: Thu, 7 Mar 2019 13:53:58 +0100 Subject: [PATCH] Add test for potential namespace Test verifies that potential namespace is stored in database and it can be loaded back to structure. The commit also fixes few typos and bugs. --- database/dbutil.go | 2 +- database/pgsql/layer.go | 20 +++++++++++------ database/pgsql/layer_test.go | 22 +++++++++++++++++++ .../pgsql/migrations/00001_initial_schema.go | 2 +- database/pgsql/testdata/data.sql | 3 ++- database/pgsql/testutil.go | 1 + ext/featurefmt/apk/apk.go | 2 +- ext/featurefmt/dpkg/dpkg.go | 2 +- ext/featurefmt/rpm/rpm.go | 2 +- 9 files changed, 43 insertions(+), 13 deletions(-) diff --git a/database/dbutil.go b/database/dbutil.go index 6581e252..94528266 100644 --- a/database/dbutil.go +++ b/database/dbutil.go @@ -60,7 +60,7 @@ func ConvertFeatureSetToFeatures(features mapset.Set) []Feature { return uniqueFeatures } -func ConvertFeatureSerToLayerFeatures(features mapset.Set) []LayerFeature { +func ConvertFeatureSetToLayerFeatures(features mapset.Set) []LayerFeature { uniqueLayerFeatures := make([]LayerFeature, 0, features.Cardinality()) for f := range features.Iter() { feature := f.(Feature) diff --git a/database/pgsql/layer.go b/database/pgsql/layer.go index 4c1497fb..bce1ef06 100644 --- a/database/pgsql/layer.go +++ b/database/pgsql/layer.go @@ -37,12 +37,15 @@ const ( SELECT id FROM layer WHERE hash = $1` findLayerFeatures = ` - SELECT f.name, f.version, f.version_format, t.name, lf.detector_id, ns.name, ns.version_format - FROM layer_feature AS lf, feature AS f, feature_type AS t, namespace AS ns - WHERE lf.feature_id = f.id - AND t.id = f.type - AND lf.namespace_id = ns.id - AND lf.layer_id = $1` + SELECT + f.name, f.version, f.version_format, ft.name, lf.detector_id, ns.name, ns.version_format + FROM + layer_feature AS lf + LEFT JOIN feature f on f.id = lf.feature_id + LEFT JOIN feature_type ft on ft.id = f.type + LEFT JOIN namespace ns ON ns.id = lf.namespace_id + + WHERE lf.layer_id = $1` findLayerNamespaces = ` SELECT ns.name, ns.version_format, ln.detector_id @@ -320,9 +323,12 @@ func (tx *pgSession) findLayerFeatures(layerID int64, detectors detectorMap) ([] detectorID int64 feature database.LayerFeature ) - if err := rows.Scan(&feature.Name, &feature.Version, &feature.VersionFormat, &feature.Type, &detectorID, &feature.PotentialNamespace.Name, &feature.PotentialNamespace.VersionFormat); err != nil { + var namespaceName, namespaceVersion sql.NullString + if err := rows.Scan(&feature.Name, &feature.Version, &feature.VersionFormat, &feature.Type, &detectorID, &namespaceName, &namespaceVersion); err != nil { return nil, handleError("findLayerFeatures", err) } + feature.PotentialNamespace.Name = namespaceName.String + feature.PotentialNamespace.VersionFormat = namespaceVersion.String feature.By = detectors.byID[detectorID] features = append(features, feature) diff --git a/database/pgsql/layer_test.go b/database/pgsql/layer_test.go index 86ada23e..9b2be2bb 100644 --- a/database/pgsql/layer_test.go +++ b/database/pgsql/layer_test.go @@ -116,6 +116,28 @@ var persistLayerTests = []struct { }, }, }, + + { + title: "layer with potential namespace", + name: "layer-potential-namespace", + by: []database.Detector{realDetectors[3]}, + features: []database.LayerFeature{ + {realFeatures[4], realDetectors[3], realNamespaces[4]}, + }, + namespaces: []database.LayerNamespace{ + {realNamespaces[3], realDetectors[3]}, + }, + layer: &database.Layer{ + Hash: "layer-potential-namespace", + By: []database.Detector{realDetectors[3]}, + Features: []database.LayerFeature{ + {realFeatures[4], realDetectors[3], realNamespaces[4]}, + }, + Namespaces: []database.LayerNamespace{ + {realNamespaces[3], realDetectors[3]}, + }, + }, + }, } func TestPersistLayer(t *testing.T) { diff --git a/database/pgsql/migrations/00001_initial_schema.go b/database/pgsql/migrations/00001_initial_schema.go index 180a1a15..0072857c 100644 --- a/database/pgsql/migrations/00001_initial_schema.go +++ b/database/pgsql/migrations/00001_initial_schema.go @@ -89,7 +89,7 @@ var ( layer_id INT REFERENCES layer ON DELETE CASCADE, feature_id INT REFERENCES feature ON DELETE CASCADE, detector_id INT REFERENCES detector ON DELETE CASCADE, - namespace_id INT REFERENCES namespace ON DELETE CASCADE, + namespace_id INT NULL REFERENCES namespace ON DELETE CASCADE, UNIQUE (layer_id, feature_id, namespace_id));`, `CREATE INDEX ON layer_feature(layer_id);`, diff --git a/database/pgsql/testdata/data.sql b/database/pgsql/testdata/data.sql index 4c90ae0d..58d4c8bf 100644 --- a/database/pgsql/testdata/data.sql +++ b/database/pgsql/testdata/data.sql @@ -2,7 +2,8 @@ INSERT INTO namespace (id, name, version_format) VALUES (1, 'debian:7', 'dpkg'), (2, 'debian:8', 'dpkg'), - (3, 'fake:1.0', 'rpm'); + (3, 'fake:1.0', 'rpm'), + (4, 'cpe:/o:redhat:enterprise_linux:7::server', 'rpm'); INSERT INTO feature (id, name, version, version_format, type) VALUES (1, 'ourchat', '0.5', 'dpkg', 1), diff --git a/database/pgsql/testutil.go b/database/pgsql/testutil.go index d6ceb145..b1bfabf7 100644 --- a/database/pgsql/testutil.go +++ b/database/pgsql/testutil.go @@ -49,6 +49,7 @@ var ( 1: {"debian:7", "dpkg"}, 2: {"debian:8", "dpkg"}, 3: {"fake:1.0", "rpm"}, + 4: {"cpe:/o:redhat:enterprise_linux:7::server", "rpm"}, } realNamespacedFeatures = map[int]database.NamespacedFeature{ diff --git a/ext/featurefmt/apk/apk.go b/ext/featurefmt/apk/apk.go index dcc9f5eb..d245de5d 100644 --- a/ext/featurefmt/apk/apk.go +++ b/ext/featurefmt/apk/apk.go @@ -86,7 +86,7 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.LayerFeature, e packages.Add(pkg) } - return database.ConvertFeatureSerToLayerFeatures(packages), nil + return database.ConvertFeatureSetToLayerFeatures(packages), nil } func (l lister) RequiredFilenames() []string { diff --git a/ext/featurefmt/dpkg/dpkg.go b/ext/featurefmt/dpkg/dpkg.go index 2b5fd876..ea88c372 100644 --- a/ext/featurefmt/dpkg/dpkg.go +++ b/ext/featurefmt/dpkg/dpkg.go @@ -69,7 +69,7 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.LayerFeature, e } } - return database.ConvertFeatureSerToLayerFeatures(packages), nil + return database.ConvertFeatureSetToLayerFeatures(packages), nil } // parseDpkgDB consumes the status file scanner exactly one package info, until diff --git a/ext/featurefmt/rpm/rpm.go b/ext/featurefmt/rpm/rpm.go index b85bc81f..f8d91055 100644 --- a/ext/featurefmt/rpm/rpm.go +++ b/ext/featurefmt/rpm/rpm.go @@ -101,7 +101,7 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.LayerFeature, e } } - return database.ConvertFeatureSerToLayerFeatures(packages), nil + return database.ConvertFeatureSetToLayerFeatures(packages), nil } func parseRPMOutput(raw string) (rpmPackage *database.Feature, srpmPackage *database.Feature) {