77
88try
99{
10- await RunOssClientAsync ( ) ;
11- /*var isOssMode = args.Length > 0 && args[0] == "--oss";
12-
13- if (isOssMode)
14- {
15- await RunOssClientAsync();
16- }
17- else
18- {
19- await RunStandardClientAsync();
20- }*/
10+ await RunUpdateTestAsync ( ) ;
2111}
2212catch ( Exception ex )
2313{
2717 Environment . Exit ( 1 ) ;
2818}
2919
20+ // NOTE: In the success path where a MainApp update is applied and the Upgrade
21+ // process is launched, the Client process exits inside the bootstrap —
22+ // the OS strategy's StartAppAsync() calls GracefulExit.CurrentProcessAsync().
23+ // The code below is only reached when no update is needed, or when only
24+ // Upgrade packages were applied (no MainApp IPC/launch).
3025Console . WriteLine ( "Press Enter to exit..." ) ;
3126Console . ReadLine ( ) ;
3227
3328// ═══════════════════════════════════════════════════════════════════
34- // OSS Client mode — version JSON download → version compare → launch upgrade
29+ // Core update test — runs the full non-silent immediate update flow.
30+ //
31+ // The update mode (chain vs. cross-version) is determined entirely by
32+ // GeneralUpdate.Core's DownloadPlanBuilder, which inspects the server
33+ // response and prefers CVP when its FromVersion matches the local
34+ // client version. The test itself is mode-agnostic — configure the
35+ // GeneralSpacestation server's data to exercise either path.
3536// ═══════════════════════════════════════════════════════════════════
36- static async Task RunOssClientAsync ( )
37+ static async Task RunUpdateTestAsync ( )
3738{
38- Console . WriteLine ( "=== GeneralUpdate OSS Client Test ===" ) ;
39+ Console . WriteLine ( "=== GeneralUpdate Client Test ===" ) ;
3940 Console . WriteLine ( $ "Started at { DateTime . Now } ") ;
4041 Console . WriteLine ( $ "Running from: { AppDomain . CurrentDomain . BaseDirectory } ") ;
4142
42- // Only secrets are supplied in code. Identity fields (MainAppName,
43- // ClientVersion, UpdateAppName, UpdatePath) are read from
44- // generalupdate.manifest.json by OssStrategy via
45- // AppMetadataDiscoverer.Discover() — same as the standard flow.
46- var updateUrl = "http://localhost:5000/packages/versions.json" ;
47- var appSecretKey = "dfeb5833-975e-4afb-88f1-6278ee9aeff6" ;
43+ var updateUrl = "http://localhost:7391/Upgrade/Verification" ;
44+ var reportUrl = "http://localhost:7391/Upgrade/Report" ;
45+ var appSecretKey =
46+ Environment . GetEnvironmentVariable ( "APP_SECRET_KEY" )
47+ ?? "dfeb5833-975e-4afb-88f1-6278ee9aeff6" ;
4848
4949 Console . WriteLine ( $ "UpdateUrl: { updateUrl } ") ;
5050 Console . WriteLine ( ) ;
51-
52- await new GeneralUpdateBootstrap ( )
53- . SetSource ( updateUrl , appSecretKey )
54- . SetOption ( Option . AppType , AppType . OssClient )
55- . Hooks < ClientTestHooks > ( )
56- . AddListenerMultiDownloadStatistics ( OnDownloadStatistics )
57- . AddListenerMultiDownloadCompleted ( OnDownloadCompleted )
58- . AddListenerMultiAllDownloadCompleted ( OnAllDownloadCompleted )
59- . AddListenerMultiDownloadError ( OnDownloadError )
60- . AddListenerException ( OnException )
61- . AddListenerUpdateInfo ( OnUpdateInfo )
62- . LaunchAsync ( ) ;
63-
64- Console . WriteLine ( "OSS Client test completed." ) ;
65- }
66-
67- // ═══════════════════════════════════════════════════════════════════
68- // Standard Client mode — silent poll with IPC handoff to Upgrade
69- // ═══════════════════════════════════════════════════════════════════
70- static async Task RunStandardClientAsync ( )
71- {
72- Console . WriteLine ( "=== GeneralUpdate Client Test (Silent Mode) ===" ) ;
73- Console . WriteLine ( $ "Started at { DateTime . Now } ") ;
74- Console . WriteLine ( $ "Running from: { AppDomain . CurrentDomain . BaseDirectory } ") ;
75-
76- // Secrets come from code — never from files.
77- var updateUrl = "http://localhost:5000/Upgrade/Verification" ;
78- var reportUrl = "http://localhost:5000/Upgrade/Report" ;
79- var appSecretKey = Environment . GetEnvironmentVariable ( "APP_SECRET_KEY" ) ?? "dfeb5833-975e-4afb-88f1-6278ee9aeff6" ;
80-
81- Console . WriteLine ( $ "UpdateUrl: { updateUrl } ") ;
82- Console . WriteLine ( $ "Silent mode: ENABLED (poll every 1 minute)") ;
51+ Console . WriteLine ( "NOTE: Configure the GeneralSpacestation server with" ) ;
52+ Console . WriteLine ( " the desired test data before running." ) ;
53+ Console . WriteLine ( " - Chain data: TbPackets (IsCrossVersion=false)" ) ;
54+ Console . WriteLine ( " - Cross-version: additionally TbVersionArchives +" ) ;
55+ Console . WriteLine ( " TbPacket (IsCrossVersion=true," ) ;
56+ Console . WriteLine ( " FromVersion=currentVersion)" ) ;
8357 Console . WriteLine ( ) ;
8458
85- // Silent mode: polls server in background, prepares update, launches Upgrade on exit.
86- var bootstrap = await new GeneralUpdateBootstrap ( )
59+ // Non-silent immediate update flow:
60+ // 1. Version validation against server (HttpDownloadSource.ListAsync)
61+ // 2. Event dispatch (UpdateInfoEventArgs — shows available versions)
62+ // 3. Pre-check, hooks, backup
63+ // 4. Download all packages via DefaultDownloadOrchestrator
64+ // 5. Scenario dispatch:
65+ // - UpgradeOnly: apply upgrade packages in-place, client continues
66+ // - MainOnly: send MainApp versions via IPC → launch Upgrade process → exit
67+ // - Both: apply upgrade packages → IPC → launch Upgrade process → exit
68+ // - None: no-op
69+ await new GeneralUpdateBootstrap ( )
8770 . SetSource ( updateUrl , appSecretKey , reportUrl )
8871 . SetOption ( Option . AppType , AppType . Client )
89- . SetOption ( Option . Silent , true )
90- . SetOption ( Option . SilentPollIntervalMinutes , 1 )
9172 . Hooks < ClientTestHooks > ( )
9273 . AddListenerMultiDownloadStatistics ( OnDownloadStatistics )
9374 . AddListenerMultiDownloadCompleted ( OnDownloadCompleted )
@@ -97,54 +78,11 @@ static async Task RunStandardClientAsync()
9778 . AddListenerUpdateInfo ( OnUpdateInfo )
9879 . LaunchAsync ( ) ;
9980
100- var orchestrator = bootstrap . SilentOrchestrator ;
101-
102- Console . WriteLine ( ) ;
103- Console . WriteLine ( "╔════════════════════════════════════════════╗" ) ;
104- Console . WriteLine ( "║ Silent poll running in background. ║" ) ;
105- Console . WriteLine ( "║ Press Ctrl+C or Enter to exit. ║" ) ;
106- Console . WriteLine ( "║ On exit, Upgrade process will be launched ║" ) ;
107- Console . WriteLine ( "║ if an update has been prepared. ║" ) ;
108- Console . WriteLine ( "╚════════════════════════════════════════════╝" ) ;
109- Console . WriteLine ( ) ;
110-
111- // Keep the process alive so the background poll loop can work.
112- var cts = new CancellationTokenSource ( ) ;
113- Console . CancelKeyPress += ( _ , e ) =>
114- {
115- Console . WriteLine ( ) ;
116- Console . WriteLine ( "[Shutdown] Ctrl+C pressed. Exiting..." ) ;
117- e . Cancel = true ;
118- cts . Cancel ( ) ;
119- } ;
120-
121- try
122- {
123- await Task . Delay ( Timeout . Infinite , cts . Token ) ;
124- }
125- catch ( OperationCanceledException )
126- {
127- // Expected on Ctrl+C — graceful shutdown
128- }
129-
130- Console . WriteLine ( "[Shutdown] Launching upgrade process..." ) ;
131- if ( orchestrator != null && orchestrator . HasPreparedUpdate )
132- {
133- var launched = orchestrator . TryLaunchUpgrade ( ) ;
134- Console . WriteLine ( launched
135- ? "[Shutdown] Upgrade process launched successfully."
136- : "[Shutdown] No update prepared or upgrade already launched." ) ;
137- }
138- else
139- {
140- Console . WriteLine ( "[Shutdown] No orchestrator or no update prepared." ) ;
141- }
142-
143- Console . WriteLine ( "[Shutdown] Client test exiting gracefully." ) ;
81+ Console . WriteLine ( "Update test completed." ) ;
14482}
14583
14684// ═══════════════════════════════════════════════════════════════════
147- // Event handlers (shared across both modes)
85+ // Event handlers
14886// ═══════════════════════════════════════════════════════════════════
14987
15088static void OnDownloadStatistics ( object sender , MultiDownloadStatisticsEventArgs e )
@@ -183,7 +121,19 @@ static void OnUpdateInfo(object sender, UpdateInfoEventArgs e)
183121 if ( e . Info ? . Body is { Count : > 0 } )
184122 {
185123 foreach ( var vi in e . Info . Body )
186- Console . WriteLine ( $ " - { vi . Version } ({ vi . Name } ) [{ vi . Size } bytes] { ( vi . IsForcibly == true ? "(forced)" : "" ) } ") ;
124+ {
125+ var mode = vi . IsCrossVersion == true ? "CVP" : "Chain" ;
126+ var appType = vi . AppType switch
127+ {
128+ 1 => "Client" ,
129+ 2 => "Upgrade" ,
130+ _ => $ "Unknown({ vi . AppType } )"
131+ } ;
132+ Console . WriteLine ( $ " - [{ mode } ] { vi . Version } ({ vi . Name } ) [{ vi . Size } bytes] " +
133+ $ "AppType={ appType } " +
134+ $ "{ ( vi . IsForcibly == true ? "(forced)" : "" ) } " +
135+ $ "{ ( ! string . IsNullOrEmpty ( vi . FromVersion ) ? $ " from={ vi . FromVersion } " : "" ) } ") ;
136+ }
187137 }
188138 else
189139 {
@@ -192,7 +142,7 @@ static void OnUpdateInfo(object sender, UpdateInfoEventArgs e)
192142}
193143
194144// ═══════════════════════════════════════════════════════════════════
195- // Hooks (shared across both modes)
145+ // Hooks
196146// ═══════════════════════════════════════════════════════════════════
197147
198148sealed class ClientTestHooks : IUpdateHooks
0 commit comments