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+
115+ // We can ignore the fact that this level's title won't end on " test", since when we add a real migration job for a certain entity,
116+ // we also adjust that entity's creation/update methods in order to apply whatever change we want to new entities aswell.
117+ // We don't do it here, and it doesn't matter in this test.
118+ context . Database . Refresh ( ) ;
119+ GameLevel secondLevel = context . CreateLevel ( user ) ;
120+ // Should skip job because it's still "complete", so the new level won't be migrated.
121+ manager . RunWorkCycle ( ) ;
122+ context . Database . Refresh ( ) ;
123+
124+ GameLevel ? secondLevelFromDb = context . Database . GetLevelById ( secondLevel . LevelId ) ;
125+ Assert . That ( secondLevelFromDb , Is . Not . Null ) ;
126+ Assert . That ( secondLevelFromDb ! . Title , Does . Not . EndWith ( " test" ) ) ;
127+
128+ stateObject = context . Database . GetJobState ( typeof ( TestMigrationJob ) . Name , typeof ( MigrationJobState ) , WorkerClass . Refresh ) ;
129+ Assert . That ( stateObject , Is . Not . Null ) ;
130+
131+ jobState = ( MigrationJobState ) stateObject ! ;
132+ Assert . That ( jobState . Complete , Is . True ) ;
133+ Assert . That ( jobState . Processed , Is . EqualTo ( 1 ) ) ;
134+
135+ // 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
136+ // auto-removed by WorkerManager.Start() in real cases.
137+ context . Database . Refresh ( ) ;
138+ manager = new ( Logger , dataStore , context . DatabaseProvider ) ;
139+ GameLevel thirdLevel = context . CreateLevel ( user ) ;
140+
141+ manager . RemoveUnusedJobStates ( ) ;
142+ manager . RunWorkCycle ( ) ;
143+ context . Database . Refresh ( ) ;
144+
145+ // No new levels were migrated, and the job state was removed
146+ stateObject = context . Database . GetJobState ( typeof ( TestMigrationJob ) . Name , typeof ( MigrationJobState ) , WorkerClass . Refresh ) ;
147+ Assert . That ( stateObject , Is . Null ) ;
148+
149+ GameLevel ? secondLevelMigrated = context . Database . GetLevelById ( secondLevel . LevelId ) ;
150+ Assert . That ( secondLevelMigrated , Is . Not . Null ) ;
151+ Assert . That ( secondLevelMigrated ! . Title , Does . Not . EndWith ( " test" ) ) ;
152+
153+ GameLevel ? thirdLevelMigrated = context . Database . GetLevelById ( thirdLevel . LevelId ) ;
154+ Assert . That ( thirdLevelMigrated , Is . Not . Null ) ;
155+ Assert . That ( thirdLevelMigrated ! . Title , Does . Not . EndWith ( " test" ) ) ;
156+
157+ // Now simulate a re-update, where the job is in the WorkerManager again
158+ manager = new ( Logger , dataStore , context . DatabaseProvider ) ;
159+ job = new ( ) ;
160+ manager . AddJob ( job ) ;
161+ manager . RemoveUnusedJobStates ( ) ;
162+ manager . RunWorkCycle ( ) ;
163+ context . Database . Refresh ( ) ;
164+
165+ stateObject = context . Database . GetJobState ( typeof ( TestMigrationJob ) . Name , typeof ( MigrationJobState ) , WorkerClass . Refresh ) ;
166+ Assert . That ( stateObject , Is . Not . Null ) ;
167+
168+ jobState = ( MigrationJobState ) stateObject ! ;
169+ Assert . That ( jobState . Complete , Is . True ) ;
170+ Assert . That ( jobState . Processed , Is . EqualTo ( 3 ) ) ;
171+
172+ secondLevelMigrated = context . Database . GetLevelById ( secondLevel . LevelId ) ;
173+ Assert . That ( secondLevelMigrated , Is . Not . Null ) ;
174+ Assert . That ( secondLevelMigrated ! . Title , Does . EndWith ( " test" ) ) ;
175+
176+ thirdLevelMigrated = context . Database . GetLevelById ( thirdLevel . LevelId ) ;
177+ Assert . That ( thirdLevelMigrated , Is . Not . Null ) ;
178+ Assert . That ( thirdLevelMigrated ! . Title , Does . EndWith ( " test" ) ) ;
179+ }
180+ }
0 commit comments