Skip to content
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
2 changes: 2 additions & 0 deletions .github/workflows/tang-actions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,7 @@ jobs:
DATABASE_NAME: pulp
DATABASE_PASSWORD: password
SERVER_URL: http://localhost:8087
SERVER_CONTENT_URL: http://localhost:8088
SERVER_CONTENT_PATH_PREFIX: /pulp/content/
SERVER_USERNAME: admin
SERVER_PASSWORD: password
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ CONFIG_PATH="$(pwd)/configs/" go test ./internal/test/integration/ -run TestMave
CONFIG_PATH="$(pwd)/configs/" go test ./internal/test/integration/ -run TestNpmSuite -v
```

The Python integration test syncs `shelf-reader` from PyPI into a random domain via the Pulp API, then asserts tangy can read it from the database. The Maven integration test pull-through caches `junit:junit:4.13.2` from a local nginx fixture in the compose stack (avoids Maven Central rate limits in CI), adds the cached content to a repository, then asserts tangy can read it from the database. The npm integration test syncs `is-odd@3.0.1` from registry.npmjs.org (version-specific metadata URL), then asserts tangy can read it from the database. Test data is left in the database after a run; use `make compose-clean` to wipe volumes and start fresh.
The Python integration test syncs `shelf-reader` from PyPI into a random domain via the Pulp API, then asserts tangy can read it from the database. The Maven integration test pull-through caches artifacts, adds the cached content to a repository, then asserts tangy can read it from the database. The npm integration test syncs `is-odd@3.0.1` from registry.npmjs.org (version-specific metadata URL), then asserts tangy can read it from the database. Test data is left in the database after a run; use `make compose-clean` to wipe volumes and start fresh.

### Mocking
Tangy also exports a mock interface you can regenerate using the [mockery](https://github.com/vektra/mockery) tool.
Binary file not shown.

This file was deleted.

Binary file not shown.

This file was deleted.

Binary file not shown.

This file was deleted.

6 changes: 0 additions & 6 deletions compose_files/pulp/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,6 @@ services:
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]

maven_fixture:
image: "docker.io/library/nginx:alpine"
volumes:
- "./assets/maven-fixture:/usr/share/nginx/html:ro"
restart: always

pulp_api:
image: "quay.io/redhat-services-prod/pulp-services-tenant/pulp:latest"
platform: linux/amd64
Expand Down
4 changes: 3 additions & 1 deletion configs/config.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ database:
# Configuration options for the pulp server
server:
url: "http://localhost:8087"
content_url: "http://localhost:8088"
username: "admin"
password: "password"
storage_type: "local"
download_policy: "on_demand"
download_policy: "on_demand"
content_path_prefix: "/api/pulp-content/"
14 changes: 9 additions & 5 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,23 @@ func setDefaults(v *viper.Viper) {
v.SetDefault("database.name", "")

v.SetDefault("server.url", "")
v.SetDefault("server.content_url", "")
v.SetDefault("server.username", "")
v.SetDefault("server.password", "")
v.SetDefault("server.storage_type", "")
v.SetDefault("server.download_policy", "")
v.SetDefault("server.content_path_prefix", "/api/pulp-content/")
}

// Server configuration options for connecting to a pulp server
type Server struct {
Url string `mapstructure:"url"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
StorageType string `mapstructure:"storage_type"`
DownloadPolicy string `mapstructure:"download_policy"`
Url string `mapstructure:"url"`
ContentUrl string `mapstructure:"content_url"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
StorageType string `mapstructure:"storage_type"`
DownloadPolicy string `mapstructure:"download_policy"`
ContentPathPrefix string `mapstructure:"content_path_prefix"`
}

// Database configuration options for connection to a pulp database. Duplicated of tangy.Database.
Expand Down
154 changes: 88 additions & 66 deletions internal/test/integration/maven_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,34 @@ import (
)

const (
testMavenRepoName = "foo-fixture"
testMavenDistributionBasePath = "foo-fixture"
testMavenRemoteURL = "http://maven_fixture/"
testMavenContentOrigin = "http://localhost:8088"
testMavenGroupID = "foo"
testMavenArtifactID = "bar"
testMavenBuildVersion123R1 = "1.2.3.rhlw-00001"
testMavenBuildVersion123R2 = "1.2.3.rhlw-00002"
testMavenBuildVersion201R1 = "2.0.1.rhlw-00001"
testMavenRepoName = "maven-releases-fixture"
testMavenDistributionBasePath = "maven-releases-fixture"
testMavenFixtureUrl = "https://content-services.github.io/fixtures/maven/maven-releases/"
testMavenGroupID = "com.example.fixture"
testMavenArtifactID = "raccoon"
testMavenBaseVersion100 = "1.0.0"
testMavenBaseVersion200 = "2.0.0"
)

var testMavenArtifactPaths = []string{
"foo/bar/1.2.3.rhlw-00001/foo.bar.1.2.3.rhlw-00001.pom",
"foo/bar/1.2.3.rhlw-00001/foo.bar.1.2.3.rhlw-00001.jar",
"foo/bar/1.2.3.rhlw-00002/foo.bar.1.2.3.rhlw-00002.pom",
"foo/bar/1.2.3.rhlw-00002/foo.bar.1.2.3.rhlw-00002.jar",
"foo/bar/2.0.1.rhlw-00001/foo.bar.2.0.1.rhlw-00001.pom",
"foo/bar/2.0.1.rhlw-00001/foo.bar.2.0.1.rhlw-00001.jar",
"com/example/fixture/raccoon/1.0.0.rhlw-00001/com.example.fixture.raccoon.1.0.0.rhlw-00001.pom",
"com/example/fixture/raccoon/1.0.0.rhlw-00001/com.example.fixture.raccoon.1.0.0.rhlw-00001.jar",
"com/example/fixture/raccoon/1.0.0.rhlw-00002/com.example.fixture.raccoon.1.0.0.rhlw-00002.pom",
"com/example/fixture/raccoon/1.0.0.rhlw-00002/com.example.fixture.raccoon.1.0.0.rhlw-00002.jar",
"com/example/fixture/raccoon/2.0.0.rhlw-00001/com.example.fixture.raccoon.2.0.0.rhlw-00001.pom",
"com/example/fixture/raccoon/2.0.0.rhlw-00001/com.example.fixture.raccoon.2.0.0.rhlw-00001.jar",
"com/example/fixture/raccoon/2.0.0.rhlw-00002/com.example.fixture.raccoon.2.0.0.rhlw-00002.pom",
"com/example/fixture/raccoon/2.0.0.rhlw-00002/com.example.fixture.raccoon.2.0.0.rhlw-00002.jar",
}

type MavenSuite struct {
suite.Suite
client *zestwrapper.MavenZest
tangy tangy.Tangy
domainName string
repositoryHref string
client *zestwrapper.MavenZest
tangy tangy.Tangy
domainName string
contentUrl string
contentPathPrefix string
repositoryHref string
}

func (m *MavenSuite) createTestRepository(t *testing.T) {
Expand All @@ -51,13 +53,13 @@ func (m *MavenSuite) createTestRepository(t *testing.T) {
repoHref, remoteHref, err := m.client.CreateRepository(
m.domainName,
testMavenRepoName,
testMavenRemoteURL,
testMavenFixtureUrl,
testMavenDistributionBasePath,
)
require.NoError(t, err)

for _, artifactPath := range testMavenArtifactPaths {
err = m.client.FetchArtifact(testMavenContentOrigin, m.domainName, testMavenDistributionBasePath, artifactPath)
err = m.client.FetchArtifact(m.contentUrl, m.contentPathPrefix, m.domainName, testMavenDistributionBasePath, artifactPath)
require.NoError(t, err)
}

Expand Down Expand Up @@ -88,6 +90,8 @@ func TestMavenSuite(t *testing.T) {
m := MavenSuite{}
m.client = &mavenZest
m.tangy = ta
m.contentUrl = s.ContentUrl
m.contentPathPrefix = s.ContentPathPrefix
m.domainName = RandStringBytes(10)

m.createTestRepository(t)
Expand All @@ -107,23 +111,22 @@ func (m *MavenSuite) TestMavenPackageList() {
pkg := response.Results[0]
assert.Equal(m.T(), testMavenGroupID, pkg.GroupID)
assert.Equal(m.T(), testMavenArtifactID, pkg.ArtifactID)
assert.Contains(m.T(), pkg.Versions, testMavenBuildVersion123R1)
assert.Contains(m.T(), pkg.Versions, testMavenBuildVersion123R2)
assert.Contains(m.T(), pkg.Versions, testMavenBuildVersion201R1)
require.NotEmpty(m.T(), pkg.LatestReleases)
assert.Len(m.T(), pkg.Versions, 2)
assert.Contains(m.T(), pkg.Versions, testMavenBaseVersion100)
assert.Contains(m.T(), pkg.Versions, testMavenBaseVersion200)
require.Len(m.T(), pkg.LatestReleases, 2)

foundVersions := make(map[string]bool)
foundVersions := make(map[string]string)
for _, latest := range pkg.LatestReleases {
foundVersions[latest.Version] = true
foundVersions[latest.Version] = latest.Release
assert.NotEmpty(m.T(), latest.CreatedAt)
}
assert.True(m.T(), foundVersions[testMavenBuildVersion123R1])
assert.True(m.T(), foundVersions[testMavenBuildVersion123R2])
assert.True(m.T(), foundVersions[testMavenBuildVersion201R1])
assert.Equal(m.T(), "rhlw-00002", foundVersions[testMavenBaseVersion100])
assert.Equal(m.T(), "rhlw-00002", foundVersions[testMavenBaseVersion200])
}

func (m *MavenSuite) TestMavenPackageListSearchFilter() {
response, err := m.tangy.MavenPackageList(context.Background(), m.repositoryHref, tangy.MavenPackageListFilters{Search: "foo"}, tangy.PageOptions{
response, err := m.tangy.MavenPackageList(context.Background(), m.repositoryHref, tangy.MavenPackageListFilters{Search: "raccoon"}, tangy.PageOptions{
Offset: 0,
Limit: 10,
})
Expand Down Expand Up @@ -167,63 +170,72 @@ func (m *MavenSuite) TestMavenPackageListEmptyHref() {
assert.Zero(m.T(), response.Total)
}

func (m *MavenSuite) TestMavenBuildList() {
response, err := m.tangy.MavenBuildList(
func (m *MavenSuite) TestMavenVersionsList() {
response, err := m.tangy.MavenVersionsList(
context.Background(),
m.repositoryHref,
testMavenGroupID,
testMavenArtifactID,
testMavenBuildVersion123R1,
testMavenBaseVersion100,
tangy.PageOptions{Offset: 0, Limit: 10},
)
require.NoError(m.T(), err)
require.NotEmpty(m.T(), response.Results)
require.Len(m.T(), response.Results, 1)
assert.Equal(m.T(), 1, response.Total)
assert.Equal(m.T(), 10, response.Limit)

build := response.Results[0]
assert.Equal(m.T(), testMavenGroupID, build.GroupID)
assert.Equal(m.T(), testMavenArtifactID, build.ArtifactID)
assert.Equal(m.T(), testMavenBuildVersion123R1, build.Version)
assert.True(m.T(), strings.HasSuffix(build.Filename, ".pom"), build.Filename)
assert.NotEmpty(m.T(), build.CreatedAt)
version := response.Results[0]
assert.Equal(m.T(), testMavenGroupID, version.GroupID)
assert.Equal(m.T(), testMavenArtifactID, version.ArtifactID)
assert.Equal(m.T(), testMavenBaseVersion100, version.Version)
require.Len(m.T(), version.Builds, 2)

foundReleases := make(map[string]bool)
for _, build := range version.Builds {
assert.Equal(m.T(), testMavenBaseVersion100, build.Version)
assert.True(m.T(), strings.HasSuffix(build.Filename, ".pom"), build.Filename)
assert.NotEmpty(m.T(), build.CreatedAt)
foundReleases[build.Release] = true
}
assert.True(m.T(), foundReleases["rhlw-00001"])
assert.True(m.T(), foundReleases["rhlw-00002"])
}

func (m *MavenSuite) TestMavenBuildListPagination() {
response, err := m.tangy.MavenBuildList(
func (m *MavenSuite) TestMavenVersionsListPagination() {
response, err := m.tangy.MavenVersionsList(
context.Background(),
m.repositoryHref,
testMavenGroupID,
testMavenArtifactID,
testMavenBuildVersion123R1,
"",
tangy.PageOptions{Offset: 0, Limit: 1},
)
require.NoError(m.T(), err)
assert.Len(m.T(), response.Results, 1)
assert.Equal(m.T(), 1, response.Total)
assert.Equal(m.T(), 2, response.Total)

response, err = m.tangy.MavenBuildList(
response, err = m.tangy.MavenVersionsList(
context.Background(),
m.repositoryHref,
testMavenGroupID,
testMavenArtifactID,
testMavenBuildVersion123R1,
tangy.PageOptions{Offset: 1, Limit: 10},
"",
tangy.PageOptions{Offset: 2, Limit: 10},
)
require.NoError(m.T(), err)
assert.Empty(m.T(), response.Results)
assert.Equal(m.T(), 1, response.Total)
assert.Equal(m.T(), 2, response.Total)
}

func (m *MavenSuite) TestMavenBuildListEmptyHref() {
response, err := m.tangy.MavenBuildList(context.Background(), "", testMavenGroupID, testMavenArtifactID, testMavenBuildVersion123R1, tangy.PageOptions{Limit: 10})
func (m *MavenSuite) TestMavenVersionsListEmptyHref() {
response, err := m.tangy.MavenVersionsList(context.Background(), "", testMavenGroupID, testMavenArtifactID, testMavenBaseVersion100, tangy.PageOptions{Limit: 10})
require.NoError(m.T(), err)
assert.Empty(m.T(), response.Results)
assert.Zero(m.T(), response.Total)
}

func (m *MavenSuite) TestMavenBuildListOptionalFilters() {
response, err := m.tangy.MavenBuildList(
func (m *MavenSuite) TestMavenVersionsListOptionalFilters() {
response, err := m.tangy.MavenVersionsList(
context.Background(),
m.repositoryHref,
"",
Expand All @@ -232,14 +244,24 @@ func (m *MavenSuite) TestMavenBuildListOptionalFilters() {
tangy.PageOptions{Offset: 0, Limit: 10},
)
require.NoError(m.T(), err)
require.NotEmpty(m.T(), response.Results)
assert.Equal(m.T(), 3, response.Total)

build := response.Results[0]
assert.Equal(m.T(), testMavenGroupID, build.GroupID)
assert.Equal(m.T(), testMavenArtifactID, build.ArtifactID)
require.Len(m.T(), response.Results, 2)
assert.Equal(m.T(), 2, response.Total)

type versionRelease struct{ version, release string }
foundBuilds := make(map[versionRelease]bool)
for _, result := range response.Results {
assert.Equal(m.T(), testMavenGroupID, result.GroupID)
assert.Equal(m.T(), testMavenArtifactID, result.ArtifactID)
for _, build := range result.Builds {
foundBuilds[versionRelease{build.Version, build.Release}] = true
}
}
assert.True(m.T(), foundBuilds[versionRelease{testMavenBaseVersion100, "rhlw-00001"}])
assert.True(m.T(), foundBuilds[versionRelease{testMavenBaseVersion100, "rhlw-00002"}])
assert.True(m.T(), foundBuilds[versionRelease{testMavenBaseVersion200, "rhlw-00001"}])
assert.True(m.T(), foundBuilds[versionRelease{testMavenBaseVersion200, "rhlw-00002"}])

filtered, err := m.tangy.MavenBuildList(
filtered, err := m.tangy.MavenVersionsList(
context.Background(),
m.repositoryHref,
testMavenGroupID,
Expand All @@ -248,10 +270,10 @@ func (m *MavenSuite) TestMavenBuildListOptionalFilters() {
tangy.PageOptions{Offset: 0, Limit: 10},
)
require.NoError(m.T(), err)
require.Len(m.T(), filtered.Results, 3)
assert.Equal(m.T(), 3, filtered.Total)
require.Len(m.T(), filtered.Results, 2)
assert.Equal(m.T(), 2, filtered.Total)

filtered, err = m.tangy.MavenBuildList(
filtered, err = m.tangy.MavenVersionsList(
context.Background(),
m.repositoryHref,
"",
Expand All @@ -260,15 +282,15 @@ func (m *MavenSuite) TestMavenBuildListOptionalFilters() {
tangy.PageOptions{Offset: 0, Limit: 10},
)
require.NoError(m.T(), err)
require.Len(m.T(), filtered.Results, 3)
assert.Equal(m.T(), 3, filtered.Total)
require.Len(m.T(), filtered.Results, 2)
assert.Equal(m.T(), 2, filtered.Total)
}

func (m *MavenSuite) TestMavenRepositoryMetrics() {
metrics, err := m.tangy.MavenRepositoryMetrics(context.Background(), m.repositoryHref)
require.NoError(m.T(), err)
assert.Equal(m.T(), 1, metrics.PackageCount)
assert.Equal(m.T(), 3, metrics.BuildCount)
assert.Equal(m.T(), 4, metrics.BuildCount)
assert.Equal(m.T(), 2, metrics.VersionCount)
}

Expand Down
5 changes: 3 additions & 2 deletions internal/zestwrapper/maven.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@ func (m *MavenZest) CreateRepository(domain, name, remoteURL, distributionBasePa
}

// FetchArtifact triggers pull-through caching for an artifact path via the content app.
func (m *MavenZest) FetchArtifact(contentOrigin, domain, distributionBasePath, artifactPath string) error {
func (m *MavenZest) FetchArtifact(contentOrigin, contentPathPrefix, domain, distributionBasePath, artifactPath string) error {
artifactPath = strings.TrimPrefix(artifactPath, "/")
url := fmt.Sprintf("%s/pulp/content/%s/%s/%s", strings.TrimRight(contentOrigin, "/"), domain, distributionBasePath, artifactPath)
contentPathPrefix = strings.Trim(contentPathPrefix, "/")
url := fmt.Sprintf("%s/%s/%s/%s/%s", strings.TrimRight(contentOrigin, "/"), contentPathPrefix, domain, distributionBasePath, artifactPath)

resp, err := m.httpClient.Get(url)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/tangy/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ type Tangy interface {
PythonBuildList(ctx context.Context, repositoryHref, nameNormalized, version string, pageOpts PageOptions) (PythonBuildListResponse, error)
PythonRepositoryMetrics(ctx context.Context, repositoryHref string) (PythonRepositoryMetrics, error)
MavenPackageList(ctx context.Context, repositoryHref string, filterOpts MavenPackageListFilters, pageOpts PageOptions) (MavenPackageListResponse, error)
MavenBuildList(ctx context.Context, repositoryHref, groupID, artifactID, version string, pageOpts PageOptions) (MavenBuildListResponse, error)
MavenVersionsList(ctx context.Context, repositoryHref, groupID, artifactID, version string, pageOpts PageOptions) (MavenVersionsResponse, error)
MavenRepositoryMetrics(ctx context.Context, repositoryHref string) (MavenRepositoryMetrics, error)
NpmPackageList(ctx context.Context, repositoryHref string, filterOpts NpmPackageListFilters, pageOpts PageOptions) (NpmPackageListResponse, error)
NpmPackageGet(ctx context.Context, repositoryHref, name, version string) (NpmPackageDetail, error)
Expand Down
Loading
Loading