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) } } }