| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 | package nginximport (	"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")	}}
 |