1717package com .ctrip .framework .apollo .internals ;
1818
1919import static org .junit .Assert .assertEquals ;
20+ import static org .junit .Assert .assertNotSame ;
21+ import static org .junit .Assert .assertTrue ;
2022import static org .mockito .ArgumentMatchers .any ;
2123import static org .mockito .ArgumentMatchers .eq ;
2224import static org .mockito .Mockito .spy ;
2830import com .ctrip .framework .apollo .enums .PropertyChangeType ;
2931import com .ctrip .framework .apollo .model .ConfigChange ;
3032import com .ctrip .framework .apollo .model .ConfigChangeEvent ;
33+ import com .ctrip .framework .apollo .spring .config .CachedCompositePropertySource ;
3134import com .google .common .util .concurrent .SettableFuture ;
3235import java .util .Collections ;
3336import java .util .HashMap ;
@@ -122,6 +125,36 @@ public void onChange(ConfigChangeEvent changeEvent) {
122125 verify (configChangeListener2 , times (1 )).onChange (eq (configChangeEvent ));
123126 }
124127
128+ @ Test
129+ public void testFireConfigChange_twoCachedCompositePropertySourcesWithSameName_shouldBothBeNotified ()
130+ throws InterruptedException {
131+ AbstractConfig abstractConfig = new ErrorConfig ();
132+ final String namespace = "app-namespace-listener-equals" ;
133+ final String key = "great-key" ;
134+
135+ final CountingCachedCompositePropertySource listener1 =
136+ new CountingCachedCompositePropertySource ("ApolloBootstrapPropertySources" );
137+ final CountingCachedCompositePropertySource listener2 =
138+ new CountingCachedCompositePropertySource ("ApolloBootstrapPropertySources" );
139+
140+ assertNotSame (listener1 , listener2 );
141+ assertTrue (listener1 .equals (listener2 ));
142+
143+ abstractConfig .addChangeListener (listener1 , Collections .singleton (key ));
144+ abstractConfig .addChangeListener (listener2 , Collections .singleton (key ));
145+
146+ Map <String , ConfigChange > changes = new HashMap <>();
147+ changes .put (key ,
148+ new ConfigChange (someAppId , namespace , key , "old-value" , "new-value" , PropertyChangeType .MODIFIED ));
149+
150+ abstractConfig .fireConfigChange (someAppId , namespace , changes );
151+
152+ Thread .sleep (100 );
153+
154+ assertEquals (1 , listener1 .changeCount .get ());
155+ assertEquals (1 , listener2 .changeCount .get ());
156+ }
157+
125158 @ Test
126159 public void testFireConfigChange_changes_notify_once ()
127160 throws ExecutionException , InterruptedException , TimeoutException {
@@ -188,4 +221,18 @@ public ConfigSourceType getSourceType() {
188221 throw new UnsupportedOperationException ();
189222 }
190223 }
191- }
224+
225+ private static class CountingCachedCompositePropertySource extends CachedCompositePropertySource {
226+ private final AtomicInteger changeCount = new AtomicInteger ();
227+
228+ private CountingCachedCompositePropertySource (String name ) {
229+ super (name );
230+ }
231+
232+ @ Override
233+ public void onChange (ConfigChangeEvent changeEvent ) {
234+ changeCount .incrementAndGet ();
235+ super .onChange (changeEvent );
236+ }
237+ }
238+ }
0 commit comments