1 /*******************************************************************************
2  * Copyright (c) 2007, 2012 IBM Corporation and others
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.equinox.cm.test;
15 
16 import static org.junit.Assert.*;
17 
18 import java.util.Dictionary;
19 import java.util.Hashtable;
20 import org.eclipse.equinox.log.ExtendedLogReaderService;
21 import org.eclipse.equinox.log.LogFilter;
22 import org.junit.*;
23 import org.osgi.framework.*;
24 import org.osgi.service.cm.*;
25 import org.osgi.service.log.*;
26 
27 public class ManagedServiceTest {
28 
29 	private ConfigurationAdmin cm;
30 	private ServiceReference<ConfigurationAdmin> reference;
31 	int updateCount = 0;
32 	boolean locked = false;
33 	Object lock = new Object();
34 
35 	@Before
setUp()36 	public void setUp() throws Exception {
37 		Activator.getBundle("org.eclipse.equinox.cm").start();
38 		reference = Activator.getBundleContext().getServiceReference(ConfigurationAdmin.class);
39 		cm = Activator.getBundleContext().getService(reference);
40 	}
41 
42 	@After
tearDown()43 	public void tearDown() throws Exception {
44 		Activator.getBundleContext().ungetService(reference);
45 		Activator.getBundle("org.eclipse.equinox.cm").stop();
46 	}
47 
48 	@Test
testSamePidManagedService()49 	public void testSamePidManagedService() throws Exception {
50 
51 		Configuration config = cm.getConfiguration("test");
52 		Dictionary<String, Object> props = new Hashtable<String, Object>();
53 		props.put("testkey", "testvalue");
54 		config.update(props);
55 
56 		updateCount = 0;
57 		ManagedService ms = new ManagedService() {
58 
59 			public void updated(Dictionary<String, ?> properties) {
60 				synchronized (lock) {
61 					locked = false;
62 					lock.notify();
63 					updateCount++;
64 				}
65 
66 			}
67 		};
68 
69 		Dictionary<String, Object> dict = new Hashtable<String, Object>();
70 		dict.put(Constants.SERVICE_PID, "test");
71 		ServiceRegistration<ManagedService> reg = null;
72 		synchronized (lock) {
73 			reg = Activator.getBundleContext().registerService(ManagedService.class, ms, dict);
74 			locked = true;
75 			lock.wait(5000);
76 			if (locked)
77 				fail("should have updated");
78 			assertEquals(1, updateCount);
79 		}
80 
81 		ServiceRegistration<ManagedService> reg2 = null;
82 		synchronized (lock) {
83 			reg2 = Activator.getBundleContext().registerService(ManagedService.class, ms, dict);
84 			locked = true;
85 			lock.wait(5000);
86 			if (locked)
87 				fail("should have updated");
88 			assertEquals(2, updateCount);
89 		}
90 		reg.unregister();
91 		reg2.unregister();
92 		config.delete();
93 	}
94 
95 	@Test
testBug374637()96 	public void testBug374637() throws Exception {
97 
98 		ManagedService ms = new ManagedService() {
99 
100 			public void updated(Dictionary<String, ?> properties) {
101 				// nothing
102 			}
103 		};
104 
105 		ExtendedLogReaderService reader = Activator.getBundleContext().getService(Activator.getBundleContext().getServiceReference(ExtendedLogReaderService.class));
106 		synchronized (lock) {
107 			locked = false;
108 		}
109 		LogListener listener = new LogListener() {
110 			public void logged(LogEntry entry) {
111 				synchronized (lock) {
112 					locked = true;
113 					lock.notifyAll();
114 				}
115 			}
116 		};
117 		reader.addLogListener(listener, new LogFilter() {
118 			public boolean isLoggable(Bundle bundle, String loggerName, int logLevel) {
119 				return logLevel == LogService.LOG_ERROR;
120 			}
121 		});
122 		Dictionary<String, Object> dict = new Hashtable<String, Object>();
123 		dict.put(Constants.SERVICE_PID, "test");
124 		ServiceRegistration<ManagedService> reg1 = Activator.getBundleContext().registerService(ManagedService.class, ms, dict);
125 		ServiceRegistration<ManagedService> reg2 = Activator.getBundleContext().registerService(ManagedService.class, ms, dict);
126 
127 		reg1.unregister();
128 		reg2.unregister();
129 		reader.removeLogListener(listener);
130 
131 		synchronized (lock) {
132 			lock.wait(1000);
133 			assertFalse("Got a error log", locked);
134 		}
135 	}
136 
137 	@Test
testGeneralManagedService()138 	public void testGeneralManagedService() throws Exception {
139 		updateCount = 0;
140 		ManagedService ms = new ManagedService() {
141 
142 			public void updated(Dictionary<String, ?> properties) {
143 				synchronized (lock) {
144 					locked = false;
145 					lock.notify();
146 					updateCount++;
147 				}
148 
149 			}
150 		};
151 
152 		Dictionary<String, Object> dict = new Hashtable<String, Object>();
153 		dict.put(Constants.SERVICE_PID, "test");
154 
155 		ServiceRegistration<ManagedService> reg = null;
156 		synchronized (lock) {
157 			reg = Activator.getBundleContext().registerService(ManagedService.class, ms, dict);
158 			locked = true;
159 			lock.wait(5000);
160 			if (locked)
161 				fail("should have updated");
162 			assertEquals(1, updateCount);
163 		}
164 
165 		Configuration config = cm.getConfiguration("test");
166 		assertNull(config.getProperties());
167 		Dictionary<String, Object> props = new Hashtable<String, Object>();
168 		props.put("testkey", "testvalue");
169 
170 		synchronized (lock) {
171 			config.update(props);
172 			locked = true;
173 			lock.wait(5000);
174 			if (locked)
175 				fail("should have updated");
176 			assertEquals(2, updateCount);
177 		}
178 
179 		String location = config.getBundleLocation();
180 
181 		synchronized (lock) {
182 			config.setBundleLocation("bogus");
183 			locked = true;
184 			lock.wait(5000);
185 			if (locked)
186 				fail("should have updated");
187 			assertEquals(3, updateCount);
188 		}
189 
190 		synchronized (lock) {
191 			config.update();
192 			locked = true;
193 			lock.wait(100);
194 			assertTrue(locked);
195 			assertEquals(3, updateCount);
196 			locked = false;
197 		}
198 
199 		synchronized (lock) {
200 			config.setBundleLocation(location);
201 			locked = true;
202 			lock.wait(5000);
203 			if (locked)
204 				fail("should have updated");
205 			assertEquals(4, updateCount);
206 		}
207 
208 		dict.remove(Constants.SERVICE_PID);
209 		synchronized (lock) {
210 			reg.setProperties(dict);
211 			locked = true;
212 			lock.wait(100);
213 			assertTrue(locked);
214 			assertEquals(4, updateCount);
215 			locked = false;
216 		}
217 
218 		synchronized (lock) {
219 			props.put("testkey", "testvalue2");
220 			config.update(props);
221 			locked = true;
222 			lock.wait(100);
223 			assertTrue(locked);
224 			assertEquals(4, updateCount);
225 			locked = false;
226 		}
227 
228 		config.delete();
229 		config = cm.getConfiguration("test2");
230 		dict.put(Constants.SERVICE_PID, "test2");
231 		synchronized (lock) {
232 			reg.setProperties(dict);
233 			locked = true;
234 			lock.wait(5000);
235 			if (locked)
236 				fail("should have updated");
237 			assertEquals(5, updateCount);
238 		}
239 
240 		synchronized (lock) {
241 			config.delete();
242 			locked = true;
243 			lock.wait(5000);
244 			if (locked)
245 				fail("should have updated");
246 			assertEquals(6, updateCount);
247 		}
248 		reg.unregister();
249 	}
250 }
251