From 88aa07c041b8a3ca4567941f06f1dab9e210cde3 Mon Sep 17 00:00:00 2001 From: Vault Automation Date: Mon, 30 Mar 2026 10:09:53 -0600 Subject: [PATCH] (enos) Improve Blackbox SDK Filtering and Test Organization (#13350) (#13490) * reorganize the blackbox structure * mend * organize by directories * respond to feedback: * Formatting * whitespace * default testnames * local * nullcheck Co-authored-by: Luis (LT) Carbonell --- enos/enos-scenario-plugin.hcl | 22 ++- enos/enos-scenario-smoke-sdk.hcl | 40 ++-- enos/enos-variables.hcl | 6 + enos/modules/vault_run_blackbox_test/main.tf | 12 +- .../vault_run_blackbox_test/outputs.tf | 2 +- .../scripts/run-test.sh | 7 +- .../blackbox/{ => auth}/auth_engines_test.go | 2 +- .../blackbox/{ => auth}/auth_userpass_test.go | 7 +- .../blackbox/core/license_test.go | 25 +++ vault/external_tests/blackbox/core/ui_test.go | 24 +++ .../blackbox/core/unsealed_test.go | 21 +++ .../blackbox/core/version_test.go | 23 +++ .../external_secrets_test.go} | 2 +- .../blackbox/{ => integration}/smoke_test.go | 2 +- .../blackbox/{ => integration}/token_test.go | 29 ++- .../blackbox/plugin/plugin_test.go | 12 -- .../blackbox/{ => plugins}/ldap/helpers.go | 2 +- .../ldap/secrets_ldap_dynamic_audit_test.go | 2 +- .../secrets_ldap_dynamic_deletion_test.go | 2 +- .../ldap/secrets_ldap_dynamic_roles_test.go | 2 +- .../secrets_ldap_dynamic_rollback_test.go | 2 +- ...rets_ldap_root_credential_rollback_test.go | 2 +- .../{ => plugins}/ldap/secrets_ldap_test.go | 2 +- .../ldap/testdata/dynamic_deletion.ldif | 0 .../ldap/testdata/dynamic_rollback.ldif | 0 .../blackbox/raft/node_operations_test.go | 21 +++ .../blackbox/raft/voters_test.go | 20 ++ .../blackbox/replication/status_test.go | 40 ++++ .../engines_test.go} | 2 +- .../{ => secrets}/secrets_aws_test.go | 2 +- .../{ => secrets}/secrets_identity_test.go | 2 +- .../{ => secrets}/secrets_kmip_test.go | 2 +- .../blackbox/{ => secrets}/secrets_kv_test.go | 21 ++- .../{ => secrets}/secrets_ldap_test.go | 2 +- .../{ => secrets}/secrets_pki_test.go | 2 +- .../{ => secrets}/secrets_ssh_test.go | 2 +- .../{ => secrets}/secrets_transit_test.go | 2 +- .../blackbox/system/billing_test.go | 65 +++++++ vault/external_tests/blackbox/system_test.go | 175 ------------------ 39 files changed, 341 insertions(+), 267 deletions(-) rename vault/external_tests/blackbox/{ => auth}/auth_engines_test.go (99%) rename vault/external_tests/blackbox/{ => auth}/auth_userpass_test.go (92%) create mode 100644 vault/external_tests/blackbox/core/license_test.go create mode 100644 vault/external_tests/blackbox/core/ui_test.go create mode 100644 vault/external_tests/blackbox/core/unsealed_test.go create mode 100644 vault/external_tests/blackbox/core/version_test.go rename vault/external_tests/blackbox/{secrets_engines_external_test.go => integration/external_secrets_test.go} (98%) rename vault/external_tests/blackbox/{ => integration}/smoke_test.go (99%) rename vault/external_tests/blackbox/{ => integration}/token_test.go (53%) delete mode 100644 vault/external_tests/blackbox/plugin/plugin_test.go rename vault/external_tests/blackbox/{ => plugins}/ldap/helpers.go (99%) rename vault/external_tests/blackbox/{ => plugins}/ldap/secrets_ldap_dynamic_audit_test.go (98%) rename vault/external_tests/blackbox/{ => plugins}/ldap/secrets_ldap_dynamic_deletion_test.go (99%) rename vault/external_tests/blackbox/{ => plugins}/ldap/secrets_ldap_dynamic_roles_test.go (99%) rename vault/external_tests/blackbox/{ => plugins}/ldap/secrets_ldap_dynamic_rollback_test.go (98%) rename vault/external_tests/blackbox/{ => plugins}/ldap/secrets_ldap_root_credential_rollback_test.go (99%) rename vault/external_tests/blackbox/{ => plugins}/ldap/secrets_ldap_test.go (99%) rename vault/external_tests/blackbox/{ => plugins}/ldap/testdata/dynamic_deletion.ldif (100%) rename vault/external_tests/blackbox/{ => plugins}/ldap/testdata/dynamic_rollback.ldif (100%) create mode 100644 vault/external_tests/blackbox/raft/node_operations_test.go create mode 100644 vault/external_tests/blackbox/raft/voters_test.go create mode 100644 vault/external_tests/blackbox/replication/status_test.go rename vault/external_tests/blackbox/{secrets_engines_test.go => secrets/engines_test.go} (99%) rename vault/external_tests/blackbox/{ => secrets}/secrets_aws_test.go (99%) rename vault/external_tests/blackbox/{ => secrets}/secrets_identity_test.go (99%) rename vault/external_tests/blackbox/{ => secrets}/secrets_kmip_test.go (99%) rename vault/external_tests/blackbox/{ => secrets}/secrets_kv_test.go (67%) rename vault/external_tests/blackbox/{ => secrets}/secrets_ldap_test.go (99%) rename vault/external_tests/blackbox/{ => secrets}/secrets_pki_test.go (99%) rename vault/external_tests/blackbox/{ => secrets}/secrets_ssh_test.go (99%) rename vault/external_tests/blackbox/{ => secrets}/secrets_transit_test.go (99%) create mode 100644 vault/external_tests/blackbox/system/billing_test.go delete mode 100644 vault/external_tests/blackbox/system_test.go diff --git a/enos/enos-scenario-plugin.hcl b/enos/enos-scenario-plugin.hcl index 216de3788c..35f035ecb6 100644 --- a/enos/enos-scenario-plugin.hcl +++ b/enos/enos-scenario-plugin.hcl @@ -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 } diff --git a/enos/enos-scenario-smoke-sdk.hcl b/enos/enos-scenario-smoke-sdk.hcl index e8412f9500..f8a96e678b 100644 --- a/enos/enos-scenario-smoke-sdk.hcl +++ b/enos/enos-scenario-smoke-sdk.hcl @@ -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 } diff --git a/enos/enos-variables.hcl b/enos/enos-variables.hcl index b20bf023e3..449f29cbab 100644 --- a/enos/enos-variables.hcl +++ b/enos/enos-variables.hcl @@ -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 diff --git a/enos/modules/vault_run_blackbox_test/main.tf b/enos/modules/vault_run_blackbox_test/main.tf index f7d3f9da4f..22f97c87d2 100644 --- a/enos/modules/vault_run_blackbox_test/main.tf +++ b/enos/modules/vault_run_blackbox_test/main.tf @@ -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 ? { diff --git a/enos/modules/vault_run_blackbox_test/outputs.tf b/enos/modules/vault_run_blackbox_test/outputs.tf index 870103e9ab..c22f750712 100644 --- a/enos/modules/vault_run_blackbox_test/outputs.tf +++ b/enos/modules/vault_run_blackbox_test/outputs.tf @@ -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 } } diff --git a/enos/modules/vault_run_blackbox_test/scripts/run-test.sh b/enos/modules/vault_run_blackbox_test/scripts/run-test.sh index 5a91e3854c..41cb680383 100755 --- a/enos/modules/vault_run_blackbox_test/scripts/run-test.sh +++ b/enos/modules/vault_run_blackbox_test/scripts/run-test.sh @@ -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 diff --git a/vault/external_tests/blackbox/auth_engines_test.go b/vault/external_tests/blackbox/auth/auth_engines_test.go similarity index 99% rename from vault/external_tests/blackbox/auth_engines_test.go rename to vault/external_tests/blackbox/auth/auth_engines_test.go index 9e9483ad90..4b506b7e4e 100644 --- a/vault/external_tests/blackbox/auth_engines_test.go +++ b/vault/external_tests/blackbox/auth/auth_engines_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package auth import ( "testing" diff --git a/vault/external_tests/blackbox/auth_userpass_test.go b/vault/external_tests/blackbox/auth/auth_userpass_test.go similarity index 92% rename from vault/external_tests/blackbox/auth_userpass_test.go rename to vault/external_tests/blackbox/auth/auth_userpass_test.go index efdcee300f..9985f85a92 100644 --- a/vault/external_tests/blackbox/auth_userpass_test.go +++ b/vault/external_tests/blackbox/auth/auth_userpass_test.go @@ -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") diff --git a/vault/external_tests/blackbox/core/license_test.go b/vault/external_tests/blackbox/core/license_test.go new file mode 100644 index 0000000000..e1472caabd --- /dev/null +++ b/vault/external_tests/blackbox/core/license_test.go @@ -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") + } +} diff --git a/vault/external_tests/blackbox/core/ui_test.go b/vault/external_tests/blackbox/core/ui_test.go new file mode 100644 index 0000000000..2c4d73ce49 --- /dev/null +++ b/vault/external_tests/blackbox/core/ui_test.go @@ -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") +} diff --git a/vault/external_tests/blackbox/core/unsealed_test.go b/vault/external_tests/blackbox/core/unsealed_test.go new file mode 100644 index 0000000000..accea7ecff --- /dev/null +++ b/vault/external_tests/blackbox/core/unsealed_test.go @@ -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") +} diff --git a/vault/external_tests/blackbox/core/version_test.go b/vault/external_tests/blackbox/core/version_test.go new file mode 100644 index 0000000000..0d82faa68c --- /dev/null +++ b/vault/external_tests/blackbox/core/version_test.go @@ -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"]) +} diff --git a/vault/external_tests/blackbox/secrets_engines_external_test.go b/vault/external_tests/blackbox/integration/external_secrets_test.go similarity index 98% rename from vault/external_tests/blackbox/secrets_engines_external_test.go rename to vault/external_tests/blackbox/integration/external_secrets_test.go index baba4e3a9f..2e0fcab614 100644 --- a/vault/external_tests/blackbox/secrets_engines_external_test.go +++ b/vault/external_tests/blackbox/integration/external_secrets_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package integration import ( "testing" diff --git a/vault/external_tests/blackbox/smoke_test.go b/vault/external_tests/blackbox/integration/smoke_test.go similarity index 99% rename from vault/external_tests/blackbox/smoke_test.go rename to vault/external_tests/blackbox/integration/smoke_test.go index 88692d23e9..10848c03a5 100644 --- a/vault/external_tests/blackbox/smoke_test.go +++ b/vault/external_tests/blackbox/integration/smoke_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package integration import ( "testing" diff --git a/vault/external_tests/blackbox/token_test.go b/vault/external_tests/blackbox/integration/token_test.go similarity index 53% rename from vault/external_tests/blackbox/token_test.go rename to vault/external_tests/blackbox/integration/token_test.go index 199fb73477..0112c30070 100644 --- a/vault/external_tests/blackbox/token_test.go +++ b/vault/external_tests/blackbox/integration/token_test.go @@ -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"}) diff --git a/vault/external_tests/blackbox/plugin/plugin_test.go b/vault/external_tests/blackbox/plugin/plugin_test.go deleted file mode 100644 index e42982d3ea..0000000000 --- a/vault/external_tests/blackbox/plugin/plugin_test.go +++ /dev/null @@ -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 -} diff --git a/vault/external_tests/blackbox/ldap/helpers.go b/vault/external_tests/blackbox/plugins/ldap/helpers.go similarity index 99% rename from vault/external_tests/blackbox/ldap/helpers.go rename to vault/external_tests/blackbox/plugins/ldap/helpers.go index 5566e39841..18c94ba66c 100644 --- a/vault/external_tests/blackbox/ldap/helpers.go +++ b/vault/external_tests/blackbox/plugins/ldap/helpers.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package ldap import ( "bytes" diff --git a/vault/external_tests/blackbox/ldap/secrets_ldap_dynamic_audit_test.go b/vault/external_tests/blackbox/plugins/ldap/secrets_ldap_dynamic_audit_test.go similarity index 98% rename from vault/external_tests/blackbox/ldap/secrets_ldap_dynamic_audit_test.go rename to vault/external_tests/blackbox/plugins/ldap/secrets_ldap_dynamic_audit_test.go index f0b9c11235..5833bcbc10 100644 --- a/vault/external_tests/blackbox/ldap/secrets_ldap_dynamic_audit_test.go +++ b/vault/external_tests/blackbox/plugins/ldap/secrets_ldap_dynamic_audit_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package ldap import ( "testing" diff --git a/vault/external_tests/blackbox/ldap/secrets_ldap_dynamic_deletion_test.go b/vault/external_tests/blackbox/plugins/ldap/secrets_ldap_dynamic_deletion_test.go similarity index 99% rename from vault/external_tests/blackbox/ldap/secrets_ldap_dynamic_deletion_test.go rename to vault/external_tests/blackbox/plugins/ldap/secrets_ldap_dynamic_deletion_test.go index 0644ef85f8..41d6afa4bd 100644 --- a/vault/external_tests/blackbox/ldap/secrets_ldap_dynamic_deletion_test.go +++ b/vault/external_tests/blackbox/plugins/ldap/secrets_ldap_dynamic_deletion_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package ldap import ( "testing" diff --git a/vault/external_tests/blackbox/ldap/secrets_ldap_dynamic_roles_test.go b/vault/external_tests/blackbox/plugins/ldap/secrets_ldap_dynamic_roles_test.go similarity index 99% rename from vault/external_tests/blackbox/ldap/secrets_ldap_dynamic_roles_test.go rename to vault/external_tests/blackbox/plugins/ldap/secrets_ldap_dynamic_roles_test.go index 7fb49b4d9d..60385f60e7 100644 --- a/vault/external_tests/blackbox/ldap/secrets_ldap_dynamic_roles_test.go +++ b/vault/external_tests/blackbox/plugins/ldap/secrets_ldap_dynamic_roles_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package ldap import ( "testing" diff --git a/vault/external_tests/blackbox/ldap/secrets_ldap_dynamic_rollback_test.go b/vault/external_tests/blackbox/plugins/ldap/secrets_ldap_dynamic_rollback_test.go similarity index 98% rename from vault/external_tests/blackbox/ldap/secrets_ldap_dynamic_rollback_test.go rename to vault/external_tests/blackbox/plugins/ldap/secrets_ldap_dynamic_rollback_test.go index d27851d6b9..3562f0ebbd 100644 --- a/vault/external_tests/blackbox/ldap/secrets_ldap_dynamic_rollback_test.go +++ b/vault/external_tests/blackbox/plugins/ldap/secrets_ldap_dynamic_rollback_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package ldap import ( "testing" diff --git a/vault/external_tests/blackbox/ldap/secrets_ldap_root_credential_rollback_test.go b/vault/external_tests/blackbox/plugins/ldap/secrets_ldap_root_credential_rollback_test.go similarity index 99% rename from vault/external_tests/blackbox/ldap/secrets_ldap_root_credential_rollback_test.go rename to vault/external_tests/blackbox/plugins/ldap/secrets_ldap_root_credential_rollback_test.go index c74d768bb4..8bd3a36930 100644 --- a/vault/external_tests/blackbox/ldap/secrets_ldap_root_credential_rollback_test.go +++ b/vault/external_tests/blackbox/plugins/ldap/secrets_ldap_root_credential_rollback_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package ldap import ( "fmt" diff --git a/vault/external_tests/blackbox/ldap/secrets_ldap_test.go b/vault/external_tests/blackbox/plugins/ldap/secrets_ldap_test.go similarity index 99% rename from vault/external_tests/blackbox/ldap/secrets_ldap_test.go rename to vault/external_tests/blackbox/plugins/ldap/secrets_ldap_test.go index 183bd47447..83622b993f 100644 --- a/vault/external_tests/blackbox/ldap/secrets_ldap_test.go +++ b/vault/external_tests/blackbox/plugins/ldap/secrets_ldap_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package ldap import ( "testing" diff --git a/vault/external_tests/blackbox/ldap/testdata/dynamic_deletion.ldif b/vault/external_tests/blackbox/plugins/ldap/testdata/dynamic_deletion.ldif similarity index 100% rename from vault/external_tests/blackbox/ldap/testdata/dynamic_deletion.ldif rename to vault/external_tests/blackbox/plugins/ldap/testdata/dynamic_deletion.ldif diff --git a/vault/external_tests/blackbox/ldap/testdata/dynamic_rollback.ldif b/vault/external_tests/blackbox/plugins/ldap/testdata/dynamic_rollback.ldif similarity index 100% rename from vault/external_tests/blackbox/ldap/testdata/dynamic_rollback.ldif rename to vault/external_tests/blackbox/plugins/ldap/testdata/dynamic_rollback.ldif diff --git a/vault/external_tests/blackbox/raft/node_operations_test.go b/vault/external_tests/blackbox/raft/node_operations_test.go new file mode 100644 index 0000000000..dad9346146 --- /dev/null +++ b/vault/external_tests/blackbox/raft/node_operations_test.go @@ -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") +} diff --git a/vault/external_tests/blackbox/raft/voters_test.go b/vault/external_tests/blackbox/raft/voters_test.go new file mode 100644 index 0000000000..21280fe3b7 --- /dev/null +++ b/vault/external_tests/blackbox/raft/voters_test.go @@ -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") +} diff --git a/vault/external_tests/blackbox/replication/status_test.go b/vault/external_tests/blackbox/replication/status_test.go new file mode 100644 index 0000000000..40a5bd5885 --- /dev/null +++ b/vault/external_tests/blackbox/replication/status_test.go @@ -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") +} diff --git a/vault/external_tests/blackbox/secrets_engines_test.go b/vault/external_tests/blackbox/secrets/engines_test.go similarity index 99% rename from vault/external_tests/blackbox/secrets_engines_test.go rename to vault/external_tests/blackbox/secrets/engines_test.go index 896ce5582c..af88e6b312 100644 --- a/vault/external_tests/blackbox/secrets_engines_test.go +++ b/vault/external_tests/blackbox/secrets/engines_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package secrets import ( "testing" diff --git a/vault/external_tests/blackbox/secrets_aws_test.go b/vault/external_tests/blackbox/secrets/secrets_aws_test.go similarity index 99% rename from vault/external_tests/blackbox/secrets_aws_test.go rename to vault/external_tests/blackbox/secrets/secrets_aws_test.go index 040fe0a13e..829cfd2066 100644 --- a/vault/external_tests/blackbox/secrets_aws_test.go +++ b/vault/external_tests/blackbox/secrets/secrets_aws_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package secrets import ( "os" diff --git a/vault/external_tests/blackbox/secrets_identity_test.go b/vault/external_tests/blackbox/secrets/secrets_identity_test.go similarity index 99% rename from vault/external_tests/blackbox/secrets_identity_test.go rename to vault/external_tests/blackbox/secrets/secrets_identity_test.go index b1acbf1f9b..6c91c42e78 100644 --- a/vault/external_tests/blackbox/secrets_identity_test.go +++ b/vault/external_tests/blackbox/secrets/secrets_identity_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package secrets import ( "testing" diff --git a/vault/external_tests/blackbox/secrets_kmip_test.go b/vault/external_tests/blackbox/secrets/secrets_kmip_test.go similarity index 99% rename from vault/external_tests/blackbox/secrets_kmip_test.go rename to vault/external_tests/blackbox/secrets/secrets_kmip_test.go index a4db4a0e12..3ee092683c 100644 --- a/vault/external_tests/blackbox/secrets_kmip_test.go +++ b/vault/external_tests/blackbox/secrets/secrets_kmip_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package secrets import ( "os" diff --git a/vault/external_tests/blackbox/secrets_kv_test.go b/vault/external_tests/blackbox/secrets/secrets_kv_test.go similarity index 67% rename from vault/external_tests/blackbox/secrets_kv_test.go rename to vault/external_tests/blackbox/secrets/secrets_kv_test.go index 08faa648ba..af99c8c979 100644 --- a/vault/external_tests/blackbox/secrets_kv_test.go +++ b/vault/external_tests/blackbox/secrets/secrets_kv_test.go @@ -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}, }) diff --git a/vault/external_tests/blackbox/secrets_ldap_test.go b/vault/external_tests/blackbox/secrets/secrets_ldap_test.go similarity index 99% rename from vault/external_tests/blackbox/secrets_ldap_test.go rename to vault/external_tests/blackbox/secrets/secrets_ldap_test.go index a76ac89eba..c8897a9cf3 100644 --- a/vault/external_tests/blackbox/secrets_ldap_test.go +++ b/vault/external_tests/blackbox/secrets/secrets_ldap_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package secrets import ( "net" diff --git a/vault/external_tests/blackbox/secrets_pki_test.go b/vault/external_tests/blackbox/secrets/secrets_pki_test.go similarity index 99% rename from vault/external_tests/blackbox/secrets_pki_test.go rename to vault/external_tests/blackbox/secrets/secrets_pki_test.go index e30a72689d..eb5418242e 100644 --- a/vault/external_tests/blackbox/secrets_pki_test.go +++ b/vault/external_tests/blackbox/secrets/secrets_pki_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package secrets import ( "testing" diff --git a/vault/external_tests/blackbox/secrets_ssh_test.go b/vault/external_tests/blackbox/secrets/secrets_ssh_test.go similarity index 99% rename from vault/external_tests/blackbox/secrets_ssh_test.go rename to vault/external_tests/blackbox/secrets/secrets_ssh_test.go index 5d4b39b69e..716c87cc25 100644 --- a/vault/external_tests/blackbox/secrets_ssh_test.go +++ b/vault/external_tests/blackbox/secrets/secrets_ssh_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package secrets import ( "testing" diff --git a/vault/external_tests/blackbox/secrets_transit_test.go b/vault/external_tests/blackbox/secrets/secrets_transit_test.go similarity index 99% rename from vault/external_tests/blackbox/secrets_transit_test.go rename to vault/external_tests/blackbox/secrets/secrets_transit_test.go index dc95f1fb7d..8130366128 100644 --- a/vault/external_tests/blackbox/secrets_transit_test.go +++ b/vault/external_tests/blackbox/secrets/secrets_transit_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2025, 2026 // SPDX-License-Identifier: BUSL-1.1 -package blackbox +package secrets import ( "testing" diff --git a/vault/external_tests/blackbox/system/billing_test.go b/vault/external_tests/blackbox/system/billing_test.go new file mode 100644 index 0000000000..8251732117 --- /dev/null +++ b/vault/external_tests/blackbox/system/billing_test.go @@ -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) + }) + } +} diff --git a/vault/external_tests/blackbox/system_test.go b/vault/external_tests/blackbox/system_test.go deleted file mode 100644 index a24750e4c4..0000000000 --- a/vault/external_tests/blackbox/system_test.go +++ /dev/null @@ -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) - }) - } -}