Harden marketplace listing and debug smoke errors

This commit is contained in:
npc0-hue
2026-08-22 22:31:33 +08:00
parent ebd616c549
commit 4d945eb809
3 changed files with 38 additions and 3 deletions
+7
View File
@@ -1532,6 +1532,13 @@ func (svc *CoreService) ListMarketplacePlugins(filter domain.PluginMarketplaceFi
if filter.Keyword != "" && !marketplacePluginMatchesKeyword(projected, filter.Keyword) { if filter.Keyword != "" && !marketplacePluginMatchesKeyword(projected, filter.Keyword) {
continue continue
} }
// The registry can outlive a manifest contract. Do not let a historical
// plugin with removed capabilities make the usable marketplace entries
// fail as one invalid response; it is still available through the plugin
// registry for an explicit refresh or migration.
if err := validator.ValidatePluginMarketplacePlugin(projected); err != nil {
continue
}
items = append(items, projected) items = append(items, projected)
} }
if err := validator.ValidatePluginMarketplacePlugins(items); err != nil { if err := validator.ValidatePluginMarketplacePlugins(items); err != nil {
+24
View File
@@ -1324,6 +1324,30 @@ func TestCoreServiceMarketplacePluginsAreFilteredSafeAndStateful(t *testing.T) {
} }
} }
func TestCoreServiceMarketplaceListSkipsHistoricalInvalidCapabilities(t *testing.T) {
svc := newTestCoreService()
if _, err := svc.RegisterGamePluginManifest(validPluginManifestRegistration()); err != nil {
t.Fatalf("register current manifest: %v", err)
}
legacy := gamePluginFromManifestRegistration(validPluginManifestRegistration())
legacy.ID = "game.legacy"
legacy.Name = "Legacy Server"
legacy.RequiredRunCapabilities = append(legacy.RequiredRunCapabilities, "remote.run.protected.sql", "remote.run.protected.rcon")
legacy.RemoteAccess.RunCapabilities = append(legacy.RemoteAccess.RunCapabilities, "remote.run.protected.sql", "remote.run.protected.rcon")
if err := svc.store.GamePlugins().Create(legacy); err != nil {
t.Fatalf("seed historical plugin: %v", err)
}
listed, err := svc.ListMarketplacePlugins(domain.PluginMarketplaceFilter{})
if err != nil {
t.Fatalf("list marketplace plugins with historical record: %v", err)
}
if len(listed) != 1 || listed[0].ID != "game.example" {
t.Fatalf("expected only current marketplace plugin, got %+v", listed)
}
}
func TestCoreServiceAuthorizesPluginBridgeActions(t *testing.T) { func TestCoreServiceAuthorizesPluginBridgeActions(t *testing.T) {
svc := newTestCoreService() svc := newTestCoreService()
if _, err := svc.RegisterGamePluginManifest(validPluginManifestRegistration()); err != nil { if _, err := svc.RegisterGamePluginManifest(validPluginManifestRegistration()); err != nil {
+7 -3
View File
@@ -323,9 +323,13 @@ json_post() {
2*) 2*)
return 0 return 0
;; ;;
*) *)
if [[ ! -s "$output_file" ]] || ! response_code_is_duplicate "$output_file"; then if [[ ! -s "$output_file" ]] || ! response_code_is_duplicate "$output_file"; then
printf 'POST %s failed with HTTP %s\n' "$url" "$status" >&2 printf 'POST %s failed with HTTP %s\n' "$url" "$status" >&2
if [[ -s "$output_file" ]]; then
printf 'response body:\n' >&2
sed -n '1,160p' "$output_file" >&2
fi
fi fi
return 1 return 1
;; ;;
@@ -1416,7 +1420,7 @@ if [[ "${LOCAL_DEBUG_LOG_SESSION_SMOKE_ONLY:-false}" == "true" ]]; then
fi fi
printf 'generating host-native example Run through platform Docker builder\n' printf 'generating host-native example Run through platform Docker builder\n'
curl -fsS -H 'Content-Type: application/json' "${AUTH_HEADER[@]}" --data-binary "@$WORK_DIR/server-run-generate.request.json" "$API_URL/server-instances/$SERVER_ID/run/generate" >"$WORK_DIR/server-run-generate.response.json" json_post "$API_URL/server-instances/$SERVER_ID/run/generate" "$WORK_DIR/server-run-generate.request.json" "$WORK_DIR/server-run-generate.response.json" "${AUTH_HEADER[@]}"
reject_forbidden_fragments "$WORK_DIR/server-run-generate.response.json" reject_forbidden_fragments "$WORK_DIR/server-run-generate.response.json"
node - "$WORK_DIR/server-run-generate.response.json" "$SERVER_ID" "$GENERATED_RUN_ENDPOINT_ID" "$GENERATED_RUN_TARGET_OS" "$GENERATED_RUN_TARGET_ARCH" <<'NODE' node - "$WORK_DIR/server-run-generate.response.json" "$SERVER_ID" "$GENERATED_RUN_ENDPOINT_ID" "$GENERATED_RUN_TARGET_OS" "$GENERATED_RUN_TARGET_ARCH" <<'NODE'
const fs = require("fs"); const fs = require("fs");
@@ -1499,7 +1503,7 @@ if ((action.reason || "").includes("run endpoint")) {
NODE NODE
printf 'generating SCUM run package through platform API\n' printf 'generating SCUM run package through platform API\n'
curl -fsS -H 'Content-Type: application/json' "${AUTH_HEADER[@]}" --data-binary "@$WORK_DIR/scum-alpha-run-generate.request.json" "$API_URL/server-instances/$SCUM_ALPHA_ID/run/generate" >"$WORK_DIR/scum-alpha-run-generate.response.json" json_post "$API_URL/server-instances/$SCUM_ALPHA_ID/run/generate" "$WORK_DIR/scum-alpha-run-generate.request.json" "$WORK_DIR/scum-alpha-run-generate.response.json" "${AUTH_HEADER[@]}"
reject_forbidden_fragments "$WORK_DIR/scum-alpha-run-generate.response.json" reject_forbidden_fragments "$WORK_DIR/scum-alpha-run-generate.response.json"
require_file_contains "$WORK_DIR/scum-alpha-run-generate.response.json" "\"serverInstanceId\"[[:space:]]*:[[:space:]]*\"$SCUM_ALPHA_ID\"" require_file_contains "$WORK_DIR/scum-alpha-run-generate.response.json" "\"serverInstanceId\"[[:space:]]*:[[:space:]]*\"$SCUM_ALPHA_ID\""
require_file_contains "$WORK_DIR/scum-alpha-run-generate.response.json" "\"artifactId\"[[:space:]]*:[[:space:]]*\"artifact-run-dist-$SCUM_ALPHA_ID" require_file_contains "$WORK_DIR/scum-alpha-run-generate.response.json" "\"artifactId\"[[:space:]]*:[[:space:]]*\"artifact-run-dist-$SCUM_ALPHA_ID"