Skip to content

fix(cmd): move file read from newInvokeConfig to runInvoke#3847

Open
Elvand-Lie wants to merge 1 commit into
knative:mainfrom
Elvand-Lie:fix/invoke-remove-redundant-file-read
Open

fix(cmd): move file read from newInvokeConfig to runInvoke#3847
Elvand-Lie wants to merge 1 commit into
knative:mainfrom
Elvand-Lie:fix/invoke-remove-redundant-file-read

Conversation

@Elvand-Lie
Copy link
Copy Markdown
Contributor

@Elvand-Lie Elvand-Lie commented May 25, 2026

Fixes #3846

Problem

When --file is passed to func invoke, the file contents were read from disk twice:

  1. In newInvokeConfig() — reads file into cfg.Data
  2. In runInvoke() — reads the same file again into m.Data

The first read in newInvokeConfig() is problematic because it occurs before the --confirm interactive prompts. If the user changes the file path during these prompts, the original file data has already been loaded, causing stale data to be sent.

Changes

This PR removes the early file read and ensures the file is read only once, at the correct time:

  • Removed early read: Eliminated the os.ReadFile block from newInvokeConfig().
  • Relocated read logic: Moved the file read into runInvoke(), executing it after the configuration is finalized and immediately before client initialization for fail-fast behavior.
  • Added testing: Introduced TestInvoke_FileFlag and TestInvoke_FileFlagNonExistent with sync.Mutex synchronization to explicitly test file-based invocation and error handling.

Testing

  • TestInvoke_FileFlag — Verifies that providing a valid file correctly reads and sends its contents to the mock server.
  • TestInvoke_FileFlagNonExistent — Verifies that providing a non-existent file path immediately returns the appropriate error.

@knative-prow knative-prow Bot added the kind/cleanup Cleanup label May 25, 2026
@knative-prow knative-prow Bot requested review from dsimansk and jrangelramos May 25, 2026 15:45
@knative-prow knative-prow Bot added size/S 🤖 PR changes 10-29 lines, ignoring generated files. needs-ok-to-test 🤖 Needs an org member to approve testing labels May 25, 2026
@knative-prow
Copy link
Copy Markdown

knative-prow Bot commented May 25, 2026

Hi @Elvand-Lie. Thanks for your PR.

I'm waiting for a knative member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Tip

We noticed you've done this a few times! Consider joining the org to skip this step and gain /lgtm and other bot rights. We recommend asking approvers on your previous PRs to sponsor you.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 25, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 53.44%. Comparing base (e7d7dcf) to head (4bce48d).
⚠️ Report is 8 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3847   +/-   ##
=======================================
  Coverage   53.44%   53.44%           
=======================================
  Files         200      200           
  Lines       23450    23406   -44     
=======================================
- Hits        12533    12510   -23     
+ Misses       9662     9648   -14     
+ Partials     1255     1248    -7     
Flag Coverage Δ
e2e 33.69% <0.00%> (-0.03%) ⬇️
e2e go 29.59% <0.00%> (-0.07%) ⬇️
e2e node 25.89% <0.00%> (-0.07%) ⬇️
e2e python 29.93% <0.00%> (-0.07%) ⬇️
e2e quarkus 26.00% <0.00%> (-0.07%) ⬇️
e2e rust 25.40% <0.00%> (-0.14%) ⬇️
e2e springboot 24.13% <0.00%> (-0.08%) ⬇️
e2e typescript 25.98% <0.00%> (-0.07%) ⬇️
e2e-config-ci 26.83% <0.00%> (+0.05%) ⬆️
integration 15.78% <0.00%> (+0.02%) ⬆️
unit macos-14 42.27% <100.00%> (+0.04%) ⬆️
unit macos-latest 42.27% <100.00%> (+0.04%) ⬆️
unit ubuntu-24.04-arm 42.56% <100.00%> (+0.03%) ⬆️
unit ubuntu-latest 43.13% <100.00%> (+0.04%) ⬆️
unit windows-latest 42.33% <100.00%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Elvand-Lie Elvand-Lie force-pushed the fix/invoke-remove-redundant-file-read branch from 6087745 to 7fb6180 Compare May 25, 2026 16:25
@gauron99
Copy link
Copy Markdown
Contributor

The removed os.ReadFile in runInvoke() is the only code that reads the file after --confirm interactive prompts may have changed cfg.File. Two scenarios break:

  1. func invoke --file=a.txt --confirm → user changes file to b.txt in the prompt → a.txt contents get sent
  2. func invoke --confirm → user types mydata.txt in the File prompt → file is never read, default {"message":"Hello World"} gets sent

I suspect the first if cfg.File != "" read is actually redundant. We want to read the file after the whole config is constructed and its values finalized. The first read in newInvokeConfig() most likely served a purpose of displaying data from a file if it was already provided previously, but if File is provided the Data prompt is skipped entirely. There might be some simplification possible here. Make sure to test this locally and if no integration tests exist, create them.

@gauron99
Copy link
Copy Markdown
Contributor

/assign

@knative-prow
Copy link
Copy Markdown

knative-prow Bot commented May 27, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Elvand-Lie
Once this PR has been reviewed and has the lgtm label, please ask for approval from gauron99. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@knative-prow knative-prow Bot added size/M 🤖 PR changes 30-99 lines, ignoring generated files. and removed size/S 🤖 PR changes 10-29 lines, ignoring generated files. labels May 27, 2026
@Elvand-Lie Elvand-Lie force-pushed the fix/invoke-remove-redundant-file-read branch from e08e880 to 066d374 Compare May 27, 2026 16:41
@knative-prow knative-prow Bot added size/L 🤖 PR changes 100-499 lines, ignoring generated files. and removed size/M 🤖 PR changes 30-99 lines, ignoring generated files. labels May 27, 2026
@Elvand-Lie Elvand-Lie force-pushed the fix/invoke-remove-redundant-file-read branch from ad5d837 to a7f0756 Compare May 27, 2026 18:37
@Elvand-Lie
Copy link
Copy Markdown
Contributor Author

@gauron99 Right. Since this was meant to be a cleanup, I saw the two os.ReadFile blocks and assumed the second one in runInvoke() was redundant because cfg.Data was already populated. I didn't account for the interactive --confirm prompts mutating cfg.File between the two reads, meaning the first read pulls stale data. My bad.

I've pushed a fix:

  1. Removed the early read from newInvokeConfig().
  2. Moved the os.ReadFile back into runInvoke() so it reads the file only after the config and prompts are finalized.
  3. Added TestInvoke_FileFlag and TestInvoke_FileFlagNonExistent to explicitly test this behavior against the mock runner.
  4. Fixed formatting with goimports to pass the CI style check.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Removes redundant disk I/O when func invoke --file ... is used by ensuring the file contents are only read once and used as the invocation payload.

Changes:

  • Moves --file reading logic so the invocation message data is populated from a single read.
  • Removes the previous duplicated/now-unnecessary file-read logic.
  • Adds unit tests covering --file success and missing-file error behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
cmd/invoke.go Refactors when/where --file is read to avoid redundant reads and feed cfg.Data into the invoke message.
cmd/invoke_test.go Adds tests validating --file payload handling and error reporting for missing files.
Comments suppressed due to low confidence (1)

cmd/invoke.go:287

  • Reading the file in runInvoke means cfg.Data is still the flag-provided "data" value during newInvokeConfig(). In --confirm non-interactive mode, the command prints Data: before this read happens, so the confirmation output can be misleading when --file is set. Consider loading the file into cfg.Data inside newInvokeConfig after any interactive prompts have completed (and before printing/returning), and then avoid mutating cfg later in runInvoke.
	switch strings.ToLower(cfg.Format) {
	case "cloudevent", "cloudevents":
		cfg.Format = "cloudevent"
	}

	// if not in confirm/prompting mode, the cfg structure is complete.
	if !cfg.Confirm {
		return

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cmd/invoke.go Outdated
Comment thread cmd/invoke.go
Comment thread cmd/invoke_test.go
The os.ReadFile in newInvokeConfig() runs before --confirm prompts,
so if a user changes the file path during interactive prompts, the
old file contents get sent. Move the read to runInvoke() after config
is finalized and before client initialization for fail-fast behavior.

Add TestInvoke_FileFlag and TestInvoke_FileFlagNonExistent tests with
sync.Mutex for proper cross-goroutine synchronization.
@Elvand-Lie Elvand-Lie force-pushed the fix/invoke-remove-redundant-file-read branch from a7f0756 to 4bce48d Compare May 28, 2026 09:24
@Elvand-Lie Elvand-Lie changed the title fix(cmd): remove redundant file read in invoke command fix(cmd): move file read from newInvokeConfig to runInvoke May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/cleanup Cleanup needs-ok-to-test 🤖 Needs an org member to approve testing size/L 🤖 PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cmd: invoke reads --file data from disk twice (redundant I/O)

3 participants