1+ using Bunkum . Core . Storage ;
2+ using Refresh . Database . Models . Levels ;
3+ using Refresh . Database . Models . Users ;
4+ using Refresh . Database . Models . Workers ;
5+ using Refresh . Workers ;
6+ using Refresh . Workers . State ;
7+
8+ namespace RefreshTests . GameServer . Tests . Workers ;
9+
10+ public class JobStateTests : GameServerTest
11+ {
12+ [ Test ]
13+ public void RemovesJobStateIfJobDoesntExist ( )
14+ {
15+ using TestContext context = this . GetServer ( ) ;
16+ IDataStore dataStore = context . GetDataStore ( ) ;
17+ WorkerManager manager = new ( Logger , dataStore , context . DatabaseProvider ) ;
18+
19+ context . Database . UpdateOrCreateJobState ( typeof ( TestMigrationJob ) . Name , new MigrationJobState ( ) , WorkerClass . Refresh ) ;
20+ Assert . That ( context . Database . GetJobState ( typeof ( TestMigrationJob ) . Name , typeof ( MigrationJobState ) , WorkerClass . Refresh ) , Is . Not . Null ) ;
21+
22+ manager . RemoveUnusedJobStates ( ) ;
23+ manager . RunWorkCycle ( ) ;
24+ context . Database . Refresh ( ) ;
25+
26+ object ? stateObject = context . Database . GetJobState ( typeof ( TestMigrationJob ) . Name , typeof ( MigrationJobState ) , WorkerClass . Refresh ) ;
27+ Assert . That ( stateObject , Is . Null ) ;
28+ }
29+
30+ [ Test ]
31+ [ TestCase ( true ) ]
32+ [ TestCase ( false ) ]
33+ public void DoesNotRemoveJobStateIfJobExists ( bool uploadLevel )
34+ {
35+ using TestContext context = this . GetServer ( ) ;
36+ IDataStore dataStore = context . GetDataStore ( ) ;
37+ WorkerManager manager = new ( Logger , dataStore , context . DatabaseProvider ) ;
38+ TestMigrationJob job = new ( ) ;
39+ manager . AddJob ( job ) ;
40+
41+ context . Database . UpdateOrCreateJobState ( typeof ( TestMigrationJob ) . Name , new MigrationJobState ( )
42+ {
43+ Total = uploadLevel ? 1 : 0 , // Since we're creating the state manually, instead of having WorkerManager do it
44+ } , WorkerClass . Refresh ) ;
45+ Assert . That ( context . Database . GetJobState ( typeof ( TestMigrationJob ) . Name , typeof ( MigrationJobState ) , WorkerClass . Refresh ) , Is . Not . Null ) ;
46+
47+ if ( uploadLevel )
48+ {
49+ context . CreateLevel ( context . CreateUser ( ) ) ;
50+ Assert . That ( context . Database . GetTotalLevelCount ( ) , Is . EqualTo ( 1 ) ) ;
51+
52+ }
53+ manager . RemoveUnusedJobStates ( ) ;
54+ manager . RunWorkCycle ( ) ;
55+ context . Database . Refresh ( ) ;
56+
57+ object ? stateObject = context . Database . GetJobState ( typeof ( TestMigrationJob ) . Name , typeof ( MigrationJobState ) , WorkerClass . Refresh ) ;
58+ Assert . That ( stateObject , Is . Not . Null ) ;
59+
60+ MigrationJobState jobState = ( MigrationJobState ) stateObject ! ;
61+ Assert . That ( jobState . Processed , Is . EqualTo ( uploadLevel ? 1 : 0 ) ) ;
62+ Assert . That ( jobState . Total , Is . EqualTo ( uploadLevel ? 1 : 0 ) ) ;
63+ Assert . That ( jobState . Complete , Is . True ) ;
64+ }
65+
66+ [ Test ]
67+ public void DoesNotRemoveJobStateIfNotRefreshClass ( )
68+ {
69+ using TestContext context = this . GetServer ( ) ;
70+ IDataStore dataStore = context . GetDataStore ( ) ;
71+ WorkerManager manager = new ( Logger , dataStore , context . DatabaseProvider ) ;
72+
73+ context . Database . UpdateOrCreateJobState ( typeof ( TestMigrationJob ) . Name , new MigrationJobState ( ) , WorkerClass . Craftworld ) ;
74+ Assert . That ( context . Database . GetJobState ( typeof ( TestMigrationJob ) . Name , typeof ( MigrationJobState ) , WorkerClass . Craftworld ) , Is . Not . Null ) ;
75+
76+ manager . RemoveUnusedJobStates ( ) ;
77+ manager . RunWorkCycle ( ) ;
78+ context . Database . Refresh ( ) ;
79+
80+ object ? stateObject = context . Database . GetJobState ( typeof ( TestMigrationJob ) . Name , typeof ( MigrationJobState ) , WorkerClass . Craftworld ) ;
81+ Assert . That ( stateObject , Is . Not . Null ) ;
82+
83+ MigrationJobState jobState = ( MigrationJobState ) stateObject ! ;
84+ Assert . That ( jobState . Complete , Is . True ) ;
85+ }
86+
87+ [ Test ]
88+ public void ReExecutesMigrationJobAfterRollbackAndReupdate ( )
89+ {
90+ using TestContext context = this . GetServer ( ) ;
91+ IDataStore dataStore = context . GetDataStore ( ) ;
92+ WorkerManager manager = new ( Logger , dataStore , context . DatabaseProvider ) ;
93+ TestMigrationJob job = new ( ) ;
94+ manager . AddJob ( job ) ;
95+
96+ GameUser user = context . CreateUser ( ) ;
97+ GameLevel firstLevel = context . CreateLevel ( user ) ;
98+
99+ // migrate first level
100+ manager . RemoveUnusedJobStates ( ) ;
101+ manager . RunWorkCycle ( ) ;
102+ context . Database . Refresh ( ) ;
103+
104+ object ? stateObject = context . Database . GetJobState ( typeof ( TestMigrationJob ) . Name , typeof ( MigrationJobState ) , WorkerClass . Refresh ) ;
105+ Assert . That ( stateObject , Is . Not . Null ) ;
106+
107+ MigrationJobState jobState = ( MigrationJobState ) stateObject ! ;
108+ Assert . That ( jobState . Complete , Is . True ) ;
109+ Assert . That ( jobState . Processed , Is . EqualTo ( 1 ) ) ;
110+
111+ GameLevel ? firstLevelMigrated = context . Database . GetLevelById ( firstLevel . LevelId ) ;
112+ Assert . That ( firstLevelMigrated , Is . Not . Null ) ;
113+ Assert . That ( firstLevelMigrated ! . Title , Does . EndWith ( " test" ) ) ;
114+ context . Database . Refresh ( ) ;
115+
116+ // While we do automatically apply whatever new change we've migrated existing entities to for real migrations (photo subjects, player limits etc.),
117+ // we don't auto-append " test" to new levels here, so we can safely create this level now, which would need migration aswell because of this.
118+ GameLevel secondLevel = context . CreateLevel ( user ) ;
119+ // Should skip job because it's still "complete", so the new level won't be migrated.
120+ manager . RunWorkCycle ( ) ;
121+ context . Database . Refresh ( ) ;
122+
123+ GameLevel ? secondLevelFromDb = context . Database . GetLevelById ( secondLevel . LevelId ) ;
124+ Assert . That ( secondLevelFromDb , Is . Not . Null ) ;
125+ Assert . That ( secondLevelFromDb ! . Title , Does . Not . EndWith ( " test" ) ) ;
126+
127+ stateObject = context . Database . GetJobState ( typeof ( TestMigrationJob ) . Name , typeof ( MigrationJobState ) , WorkerClass . Refresh ) ;
128+ Assert . That ( stateObject , Is . Not . Null ) ;
129+
130+ jobState = ( MigrationJobState ) stateObject ! ;
131+ Assert . That ( jobState . Complete , Is . True ) ;
132+ Assert . That ( jobState . Processed , Is . EqualTo ( 1 ) ) ;
133+
134+ // Simulate a roll-back, meaning the job wouldn't be in the WorkerManager anymore, so no migrations will happen, and the job state would be
135+ // auto-removed by WorkerManager.Start() in real cases.
136+ manager = new ( Logger , dataStore , context . DatabaseProvider ) ;
137+ manager . RemoveUnusedJobStates ( ) ;
138+ manager . RunWorkCycle ( ) ;
139+ context . Database . Refresh ( ) ;
140+
141+ // Second level was not migrated, and the job state was removed
142+ stateObject = context . Database . GetJobState ( typeof ( TestMigrationJob ) . Name , typeof ( MigrationJobState ) , WorkerClass . Refresh ) ;
143+ Assert . That ( stateObject , Is . Null ) ;
144+
145+ GameLevel ? secondLevelMigrated = context . Database . GetLevelById ( secondLevel . LevelId ) ;
146+ Assert . That ( secondLevelMigrated , Is . Not . Null ) ;
147+ Assert . That ( secondLevelMigrated ! . Title , Does . Not . EndWith ( " test" ) ) ;
148+
149+ // Now simulate a re-update, where the job is in the WorkerManager again
150+ manager = new ( Logger , dataStore , context . DatabaseProvider ) ;
151+ job = new ( ) ;
152+ manager . AddJob ( job ) ;
153+ manager . RemoveUnusedJobStates ( ) ;
154+ manager . RunWorkCycle ( ) ;
155+ context . Database . Refresh ( ) ;
156+
157+ stateObject = context . Database . GetJobState ( typeof ( TestMigrationJob ) . Name , typeof ( MigrationJobState ) , WorkerClass . Refresh ) ;
158+ Assert . That ( stateObject , Is . Not . Null ) ;
159+
160+ jobState = ( MigrationJobState ) stateObject ! ;
161+ Assert . That ( jobState . Complete , Is . True ) ;
162+ Assert . That ( jobState . Processed , Is . EqualTo ( 2 ) ) ;
163+
164+ secondLevelMigrated = context . Database . GetLevelById ( secondLevel . LevelId ) ;
165+ Assert . That ( secondLevelMigrated , Is . Not . Null ) ;
166+ Assert . That ( secondLevelMigrated ! . Title , Does . EndWith ( " test" ) ) ;
167+ }
168+ }
0 commit comments