Skip to content

Commit 542b0c5

Browse files
authored
Merge pull request #25 from rayprogramming/copilot/implement-server-initialization
Implement server initialization logging and config parsing tests (P1-M1-T2)
2 parents a85f03f + d062c93 commit 542b0c5

File tree

3 files changed

+207
-0
lines changed

3 files changed

+207
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*.dylib
77
*.test
88
*.out
9+
/PackagePulse
10+
PackagePulse
911

1012
# Binary output
1113
PackagePulse

main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ func main() {
3535
logger.Fatal("failed to create server", zap.Error(err))
3636
}
3737

38+
// Log startup message
39+
logger.Info("PackagePulse server initialized",
40+
zap.String("name", cfg.Name),
41+
zap.String("version", cfg.Version),
42+
zap.Bool("cache_enabled", cfg.CacheEnabled))
43+
3844
// Register tools and resources
3945
if err := registerFeatures(srv, logger); err != nil {
4046
logger.Fatal("failed to register features", zap.Error(err))

main_test.go

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
"github.com/rayprogramming/hypermcp"
7+
"github.com/rayprogramming/hypermcp/cache"
8+
"go.uber.org/zap"
9+
)
10+
11+
// TestServerConfigCreation tests the server configuration creation
12+
func TestServerConfigCreation(t *testing.T) {
13+
tests := []struct {
14+
name string
15+
cfg hypermcp.Config
16+
wantError bool
17+
validateFunc func(*testing.T, hypermcp.Config)
18+
}{
19+
{
20+
name: "valid config with cache enabled",
21+
cfg: hypermcp.Config{
22+
Name: "TestServer",
23+
Version: "1.0.0",
24+
CacheEnabled: true,
25+
CacheConfig: cache.Config{
26+
MaxCost: 100 * 1024 * 1024,
27+
NumCounters: 10000,
28+
BufferItems: 64,
29+
},
30+
},
31+
wantError: false,
32+
validateFunc: func(t *testing.T, cfg hypermcp.Config) {
33+
if cfg.Name != "TestServer" {
34+
t.Errorf("Expected Name 'TestServer', got '%s'", cfg.Name)
35+
}
36+
if cfg.Version != "1.0.0" {
37+
t.Errorf("Expected Version '1.0.0', got '%s'", cfg.Version)
38+
}
39+
if !cfg.CacheEnabled {
40+
t.Error("Expected CacheEnabled to be true")
41+
}
42+
if cfg.CacheConfig.MaxCost != 100*1024*1024 {
43+
t.Errorf("Expected MaxCost 104857600, got %d", cfg.CacheConfig.MaxCost)
44+
}
45+
},
46+
},
47+
{
48+
name: "valid config with cache disabled",
49+
cfg: hypermcp.Config{
50+
Name: "PackagePulse",
51+
Version: "2.0.0",
52+
CacheEnabled: false,
53+
},
54+
wantError: false,
55+
validateFunc: func(t *testing.T, cfg hypermcp.Config) {
56+
if cfg.Name != "PackagePulse" {
57+
t.Errorf("Expected Name 'PackagePulse', got '%s'", cfg.Name)
58+
}
59+
if cfg.Version != "2.0.0" {
60+
t.Errorf("Expected Version '2.0.0', got '%s'", cfg.Version)
61+
}
62+
if cfg.CacheEnabled {
63+
t.Error("Expected CacheEnabled to be false")
64+
}
65+
},
66+
},
67+
{
68+
name: "production config matching main.go",
69+
cfg: hypermcp.Config{
70+
Name: "PackagePulse",
71+
Version: "1.0.0",
72+
CacheEnabled: true,
73+
CacheConfig: cache.Config{
74+
MaxCost: 100 * 1024 * 1024,
75+
NumCounters: 10_000,
76+
BufferItems: 64,
77+
},
78+
},
79+
wantError: false,
80+
validateFunc: func(t *testing.T, cfg hypermcp.Config) {
81+
if cfg.Name != "PackagePulse" {
82+
t.Errorf("Expected Name 'PackagePulse', got '%s'", cfg.Name)
83+
}
84+
if cfg.Version != "1.0.0" {
85+
t.Errorf("Expected Version '1.0.0', got '%s'", cfg.Version)
86+
}
87+
if !cfg.CacheEnabled {
88+
t.Error("Expected CacheEnabled to be true")
89+
}
90+
if cfg.CacheConfig.NumCounters != 10000 {
91+
t.Errorf("Expected NumCounters 10000, got %d", cfg.CacheConfig.NumCounters)
92+
}
93+
if cfg.CacheConfig.BufferItems != 64 {
94+
t.Errorf("Expected BufferItems 64, got %d", cfg.CacheConfig.BufferItems)
95+
}
96+
},
97+
},
98+
}
99+
100+
for _, tt := range tests {
101+
t.Run(tt.name, func(t *testing.T) {
102+
// Validate the config structure
103+
if tt.validateFunc != nil {
104+
tt.validateFunc(t, tt.cfg)
105+
}
106+
107+
// Attempt to create server with the config
108+
logger := zap.NewNop()
109+
srv, err := hypermcp.New(tt.cfg, logger)
110+
111+
if (err != nil) != tt.wantError {
112+
t.Errorf("hypermcp.New() error = %v, wantError %v", err, tt.wantError)
113+
return
114+
}
115+
116+
if err == nil && srv == nil {
117+
t.Error("Expected non-nil server when no error")
118+
}
119+
})
120+
}
121+
}
122+
123+
// TestConfigParsing validates that config values are correctly parsed
124+
func TestConfigParsing(t *testing.T) {
125+
t.Run("parse production config", func(t *testing.T) {
126+
// This matches the exact config from main.go
127+
cfg := hypermcp.Config{
128+
Name: "PackagePulse",
129+
Version: "1.0.0",
130+
CacheEnabled: true,
131+
CacheConfig: cache.Config{
132+
MaxCost: 100 * 1024 * 1024, // 100MB
133+
NumCounters: 10_000,
134+
BufferItems: 64,
135+
},
136+
}
137+
138+
// Verify config fields
139+
if cfg.Name == "" {
140+
t.Error("Config Name should not be empty")
141+
}
142+
if cfg.Version == "" {
143+
t.Error("Config Version should not be empty")
144+
}
145+
146+
// Verify cache config when enabled
147+
if cfg.CacheEnabled {
148+
if cfg.CacheConfig.MaxCost <= 0 {
149+
t.Error("CacheConfig.MaxCost should be positive when cache is enabled")
150+
}
151+
if cfg.CacheConfig.NumCounters <= 0 {
152+
t.Error("CacheConfig.NumCounters should be positive when cache is enabled")
153+
}
154+
if cfg.CacheConfig.BufferItems <= 0 {
155+
t.Error("CacheConfig.BufferItems should be positive when cache is enabled")
156+
}
157+
}
158+
159+
t.Logf("Config parsed successfully: Name=%s, Version=%s, CacheEnabled=%v",
160+
cfg.Name, cfg.Version, cfg.CacheEnabled)
161+
})
162+
163+
t.Run("cache size calculation", func(t *testing.T) {
164+
maxCostBytes := 100 * 1024 * 1024
165+
expectedMB := 100
166+
167+
actualMB := maxCostBytes / (1024 * 1024)
168+
if actualMB != expectedMB {
169+
t.Errorf("Expected cache size %dMB, got %dMB", expectedMB, actualMB)
170+
}
171+
})
172+
}
173+
174+
// TestRegisterFeatures tests that feature registration doesn't error
175+
func TestRegisterFeatures(t *testing.T) {
176+
logger := zap.NewNop()
177+
178+
cfg := hypermcp.Config{
179+
Name: "TestServer",
180+
Version: "1.0.0",
181+
CacheEnabled: true,
182+
CacheConfig: cache.Config{
183+
MaxCost: 100 * 1024 * 1024,
184+
NumCounters: 10000,
185+
BufferItems: 64,
186+
},
187+
}
188+
189+
srv, err := hypermcp.New(cfg, logger)
190+
if err != nil {
191+
t.Fatalf("Failed to create server: %v", err)
192+
}
193+
194+
// Test that registerFeatures completes without error
195+
err = registerFeatures(srv, logger)
196+
if err != nil {
197+
t.Errorf("registerFeatures() error = %v, want nil", err)
198+
}
199+
}

0 commit comments

Comments
 (0)