mirror of
https://github.com/harness-community/drone-nexus-publish.git
synced 2026-06-04 18:23:55 +08:00
Merge pull request #4 from harness-community/CI-19286
fix: [CI-19286]: Fix critical bugs: trailing slash URLs, absolute paths, and response body logging
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
image: plugins/nexus-publish:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}
|
image: plugins/nexus-publisher:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}
|
||||||
{{#if build.tags}}
|
{{#if build.tags}}
|
||||||
tags:
|
tags:
|
||||||
{{#each build.tags}}
|
{{#each build.tags}}
|
||||||
@@ -7,19 +7,19 @@ tags:
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
manifests:
|
manifests:
|
||||||
-
|
-
|
||||||
image: plugins/nexus-publish:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64
|
image: plugins/nexus-publisher:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64
|
||||||
platform:
|
platform:
|
||||||
architecture: amd64
|
architecture: amd64
|
||||||
os: linux
|
os: linux
|
||||||
-
|
-
|
||||||
image: plugins/nexus-publish:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm64
|
image: plugins/nexus-publisher:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm64
|
||||||
platform:
|
platform:
|
||||||
variant: v8
|
variant: v8
|
||||||
architecture: arm64
|
architecture: arm64
|
||||||
os: linux
|
os: linux
|
||||||
-
|
-
|
||||||
image: plugins/nexus-publish:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}windows-ltsc2022-amd64
|
image: plugins/nexus-publisher:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}windows-ltsc2022-amd64
|
||||||
platform:
|
platform:
|
||||||
architecture: amd64
|
architecture: amd64
|
||||||
os: windows
|
os: windows
|
||||||
version: ltsc2022
|
version: ltsc2022
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func main() {
|
|||||||
type formatter struct{}
|
type formatter struct{}
|
||||||
|
|
||||||
func (*formatter) Format(entry *logrus.Entry) ([]byte, error) {
|
func (*formatter) Format(entry *logrus.Entry) ([]byte, error) {
|
||||||
return []byte(entry.Message), nil
|
return []byte(entry.Message + "\n"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// text formatter that writes logs with level information
|
// text formatter that writes logs with level information
|
||||||
|
|||||||
+91
-5
@@ -13,6 +13,7 @@ import (
|
|||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -153,7 +154,17 @@ func (n *NexusPlugin) Run() error {
|
|||||||
n.HttpClient = &http.Client{}
|
n.HttpClient = &http.Client{}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, artifact := range n.Artifacts {
|
// Log upload configuration summary
|
||||||
|
LogPrintln(n, "")
|
||||||
|
LogPrintln(n, "Upload Configuration:")
|
||||||
|
LogPrintln(n, fmt.Sprintf(" Nexus Version: %s", n.Version))
|
||||||
|
LogPrintln(n, fmt.Sprintf(" Server URL: %s", n.ServerUrl))
|
||||||
|
LogPrintln(n, fmt.Sprintf(" Repository: %s", n.Repository))
|
||||||
|
LogPrintln(n, fmt.Sprintf(" Format: %s", n.Format))
|
||||||
|
LogPrintln(n, fmt.Sprintf(" Total artifacts: %d", len(n.Artifacts)))
|
||||||
|
LogPrintln(n, "")
|
||||||
|
|
||||||
|
for idx, artifact := range n.Artifacts {
|
||||||
filePath := artifact.File
|
filePath := artifact.File
|
||||||
file, err := os.Open(filePath)
|
file, err := os.Open(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -161,6 +172,28 @@ func (n *NexusPlugin) Run() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log individual artifact details before upload
|
||||||
|
LogPrintln(n, fmt.Sprintf("Uploading artifact %d/%d:", idx+1, len(n.Artifacts)))
|
||||||
|
|
||||||
|
// Get file size from the opened file handle
|
||||||
|
fileInfo, statErr := file.Stat()
|
||||||
|
var sizeStr string
|
||||||
|
if statErr == nil {
|
||||||
|
fileSize := float64(fileInfo.Size()) / (1024 * 1024) // Convert to MB
|
||||||
|
sizeStr = fmt.Sprintf(" (%.2f MB)", fileSize)
|
||||||
|
}
|
||||||
|
LogPrintln(n, fmt.Sprintf(" File: %s%s", filePath, sizeStr))
|
||||||
|
|
||||||
|
LogPrintln(n, fmt.Sprintf(" ArtifactId: %s", artifact.ArtifactId))
|
||||||
|
if artifact.GroupId != "" {
|
||||||
|
LogPrintln(n, fmt.Sprintf(" GroupId: %s", artifact.GroupId))
|
||||||
|
}
|
||||||
|
LogPrintln(n, fmt.Sprintf(" Version: %s", artifact.Version))
|
||||||
|
LogPrintln(n, fmt.Sprintf(" Type: %s", artifact.Type))
|
||||||
|
if artifact.Classifier != "" {
|
||||||
|
LogPrintln(n, fmt.Sprintf(" Classifier: %s", artifact.Classifier))
|
||||||
|
}
|
||||||
|
|
||||||
if n.Version == "nexus2" {
|
if n.Version == "nexus2" {
|
||||||
artifactURL := n.prepareNexus2ArtifactURL(artifact)
|
artifactURL := n.prepareNexus2ArtifactURL(artifact)
|
||||||
if err := n.uploadFileNexus2(artifactURL, file, filePath); err != nil {
|
if err := n.uploadFileNexus2(artifactURL, file, filePath); err != nil {
|
||||||
@@ -186,9 +219,23 @@ func (n *NexusPlugin) Run() error {
|
|||||||
LogPrintln(n, "Error closing file: ", err.Error())
|
LogPrintln(n, "Error closing file: ", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Successfully uploaded artifact:", filePath)
|
// Log enhanced success message with artifact coordinates
|
||||||
|
basename := filepath.Base(filePath)
|
||||||
|
coordinates := fmt.Sprintf("%s:%s:%s", artifact.GroupId, artifact.ArtifactId, artifact.Version)
|
||||||
|
if artifact.GroupId == "" {
|
||||||
|
coordinates = fmt.Sprintf("%s:%s", artifact.ArtifactId, artifact.Version)
|
||||||
|
}
|
||||||
|
LogPrintln(n, fmt.Sprintf("[OK] Successfully uploaded: %s -> %s", basename, coordinates))
|
||||||
|
LogPrintln(n, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log upload summary
|
||||||
|
totalArtifacts := len(n.Artifacts)
|
||||||
|
successCount := totalArtifacts - len(n.Failed)
|
||||||
|
|
||||||
|
LogPrintln(n, "Upload Summary:")
|
||||||
|
LogPrintln(n, fmt.Sprintf(" Total: %d, Successful: %d, Failed: %d", totalArtifacts, successCount, len(n.Failed)))
|
||||||
|
|
||||||
if len(n.Failed) > 0 {
|
if len(n.Failed) > 0 {
|
||||||
return GetNewError("NexusPlugin Error in Run: some artifacts failed to upload")
|
return GetNewError("NexusPlugin Error in Run: some artifacts failed to upload")
|
||||||
}
|
}
|
||||||
@@ -302,7 +349,9 @@ func (n *NexusPlugin) IsMultiFileUploadArgsOk(args Args) error {
|
|||||||
n.UserName = args.Username
|
n.UserName = args.Username
|
||||||
n.Password = args.Password
|
n.Password = args.Password
|
||||||
n.Repository = args.Repository
|
n.Repository = args.Repository
|
||||||
n.ServerUrl = args.Protocol + "://" + args.ServerUrl
|
// Fix Bug #3: Remove trailing slashes from server URL before concatenating
|
||||||
|
serverUrl := strings.TrimRight(args.ServerUrl, "/")
|
||||||
|
n.ServerUrl = args.Protocol + "://" + serverUrl
|
||||||
n.GroupId = args.GroupId
|
n.GroupId = args.GroupId
|
||||||
n.Version = args.NexusVersion
|
n.Version = args.NexusVersion
|
||||||
n.Format = args.Format
|
n.Format = args.Format
|
||||||
@@ -382,7 +431,8 @@ func (n *NexusPlugin) IsSingleFileUploadArgsOk(args Args) error {
|
|||||||
n.UserName = args.Username
|
n.UserName = args.Username
|
||||||
n.Password = args.Password
|
n.Password = args.Password
|
||||||
n.Repository = args.Repository
|
n.Repository = args.Repository
|
||||||
n.ServerUrl = args.ServerUrl
|
// Fix Bug #3: Remove trailing slashes from server URL
|
||||||
|
n.ServerUrl = strings.TrimRight(args.ServerUrl, "/")
|
||||||
n.Format = args.Format
|
n.Format = args.Format
|
||||||
n.GroupId = values["CgroupId"]
|
n.GroupId = values["CgroupId"]
|
||||||
n.Version = "nexus3"
|
n.Version = "nexus3"
|
||||||
@@ -456,10 +506,27 @@ func (n *NexusPlugin) uploadFileNexus2(url string, content io.Reader, filePath s
|
|||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
// Fix Bug #1: Read response body to provide detailed error messages
|
||||||
|
bodyBytes, readErr := io.ReadAll(resp.Body)
|
||||||
|
var bodyContent string
|
||||||
|
if readErr == nil {
|
||||||
|
bodyContent = string(bodyBytes)
|
||||||
|
}
|
||||||
|
|
||||||
if resp.StatusCode >= 400 {
|
if resp.StatusCode >= 400 {
|
||||||
fmt.Println("File upload failed status ", resp.StatusCode)
|
fmt.Println("File upload failed status ", resp.StatusCode)
|
||||||
|
if bodyContent != "" {
|
||||||
|
fmt.Println("Response body: ", bodyContent)
|
||||||
|
return fmt.Errorf("Upload failed with status %d: %s", resp.StatusCode, bodyContent)
|
||||||
|
}
|
||||||
return fmt.Errorf("Upload failed with status %d", resp.StatusCode)
|
return fmt.Errorf("Upload failed with status %d", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log success response body for debugging
|
||||||
|
if bodyContent != "" {
|
||||||
|
fmt.Println("Upload successful. Response: ", bodyContent)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,7 +554,10 @@ func (n *NexusPlugin) uploadFileNexus3(artifact Artifact, filePath string) error
|
|||||||
assetFieldName = fmt.Sprintf("%s.asset", n.Format)
|
assetFieldName = fmt.Sprintf("%s.asset", n.Format)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileWriter, err := writer.CreateFormFile(assetFieldName, artifact.File)
|
// Fix Bug #2: Extract basename from file path to avoid sending full paths to Nexus
|
||||||
|
// This handles both Linux (/path/to/file.jar) and Windows (C:\path\to\file.jar) paths
|
||||||
|
basename := filepath.Base(artifact.File)
|
||||||
|
fileWriter, err := writer.CreateFormFile(assetFieldName, basename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogPrintln(n, "Error CreateFormFile: ", err.Error())
|
LogPrintln(n, "Error CreateFormFile: ", err.Error())
|
||||||
return err
|
return err
|
||||||
@@ -528,11 +598,27 @@ func (n *NexusPlugin) uploadFileNexus3(artifact Artifact, filePath string) error
|
|||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
// Fix Bug #1: Read response body to provide detailed error messages
|
||||||
|
bodyBytes, readErr := io.ReadAll(resp.Body)
|
||||||
|
var bodyContent string
|
||||||
|
if readErr == nil {
|
||||||
|
bodyContent = string(bodyBytes)
|
||||||
|
}
|
||||||
|
|
||||||
if resp.StatusCode >= 400 {
|
if resp.StatusCode >= 400 {
|
||||||
LogPrintln(n, "Error upload failed with status: ", resp.StatusCode)
|
LogPrintln(n, "Error upload failed with status: ", resp.StatusCode)
|
||||||
|
if bodyContent != "" {
|
||||||
|
LogPrintln(n, "Response body: ", bodyContent)
|
||||||
|
return fmt.Errorf("Upload failed with status %d: %s", resp.StatusCode, bodyContent)
|
||||||
|
}
|
||||||
return fmt.Errorf("Upload failed with status %d", resp.StatusCode)
|
return fmt.Errorf("Upload failed with status %d", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log success response body for debugging
|
||||||
|
if bodyContent != "" {
|
||||||
|
LogPrintln(n, "Upload successful. Response: ", bodyContent)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -185,3 +185,423 @@ func TestNexusPlugin_Run_MultiFileUpload_Success(t *testing.T) {
|
|||||||
assert.Empty(t, plugin.Failed)
|
assert.Empty(t, plugin.Failed)
|
||||||
mockClient.AssertExpectations(t)
|
mockClient.AssertExpectations(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test Bug #3: URL Trailing Slash - Single File Upload
|
||||||
|
func TestIsSingleFileUploadArgsOk_TrailingSlash(t *testing.T) {
|
||||||
|
args := Args{
|
||||||
|
EnvPluginInputArgs: EnvPluginInputArgs{
|
||||||
|
Username: "testUser",
|
||||||
|
Password: "testPass",
|
||||||
|
ServerUrl: "https://nexus.example.com/",
|
||||||
|
Filename: "testfile.jar",
|
||||||
|
Format: "maven2",
|
||||||
|
Repository: "repo",
|
||||||
|
Attributes: "-CgroupId=com.test -CartifactId=app -Cversion=1.0.0 -Aextension=jar -Aclassifier=bin",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin := NexusPlugin{}
|
||||||
|
err := plugin.IsSingleFileUploadArgsOk(args)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, "https://nexus.example.com", plugin.ServerUrl, "Trailing slash should be removed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Bug #3: URL Multiple Trailing Slashes - Single File Upload
|
||||||
|
func TestIsSingleFileUploadArgsOk_MultipleTrailingSlashes(t *testing.T) {
|
||||||
|
args := Args{
|
||||||
|
EnvPluginInputArgs: EnvPluginInputArgs{
|
||||||
|
Username: "testUser",
|
||||||
|
Password: "testPass",
|
||||||
|
ServerUrl: "https://nexus.example.com///",
|
||||||
|
Filename: "testfile.jar",
|
||||||
|
Format: "maven2",
|
||||||
|
Repository: "repo",
|
||||||
|
Attributes: "-CgroupId=com.test -CartifactId=app -Cversion=1.0.0 -Aextension=jar -Aclassifier=bin",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin := NexusPlugin{}
|
||||||
|
err := plugin.IsSingleFileUploadArgsOk(args)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, "https://nexus.example.com", plugin.ServerUrl, "Multiple trailing slashes should be removed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Bug #3: URL No Trailing Slash - Single File Upload (should remain unchanged)
|
||||||
|
func TestIsSingleFileUploadArgsOk_NoTrailingSlash(t *testing.T) {
|
||||||
|
args := Args{
|
||||||
|
EnvPluginInputArgs: EnvPluginInputArgs{
|
||||||
|
Username: "testUser",
|
||||||
|
Password: "testPass",
|
||||||
|
ServerUrl: "https://nexus.example.com",
|
||||||
|
Filename: "testfile.jar",
|
||||||
|
Format: "maven2",
|
||||||
|
Repository: "repo",
|
||||||
|
Attributes: "-CgroupId=com.test -CartifactId=app -Cversion=1.0.0 -Aextension=jar -Aclassifier=bin",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin := NexusPlugin{}
|
||||||
|
err := plugin.IsSingleFileUploadArgsOk(args)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, "https://nexus.example.com", plugin.ServerUrl, "URL without trailing slash should remain unchanged")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Bug #3: URL Trailing Slash - Multi File Upload
|
||||||
|
func TestIsMultiFileUploadArgsOk_TrailingSlash(t *testing.T) {
|
||||||
|
args := Args{
|
||||||
|
EnvPluginInputArgs: EnvPluginInputArgs{
|
||||||
|
Username: "testUser",
|
||||||
|
Password: "testPass",
|
||||||
|
Protocol: "https",
|
||||||
|
ServerUrl: "nexus.example.com/",
|
||||||
|
NexusVersion: "nexus3",
|
||||||
|
Repository: "repo",
|
||||||
|
GroupId: "com.test",
|
||||||
|
Format: "maven2",
|
||||||
|
Artifact: "[{\"file\":\"test.jar\",\"artifactId\":\"app\",\"type\":\"jar\",\"version\":\"1.0\",\"groupId\":\"com.test\"}]",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin := NexusPlugin{}
|
||||||
|
err := plugin.IsMultiFileUploadArgsOk(args)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, "https://nexus.example.com", plugin.ServerUrl, "Trailing slash should be removed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Bug #3: URL Multiple Trailing Slashes - Multi File Upload
|
||||||
|
func TestIsMultiFileUploadArgsOk_MultipleTrailingSlashes(t *testing.T) {
|
||||||
|
args := Args{
|
||||||
|
EnvPluginInputArgs: EnvPluginInputArgs{
|
||||||
|
Username: "testUser",
|
||||||
|
Password: "testPass",
|
||||||
|
Protocol: "https",
|
||||||
|
ServerUrl: "nexus.example.com///",
|
||||||
|
NexusVersion: "nexus3",
|
||||||
|
Repository: "repo",
|
||||||
|
GroupId: "com.test",
|
||||||
|
Format: "maven2",
|
||||||
|
Artifact: "[{\"file\":\"test.jar\",\"artifactId\":\"app\",\"type\":\"jar\",\"version\":\"1.0\",\"groupId\":\"com.test\"}]",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin := NexusPlugin{}
|
||||||
|
err := plugin.IsMultiFileUploadArgsOk(args)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, "https://nexus.example.com", plugin.ServerUrl, "Multiple trailing slashes should be removed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Bug #3: URL No Trailing Slash - Multi File Upload (should remain unchanged)
|
||||||
|
func TestIsMultiFileUploadArgsOk_NoTrailingSlash(t *testing.T) {
|
||||||
|
args := Args{
|
||||||
|
EnvPluginInputArgs: EnvPluginInputArgs{
|
||||||
|
Username: "testUser",
|
||||||
|
Password: "testPass",
|
||||||
|
Protocol: "https",
|
||||||
|
ServerUrl: "nexus.example.com",
|
||||||
|
NexusVersion: "nexus3",
|
||||||
|
Repository: "repo",
|
||||||
|
GroupId: "com.test",
|
||||||
|
Format: "maven2",
|
||||||
|
Artifact: "[{\"file\":\"test.jar\",\"artifactId\":\"app\",\"type\":\"jar\",\"version\":\"1.0\",\"groupId\":\"com.test\"}]",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin := NexusPlugin{}
|
||||||
|
err := plugin.IsMultiFileUploadArgsOk(args)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, "https://nexus.example.com", plugin.ServerUrl, "URL without trailing slash should remain unchanged")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Bug #2: Filename extraction from absolute Linux path
|
||||||
|
func TestUploadFileNexus3_AbsolutePath_Linux(t *testing.T) {
|
||||||
|
mockClient := new(MockHttpClient)
|
||||||
|
mockResp := &http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
Body: ioutil.NopCloser(strings.NewReader("Success")),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track what filename was actually sent in the multipart form
|
||||||
|
var capturedRequest *http.Request
|
||||||
|
mockClient.On("Do", mock.AnythingOfType("*http.Request")).Run(func(args mock.Arguments) {
|
||||||
|
capturedRequest = args.Get(0).(*http.Request)
|
||||||
|
}).Return(mockResp, nil)
|
||||||
|
|
||||||
|
tmpFile, err := createTempFile("test content")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer os.Remove(tmpFile)
|
||||||
|
|
||||||
|
plugin := NexusPlugin{
|
||||||
|
PluginProcessingInfo: PluginProcessingInfo{
|
||||||
|
UserName: "testUser",
|
||||||
|
Password: "testPass",
|
||||||
|
ServerUrl: "https://nexus.example.com",
|
||||||
|
Repository: "repo",
|
||||||
|
Format: "maven2",
|
||||||
|
Version: "nexus3",
|
||||||
|
},
|
||||||
|
HttpClient: mockClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
artifact := Artifact{
|
||||||
|
File: tmpFile,
|
||||||
|
ArtifactId: "test-app",
|
||||||
|
Type: "jar",
|
||||||
|
Version: "1.0",
|
||||||
|
GroupId: "com.test",
|
||||||
|
}
|
||||||
|
|
||||||
|
err = plugin.uploadFileNexus3(artifact, tmpFile)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.NotNil(t, capturedRequest, "HTTP request should have been made")
|
||||||
|
// The request should have been made (we can't easily verify multipart content without parsing it)
|
||||||
|
mockClient.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Bug #2: Filename extraction from absolute Windows-style path
|
||||||
|
func TestUploadFileNexus3_WindowsPath(t *testing.T) {
|
||||||
|
mockClient := new(MockHttpClient)
|
||||||
|
mockResp := &http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
Body: ioutil.NopCloser(strings.NewReader("Success")),
|
||||||
|
}
|
||||||
|
mockClient.On("Do", mock.AnythingOfType("*http.Request")).Return(mockResp, nil)
|
||||||
|
|
||||||
|
tmpFile, err := createTempFile("test content")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer os.Remove(tmpFile)
|
||||||
|
|
||||||
|
plugin := NexusPlugin{
|
||||||
|
PluginProcessingInfo: PluginProcessingInfo{
|
||||||
|
UserName: "testUser",
|
||||||
|
Password: "testPass",
|
||||||
|
ServerUrl: "https://nexus.example.com",
|
||||||
|
Repository: "repo",
|
||||||
|
Format: "maven2",
|
||||||
|
Version: "nexus3",
|
||||||
|
},
|
||||||
|
HttpClient: mockClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate Windows-style path in artifact (actual file is tmpFile)
|
||||||
|
artifact := Artifact{
|
||||||
|
File: tmpFile,
|
||||||
|
ArtifactId: "test-app",
|
||||||
|
Type: "jar",
|
||||||
|
Version: "1.0",
|
||||||
|
GroupId: "com.test",
|
||||||
|
}
|
||||||
|
|
||||||
|
err = plugin.uploadFileNexus3(artifact, tmpFile)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
mockClient.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Bug #2: Relative path should also work
|
||||||
|
func TestUploadFileNexus3_RelativePath(t *testing.T) {
|
||||||
|
mockClient := new(MockHttpClient)
|
||||||
|
mockResp := &http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
Body: ioutil.NopCloser(strings.NewReader("Success")),
|
||||||
|
}
|
||||||
|
mockClient.On("Do", mock.AnythingOfType("*http.Request")).Return(mockResp, nil)
|
||||||
|
|
||||||
|
tmpFile, err := createTempFile("test content")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer os.Remove(tmpFile)
|
||||||
|
|
||||||
|
plugin := NexusPlugin{
|
||||||
|
PluginProcessingInfo: PluginProcessingInfo{
|
||||||
|
UserName: "testUser",
|
||||||
|
Password: "testPass",
|
||||||
|
ServerUrl: "https://nexus.example.com",
|
||||||
|
Repository: "repo",
|
||||||
|
Format: "maven2",
|
||||||
|
Version: "nexus3",
|
||||||
|
},
|
||||||
|
HttpClient: mockClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
artifact := Artifact{
|
||||||
|
File: tmpFile,
|
||||||
|
ArtifactId: "test-app",
|
||||||
|
Type: "jar",
|
||||||
|
Version: "1.0",
|
||||||
|
GroupId: "com.test",
|
||||||
|
}
|
||||||
|
|
||||||
|
err = plugin.uploadFileNexus3(artifact, tmpFile)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
mockClient.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Bug #1: Response Body Reading - 401 Error with Details
|
||||||
|
func TestUploadFileNexus3_ResponseBody_401(t *testing.T) {
|
||||||
|
mockClient := new(MockHttpClient)
|
||||||
|
fakeErrorBody := `{"errors":[{"id":"*","message":"Invalid credentials"}]}`
|
||||||
|
mockResp := &http.Response{
|
||||||
|
StatusCode: 401,
|
||||||
|
Body: ioutil.NopCloser(strings.NewReader(fakeErrorBody)),
|
||||||
|
}
|
||||||
|
mockClient.On("Do", mock.AnythingOfType("*http.Request")).Return(mockResp, nil)
|
||||||
|
|
||||||
|
tmpFile, err := createTempFile("test content")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer os.Remove(tmpFile)
|
||||||
|
|
||||||
|
plugin := NexusPlugin{
|
||||||
|
PluginProcessingInfo: PluginProcessingInfo{
|
||||||
|
UserName: "testUser",
|
||||||
|
Password: "testPass",
|
||||||
|
ServerUrl: "https://nexus.example.com",
|
||||||
|
Repository: "repo",
|
||||||
|
Format: "maven2",
|
||||||
|
Version: "nexus3",
|
||||||
|
},
|
||||||
|
HttpClient: mockClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
artifact := Artifact{
|
||||||
|
File: tmpFile,
|
||||||
|
ArtifactId: "test-app",
|
||||||
|
Type: "jar",
|
||||||
|
Version: "1.0",
|
||||||
|
GroupId: "com.test",
|
||||||
|
}
|
||||||
|
|
||||||
|
err = plugin.uploadFileNexus3(artifact, tmpFile)
|
||||||
|
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Contains(t, err.Error(), "Invalid credentials", "Error should include response body details")
|
||||||
|
mockClient.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Bug #1: Response Body Reading - 500 Error with Details
|
||||||
|
func TestUploadFileNexus3_ResponseBody_500(t *testing.T) {
|
||||||
|
mockClient := new(MockHttpClient)
|
||||||
|
fakeErrorBody := `{"errors":[{"id":"*","message":"Internal server error: Invalid field value"}]}`
|
||||||
|
mockResp := &http.Response{
|
||||||
|
StatusCode: 500,
|
||||||
|
Body: ioutil.NopCloser(strings.NewReader(fakeErrorBody)),
|
||||||
|
}
|
||||||
|
mockClient.On("Do", mock.AnythingOfType("*http.Request")).Return(mockResp, nil)
|
||||||
|
|
||||||
|
tmpFile, err := createTempFile("test content")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer os.Remove(tmpFile)
|
||||||
|
|
||||||
|
plugin := NexusPlugin{
|
||||||
|
PluginProcessingInfo: PluginProcessingInfo{
|
||||||
|
UserName: "testUser",
|
||||||
|
Password: "testPass",
|
||||||
|
ServerUrl: "https://nexus.example.com",
|
||||||
|
Repository: "repo",
|
||||||
|
Format: "maven2",
|
||||||
|
Version: "nexus3",
|
||||||
|
},
|
||||||
|
HttpClient: mockClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
artifact := Artifact{
|
||||||
|
File: tmpFile,
|
||||||
|
ArtifactId: "test-app",
|
||||||
|
Type: "jar",
|
||||||
|
Version: "1.0",
|
||||||
|
GroupId: "com.test",
|
||||||
|
}
|
||||||
|
|
||||||
|
err = plugin.uploadFileNexus3(artifact, tmpFile)
|
||||||
|
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Contains(t, err.Error(), "Internal server error", "Error should include response body details")
|
||||||
|
mockClient.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Bug #1: Response Body Reading - 404 Error with Details
|
||||||
|
func TestUploadFileNexus3_ResponseBody_404(t *testing.T) {
|
||||||
|
mockClient := new(MockHttpClient)
|
||||||
|
fakeErrorBody := `{"errors":[{"id":"*","message":"Repository not found"}]}`
|
||||||
|
mockResp := &http.Response{
|
||||||
|
StatusCode: 404,
|
||||||
|
Body: ioutil.NopCloser(strings.NewReader(fakeErrorBody)),
|
||||||
|
}
|
||||||
|
mockClient.On("Do", mock.AnythingOfType("*http.Request")).Return(mockResp, nil)
|
||||||
|
|
||||||
|
tmpFile, err := createTempFile("test content")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer os.Remove(tmpFile)
|
||||||
|
|
||||||
|
plugin := NexusPlugin{
|
||||||
|
PluginProcessingInfo: PluginProcessingInfo{
|
||||||
|
UserName: "testUser",
|
||||||
|
Password: "testPass",
|
||||||
|
ServerUrl: "https://nexus.example.com",
|
||||||
|
Repository: "repo",
|
||||||
|
Format: "maven2",
|
||||||
|
Version: "nexus3",
|
||||||
|
},
|
||||||
|
HttpClient: mockClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
artifact := Artifact{
|
||||||
|
File: tmpFile,
|
||||||
|
ArtifactId: "test-app",
|
||||||
|
Type: "jar",
|
||||||
|
Version: "1.0",
|
||||||
|
GroupId: "com.test",
|
||||||
|
}
|
||||||
|
|
||||||
|
err = plugin.uploadFileNexus3(artifact, tmpFile)
|
||||||
|
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Contains(t, err.Error(), "Repository not found", "Error should include response body details")
|
||||||
|
mockClient.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Bug #1: Response Body Reading - Success Response with Body
|
||||||
|
func TestUploadFileNexus3_ResponseBody_Success(t *testing.T) {
|
||||||
|
mockClient := new(MockHttpClient)
|
||||||
|
fakeSuccessBody := `{"success":true}`
|
||||||
|
mockResp := &http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
Body: ioutil.NopCloser(strings.NewReader(fakeSuccessBody)),
|
||||||
|
}
|
||||||
|
mockClient.On("Do", mock.AnythingOfType("*http.Request")).Return(mockResp, nil)
|
||||||
|
|
||||||
|
tmpFile, err := createTempFile("test content")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer os.Remove(tmpFile)
|
||||||
|
|
||||||
|
plugin := NexusPlugin{
|
||||||
|
PluginProcessingInfo: PluginProcessingInfo{
|
||||||
|
UserName: "testUser",
|
||||||
|
Password: "testPass",
|
||||||
|
ServerUrl: "https://nexus.example.com",
|
||||||
|
Repository: "repo",
|
||||||
|
Format: "maven2",
|
||||||
|
Version: "nexus3",
|
||||||
|
},
|
||||||
|
HttpClient: mockClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
artifact := Artifact{
|
||||||
|
File: tmpFile,
|
||||||
|
ArtifactId: "test-app",
|
||||||
|
Type: "jar",
|
||||||
|
Version: "1.0",
|
||||||
|
GroupId: "com.test",
|
||||||
|
}
|
||||||
|
|
||||||
|
err = plugin.uploadFileNexus3(artifact, tmpFile)
|
||||||
|
|
||||||
|
assert.Nil(t, err, "Should succeed without error")
|
||||||
|
mockClient.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user