123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- package nginx
- import (
- "os"
- "strings"
- "testing"
- )
- func TestCreateSandbox(t *testing.T) {
- namespaceInfo := &NamespaceInfo{
- ID: 1,
- Name: "test-namespace",
- }
- sitePaths := []string{"site1.conf", "site2.conf"}
- streamPaths := []string{"stream1.conf"}
- sandbox, err := createSandbox(namespaceInfo, sitePaths, streamPaths)
- if err != nil {
- t.Fatalf("Failed to create sandbox: %v", err)
- }
- defer sandbox.Cleanup()
- // Verify sandbox directory exists
- if _, err := os.Stat(sandbox.Dir); os.IsNotExist(err) {
- t.Errorf("Sandbox directory does not exist: %s", sandbox.Dir)
- }
- // Verify config file exists
- if _, err := os.Stat(sandbox.ConfigPath); os.IsNotExist(err) {
- t.Errorf("Sandbox config file does not exist: %s", sandbox.ConfigPath)
- }
- // Verify namespace info
- if sandbox.Namespace.ID != 1 {
- t.Errorf("Expected namespace ID 1, got %d", sandbox.Namespace.ID)
- }
- }
- func TestSandboxCleanup(t *testing.T) {
- sandbox, err := createSandbox(nil, []string{}, []string{})
- if err != nil {
- t.Fatalf("Failed to create sandbox: %v", err)
- }
- sandboxDir := sandbox.Dir
- // Cleanup
- sandbox.Cleanup()
- // Verify directory is removed
- if _, err := os.Stat(sandboxDir); !os.IsNotExist(err) {
- t.Errorf("Sandbox directory still exists after cleanup: %s", sandboxDir)
- }
- }
- func TestGenerateSandboxConfig(t *testing.T) {
- // Skip this test as it requires mocking GetConfEntryPath
- // The logic is tested in TestReplaceIncludeDirectives instead
- t.Skip("Skipping - requires dependency injection refactoring")
- }
- func TestReplaceIncludeDirectives(t *testing.T) {
- tests := []struct {
- name string
- mainConf string
- includePatterns []string
- expectContains []string
- expectNotContain []string
- }{
- {
- name: "Replace HTTP includes",
- mainConf: `http {
- include /etc/nginx/sites-enabled/*;
- }`,
- includePatterns: []string{
- " include /etc/nginx/sites-enabled/site1.conf;",
- " include /etc/nginx/sites-enabled/site2.conf;",
- },
- expectContains: []string{
- "include /etc/nginx/sites-enabled/site1.conf",
- "include /etc/nginx/sites-enabled/site2.conf",
- "Sandbox-specific includes",
- },
- expectNotContain: []string{
- "include /etc/nginx/sites-enabled/*",
- },
- },
- {
- name: "Replace Stream includes",
- mainConf: `stream {
- include /etc/nginx/streams-enabled/*;
- }`,
- includePatterns: []string{
- " include /etc/nginx/streams-enabled/stream1.conf;",
- },
- expectContains: []string{
- "include /etc/nginx/streams-enabled/stream1.conf",
- "Sandbox-specific includes",
- },
- expectNotContain: []string{
- "include /etc/nginx/streams-enabled/*",
- },
- },
- {
- name: "Rewrite other includes to sandbox",
- mainConf: `http {
- include /etc/nginx/mime.types;
- include /etc/nginx/conf.d/*.conf;
- include /etc/nginx/sites-enabled/*;
- }`,
- includePatterns: []string{
- " include /etc/nginx/sites-enabled/site1.conf;",
- },
- expectContains: []string{
- "include /tmp/test-sandbox/mime.types", // Rewritten to sandbox
- "include /tmp/test-sandbox/conf.d/*.conf", // Rewritten to sandbox
- "include /etc/nginx/sites-enabled/site1.conf",
- },
- expectNotContain: []string{
- "include /etc/nginx/sites-enabled/*",
- "include /etc/nginx/mime.types", // Should be rewritten
- "include /etc/nginx/conf.d/*.conf", // Should be rewritten
- },
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- sandboxDir := "/tmp/test-sandbox"
- result := replaceIncludeDirectives(tt.mainConf, tt.includePatterns, sandboxDir)
- for _, expected := range tt.expectContains {
- if !strings.Contains(result, expected) {
- t.Errorf("Expected result to contain %q, but it doesn't.\nResult:\n%s", expected, result)
- }
- }
- for _, notExpected := range tt.expectNotContain {
- if strings.Contains(result, notExpected) {
- t.Errorf("Expected result NOT to contain %q, but it does.\nResult:\n%s", notExpected, result)
- }
- }
- })
- }
- }
- func TestReplaceIncludeDirectivesEdgeCases(t *testing.T) {
- t.Run("Empty include patterns", func(t *testing.T) {
- mainConf := `http {
- include /etc/nginx/sites-enabled/*;
- }`
- result := replaceIncludeDirectives(mainConf, []string{}, "/tmp/test-sandbox")
- // Should still add comment but no includes
- if !strings.Contains(result, "Sandbox-specific includes") {
- t.Error("Expected sandbox comment even with empty patterns")
- }
- })
- t.Run("No http or stream blocks", func(t *testing.T) {
- mainConf := `events {
- worker_connections 1024;
- }`
- includePatterns := []string{" include /etc/nginx/sites-enabled/site1.conf;"}
- result := replaceIncludeDirectives(mainConf, includePatterns, "/tmp/test-sandbox")
- // Should preserve original config
- if !strings.Contains(result, "worker_connections 1024") {
- t.Error("Original config not preserved when no http/stream blocks")
- }
- })
- t.Run("Nested braces", func(t *testing.T) {
- mainConf := `http {
- server {
- location / {
- return 200;
- }
- }
- include /etc/nginx/sites-enabled/*;
- }`
- includePatterns := []string{" include /etc/nginx/sites-enabled/site1.conf;"}
- result := replaceIncludeDirectives(mainConf, includePatterns, "/tmp/test-sandbox")
- // Should preserve nested structure
- if !strings.Contains(result, "location /") {
- t.Error("Nested location directive not preserved")
- }
- // Should replace include
- if strings.Contains(result, "include /etc/nginx/sites-enabled/*") {
- t.Error("Generic include should be replaced even with nested braces")
- }
- })
- }
- func TestSandboxTestConfigWithPaths(t *testing.T) {
- // Skip this integration test - requires nginx installation and proper setup
- t.Skip("Skipping integration test - requires nginx binary and proper configuration")
- }
- func BenchmarkCreateSandbox(b *testing.B) {
- namespaceInfo := &NamespaceInfo{
- ID: 1,
- Name: "bench-namespace",
- }
- sitePaths := []string{"site1.conf", "site2.conf", "site3.conf"}
- streamPaths := []string{"stream1.conf"}
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- sandbox, err := createSandbox(namespaceInfo, sitePaths, streamPaths)
- if err != nil {
- b.Fatalf("Failed to create sandbox: %v", err)
- }
- sandbox.Cleanup()
- }
- }
- func BenchmarkReplaceIncludeDirectives(b *testing.B) {
- mainConf := `
- events {
- worker_connections 1024;
- }
- http {
- include /etc/nginx/mime.types;
- include /etc/nginx/conf.d/*.conf;
- include /etc/nginx/sites-enabled/*;
- server {
- listen 80;
- server_name default;
- }
- }
- stream {
- include /etc/nginx/streams-enabled/*;
- }
- `
- includePatterns := []string{
- " include /etc/nginx/sites-enabled/site1.conf;",
- " include /etc/nginx/sites-enabled/site2.conf;",
- " include /etc/nginx/sites-enabled/site3.conf;",
- " include /etc/nginx/streams-enabled/stream1.conf;",
- }
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _ = replaceIncludeDirectives(mainConf, includePatterns, "/tmp/test-sandbox")
- }
- }
|