/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. 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
*/
package org.opendaylight.controller.config.persist.impl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.lang.management.ManagementFactory;
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;
import javax.management.MBeanServerConnection;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.opendaylight.controller.config.facade.xml.ConfigExecution;
import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacadeFactory;
import org.opendaylight.controller.config.facade.xml.mapping.config.Config;
import org.opendaylight.controller.config.facade.xml.osgi.YangStoreService;
import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
import org.opendaylight.controller.config.persist.api.Persister;
import org.opendaylight.controller.config.spi.Module;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.capability.Capability;
import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
import org.w3c.dom.Element;
public class ConfigPusherImplTest {
@Mock
private YangStoreService yangStoreService;
@Mock
private ConfigSnapshotHolder mockedConfigSnapshot;
@Mock
private Persister mockedAggregator;
@Mock
private ConfigRegistryClient configRegistryClient;
@Mock
private org.opendaylight.yangtools.yang.model.api.Module module;
@Mock
private ConfigSubsystemFacadeFactory facadeFactory;
@Mock
private ConfigSubsystemFacade facade;
@Mock
private MBeanServerConnection mBeanServer;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
doReturn("content").when(yangStoreService).getModuleSource(any(ModuleIdentifier.class));
doReturn("mocked snapshot").when(mockedConfigSnapshot).toString();
doReturn("").when(mockedConfigSnapshot).getConfigSnapshot();
doReturn(Collections.emptySet()).when(yangStoreService).getModules();
final Config mock = mock(Config.class);
doReturn("mocked config").when(mock).toString();
doReturn(facade).when(facadeFactory).createFacade(anyString());
doReturn(Sets.newHashSet()).when(facadeFactory).getCurrentCapabilities();
doReturn(mock).when(facade).getConfigMapping();
doNothing().when(mBeanServer).addNotificationListener(any(ObjectName.class), any(NotificationListener.class), any(NotificationFilter.class), anyObject());
}
@Test
public void testPersisterNotAllCapabilitiesProvided() throws Exception {
doReturn(new TreeSet<>(Lists.newArrayList("required-cap"))).when(mockedConfigSnapshot).getCapabilities();
final ConfigPusherImpl configPusher = new ConfigPusherImpl(facadeFactory, 0, 0);
configPusher.pushConfigs(Collections.singletonList(mockedConfigSnapshot));
try {
configPusher.process(Lists.newArrayList(), ManagementFactory.getPlatformMBeanServer(),
mockedAggregator, true);
} catch(IllegalStateException e) {
Throwable cause = Throwables.getRootCause(e);
assertTrue(cause instanceof ConfigPusherImpl.NotEnoughCapabilitiesException);
final Set missingCaps = ((ConfigPusherImpl.NotEnoughCapabilitiesException) cause).getMissingCaps();
assertEquals(missingCaps.size(), 1);
assertEquals(missingCaps.iterator().next(), "required-cap");
return;
}
fail();
}
@Test
public void testPersisterSuccessfulPush() throws Exception {
doReturn(new TreeSet<>(Lists.newArrayList("namespace?module=module&revision=2012-12-12"))).when(mockedConfigSnapshot).getCapabilities();
final Capability cap = mock(Capability.class);
doReturn("namespace?module=module&revision=2012-12-12").when(cap).getCapabilityUri();
doReturn(Sets.newHashSet(cap)).when(facadeFactory).getCurrentCapabilities();
final ConfigExecution cfgExec = mock(ConfigExecution.class);
doReturn("cfg exec").when(cfgExec).toString();
doReturn(cfgExec).when(facade).getConfigExecution(any(Config.class), any(Element.class));
doNothing().when(facade).executeConfigExecution(any(ConfigExecution.class));
doReturn(mock(CommitStatus.class)).when(facade).commitSilentTransaction();
doReturn(Sets.newHashSet(module)).when(yangStoreService).getModules();
final ConfigPusherImpl configPusher = new ConfigPusherImpl(facadeFactory, 0, 0);
configPusher.pushConfigs(Collections.singletonList(mockedConfigSnapshot));
configPusher.processSingle(Lists.newArrayList(), mBeanServer, mockedAggregator, true);
verify(facade).executeConfigExecution(cfgExec);
verify(facade).commitSilentTransaction();
}
@Test
public void testPersisterConflictingVersionException() throws Exception {
doReturn(new TreeSet<>(Lists.newArrayList("namespace?module=module&revision=2012-12-12"))).when(mockedConfigSnapshot).getCapabilities();
final Capability cap = mock(Capability.class);
doReturn("namespace?module=module&revision=2012-12-12").when(cap).getCapabilityUri();
doReturn(Sets.newHashSet(cap)).when(facadeFactory).getCurrentCapabilities();
final ConfigExecution cfgExec = mock(ConfigExecution.class);
doReturn("cfg exec").when(cfgExec).toString();
doReturn(cfgExec).when(facade).getConfigExecution(any(Config.class), any(Element.class));
doNothing().when(facade).executeConfigExecution(any(ConfigExecution.class));
doThrow(ConflictingVersionException.class).when(facade).commitSilentTransaction();
doReturn(Sets.newHashSet(module)).when(yangStoreService).getModules();
final ConfigPusherImpl configPusher = new ConfigPusherImpl(facadeFactory, 0, 0);
configPusher.pushConfigs(Collections.singletonList(mockedConfigSnapshot));
try {
configPusher.processSingle(Lists.newArrayList(), mBeanServer, mockedAggregator, true);
} catch (IllegalStateException e) {
Throwable cause = Throwables.getRootCause(e);
assertTrue(cause instanceof ConflictingVersionException);
return;
}
fail();
}
@Test
public void testSuccessConflictingVersionException() throws Exception {
doReturn(new TreeSet<>(Lists.newArrayList("namespace?module=module&revision=2012-12-12"))).when(mockedConfigSnapshot).getCapabilities();
final Capability cap = mock(Capability.class);
doReturn("namespace?module=module&revision=2012-12-12").when(cap).getCapabilityUri();
doReturn(Sets.newHashSet(cap)).when(facadeFactory).getCurrentCapabilities();
final ConfigExecution cfgExec = mock(ConfigExecution.class);
doReturn("cfg exec").when(cfgExec).toString();
doReturn(cfgExec).when(facade).getConfigExecution(any(Config.class), any(Element.class));
doNothing().when(facade).executeConfigExecution(any(ConfigExecution.class));
doThrow(ConflictingVersionException.class)
.doThrow(ConflictingVersionException.class)
.doReturn(mock(CommitStatus.class)).when(facade).commitSilentTransaction();
doReturn(Sets.newHashSet(module)).when(yangStoreService).getModules();
final ConfigPusherImpl configPusher = new ConfigPusherImpl(facadeFactory, 5000, 5000);
configPusher.pushConfigs(Collections.singletonList(mockedConfigSnapshot));
configPusher.processSingle(Lists.newArrayList(), mBeanServer, mockedAggregator, true);
verify(facade, times(3)).executeConfigExecution(cfgExec);
verify(facade, times(3)).commitSilentTransaction();
}
}