Class PortalRolloutDifferTest
portal 是逐類別 rollout 第一棒(無併發、per-conversation 無狀態)。本測試是把
scripts/portal/ 切到 GraalJS 之前的自動化 gate,對應計畫 C3 的出口條件
「Tier2+Tier3 differ 過關(驗 getInterface SAM)」。
同一 JVM 並存 nashorn-core(黃金參考)與 GraalJS(候選),命名空間不相交,皆由
ScriptEngines.fresh(ScriptEngines.Backend) 建立(順帶驗接縫工廠)。
本檔(C3 第一批:Tier3 全語料 + getInterface SAM 等價)
- Tier3 解析等價:全 ~825 個 portal 檔的「解析成功與否」在兩引擎必須一致(零 XOR 分歧)。任何 E4X/Nashorn-only 語法殘留都會讓某檔「Nashorn 過、GraalJS 爆」而在此現形。 既有壞腳本(兩引擎皆解析失敗,如未閉合字串)屬行為等價,記錄不擋(見該測試 javadoc)。
- getInterface SAM 綁定等價:對每個 portal 檔,eval(容忍頂層丟例外,如 org.rise.* 死腳本)後
getInterface(PortalScript.class)在兩引擎的「非 null」結果必須一致。這驗證PortalScriptManager線上實際走的 SAM 映射路徑(:83getInterface(PortalScript.class)) 在 GraalJS nashorn-compat 下與黃金參考逐檔等價(差異類別 #6,計畫表第 6 列)。
Tier2 代表性轉錄 differ(逐筆 pi.* host 呼叫序列比對、含多載選擇/數值強制/String 身份/
例外前綴)以 RecordingPortal stub 注入,見本檔下半(隨 recon 選定的 shallow 代表集擴充)。
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classstatic final class受信任第一方腳本以HostAccess.ALL直呼本物件的 public 方法 —— 與線上pi(PortalPlayerInteraction)同樣的 host-interop 路徑。 -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoid全scripts/portal/*.js在 nashorn-core 與 GraalJS 必須等價(非「全部成功」): 解析分歧(XOR)= 零:不得有任何腳本「一引擎解析成功、另一引擎失敗」。void佐證修補:套上 per-script-nameReentrantLock(即 PortalScriptManager.executePortalScript 對 GraalJS 路徑的作法)→ 無例外、maxInFlight<=1。void重現危害:單一共用 GraalJS Context 被兩執行緒同時sam.enter(null)(線上型別化 SAM 路徑) → 拋多執行緒例外(或一度重疊)。void
-
Constructor Details
-
PortalRolloutDifferTest
public PortalRolloutDifferTest()
-
-
Method Details
-
corpusParseAndSamBindingAreEngineEquivalent
全scripts/portal/*.js在 nashorn-core 與 GraalJS 必須等價(非「全部成功」):- 解析分歧(XOR)= 零:不得有任何腳本「一引擎解析成功、另一引擎失敗」。這正是 E4X/Nashorn-only 語法殘留會現形之處 —— rollout 硬門檻。
- SAM 綁定逐檔等價:eval(容忍頂層丟)後
getInterface(PortalScript.class)的非 null 與否兩引擎必須一致 —— 驗PortalScriptManager線上實際走的 SAM 路徑。
「兩引擎皆解析失敗」≠ 分歧:語料含既有壞腳本 —— 例如
Ravana_Enter.js:75未閉合 字串字面值、apq_*的org.rise.*殘留 + 小寫importpackage。這些在線上 今日的 Nashorn 也載不起(PortalScriptManager接住ScriptException、記錯誤、傳點 無作用),GraalJS 切換後同樣載不起 → 行為保持。本測試把它們列為「broken-both」記錄到build/portal-parse-broken-both.txt與主控台,但不當 rollout 阻擋(內容修正屬另案)。 這即 differ 的等價哲學:重點是「兩引擎行為一致」,而非「腳本本身完美」。(「死腳本」org.rise/小寫 importpackage 是頂層 eval 才丟、能解析,故落在 broken-both 之外、走 SAM 綁定等價那條:enter 被 hoist → 兩引擎皆綁得到 → parity。)
- Throws:
Exception
-
tier2TranscriptsAndReturnsMatchAcrossEngines
-
perScriptNameLockSerializesConcurrentPortalEntry
佐證修補:套上 per-script-nameReentrantLock(即 PortalScriptManager.executePortalScript 對 GraalJS 路徑的作法)→ 無例外、maxInFlight<=1。- Throws:
Exception
-