11package config_test
22
33import (
4+ "crypto/rand"
5+ "crypto/rsa"
6+ "crypto/x509"
7+ "encoding/pem"
48 "os"
9+ "sync"
510 "testing"
611 "time"
712
@@ -16,20 +21,22 @@ import (
1621func setValidEnv (t * testing.T ) {
1722 t .Helper ()
1823
24+ privateKeyPEM := generatedTestPrivateKeyPEM (t )
1925 t .Setenv ("ENV" , "local" )
2026 t .Setenv ("MCP_BASE_URL" , "https://mcp.httpsms.com" )
2127 t .Setenv ("HTTPSMS_API_URL" , "https://api.httpsms.com" )
2228 t .Setenv ("REDIS_URL" , "redis://localhost:6379" )
2329 t .Setenv ("FIREBASE_PROJECT_ID" , "httpsms" )
2430 t .Setenv ("FIREBASE_API_KEY" , "test-firebase-api-key" )
2531 t .Setenv ("FIREBASE_AUTH_DOMAIN" , "httpsms.firebaseapp.com" )
26- t .Setenv ("MCP_SIGNING_PRIVATE_KEY" , testPrivateKeyPEM )
32+ t .Setenv ("MCP_SIGNING_PRIVATE_KEY" , privateKeyPEM )
2733 t .Setenv ("MCP_SIGNING_PRIVATE_KEY_FILE" , "" )
2834 t .Setenv ("MCP_SIGNING_KEY_ID" , "test-key-1" )
2935}
3036
3137func TestLoadSucceedsWithAValidEnvironment (t * testing.T ) {
3238 setValidEnv (t )
39+ privateKeyPEM := generatedTestPrivateKeyPEM (t )
3340
3441 cfg , err := config .Load ()
3542
@@ -41,7 +48,7 @@ func TestLoadSucceedsWithAValidEnvironment(t *testing.T) {
4148 assert .Equal (t , "redis://localhost:6379" , cfg .RedisURL )
4249 assert .Equal (t , "httpsms" , cfg .FirebaseProjectID )
4350 assert .Equal (t , "test-key-1" , cfg .SigningKeyID )
44- assert .Equal (t , []byte (testPrivateKeyPEM ), cfg .SigningPrivateKeyPEM )
51+ assert .Equal (t , []byte (privateKeyPEM ), cfg .SigningPrivateKeyPEM )
4552 assert .Equal (t , "https://mcp.httpsms.com/mcp" , cfg .MCPAudience )
4653 assert .Equal (t , "https://api.httpsms.com" , cfg .APIAudience )
4754 assert .Equal (t , 15 * time .Minute , cfg .AccessTokenTTL )
@@ -158,14 +165,15 @@ func TestLoadRejectsMalformedSigningKeyPEM(t *testing.T) {
158165
159166func TestLoadReadsSigningKeyFromFile (t * testing.T ) {
160167 setValidEnv (t )
168+ privateKeyPEM := generatedTestPrivateKeyPEM (t )
161169 t .Setenv ("MCP_SIGNING_PRIVATE_KEY" , "" )
162- keyFile := writeTempKeyFile (t , testPrivateKeyPEM )
170+ keyFile := writeTempKeyFile (t , privateKeyPEM )
163171 t .Setenv ("MCP_SIGNING_PRIVATE_KEY_FILE" , keyFile )
164172
165173 cfg , err := config .Load ()
166174
167175 require .NoError (t , err )
168- assert .Equal (t , []byte (testPrivateKeyPEM ), cfg .SigningPrivateKeyPEM )
176+ assert .Equal (t , []byte (privateKeyPEM ), cfg .SigningPrivateKeyPEM )
169177}
170178
171179func TestLoadRejectsUnreadableSigningKeyFile (t * testing.T ) {
@@ -266,37 +274,31 @@ func TestLoadReportsEveryProblemAtOnce(t *testing.T) {
266274 require .ErrorContains (t , err , "REDIS_URL" )
267275}
268276
269- // testPrivateKeyPEM is a throwaway 2048-bit RSA private key used only to
270- // exercise config.Load's PEM validation. It is not used to sign anything and
271- // is not the same key used by any other package's tests.
272- const testPrivateKeyPEM = `-----BEGIN RSA PRIVATE KEY-----
273- MIIEpAIBAAKCAQEAsaRrsPaMlhkOb2j7UOaCShBBZNZ5nz0AGJq3HHW92Rd+VQ3l
274- /vl1Zed0laz9lUyxWqR6vVR0fuK5reBVaN1GYHV9GgT9x1HM9cTg6eN0n8qpblWo
275- DBKq8Qi4o2D7sNr2tl3SWbrUfKaKnBd6bFRHihJyEZXwc6zCXoPQ7eBQ7ozy99g7
276- nyXtBse5Z5VY563W+hRbqOqHzzZ3qFwDv1Gy0VQZuMz2Paik1cY+XhVIdA2D3pAh
277- UxDxG1TYkBKxsLuM+LmH3HgUGba+Pu9QGYe8PaH5SqGGX3EZxLDyClaaxQgmsZpt
278- KzlwNSZk2sPAvCrYQxto8gelflYPw0jOSX/6EQIDAQABAoIBAEhQrcJZa7vCsXyr
279- GPvDCrEJ0wUwxkwLshlSCk7co49XoAcR5FoaxS7ZvT0dMhHwKZbDtG+UjOQGeh4N
280- X9eTlI255laMR583bp9yKTktbhGKl9ShrApWIx6CNV/VIEDLsnlk0jfS9aNUzMJk
281- UGL/ICxV+/equTrtziZZtNjRY0DolFbo7swFhwey9K4bT7JGl5W+fpRLz3ucjN0z
282- mBU7yI6CAM7YXH0kR4DXSZKiEUZ8xf0fbbraBpjbrA9hTVSWvouEtBJfyIjs6oXy
283- ktchAWydNILqjiQzsNWLI/Vt3PdG9Gs2QT7ZpDxjuOiP7J9CDphDqhLoutD+bHJ8
284- K4i+s/0CgYEAzaRj9KVt8x8IGv68gHShL+4eqXB6MAItLYFlLMDWWo5QK3l7ppFi
285- dwHf3GpAdftQxzCy/R2TARu9oC822DiJJE+8YFci9uIH06adW1nqMPdIorPkvF8Y
286- fKB7Sudw/2ILjeT0wg2AAaDw2VutVvSEpm5j9zA0NSUyKhNYt5thXbcCgYEA3SS7
287- FfFM3EWhsjlKoa6RY6djTZzt7osMGy8u52nqPiFZR7fCbhrxJYROh2UmFn0/J8RB
288- gLoHN4ZbmBze6cro8aTScFmz7cK6bT/eCLq0NopAL+OFP9jGkawo5UMZ7/hfBX8P
289- gMoBD97VkTZw75uAyuVwbKMfPKF6lsFKUMNN5ncCgYEAxawQ3TksAHjC3NgjMMNr
290- sdwOI0fYXE+rR8PLEoLnSbLlA3VKU+oKoWTu4DxObFrA4khAtah5B6a318Oqz5tA
291- 0OPIqz73gCPz7BKLziUXRixd6PBNnnk2242UFoN1Djgb7TC5ydMaSfZ/riA+9ogi
292- /qy8cP8oIDH6D5H7RLsak+8CgYEAiPzY25XXS9fiezmcLp2puHaXQBvHE+6UeD55
293- KqbkkMotuQxu56/O07OqxZp1xpadSa/795bFI7MaCBdSSrcEJ7Q3G5ulptHqlARt
294- MTEes25epoulHlDVaKWhy6sOZSWRDyGPY/M+Ryt9Vm/H89V7KbSJOPKvReqturdP
295- psnk9q8CgYB0knFbkzt3R7mowiiXqj4MhfO4baCPk9PeOslujQIJoX1Ca+/wQdox
296- F2m9w4bRMrdsT19eMrRZsJYslJc6s2tNlCuUDMgFk3FUrmpFDQlq/taUCB/wDUxp
297- 3SBuTr9BHx8yJc9p6hYkjI3HZ+aqsImZIxN/23OFEvtOH2z3m8JPnA==
298- -----END RSA PRIVATE KEY-----
299- `
277+ var (
278+ testPrivateKeyOnce sync.Once
279+ testPrivateKeyPEM string
280+ testPrivateKeyErr error
281+ )
282+
283+ func generatedTestPrivateKeyPEM (t * testing.T ) string {
284+ t .Helper ()
285+
286+ testPrivateKeyOnce .Do (func () {
287+ privateKey , err := rsa .GenerateKey (rand .Reader , 2048 )
288+ if err != nil {
289+ testPrivateKeyErr = err
290+ return
291+ }
292+
293+ testPrivateKeyPEM = string (pem .EncodeToMemory (& pem.Block {
294+ Type : "RSA PRIVATE KEY" ,
295+ Bytes : x509 .MarshalPKCS1PrivateKey (privateKey ),
296+ }))
297+ })
298+
299+ require .NoError (t , testPrivateKeyErr )
300+ return testPrivateKeyPEM
301+ }
300302
301303// writeTempKeyFile writes contents to a new file inside t.TempDir() and
302304// returns its path.
0 commit comments