Files
osmedeus/pkg/cli/run_fetch_test.go
j3ssie 8ec1de4f84 feat(db): add db_import_vigolium importer and harden CLI run
- Add db_import_vigolium JS function that routes vigolium JSONL records
  by envelope type: http_record -> assets, finding -> vulnerabilities
  (deduped on new finding_hash column), skipping scan/oast_interaction
- Add FindingHash field to Vulnerability model with idempotent ALTER
  TABLE migration and matching index
- Suppress run errors when using --silent --empty-target placeholder mode
- Retry transient fetchURLContent failures (network errors, 408/429/5xx)
  with exponential backoff; leave 4xx untouched so GitHub auth fallback
  can engage
- Add unit tests for the vigolium importer (import + idempotency) and
  the HTTP retry behavior, plus a vigolium juice-shop sample fixture
- Bump katana, naabu, kingfisher, bearer registry entries and add
  vigolium to the direct-fetch registry
2026-05-29 23:31:56 +08:00

55 lines
1.7 KiB
Go

package cli
import (
"net/http"
"net/http/httptest"
"sync/atomic"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRetryableHTTPStatus(t *testing.T) {
for _, code := range []int{408, 429, 500, 502, 503, 504} {
assert.Truef(t, retryableHTTPStatus(code), "status %d should be retryable", code)
}
for _, code := range []int{200, 301, 400, 401, 403, 404, 422} {
assert.Falsef(t, retryableHTTPStatus(code), "status %d should not be retryable", code)
}
}
// fetchURLContent should retry transient (5xx) failures and eventually succeed.
func TestFetchURLContentRetriesTransientThenSucceeds(t *testing.T) {
var attempts int32
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if atomic.AddInt32(&attempts, 1) < 2 {
w.WriteHeader(http.StatusServiceUnavailable)
return
}
_, _ = w.Write([]byte("name: test\nkind: module\n"))
}))
defer srv.Close()
content, err := fetchURLContent(srv.URL, nil)
require.NoError(t, err)
assert.Contains(t, string(content), "name: test")
assert.Equal(t, int32(2), atomic.LoadInt32(&attempts), "should retry once then succeed")
}
// fetchURLContent should NOT retry non-retryable statuses (e.g. 404) so the
// GitHub auth fallback in fetchWorkflowFromURL can kick in promptly.
func TestFetchURLContentDoesNotRetryNonRetryable(t *testing.T) {
var attempts int32
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
atomic.AddInt32(&attempts, 1)
w.WriteHeader(http.StatusNotFound)
}))
defer srv.Close()
_, err := fetchURLContent(srv.URL, nil)
require.Error(t, err)
assert.Contains(t, err.Error(), "HTTP 404")
assert.Equal(t, int32(1), atomic.LoadInt32(&attempts), "404 should not be retried")
}