Files
volt/pkg/license/features_test.go
Karl Clinger 81ad0b597c Volt CLI: source-available under AGPSL v5.0
Complete infrastructure platform CLI:
- Container runtime (systemd-nspawn)
- VoltVisor VMs (Neutron Stardust / QEMU)
- Stellarium CAS (content-addressed storage)
- ORAS Registry
- GitOps integration
- Landlock LSM security
- Compose orchestration
- Mesh networking

Copyright (c) Armored Gates LLC. All rights reserved.
Licensed under AGPSL v5.0
2026-03-21 00:31:12 -05:00

162 lines
5.4 KiB
Go

package license
import (
"testing"
)
// TestCASAvailableInAllTiers verifies the CAS pivot: local CAS must be
// available in Community (free), not just Pro/Enterprise.
func TestCASAvailableInAllTiers(t *testing.T) {
casFeatures := []string{"cas", "cas-pull", "cas-push", "encryption"}
for _, feature := range casFeatures {
for _, tier := range []string{TierCommunity, TierPro, TierEnterprise} {
if !TierIncludes(tier, feature) {
t.Errorf("feature %q must be available in %s tier (CAS pivot requires it)", feature, tier)
}
}
}
}
// TestConstellationsProOnly verifies compose/constellations is gated to Pro+.
func TestConstellationsProOnly(t *testing.T) {
if TierIncludes(TierCommunity, "constellations") {
t.Error("constellations must NOT be in Community tier")
}
if !TierIncludes(TierPro, "constellations") {
t.Error("constellations must be in Pro tier")
}
if !TierIncludes(TierEnterprise, "constellations") {
t.Error("constellations must be in Enterprise tier")
}
}
// TestAdvancedNetworkingProOnly verifies advanced networking is gated to Pro+.
func TestAdvancedNetworkingProOnly(t *testing.T) {
// Basic networking is Community
if !TierIncludes(TierCommunity, "networking-basic") {
t.Error("networking-basic must be in Community tier")
}
// Advanced networking is Pro+
if TierIncludes(TierCommunity, "networking") {
t.Error("advanced networking must NOT be in Community tier")
}
if !TierIncludes(TierPro, "networking") {
t.Error("advanced networking must be in Pro tier")
}
}
// TestDistributedCASNotInCommunity verifies distributed CAS is still gated to Pro+.
func TestDistributedCASNotInCommunity(t *testing.T) {
proOnlyCAS := []string{"cas-distributed", "cas-retention", "cas-analytics"}
for _, feature := range proOnlyCAS {
if TierIncludes(TierCommunity, feature) {
t.Errorf("feature %q must NOT be in Community tier (distributed CAS is Pro+)", feature)
}
if !TierIncludes(TierPro, feature) {
t.Errorf("feature %q must be in Pro tier", feature)
}
if !TierIncludes(TierEnterprise, feature) {
t.Errorf("feature %q must be in Enterprise tier", feature)
}
}
}
// TestEnterpriseCASNotInProOrCommunity verifies enterprise CAS features are gated.
func TestEnterpriseCASNotInProOrCommunity(t *testing.T) {
enterpriseOnly := []string{"cas-cross-region", "cas-audit", "encryption-hsm"}
for _, feature := range enterpriseOnly {
if TierIncludes(TierCommunity, feature) {
t.Errorf("feature %q must NOT be in Community tier", feature)
}
if TierIncludes(TierPro, feature) {
t.Errorf("feature %q must NOT be in Pro tier (Enterprise only)", feature)
}
if !TierIncludes(TierEnterprise, feature) {
t.Errorf("feature %q must be in Enterprise tier", feature)
}
}
}
// TestVMsStillProOnly verifies VoltVisor is not in Community.
func TestVMsStillProOnly(t *testing.T) {
if TierIncludes(TierCommunity, "vms") {
t.Error("VoltVisor (vms) must NOT be in Community tier")
}
if !TierIncludes(TierPro, "vms") {
t.Error("VoltVisor (vms) must be in Pro tier")
}
if !TierIncludes(TierEnterprise, "vms") {
t.Error("VoltVisor (vms) must be in Enterprise tier")
}
}
// TestBYOKNotInCommunity verifies BYOK is Pro+.
func TestBYOKNotInCommunity(t *testing.T) {
if TierIncludes(TierCommunity, "encryption-byok") {
t.Error("BYOK encryption must NOT be in Community tier")
}
if !TierIncludes(TierPro, "encryption-byok") {
t.Error("BYOK encryption must be in Pro tier")
}
}
// TestCommunityContainerLimit verifies the 50/node limit for Community.
func TestCommunityContainerLimit(t *testing.T) {
if MaxContainersPerNode(TierCommunity) != 50 {
t.Errorf("Community container limit should be 50, got %d", MaxContainersPerNode(TierCommunity))
}
if MaxContainersPerNode(TierPro) != 500 {
t.Errorf("Pro container limit should be 500, got %d", MaxContainersPerNode(TierPro))
}
if MaxContainersPerNode(TierEnterprise) != 0 {
t.Errorf("Enterprise container limit should be 0 (unlimited), got %d", MaxContainersPerNode(TierEnterprise))
}
}
// TestTierIncludesUnknownTier verifies unknown tiers return false.
func TestTierIncludesUnknownTier(t *testing.T) {
if TierIncludes("unknown", "cas") {
t.Error("unknown tier should not include any features")
}
}
// TestFeatureCountProgression verifies each higher tier has more features.
func TestFeatureCountProgression(t *testing.T) {
community := FeatureCount(TierCommunity)
pro := FeatureCount(TierPro)
enterprise := FeatureCount(TierEnterprise)
if pro <= community {
t.Errorf("Pro (%d features) should have more features than Community (%d)", pro, community)
}
if enterprise <= pro {
t.Errorf("Enterprise (%d features) should have more features than Pro (%d)", enterprise, pro)
}
}
// TestAllCommunityFeaturesInHigherTiers verifies tier inclusion is hierarchical.
func TestAllCommunityFeaturesInHigherTiers(t *testing.T) {
communityFeatures := TierFeatures[TierCommunity]
for _, f := range communityFeatures {
if !TierIncludes(TierPro, f) {
t.Errorf("Community feature %q missing from Pro tier", f)
}
if !TierIncludes(TierEnterprise, f) {
t.Errorf("Community feature %q missing from Enterprise tier", f)
}
}
}
// TestAllProFeaturesInEnterprise verifies Pro features are in Enterprise.
func TestAllProFeaturesInEnterprise(t *testing.T) {
proFeatures := TierFeatures[TierPro]
for _, f := range proFeatures {
if !TierIncludes(TierEnterprise, f) {
t.Errorf("Pro feature %q missing from Enterprise tier", f)
}
}
}