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 list module Streams endpoint #14

Merged
merged 1 commit into from
Dec 19, 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
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
Andrewgdewar marked this conversation as resolved.
Show resolved Hide resolved
disable-version-string: True
packages:
github.com/content-services/tang:
config:
Andrewgdewar marked this conversation as resolved.
Show resolved Hide resolved
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() {
Andrewgdewar 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)

// 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.

Loading