Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rpm list api #5

Merged
merged 7 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,32 @@ if err != nil {
}
defer t.Close()

// Use Tangy to list RPMs with pagination for one or more repository versions, with name filtering
versionHref := "/api/pulp/e1c6bee3/api/v3/repositories/rpm/rpm/018c1c95-4281-76eb-b277-842cbad524f4/versions/1/"
rows, err := t.r.tangy.RpmRepositoryVersionPackageList(context.Background(), []string{versionHref}, tangy.RpmListFilters{Name: "kernel"}, tangy.PageOptions{Offset: 100, Limit: 20})
if err != nil {
return err
}

// Use Tangy to search for RPMs, by name, that are associated to a specific repository version, returning up to the first 100 results
versionHref := "/api/pulp/e1c6bee3/api/v3/repositories/rpm/rpm/018c1c95-4281-76eb-b277-842cbad524f4/versions/1/"
rows, err := t.RpmRepositoryVersionPackageSearch(context.Background(), []string{versionHref}, "bear", 100)
if err != nil {
return err
return err
}

// Use Tangy to search for RPM Package Groups, by name, that are associated to a specific repository version, returning up to the first 100 results
versionHref := "/api/pulp/e1c6bee3/api/v3/repositories/rpm/rpm/018c1c95-4281-76eb-b277-842cbad524f4/versions/1/"
rows, err := t.RpmRepositoryVersionPackageGroupSearch(context.Background(), []string{versionHref}, "mammals", 100)
if err != nil {
return err
return err
}

// Use Tangy to search for RPM Environments, by name, that are associated to a specific repository version, returning up to the first 100 results
versionHref := "/api/pulp/e1c6bee3/api/v3/repositories/rpm/rpm/018c1c95-4281-76eb-b277-842cbad524f4/versions/1/"
rows, err := t.RpmRepositoryVersionPackageGroupSearch(context.Background(), []string{versionHref}, "animals", 100)
if err != nil {
return err
return err
}
```
See example.go for a complete example.
Expand Down
84 changes: 77 additions & 7 deletions internal/test/integration/rpm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,11 @@ const testRepoName = "zoo"
const testRepoURL = "https://rverdile.fedorapeople.org/dummy-repos/comps/repo1/"
const testRepoURLTwo = "https://rverdile.fedorapeople.org/dummy-repos/comps/repo2/"

func (r *RpmSuite) CreateTestRepository(t *testing.T) {
domainName := RandStringBytes(10)
r.domainName = domainName

_, err := r.client.LookupOrCreateDomain(domainName)
func (r *RpmSuite) CreateTestRepository(t *testing.T, repoName string) {
_, err := r.client.LookupOrCreateDomain(r.domainName)
require.NoError(t, err)

repoHref, remoteHref, err := r.client.CreateRepository(domainName, testRepoName, testRepoURL)
repoHref, remoteHref, err := r.client.CreateRepository(r.domainName, repoName, testRepoURL)
require.NoError(t, err)

r.repoHref = repoHref
Expand Down Expand Up @@ -78,7 +75,10 @@ func TestRpmSuite(t *testing.T) {
r := RpmSuite{}
r.client = &rpmZest
r.tangy = ta
r.CreateTestRepository(t)

r.domainName = RandStringBytes(10)

r.CreateTestRepository(t, testRepoName)

// Get first version href
resp, err := r.client.GetRpmRepositoryByName(r.domainName, testRepoName)
Expand Down Expand Up @@ -244,6 +244,76 @@ func (r *RpmSuite) TestRpmRepositoryVersionEnvironmentSearch() {
assert.Len(r.T(), search, 0)
}

func (r *RpmSuite) TestRpmRepositoryVersionPackageListNameFilter() {
rverdile marked this conversation as resolved.
Show resolved Hide resolved
resp, err := r.client.GetRpmRepositoryByName(r.domainName, testRepoName)
require.NoError(r.T(), err)
firstVersionHref := resp.LatestVersionHref
require.NotNil(r.T(), firstVersionHref)

// no filter
singleList, total, err := r.tangy.RpmRepositoryVersionPackageList(context.Background(), []string{*firstVersionHref}, tangy.RpmListFilters{Name: ""}, tangy.PageOptions{})
require.NoError(r.T(), err)
assert.NotEmpty(r.T(), singleList)
assert.Equal(r.T(), total, 4)

// exact match
singleList, total, err = r.tangy.RpmRepositoryVersionPackageList(context.Background(), []string{*firstVersionHref}, tangy.RpmListFilters{Name: "bear"}, tangy.PageOptions{})
require.NoError(r.T(), err)
assert.NotEmpty(r.T(), singleList)
assert.Equal(r.T(), total, 1)

// partial match
singleList, total, err = r.tangy.RpmRepositoryVersionPackageList(context.Background(), []string{*firstVersionHref}, tangy.RpmListFilters{Name: "bea"}, tangy.PageOptions{})
require.NoError(r.T(), err)
assert.NotEmpty(r.T(), singleList)
assert.Equal(r.T(), total, 1)

// no match
singleList, total, err = r.tangy.RpmRepositoryVersionPackageList(context.Background(), []string{*firstVersionHref}, tangy.RpmListFilters{Name: "wal"}, tangy.PageOptions{})
require.NoError(r.T(), err)
assert.Empty(r.T(), singleList)
assert.Equal(r.T(), total, 0)
}

// RpmRepositoryVersionPackageList
func (r *RpmSuite) TestRpmRepositoryVersionPackageListNoDuplicates() {
firstVersionHref := r.firstVersionHref
secondVersionHref := r.secondVersionHref

doubleList, total, err := r.tangy.RpmRepositoryVersionPackageList(context.Background(), []string{firstVersionHref, secondVersionHref}, tangy.RpmListFilters{}, tangy.PageOptions{})
require.NoError(r.T(), err)
assert.NotEmpty(r.T(), doubleList)
assert.Equal(r.T(), total, 5)

singleList, total, err := r.tangy.RpmRepositoryVersionPackageList(context.Background(), []string{firstVersionHref}, tangy.RpmListFilters{}, tangy.PageOptions{})
require.NoError(r.T(), err)
assert.NotEmpty(r.T(), singleList)
assert.Equal(r.T(), total, 3)
}

func (r *RpmSuite) TestRpmRepositoryVersionPackageListOffsetLimit() {
firstVersionHref := r.firstVersionHref
secondVersionHref := r.secondVersionHref

list, total, err := r.tangy.RpmRepositoryVersionPackageList(context.Background(), []string{firstVersionHref, secondVersionHref}, tangy.RpmListFilters{}, tangy.PageOptions{Offset: 1, Limit: 4})
require.NoError(r.T(), err)
assert.NotEmpty(r.T(), list)
assert.Equal(r.T(), 4, len(list))
assert.Equal(r.T(), 5, total)

list, total, err = r.tangy.RpmRepositoryVersionPackageList(context.Background(), []string{firstVersionHref, secondVersionHref}, tangy.RpmListFilters{}, tangy.PageOptions{Offset: 4, Limit: 1})
require.NoError(r.T(), err)
assert.NotEmpty(r.T(), list)
assert.Equal(r.T(), 1, len(list))
assert.Equal(r.T(), 5, total)

list, total, err = r.tangy.RpmRepositoryVersionPackageList(context.Background(), []string{firstVersionHref, secondVersionHref}, tangy.RpmListFilters{}, tangy.PageOptions{Offset: 100, Limit: 100})
require.NoError(r.T(), err)
assert.Empty(r.T(), list)
assert.Equal(r.T(), 0, len(list))
assert.Equal(r.T(), 5, total)
}

func RandStringBytes(n int) string {
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
b := make([]byte, n)
Expand Down
1 change: 1 addition & 0 deletions pkg/tangy/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type Tangy interface {
RpmRepositoryVersionPackageSearch(ctx context.Context, hrefs []string, search string, limit int) ([]RpmPackageSearch, error)
RpmRepositoryVersionPackageGroupSearch(ctx context.Context, hrefs []string, search string, limit int) ([]RpmPackageGroupSearch, error)
RpmRepositoryVersionEnvironmentSearch(ctx context.Context, hrefs []string, search string, limit int) ([]RpmEnvironmentSearch, error)
RpmRepositoryVersionPackageList(ctx context.Context, hrefs []string, filterOpts RpmListFilters, pageOpts PageOptions) ([]RpmListItem, int, error)
Close()
}

Expand Down
42 changes: 42 additions & 0 deletions pkg/tangy/queries.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package tangy

import (
"fmt"
"strings"

"github.com/jackc/pgx/v5"
"golang.org/x/exp/rand"
)

// contentIdsInVersion forms a single query to fetch a list of content ids in a repository version
//
// It uses randomized query parameter names and modifies the passed in namedArgs to include the key/values for these named query parameters.
// By using randomized query parameter names, this query can be included multiple times with different repository
// versions as multiple subqueries.
func contentIdsInVersion(repoId string, versionNum int, namedArgs *pgx.NamedArgs) string {
ran := rand.Int()
repoIdName := fmt.Sprintf("%v%v", "repoName", ran)
versionNumName := fmt.Sprintf("%v%v", "versionNum", ran)
rverdile marked this conversation as resolved.
Show resolved Hide resolved
query := `
SELECT crc.content_id
FROM core_repositorycontent crc
INNER JOIN core_repositoryversion crv ON (crc.version_added_id = crv.pulp_id)
LEFT OUTER JOIN core_repositoryversion crv2 ON (crc.version_removed_id = crv2.pulp_id)
WHERE crv.repository_id = @%v AND crv.number <= @%v AND NOT (crv2.number <= @%v AND crv2.number IS NOT NULL)
`
(*namedArgs)[repoIdName] = repoId
(*namedArgs)[versionNumName] = versionNum
return fmt.Sprintf(query, repoIdName, versionNumName, versionNumName)
}

// Creates a sub query (including parenthesis) to lookup the content IDs of a list of repository versions.
//
// Takes in a pointer to Named args in order to add required named arguments for the query. Multiple queries are created
// and UNION'd together
func contentIdsInVersions(repoVerMap []ParsedRepoVersion, namedArgs *pgx.NamedArgs) string {
queries := []string{}
for _, parsed := range repoVerMap {
queries = append(queries, contentIdsInVersion(parsed.RepositoryUUID, parsed.Version, namedArgs))
}
return fmt.Sprintf("( %v ) ", strings.Join(queries, " UNION "))
}
Loading
Loading