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=0dedcc3d46a6b1bbc894d850d4c2d3cbd117af6c;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 378a226..ae36d3a 100644 --- a/artifacts/artifacts.go +++ b/artifacts/artifacts.go @@ -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. diff --git a/artifacts/database/database.go b/artifacts/database/database.go index 73915e1..d32256c 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" @@ -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 ( diff --git a/artifacts/database/database_test.go b/artifacts/database/database_test.go index 7c6e812..df8d7f3 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,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), + ) + + }) })