Implement List with tests 89/161089/12
authorKatarzyna Gorska <k.gorska@samsung.com>
Wed, 29 Nov 2017 19:11:20 +0000 (20:11 +0100)
committerKatarzyna Gorska <k.gorska@samsung.com>
Fri, 15 Dec 2017 11:16:00 +0000 (12:16 +0100)
List is part of implementation of ArtifactManager.

It filters ArtifactDB with given filter
and returns list of all matching elements.

Change-Id: I746ea564e07d512ddf55e36d92f515e5f804b120
Signed-off-by: Katarzyna Gorska <k.gorska@samsung.com>
artifacts/artifacts.go
artifacts/database/database.go
artifacts/database/database_test.go

index 378a226..ae36d3a 100644 (file)
@@ -69,7 +69,7 @@ func NewArtifactManager() (ArtifactManager, error) {
 
 // ListArtifact is part of implementation of ArtifactManager interface.
 func (s *Storage) ListArtifact(filter ArtifactFilter) ([]ArtifactInfo, error) {
-       return nil, ErrNotImplemented
+       return s.db.Filter(filter)
 }
 
 // PushArtifact is part of implementation of ArtifactManager interface.
index 73915e1..d32256c 100644 (file)
@@ -19,6 +19,7 @@ package database
 
 import (
        "database/sql"
+       "strings"
 
        . "git.tizen.org/tools/weles"
 
@@ -80,6 +81,72 @@ func (aDB *ArtifactDB) SelectPath(path ArtifactPath) (ArtifactInfo, error) {
        return artifactRecordToInfo(ar), nil
 }
 
+// prepareQuery prepares query based on given filter.
+// TODO code duplication
+func prepareQuery(filter ArtifactFilter) (string, []interface{}) {
+       var (
+               conditions []string
+               query      = "select * from artifacts "
+               args       []interface{}
+       )
+       if len(filter.JobID) > 0 {
+               q := make([]string, len(filter.JobID))
+               for i, job := range filter.JobID {
+                       q[i] = "?"
+                       args = append(args, job)
+               }
+               conditions = append(conditions, " JobID in ("+strings.Join(q, ",")+")")
+       }
+       if len(filter.Type) > 0 {
+               q := make([]string, len(filter.Type))
+               for i, typ := range filter.Type {
+                       q[i] = "?"
+                       args = append(args, typ)
+               }
+               conditions = append(conditions, " Type in ("+strings.Join(q, ",")+")")
+       }
+       if len(filter.Status) > 0 {
+               q := make([]string, len(filter.Status))
+               for i, status := range filter.Status {
+                       q[i] = "?"
+                       args = append(args, status)
+               }
+               conditions = append(conditions, " Status in ("+strings.Join(q, ",")+")")
+       }
+       if len(filter.Alias) > 0 {
+               q := make([]string, len(filter.Alias))
+               for i, alias := range filter.Alias {
+                       q[i] = "?"
+                       args = append(args, alias)
+               }
+               conditions = append(conditions, " Alias in ("+strings.Join(q, ",")+")")
+       }
+       if len(conditions) > 0 {
+               query += " where " + strings.Join(conditions, " AND ")
+       }
+       return query, args
+}
+
+// Filter fetches elements matching ArtifactFilter from database.
+func (aDB *ArtifactDB) Filter(filter ArtifactFilter) ([]ArtifactInfo, error) {
+       results := []artifactInfoRecord{}
+
+       query, args := prepareQuery(filter)
+
+       // TODO gorp doesn't support passing list of arguments to where in(...) clause yet.
+       // Thats why it's done with the use prepareQuery.
+       _, err := aDB.dbmap.Select(&results, query, args...)
+       if err != nil {
+               return nil, err
+       }
+       artifacts := make([]ArtifactInfo, len(results))
+       for i, res := range results {
+               artifacts[i] = artifactRecordToInfo(res)
+       }
+       return artifacts, nil
+
+}
+
 // Select fetches artifacts from ArtifactDB.
 func (aDB *ArtifactDB) Select(arg interface{}) (artifacts []ArtifactInfo, err error) {
        var (
index 7c6e812..df8d7f3 100644 (file)
@@ -32,9 +32,12 @@ import (
 
 var _ = Describe("ArtifactDB", func() {
        var (
-               job           weles.JobID        = 58008
-               invalidJob    weles.JobID        = 1
-               invalidPath   weles.ArtifactPath = "invalidPath"
+               job           weles.JobID          = 58008
+               invalidJob    weles.JobID          = 1
+               invalidPath   weles.ArtifactPath   = "invalidPath"
+               invalidStatus weles.ArtifactStatus = "invalidStatus"
+               invalidType   weles.ArtifactType   = "invalidType"
+               invalidAlias  weles.ArtifactAlias  = "invalidAlias"
                goldenUnicorn ArtifactDB
                tmpDir        string
 
@@ -87,6 +90,26 @@ var _ = Describe("ArtifactDB", func() {
                }
 
                testArtifacts = []weles.ArtifactInfo{artifact, aImageReady, aYamlFailed, aTestFailed}
+
+               oneJobFilter  = weles.ArtifactFilter{[]weles.JobID{artifact.JobID}, nil, nil, nil}
+               twoJobsFilter = weles.ArtifactFilter{[]weles.JobID{artifact.JobID, aImageReady.JobID}, nil, nil, nil}
+               noJobFilter   = weles.ArtifactFilter{[]weles.JobID{invalidJob}, nil, nil, nil}
+
+               oneTypeFilter  = weles.ArtifactFilter{nil, []weles.ArtifactType{aYamlFailed.Type}, nil, nil}
+               twoTypesFilter = weles.ArtifactFilter{nil, []weles.ArtifactType{aYamlFailed.Type, aTestFailed.Type}, nil, nil}
+               noTypeFilter   = weles.ArtifactFilter{nil, []weles.ArtifactType{invalidType}, nil, nil}
+
+               oneStatusFilter = weles.ArtifactFilter{nil, nil, []weles.ArtifactStatus{artifact.Status}, nil}
+               twoStatusFilter = weles.ArtifactFilter{nil, nil, []weles.ArtifactStatus{artifact.Status, aYamlFailed.Status}, nil}
+               noStatusFilter  = weles.ArtifactFilter{nil, nil, []weles.ArtifactStatus{invalidStatus}, nil}
+
+               oneAliasFilter = weles.ArtifactFilter{nil, nil, nil, []weles.ArtifactAlias{artifact.Alias}}
+               twoAliasFilter = weles.ArtifactFilter{nil, nil, nil, []weles.ArtifactAlias{artifact.Alias, aImageReady.Alias}}
+               noAliasFilter  = weles.ArtifactFilter{nil, nil, nil, []weles.ArtifactAlias{invalidAlias}}
+
+               fullFilter    = weles.ArtifactFilter{twoJobsFilter.JobID, twoTypesFilter.Type, twoStatusFilter.Status, twoAliasFilter.Alias}
+               noMatchFilter = weles.ArtifactFilter{oneJobFilter.JobID, oneTypeFilter.Type, nil, nil}
+               emptyFilter   = weles.ArtifactFilter{}
        )
 
        jobsInDB := func(job weles.JobID) int64 {
@@ -200,4 +223,36 @@ var _ = Describe("ArtifactDB", func() {
                        Entry("select multiple entries for Status", weles.AM_FAILED, nil, aYamlFailed, aTestFailed),
                )
        })
+
+       Describe("list", func() {
+               BeforeEach(func() {
+                       for _, a := range testArtifacts {
+                               err := goldenUnicorn.InsertArtifactInfo(&a)
+                               Expect(err).ToNot(HaveOccurred())
+                       }
+               })
+               DescribeTable("ArtifactDB.List()",
+                       func(filter weles.ArtifactFilter, expected []weles.ArtifactInfo) {
+                               results, err := goldenUnicorn.Filter(filter)
+                               Expect(err).ToNot(HaveOccurred())
+                               Expect(results).To(ConsistOf(expected))
+                       },
+                       Entry("filter one JobID", oneJobFilter, []weles.ArtifactInfo{artifact}),
+                       Entry("filter more than one JobIDs", twoJobsFilter, []weles.ArtifactInfo{artifact, aImageReady, aYamlFailed}),
+                       Entry("filter JobID not in db", noJobFilter, nil),
+                       Entry("filter one Type", oneTypeFilter, []weles.ArtifactInfo{aYamlFailed}),
+                       Entry("filter more than one Type", twoTypesFilter, []weles.ArtifactInfo{aYamlFailed, aTestFailed}),
+                       Entry("filter Type not in db", noTypeFilter, nil),
+                       Entry("filter one Status", oneStatusFilter, []weles.ArtifactInfo{artifact}),
+                       Entry("filter more than one Status", twoStatusFilter, []weles.ArtifactInfo{artifact, aTestFailed, aYamlFailed}),
+                       Entry("filter Status not in db", noStatusFilter, nil),
+                       Entry("filter one Alias", oneAliasFilter, []weles.ArtifactInfo{artifact}),
+                       Entry("filter more than one Alias", twoAliasFilter, []weles.ArtifactInfo{artifact, aImageReady, aYamlFailed}),
+                       Entry("filter Alias not in db", noAliasFilter, nil),
+                       Entry("filter is completly set up", fullFilter, []weles.ArtifactInfo{aYamlFailed}),
+                       Entry("no artifact in db matches filter", noMatchFilter, nil),
+                       Entry("filter is empty", emptyFilter, testArtifacts),
+               )
+
+       })
 })