|
6 | 6 | "path/filepath" |
7 | 7 | "sort" |
8 | 8 | "testing" |
| 9 | + |
| 10 | + "github.com/flatrun/agent/pkg/models" |
| 11 | + "gopkg.in/yaml.v3" |
9 | 12 | ) |
10 | 13 |
|
11 | 14 | func TestExtractBindMountPath(t *testing.T) { |
@@ -408,6 +411,138 @@ func TestGenerateMetadataFromCompose_ServiceName(t *testing.T) { |
408 | 411 | } |
409 | 412 | } |
410 | 413 |
|
| 414 | +func TestGenerateMetadataFromCompose_Expose(t *testing.T) { |
| 415 | + tests := []struct { |
| 416 | + name string |
| 417 | + compose string |
| 418 | + wantPort int |
| 419 | + }{ |
| 420 | + { |
| 421 | + name: "expose sets container port", |
| 422 | + compose: `services: |
| 423 | + app: |
| 424 | + image: myapp:latest |
| 425 | + expose: |
| 426 | + - "80" |
| 427 | +`, |
| 428 | + wantPort: 80, |
| 429 | + }, |
| 430 | + { |
| 431 | + name: "ports takes precedence over expose", |
| 432 | + compose: `services: |
| 433 | + app: |
| 434 | + image: myapp:latest |
| 435 | + ports: |
| 436 | + - "8080:3000" |
| 437 | + expose: |
| 438 | + - "80" |
| 439 | +`, |
| 440 | + wantPort: 3000, |
| 441 | + }, |
| 442 | + { |
| 443 | + name: "expose picks primary service in multi-service", |
| 444 | + compose: `services: |
| 445 | + app: |
| 446 | + image: myapp:latest |
| 447 | + expose: |
| 448 | + - "8080" |
| 449 | + db: |
| 450 | + image: postgres:15 |
| 451 | +`, |
| 452 | + wantPort: 8080, |
| 453 | + }, |
| 454 | + } |
| 455 | + |
| 456 | + for _, tt := range tests { |
| 457 | + t.Run(tt.name, func(t *testing.T) { |
| 458 | + tmpDir, err := os.MkdirTemp("", "expose-test-*") |
| 459 | + if err != nil { |
| 460 | + t.Fatalf("Failed to create temp dir: %v", err) |
| 461 | + } |
| 462 | + defer os.RemoveAll(tmpDir) |
| 463 | + |
| 464 | + composePath := filepath.Join(tmpDir, "docker-compose.yml") |
| 465 | + if err := os.WriteFile(composePath, []byte(tt.compose), 0644); err != nil { |
| 466 | + t.Fatalf("Failed to write compose file: %v", err) |
| 467 | + } |
| 468 | + |
| 469 | + d := NewDiscovery(tmpDir) |
| 470 | + metadata := d.generateMetadataFromCompose(composePath, "test") |
| 471 | + if metadata == nil { |
| 472 | + t.Fatal("generateMetadataFromCompose returned nil") |
| 473 | + } |
| 474 | + |
| 475 | + if metadata.Networking.ContainerPort != tt.wantPort { |
| 476 | + t.Errorf("ContainerPort = %d, want %d", metadata.Networking.ContainerPort, tt.wantPort) |
| 477 | + } |
| 478 | + }) |
| 479 | + } |
| 480 | +} |
| 481 | + |
| 482 | +func TestUpdateComposeFile_SyncsMetadata(t *testing.T) { |
| 483 | + tmpDir, err := os.MkdirTemp("", "sync-test-*") |
| 484 | + if err != nil { |
| 485 | + t.Fatalf("Failed to create temp dir: %v", err) |
| 486 | + } |
| 487 | + defer os.RemoveAll(tmpDir) |
| 488 | + |
| 489 | + deployDir := filepath.Join(tmpDir, "myapp") |
| 490 | + if err := os.MkdirAll(deployDir, 0755); err != nil { |
| 491 | + t.Fatalf("Failed to create deploy dir: %v", err) |
| 492 | + } |
| 493 | + |
| 494 | + compose := `services: |
| 495 | + app: |
| 496 | + image: myapp:latest |
| 497 | + expose: |
| 498 | + - "3000" |
| 499 | +` |
| 500 | + composePath := filepath.Join(deployDir, "docker-compose.yml") |
| 501 | + if err := os.WriteFile(composePath, []byte(compose), 0644); err != nil { |
| 502 | + t.Fatalf("Failed to write compose: %v", err) |
| 503 | + } |
| 504 | + |
| 505 | + d := NewDiscovery(tmpDir) |
| 506 | + metadata := &models.ServiceMetadata{ |
| 507 | + Name: "myapp", |
| 508 | + Networking: models.NetworkingConfig{ |
| 509 | + ContainerPort: 3000, |
| 510 | + Expose: true, |
| 511 | + }, |
| 512 | + } |
| 513 | + if err := d.SaveMetadata("myapp", metadata); err != nil { |
| 514 | + t.Fatalf("Failed to save metadata: %v", err) |
| 515 | + } |
| 516 | + |
| 517 | + updatedCompose := `services: |
| 518 | + app: |
| 519 | + image: myapp:latest |
| 520 | + expose: |
| 521 | + - "8080" |
| 522 | +` |
| 523 | + if err := d.UpdateComposeFile("myapp", updatedCompose); err != nil { |
| 524 | + t.Fatalf("UpdateComposeFile failed: %v", err) |
| 525 | + } |
| 526 | + |
| 527 | + metadataPath := filepath.Join(deployDir, "service.yml") |
| 528 | + data, err := os.ReadFile(metadataPath) |
| 529 | + if err != nil { |
| 530 | + t.Fatalf("Failed to read service.yml: %v", err) |
| 531 | + } |
| 532 | + |
| 533 | + var updated models.ServiceMetadata |
| 534 | + if err := yaml.Unmarshal(data, &updated); err != nil { |
| 535 | + t.Fatalf("Failed to parse service.yml: %v", err) |
| 536 | + } |
| 537 | + |
| 538 | + if updated.Networking.ContainerPort != 8080 { |
| 539 | + t.Errorf("ContainerPort = %d, want 8080", updated.Networking.ContainerPort) |
| 540 | + } |
| 541 | + if !updated.Networking.Expose { |
| 542 | + t.Error("Expose should be preserved as true") |
| 543 | + } |
| 544 | +} |
| 545 | + |
411 | 546 | func TestExtractBindMounts(t *testing.T) { |
412 | 547 | tests := []struct { |
413 | 548 | name string |
|
0 commit comments