Added test for maven cleanup

pull/33420/head
Diana Str 2025-09-19 16:30:45 +07:00 committed by dianaStr7
parent 7881d764e4
commit bed592c075
6 changed files with 460 additions and 6 deletions

@ -0,0 +1,6 @@
-
id: 1
owner_id: 2
type: maven
name: com.gitea:test-project
lower_name: com.gitea:test-project

@ -0,0 +1,88 @@
-
id: 1
size: 14
hash_md5: 27224a672372115e5a1d125ed7b2a0b1
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c01
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a01
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a801
created_unix: 1672531200
-
id: 2
size: 14
hash_md5: 27224a672372115e5a1d125ed7b2a0b2
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c02
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a02
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a802
created_unix: 1672531200
-
id: 3
size: 14
hash_md5: 27224a672372115e5a1d125ed7b2a0b3
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c03
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a03
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a803
created_unix: 1672531200
-
id: 4
size: 14
hash_md5: 27224a672372115e5a1d125ed7b2a0b4
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c04
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a04
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a804
created_unix: 1672531200
-
id: 5
size: 14
hash_md5: 27224a672372115e5a1d125ed7b2a0b5
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c05
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a05
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a805
created_unix: 1672531200
-
id: 6
size: 14
hash_md5: 27224a672372115e5a1d125ed7b2a0b6
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c06
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a06
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a806
created_unix: 1672531200
-
id: 7
size: 14
hash_md5: 27224a672372115e5a1d125ed7b2a0b7
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c07
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a07
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a807
created_unix: 1672531200
-
id: 8
size: 14
hash_md5: 27224a672372115e5a1d125ed7b2a0b8
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c08
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a808
created_unix: 1672531200
-
id: 9
size: 14
hash_md5: 27224a672372115e5a1d125ed7b2a0b9
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c09
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a09
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a809
created_unix: 1672531200
-
id: 10
size: 14
hash_md5: 27224a672372115e5a1d125ed7b2a0ba
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c10
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a10
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a810
created_unix: 1672531200
-
id: 11
size: 14
hash_md5: 27224a672372115e5a1d125ed7b2a0bb
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c11
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a11
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a811
created_unix: 1672531200

@ -0,0 +1,99 @@
-
id: 1
version_id: 1
blob_id: 1
name: gitea-test-1.0-20230101.000000-1.jar
lower_name: gitea-test-1.0-20230101.000000-1.jar
composite_key: ""
is_lead: false
created_unix: 1672531200
-
id: 2
version_id: 1
blob_id: 2
name: gitea-test-1.0-20230101.000000-2.jar
lower_name: gitea-test-1.0-20230101.000000-2.jar
composite_key: ""
is_lead: false
created_unix: 1672531200
-
id: 3
version_id: 1
blob_id: 3
name: gitea-test-1.0-20230101.000000-3.jar
lower_name: gitea-test-1.0-20230101.000000-3.jar
composite_key: ""
is_lead: false
created_unix: 1672531200
-
id: 4
version_id: 1
blob_id: 4
name: gitea-test-1.0-20230101.000000-4.jar
lower_name: gitea-test-1.0-20230101.000000-4.jar
composite_key: ""
is_lead: false
created_unix: 1672531200
-
id: 5
version_id: 1
blob_id: 5
name: gitea-test-1.0-20230101.000000-5.jar
lower_name: gitea-test-1.0-20230101.000000-5.jar
composite_key: ""
is_lead: false
created_unix: 1672531200
-
id: 6
version_id: 1
blob_id: 6
name: gitea-test-1.0-20230101.000000-3-sources.jar
lower_name: gitea-test-1.0-20230101.000000-3-sources.jar
composite_key: ""
is_lead: false
created_unix: 1672531200
-
id: 7
version_id: 1
blob_id: 7
name: gitea-test-1.0-20230101.000000-3-javadoc.jar
lower_name: gitea-test-1.0-20230101.000000-3-javadoc.jar
composite_key: ""
is_lead: false
created_unix: 1672531200
-
id: 8
version_id: 1
blob_id: 8
name: gitea-test-1.0-20230101.000000-4-sources.jar
lower_name: gitea-test-1.0-20230101.000000-4-sources.jar
composite_key: ""
is_lead: false
created_unix: 1672531200
-
id: 9
version_id: 1
blob_id: 9
name: gitea-test-1.0-20230101.000000-4-javadoc.jar
lower_name: gitea-test-1.0-20230101.000000-4-javadoc.jar
composite_key: ""
is_lead: false
created_unix: 1672531200
-
id: 10
version_id: 1
blob_id: 10
name: gitea-test-1.0-20230101.000000-5-sources.jar
lower_name: gitea-test-1.0-20230101.000000-5-sources.jar
composite_key: ""
is_lead: false
created_unix: 1672531200
-
id: 11
version_id: 1
blob_id: 11
name: gitea-test-1.0-20230101.000000-5-javadoc.jar
lower_name: gitea-test-1.0-20230101.000000-5-javadoc.jar
composite_key: ""
is_lead: false
created_unix: 1672531200

@ -0,0 +1,8 @@
-
id: 1
package_id: 1
creator_id: 2
version: 1.0-SNAPSHOT
lower_version: 1.0-snapshot
metadata_json: '{"artifact_id":"test-project","group_id":"com.gitea"}'
created_unix: 1672531200

@ -1,3 +1,6 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package maven package maven
import ( import (
@ -38,21 +41,21 @@ func CleanupSnapshotVersions(ctx context.Context) error {
continue continue
} }
var artifactId, groupId string var artifactID, groupID string
if version.MetadataJSON != "" { if version.MetadataJSON != "" {
var metadata map[string]interface{} var metadata map[string]any
if err := json.Unmarshal([]byte(version.MetadataJSON), &metadata); err != nil { if err := json.Unmarshal([]byte(version.MetadataJSON), &metadata); err != nil {
log.Warn("Maven Cleanup: error during cleanup: failed to unmarshal metadataJSON for package version ID: %d: %w", version.ID, err) log.Warn("Maven Cleanup: error during cleanup: failed to unmarshal metadataJSON for package version ID: %d: %w", version.ID, err)
} else { } else {
artifactId, _ = metadata["artifact_id"].(string) artifactID, _ = metadata["artifact_id"].(string)
groupId, _ = metadata["group_id"].(string) groupID, _ = metadata["group_id"].(string)
log.Debug("Maven Cleanup: processing package version with ID: %s, Group ID: %s, Artifact ID: %s, Version: %s", version.ID, groupId, artifactId, version.Version) log.Debug("Maven Cleanup: processing package version with ID: %s, Group ID: %s, Artifact ID: %s, Version: %s", version.ID, groupID, artifactID, version.Version)
} }
} }
if err := cleanSnapshotFiles(ctx, version.ID, retainBuilds, debugSession); err != nil { if err := cleanSnapshotFiles(ctx, version.ID, retainBuilds, debugSession); err != nil {
formattedErr := fmt.Errorf("version '%s' (ID: %d, Group ID: %s, Artifact ID: %s): %w", formattedErr := fmt.Errorf("version '%s' (ID: %d, Group ID: %s, Artifact ID: %s): %w",
version.Version, version.ID, groupId, artifactId, err) version.Version, version.ID, groupID, artifactID, err)
if errors.Is(err, packages.ErrMetadataFile) { if errors.Is(err, packages.ErrMetadataFile) {
metadataErrors = append(metadataErrors, formattedErr) metadataErrors = append(metadataErrors, formattedErr)

@ -0,0 +1,250 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package maven
import (
"bytes"
"testing"
"code.gitea.io/gitea/models/packages"
"code.gitea.io/gitea/models/unittest"
packages_module "code.gitea.io/gitea/modules/packages"
"code.gitea.io/gitea/modules/setting"
packages_service "code.gitea.io/gitea/services/packages"
"github.com/stretchr/testify/assert"
)
func TestMain(m *testing.M) {
unittest.MainTest(m)
}
func addMavenMetadataToPackageVersion(t *testing.T, pv *packages.PackageVersion) {
// Create maven-metadata.xml content with build number 5 (matching the fixtures)
// Maven metadata structure explanation:
// - <snapshot>: Contains the latest snapshot timestamp and build number
// - <snapshotVersions>: Lists all available files for each build number
// - <extension>: File extension (jar, pom, etc.)
// - <classifier>: Optional classifier (sources, javadoc, tests, etc.)
// - <value>: The actual version string with timestamp and build number
// - <updated>: Timestamp when the artifact was deployed
metadataXML := `<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>com.gitea</groupId>
<artifactId>test-project</artifactId>
<version>1.0-SNAPSHOT</version>
<versioning>
<snapshot>
<timestamp>20230101.000000</timestamp>
<buildNumber>5</buildNumber>
</snapshot>
<lastUpdated>20230101000000</lastUpdated>
<snapshotVersions>
<snapshotVersion>
<extension>jar</extension>
<value>1.0-20230101.000000-1</value>
<updated>20230101000000</updated>
</snapshotVersion>
<snapshotVersion>
<extension>jar</extension>
<value>1.0-20230101.000000-2</value>
<updated>20230101000000</updated>
</snapshotVersion>
<snapshotVersion>
<extension>jar</extension>
<value>1.0-20230101.000000-3</value>
<updated>20230101000000</updated>
</snapshotVersion>
<snapshotVersion>
<classifier>sources</classifier>
<extension>jar</extension>
<value>1.0-20230101.000000-3</value>
<updated>20230101000000</updated>
</snapshotVersion>
<snapshotVersion>
<classifier>javadoc</classifier>
<extension>jar</extension>
<value>1.0-20230101.000000-3</value>
<updated>20230101000000</updated>
</snapshotVersion>
<snapshotVersion>
<extension>jar</extension>
<value>1.0-20230101.000000-4</value>
<updated>20230101000000</updated>
</snapshotVersion>
<snapshotVersion>
<classifier>sources</classifier>
<extension>jar</extension>
<value>1.0-20230101.000000-4</value>
<updated>20230101000000</updated>
</snapshotVersion>
<snapshotVersion>
<classifier>javadoc</classifier>
<extension>jar</extension>
<value>1.0-20230101.000000-4</value>
<updated>20230101000000</updated>
</snapshotVersion>
<snapshotVersion>
<extension>jar</extension>
<value>1.0-20230101.000000-5</value>
<updated>20230101000000</updated>
</snapshotVersion>
<snapshotVersion>
<classifier>sources</classifier>
<extension>jar</extension>
<value>1.0-20230101.000000-5</value>
<updated>20230101000000</updated>
</snapshotVersion>
<snapshotVersion>
<classifier>javadoc</classifier>
<extension>jar</extension>
<value>1.0-20230101.000000-5</value>
<updated>20230101000000</updated>
</snapshotVersion>
</snapshotVersions>
</versioning>
</metadata>`
// Add metadata file to the existing package version using service method
metadataReader := bytes.NewReader([]byte(metadataXML))
hsr, err := packages_module.CreateHashedBufferFromReader(metadataReader)
assert.NoError(t, err)
pfci := &packages_service.PackageFileCreationInfo{
PackageFileInfo: packages_service.PackageFileInfo{
Filename: "maven-metadata.xml",
},
Data: hsr,
}
_, err = packages_service.AddFileToPackageVersionInternal(t.Context(), pv, pfci)
assert.NoError(t, err)
}
func TestCleanupSnapshotVersions(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
t.Run("Should skip when retainBuilds is negative", func(t *testing.T) {
setting.Packages.RetainMavenSnapshotBuilds = -1
setting.Packages.DebugMavenCleanup = false
t.Logf("Test settings: retainBuilds=%d, debug=%t", setting.Packages.RetainMavenSnapshotBuilds, setting.Packages.DebugMavenCleanup)
err := CleanupSnapshotVersions(t.Context())
assert.NoError(t, err)
})
t.Run("Should skip when retainBuilds is zero", func(t *testing.T) {
setting.Packages.RetainMavenSnapshotBuilds = 0
setting.Packages.DebugMavenCleanup = false
t.Logf("Test settings: retainBuilds=%d, debug=%t", setting.Packages.RetainMavenSnapshotBuilds, setting.Packages.DebugMavenCleanup)
err := CleanupSnapshotVersions(t.Context())
assert.NoError(t, err)
})
t.Run("Should handle missing metadata file gracefully", func(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
setting.Packages.RetainMavenSnapshotBuilds = 2
setting.Packages.DebugMavenCleanup = false
// Get the existing package version from fixtures (ID 1)
pv, err := packages.GetVersionByID(t.Context(), 1)
assert.NoError(t, err)
// Verify all 11 files exist before cleanup (5 base jars + 6 classifier jars)
filesBefore, err := packages.GetFilesByVersionID(t.Context(), pv.ID)
assert.NoError(t, err)
assert.Len(t, filesBefore, 11) // 5 base jars + 6 classifier jars (sources + javadoc for builds 3,4,5)
// No metadata file exists in fixtures - should handle gracefully
err = CleanupSnapshotVersions(t.Context())
assert.NoError(t, err)
// Verify all 11 files still exist after cleanup (no cleanup should occur without metadata)
filesAfter, err := packages.GetFilesByVersionID(t.Context(), pv.ID)
assert.NoError(t, err)
assert.Len(t, filesAfter, 11, "All files should remain when metadata is missing")
})
t.Run("Should work with debug mode", func(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
setting.Packages.RetainMavenSnapshotBuilds = 2
setting.Packages.DebugMavenCleanup = true
pv, err := packages.GetVersionByID(t.Context(), 1)
assert.NoError(t, err)
addMavenMetadataToPackageVersion(t, pv)
filesBefore, err := packages.GetFilesByVersionID(t.Context(), pv.ID)
assert.NoError(t, err)
assert.Len(t, filesBefore, 12) // 11 jar files + 1 metadata file
err = CleanupSnapshotVersions(t.Context())
assert.NoError(t, err)
// Verify all files still exist after cleanup (debug mode should not delete anything)
filesAfter, err := packages.GetFilesByVersionID(t.Context(), pv.ID)
assert.NoError(t, err)
assert.Len(t, filesAfter, 12, "All files should remain in debug mode")
})
t.Run("Should test actual cleanup with metadata", func(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
setting.Packages.DebugMavenCleanup = false
setting.Packages.RetainMavenSnapshotBuilds = 2
t.Logf("Test settings: retainBuilds=%d, debug=%t", setting.Packages.RetainMavenSnapshotBuilds, setting.Packages.DebugMavenCleanup)
// Get the existing package version from fixtures (ID 1)
pv, err := packages.GetVersionByID(t.Context(), 1)
assert.NoError(t, err)
assert.Equal(t, "1.0-SNAPSHOT", pv.Version)
addMavenMetadataToPackageVersion(t, pv)
filesBefore, err := packages.GetFilesByVersionID(t.Context(), pv.ID)
assert.NoError(t, err)
assert.Len(t, filesBefore, 12) // 11 jar files + 1 metadata file
// Test cleanup with retainBuilds = 2 (should keep builds 4 and 5, remove 1, 2, 3)
// Build 4: base jar + sources + javadoc = 3 files
// Build 5: base jar + sources + javadoc = 3 files
// Total retained: 6 files + 1 metadata = 7 files
err = CleanupSnapshotVersions(t.Context())
assert.NoError(t, err)
filesAfter, err := packages.GetFilesByVersionID(t.Context(), pv.ID)
assert.NoError(t, err)
// Should have metadata file + 6 retained build artifacts (2 builds × 3 files each)
assert.Len(t, filesAfter, 7)
// Check that metadata file is still there
var hasMetadata bool
var retainedBuilds []string
for _, file := range filesAfter {
if file.Name == "maven-metadata.xml" {
hasMetadata = true
} else {
retainedBuilds = append(retainedBuilds, file.Name)
}
}
assert.True(t, hasMetadata, "maven-metadata.xml should be retained")
assert.Len(t, retainedBuilds, 6, "Should retain exactly 6 files (2 builds with 3 artifacts each)")
t.Logf("Retained builds: %v", retainedBuilds)
// Verify build 4 artifacts are retained
assert.Contains(t, retainedBuilds, "gitea-test-1.0-20230101.000000-4.jar")
assert.Contains(t, retainedBuilds, "gitea-test-1.0-20230101.000000-4-sources.jar")
assert.Contains(t, retainedBuilds, "gitea-test-1.0-20230101.000000-4-javadoc.jar")
// Verify build 5 artifacts are retained
assert.Contains(t, retainedBuilds, "gitea-test-1.0-20230101.000000-5.jar")
assert.Contains(t, retainedBuilds, "gitea-test-1.0-20230101.000000-5-sources.jar")
assert.Contains(t, retainedBuilds, "gitea-test-1.0-20230101.000000-5-javadoc.jar")
})
}