From 5fbe9789faf05ce99bbff6ec4cd0b905519acbd0 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Fri, 03 Jul 2026 05:18:07 +0800
Subject: [PATCH] Freeze R221 2.2.2 source baseline
---
C1.source/privatevoice.src/app_live_caption_test.go | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 101 insertions(+), 0 deletions(-)
diff --git a/C1.source/privatevoice.src/app_live_caption_test.go b/C1.source/privatevoice.src/app_live_caption_test.go
index 2c1610d..accb99c 100644
--- a/C1.source/privatevoice.src/app_live_caption_test.go
+++ b/C1.source/privatevoice.src/app_live_caption_test.go
@@ -2,8 +2,11 @@
import (
"strings"
+ "sync/atomic"
"testing"
"time"
+
+ "voicesnap/internal/engine"
)
func TestLiveCaptionDisplayTextFitsOverlayBuffer(t *testing.T) {
@@ -131,6 +134,95 @@
}
}
+func TestInitEngineSerializesAndDiscardsStaleEngine(t *testing.T) {
+ first := &closeTrackingTestEngine{name: "first"}
+ second := &closeTrackingTestEngine{name: "second"}
+ firstStarted := make(chan struct{})
+ allowFirst := make(chan struct{})
+ calls := atomic.Int32{}
+
+ a := &App{
+ engineFactory: func(initID uint64) (engine.Engine, engineMetadata, bool, error) {
+ call := calls.Add(1)
+ switch call {
+ case 1:
+ close(firstStarted)
+ <-allowFirst
+ return first, engineMetadata{InitID: initID, ResolvedModelID: "first", HardwareInfo: "first"}, true, nil
+ case 2:
+ return second, engineMetadata{InitID: initID, ResolvedModelID: "second", HardwareInfo: "second"}, true, nil
+ default:
+ t.Fatalf("unexpected engine factory call %d", call)
+ return nil, engineMetadata{}, false, nil
+ }
+ },
+ }
+
+ doneFirst := make(chan struct{})
+ go func() {
+ a.initEngine()
+ close(doneFirst)
+ }()
+
+ select {
+ case <-firstStarted:
+ case <-time.After(time.Second):
+ t.Fatal("first engine init did not start")
+ }
+
+ doneSecond := make(chan struct{})
+ go func() {
+ a.initEngine()
+ close(doneSecond)
+ }()
+
+ waitForCondition(t, time.Second, func() bool {
+ return a.engineInitSeq.Load() == 2
+ })
+ close(allowFirst)
+
+ select {
+ case <-doneFirst:
+ case <-time.After(time.Second):
+ t.Fatal("first engine init did not finish")
+ }
+ select {
+ case <-doneSecond:
+ case <-time.After(time.Second):
+ t.Fatal("second engine init did not finish")
+ }
+
+ a.engineMu.Lock()
+ gotEngine := a.eng
+ gotMeta := a.engineMeta
+ a.engineMu.Unlock()
+
+ if gotEngine != second {
+ t.Fatalf("final engine = %#v, want second", gotEngine)
+ }
+ if !first.closed.Load() {
+ t.Fatal("stale first engine should be closed")
+ }
+ if second.closed.Load() {
+ t.Fatal("current second engine should remain open")
+ }
+ if gotMeta.ResolvedModelID != "second" || gotMeta.InitID != 2 {
+ t.Fatalf("engine metadata = %+v, want second init metadata", gotMeta)
+ }
+}
+
+func waitForCondition(t *testing.T, timeout time.Duration, fn func() bool) {
+ t.Helper()
+ deadline := time.Now().Add(timeout)
+ for time.Now().Before(deadline) {
+ if fn() {
+ return
+ }
+ time.Sleep(10 * time.Millisecond)
+ }
+ t.Fatal("condition was not met before timeout")
+}
+
func TestShouldStartHoldPreCaptureLocked(t *testing.T) {
a := &App{}
a.holdPreCaptureEnabled.Store(true)
@@ -189,6 +281,15 @@
func (plainTestEngine) HardwareInfo() string { return "test" }
func (plainTestEngine) Close() {}
+type closeTrackingTestEngine struct {
+ plainTestEngine
+ name string
+ closed atomic.Bool
+}
+
+func (e *closeTrackingTestEngine) HardwareInfo() string { return e.name }
+func (e *closeTrackingTestEngine) Close() { e.closed.Store(true) }
+
type tailCaptureTestEngine struct {
plainTestEngine
delay time.Duration
--
Gitblit v1.9.3