@@ -2,9 +2,11 @@ package main
2
2
3
3
import (
4
4
"encoding/json"
5
+ "log/slog"
5
6
"os"
6
7
"path/filepath"
7
8
"reflect"
9
+ "strings"
8
10
"testing"
9
11
)
10
12
@@ -156,7 +158,7 @@ func TestConvertToMCPClientConfig(t *testing.T) {
156
158
want * MCPClientConfig
157
159
}{
158
160
{
159
- name : "基本的な変換 " ,
161
+ name : "Basic conversion " ,
160
162
serverCfg : ServerConfig {
161
163
Command : "test-command" ,
162
164
Args : []string {"arg1" , "arg2" },
@@ -169,7 +171,7 @@ func TestConvertToMCPClientConfig(t *testing.T) {
169
171
},
170
172
},
171
173
{
172
- name : "空の値を持つ設定 " ,
174
+ name : "Empty values " ,
173
175
serverCfg : ServerConfig {
174
176
Command : "" ,
175
177
Args : []string {},
@@ -216,3 +218,134 @@ func TestMCPClientConfigSerialization(t *testing.T) {
216
218
t .Errorf ("Data does not match after JSON round-trip. Original: %v, Result: %v" , original , jsonDeserialized )
217
219
}
218
220
}
221
+
222
+ // TestLogConfig tests secure logging functionality for environment variables
223
+ func TestLogConfig (t * testing.T ) {
224
+ // Create test environment variables map
225
+ testEnv := map [string ]string {
226
+ "API_KEY" : "secret-api-key-123" ,
227
+ "DATABASE_URL" : "postgres://user:password@localhost:5432/db" ,
228
+ "DEBUG" : "true" ,
229
+ }
230
+
231
+ // Prepare buffer to capture log output
232
+ var logBuffer strings.Builder
233
+ testHandler := slog .NewTextHandler (& logBuffer , & slog.HandlerOptions {
234
+ Level : slog .LevelDebug ,
235
+ })
236
+ testLogger := slog .New (testHandler )
237
+
238
+ // Execute the function under test
239
+ LogConfig (testLogger , "test-server" , testEnv )
240
+
241
+ // Verify log output
242
+ logOutput := logBuffer .String ()
243
+
244
+ // Verify each environment variable key is present in logs
245
+ for key := range testEnv {
246
+ if ! strings .Contains (logOutput , key ) {
247
+ t .Errorf ("Log output doesn't contain key %s" , key )
248
+ }
249
+ }
250
+
251
+ // Verify actual values (sensitive info) are not present in logs
252
+ for _ , value := range testEnv {
253
+ if strings .Contains (logOutput , value ) {
254
+ t .Errorf ("Log output contains raw sensitive value: %s" , value )
255
+ }
256
+ }
257
+
258
+ // Verify checksum format (generic check since implementation dependent)
259
+ if ! strings .Contains (logOutput , "value_checksum=" ) {
260
+ t .Errorf ("Log output doesn't contain checksums" )
261
+ }
262
+
263
+ // Verify server name is correctly included in logs
264
+ if ! strings .Contains (logOutput , "test-server" ) {
265
+ t .Errorf ("Log output doesn't contain server name" )
266
+ }
267
+ }
268
+
269
+ // TestLogConfigConsistency tests the consistency of checksum calculation
270
+ func TestLogConfigConsistency (t * testing.T ) {
271
+ // Capture and compare multiple log outputs for the same value
272
+ testValue := "very-secret-password"
273
+ testEnv := map [string ]string {
274
+ "TEST_SECRET" : testValue ,
275
+ }
276
+
277
+ // First log output
278
+ var logBuffer1 strings.Builder
279
+ testHandler1 := slog .NewTextHandler (& logBuffer1 , & slog.HandlerOptions {
280
+ Level : slog .LevelDebug ,
281
+ })
282
+ testLogger1 := slog .New (testHandler1 )
283
+ LogConfig (testLogger1 , "test-server" , testEnv )
284
+ logOutput1 := logBuffer1 .String ()
285
+
286
+ // Second log output
287
+ var logBuffer2 strings.Builder
288
+ testHandler2 := slog .NewTextHandler (& logBuffer2 , & slog.HandlerOptions {
289
+ Level : slog .LevelDebug ,
290
+ })
291
+ testLogger2 := slog .New (testHandler2 )
292
+ LogConfig (testLogger2 , "test-server" , testEnv )
293
+ logOutput2 := logBuffer2 .String ()
294
+
295
+ // Extract checksum from log outputs
296
+ checksum1 := extractChecksum (logOutput1 )
297
+ checksum2 := extractChecksum (logOutput2 )
298
+
299
+ // Verify same checksum is generated for same value
300
+ if checksum1 == "" || checksum2 == "" {
301
+ t .Errorf ("Failed to extract checksums from log output" )
302
+ } else if checksum1 != checksum2 {
303
+ t .Errorf ("Checksum calculation is not consistent: %s != %s" , checksum1 , checksum2 )
304
+ }
305
+
306
+ // Verify different checksum is generated when value changes
307
+ testEnvModified := map [string ]string {
308
+ "TEST_SECRET" : testValue + "-modified" ,
309
+ }
310
+
311
+ var logBuffer3 strings.Builder
312
+ testHandler3 := slog .NewTextHandler (& logBuffer3 , & slog.HandlerOptions {
313
+ Level : slog .LevelDebug ,
314
+ })
315
+ testLogger3 := slog .New (testHandler3 )
316
+ LogConfig (testLogger3 , "test-server" , testEnvModified )
317
+ logOutput3 := logBuffer3 .String ()
318
+
319
+ // Extract checksum from modified value log
320
+ checksum3 := extractChecksum (logOutput3 )
321
+
322
+ // Verify different values produce different checksums
323
+ if checksum1 == "" || checksum3 == "" {
324
+ t .Errorf ("Failed to extract checksums from log output" )
325
+ } else if checksum1 == checksum3 {
326
+ t .Errorf ("Different values produced the same checksum: %s" , checksum1 )
327
+ }
328
+ }
329
+
330
+ // extractChecksum extracts the checksum value from log output
331
+ func extractChecksum (logOutput string ) string {
332
+ // Find the value_checksum field in the log output
333
+ checksumIndex := strings .Index (logOutput , "value_checksum=" )
334
+ if checksumIndex == - 1 {
335
+ return ""
336
+ }
337
+
338
+ // Extract the checksum value (assuming it's 8 chars as specified in the implementation)
339
+ checksumStart := checksumIndex + len ("value_checksum=" )
340
+ if checksumStart >= len (logOutput ) {
341
+ return ""
342
+ }
343
+
344
+ // Find the end of the checksum (either space, newline or end of string)
345
+ checksumEnd := checksumStart + 8
346
+ if checksumEnd > len (logOutput ) {
347
+ checksumEnd = len (logOutput )
348
+ }
349
+
350
+ return logOutput [checksumStart :checksumEnd ]
351
+ }
0 commit comments