2016-12-28 01:45:11 +00:00
// Copyright 2016 clair authors
2016-01-19 20:16:45 +00:00
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2015-12-28 20:03:29 +00:00
package pgsql
import (
"testing"
2016-05-02 22:33:03 +00:00
"github.com/stretchr/testify/assert"
2019-02-19 21:42:00 +00:00
"github.com/stretchr/testify/require"
2016-05-02 22:33:03 +00:00
2015-12-28 20:03:29 +00:00
"github.com/coreos/clair/database"
)
2017-07-26 23:23:54 +00:00
func TestPersistFeatures ( t * testing . T ) {
2019-02-19 21:42:00 +00:00
tx , cleanup := createTestPgSession ( t , "TestPersistFeatures" )
defer cleanup ( )
2017-07-26 23:23:54 +00:00
2019-02-19 21:42:00 +00:00
invalid := database . Feature { }
2019-02-28 09:59:49 +00:00
valid := * database . NewBinaryPackage ( "mount" , "2.31.1-0.4ubuntu3.1" , "dpkg" , database . Namespace { } )
2017-07-26 23:23:54 +00:00
// invalid
2019-02-19 21:42:00 +00:00
require . NotNil ( t , tx . PersistFeatures ( [ ] database . Feature { invalid } ) )
2017-07-26 23:23:54 +00:00
// existing
2019-02-19 21:42:00 +00:00
require . Nil ( t , tx . PersistFeatures ( [ ] database . Feature { valid } ) )
require . Nil ( t , tx . PersistFeatures ( [ ] database . Feature { valid } ) )
2017-07-26 23:23:54 +00:00
2019-02-19 21:42:00 +00:00
features := selectAllFeatures ( t , tx )
assert . Equal ( t , [ ] database . Feature { valid } , features )
2017-07-26 23:23:54 +00:00
}
func TestPersistNamespacedFeatures ( t * testing . T ) {
2019-02-19 21:42:00 +00:00
tx , cleanup := createTestPgSessionWithFixtures ( t , "TestPersistNamespacedFeatures" )
defer cleanup ( )
2017-07-26 23:23:54 +00:00
// existing features
2019-02-28 09:59:49 +00:00
f1 := database . NewSourcePackage ( "ourchat" , "0.5" , "dpkg" , database . Namespace { } )
2017-07-26 23:23:54 +00:00
// non-existing features
2019-02-28 09:59:49 +00:00
f2 := database . NewSourcePackage ( "fake!" , "" , "" , database . Namespace { } )
2017-07-26 23:23:54 +00:00
// exising namespace
2019-02-19 21:42:00 +00:00
n1 := database . NewNamespace ( "debian:7" , "dpkg" )
2017-07-26 23:23:54 +00:00
// non-existing namespace
2019-02-19 21:42:00 +00:00
n2 := database . NewNamespace ( "debian:non" , "dpkg" )
2017-07-26 23:23:54 +00:00
// existing namespaced feature
2019-02-19 21:42:00 +00:00
nf1 := database . NewNamespacedFeature ( n1 , f1 )
2017-07-26 23:23:54 +00:00
// invalid namespaced feature
2019-02-19 21:42:00 +00:00
nf2 := database . NewNamespacedFeature ( n2 , f2 )
2017-07-26 23:23:54 +00:00
// namespaced features with namespaces or features not in the database will
// generate error.
assert . Nil ( t , tx . PersistNamespacedFeatures ( [ ] database . NamespacedFeature { } ) )
2019-02-19 21:42:00 +00:00
assert . NotNil ( t , tx . PersistNamespacedFeatures ( [ ] database . NamespacedFeature { * nf1 , * nf2 } ) )
2017-07-26 23:23:54 +00:00
// valid case: insert nf3
2019-02-19 21:42:00 +00:00
assert . Nil ( t , tx . PersistNamespacedFeatures ( [ ] database . NamespacedFeature { * nf1 } ) )
2017-07-26 23:23:54 +00:00
all := listNamespacedFeatures ( t , tx )
2019-02-19 21:42:00 +00:00
assert . Contains ( t , all , * nf1 )
2017-07-26 23:23:54 +00:00
}
func TestFindAffectedNamespacedFeatures ( t * testing . T ) {
datastore , tx := openSessionForTest ( t , "FindAffectedNamespacedFeatures" , true )
defer closeTest ( t , datastore , tx )
ns := database . NamespacedFeature {
2015-12-28 20:03:29 +00:00
Feature : database . Feature {
2017-07-26 23:23:54 +00:00
Name : "openssl" ,
Version : "1.0" ,
VersionFormat : "dpkg" ,
2019-02-19 21:42:00 +00:00
Type : database . SourcePackage ,
2017-07-26 23:23:54 +00:00
} ,
Namespace : database . Namespace {
Name : "debian:7" ,
VersionFormat : "dpkg" ,
2015-12-28 20:03:29 +00:00
} ,
}
2017-07-26 23:23:54 +00:00
ans , err := tx . FindAffectedNamespacedFeatures ( [ ] database . NamespacedFeature { ns } )
if assert . Nil ( t , err ) &&
assert . Len ( t , ans , 1 ) &&
assert . True ( t , ans [ 0 ] . Valid ) &&
assert . Len ( t , ans [ 0 ] . AffectedBy , 1 ) {
assert . Equal ( t , "CVE-OPENSSL-1-DEB7" , ans [ 0 ] . AffectedBy [ 0 ] . Name )
}
}
func listNamespacedFeatures ( t * testing . T , tx * pgSession ) [ ] database . NamespacedFeature {
2019-02-19 21:42:00 +00:00
types , err := tx . getFeatureTypeMap ( )
if err != nil {
panic ( err )
}
rows , err := tx . Query ( ` SELECT f . name , f . version , f . version_format , f . type , n . name , n . version_format
2017-07-26 23:23:54 +00:00
FROM feature AS f , namespace AS n , namespaced_feature AS nf
WHERE nf . feature_id = f . id AND nf . namespace_id = n . id ` )
if err != nil {
2019-02-19 21:42:00 +00:00
panic ( err )
2017-07-26 23:23:54 +00:00
}
nf := [ ] database . NamespacedFeature { }
for rows . Next ( ) {
f := database . NamespacedFeature { }
2019-02-19 21:42:00 +00:00
var typeID int
err := rows . Scan ( & f . Name , & f . Version , & f . VersionFormat , & typeID , & f . Namespace . Name , & f . Namespace . VersionFormat )
2017-07-26 23:23:54 +00:00
if err != nil {
2019-02-19 21:42:00 +00:00
panic ( err )
2017-07-26 23:23:54 +00:00
}
2019-02-19 21:42:00 +00:00
f . Type = types . byID [ typeID ]
2017-07-26 23:23:54 +00:00
nf = append ( nf , f )
}
return nf
}
2019-02-19 21:42:00 +00:00
func selectAllFeatures ( t * testing . T , tx * pgSession ) [ ] database . Feature {
types , err := tx . getFeatureTypeMap ( )
if err != nil {
panic ( err )
}
rows , err := tx . Query ( "SELECT name, version, version_format, type FROM feature" )
2017-07-26 23:23:54 +00:00
if err != nil {
t . FailNow ( )
}
fs := [ ] database . Feature { }
for rows . Next ( ) {
f := database . Feature { }
2019-02-19 21:42:00 +00:00
var typeID int
err := rows . Scan ( & f . Name , & f . Version , & f . VersionFormat , & typeID )
f . Type = types . byID [ typeID ]
2017-07-26 23:23:54 +00:00
if err != nil {
t . FailNow ( )
}
fs = append ( fs , f )
}
return fs
}
func assertNamespacedFeatureEqual ( t * testing . T , expected [ ] database . NamespacedFeature , actual [ ] database . NamespacedFeature ) bool {
if assert . Len ( t , actual , len ( expected ) ) {
has := map [ database . NamespacedFeature ] bool { }
for _ , nf := range expected {
has [ nf ] = false
}
for _ , nf := range actual {
has [ nf ] = true
}
for nf , visited := range has {
if ! assert . True ( t , visited , nf . Namespace . Name + ":" + nf . Name + " is expected" ) {
return false
}
}
return true
}
return false
2015-12-28 20:03:29 +00:00
}
2019-02-19 21:42:00 +00:00
func TestFindNamespacedFeatureIDs ( t * testing . T ) {
tx , cleanup := createTestPgSessionWithFixtures ( t , "TestFindNamespacedFeatureIDs" )
defer cleanup ( )
features := [ ] database . NamespacedFeature { }
expectedIDs := [ ] int { }
for id , feature := range realNamespacedFeatures {
features = append ( features , feature )
expectedIDs = append ( expectedIDs , id )
}
features = append ( features , realNamespacedFeatures [ 1 ] ) // test duplicated
expectedIDs = append ( expectedIDs , 1 )
namespace := realNamespaces [ 1 ]
2019-02-28 10:02:39 +00:00
features = append ( features , * database . NewNamespacedFeature ( & namespace , database . NewBinaryPackage ( "not-found" , "1.0" , "dpkg" , database . Namespace { } ) ) ) // test not found feature
2019-02-19 21:42:00 +00:00
ids , err := tx . findNamespacedFeatureIDs ( features )
require . Nil ( t , err )
require . Len ( t , ids , len ( expectedIDs ) + 1 )
for i , id := range ids {
if i == len ( ids ) - 1 {
require . False ( t , id . Valid )
} else {
require . True ( t , id . Valid )
require . Equal ( t , expectedIDs [ i ] , int ( id . Int64 ) )
}
}
}