mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-17 22:35:27 +00:00
185 lines
5.1 KiB
Go
185 lines
5.1 KiB
Go
|
|
package tmplexec
|
||
|
|
|
||
|
|
import (
|
||
|
|
"errors"
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/stretchr/testify/assert"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestGetErrorCause_DebugMode(t *testing.T) {
|
||
|
|
testCases := []struct {
|
||
|
|
name string
|
||
|
|
err error
|
||
|
|
debugMode bool
|
||
|
|
expectTrace bool
|
||
|
|
description string
|
||
|
|
}{
|
||
|
|
{
|
||
|
|
name: "Debug mode enabled - should enrich error",
|
||
|
|
err: errors.New("malformed request specified: GET /file=>"),
|
||
|
|
debugMode: true,
|
||
|
|
expectTrace: true,
|
||
|
|
description: "When debug mode is enabled, errors should be enriched with additional context",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "Debug mode disabled - should not enrich error",
|
||
|
|
err: errors.New("malformed request specified: GET /file=>"),
|
||
|
|
debugMode: false,
|
||
|
|
expectTrace: false,
|
||
|
|
description: "When debug mode is disabled, errors should not be enriched to avoid stack traces",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "Nil error - debug mode enabled",
|
||
|
|
err: nil,
|
||
|
|
debugMode: true,
|
||
|
|
expectTrace: false,
|
||
|
|
description: "Nil errors should return empty string regardless of debug mode",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "Nil error - debug mode disabled",
|
||
|
|
err: nil,
|
||
|
|
debugMode: false,
|
||
|
|
expectTrace: false,
|
||
|
|
description: "Nil errors should return empty string regardless of debug mode",
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, tc := range testCases {
|
||
|
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
|
result := getErrorCause(tc.err, tc.debugMode)
|
||
|
|
|
||
|
|
if tc.err == nil {
|
||
|
|
assert.Empty(t, result, "Expected empty string for nil error")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
// Basic validation - result should contain the original error message
|
||
|
|
assert.Contains(t, result, "malformed request specified",
|
||
|
|
"Result should contain the original error message")
|
||
|
|
|
||
|
|
if tc.debugMode {
|
||
|
|
// In debug mode, we expect the error to be processed through errkit
|
||
|
|
// This doesn't necessarily mean stack traces in the final result,
|
||
|
|
// but ensures the error went through the enrichment path
|
||
|
|
assert.NotEmpty(t, result, "Debug mode should produce non-empty result")
|
||
|
|
} else {
|
||
|
|
// In non-debug mode, we should get a simple error message
|
||
|
|
// without any stack trace information
|
||
|
|
assert.NotContains(t, result, "Stacktrace:",
|
||
|
|
"Non-debug mode should not contain stack trace")
|
||
|
|
assert.NotContains(t, result, "goroutine",
|
||
|
|
"Non-debug mode should not contain goroutine information")
|
||
|
|
assert.NotContains(t, result, "runtime/debug.Stack()",
|
||
|
|
"Non-debug mode should not contain runtime stack information")
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestParseScanErrorWithDebug(t *testing.T) {
|
||
|
|
testCases := []struct {
|
||
|
|
name string
|
||
|
|
msg string
|
||
|
|
debugMode bool
|
||
|
|
expected string
|
||
|
|
}{
|
||
|
|
{
|
||
|
|
name: "Simple error - debug mode off",
|
||
|
|
msg: "connection refused",
|
||
|
|
debugMode: false,
|
||
|
|
expected: "connection refused",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "Simple error - debug mode on",
|
||
|
|
msg: "connection refused",
|
||
|
|
debugMode: true,
|
||
|
|
expected: "connection refused",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "ReadStatusLine error - debug mode off",
|
||
|
|
msg: "ReadStatusLine: malformed HTTP response",
|
||
|
|
debugMode: false,
|
||
|
|
expected: "malformed HTTP response",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "Empty message",
|
||
|
|
msg: "",
|
||
|
|
debugMode: false,
|
||
|
|
expected: "",
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, tc := range testCases {
|
||
|
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
|
result := parseScanErrorWithDebug(tc.msg, tc.debugMode)
|
||
|
|
assert.Contains(t, result, tc.expected,
|
||
|
|
"Result should contain expected error message")
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetErrorCause_ContextDeadlineHandling(t *testing.T) {
|
||
|
|
testCases := []struct {
|
||
|
|
name string
|
||
|
|
err error
|
||
|
|
debugMode bool
|
||
|
|
}{
|
||
|
|
{
|
||
|
|
name: "Context deadline exceeded - debug mode",
|
||
|
|
err: errors.New("context deadline exceeded"),
|
||
|
|
debugMode: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "Context deadline exceeded - non-debug mode",
|
||
|
|
err: errors.New("context deadline exceeded"),
|
||
|
|
debugMode: false,
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, tc := range testCases {
|
||
|
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
|
result := getErrorCause(tc.err, tc.debugMode)
|
||
|
|
assert.NotEmpty(t, result, "Should handle context deadline exceeded errors")
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetErrorCause_ErrorMessageFormat(t *testing.T) {
|
||
|
|
originalError := errors.New("test error message")
|
||
|
|
|
||
|
|
debugResult := getErrorCause(originalError, true)
|
||
|
|
nonDebugResult := getErrorCause(originalError, false)
|
||
|
|
|
||
|
|
// Both should contain the original error message
|
||
|
|
assert.Contains(t, debugResult, "test error message",
|
||
|
|
"Debug result should contain original error message")
|
||
|
|
assert.Contains(t, nonDebugResult, "test error message",
|
||
|
|
"Non-debug result should contain original error message")
|
||
|
|
|
||
|
|
// Non-debug should be simpler (no enrichment artifacts)
|
||
|
|
assert.True(t, len(nonDebugResult) <= len(debugResult) ||
|
||
|
|
strings.Count(nonDebugResult, "\n") <= strings.Count(debugResult, "\n"),
|
||
|
|
"Non-debug result should be simpler than debug result")
|
||
|
|
}
|
||
|
|
|
||
|
|
// Benchmark to ensure the non-debug path is more efficient
|
||
|
|
func BenchmarkGetErrorCause_Debug(b *testing.B) {
|
||
|
|
err := errors.New("benchmark test error")
|
||
|
|
b.ResetTimer()
|
||
|
|
|
||
|
|
for i := 0; i < b.N; i++ {
|
||
|
|
getErrorCause(err, true)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func BenchmarkGetErrorCause_NonDebug(b *testing.B) {
|
||
|
|
err := errors.New("benchmark test error")
|
||
|
|
b.ResetTimer()
|
||
|
|
|
||
|
|
for i := 0; i < b.N; i++ {
|
||
|
|
getErrorCause(err, false)
|
||
|
|
}
|
||
|
|
}
|