mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-13 22:26:14 +00:00
Mirrors the .md/.txt sweep across all tracked _test.go, testdata XML,
and .http integration files. Test files are self-contained (producer
+ assertion in the same file), so the matched-pair swap stays green
under `go test ./...`.
Mapping applied:
192.168.178.[0-9]+ → 192.0.2.[same]
192.168.1.[0-9]+ → 192.0.2.[same]
Sound Machinechen → Living Room SoundTouch
A Sound Machine → Kitchen SoundTouch
A81B6A536A98 + case/separator variants → AABBCCDDEEFF (etc.)
A81B6A849D99 → AABBCCDDEE01
A81B6A849D88 → AABBCCDDEE03
A81B6A536A09 → AABBCCDDEE04
884AEAEEBD27 → AABBCCDDEE02
3230304 → 1000001
9569497 → 1000002
Two semantic fixes alongside the bulk swap:
- pkg/service/zeroconf/zeroconf_test.go: the "private 192" and
"strips query" cases pin acceptance of RFC-1918 192.168/16. They
must use a real 192.168 value; doc-range IPs would (correctly) be
rejected by validateZcBaseURL. Switched to 192.168.10.10 — generic
enough not to match any home LAN default, real enough for the
validator. Added a comment explaining why this single test still
carries a 192.168 literal.
- pkg/service/setup/setup_test.go: TestTestDNSRedirection mocks the
device's `od -An -tu1` byte output, which is space-separated
octets ("192 168 1 100"). My sed only matched the dot-separated
form, so the mock was returning the old IP while the test
assertions had moved to the doc range. Updated to " 192 0 2 100".
go build ./... clean. go test ./... clean (only TestDocsConsistency
remains failing, which is a pre-existing/untracked-file issue).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
174 lines
4.4 KiB
Go
174 lines
4.4 KiB
Go
package certmanager
|
|
|
|
import (
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestCertificateManager(t *testing.T) {
|
|
tempDir, err := os.MkdirTemp("", "crypto-test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir: %v", err)
|
|
}
|
|
defer os.RemoveAll(tempDir)
|
|
|
|
cm := NewCertificateManager(filepath.Join(tempDir, "certs"))
|
|
cm.CommonName = "test.local"
|
|
|
|
// Test CA generation
|
|
if err := cm.EnsureCA(); err != nil {
|
|
t.Fatalf("Failed to ensure CA: %v", err)
|
|
}
|
|
|
|
if _, err := os.Stat(cm.GetCACertPath()); os.IsNotExist(err) {
|
|
t.Errorf("CA certificate not created")
|
|
}
|
|
if _, err := os.Stat(cm.GetCAKeyPath()); os.IsNotExist(err) {
|
|
t.Errorf("CA key not created")
|
|
}
|
|
|
|
// Test loading CA
|
|
caCertPEM, err := os.ReadFile(cm.GetCACertPath())
|
|
if err != nil {
|
|
t.Fatalf("Failed to read CA cert: %v", err)
|
|
}
|
|
block, _ := pem.Decode(caCertPEM)
|
|
if block == nil || block.Type != "CERTIFICATE" {
|
|
t.Errorf("Invalid CA certificate PEM")
|
|
}
|
|
caCert, err := x509.ParseCertificate(block.Bytes)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse CA cert: %v", err)
|
|
}
|
|
if !caCert.IsCA {
|
|
t.Errorf("Generated certificate is not a CA")
|
|
}
|
|
|
|
// Test certificate generation
|
|
domains := []string{"streaming.bose.com", "updates.bose.com"}
|
|
certPEM, keyPEM, err := cm.GenerateCertificate(domains)
|
|
if err != nil {
|
|
t.Fatalf("Failed to generate certificate: %v", err)
|
|
}
|
|
|
|
if len(certPEM) == 0 || len(keyPEM) == 0 {
|
|
t.Errorf("Generated certificate or key is empty")
|
|
}
|
|
|
|
// Verify generated certificate
|
|
block, _ = pem.Decode(certPEM)
|
|
if block == nil || block.Type != "CERTIFICATE" {
|
|
t.Errorf("Invalid certificate PEM")
|
|
}
|
|
cert, err := x509.ParseCertificate(block.Bytes)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse certificate: %v", err)
|
|
}
|
|
|
|
if cert.Subject.CommonName != cm.CommonName {
|
|
t.Errorf("Expected CommonName %s, got %s", cm.CommonName, cert.Subject.CommonName)
|
|
}
|
|
|
|
// Check DNS names
|
|
if len(cert.DNSNames) != len(domains) {
|
|
t.Errorf("Expected %d DNS names, got %d", len(domains), len(cert.DNSNames))
|
|
}
|
|
|
|
// Verify against CA
|
|
roots := x509.NewCertPool()
|
|
roots.AddCert(caCert)
|
|
opts := x509.VerifyOptions{
|
|
DNSName: domains[0],
|
|
Roots: roots,
|
|
}
|
|
|
|
if _, err := cert.Verify(opts); err != nil {
|
|
t.Errorf("Failed to verify certificate against CA: %v", err)
|
|
}
|
|
|
|
// Test GetServerTLSConfig
|
|
tlsConfig, err := cm.GetServerTLSConfig(domains)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get TLS config: %v", err)
|
|
}
|
|
|
|
if tlsConfig == nil {
|
|
t.Fatal("TLS config is nil")
|
|
}
|
|
|
|
if len(tlsConfig.Certificates) == 0 {
|
|
t.Fatal("TLS config has no certificates")
|
|
}
|
|
|
|
// Test certificate regeneration if domains change
|
|
newDomains := append(domains, "foo.local")
|
|
tlsConfig2, err := cm.GetServerTLSConfig(newDomains)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get updated TLS config: %v", err)
|
|
}
|
|
if len(tlsConfig2.Certificates[0].Leaf.DNSNames) < 3 {
|
|
// Note: tls.LoadX509KeyPair doesn't populate Leaf by default.
|
|
// We should parse it manually or rely on the file existence/content.
|
|
certBytes, _ := os.ReadFile(cm.GetServerCertPEMPath())
|
|
block, _ := pem.Decode(certBytes)
|
|
cert, _ := x509.ParseCertificate(block.Bytes)
|
|
found := false
|
|
for _, d := range cert.DNSNames {
|
|
if d == "foo.local" {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Errorf("Regenerated certificate does not contain new domain")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCertificateManagerIPAddress(t *testing.T) {
|
|
tempDir, err := os.MkdirTemp("", "crypto-ip-test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir: %v", err)
|
|
}
|
|
defer os.RemoveAll(tempDir)
|
|
|
|
cm := NewCertificateManager(filepath.Join(tempDir, "certs"))
|
|
|
|
// Test certificate generation with an IP address
|
|
domains := []string{"192.0.2.100", "localhost"}
|
|
certPEM, _, err := cm.GenerateCertificate(domains)
|
|
if err != nil {
|
|
t.Fatalf("Failed to generate certificate: %v", err)
|
|
}
|
|
|
|
// Verify generated certificate
|
|
block, _ := pem.Decode(certPEM)
|
|
cert, err := x509.ParseCertificate(block.Bytes)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse certificate: %v", err)
|
|
}
|
|
|
|
// Check IP addresses
|
|
foundIP := false
|
|
for _, ip := range cert.IPAddresses {
|
|
if ip.String() == "192.0.2.100" {
|
|
foundIP = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !foundIP {
|
|
t.Errorf("Expected IP address 192.0.2.100 in IPAddresses, but it was not found")
|
|
}
|
|
|
|
// Check if it was mistakenly added to DNSNames
|
|
for _, dns := range cert.DNSNames {
|
|
if dns == "192.0.2.100" {
|
|
t.Errorf("IP address 192.0.2.100 should NOT be in DNSNames")
|
|
}
|
|
}
|
|
}
|