janhoy commented on PR #5047:
URL: https://github.com/apache/solr/pull/5047#issuecomment-6066798920

   🤖 Bug fix and pr comment below written by Claude Fable
   
   ---
   ### Flaky `PackageToolPicocliTest.testPackageTool` and the fix
   
   Running `org.apache.solr.cli.*` on this branch, `PackageToolPicocliTest` 
failed in roughly a third of runs while `PackageToolTest` always passed. With 
`-Ptests.seed=CE8CB19A405A7699` the picocli test failed 7 of 8 runs. The 
failing step is the second `install question-answer` in the random "auto-update 
to latest" branch of `testPackageTool`, which exits 1 after `Actual: 1.0.0, 
expected: 1.1.0` / `Failed verification after deployment`.
   
   This is not a bug in the port. The commons-cli `PackageTool.install()` was 
`void`, so the legacy path printed `installation failed` and still exited 0, 
which hid a pre-existing server-side race. The new `PackageInstall` correctly 
propagates the result, which is why the test now sees it.
   
   **The race.** `RepositoryManager.install` adds the new version through `POST 
/api/cluster/package {add: ...}` and then immediately verifies the collections 
pegged to `$LATEST`. On the server, `PackageAPI.Edit.add` writes 
`packages.json` and calls `notifyAllNodesToSync(znodeVersion)`, and each node 
answers via `Read.syncToVersion`. That method considered a node synced as soon 
as `pkgs.znodeVersion` had reached the expected version. But that field is 
bumped by the node's own ZK watcher thread at the start of `refreshPackages`, 
before `SolrPackageLoader.refreshPackageConf()` has built the new version's 
classloader and reloaded the plugins. So when the watcher fires first, which is 
the common case, the sync request returns instantly while the reload is still 
in flight, `add` returns to the client, and the verify reads the old plugin 
version. The explicit `refresh` command had the same hole: `notifyListeners` 
would run against a `SolrPackage` whose version list the watcher thread had n
 ot finished updating, so it reloaded nothing. I first tried posting a 
`refresh` from the client before verifying, the way the deploy path does, and 
it failed deterministically for exactly that reason.
   
   **The fix** (separate commit on this branch, `3ca62e67c71`) is server-side 
and small:
   
   - `SolrPackageLoader.refreshPackageConf()` and `notifyListeners()` are now 
`synchronized`, so a sync or refresh request blocks until any application of 
`packages.json` already started by the ZK watcher has completed, and is a no-op 
afterwards.
   - `PackageAPI.Read.syncToVersion` always goes through `refreshPackageConf()` 
once the expected version is visible, instead of skipping it when the watcher 
had already bumped the version number.
   
   Lock order stays one-directional (loader monitor, then `PackageListeners`, 
then `PackagePluginHolder`), and nothing on the listener path calls back into 
the loader, so there is no new deadlock risk.
   
   **Verification.** The failing seed now passes 8 of 8 runs, both 
`PackageToolTest` and `PackageToolPicocliTest` pass on repeated random seeds, 
and `org.apache.solr.pkg.*`, `org.apache.solr.filestore.*` and 
`TestContainerPlugin` all pass. `gradlew check -x test` is green.
   
   A second small commit (`7ee9561c11c`) tidies the test: 
`testDeployValidationMessages` created `validation-test` on `conf1`, the same 
configset as `abc`, so after a deploy to `abc` the package also showed as 
deployed on `validation-test` via the shared `PKG_VERSIONS` params. It now gets 
its own configset so the two test methods do not influence each other. Both 
twins pass on repeated runs and `list-deployed` reports only `abc`.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to