mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-08 05:46:24 +02:00
Merge remote-tracking branch 'remotes/from/ce/main'
This commit is contained in:
commit
ec3496213b
@ -95,12 +95,6 @@ scenario "plugin" {
|
||||
ubuntu = provider.enos.ubuntu
|
||||
}
|
||||
manage_service = matrix.artifact_type == "bundle"
|
||||
test_names = {
|
||||
ldap = ["TestLDAPSecretsEngineComprehensive"]
|
||||
// database = ["TestDatabaseSecretsEngineComprehensive"] // Future
|
||||
// ssh = ["TestSSHSecretsEngineComprehensive"] // Future
|
||||
// pki = ["TestPKISecretsEngineComprehensive"] // Future
|
||||
}
|
||||
}
|
||||
|
||||
step "build_vault" {
|
||||
@ -467,9 +461,19 @@ scenario "plugin" {
|
||||
}
|
||||
}
|
||||
|
||||
locals {
|
||||
// Determine if filter contains test names (starts with "Test") or package names
|
||||
is_test_name_filter = length(var.blackbox_test_filter) > 0 && length([for t in var.blackbox_test_filter : t if can(regex("^Test", t))]) > 0
|
||||
|
||||
// For plugins, if package filter is provided, convert to paths, otherwise use default plugins path
|
||||
plugin_test_packages = length(var.blackbox_test_filter) > 0 && !local.is_test_name_filter ? [
|
||||
for pkg in var.blackbox_test_filter : "./vault/external_tests/blackbox/plugins/${pkg}/..."
|
||||
] : ["./vault/external_tests/blackbox/plugins/..."]
|
||||
}
|
||||
|
||||
// Run comprehensive plugin blackbox tests
|
||||
step "run_plugin_blackbox_tests" {
|
||||
description = "Run comprehensive plugin blackbox tests"
|
||||
description = local.is_test_name_filter ? "Run specific plugin tests: ${join(", ", var.blackbox_test_filter)}" : "Run plugin blackbox tests from: ${join(", ", length(var.blackbox_test_filter) > 0 && !local.is_test_name_filter ? var.blackbox_test_filter : ["plugins"])}"
|
||||
module = module.vault_run_blackbox_test
|
||||
depends_on = [step.get_vault_cluster_ips, step.set_up_plugin_services, step.verify_vault_version]
|
||||
|
||||
@ -485,8 +489,8 @@ scenario "plugin" {
|
||||
leader_host = step.get_vault_cluster_ips.leader_host
|
||||
leader_public_ip = step.get_vault_cluster_ips.leader_public_ip
|
||||
vault_root_token = step.create_vault_cluster.root_token
|
||||
test_names = local.test_names["ldap"] // Update this to select different plugin tests based on scenario configuration
|
||||
test_package = "./vault/external_tests/blackbox/ldap"
|
||||
test_names = local.is_test_name_filter ? var.blackbox_test_filter : null
|
||||
test_package = local.is_test_name_filter ? "./vault/external_tests/blackbox" : join(" ", local.plugin_test_packages)
|
||||
integration_host_state = step.set_up_plugin_services.state
|
||||
vault_edition = matrix.edition
|
||||
}
|
||||
|
||||
@ -410,34 +410,24 @@ scenario "smoke_sdk" {
|
||||
}
|
||||
}
|
||||
|
||||
// Define smoke test suite
|
||||
locals {
|
||||
smoke_tests = [
|
||||
"TestSecretsEngineCreate",
|
||||
"TestSecretsEngineExternalCreate",
|
||||
"TestUnsealedStatus",
|
||||
"TestVaultVersion",
|
||||
"TestSecretsEngineRead",
|
||||
"TestSecretsEngineExternalRead",
|
||||
"TestReplicationStatus",
|
||||
"TestUIAssets",
|
||||
"TestSecretsEngineDelete",
|
||||
"TestSecretsEngineExternalDelete"
|
||||
]
|
||||
// Default test packages for smoke_sdk scenario
|
||||
default_test_packages = ["core", "secrets", "replication", "raft", "integration"]
|
||||
|
||||
// Add backend-specific tests
|
||||
smoke_tests_with_backend = concat(
|
||||
local.smoke_tests,
|
||||
matrix.backend == "raft" ? [
|
||||
"TestRaftVoters",
|
||||
"TestNodeRemovalAndRejoin"
|
||||
] : []
|
||||
)
|
||||
// Determine if filter contains test names (starts with "Test") or package names
|
||||
is_test_name_filter = length(var.blackbox_test_filter) > 0 && length([for t in var.blackbox_test_filter : t if can(regex("^Test", t))]) > 0
|
||||
|
||||
// Convert package names to directory paths, or use defaults
|
||||
test_packages = length(var.blackbox_test_filter) > 0 && !local.is_test_name_filter ? [
|
||||
for pkg in var.blackbox_test_filter : "./vault/external_tests/blackbox/${pkg}/..."
|
||||
] : [
|
||||
for pkg in local.default_test_packages : "./vault/external_tests/blackbox/${pkg}/..."
|
||||
]
|
||||
}
|
||||
|
||||
// Run all blackbox SDK smoke tests
|
||||
// Run all blackbox SDK smoke tests using directory-based organization
|
||||
step "run_blackbox_tests" {
|
||||
description = "Run blackbox SDK smoke tests: ${join(", ", local.smoke_tests_with_backend)}"
|
||||
description = local.is_test_name_filter ? "Run specific blackbox tests: ${join(", ", var.blackbox_test_filter)}" : "Run blackbox SDK tests from packages: ${join(", ", length(var.blackbox_test_filter) > 0 ? var.blackbox_test_filter : local.default_test_packages)}"
|
||||
module = module.vault_run_blackbox_test
|
||||
depends_on = [step.get_vault_cluster_ips, step.set_up_external_integration_target]
|
||||
|
||||
@ -449,8 +439,8 @@ scenario "smoke_sdk" {
|
||||
leader_host = step.get_vault_cluster_ips.leader_host
|
||||
leader_public_ip = step.get_vault_cluster_ips.leader_public_ip
|
||||
vault_root_token = step.create_vault_cluster.root_token
|
||||
test_names = local.smoke_tests_with_backend
|
||||
test_package = "./vault/external_tests/blackbox"
|
||||
test_names = local.is_test_name_filter ? var.blackbox_test_filter : null
|
||||
test_package = local.is_test_name_filter ? "./vault/external_tests/blackbox" : join(" ", local.test_packages)
|
||||
integration_host_state = step.set_up_external_integration_target.state
|
||||
vault_edition = matrix.edition
|
||||
}
|
||||
|
||||
@ -62,6 +62,12 @@ variable "backend_log_level" {
|
||||
default = "trace"
|
||||
}
|
||||
|
||||
variable "blackbox_test_filter" {
|
||||
type = list(string)
|
||||
description = "Override list of specific blackbox test packages (e.g., ['core', 'secrets']) or test names (e.g., ['TestUnsealedStatus']). Empty list uses scenario defaults. Package names are converted to directory paths automatically."
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "distro_version_amzn" {
|
||||
description = "The version of Amazon Linux 2 to use"
|
||||
type = string
|
||||
|
||||
@ -10,14 +10,18 @@ terraform {
|
||||
}
|
||||
|
||||
# Generate matrix.json for gotestsum from the test list
|
||||
locals {
|
||||
test_names = var.test_names != null ? var.test_names : []
|
||||
}
|
||||
|
||||
resource "local_file" "test_matrix" {
|
||||
filename = "/tmp/vault_test_matrix_${random_string.test_id.result}.json"
|
||||
content = jsonencode({
|
||||
include = length(var.test_names) > 0 ? [
|
||||
for test in var.test_names : {
|
||||
include = [
|
||||
for test in local.test_names : {
|
||||
test = test
|
||||
}
|
||||
] : []
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
@ -33,7 +37,7 @@ resource "enos_local_exec" "run_blackbox_test" {
|
||||
VAULT_TOKEN = var.vault_root_token
|
||||
VAULT_ADDR = var.vault_addr != null ? var.vault_addr : "http://${var.leader_public_ip}:8200"
|
||||
VAULT_TEST_PACKAGE = var.test_package
|
||||
VAULT_TEST_MATRIX = length(var.test_names) > 0 ? local_file.test_matrix.filename : ""
|
||||
VAULT_TEST_MATRIX = length(local.test_names) > 0 ? local_file.test_matrix.filename : ""
|
||||
VAULT_EDITION = var.vault_edition
|
||||
# PATH and Go-related environment variables are inherited from the calling process
|
||||
}, var.vault_namespace != null ? {
|
||||
|
||||
@ -15,7 +15,7 @@ output "test_results_summary" {
|
||||
exit_code = local.test_exit_code
|
||||
timestamp = timestamp()
|
||||
json_file = local.json_file_path
|
||||
test_filter = length(var.test_names) > 0 ? join(", ", var.test_names) : "all tests"
|
||||
test_filter = length(local.test_names) > 0 ? join(", ", local.test_names) : "all tests"
|
||||
test_package = var.test_package
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,6 +90,9 @@ case $VAULT_EDITION in
|
||||
esac
|
||||
|
||||
# Build gotestsum command based on whether we have specific tests
|
||||
# Convert VAULT_TEST_PACKAGE to array to handle multiple package paths properly
|
||||
IFS=$' ' read -r -d '' -a packages <<< "$VAULT_TEST_PACKAGE" || true
|
||||
|
||||
set -x # Show commands being executed
|
||||
set +e # Temporarily disable exit on error
|
||||
if [ -n "$VAULT_TEST_MATRIX" ] && [ -f "$VAULT_TEST_MATRIX" ]; then
|
||||
@ -97,10 +100,10 @@ if [ -n "$VAULT_TEST_MATRIX" ] && [ -f "$VAULT_TEST_MATRIX" ]; then
|
||||
# Extract test names from matrix and create regex pattern
|
||||
test_pattern=$(jq -r '.include[].test' "$VAULT_TEST_MATRIX" | paste -sd '|' -)
|
||||
echo "Running specific tests: $test_pattern"
|
||||
gotestsum --junitfile="$junit_output" --format=standard-verbose --jsonfile="$json_output" -- -count=1 "${tags}" -run="$test_pattern" "$VAULT_TEST_PACKAGE"
|
||||
gotestsum --junitfile="$junit_output" --format=standard-verbose --jsonfile="$json_output" -- -count=1 "${tags}" -run="$test_pattern" "${packages[@]}"
|
||||
else
|
||||
echo "Running all tests in package"
|
||||
gotestsum --junitfile="$junit_output" --format=standard-verbose --jsonfile="$json_output" -- -count=1 "${tags}" "$VAULT_TEST_PACKAGE"
|
||||
gotestsum --junitfile="$junit_output" --format=standard-verbose --jsonfile="$json_output" -- -count=1 "${tags}" "${packages[@]}"
|
||||
fi
|
||||
test_exit_code=$?
|
||||
set -e # Re-enable exit on error
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package auth
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -1,13 +1,14 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package auth
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/api"
|
||||
"github.com/hashicorp/vault/sdk/helper/testcluster/blackbox"
|
||||
helpers "github.com/hashicorp/vault/vault/external_tests/blackbox"
|
||||
)
|
||||
|
||||
// testUserpassAuthCreate tests userpass auth engine creation
|
||||
@ -20,7 +21,7 @@ func testUserpassAuthCreate(t *testing.T, v *blackbox.Session) {
|
||||
`
|
||||
|
||||
// Use common utility to setup userpass auth
|
||||
userClient := SetupUserpassAuth(v, "testuser", "passtestuser1", "reguser", userPolicy)
|
||||
userClient := helpers.SetupUserpassAuth(v, "testuser", "passtestuser1", "reguser", userPolicy)
|
||||
|
||||
// Verify the auth method was enabled by reading auth mounts
|
||||
authMounts := v.MustRead("sys/auth")
|
||||
@ -56,7 +57,7 @@ func testUserpassAuthCreate(t *testing.T, v *blackbox.Session) {
|
||||
// testUserpassAuthRead tests userpass auth engine read operations
|
||||
func testUserpassAuthRead(t *testing.T, v *blackbox.Session) {
|
||||
// Use common utility to setup userpass auth with default policy
|
||||
userClient := SetupUserpassAuth(v, "readuser", "readpass123", "default", "")
|
||||
userClient := helpers.SetupUserpassAuth(v, "readuser", "readpass123", "default", "")
|
||||
|
||||
// Read the user configuration
|
||||
userConfig := v.MustRead("auth/userpass/users/readuser")
|
||||
25
vault/external_tests/blackbox/core/license_test.go
Normal file
25
vault/external_tests/blackbox/core/license_test.go
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/helper/testcluster/blackbox"
|
||||
)
|
||||
|
||||
// TestVaultLicenseStatus verifies Vault license status response
|
||||
func TestVaultLicenseStatus(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// Read the sys/license/status endpoint which should contain license info
|
||||
licenseStatus := v.MustRead("sys/license/status")
|
||||
if licenseStatus.Data["autoloaded"] == nil {
|
||||
t.Fatal("Could not get license details from sys/license/status")
|
||||
}
|
||||
autoloaded := licenseStatus.Data["autoloaded"].(map[string]interface{})
|
||||
if autoloaded["license_id"].(string) == "" {
|
||||
t.Fatal("Could not retrieve license_id from sys/license/status")
|
||||
}
|
||||
}
|
||||
24
vault/external_tests/blackbox/core/ui_test.go
Normal file
24
vault/external_tests/blackbox/core/ui_test.go
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/helper/testcluster/blackbox"
|
||||
)
|
||||
|
||||
// TestUIAssets verifies that the Vault UI is accessible
|
||||
func TestUIAssets(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// This is a stub - in a real implementation, you would verify UI assets are accessible
|
||||
// For now, just verify the UI endpoint is available by checking sys/internal/ui/mounts
|
||||
uiMounts := v.MustRead("sys/internal/ui/mounts")
|
||||
if uiMounts == nil || uiMounts.Data == nil {
|
||||
t.Fatal("Could not access UI mounts endpoint")
|
||||
}
|
||||
|
||||
t.Log("Successfully verified UI assets are accessible")
|
||||
}
|
||||
21
vault/external_tests/blackbox/core/unsealed_test.go
Normal file
21
vault/external_tests/blackbox/core/unsealed_test.go
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/helper/testcluster/blackbox"
|
||||
)
|
||||
|
||||
// TestUnsealedStatus verifies that the Vault cluster is unsealed (not sealed).
|
||||
// This test only checks seal status, not general cluster health.
|
||||
func TestUnsealedStatus(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// Verify the cluster is unsealed
|
||||
v.AssertUnsealedAny()
|
||||
|
||||
t.Log("Successfully verified Vault cluster is unsealed")
|
||||
}
|
||||
23
vault/external_tests/blackbox/core/version_test.go
Normal file
23
vault/external_tests/blackbox/core/version_test.go
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/helper/testcluster/blackbox"
|
||||
)
|
||||
|
||||
// TestVaultVersion verifies Vault version endpoint accessibility and response
|
||||
func TestVaultVersion(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// Read the sys/seal-status endpoint which should contain version info
|
||||
sealStatus := v.MustRead("sys/seal-status")
|
||||
if sealStatus.Data["version"] == nil {
|
||||
t.Fatal("Could not retrieve version from sys/seal-status")
|
||||
}
|
||||
|
||||
t.Logf("Vault version: %v", sealStatus.Data["version"])
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package integration
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package integration
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -1,31 +1,44 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package integration
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/helper/testcluster/blackbox"
|
||||
helpers "github.com/hashicorp/vault/vault/external_tests/blackbox"
|
||||
)
|
||||
|
||||
// TestToken_OrphanedWithPolicy verifies token creation with policy assignment,
|
||||
// validates token authentication, and tests policy enforcement by attempting
|
||||
// both allowed and denied operations on KV secrets.
|
||||
func TestToken_OrphanedWithPolicy(t *testing.T) {
|
||||
// TestAuthTokenIntegration tests token operations requiring elevated permissions
|
||||
// These tests are excluded from cloud environments (HCP/Docker) which don't have
|
||||
// the necessary permissions to create orphaned tokens.
|
||||
func TestAuthTokenIntegration(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// Verify we have a healthy cluster first
|
||||
v.AssertClusterHealthy()
|
||||
|
||||
t.Run("OrphanedWithPolicy", func(t *testing.T) {
|
||||
testTokenOrphanedWithPolicy(t, v)
|
||||
})
|
||||
}
|
||||
|
||||
// testTokenOrphanedWithPolicy verifies token creation with policy assignment,
|
||||
// validates token authentication, and tests policy enforcement by attempting
|
||||
// both allowed and denied operations on KV secrets.
|
||||
func testTokenOrphanedWithPolicy(t *testing.T, v *blackbox.Session) {
|
||||
// Use common utility to create token with read-only policy
|
||||
policyName := "read-secret-only"
|
||||
v.MustWritePolicy(policyName, ReadOnlyPolicy)
|
||||
v.MustWritePolicy(policyName, helpers.ReadOnlyPolicy)
|
||||
|
||||
token := CreateTestToken(v, []string{policyName}, "15m")
|
||||
token := helpers.CreateTestToken(v, []string{policyName}, "15m")
|
||||
t.Logf("Generated Token: %s...", token[:5])
|
||||
|
||||
v.AssertTokenIsValid(token, policyName)
|
||||
|
||||
// Setup KV engine and seed test data
|
||||
SetupKVEngine(v, "secret")
|
||||
helpers.SetupKVEngine(v, "secret")
|
||||
v.MustWriteKV2("secret", "allowed/test", map[string]any{"val": "allowed"})
|
||||
v.MustWriteKV2("secret", "denied/test", map[string]any{"val": "denied"})
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
// Copyright IBM Corp. 2016, 2025
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package plugin
|
||||
|
||||
import "testing"
|
||||
|
||||
// TestAlwaysPass is a placeholder test that always passes.
|
||||
// This ensures the test directory has at least one test to run.
|
||||
func TestAlwaysPass(t *testing.T) {
|
||||
// This test intentionally does nothing and always passes
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"testing"
|
||||
21
vault/external_tests/blackbox/raft/node_operations_test.go
Normal file
21
vault/external_tests/blackbox/raft/node_operations_test.go
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package raft
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/helper/testcluster/blackbox"
|
||||
)
|
||||
|
||||
// TestNodeRemovalAndRejoin tests raft node removal and rejoin capabilities
|
||||
func TestNodeRemovalAndRejoin(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// This is a stub for node removal and rejoin testing
|
||||
// In a real implementation, you would test raft node removal and rejoin
|
||||
v.AssertClusterHealthy()
|
||||
|
||||
t.Log("Successfully verified raft cluster stability for node operations")
|
||||
}
|
||||
20
vault/external_tests/blackbox/raft/voters_test.go
Normal file
20
vault/external_tests/blackbox/raft/voters_test.go
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package raft
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/helper/testcluster/blackbox"
|
||||
)
|
||||
|
||||
// TestRaftVoters verifies that all nodes in the raft cluster are voters
|
||||
func TestRaftVoters(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// Verify we have a healthy cluster regardless of node count
|
||||
v.AssertClusterHealthy()
|
||||
|
||||
t.Log("Successfully verified raft cluster is healthy with at least one voter")
|
||||
}
|
||||
40
vault/external_tests/blackbox/replication/status_test.go
Normal file
40
vault/external_tests/blackbox/replication/status_test.go
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package replication
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/helper/testcluster/blackbox"
|
||||
)
|
||||
|
||||
// TestReplicationStatus verifies replication status for both DR and performance replication
|
||||
func TestReplicationStatus(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// Read replication status with proper nil checks
|
||||
drStatus := v.MustRead("sys/replication/dr/status")
|
||||
if drStatus == nil || drStatus.Data == nil {
|
||||
t.Log("DR replication not available or not configured - skipping DR replication check")
|
||||
} else {
|
||||
if drMode, ok := drStatus.Data["mode"]; ok {
|
||||
t.Logf("DR replication mode: %v", drMode)
|
||||
} else {
|
||||
t.Log("DR replication mode not available")
|
||||
}
|
||||
}
|
||||
|
||||
prStatus := v.MustRead("sys/replication/performance/status")
|
||||
if prStatus == nil || prStatus.Data == nil {
|
||||
t.Log("Performance replication not available or not configured - skipping performance replication check")
|
||||
} else {
|
||||
if prMode, ok := prStatus.Data["mode"]; ok {
|
||||
t.Logf("Performance replication mode: %v", prMode)
|
||||
} else {
|
||||
t.Log("Performance replication mode not available")
|
||||
}
|
||||
}
|
||||
|
||||
t.Log("Successfully verified replication status endpoints are accessible")
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"os"
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"os"
|
||||
@ -1,23 +1,24 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/helper/testcluster/blackbox"
|
||||
helpers "github.com/hashicorp/vault/vault/external_tests/blackbox"
|
||||
)
|
||||
|
||||
// testKVSecretsCreate tests KV secrets engine creation
|
||||
func testKVSecretsCreate(t *testing.T, v *blackbox.Session) {
|
||||
// KV secrets engine tests are now in kvv2_test.go - just test basic enablement here
|
||||
SetupKVEngine(v, "kv-create")
|
||||
helpers.SetupKVEngine(v, "kv-create")
|
||||
|
||||
// Write and read test data to verify engine works
|
||||
v.MustWriteKV2("kv-create", "test/path", StandardKVData)
|
||||
v.MustWriteKV2("kv-create", "test/path", helpers.StandardKVData)
|
||||
secret := v.MustReadKV2("kv-create", "test/path")
|
||||
AssertKVData(t, v, secret, StandardKVData)
|
||||
helpers.AssertKVData(t, v, secret, helpers.StandardKVData)
|
||||
|
||||
t.Log("Successfully created and tested KV secrets engine")
|
||||
}
|
||||
@ -25,20 +26,20 @@ func testKVSecretsCreate(t *testing.T, v *blackbox.Session) {
|
||||
// testKVSecretsRead tests KV secrets engine read operations
|
||||
func testKVSecretsRead(t *testing.T, v *blackbox.Session) {
|
||||
// KV read tests are in kvv2_test.go - test basic read functionality here
|
||||
SetupKVEngine(v, "kv-read")
|
||||
v.MustWriteKV2("kv-read", "read/test", AltKVData)
|
||||
helpers.SetupKVEngine(v, "kv-read")
|
||||
v.MustWriteKV2("kv-read", "read/test", helpers.AltKVData)
|
||||
secret := v.MustReadKV2("kv-read", "read/test")
|
||||
AssertKVData(t, v, secret, AltKVData)
|
||||
helpers.AssertKVData(t, v, secret, helpers.AltKVData)
|
||||
|
||||
t.Log("Successfully read KV secrets engine data")
|
||||
}
|
||||
|
||||
// testKVSecretsDelete tests KV secrets engine delete operations
|
||||
func testKVSecretsDelete(t *testing.T, v *blackbox.Session) {
|
||||
SetupKVEngine(v, "kv-delete")
|
||||
v.MustWriteKV2("kv-delete", "delete/test", StandardKVData)
|
||||
helpers.SetupKVEngine(v, "kv-delete")
|
||||
v.MustWriteKV2("kv-delete", "delete/test", helpers.StandardKVData)
|
||||
secret := v.MustReadKV2("kv-delete", "delete/test")
|
||||
AssertKVData(t, v, secret, StandardKVData)
|
||||
helpers.AssertKVData(t, v, secret, helpers.StandardKVData)
|
||||
v.MustWrite("kv-delete/delete/delete/test", map[string]any{
|
||||
"versions": []int{1},
|
||||
})
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"net"
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"testing"
|
||||
65
vault/external_tests/blackbox/system/billing_test.go
Normal file
65
vault/external_tests/blackbox/system/billing_test.go
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/api"
|
||||
"github.com/hashicorp/vault/sdk/helper/testcluster/blackbox"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestBillingOverviewNamespaceRestrictions verifies that sys/billing/overview
|
||||
// returns appropriate errors when called from different namespace levels in HVD.
|
||||
// In HVD, tests run in admin/bbsdk-xxxxx, and this test verifies:
|
||||
// - Calling from base namespace (admin) returns "unsupported path"
|
||||
// - Calling from root namespace (empty) returns "permission denied"
|
||||
func TestBillingOverviewNamespaceRestrictions(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// Verify cluster stability first
|
||||
v.AssertClusterHealthy()
|
||||
|
||||
// Check if we're in HVD (has base namespace from VAULT_NAMESPACE)
|
||||
baseNS := v.GetParentNamespace()
|
||||
if baseNS == "" {
|
||||
t.Skip("Skipping namespace restriction tests - no base namespace configured (not in HVD)")
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
namespaceSwitcher func(func() (*api.Secret, error)) (*api.Secret, error)
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
name: "base_namespace_unsupported",
|
||||
namespaceSwitcher: v.WithParentNamespace,
|
||||
expectedError: "unsupported path",
|
||||
},
|
||||
{
|
||||
name: "root_namespace_permission_denied",
|
||||
namespaceSwitcher: v.WithRootNamespace,
|
||||
expectedError: "permission denied",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var rawResp *api.Response
|
||||
var err error
|
||||
_, err = tc.namespaceSwitcher(func() (*api.Secret, error) {
|
||||
var readErr error
|
||||
rawResp, readErr = v.Client.Logical().ReadRawWithContext(context.Background(), "sys/billing/overview")
|
||||
if readErr != nil {
|
||||
return nil, readErr
|
||||
}
|
||||
// Parse the raw response to get the error
|
||||
return v.Client.Logical().ParseRawResponseAndCloseBody(rawResp, nil)
|
||||
})
|
||||
require.ErrorContains(t, err, tc.expectedError)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1,175 +0,0 @@
|
||||
// Copyright IBM Corp. 2025, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package blackbox
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/api"
|
||||
"github.com/hashicorp/vault/sdk/helper/testcluster/blackbox"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestUnsealedStatus verifies that the Vault cluster is unsealed and healthy
|
||||
func TestUnsealedStatus(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// Verify the cluster is unsealed
|
||||
v.AssertUnsealedAny()
|
||||
|
||||
t.Log("Successfully verified Vault cluster is unsealed")
|
||||
}
|
||||
|
||||
// TestVaultVersion verifies Vault version endpoint accessibility and response
|
||||
func TestVaultVersion(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// Read the sys/seal-status endpoint which should contain version info
|
||||
sealStatus := v.MustRead("sys/seal-status")
|
||||
if sealStatus.Data["version"] == nil {
|
||||
t.Fatal("Could not retrieve version from sys/seal-status")
|
||||
}
|
||||
|
||||
t.Logf("Vault version: %v", sealStatus.Data["version"])
|
||||
}
|
||||
|
||||
// TestVaultLicenseStatus verifies Vault license status response
|
||||
func TestVaultLicenseStatus(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// Read the sys/license/status endpoint which should contain license info
|
||||
licenseStatus := v.MustRead("sys/license/status")
|
||||
if licenseStatus.Data["autoloaded"] == nil {
|
||||
t.Fatal("Could not get license details from sys/license/status")
|
||||
}
|
||||
autoloaded := licenseStatus.Data["autoloaded"].(map[string]interface{})
|
||||
if autoloaded["license_id"].(string) == "" {
|
||||
t.Fatal("Could not retrieve license_id from sys/license/status")
|
||||
}
|
||||
}
|
||||
|
||||
// TestRaftVoters verifies that all nodes in the raft cluster are voters
|
||||
func TestRaftVoters(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// Verify we have a healthy cluster regardless of node count
|
||||
v.AssertClusterHealthy()
|
||||
|
||||
t.Log("Successfully verified raft cluster is healthy with at least one voter")
|
||||
}
|
||||
|
||||
// TestReplicationStatus verifies replication status for both DR and performance replication
|
||||
func TestReplicationStatus(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// Read replication status with proper nil checks
|
||||
drStatus := v.MustRead("sys/replication/dr/status")
|
||||
if drStatus == nil || drStatus.Data == nil {
|
||||
t.Log("DR replication not available or not configured - skipping DR replication check")
|
||||
} else {
|
||||
if drMode, ok := drStatus.Data["mode"]; ok {
|
||||
t.Logf("DR replication mode: %v", drMode)
|
||||
} else {
|
||||
t.Log("DR replication mode not available")
|
||||
}
|
||||
}
|
||||
|
||||
prStatus := v.MustRead("sys/replication/performance/status")
|
||||
if prStatus == nil || prStatus.Data == nil {
|
||||
t.Log("Performance replication not available or not configured - skipping performance replication check")
|
||||
} else {
|
||||
if prMode, ok := prStatus.Data["mode"]; ok {
|
||||
t.Logf("Performance replication mode: %v", prMode)
|
||||
} else {
|
||||
t.Log("Performance replication mode not available")
|
||||
}
|
||||
}
|
||||
|
||||
t.Log("Successfully verified replication status endpoints are accessible")
|
||||
}
|
||||
|
||||
// TestUIAssets verifies that the Vault UI is accessible
|
||||
func TestUIAssets(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// This is a stub - in a real implementation, you would verify UI assets are accessible
|
||||
// For now, just verify the UI endpoint is available by checking sys/internal/ui/mounts
|
||||
uiMounts := v.MustRead("sys/internal/ui/mounts")
|
||||
if uiMounts == nil || uiMounts.Data == nil {
|
||||
t.Fatal("Could not access UI mounts endpoint")
|
||||
}
|
||||
|
||||
t.Log("Successfully verified UI assets are accessible")
|
||||
}
|
||||
|
||||
// TestLogSecrets is a stub for log secrets verification
|
||||
func TestLogSecrets(t *testing.T) {
|
||||
// This is a stub for log secrets verification
|
||||
// In a real implementation, you would check audit logs for proper secret handling
|
||||
t.Skip("Log secrets verification - implementation pending")
|
||||
}
|
||||
|
||||
// TestNodeRemovalAndRejoin tests raft node removal and rejoin capabilities
|
||||
func TestNodeRemovalAndRejoin(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// This is a stub for node removal and rejoin testing
|
||||
// In a real implementation, you would test raft node removal and rejoin
|
||||
v.AssertClusterHealthy()
|
||||
|
||||
t.Log("Successfully verified raft cluster stability for node operations")
|
||||
}
|
||||
|
||||
// TestBillingOverviewNamespaceRestrictions verifies that sys/billing/overview
|
||||
// returns appropriate errors when called from different namespace levels in HVD.
|
||||
// In HVD, tests run in admin/bbsdk-xxxxx, and this test verifies:
|
||||
// - Calling from base namespace (admin) returns "unsupported path"
|
||||
// - Calling from root namespace (empty) returns "permission denied"
|
||||
func TestBillingOverviewNamespaceRestrictions(t *testing.T) {
|
||||
v := blackbox.New(t)
|
||||
|
||||
// Verify cluster stability first
|
||||
v.AssertClusterHealthy()
|
||||
|
||||
// Check if we're in HVD (has base namespace from VAULT_NAMESPACE)
|
||||
baseNS := v.GetParentNamespace()
|
||||
if baseNS == "" {
|
||||
t.Skip("Skipping namespace restriction tests - no base namespace configured (not in HVD)")
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
namespaceSwitcher func(func() (*api.Secret, error)) (*api.Secret, error)
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
name: "base_namespace_unsupported",
|
||||
namespaceSwitcher: v.WithParentNamespace,
|
||||
expectedError: "unsupported path",
|
||||
},
|
||||
{
|
||||
name: "root_namespace_permission_denied",
|
||||
namespaceSwitcher: v.WithRootNamespace,
|
||||
expectedError: "permission denied",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var rawResp *api.Response
|
||||
var err error
|
||||
_, err = tc.namespaceSwitcher(func() (*api.Secret, error) {
|
||||
var readErr error
|
||||
rawResp, readErr = v.Client.Logical().ReadRawWithContext(context.Background(), "sys/billing/overview")
|
||||
if readErr != nil {
|
||||
return nil, readErr
|
||||
}
|
||||
// Parse the raw response to get the error
|
||||
return v.Client.Logical().ParseRawResponseAndCloseBody(rawResp, nil)
|
||||
})
|
||||
require.ErrorContains(t, err, tc.expectedError)
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user