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
This commit is contained in:
161
pkg/license/features_test.go
Normal file
161
pkg/license/features_test.go
Normal file
@@ -0,0 +1,161 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user