Ray Milkey
Committed by Gerrit Code Review

Unit tests for packet processing the the AAA app

Change-Id: I51149fdf9ce5bfe4ee8d67564165b94f3e39e379
...@@ -44,31 +44,36 @@ ...@@ -44,31 +44,36 @@
44 44
45 <dependency> 45 <dependency>
46 <groupId>org.onosproject</groupId> 46 <groupId>org.onosproject</groupId>
47 - <artifactId>onlab-junit</artifactId> 47 + <artifactId>onos-api</artifactId>
48 - <scope>test</scope> 48 + <version>${project.version}</version>
49 </dependency> 49 </dependency>
50 50
51 <dependency> 51 <dependency>
52 <groupId>org.onosproject</groupId> 52 <groupId>org.onosproject</groupId>
53 - <artifactId>onos-api</artifactId> 53 + <artifactId>onos-app-xos-integration</artifactId>
54 <version>${project.version}</version> 54 <version>${project.version}</version>
55 </dependency> 55 </dependency>
56 56
57 <dependency> 57 <dependency>
58 <groupId>org.onosproject</groupId> 58 <groupId>org.onosproject</groupId>
59 - <artifactId>onlab-osgi</artifactId> 59 + <artifactId>onlab-junit</artifactId>
60 - <version>${project.version}</version> 60 + <scope>test</scope>
61 </dependency> 61 </dependency>
62 62
63 <dependency> 63 <dependency>
64 - <groupId>org.apache.felix</groupId> 64 + <groupId>org.onosproject</groupId>
65 - <artifactId>org.apache.felix.scr.annotations</artifactId> 65 + <artifactId>onlab-osgi</artifactId>
66 + <version>${project.version}</version>
67 + <classifier>tests</classifier>
68 + <scope>test</scope>
66 </dependency> 69 </dependency>
67 70
68 <dependency> 71 <dependency>
69 <groupId>org.onosproject</groupId> 72 <groupId>org.onosproject</groupId>
70 - <artifactId>onos-app-xos-integration</artifactId> 73 + <artifactId>onos-api</artifactId>
71 <version>${project.version}</version> 74 <version>${project.version}</version>
75 + <classifier>tests</classifier>
76 + <scope>test</scope>
72 </dependency> 77 </dependency>
73 </dependencies> 78 </dependencies>
74 79
......
...@@ -136,23 +136,23 @@ public class AAA { ...@@ -136,23 +136,23 @@ public class AAA {
136 136
137 @Property(name = "radiusIpAddress", value = DEFAULT_RADIUS_IP, 137 @Property(name = "radiusIpAddress", value = DEFAULT_RADIUS_IP,
138 label = "RADIUS IP Address") 138 label = "RADIUS IP Address")
139 - private String radiusIpAddress = DEFAULT_RADIUS_IP; 139 + protected String radiusIpAddress = DEFAULT_RADIUS_IP;
140 140
141 @Property(name = "nasIpAddress", value = DEFAULT_NAS_IP, 141 @Property(name = "nasIpAddress", value = DEFAULT_NAS_IP,
142 label = "NAS IP Address") 142 label = "NAS IP Address")
143 - private String nasIpAddress = DEFAULT_NAS_IP; 143 + protected String nasIpAddress = DEFAULT_NAS_IP;
144 144
145 @Property(name = "radiusMacAddress", value = RADIUS_MAC_ADDRESS, 145 @Property(name = "radiusMacAddress", value = RADIUS_MAC_ADDRESS,
146 label = "RADIUS MAC Address") 146 label = "RADIUS MAC Address")
147 - private String radiusMacAddress = RADIUS_MAC_ADDRESS; 147 + protected String radiusMacAddress = RADIUS_MAC_ADDRESS;
148 148
149 @Property(name = "nasMacAddress", value = NAS_MAC_ADDRESS, 149 @Property(name = "nasMacAddress", value = NAS_MAC_ADDRESS,
150 label = "NAS MAC Address") 150 label = "NAS MAC Address")
151 - private String nasMacAddress = NAS_MAC_ADDRESS; 151 + protected String nasMacAddress = NAS_MAC_ADDRESS;
152 152
153 @Property(name = "radiusSecret", value = DEFAULT_RADIUS_SECRET, 153 @Property(name = "radiusSecret", value = DEFAULT_RADIUS_SECRET,
154 label = "RADIUS shared secret") 154 label = "RADIUS shared secret")
155 - private String radiusSecret = DEFAULT_RADIUS_SECRET; 155 + protected String radiusSecret = DEFAULT_RADIUS_SECRET;
156 156
157 @Property(name = "radiusSwitchId", value = DEFAULT_RADIUS_SWITCH, 157 @Property(name = "radiusSwitchId", value = DEFAULT_RADIUS_SWITCH,
158 label = "Radius switch") 158 label = "Radius switch")
......
...@@ -15,29 +15,471 @@ ...@@ -15,29 +15,471 @@
15 */ 15 */
16 package org.onosproject.aaa; 16 package org.onosproject.aaa;
17 17
18 +import java.nio.ByteBuffer;
19 +import java.util.LinkedList;
20 +import java.util.List;
21 +import java.util.Set;
22 +
18 import org.junit.After; 23 import org.junit.After;
19 import org.junit.Before; 24 import org.junit.Before;
20 import org.junit.Test; 25 import org.junit.Test;
26 +import org.onlab.osgi.ComponentContextAdapter;
27 +import org.onlab.packet.Data;
28 +import org.onlab.packet.DeserializationException;
29 +import org.onlab.packet.EAP;
30 +import org.onlab.packet.EAPOL;
31 +import org.onlab.packet.EthType;
32 +import org.onlab.packet.Ethernet;
33 +import org.onlab.packet.IPv4;
34 +import org.onlab.packet.IpAddress;
35 +import org.onlab.packet.MacAddress;
36 +import org.onlab.packet.RADIUS;
37 +import org.onlab.packet.RADIUSAttribute;
38 +import org.onlab.packet.UDP;
39 +import org.onlab.packet.VlanId;
40 +import org.onosproject.cfg.ComponentConfigAdapter;
41 +import org.onosproject.core.CoreServiceAdapter;
42 +import org.onosproject.net.Annotations;
43 +import org.onosproject.net.Host;
44 +import org.onosproject.net.HostId;
45 +import org.onosproject.net.HostLocation;
46 +import org.onosproject.net.host.HostServiceAdapter;
47 +import org.onosproject.net.packet.DefaultInboundPacket;
48 +import org.onosproject.net.packet.DefaultPacketContext;
49 +import org.onosproject.net.packet.InboundPacket;
50 +import org.onosproject.net.packet.OutboundPacket;
51 +import org.onosproject.net.packet.PacketContext;
52 +import org.onosproject.net.packet.PacketProcessor;
53 +import org.onosproject.net.packet.PacketServiceAdapter;
54 +import org.onosproject.net.provider.ProviderId;
55 +
56 +import com.google.common.base.Charsets;
57 +import com.google.common.collect.ImmutableSet;
58 +
59 +import static org.hamcrest.Matchers.instanceOf;
60 +import static org.hamcrest.Matchers.is;
61 +import static org.hamcrest.Matchers.notNullValue;
62 +import static org.junit.Assert.assertThat;
63 +import static org.junit.Assert.fail;
64 +import static org.onosproject.net.NetTestTools.connectPoint;
21 65
22 /** 66 /**
23 * Set of tests of the ONOS application component. 67 * Set of tests of the ONOS application component.
24 */ 68 */
25 public class AAATest { 69 public class AAATest {
26 70
71 + MacAddress clientMac = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
72 + MacAddress serverMac = MacAddress.valueOf("2a:2a:2a:2a:2a:2a");
73 +
74 + PacketProcessor packetProcessor;
27 private AAA aaa; 75 private AAA aaa;
76 + List<Ethernet> savedPackets = new LinkedList<>();
77 +
78 + /**
79 + * Saves the given packet onto the saved packets list.
80 + *
81 + * @param eth packet to save
82 + */
83 + private void savePacket(Ethernet eth) {
84 + savedPackets.add(eth);
85 + }
86 +
87 + /**
88 + * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
89 + */
90 + private class MockPacketService extends PacketServiceAdapter {
91 +
92 + @Override
93 + public void addProcessor(PacketProcessor processor, int priority) {
94 + packetProcessor = processor;
95 + }
96 +
97 + @Override
98 + public void emit(OutboundPacket packet) {
99 + try {
100 + Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
101 + 0, packet.data().array().length);
102 + savePacket(eth);
103 + } catch (Exception e) {
104 + fail(e.getMessage());
105 + }
106 + }
107 + }
108 +
109 + /**
110 + * Mocks the DefaultPacketContext.
111 + */
112 + private final class TestPacketContext extends DefaultPacketContext {
113 +
114 + private TestPacketContext(long time, InboundPacket inPkt,
115 + OutboundPacket outPkt, boolean block) {
116 + super(time, inPkt, outPkt, block);
117 + }
118 +
119 + @Override
120 + public void send() {
121 + // We don't send anything out.
122 + }
123 + }
124 +
125 + /**
126 + * Mocks a host to allow locating the Radius server.
127 + */
128 + private static final class MockHost implements Host {
129 + @Override
130 + public HostId id() {
131 + return null;
132 + }
133 +
134 + @Override
135 + public MacAddress mac() {
136 + return null;
137 + }
138 +
139 + @Override
140 + public VlanId vlan() {
141 + return VlanId.vlanId(VlanId.UNTAGGED);
142 + }
143 +
144 + @Override
145 + public Set<IpAddress> ipAddresses() {
146 + return null;
147 + }
148 +
149 + @Override
150 + public HostLocation location() {
151 + return null;
152 + }
153 +
154 + @Override
155 + public Annotations annotations() {
156 + return null;
157 + }
158 +
159 + @Override
160 + public ProviderId providerId() {
161 + return null;
162 + }
163 + }
164 +
165 + /**
166 + * Mocks the Host service.
167 + */
168 + private static final class MockHostService extends HostServiceAdapter {
169 + @Override
170 + public Set<Host> getHostsByIp(IpAddress ip) {
171 + return ImmutableSet.of(new MockHost());
172 + }
173 + }
174 +
175 + /**
176 + * Sends an Ethernet packet to the process method of the Packet Processor.
177 + *
178 + * @param reply Ethernet packet
179 + */
180 + private void sendPacket(Ethernet reply) {
181 + final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
182 + InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
183 + reply,
184 + byteBuffer);
185 +
186 + PacketContext context = new TestPacketContext(127L, inPacket, null, false);
187 + packetProcessor.process(context);
188 + }
189 +
190 + /**
191 + * Constructs an Ethernet packet containing a EAPOL_START Payload.
192 + *
193 + * @return Ethernet packet
194 + */
195 + private Ethernet constructSupplicantStartPacket() {
196 + Ethernet eth = new Ethernet();
197 + eth.setDestinationMACAddress(clientMac.toBytes());
198 + eth.setSourceMACAddress(serverMac.toBytes());
199 + eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
200 + eth.setVlanID((short) 2);
201 +
202 + EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 1, EAPOL.EAPOL_START, null);
203 +
204 + //eapol header
205 + EAPOL eapol = new EAPOL();
206 + eapol.setEapolType(EAPOL.EAPOL_START);
207 + eapol.setPacketLength(eap.getLength());
208 +
209 + //eap part
210 + eapol.setPayload(eap);
211 +
212 + eth.setPayload(eapol);
213 + eth.setPad(true);
214 + return eth;
215 + }
216 +
217 + /**
218 + * Constructs an Ethernet packet containing identification payload.
219 + *
220 + * @return Ethernet packet
221 + */
222 + private Ethernet constructSupplicantIdentifyPacket(byte type) {
223 + Ethernet eth = new Ethernet();
224 + eth.setDestinationMACAddress(clientMac.toBytes());
225 + eth.setSourceMACAddress(serverMac.toBytes());
226 + eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
227 + eth.setVlanID((short) 2);
228 +
229 + String username = "user";
230 + EAP eap = new EAP(EAP.REQUEST, (byte) 1, type,
231 + username.getBytes(Charsets.US_ASCII));
232 + eap.setIdentifier((byte) 1);
233 +
234 + // eapol header
235 + EAPOL eapol = new EAPOL();
236 + eapol.setEapolType(EAPOL.EAPOL_PACKET);
237 + eapol.setPacketLength(eap.getLength());
238 +
239 + // eap part
240 + eapol.setPayload(eap);
241 +
242 + eth.setPayload(eapol);
243 + eth.setPad(true);
244 + return eth;
245 + }
28 246
247 + /**
248 + * Constructs an Ethernet packet containing a RADIUS challenge
249 + * packet.
250 + *
251 + * @param challengeCode code to use in challenge packet
252 + * @param challengeType type to use in challenge packet
253 + * @return Ethernet packet
254 + */
255 + private Ethernet constructRADIUSCodeAccessChallengePacket(byte challengeCode, byte challengeType) {
256 + Ethernet eth = new Ethernet();
257 + eth.setDestinationMACAddress(clientMac.toBytes());
258 + eth.setSourceMACAddress(serverMac.toBytes());
259 + eth.setEtherType(EthType.EtherType.IPV4.ethType().toShort());
260 + eth.setVlanID((short) 2);
261 +
262 + IPv4 ipv4 = new IPv4();
263 + ipv4.setProtocol(IPv4.PROTOCOL_UDP);
264 + ipv4.setSourceAddress("127.0.0.1");
265 +
266 + String challenge = "1234";
267 +
268 + EAP eap = new EAP(challengeType, (byte) 1, challengeType,
269 + challenge.getBytes(Charsets.US_ASCII));
270 + eap.setIdentifier((byte) 1);
271 +
272 + RADIUS radius = new RADIUS();
273 + radius.setCode(challengeCode);
274 +
275 + radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
276 + challenge.getBytes(Charsets.US_ASCII));
277 +
278 + radius.setPayload(eap);
279 + radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE,
280 + eap.serialize());
281 +
282 + UDP udp = new UDP();
283 + udp.setPayload(radius);
284 + ipv4.setPayload(udp);
285 +
286 + eth.setPayload(ipv4);
287 + eth.setPad(true);
288 + return eth;
289 + }
290 +
291 + /**
292 + * Sets up the services required by the AAA application.
293 + */
29 @Before 294 @Before
30 public void setUp() { 295 public void setUp() {
31 - 296 + aaa = new AAA();
297 + aaa.cfgService = new ComponentConfigAdapter();
298 + aaa.coreService = new CoreServiceAdapter();
299 + aaa.packetService = new MockPacketService();
300 + aaa.hostService = new MockHostService();
301 + aaa.activate(new ComponentContextAdapter());
32 } 302 }
33 303
304 + /**
305 + * Tears down the AAA application.
306 + */
34 @After 307 @After
35 public void tearDown() { 308 public void tearDown() {
309 + aaa.deactivate();
36 } 310 }
37 311
38 - @Test 312 + /**
39 - public void basics() { 313 + * Extracts the RADIUS packet from a packet sent by the supplicant.
314 + *
315 + * @param supplicantPacket packet sent by the supplicant
316 + * @return RADIUS packet
317 + * @throws DeserializationException if deserialization of the packet contents
318 + * fails.
319 + */
320 + private RADIUS checkAndFetchRADIUSPacketFromSupplicant(Ethernet supplicantPacket)
321 + throws DeserializationException {
322 + assertThat(supplicantPacket, notNullValue());
323 + assertThat(supplicantPacket.getVlanID(), is(VlanId.UNTAGGED));
324 + assertThat(supplicantPacket.getSourceMAC().toString(), is(aaa.nasMacAddress));
325 + assertThat(supplicantPacket.getDestinationMAC().toString(), is(aaa.radiusMacAddress));
326 +
327 + assertThat(supplicantPacket.getPayload(), instanceOf(IPv4.class));
328 + IPv4 ipv4 = (IPv4) supplicantPacket.getPayload();
329 + assertThat(ipv4, notNullValue());
330 + assertThat(IpAddress.valueOf(ipv4.getSourceAddress()).toString(),
331 + is(aaa.nasIpAddress));
332 + assertThat(IpAddress.valueOf(ipv4.getDestinationAddress()).toString(),
333 + is(aaa.radiusIpAddress));
334 +
335 + assertThat(ipv4.getPayload(), instanceOf(UDP.class));
336 + UDP udp = (UDP) ipv4.getPayload();
337 + assertThat(udp, notNullValue());
338 +
339 + assertThat(udp.getPayload(), instanceOf(Data.class));
340 + Data data = (Data) udp.getPayload();
341 + RADIUS radius = RADIUS.deserializer()
342 + .deserialize(data.getData(), 0, data.getData().length);
343 + assertThat(radius, notNullValue());
344 + return radius;
345 + }
346 +
347 + /**
348 + * Checks the contents of a RADIUS packet being sent to the RADIUS server.
349 + *
350 + * @param radiusPacket packet to check
351 + * @param code expected code
352 + */
353 + private void checkRadiusPacket(Ethernet radiusPacket, byte code) {
354 + assertThat(radiusPacket.getVlanID(), is((short) 2));
355 +
356 + // TODO: These address values seem wrong, but are produced by the current AAA implementation
357 + assertThat(radiusPacket.getSourceMAC(), is(MacAddress.valueOf(1L)));
358 + assertThat(radiusPacket.getDestinationMAC(), is(serverMac));
359 +
360 + assertThat(radiusPacket.getPayload(), instanceOf(EAPOL.class));
361 + EAPOL eapol = (EAPOL) radiusPacket.getPayload();
362 + assertThat(eapol, notNullValue());
363 +
364 + assertThat(eapol.getEapolType(), is(EAPOL.EAPOL_PACKET));
365 + assertThat(eapol.getPayload(), instanceOf(EAP.class));
366 + EAP eap = (EAP) eapol.getPayload();
367 + assertThat(eap, notNullValue());
368 + assertThat(eap.getCode(), is(code));
369 + }
40 370
371 + /**
372 + * Fetches the sent packet at the given index. The requested packet
373 + * must be the last packet on the list.
374 + *
375 + * @param index index into sent packets array
376 + * @return packet
377 + */
378 + private Ethernet fetchPacket(int index) {
379 + assertThat(savedPackets.size(), is(index + 1));
380 + Ethernet eth = savedPackets.get(index);
381 + assertThat(eth, notNullValue());
382 + return eth;
41 } 383 }
42 384
385 + /**
386 + * Tests the authentication path through the AAA application.
387 + *
388 + * @throws DeserializationException if packed deserialization fails.
389 + */
390 + @Test
391 + public void testAuthentication() throws DeserializationException {
392 +
393 + // Our session id will be the device ID ("of:1") with the port ("1") concatenated
394 + String sessionId = "of:11";
395 +
396 + // (1) Supplicant start up
397 +
398 + Ethernet startPacket = constructSupplicantStartPacket();
399 + sendPacket(startPacket);
400 +
401 + Ethernet responsePacket = fetchPacket(0);
402 + checkRadiusPacket(responsePacket, EAP.ATTR_IDENTITY);
403 +
404 + // (2) Supplicant identify
405 +
406 + Ethernet identifyPacket = constructSupplicantIdentifyPacket(EAP.ATTR_IDENTITY);
407 + sendPacket(identifyPacket);
408 +
409 + Ethernet radiusIdentifyPacket = fetchPacket(1);
410 +
411 + RADIUS radiusAccessRequest = checkAndFetchRADIUSPacketFromSupplicant(radiusIdentifyPacket);
412 + assertThat(radiusAccessRequest, notNullValue());
413 + assertThat(radiusAccessRequest.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
414 + assertThat(new String(radiusAccessRequest.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()),
415 + is("user"));
416 +
417 + IpAddress nasIp =
418 + IpAddress.valueOf(IpAddress.Version.INET,
419 + radiusAccessRequest.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP)
420 + .getValue());
421 + assertThat(nasIp.toString(), is("127.0.0.1"));
422 +
423 + // State machine should have been created by now
424 +
425 + StateMachine stateMachine =
426 + StateMachine.lookupStateMachineBySessionId(sessionId);
427 + assertThat(stateMachine, notNullValue());
428 + assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
429 +
430 + // (3) RADIUS MD5 challenge
431 +
432 + Ethernet radiusCodeAccessChallengePacket =
433 + constructRADIUSCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5);
434 + sendPacket(radiusCodeAccessChallengePacket);
435 +
436 + Ethernet radiusChallengeMD5Packet = fetchPacket(2);
437 + checkRadiusPacket(radiusChallengeMD5Packet, EAP.ATTR_MD5);
438 +
439 + // (4) Supplicant MD5 response
440 +
441 + Ethernet md5RadiusPacket = constructSupplicantIdentifyPacket(EAP.ATTR_MD5);
442 + sendPacket(md5RadiusPacket);
443 + Ethernet supplicantMD5ResponsePacket = fetchPacket(3);
444 + RADIUS responseMd5RadiusPacket = checkAndFetchRADIUSPacketFromSupplicant(supplicantMD5ResponsePacket);
445 + assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 1));
446 + assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
447 +
448 + // State machine should be in pending state
449 +
450 + assertThat(stateMachine, notNullValue());
451 + assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
452 +
453 + // (5) RADIUS TLS Challenge
454 +
455 + Ethernet radiusCodeAccessChallengeTLSPacket =
456 + constructRADIUSCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_TLS);
457 + sendPacket(radiusCodeAccessChallengeTLSPacket);
458 +
459 + Ethernet radiusChallengeTLSPacket = fetchPacket(4);
460 + checkRadiusPacket(radiusChallengeTLSPacket, EAP.ATTR_TLS);
461 +
462 + // (6) Supplicant TLS response
463 +
464 + Ethernet tlsRadiusPacket = constructSupplicantIdentifyPacket(EAP.ATTR_TLS);
465 + sendPacket(tlsRadiusPacket);
466 + Ethernet supplicantTLSResponsePacket = fetchPacket(5);
467 + RADIUS responseTLSRadiusPacket = checkAndFetchRADIUSPacketFromSupplicant(supplicantTLSResponsePacket);
468 + assertThat(responseTLSRadiusPacket.getIdentifier(), is((byte) 0));
469 + assertThat(responseTLSRadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
470 +
471 + // (7) RADIUS Success
472 +
473 + Ethernet successPacket =
474 + constructRADIUSCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT, EAP.SUCCESS);
475 + sendPacket(successPacket);
476 + Ethernet supplicantSuccessPacket = fetchPacket(6);
477 +
478 + checkRadiusPacket(supplicantSuccessPacket, EAP.SUCCESS);
479 +
480 + // State machine should be in authorized state
481 +
482 + assertThat(stateMachine, notNullValue());
483 + assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED));
484 + }
43 } 485 }
......
...@@ -17,10 +17,13 @@ package org.onosproject.cfg; ...@@ -17,10 +17,13 @@ package org.onosproject.cfg;
17 17
18 import java.util.Set; 18 import java.util.Set;
19 19
20 +import com.google.common.collect.ImmutableSet;
21 +
20 /** 22 /**
21 * Adapter for testing against component configuration service. 23 * Adapter for testing against component configuration service.
22 */ 24 */
23 public class ComponentConfigAdapter implements ComponentConfigService { 25 public class ComponentConfigAdapter implements ComponentConfigService {
26 +
24 @Override 27 @Override
25 public Set<String> getComponentNames() { 28 public Set<String> getComponentNames() {
26 return null; 29 return null;
...@@ -38,7 +41,7 @@ public class ComponentConfigAdapter implements ComponentConfigService { ...@@ -38,7 +41,7 @@ public class ComponentConfigAdapter implements ComponentConfigService {
38 41
39 @Override 42 @Override
40 public Set<ConfigProperty> getProperties(String componentName) { 43 public Set<ConfigProperty> getProperties(String componentName) {
41 - return null; 44 + return ImmutableSet.of();
42 } 45 }
43 46
44 @Override 47 @Override
......
...@@ -22,17 +22,56 @@ import org.osgi.service.component.ComponentContext; ...@@ -22,17 +22,56 @@ import org.osgi.service.component.ComponentContext;
22 import org.osgi.service.component.ComponentInstance; 22 import org.osgi.service.component.ComponentInstance;
23 23
24 import java.util.Dictionary; 24 import java.util.Dictionary;
25 +import java.util.Enumeration;
25 26
26 /** 27 /**
27 * Adapter implementation of OSGI component context. 28 * Adapter implementation of OSGI component context.
28 */ 29 */
29 public class ComponentContextAdapter implements ComponentContext { 30 public class ComponentContextAdapter implements ComponentContext {
31 + private static class MockDictionary extends Dictionary {
32 +
30 @Override 33 @Override
31 - public Dictionary getProperties() { 34 + public int size() {
35 + return 0;
36 + }
37 +
38 + @Override
39 + public boolean isEmpty() {
40 + return false;
41 + }
42 +
43 + @Override
44 + public Enumeration keys() {
32 return null; 45 return null;
33 } 46 }
34 47
35 @Override 48 @Override
49 + public Enumeration elements() {
50 + return null;
51 + }
52 +
53 + @Override
54 + public Object get(Object key) {
55 + return null;
56 + }
57 +
58 + @Override
59 + public Object put(Object key, Object value) {
60 + return null;
61 + }
62 +
63 + @Override
64 + public Object remove(Object key) {
65 + return null;
66 + }
67 + }
68 +
69 + @Override
70 + public Dictionary getProperties() {
71 + return new MockDictionary();
72 + }
73 +
74 + @Override
36 public Object locateService(String name) { 75 public Object locateService(String name) {
37 return null; 76 return null;
38 } 77 }
......