Skip to content

Commit

Permalink
Fixes 4932: Add list module Streams endpoint (#14)
Browse files Browse the repository at this point in the history
Fixes 4932: Add list module streams for a snapshots
  • Loading branch information
Andrewgdewar authored Dec 19, 2024
1 parent 169c0b1 commit 6507fd1
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 3 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,7 @@ Containerfile
compose_files/pulp/pulp-oci-images

#config
configs/config.yaml
configs/config.yaml

#mockery binaries
bin
13 changes: 13 additions & 0 deletions .mockery.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
with-expecter: false
inpackage: True
dir: "./pkg/tangy"
mockname: "Mock{{.InterfaceName}}"
outpkg: "{{.PackageName}}"
filename: "{{.InterfaceName}}_mock.go"
all: True
disable-version-string: True
packages:
github.com/content-services/tang:
config:
filename: "tangy_mock.go"
recursive: True
7 changes: 7 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": []
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"git.mergeEditor": false
}
50 changes: 50 additions & 0 deletions internal/test/integration/rpm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const testRepoURL = "https://rverdile.fedorapeople.org/dummy-repos/comps/repo1/"
const testRepoURLTwo = "https://rverdile.fedorapeople.org/dummy-repos/comps/repo2/"
const testRepoNameWithErrata = "multiple-errata"
const testRepoURLWithErrata = "https://stephenw.fedorapeople.org/fakerepos/multiple_errata/"
const rpmNameWithModule = "rpm-with-modules"
const rpmUrlWithModule = "https://fixtures.pulpproject.org/rpm-with-modules-modified/"

func (r *RpmSuite) CreateTestRepository(t *testing.T, repoName string, repoUrl string) {
_, err := r.client.LookupOrCreateDomain(r.domainName)
Expand Down Expand Up @@ -372,6 +374,54 @@ func (r *RpmSuite) TestRpmRepositoryVersionErrataListSort() {
assert.Equal(r.T(), total, 6)
}

func (r *RpmSuite) TestRpmRepositoryVersionModuleStreamsList() {
resp, err := r.client.GetRpmRepositoryByName(r.domainName, testRepoName)
require.NoError(r.T(), err)
firstVersionHref := resp.LatestVersionHref
require.NotNil(r.T(), firstVersionHref)

// expect empty
emptyList, err := r.tangy.RpmRepositoryVersionModuleStreamsList(context.Background(), []string{*firstVersionHref}, tangy.ModuleStreamListFilters{}, "name ASC")
require.NoError(r.T(), err)
assert.Empty(r.T(), emptyList)

r.CreateTestRepository(r.T(), rpmNameWithModule, rpmUrlWithModule)
resp, err = r.client.GetRpmRepositoryByName(r.domainName, rpmNameWithModule)

require.NoError(r.T(), err)
require.NotNil(r.T(), resp.LatestVersionHref)
firstVersionHref = resp.LatestVersionHref

// Expect populated
singleList, err := r.tangy.RpmRepositoryVersionModuleStreamsList(context.Background(), []string{*firstVersionHref}, tangy.ModuleStreamListFilters{}, "anything!")

assert.Equal(r.T(), singleList[0].Name, "duck")
require.NoError(r.T(), err)
assert.NotEmpty(r.T(), singleList)

// Test search
singleList, err = r.tangy.RpmRepositoryVersionModuleStreamsList(context.Background(), []string{*firstVersionHref}, tangy.ModuleStreamListFilters{Search: "Duck"}, "")
require.NoError(r.T(), err)
assert.NotEmpty(r.T(), singleList)

// Test package name list filter
singleList, err = r.tangy.RpmRepositoryVersionModuleStreamsList(context.Background(), []string{*firstVersionHref}, tangy.ModuleStreamListFilters{RpmNames: []string{"walrus", "kangaroo"}}, "anything DesC")
require.NoError(r.T(), err)
assert.Equal(r.T(), singleList[0].Name, "walrus")
assert.NotEmpty(r.T(), singleList)

// Test package name list filter
singleList, err = r.tangy.RpmRepositoryVersionModuleStreamsList(context.Background(), []string{*firstVersionHref}, tangy.ModuleStreamListFilters{RpmNames: []string{"walrus", "kangaroo"}}, "name ASC")
require.NoError(r.T(), err)
assert.Equal(r.T(), singleList[0].Name, "kangaroo")
assert.NotEmpty(r.T(), singleList)

// Confirm no error on not found rpm name
singleList, err = r.tangy.RpmRepositoryVersionModuleStreamsList(context.Background(), []string{*firstVersionHref}, tangy.ModuleStreamListFilters{RpmNames: []string{"banana"}}, "")
require.NoError(r.T(), err)
assert.Empty(r.T(), singleList)
}

func (r *RpmSuite) TestRpmRepositoryVersionPackageListNameFilter() {
resp, err := r.client.GetRpmRepositoryByName(r.domainName, testRepoName)
require.NoError(r.T(), err)
Expand Down
1 change: 1 addition & 0 deletions mk/includes.mk
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ include mk/variables.mk
include mk/compose.mk
include mk/help.mk
include mk/test.mk
include mk/mockery.mk
17 changes: 17 additions & 0 deletions mk/mockery.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
##
# Set of rules to manage podman-compose
#
# Requires 'mk/variables.mk'
##

MOCKERY_VERSION := $(shell curl -L https://api.github.com/repos/vektra/mockery/releases/latest | jq --raw-output .tag_name | sed 's/^v//')

GO_OUTPUT ?= $(PROJECT_DIR)/bin

$(GO_OUTPUT)/mockery: ## Install mockery locally on your GO_OUTPUT (./release) directory
mkdir -p $(GO_OUTPUT) && \
curl -sSfL https://github.com/vektra/mockery/releases/download/v$(MOCKERY_VERSION)/mockery_$(MOCKERY_VERSION)_$(shell uname -s)_$(shell uname -m).tar.gz | tar -xz -C $(GO_OUTPUT) mockery

.PHONY: mock ## Run mockery
mock: $(GO_OUTPUT)/mockery ## Install mockery if it isn't already in ./release directory and regenerate mocks
$(GO_OUTPUT)/mockery
2 changes: 1 addition & 1 deletion pkg/tangy/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ type tangyImpl struct {
logger Logger
}

//go:generate mockery --name Tangy --filename tangy_mock.go --inpackage
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)
RpmRepositoryVersionModuleStreamsList(ctx context.Context, hrefs []string, filterOpts ModuleStreamListFilters, sortBy string) ([]ModuleStreams, error)
RpmRepositoryVersionErrataList(ctx context.Context, hrefs []string, filterOpts ErrataListFilters, pageOpts PageOptions) ([]ErrataListItem, int, error)
Close()
}
Expand Down
75 changes: 75 additions & 0 deletions pkg/tangy/rpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ type RpmListItem struct {
Summary string // The summary of the rpm
}

type ModuleStreams struct {
Name string // Name of the module
Stream string // Module stream version
Version string // The version of the rpm
Context string // Context of the module
Arch string // The Architecture of the rpm
Description string // Module description
Profiles map[string][]string // Module profile data
}

type ErrataListItem struct {
Id string
ErrataId string
Expand All @@ -70,6 +80,11 @@ type RpmListFilters struct {
Name string
}

type ModuleStreamListFilters struct {
RpmNames []string
Search string
}

type ErrataListFilters struct {
Search string
Type []string
Expand Down Expand Up @@ -353,6 +368,66 @@ func (t *tangyImpl) RpmRepositoryVersionErrataList(ctx context.Context, hrefs []
return errata, countTotal, nil
}

// RpmRepositoryVersionModuleStreamsList List Modules streams within a repository version, with pagination, search and an optional name filter
func (t *tangyImpl) RpmRepositoryVersionModuleStreamsList(ctx context.Context, hrefs []string, filterOpts ModuleStreamListFilters, sortBy string) ([]ModuleStreams, error) {
if len(hrefs) == 0 {
return []ModuleStreams{}, nil
}

conn, err := t.pool.Acquire(ctx)
if err != nil {
return nil, err
}
defer conn.Release()

repoVerMap, err := parseRepositoryVersionHrefsMap(hrefs)
if err != nil {
return nil, fmt.Errorf("error parsing repository version hrefs: %w", err)
}

orderBy := "rp.name"

if strings.Contains(strings.ToLower(sortBy), "desc") {
orderBy += " DESC"
} else {
orderBy += " ASC"
}

orderBy += ", rp.stream, rp.version"

args := pgx.NamedArgs{
"nameFilter": "%" + filterOpts.Search + "%",
"rpm_names": filterOpts.RpmNames,
}
query := `Select distinct on (rp.name, rp.stream) rp.name, rp.stream, rp.version, rp.profiles, rp.context, rp.arch, rp.description FROM rpm_modulemd rp
INNER JOIN rpm_modulemd_packages rmp on rmp.modulemd_id = rp.content_ptr_id
INNER JOIN rpm_package pack on pack.content_ptr_id = rmp.package_id `

innerUnion := contentIdsInVersions(repoVerMap, &args)

rpmNameFilter := ""

if len(filterOpts.RpmNames) > 0 {
rpmNameFilter = " AND pack.name = ANY(@rpm_names)"
}

filter := rpmNameFilter + " AND rp.name ILIKE CONCAT( '%', @nameFilter::text, '%') "

rows, err := conn.Query(ctx, query+innerUnion+filter+" ORDER BY "+orderBy+" LIMIT 5000", args)

if err != nil {
return nil, err
}

moduleStreams, err := pgx.CollectRows(rows, pgx.RowToStructByName[ModuleStreams])

if err != nil {
return nil, err
}

return moduleStreams, nil
}

// RpmRepositoryVersionPackageList List RPMs within a repository version, with pagination, and an optional name filter
func (t *tangyImpl) RpmRepositoryVersionPackageList(ctx context.Context, hrefs []string, filterOpts RpmListFilters, pageOpts PageOptions) ([]RpmListItem, int, error) {
if len(hrefs) == 0 {
Expand Down
32 changes: 31 additions & 1 deletion pkg/tangy/tangy_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6507fd1

Please sign in to comment.