From: Katarzyna Gorska Date: Wed, 29 Nov 2017 19:11:20 +0000 (+0100) Subject: Implement List with tests X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8ac1ae0c370c40abb40b96391e63f132842eae9e;p=tools%2Fweles.git Implement List with tests 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 --- diff --git a/artifacts/artifacts.go b/artifacts/artifacts.go index cf5c6bb..c5e37f1 100644 --- a/artifacts/artifacts.go +++ b/artifacts/artifacts.go @@ -84,7 +84,7 @@ func NewArtifactManager(db, dir string) (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. diff --git a/artifacts/database/database.go b/artifacts/database/database.go index faf3774..b8ba759 100644 --- a/artifacts/database/database.go +++ b/artifacts/database/database.go @@ -19,6 +19,7 @@ package database import ( "database/sql" + "strings" . "git.tizen.org/tools/weles" @@ -82,6 +83,72 @@ func (aDB *ArtifactDB) SelectPath(path ArtifactPath) (ArtifactInfo, error) { return ar.ArtifactInfo, 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] = res.ArtifactInfo + } + return artifacts, nil + +} + // Select fetches artifacts from ArtifactDB. func (aDB *ArtifactDB) Select(arg interface{}) (artifacts []ArtifactInfo, err error) { var ( diff --git a/artifacts/database/database_test.go b/artifacts/database/database_test.go index 7c6e812..ca9df77 100644 --- a/artifacts/database/database_test.go +++ b/artifacts/database/database_test.go @@ -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,35 @@ 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("list artifacts matching filter", + 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, artifact), + Entry("filter more than one JobIDs", twoJobsFilter, artifact, aImageReady, aYamlFailed), + Entry("filter JobID not in db", noJobFilter), + Entry("filter one Type", oneTypeFilter, aYamlFailed), + Entry("filter more than one Type", twoTypesFilter, aYamlFailed, aTestFailed), + Entry("filter Type not in db", noTypeFilter), + Entry("filter one Status", oneStatusFilter, artifact), + Entry("filter more than one Status", twoStatusFilter, artifact, aTestFailed, aYamlFailed), + Entry("filter Status not in db", noStatusFilter), + Entry("filter one Alias", oneAliasFilter, artifact), + Entry("filter more than one Alias", twoAliasFilter, artifact, aImageReady, aYamlFailed), + Entry("filter Alias not in db", noAliasFilter), + Entry("filter is completly set up", fullFilter, aYamlFailed), + Entry("no artifact in db matches filter", noMatchFilter), + Entry("filter is empty", emptyFilter, artifact, aImageReady, aYamlFailed, aTestFailed), + ) + }) })