software steht so weit.
jetzt build + docker build und testen
This commit is contained in:
1 parent
42f0c0accb
commit
ca6cdcca63
90 files changed
+10298
-480
No files matched your search
@@ -0,0 +1,132 @@
|
||||
package license
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var t0 = time.Date(2026, 10, 2, 12, 0, 0, 0, time.UTC)
|
||||
|
||||
const day = 24 * time.Hour
|
||||
|
||||
func noJitter(time.Duration) time.Duration { return 0 }
|
||||
|
||||
func TestLeaseTerms(t *testing.T) {
|
||||
far := t0.AddDate(1, 0, 0)
|
||||
tests := []struct {
|
||||
name string
|
||||
tier Tier
|
||||
maintenance bool
|
||||
licenseUntil time.Time
|
||||
valid, renew time.Duration // relativ zu t0
|
||||
ok bool
|
||||
}{
|
||||
{"community", TierCommunity, false, far, 14 * day, 7 * day, true},
|
||||
{"community ignoriert Vertragsende", TierCommunity, false, t0.Add(day), 14 * day, 7 * day, true},
|
||||
{"pro", TierPro, false, far, 7 * day, 7 * day * 2 / 3, true},
|
||||
{"pro in Wartung", TierPro, true, far, 10 * day, 10 * day * 2 / 3, true},
|
||||
{"enterprise am Vertragsende gekappt", TierEnterprise, false, t0.Add(3 * day), 3 * day, 2 * day, true},
|
||||
{"Vertrag abgelaufen", TierPro, false, t0, 0, 0, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
terms, ok := TermsFor(tt.tier, tt.maintenance, tt.licenseUntil, t0, 0, noJitter)
|
||||
if ok != tt.ok {
|
||||
t.Errorf("%s: ok=%v", tt.name, ok)
|
||||
continue
|
||||
}
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if !terms.ValidUntil.Equal(t0.Add(tt.valid)) || !terms.RenewAfter.Equal(t0.Add(tt.renew)) {
|
||||
t.Errorf("%s: gültig bis +%v, erneuern ab +%v; erwartet +%v / +%v",
|
||||
tt.name, terms.ValidUntil.Sub(t0), terms.RenewAfter.Sub(t0), tt.valid, tt.renew)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Community-Erneuerung gestreut (± 12 h), damit nicht alle Agents gleichzeitig erneuern.
|
||||
func TestLeaseTerms_CommunityJitter(t *testing.T) {
|
||||
var maxSeen time.Duration
|
||||
jitter := func(max time.Duration) time.Duration { maxSeen = max; return -5 * time.Hour }
|
||||
terms, _ := TermsFor(TierCommunity, false, t0.AddDate(1, 0, 0), t0, 0, jitter)
|
||||
if maxSeen != 12*time.Hour {
|
||||
t.Errorf("Streuung ±%v, erwartet ±12h", maxSeen)
|
||||
}
|
||||
if !terms.RenewAfter.Equal(t0.Add(7*day - 5*time.Hour)) {
|
||||
t.Errorf("RenewAfter = +%v", terms.RenewAfter.Sub(t0))
|
||||
}
|
||||
// Ohne explizite Funktion: echte Streuung, aber innerhalb der Grenzen.
|
||||
for range 100 {
|
||||
terms, _ := TermsFor(TierCommunity, false, t0.AddDate(1, 0, 0), t0, 0, nil)
|
||||
if d := terms.RenewAfter.Sub(t0); d < 7*day-12*time.Hour || d > 7*day+12*time.Hour {
|
||||
t.Fatalf("Streuung außerhalb: +%v", d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Override (Tests, Betrieb): feste Laufzeit, Erneuerung nach 2/3, Vertragsende gilt weiter.
|
||||
func TestLeaseTerms_Override(t *testing.T) {
|
||||
terms, ok := TermsFor(TierCommunity, false, t0.AddDate(1, 0, 0), t0, 300*time.Millisecond, noJitter)
|
||||
if !ok || !terms.ValidUntil.Equal(t0.Add(300*time.Millisecond)) || !terms.RenewAfter.Equal(t0.Add(200*time.Millisecond)) {
|
||||
t.Errorf("Override: %+v", terms)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssueAndParseLease(t *testing.T) {
|
||||
iss, pub := newIssuer(t)
|
||||
lic := sample()
|
||||
terms := LeaseTerms{RenewAfter: t0.Add(4 * day), ValidUntil: t0.Add(7 * day)}
|
||||
l, err := iss.IssueLease(lic, "node-1", terms, t0)
|
||||
if err != nil {
|
||||
t.Fatalf("IssueLease: %v", err)
|
||||
}
|
||||
if l.NodeID != "node-1" || l.TenantID != lic.TenantID || !l.IssuedAt.Equal(t0) || !l.ValidUntil.Equal(terms.ValidUntil) ||
|
||||
l.MaxRoutes != lic.MaxRoutes || len(l.AllowedDomains) != 2 {
|
||||
t.Errorf("Lease: %+v", l)
|
||||
}
|
||||
doc, _ := json.Marshal(l)
|
||||
parsed, err := ParseLease(doc, pub)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseLease: %v", err)
|
||||
}
|
||||
if parsed.NodeID != "node-1" || !parsed.ValidUntil.Equal(terms.ValidUntil) {
|
||||
t.Errorf("geparst: %+v", parsed)
|
||||
}
|
||||
if !l.Expired(terms.ValidUntil) || l.Expired(terms.ValidUntil.Add(-time.Second)) {
|
||||
t.Error("Expired falsch")
|
||||
}
|
||||
|
||||
for name, tamper := range map[string]func(*Lease){
|
||||
"Knoten": func(l *Lease) { l.NodeID = "node-2" },
|
||||
"Laufzeit": func(l *Lease) { l.ValidUntil = l.ValidUntil.Add(time.Hour) },
|
||||
"Domains": func(l *Lease) { l.AllowedDomains = append([]string(nil), "bank.de") },
|
||||
"Erneuerung": func(l *Lease) { l.RenewAfter = l.RenewAfter.Add(time.Hour) },
|
||||
} {
|
||||
c := l
|
||||
tamper(&c)
|
||||
if err := c.Verify(pub); !errors.Is(err, ErrInvalidSignature) {
|
||||
t.Errorf("%s manipuliert: %v", name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Domänentrennung: Eine Lease ist keine Lizenz und umgekehrt.
|
||||
func TestLeaseIsNotALicense(t *testing.T) {
|
||||
iss, pub := newIssuer(t)
|
||||
lic, _ := iss.Issue(sample())
|
||||
lease, _ := iss.IssueLease(sample(), "node-1", LeaseTerms{RenewAfter: t0.Add(day), ValidUntil: t0.Add(2 * day)}, t0)
|
||||
|
||||
licDoc, _ := json.Marshal(lic)
|
||||
if _, err := ParseLease(licDoc, pub); err == nil {
|
||||
t.Error("Lizenz als Lease akzeptiert")
|
||||
}
|
||||
asLicense := License{
|
||||
TenantID: lease.TenantID, Tier: lease.Tier, MaxRoutes: lease.MaxRoutes, AllowedDomains: lease.AllowedDomains,
|
||||
Features: lease.Features, ValidUntil: lease.ValidUntil, Signature: lease.Signature,
|
||||
}
|
||||
if err := asLicense.Verify(pub); !errors.Is(err, ErrInvalidSignature) {
|
||||
t.Error("Lease-Signatur als Lizenz-Signatur akzeptiert")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user