Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 38 additions & 29 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,37 +59,46 @@ endif

# Short fuzz smoke (extend FUZZTIME locally, e.g. FUZZTIME=30s make test-fuzz)
FUZZTIME ?= 500ms
# Route each fuzz invocation through a wrapper that tolerates the Go fuzz
# engine's spurious "context deadline exceeded" at -fuzztime expiry
# (golang/go#75804, Go 1.25-1.26.x). On Windows `go test` runs directly: local
# fuzz smoke is short and a rare flake is cheap to re-run, and bash may be absent.
ifeq ($(OS),Windows_NT)
FUZZ_WRAPPER := $(GO) test
else
FUZZ_WRAPPER := bash scripts/fuzz-run.sh
endif
test-fuzz:
@echo "Fuzz smoke (FUZZTIME=$(FUZZTIME)) one target per line"
$(GO) test -fuzz=FuzzJSONRoundTrip$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/testkit
$(GO) test -fuzz=FuzzParseSnapshot$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/infra/modelcatalog/modelsdev
$(GO) test -fuzz=FuzzParseSelector$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/routing
$(GO) test -fuzz=FuzzParseSelectorFromBytes$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/routing
$(GO) test -fuzz=FuzzDecodeCreateRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/openairesponses
$(GO) test -fuzz=FuzzDecodeMessageRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/anthropic
$(GO) test -fuzz=FuzzDecodeGenerateContentRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/gemini
$(GO) test -fuzz=FuzzDecodeChatRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/openailegacy
$(GO) test -fuzz=FuzzWriteNonStreamJSON_toolArguments$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/anthropic
$(GO) test -fuzz=FuzzBuildGenerateContentResponse_toolJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/gemini
$(GO) test -fuzz=FuzzCallValidateJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./pkg/lipapi
$(GO) test -fuzz=FuzzMergeRouteQueryGenerationOptions$$ -fuzztime=$(FUZZTIME) -run=^$$ ./pkg/lipapi
$(GO) test -fuzz=FuzzCollectWithLimitsProgram$$ -fuzztime=$(FUZZTIME) -run=^$$ ./pkg/lipapi
$(GO) test -fuzz=FuzzStableCallIdentity$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/diag
$(GO) test -fuzz=FuzzParamsForCall$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openairesponses
$(GO) test -fuzz=FuzzHandleResponseStreamUnion$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openairesponses
$(GO) test -fuzz=FuzzBuildToolsParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openairesponses
$(GO) test -fuzz=FuzzHandleMessageStreamEventUnion$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/anthropicmessages
$(GO) test -fuzz=FuzzToolInputSchemaParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/anthropicmessages
$(GO) test -fuzz=FuzzHandleChatCompletionChunk$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openailegacy
$(GO) test -fuzz=FuzzBuildChatToolsParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openailegacy
$(GO) test -fuzz=FuzzHandleGenerateContentResponse$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/geminigenerate
$(GO) test -fuzz=FuzzBuildToolsParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/geminigenerate
$(GO) test -fuzz=FuzzMessageToContentToolResultJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/geminigenerate
$(GO) test -fuzz=FuzzAssistantPartsToContentBlocksJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/bedrock
$(GO) test -fuzz=FuzzParseNDJSONLine$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/acp
$(GO) test -fuzz=FuzzMapSessionUpdateToEvents$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/acp
$(GO) test -fuzz=FuzzMergeHandshakeProfileExtensions$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/acp
$(GO) test -fuzz=FuzzHookMutationValidators$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/hooks
$(FUZZ_WRAPPER) -fuzz=FuzzJSONRoundTrip$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/testkit
$(FUZZ_WRAPPER) -fuzz=FuzzParseSnapshot$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/infra/modelcatalog/modelsdev
$(FUZZ_WRAPPER) -fuzz=FuzzParseSelector$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/routing
$(FUZZ_WRAPPER) -fuzz=FuzzParseSelectorFromBytes$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/routing
$(FUZZ_WRAPPER) -fuzz=FuzzDecodeCreateRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/openairesponses
$(FUZZ_WRAPPER) -fuzz=FuzzDecodeMessageRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/anthropic
$(FUZZ_WRAPPER) -fuzz=FuzzDecodeGenerateContentRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/gemini
$(FUZZ_WRAPPER) -fuzz=FuzzDecodeChatRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/openailegacy
$(FUZZ_WRAPPER) -fuzz=FuzzWriteNonStreamJSON_toolArguments$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/anthropic
$(FUZZ_WRAPPER) -fuzz=FuzzBuildGenerateContentResponse_toolJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/gemini
$(FUZZ_WRAPPER) -fuzz=FuzzCallValidateJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./pkg/lipapi
$(FUZZ_WRAPPER) -fuzz=FuzzMergeRouteQueryGenerationOptions$$ -fuzztime=$(FUZZTIME) -run=^$$ ./pkg/lipapi
$(FUZZ_WRAPPER) -fuzz=FuzzCollectWithLimitsProgram$$ -fuzztime=$(FUZZTIME) -run=^$$ ./pkg/lipapi
$(FUZZ_WRAPPER) -fuzz=FuzzStableCallIdentity$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/diag
$(FUZZ_WRAPPER) -fuzz=FuzzParamsForCall$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openairesponses
$(FUZZ_WRAPPER) -fuzz=FuzzHandleResponseStreamUnion$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openairesponses
$(FUZZ_WRAPPER) -fuzz=FuzzBuildToolsParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openairesponses
$(FUZZ_WRAPPER) -fuzz=FuzzHandleMessageStreamEventUnion$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/anthropicmessages
$(FUZZ_WRAPPER) -fuzz=FuzzToolInputSchemaParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/anthropicmessages
$(FUZZ_WRAPPER) -fuzz=FuzzHandleChatCompletionChunk$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openailegacy
$(FUZZ_WRAPPER) -fuzz=FuzzBuildChatToolsParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openailegacy
$(FUZZ_WRAPPER) -fuzz=FuzzHandleGenerateContentResponse$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/geminigenerate
$(FUZZ_WRAPPER) -fuzz=FuzzBuildToolsParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/geminigenerate
$(FUZZ_WRAPPER) -fuzz=FuzzMessageToContentToolResultJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/geminigenerate
$(FUZZ_WRAPPER) -fuzz=FuzzAssistantPartsToContentBlocksJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/bedrock
$(FUZZ_WRAPPER) -fuzz=FuzzParseNDJSONLine$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/acp
$(FUZZ_WRAPPER) -fuzz=FuzzMapSessionUpdateToEvents$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/acp
$(FUZZ_WRAPPER) -fuzz=FuzzMergeHandshakeProfileExtensions$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/acp
$(FUZZ_WRAPPER) -fuzz=FuzzHookMutationValidators$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/hooks
Comment on lines 71 to +101

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ“ Maintainability & Code Quality | πŸ”΅ Trivial | ⚑ Quick win

Consider collapsing the repetitive fuzz invocations into a data-driven loop.

checkmake flags test-fuzz's body as exceeding the max line length (30 lines); every line differs only by fuzz name and package path. A list + loop would shrink the target and make adding/removing fuzz targets a one-line change.

♻️ Proposed data-driven refactor
+FUZZ_TARGETS := \
+	FuzzJSONRoundTrip:./internal/testkit \
+	FuzzParseSnapshot:./internal/infra/modelcatalog/modelsdev \
+	FuzzParseSelector:./internal/core/routing \
+	FuzzParseSelectorFromBytes:./internal/core/routing \
+	FuzzDecodeCreateRequest:./internal/plugins/frontends/openairesponses \
+	FuzzDecodeMessageRequest:./internal/plugins/frontends/anthropic \
+	FuzzDecodeGenerateContentRequest:./internal/plugins/frontends/gemini \
+	FuzzDecodeChatRequest:./internal/plugins/frontends/openailegacy \
+	FuzzWriteNonStreamJSON_toolArguments:./internal/plugins/frontends/anthropic \
+	FuzzBuildGenerateContentResponse_toolJSON:./internal/plugins/frontends/gemini \
+	FuzzCallValidateJSON:./pkg/lipapi \
+	FuzzMergeRouteQueryGenerationOptions:./pkg/lipapi \
+	FuzzCollectWithLimitsProgram:./pkg/lipapi \
+	FuzzStableCallIdentity:./internal/core/diag \
+	FuzzParamsForCall:./internal/plugins/backends/openairesponses \
+	FuzzHandleResponseStreamUnion:./internal/plugins/backends/openairesponses \
+	FuzzBuildToolsParametersJSON:./internal/plugins/backends/openairesponses \
+	FuzzHandleMessageStreamEventUnion:./internal/plugins/backends/protocols/anthropicmessages \
+	FuzzToolInputSchemaParametersJSON:./internal/plugins/backends/protocols/anthropicmessages \
+	FuzzHandleChatCompletionChunk:./internal/plugins/backends/openailegacy \
+	FuzzBuildChatToolsParametersJSON:./internal/plugins/backends/openailegacy \
+	FuzzHandleGenerateContentResponse:./internal/plugins/backends/protocols/geminigenerate \
+	FuzzBuildToolsParametersJSON:./internal/plugins/backends/protocols/geminigenerate \
+	FuzzMessageToContentToolResultJSON:./internal/plugins/backends/protocols/geminigenerate \
+	FuzzAssistantPartsToContentBlocksJSON:./internal/plugins/backends/bedrock \
+	FuzzParseNDJSONLine:./internal/plugins/backends/acp \
+	FuzzMapSessionUpdateToEvents:./internal/plugins/backends/acp \
+	FuzzMergeHandshakeProfileExtensions:./internal/plugins/backends/acp \
+	FuzzHookMutationValidators:./internal/core/hooks
+
 test-fuzz:
 	`@echo` "Fuzz smoke (FUZZTIME=$(FUZZTIME)) one target per line"
-	$(FUZZ_WRAPPER) -fuzz=FuzzJSONRoundTrip$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/testkit
-	$(FUZZ_WRAPPER) -fuzz=FuzzParseSnapshot$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/infra/modelcatalog/modelsdev
-	...
+	`@for` t in $(FUZZ_TARGETS); do \
+		name=$${t%%:*}; pkg=$${t#*:}; \
+		$(FUZZ_WRAPPER) -fuzz=$$name$$ -fuzztime=$(FUZZTIME) -run=^$$ $$pkg || exit $$?; \
+	done
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test-fuzz:
@echo "Fuzz smoke (FUZZTIME=$(FUZZTIME)) one target per line"
$(GO) test -fuzz=FuzzJSONRoundTrip$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/testkit
$(GO) test -fuzz=FuzzParseSnapshot$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/infra/modelcatalog/modelsdev
$(GO) test -fuzz=FuzzParseSelector$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/routing
$(GO) test -fuzz=FuzzParseSelectorFromBytes$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/routing
$(GO) test -fuzz=FuzzDecodeCreateRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/openairesponses
$(GO) test -fuzz=FuzzDecodeMessageRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/anthropic
$(GO) test -fuzz=FuzzDecodeGenerateContentRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/gemini
$(GO) test -fuzz=FuzzDecodeChatRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/openailegacy
$(GO) test -fuzz=FuzzWriteNonStreamJSON_toolArguments$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/anthropic
$(GO) test -fuzz=FuzzBuildGenerateContentResponse_toolJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/gemini
$(GO) test -fuzz=FuzzCallValidateJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./pkg/lipapi
$(GO) test -fuzz=FuzzMergeRouteQueryGenerationOptions$$ -fuzztime=$(FUZZTIME) -run=^$$ ./pkg/lipapi
$(GO) test -fuzz=FuzzCollectWithLimitsProgram$$ -fuzztime=$(FUZZTIME) -run=^$$ ./pkg/lipapi
$(GO) test -fuzz=FuzzStableCallIdentity$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/diag
$(GO) test -fuzz=FuzzParamsForCall$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openairesponses
$(GO) test -fuzz=FuzzHandleResponseStreamUnion$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openairesponses
$(GO) test -fuzz=FuzzBuildToolsParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openairesponses
$(GO) test -fuzz=FuzzHandleMessageStreamEventUnion$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/anthropicmessages
$(GO) test -fuzz=FuzzToolInputSchemaParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/anthropicmessages
$(GO) test -fuzz=FuzzHandleChatCompletionChunk$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openailegacy
$(GO) test -fuzz=FuzzBuildChatToolsParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openailegacy
$(GO) test -fuzz=FuzzHandleGenerateContentResponse$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/geminigenerate
$(GO) test -fuzz=FuzzBuildToolsParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/geminigenerate
$(GO) test -fuzz=FuzzMessageToContentToolResultJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/geminigenerate
$(GO) test -fuzz=FuzzAssistantPartsToContentBlocksJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/bedrock
$(GO) test -fuzz=FuzzParseNDJSONLine$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/acp
$(GO) test -fuzz=FuzzMapSessionUpdateToEvents$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/acp
$(GO) test -fuzz=FuzzMergeHandshakeProfileExtensions$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/acp
$(GO) test -fuzz=FuzzHookMutationValidators$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/hooks
$(FUZZ_WRAPPER) -fuzz=FuzzJSONRoundTrip$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/testkit
$(FUZZ_WRAPPER) -fuzz=FuzzParseSnapshot$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/infra/modelcatalog/modelsdev
$(FUZZ_WRAPPER) -fuzz=FuzzParseSelector$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/routing
$(FUZZ_WRAPPER) -fuzz=FuzzParseSelectorFromBytes$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/routing
$(FUZZ_WRAPPER) -fuzz=FuzzDecodeCreateRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/openairesponses
$(FUZZ_WRAPPER) -fuzz=FuzzDecodeMessageRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/anthropic
$(FUZZ_WRAPPER) -fuzz=FuzzDecodeGenerateContentRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/gemini
$(FUZZ_WRAPPER) -fuzz=FuzzDecodeChatRequest$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/openailegacy
$(FUZZ_WRAPPER) -fuzz=FuzzWriteNonStreamJSON_toolArguments$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/anthropic
$(FUZZ_WRAPPER) -fuzz=FuzzBuildGenerateContentResponse_toolJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/frontends/gemini
$(FUZZ_WRAPPER) -fuzz=FuzzCallValidateJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./pkg/lipapi
$(FUZZ_WRAPPER) -fuzz=FuzzMergeRouteQueryGenerationOptions$$ -fuzztime=$(FUZZTIME) -run=^$$ ./pkg/lipapi
$(FUZZ_WRAPPER) -fuzz=FuzzCollectWithLimitsProgram$$ -fuzztime=$(FUZZTIME) -run=^$$ ./pkg/lipapi
$(FUZZ_WRAPPER) -fuzz=FuzzStableCallIdentity$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/diag
$(FUZZ_WRAPPER) -fuzz=FuzzParamsForCall$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openairesponses
$(FUZZ_WRAPPER) -fuzz=FuzzHandleResponseStreamUnion$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openairesponses
$(FUZZ_WRAPPER) -fuzz=FuzzBuildToolsParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openairesponses
$(FUZZ_WRAPPER) -fuzz=FuzzHandleMessageStreamEventUnion$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/anthropicmessages
$(FUZZ_WRAPPER) -fuzz=FuzzToolInputSchemaParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/anthropicmessages
$(FUZZ_WRAPPER) -fuzz=FuzzHandleChatCompletionChunk$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openailegacy
$(FUZZ_WRAPPER) -fuzz=FuzzBuildChatToolsParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/openailegacy
$(FUZZ_WRAPPER) -fuzz=FuzzHandleGenerateContentResponse$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/geminigenerate
$(FUZZ_WRAPPER) -fuzz=FuzzBuildToolsParametersJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/geminigenerate
$(FUZZ_WRAPPER) -fuzz=FuzzMessageToContentToolResultJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/protocols/geminigenerate
$(FUZZ_WRAPPER) -fuzz=FuzzAssistantPartsToContentBlocksJSON$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/bedrock
$(FUZZ_WRAPPER) -fuzz=FuzzParseNDJSONLine$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/acp
$(FUZZ_WRAPPER) -fuzz=FuzzMapSessionUpdateToEvents$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/acp
$(FUZZ_WRAPPER) -fuzz=FuzzMergeHandshakeProfileExtensions$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/plugins/backends/acp
$(FUZZ_WRAPPER) -fuzz=FuzzHookMutationValidators$$ -fuzztime=$(FUZZTIME) -run=^$$ ./internal/core/hooks
FUZZ_TARGETS := \
FuzzJSONRoundTrip:./internal/testkit \
FuzzParseSnapshot:./internal/infra/modelcatalog/modelsdev \
FuzzParseSelector:./internal/core/routing \
FuzzParseSelectorFromBytes:./internal/core/routing \
FuzzDecodeCreateRequest:./internal/plugins/frontends/openairesponses \
FuzzDecodeMessageRequest:./internal/plugins/frontends/anthropic \
FuzzDecodeGenerateContentRequest:./internal/plugins/frontends/gemini \
FuzzDecodeChatRequest:./internal/plugins/frontends/openailegacy \
FuzzWriteNonStreamJSON_toolArguments:./internal/plugins/frontends/anthropic \
FuzzBuildGenerateContentResponse_toolJSON:./internal/plugins/frontends/gemini \
FuzzCallValidateJSON:./pkg/lipapi \
FuzzMergeRouteQueryGenerationOptions:./pkg/lipapi \
FuzzCollectWithLimitsProgram:./pkg/lipapi \
FuzzStableCallIdentity:./internal/core/diag \
FuzzParamsForCall:./internal/plugins/backends/openairesponses \
FuzzHandleResponseStreamUnion:./internal/plugins/backends/openairesponses \
FuzzBuildToolsParametersJSON:./internal/plugins/backends/openairesponses \
FuzzHandleMessageStreamEventUnion:./internal/plugins/backends/protocols/anthropicmessages \
FuzzToolInputSchemaParametersJSON:./internal/plugins/backends/protocols/anthropicmessages \
FuzzHandleChatCompletionChunk:./internal/plugins/backends/openailegacy \
FuzzBuildChatToolsParametersJSON:./internal/plugins/backends/openailegacy \
FuzzHandleGenerateContentResponse:./internal/plugins/backends/protocols/geminigenerate \
FuzzBuildToolsParametersJSON:./internal/plugins/backends/protocols/geminigenerate \
FuzzMessageToContentToolResultJSON:./internal/plugins/backends/protocols/geminigenerate \
FuzzAssistantPartsToContentBlocksJSON:./internal/plugins/backends/bedrock \
FuzzParseNDJSONLine:./internal/plugins/backends/acp \
FuzzMapSessionUpdateToEvents:./internal/plugins/backends/acp \
FuzzMergeHandshakeProfileExtensions:./internal/plugins/backends/acp \
FuzzHookMutationValidators:./internal/core/hooks
test-fuzz:
`@echo` "Fuzz smoke (FUZZTIME=$(FUZZTIME)) one target per line"
`@for` t in $(FUZZ_TARGETS); do \
name=$${t%%:*}; pkg=$${t#*:}; \
$(FUZZ_WRAPPER) -fuzz=$$name$$ -fuzztime=$(FUZZTIME) -run=^$$ $$pkg || exit $$?; \
done
🧰 Tools
πŸͺ› checkmake (0.3.2)

[warning] 71-71: Target body for "test-fuzz" exceeds allowed length of 5 lines (30).

(maxbodylength)

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Makefile` around lines 71 - 101, The test-fuzz target in the Makefile is too
repetitive and exceeds the checkmake limit because each invocation only varies
by fuzz function and package path. Refactor the body of test-fuzz to use a
data-driven loop or target list so the shared FUZZ_WRAPPER, -fuzztime, and -run
flags are defined once and each fuzz case is just an item. Keep the existing
fuzz names and package paths from test-fuzz, but make adding or removing entries
a one-line change instead of duplicating full commands.

Source: Linters/SAST tools


parity-checks:
$(GO) test $(GO_TEST_FLAGS) -tags=precommit,integration ./internal/testkit/conformance/...
Expand Down
11 changes: 11 additions & 0 deletions internal/plugins/frontends/openaiwire/parts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ func TestFilePartFromBase64_pdfFilename(t *testing.T) {
}
}

func TestFilePartFromBase64_nonPdfFilename(t *testing.T) {
t.Parallel()
p := FilePartFromBase64("doc.txt", "qqq")
if p.FileMIME != "application/octet-stream" {
t.Fatalf("mime %q", p.FileMIME)
}
if p.Kind != lipapi.PartFileRef {
t.Fatalf("kind %v", p.Kind)
}
}

func TestImagePartFromURL_standardURL(t *testing.T) {
t.Parallel()
urlStr := "https://example.com/image.png"
Expand Down
54 changes: 54 additions & 0 deletions scripts/fuzz-run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
# fuzz-run.sh β€” run a single `go test -fuzz=...` invocation and tolerate the
# Go fuzz engine's known spurious "context deadline exceeded" failure that
# occurs when -fuzztime expires (golang/go#75804, Go 1.25-1.26.x).
#
# At the -fuzztime boundary the fuzz coordinator cancels in-flight iterations
# and may emit:
# --- FAIL: FuzzX (Ns)
# context deadline exceeded
# with NO `file:line` reference and NO "Failing input written to" corpus entry.
# That is the time budget expiring, not a real test failure.
#
# Real failures always include either a `..._test.go:<line>:` (or any
# `*.go:<line>:`) reference or a "Failing input written to" line; those are
# still surfaced as failures. Only the bare deadline message is tolerated.
#
# Usage: fuzz-run.sh <args passed to `go test -fuzz=...`>
# Env: GO β€” go binary (default: go)

set -u

GO_BIN="${GO:-go}"

out="$(mktemp)"
trap 'rm -f "$out"' EXIT

# Note: no `set -e`/pipefail here β€” a nonzero `go test` exit is classified below.
"$GO_BIN" test "$@" >"$out" 2>&1
status=$?
cat "$out"

# Clean exit.
if [ "$status" -eq 0 ]; then
exit 0
fi

# Real finding: a new failing corpus entry was written.
if grep -q 'Failing input written to' "$out"; then
exit "$status"
fi

# Real assertion/panic failure: a source file:line reference is present.
if grep -qE '\.go:[0-9]+:' "$out"; then
exit "$status"
fi

# Spurious engine deadline flake at the -fuzztime boundary β€” tolerate.
if grep -q 'context deadline exceeded' "$out"; then
echo "fuzz-run: tolerated spurious Go fuzz engine 'context deadline exceeded' at -fuzztime boundary (golang/go#75804)" >&2
exit 0
fi

# Any other non-zero exit is a real error (build failure, panic w/o location, etc.).
exit "$status"