mirror of
https://github.com/portainer/portainer.git
synced 2025-07-19 13:29:41 +02:00
252 lines
7.7 KiB
Go
252 lines
7.7 KiB
Go
package liboras
|
|
|
|
import (
|
|
"testing"
|
|
|
|
portainer "github.com/portainer/portainer/api"
|
|
"github.com/stretchr/testify/assert"
|
|
"oras.land/oras-go/v2/registry/remote/auth"
|
|
"oras.land/oras-go/v2/registry/remote/retry"
|
|
)
|
|
|
|
func TestCreateClient_AuthenticationScenarios(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
registry portainer.Registry
|
|
expectAuthenticated bool
|
|
description string
|
|
}{
|
|
{
|
|
name: "authentication disabled should create anonymous client",
|
|
registry: portainer.Registry{
|
|
URL: "registry.example.com",
|
|
Authentication: false,
|
|
Username: "testuser",
|
|
Password: "testpass",
|
|
},
|
|
expectAuthenticated: false,
|
|
description: "Even with credentials present, authentication=false should result in anonymous access",
|
|
},
|
|
{
|
|
name: "authentication enabled with valid credentials should create authenticated client",
|
|
registry: portainer.Registry{
|
|
URL: "registry.example.com",
|
|
Authentication: true,
|
|
Username: "testuser",
|
|
Password: "testpass",
|
|
},
|
|
expectAuthenticated: true,
|
|
description: "Valid credentials with authentication=true should result in authenticated access",
|
|
},
|
|
{
|
|
name: "authentication enabled with empty username should create anonymous client",
|
|
registry: portainer.Registry{
|
|
URL: "registry.example.com",
|
|
Authentication: true,
|
|
Username: "",
|
|
Password: "testpass",
|
|
},
|
|
expectAuthenticated: false,
|
|
description: "Empty username should fallback to anonymous access",
|
|
},
|
|
{
|
|
name: "authentication enabled with whitespace-only username should create anonymous client",
|
|
registry: portainer.Registry{
|
|
URL: "registry.example.com",
|
|
Authentication: true,
|
|
Username: " ",
|
|
Password: "testpass",
|
|
},
|
|
expectAuthenticated: false,
|
|
description: "Whitespace-only username should fallback to anonymous access",
|
|
},
|
|
{
|
|
name: "authentication enabled with empty password should create anonymous client",
|
|
registry: portainer.Registry{
|
|
URL: "registry.example.com",
|
|
Authentication: true,
|
|
Username: "testuser",
|
|
Password: "",
|
|
},
|
|
expectAuthenticated: false,
|
|
description: "Empty password should fallback to anonymous access",
|
|
},
|
|
{
|
|
name: "authentication enabled with whitespace-only password should create anonymous client",
|
|
registry: portainer.Registry{
|
|
URL: "registry.example.com",
|
|
Authentication: true,
|
|
Username: "testuser",
|
|
Password: " ",
|
|
},
|
|
expectAuthenticated: false,
|
|
description: "Whitespace-only password should fallback to anonymous access",
|
|
},
|
|
{
|
|
name: "authentication enabled with both credentials empty should create anonymous client",
|
|
registry: portainer.Registry{
|
|
URL: "registry.example.com",
|
|
Authentication: true,
|
|
Username: "",
|
|
Password: "",
|
|
},
|
|
expectAuthenticated: false,
|
|
description: "Both credentials empty should fallback to anonymous access",
|
|
},
|
|
{
|
|
name: "public registry with no authentication should create anonymous client",
|
|
registry: portainer.Registry{
|
|
URL: "docker.io",
|
|
Authentication: false,
|
|
Username: "",
|
|
Password: "",
|
|
},
|
|
expectAuthenticated: false,
|
|
description: "Public registries without authentication should use anonymous access",
|
|
},
|
|
{
|
|
name: "GitLab registry with valid credentials should create authenticated client",
|
|
registry: portainer.Registry{
|
|
Type: portainer.GitlabRegistry,
|
|
URL: "registry.gitlab.com",
|
|
Authentication: true,
|
|
Username: "gitlab-ci-token",
|
|
Password: "glpat-xxxxxxxxxxxxxxxxxxxx",
|
|
Gitlab: portainer.GitlabRegistryData{
|
|
ProjectID: 12345,
|
|
InstanceURL: "https://gitlab.com",
|
|
ProjectPath: "my-group/my-project",
|
|
},
|
|
},
|
|
expectAuthenticated: true,
|
|
description: "GitLab registry with valid credentials should result in authenticated access",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
client, err := CreateClient(tt.registry)
|
|
|
|
assert.NoError(t, err, "CreateClient should not return an error")
|
|
assert.NotNil(t, client, "Client should not be nil")
|
|
|
|
// Check if the client has authentication configured
|
|
if tt.expectAuthenticated {
|
|
// Should have auth.Client with credentials
|
|
authClient, ok := client.Client.(*auth.Client)
|
|
assert.True(t, ok, "Expected auth.Client for authenticated access")
|
|
assert.NotNil(t, authClient, "Auth client should not be nil")
|
|
assert.NotNil(t, authClient.Credential, "Credential function should be set")
|
|
} else {
|
|
// Should use retry.DefaultClient (no authentication)
|
|
assert.Equal(t, retry.DefaultClient, client.Client,
|
|
"Expected retry.DefaultClient for anonymous access")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCreateClient_RegistryTypes(t *testing.T) {
|
|
registryTypes := []struct {
|
|
name string
|
|
registryType portainer.RegistryType
|
|
expectedName string
|
|
}{
|
|
{"DockerHub", portainer.DockerHubRegistry, "DockerHub"},
|
|
{"Azure", portainer.AzureRegistry, "Azure"},
|
|
{"Custom", portainer.CustomRegistry, "Custom"},
|
|
{"GitLab", portainer.GitlabRegistry, "GitLab"},
|
|
{"Quay", portainer.QuayRegistry, "Quay"},
|
|
{"ProGet", portainer.ProGetRegistry, "ProGet"},
|
|
{"ECR", portainer.EcrRegistry, "ECR"},
|
|
}
|
|
|
|
for _, rt := range registryTypes {
|
|
t.Run(rt.name, func(t *testing.T) {
|
|
registry := portainer.Registry{
|
|
URL: "registry.example.com",
|
|
Type: rt.registryType,
|
|
Authentication: false,
|
|
}
|
|
|
|
client, err := CreateClient(registry)
|
|
|
|
assert.NoError(t, err, "CreateClient should not return an error")
|
|
assert.NotNil(t, client, "Client should not be nil")
|
|
|
|
// Verify that getRegistryTypeName returns the expected name
|
|
typeName := getRegistryTypeName(rt.registryType)
|
|
assert.Equal(t, rt.expectedName, typeName, "Registry type name mismatch")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetRegistryTypeName(t *testing.T) {
|
|
tests := []struct {
|
|
registryType portainer.RegistryType
|
|
expectedName string
|
|
}{
|
|
{portainer.QuayRegistry, "Quay"},
|
|
{portainer.AzureRegistry, "Azure"},
|
|
{portainer.CustomRegistry, "Custom"},
|
|
{portainer.GitlabRegistry, "GitLab"},
|
|
{portainer.ProGetRegistry, "ProGet"},
|
|
{portainer.DockerHubRegistry, "DockerHub"},
|
|
{portainer.EcrRegistry, "ECR"},
|
|
{portainer.RegistryType(999), "Unknown"}, // Unknown type
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.expectedName, func(t *testing.T) {
|
|
result := getRegistryTypeName(tt.registryType)
|
|
assert.Equal(t, tt.expectedName, result, "Registry type name mismatch")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCreateClient_ErrorHandling(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
registry portainer.Registry
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "valid registry URL should not error",
|
|
registry: portainer.Registry{
|
|
URL: "registry.example.com",
|
|
Authentication: false,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "empty registry URL should error",
|
|
registry: portainer.Registry{
|
|
URL: "",
|
|
Authentication: false,
|
|
},
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "invalid registry URL should error",
|
|
registry: portainer.Registry{
|
|
URL: "://invalid-url",
|
|
Authentication: false,
|
|
},
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
client, err := CreateClient(tt.registry)
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err, "Expected an error but got none")
|
|
assert.Nil(t, client, "Client should be nil when error occurs")
|
|
} else {
|
|
assert.NoError(t, err, "Expected no error but got: %v", err)
|
|
assert.NotNil(t, client, "Client should not be nil")
|
|
}
|
|
})
|
|
}
|
|
}
|