1
+ /*
2
+ * Copyright 1999-$toady.year Alibaba Group Holding Ltd.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ package com .alibaba .nacos .config .server .service .dump .processor ;
18
+
19
+ import com .alibaba .nacos .common .task .NacosTask ;
20
+ import com .alibaba .nacos .common .utils .MD5Utils ;
21
+ import com .alibaba .nacos .config .server .model .CacheItem ;
22
+ import com .alibaba .nacos .config .server .model .ConfigInfoGrayWrapper ;
23
+ import com .alibaba .nacos .config .server .service .ConfigCacheService ;
24
+ import com .alibaba .nacos .config .server .service .dump .ExternalDumpService ;
25
+ import com .alibaba .nacos .config .server .service .dump .disk .ConfigDiskServiceFactory ;
26
+ import com .alibaba .nacos .config .server .service .dump .task .DumpAllGrayTask ;
27
+ import com .alibaba .nacos .config .server .service .repository .ConfigInfoGrayPersistService ;
28
+ import com .alibaba .nacos .config .server .service .repository .ConfigInfoPersistService ;
29
+ import com .alibaba .nacos .config .server .utils .GroupKey2 ;
30
+ import com .alibaba .nacos .config .server .utils .PropertyUtil ;
31
+ import com .alibaba .nacos .persistence .datasource .DataSourceService ;
32
+ import com .alibaba .nacos .persistence .datasource .DynamicDataSource ;
33
+ import com .alibaba .nacos .persistence .model .Page ;
34
+ import com .alibaba .nacos .plugin .datasource .constants .CommonConstant ;
35
+ import com .alibaba .nacos .sys .env .EnvUtil ;
36
+ import org .junit .jupiter .api .AfterEach ;
37
+ import org .junit .jupiter .api .BeforeEach ;
38
+ import org .junit .jupiter .api .Test ;
39
+ import org .junit .jupiter .api .extension .ExtendWith ;
40
+ import org .mockito .Mock ;
41
+ import org .mockito .MockedStatic ;
42
+ import org .mockito .Mockito ;
43
+ import org .mockito .junit .jupiter .MockitoExtension ;
44
+
45
+ import java .util .ArrayList ;
46
+ import java .util .Arrays ;
47
+ import java .util .List ;
48
+
49
+ import static org .junit .jupiter .api .Assertions .assertEquals ;
50
+ import static org .junit .jupiter .api .Assertions .assertFalse ;
51
+ import static org .junit .jupiter .api .Assertions .assertTrue ;
52
+ import static org .mockito .ArgumentMatchers .anyInt ;
53
+ import static org .mockito .ArgumentMatchers .eq ;
54
+ import static org .mockito .Mockito .atLeast ;
55
+ import static org .mockito .Mockito .mock ;
56
+ import static org .mockito .Mockito .never ;
57
+ import static org .mockito .Mockito .times ;
58
+ import static org .mockito .Mockito .verify ;
59
+ import static org .mockito .Mockito .when ;
60
+
61
+ @ ExtendWith (MockitoExtension .class )
62
+ class DumpAllGrayProcessorTest {
63
+
64
+ private static final int PAGE_SIZE = 100 ;
65
+
66
+ @ Mock
67
+ DynamicDataSource dynamicDataSource ;
68
+
69
+ @ Mock
70
+ DataSourceService dataSourceService ;
71
+
72
+ @ Mock
73
+ ConfigInfoGrayPersistService configInfoGrayPersistService ;
74
+
75
+ DumpAllProcessor dumpAllProcessor ;
76
+
77
+ DumpAllGrayProcessor dumpAllGrayProcessor ;
78
+
79
+ ExternalDumpService dumpService ;
80
+
81
+ MockedStatic <DynamicDataSource > dynamicDataSourceMockedStatic ;
82
+
83
+ MockedStatic <PropertyUtil > propertyUtilMockedStatic ;
84
+
85
+ @ Mock
86
+ ConfigInfoPersistService configInfoPersistService ;
87
+
88
+ MockedStatic <EnvUtil > envUtilMockedStatic ;
89
+
90
+ private String mockMem = "tmpmocklimitfile.txt" ;
91
+
92
+ @ BeforeEach
93
+ void init () throws Exception {
94
+ dynamicDataSourceMockedStatic = Mockito .mockStatic (DynamicDataSource .class );
95
+ envUtilMockedStatic = Mockito .mockStatic (EnvUtil .class );
96
+ propertyUtilMockedStatic = Mockito .mockStatic (PropertyUtil .class );
97
+ propertyUtilMockedStatic .when (PropertyUtil ::getAllDumpPageSize ).thenReturn (100 );
98
+ dumpAllGrayProcessor = new DumpAllGrayProcessor (configInfoGrayPersistService );
99
+ when (EnvUtil .getNacosHome ()).thenReturn (System .getProperty ("user.home" ));
100
+ when (EnvUtil .getProperty (eq (CommonConstant .NACOS_PLUGIN_DATASOURCE_LOG ), eq (Boolean .class ),
101
+ eq (false ))).thenReturn (false );
102
+ dynamicDataSourceMockedStatic .when (DynamicDataSource ::getInstance ).thenReturn (dynamicDataSource );
103
+
104
+ when (dynamicDataSource .getDataSource ()).thenReturn (dataSourceService );
105
+
106
+ dumpService = new ExternalDumpService (configInfoPersistService , null , null , configInfoGrayPersistService , null );
107
+
108
+ dumpAllProcessor = new DumpAllProcessor (configInfoPersistService );
109
+ envUtilMockedStatic .when (() -> EnvUtil .getProperty (eq ("memory_limit_file_path" ),
110
+ eq ("/sys/fs/cgroup/memory/memory.limit_in_bytes" ))).thenReturn (mockMem );
111
+
112
+ }
113
+
114
+ @ AfterEach
115
+ void after () {
116
+ dynamicDataSourceMockedStatic .close ();
117
+ envUtilMockedStatic .close ();
118
+ propertyUtilMockedStatic .close ();
119
+ }
120
+
121
+ @ Test
122
+ void testProcessWithInvalidTaskType () {
123
+ NacosTask invalidTask = mock (NacosTask .class );
124
+
125
+ boolean result = dumpAllGrayProcessor .process (invalidTask );
126
+
127
+ assertFalse (result );
128
+ verify (configInfoGrayPersistService , never ()).configInfoGrayCount ();
129
+ }
130
+
131
+ @ Test
132
+ void testProcessWithValidTaskType () throws Exception {
133
+ final DumpAllGrayTask validTask = mock (DumpAllGrayTask .class );
134
+ List <ConfigInfoGrayWrapper > configList = new ArrayList <>();
135
+ configList .add (createGrayWrapper ("dataId-1" , "group-1" ));
136
+
137
+ Page <ConfigInfoGrayWrapper > page = new Page <>();
138
+ when (configInfoGrayPersistService .configInfoGrayCount ()).thenReturn (1 );
139
+ when (configInfoGrayPersistService .findAllConfigInfoGrayForDumpAll (anyInt (), anyInt ())).thenReturn (page );
140
+
141
+ boolean result = dumpAllGrayProcessor .process (validTask );
142
+
143
+ assertTrue (result );
144
+ verify (configInfoGrayPersistService , times (1 )).configInfoGrayCount ();
145
+ verify (configInfoGrayPersistService , times (1 )).findAllConfigInfoGrayForDumpAll (anyInt (), anyInt ());
146
+ }
147
+
148
+ @ Test
149
+ void testPaginationLogic () {
150
+ DumpAllGrayTask task = mock (DumpAllGrayTask .class );
151
+ int totalConfigs = PAGE_SIZE * 2 + 50 ;
152
+ when (configInfoGrayPersistService .configInfoGrayCount ()).thenReturn (totalConfigs );
153
+
154
+ Page <ConfigInfoGrayWrapper > pageOne = new Page <>();
155
+ when (configInfoGrayPersistService .findAllConfigInfoGrayForDumpAll (eq (1 ), anyInt ())).thenReturn (pageOne );
156
+
157
+ boolean result = dumpAllGrayProcessor .process (task );
158
+
159
+ assertTrue (result );
160
+ verify (configInfoGrayPersistService , atLeast (2 )).findAllConfigInfoGrayForDumpAll (anyInt (), anyInt ());
161
+ }
162
+
163
+ @ Test
164
+ void testInteractionWithConfigCacheService () {
165
+ DumpAllGrayTask task = mock (DumpAllGrayTask .class );
166
+ Page <ConfigInfoGrayWrapper > page = new Page <>();
167
+ when (configInfoGrayPersistService .configInfoGrayCount ()).thenReturn (1 );
168
+ when (configInfoGrayPersistService .findAllConfigInfoGrayForDumpAll (anyInt (), anyInt ())).thenReturn (page );
169
+ boolean result = dumpAllGrayProcessor .process (task );
170
+ assertTrue (result );
171
+ }
172
+
173
+ /**
174
+ * test dump all for all check task.
175
+ */
176
+ @ Test
177
+ void testDumpAllGrayOnCheckAll () throws Exception {
178
+ ConfigInfoGrayWrapper configInfoGrayWrapper1 = createGrayWrapper ("data-1" , "group-1" );
179
+ ConfigInfoGrayWrapper configInfoGrayWrapper2 = createGrayWrapper ("data-2" , "group-2" );
180
+ long timestamp = System .currentTimeMillis ();
181
+ configInfoGrayWrapper1 .setLastModified (timestamp );
182
+ configInfoGrayWrapper2 .setLastModified (timestamp );
183
+
184
+ Page <ConfigInfoGrayWrapper > page = new Page <>();
185
+ page .setTotalCount (2 );
186
+ page .setPagesAvailable (2 );
187
+ page .setPageNumber (1 );
188
+ List <ConfigInfoGrayWrapper > list = Arrays .asList (configInfoGrayWrapper1 , configInfoGrayWrapper2 );
189
+ page .setPageItems (list );
190
+
191
+ Mockito .when (configInfoGrayPersistService .configInfoGrayCount ()).thenReturn (2 );
192
+ Mockito .when (configInfoGrayPersistService .findAllConfigInfoGrayForDumpAll (anyInt (), anyInt ())).thenReturn (page );
193
+
194
+ final String md51 = MD5Utils .md5Hex (configInfoGrayWrapper1 .getContent (), "UTF-8" );
195
+ final String md52 = MD5Utils .md5Hex (configInfoGrayWrapper2 .getContent (), "UTF-8" );
196
+ long latterTimestamp = timestamp + 999 ;
197
+ long earlierTimestamp = timestamp - 999 ;
198
+ String encryptedDataKey = "testEncryptedDataKey" ;
199
+
200
+ String dataId1 = configInfoGrayWrapper1 .getDataId ();
201
+ String group1 = configInfoGrayWrapper1 .getGroup ();
202
+ String grayName1 = configInfoGrayWrapper1 .getGrayName ();
203
+ String grayRule1 = configInfoGrayWrapper1 .getGrayRule ();
204
+ String tenant1 = configInfoGrayWrapper1 .getTenant ();
205
+ String content1 = configInfoGrayWrapper1 .getContent ();
206
+
207
+ String dataId2 = configInfoGrayWrapper2 .getDataId ();
208
+ String group2 = configInfoGrayWrapper2 .getGroup ();
209
+ String grayName2 = configInfoGrayWrapper2 .getGrayName ();
210
+ String grayRule2 = configInfoGrayWrapper2 .getGrayRule ();
211
+ String tenant2 = configInfoGrayWrapper2 .getTenant ();
212
+ String content2 = configInfoGrayWrapper2 .getContent ();
213
+
214
+ ConfigCacheService .dumpGray (dataId1 , group1 , tenant1 , grayName1 , grayRule1 , content1 , latterTimestamp , encryptedDataKey );
215
+ ConfigCacheService .dumpGray (dataId2 , group2 , tenant2 , grayName2 , grayRule2 , content2 , earlierTimestamp , encryptedDataKey );
216
+
217
+ DumpAllGrayTask dumpAllTask = new DumpAllGrayTask ();
218
+ boolean process = dumpAllGrayProcessor .process (dumpAllTask );
219
+
220
+ assertTrue (process );
221
+
222
+ CacheItem contentCache1 = ConfigCacheService .getContentCache (
223
+ GroupKey2 .getKey (configInfoGrayWrapper1 .getDataId (), configInfoGrayWrapper1 .getGroup (),
224
+ configInfoGrayWrapper1 .getTenant ()));
225
+ assertEquals (md51 , contentCache1 .getConfigCacheGray ().get (grayName1 ).getMd5 ());
226
+ assertEquals (latterTimestamp , contentCache1 .getConfigCacheGray ().get (grayName1 ).getLastModifiedTs ());
227
+
228
+ String contentFromDisk1 = ConfigDiskServiceFactory .getInstance ()
229
+ .getGrayContent (configInfoGrayWrapper1 .getDataId (), configInfoGrayWrapper1 .getGroup (),
230
+ configInfoGrayWrapper1 .getTenant (), configInfoGrayWrapper1 .getGrayName ());
231
+ assertEquals (configInfoGrayWrapper1 .getContent (), contentFromDisk1 );
232
+
233
+ CacheItem contentCache2 = ConfigCacheService .getContentCache (
234
+ GroupKey2 .getKey (configInfoGrayWrapper2 .getDataId (), configInfoGrayWrapper2 .getGroup (),
235
+ configInfoGrayWrapper2 .getTenant ()));
236
+ assertEquals (md52 , contentCache2 .getConfigCacheGray ().get (grayName2 ).getMd5 ());
237
+ assertEquals (configInfoGrayWrapper2 .getLastModified (), contentCache2 .getConfigCacheGray ().get (grayName2 ).getLastModifiedTs ());
238
+
239
+ String contentFromDisk2 = ConfigDiskServiceFactory .getInstance ()
240
+ .getGrayContent (configInfoGrayWrapper2 .getDataId (), configInfoGrayWrapper2 .getGroup (),
241
+ configInfoGrayWrapper2 .getTenant (), configInfoGrayWrapper2 .getGrayName ());
242
+ assertEquals (configInfoGrayWrapper2 .getContent (), contentFromDisk2 );
243
+ }
244
+
245
+ private ConfigInfoGrayWrapper createGrayWrapper (String dataId , String group ) {
246
+ ConfigInfoGrayWrapper wrapper = new ConfigInfoGrayWrapper ();
247
+ wrapper .setDataId (dataId );
248
+ wrapper .setGroup (group );
249
+ wrapper .setTenant ("tenant" );
250
+ wrapper .setGrayName ("gray-" + dataId );
251
+ String grayRule = "{\" type\" :\" beta\" ,\" version\" :\" 1.0.0\" ,\" expr\" :\" 0 0/5 * * * ?\" ,\" priority\" :1}" ;
252
+ wrapper .setGrayRule (grayRule );
253
+ wrapper .setContent ("content" );
254
+ wrapper .setLastModified (System .currentTimeMillis ());
255
+ wrapper .setEncryptedDataKey ("enc-key" );
256
+ wrapper .setMd5 (MD5Utils .md5Hex (wrapper .getContent (), "UTF-8" ));
257
+ return wrapper ;
258
+ }
259
+ }
0 commit comments