blob: 3d7ace4499c9ddd5c5dd50cb197d7b745319f00e [file] [log] [blame]
/*
* Copyright (c) 2020 Kentyou.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Kentyou - initial API and implementation
*/
package org.eclipse.sensinact.gateway.core.test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.List;
import org.eclipse.sensinact.gateway.common.bundle.Mediator;
import org.eclipse.sensinact.gateway.core.InvalidServiceProviderException;
import org.eclipse.sensinact.gateway.core.ModelConfiguration;
import org.eclipse.sensinact.gateway.core.ModelConfigurationBuilder;
import org.eclipse.sensinact.gateway.core.ModelInstance;
import org.eclipse.sensinact.gateway.core.ModelInstanceBuilder;
import org.eclipse.sensinact.gateway.core.SensiNact;
import org.eclipse.sensinact.gateway.core.SensiNactResourceModel;
import org.eclipse.sensinact.gateway.core.filtering.Filtering;
import org.eclipse.sensinact.gateway.core.message.SnaAgent;
import org.eclipse.sensinact.gateway.core.security.AuthenticationService;
import org.eclipse.sensinact.gateway.core.security.AuthorizationService;
import org.eclipse.sensinact.gateway.core.security.SecuredAccess;
import org.eclipse.sensinact.gateway.core.security.SecuredAccessException;
import org.eclipse.sensinact.gateway.datastore.api.DataStoreException;
import org.eclipse.sensinact.gateway.datastore.api.DataStoreService;
import org.eclipse.sensinact.gateway.security.signature.api.BundleValidation;
import org.eclipse.sensinact.gateway.security.signature.exception.BundleValidationException;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.log.LogService;
/**
* Test Context
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class TestContext<R extends ModelInstance> {
private static final String LOG_FILTER = "(" + Constants.OBJECTCLASS + "=" + LogService.class.getCanonicalName()
+ ")";
private static final String DATA_STORE_FILTER = "(" + Constants.OBJECTCLASS + "="
+ DataStoreService.class.getCanonicalName() + ")";
private static final String AUTHENTICATION_FILTER = "(" + Constants.OBJECTCLASS + "="
+ AuthenticationService.class.getCanonicalName() + ")";
private static final String ACCESS_FILTER = "(" + Constants.OBJECTCLASS + "="
+ SecuredAccess.class.getCanonicalName() + ")";
private static final String VALIDATION_FILTER = "(" + Constants.OBJECTCLASS + "="
+ BundleValidation.class.getCanonicalName() + ")";
private static final String AGENT_FILTER = "(" + Constants.OBJECTCLASS + "=" + SnaAgent.class.getCanonicalName()
+ ")";
private static final String AUTHORIZATION_FILTER = "(" + Constants.OBJECTCLASS + "="
+ AuthorizationService.class.getCanonicalName() + ")";
private static final String FILTERING_FILTER = "(" + Constants.OBJECTCLASS + "="
+ Filtering.class.getCanonicalName() + ")";
private static final String MOCK_BUNDLE_NAME = "MockedBundle";
private static final long MOCK_BUNDLE_ID = 1;
private final Filter filterAgent = Mockito.mock(Filter.class);
private final Filter filterAccess = Mockito.mock(Filter.class);
private final Filter filterValidation = Mockito.mock(Filter.class);
private final Filter filterDataStore = Mockito.mock(Filter.class);
private final Filter filterAuthentication = Mockito.mock(Filter.class);
private final Filter filterAuthorization = Mockito.mock(Filter.class);
private final Filter filtering = Mockito.mock(Filter.class);
private final BundleContext context = Mockito.mock(BundleContext.class);
private final Bundle bundle = Mockito.mock(Bundle.class);
private final ServiceReference referenceAgent = Mockito.mock(ServiceReference.class);
private final ServiceRegistration referenceCore = Mockito.mock(ServiceRegistration.class);
private final ServiceReference referenceAuthorization = Mockito.mock(ServiceReference.class);
private final ServiceReference referenceAccess = Mockito.mock(ServiceReference.class);
private final ServiceReference referenceValidation = Mockito.mock(ServiceReference.class);
private final ServiceRegistration registration = Mockito.mock(ServiceRegistration.class);
private final ServiceRegistration registrationAccess = Mockito.mock(ServiceRegistration.class);
private final ServiceRegistration registrationValidation = Mockito.mock(ServiceRegistration.class);
private final ServiceRegistration registrationAgent = Mockito.mock(ServiceRegistration.class);
private final ServiceReference referenceProvider = Mockito.mock(ServiceReference.class);
private final ServiceReference filteringReference = Mockito.mock(ServiceReference.class);
private final ServiceRegistration registrationFiltering = Mockito.mock(ServiceRegistration.class);
private final ComponentContext componentContext= Mockito.mock(ComponentContext.class);
private MyModelInstance instance;
private SnaAgent agent;
private volatile int callbackCount;
private volatile int linkCallbackCount;
private volatile int extraCallbackCount;
private volatile int agentCallbackCount;
private SecuredAccess securedAccess;
private SensiNact sensinact;
private Mediator mediator;
protected Dictionary<String, Object> props;
public TestContext() throws InvalidServiceProviderException, InvalidSyntaxException, SecuredAccessException,
DataStoreException, BundleException {
Filter filter = Mockito.mock(Filter.class);
Mockito.when(filter.toString()).thenReturn(LOG_FILTER);
Mockito.when(context.createFilter(LOG_FILTER)).thenReturn(filter);
Mockito.when(context.getServiceReferences((String) Mockito.eq(null), Mockito.eq(LOG_FILTER))).thenReturn(null);
Mockito.when(context.getServiceReference(LOG_FILTER)).thenReturn(null);
Mockito.when(context.createFilter(AGENT_FILTER)).thenReturn(filterAgent);
Mockito.when(filterAgent.toString()).thenReturn(AGENT_FILTER);
Mockito.when(filterAgent.match(referenceAgent)).thenReturn(true);
Mockito.when(context.createFilter(DATA_STORE_FILTER)).thenReturn(filterDataStore);
Mockito.when(filterDataStore.toString()).thenReturn(DATA_STORE_FILTER);
Mockito.when(context.createFilter(AUTHENTICATION_FILTER)).thenReturn(filterAuthentication);
Mockito.when(filterAuthentication.toString()).thenReturn(AUTHENTICATION_FILTER);
Mockito.when(context.createFilter(ACCESS_FILTER)).thenReturn(filterAccess);
Mockito.when(filterAccess.toString()).thenReturn(ACCESS_FILTER);
Mockito.when(filterAccess.match(referenceAccess)).thenReturn(true);
Mockito.when(context.createFilter(VALIDATION_FILTER)).thenReturn(filterValidation);
Mockito.when(filterValidation.toString()).thenReturn(VALIDATION_FILTER);
Mockito.when(filterValidation.match(referenceValidation)).thenReturn(true);
Mockito.when(context.createFilter(AUTHORIZATION_FILTER)).thenReturn(filterAuthorization);
Mockito.when(filterAuthorization.toString()).thenReturn(AUTHORIZATION_FILTER);
Mockito.when(filterAuthorization.match(referenceAuthorization)).thenReturn(true);
Mockito.when(context.createFilter(FILTERING_FILTER)).thenReturn(filtering);
Mockito.when(filtering.toString()).thenReturn(FILTERING_FILTER);
Mockito.when(filtering.match(filteringReference)).thenReturn(true);
Mockito.when(context.getServiceReferences(Mockito.any(Class.class), Mockito.anyString()))
.then(new Answer<Collection<ServiceReference>>() {
@Override
public Collection<ServiceReference> answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
if (SnaAgent.class.equals(arguments[0])) {
return Collections.singletonList(referenceAgent);
} else if (SensiNactResourceModel.class.equals(arguments[0])) {
if (initialized()) {
return Collections.singletonList(referenceProvider);
} else {
return Collections.emptyList();
}
} else if ((Filtering.class.equals(arguments[0]))) {
return Collections.singletonList(filteringReference);
} else if ((AuthorizationService.class.equals(arguments[0]) && arguments[1] == null)
|| (arguments[0] == null && arguments[1].equals(AUTHORIZATION_FILTER))) {
return Collections.singletonList(referenceAuthorization);
} else if ((SecuredAccess.class.equals(arguments[0]) && arguments[1] == null)
|| (arguments[0] == null && arguments[1].equals(ACCESS_FILTER))) {
return Collections.singletonList(referenceAccess);
} else if ((BundleValidation.class.equals(arguments[0]) && arguments[1] == null)
|| (arguments[0] == null && arguments[1].equals(VALIDATION_FILTER))) {
return Collections.singletonList(referenceValidation);
}
return null;
}
});
Mockito.when(context.getServiceReferences(Mockito.anyString(), Mockito.anyString())).then(
new Answer<ServiceReference[]>() {
@Override
public ServiceReference[] answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
if (SnaAgent.class.getCanonicalName().equals(arguments[0])
|| (arguments[0] == null && arguments[1].equals(AGENT_FILTER))) {
return new ServiceReference[] { referenceAgent };
} else if (SensiNactResourceModel.class.getCanonicalName().equals(arguments[0])) {
if (initialized()) {
return new ServiceReference[] { referenceProvider };
} else {
return new ServiceReference[] {};
}
} else if ((Filtering.class.getCanonicalName().equals(arguments[0]))) {
return new ServiceReference[] { filteringReference };
} else if ((AuthorizationService.class.getCanonicalName().equals(arguments[0])
&& arguments[1] == null)
|| (arguments[0] == null && arguments[1].equals(AUTHORIZATION_FILTER))) {
return new ServiceReference[] { referenceAuthorization };
} else if ((SecuredAccess.class.getCanonicalName().equals(arguments[0]) && arguments[1] == null)
|| (arguments[0] == null && arguments[1].equals(ACCESS_FILTER))) {
return new ServiceReference[] { referenceAccess };
} else if ((BundleValidation.class.getCanonicalName().equals(arguments[0])
&& arguments[1] == null)
|| (arguments[0] == null && arguments[1].equals(VALIDATION_FILTER))) {
return new ServiceReference[] { referenceValidation };
}
return null;
}
});
Mockito.when(context.getServiceReference(Mockito.any(Class.class))).then(new Answer<ServiceReference>() {
@Override
public ServiceReference answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
if (arguments[0] != null && arguments[0].equals(AuthorizationService.class)) {
return referenceAuthorization;
}
if (arguments[0] != null && arguments[0].equals(SecuredAccess.class)) {
return referenceAccess;
}
if (arguments[0] != null && arguments[0].equals(Filtering.class)) {
return filteringReference;
}
if (arguments[0] != null && arguments[0].equals(BundleValidation.class)) {
return referenceValidation;
}
return null;
}
});
Mockito.when(context.getService(Mockito.any(ServiceReference.class))).then(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
if (arguments == null || arguments.length != 1) {
return null;
} else if (arguments[0] == referenceAuthorization) {
return new MyAuthorization<R>();
} else if (arguments[0] == filteringReference) {
return new XFilter();
} else if (arguments[0] == referenceAgent) {
return TestContext.this.getAgent();
} else if (arguments[0] == referenceAccess) {
return TestContext.this.getSecuredAccess();
} else if (arguments[0] == referenceCore) {
return sensinact;
} else if (arguments[0] == referenceProvider) {
return instance;
} else if (arguments[0] == referenceValidation) {
return new BundleValidation() {
@Override
public String check(Bundle bundle) throws BundleValidationException {
return "xxxxxxxxxxx00000000";
}
};
}
return null;
}
});
Mockito.when(context.registerService(Mockito.any(Class.class), Mockito.any(Object.class),
Mockito.any(Dictionary.class))).thenAnswer(new Answer<ServiceRegistration>() {
@Override
public ServiceRegistration answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
if (SecuredAccess.class.equals(arguments[0])) {
securedAccess = (SecuredAccess) arguments[1];
return registrationAccess;
} else if (SnaAgent.class.equals(arguments[0])) {
TestContext.this.setAgent((SnaAgent) arguments[1]);
return registrationAgent;
} else if (SensiNactResourceModel.class.equals(arguments[0])) {
TestContext.this.props = (Dictionary<String, Object>) arguments[2];
return registration;
} else if (BundleValidation.class.equals(arguments[0])) {
return registrationValidation;
}
return null;
}
});
Mockito.when(context.registerService(Mockito.any(String[].class), Mockito.any(Object.class),
Mockito.any(Dictionary.class))).thenAnswer(new Answer<ServiceRegistration>() {
@Override
public ServiceRegistration answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
TestContext.this.setAgent((SnaAgent) arguments[1]);
return registrationAgent;
}
});
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
if(TestContext.this.props == null) {
TestContext.this.props = (Dictionary<String, Object>) invocation.getArguments()[0];
} else {
Dictionary<String, Object> dico = (Dictionary<String, Object>) invocation.getArguments()[0];
Enumeration<String> enu = dico.keys();
while(enu.hasMoreElements()) {
String key = enu.nextElement();
TestContext.this.props.put(key,dico.get(key));
}
}
return null;
}
}).when(registration).setProperties(Mockito.any(Dictionary.class));
Mockito.when(referenceProvider.getProperty(Mockito.anyString())).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return TestContext.this.props.get(invocation.getArguments()[0]);
}
});
Mockito.when(referenceProvider.getPropertyKeys()).thenAnswer(new Answer<String[]>() {
@Override
public String[] answer(InvocationOnMock invocation) throws Throwable {
Enumeration<String> e = TestContext.this.props.keys();
List<String> l = new ArrayList<String>();
while (e.hasMoreElements()) {
l.add(e.nextElement());
}
return l.toArray(new String[0]);
}
});
Mockito.when(registration.getReference()).thenReturn(referenceProvider);
Mockito.when(registrationAgent.getReference()).thenReturn(referenceAgent);
Mockito.when(registrationValidation.getReference()).thenReturn(referenceValidation);
Mockito.when(context.getBundle()).thenReturn(bundle);
Mockito.when(bundle.getSymbolicName()).thenReturn(MOCK_BUNDLE_NAME);
Mockito.when(bundle.getBundleId()).thenReturn(MOCK_BUNDLE_ID);
Mockito.when(bundle.getState()).thenReturn(Bundle.ACTIVE);
Mockito.when(componentContext.getBundleContext()).thenReturn(context);
sensinact = new SensiNact();
sensinact.activate(componentContext);
this.mediator = sensinact.mediator;
instance = (MyModelInstance) new ModelInstanceBuilder(mediator
).build("serviceProvider", null, new ModelConfigurationBuilder(
mediator,ModelConfiguration.class, MyModelInstance.class
).withStartAtInitializationTime(true).build());
initialized = true;
callbackCount = 0;
linkCallbackCount = 0;
extraCallbackCount = 0;
agentCallbackCount = 0;
}
public final SnaAgent getAgent() {
return this.agent;
}
public final SensiNact getSensiNact() {
return this.sensinact;
}
public final ModelInstance getModelInstance() {
return this.instance;
}
public final Mediator getMediator() {
return this.mediator;
}
public final SecuredAccess getSecuredAccess() {
return this.securedAccess;
}
public final int getCallbackCount() {
return this.callbackCount;
}
public final int getExtraCallbackCount() {
return this.extraCallbackCount;
}
public final int getLinkCallbackCount() {
return this.linkCallbackCount;
}
public final int getAgentCallbackCount() {
return this.agentCallbackCount;
}
private boolean initialized = false;
final boolean initialized() {
return initialized;
}
public void stop() {
sensinact.close();
}
private final void setAgent(SnaAgent agent) {
this.agent = agent;
}
final void callbackInc() {
this.callbackCount += 1;
}
final void extraCallbackInc() {
this.extraCallbackCount += 1;
}
final void linkCallbackInc() {
this.linkCallbackCount += 1;
}
final void agentCallbackInc() {
this.agentCallbackCount += 1;
}
public void agentCallbackCountReset() {
this.agentCallbackCount = 0;
}
}