/**
* Copyright 2014-2017 Linagora, Université Joseph Fourier, Floralis
*
* The present code is developed in the scope of the joint LINAGORA -
* Université Joseph Fourier - Floralis research program and is designated
* as a "Result" pursuant to the terms and conditions of the LINAGORA
* - Université Joseph Fourier - Floralis research program. Each copyright
* holder of Results enumerated here above fully & independently holds complete
* ownership of the complete Intellectual Property rights applicable to the whole
* of said Results, and may freely exploit it in any manner which does not infringe
* the moral rights of the other copyright holders.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.roboconf.agent.monitoring.internal;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import net.roboconf.agent.monitoring.api.IMonitoringHandler;
import net.roboconf.agent.monitoring.internal.MonitoringRunnable.MonitoringHandlerRun;
import net.roboconf.agent.monitoring.internal.file.FileHandler;
import net.roboconf.agent.monitoring.internal.nagios.NagiosHandler;
import net.roboconf.agent.monitoring.internal.rest.RestHandler;
import net.roboconf.agent.monitoring.internal.tests.MyAgentInterface;
import net.roboconf.core.Constants;
import net.roboconf.core.internal.tests.TestUtils;
import net.roboconf.core.model.beans.Component;
import net.roboconf.core.model.beans.Instance;
import net.roboconf.core.model.beans.Instance.InstanceStatus;
import net.roboconf.core.model.helpers.InstanceHelpers;
import net.roboconf.core.utils.Utils;
import net.roboconf.messaging.api.business.IAgentClient;
import net.roboconf.messaging.api.messages.Message;
import net.roboconf.messaging.api.messages.from_agent_to_dm.MsgNotifAutonomic;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
/**
* @author Vincent Zurczak - Linagora
*/
public class MonitoringRunnableTest {
private static final List<IMonitoringHandler> HANDLERS = new ArrayList<> ();
static {
HANDLERS.add( new FileHandler());
HANDLERS.add( new NagiosHandler());
HANDLERS.add( new RestHandler());
}
private IAgentClient messagingClient;
private MyAgentInterface agentInterface;
@Before
public void initializeMessagingClient() throws Exception {
this.messagingClient = Mockito.mock( IAgentClient.class );
this.agentInterface = new MyAgentInterface( this.messagingClient );
}
@Test
public void testExtractRuleSections_noSection() throws Exception {
String fileContent = "";
MonitoringRunnable task = new MonitoringRunnable( this.agentInterface, HANDLERS );
this.agentInterface.setScopedInstance( new Instance( "root" ));
List<MonitoringHandlerRun> handlers = task.extractRuleSections( new File( "whatever" ), fileContent, null );
Assert.assertEquals( 0, handlers.size());
}
@Test
public void testExtractRuleSections_file() throws Exception {
File f = TestUtils.findTestFile( "/file-events.conf" );
String fileContent = Utils.readFileContent( f );
MonitoringRunnable task = new MonitoringRunnable( this.agentInterface, HANDLERS );
this.agentInterface.setScopedInstance( new Instance( "root" ));
List<MonitoringHandlerRun> handlers = task.extractRuleSections( f, fileContent, null );
Assert.assertEquals( 3, handlers.size());
MonitoringHandlerRun bean = handlers.get( 0 );
Assert.assertEquals( "file", bean.handlerName );
Assert.assertEquals( "myRuleName-1", bean.eventId );
Assert.assertTrue( bean.rawRulesText.contains( "%TMP%/rbcf-test/ta-daaaaa" ));
bean = handlers.get( 1 );
Assert.assertEquals( "file", bean.handlerName );
Assert.assertEquals( "myRuleName-2", bean.eventId );
Assert.assertTrue( bean.rawRulesText.contains( "%TMP%/rbcf-test/ta-daaaaa-2" ));
bean = handlers.get( 2 );
Assert.assertEquals( "file", bean.handlerName );
Assert.assertEquals( "myRuleName", bean.eventId );
Assert.assertTrue( bean.rawRulesText.contains( "%TMP%/rbcf-test/a-directory-to-not-delete" ));
}
@Test
public void testExtractRuleSections_nagios() throws Exception {
File f = TestUtils.findTestFile( "/nagios-events.conf" );
String fileContent = Utils.readFileContent( f );
MonitoringRunnable task = new MonitoringRunnable( this.agentInterface, HANDLERS );
this.agentInterface.setScopedInstance( new Instance( "root" ));
List<MonitoringHandlerRun> handlers = task.extractRuleSections( f, fileContent, null );
Assert.assertEquals( 3, handlers.size());
MonitoringHandlerRun bean = handlers.get( 0 );
Assert.assertEquals( "nagios", bean.handlerName );
Assert.assertEquals( "myRuleName-80", bean.eventId );
Assert.assertTrue( bean.rawRulesText.contains( "host_name accept_passive_checks acknowledged" ));
bean = handlers.get( 1 );
Assert.assertEquals( "nagios", bean.handlerName );
Assert.assertEquals( "myRuleName-2", bean.eventId );
Assert.assertTrue( bean.rawRulesText.contains( "http://192.168.15.4" ));
bean = handlers.get( 2 );
Assert.assertEquals( "nagios", bean.handlerName );
Assert.assertEquals( "myRuleName-3", bean.eventId );
Assert.assertTrue( bean.rawRulesText.contains( "http://192.168.15.4:50001" ));
}
@Test
public void testExtractRuleSections_rest() throws Exception {
File f = TestUtils.findTestFile( "/rest-events.conf" );
String fileContent = Utils.readFileContent( f );
MonitoringRunnable task = new MonitoringRunnable( this.agentInterface, HANDLERS );
this.agentInterface.setScopedInstance( new Instance( "root" ));
List<MonitoringHandlerRun> handlers = task.extractRuleSections( f, fileContent, null );
Assert.assertEquals( 1, handlers.size());
MonitoringHandlerRun bean = handlers.get( 0 );
Assert.assertEquals( "rest", bean.handlerName );
Assert.assertEquals( "myRuleName-1", bean.eventId );
Assert.assertTrue( bean.rawRulesText.contains( "http://google.fr" ));
}
@Test
public void testExtractRuleSections_mixed() throws Exception {
File f = TestUtils.findTestFile( "/mixed-events.conf" );
String fileContent = Utils.readFileContent( f );
MonitoringRunnable task = new MonitoringRunnable( this.agentInterface, HANDLERS );
this.agentInterface.setScopedInstance( new Instance( "root" ));
List<MonitoringHandlerRun> handlers = task.extractRuleSections( f, fileContent, null );
Assert.assertEquals( 2, handlers.size());
MonitoringHandlerRun bean = handlers.get( 0 );
Assert.assertEquals( "nagios", bean.handlerName );
Assert.assertEquals( "myRuleName-nagios", bean.eventId );
Assert.assertTrue( bean.rawRulesText.contains( "Columns: host_name accept_passive_checks acknowledged" ));
bean = handlers.get( 1 );
Assert.assertEquals( "file", bean.handlerName );
Assert.assertEquals( "myRuleName-for-file", bean.eventId );
Assert.assertTrue( bean.rawRulesText.contains( "/tmp/a-directory-to-not-delete" ));
}
@Test
public void testExtractRuleSections_mixedTemplating() throws Exception {
File f = TestUtils.findTestFile( "/mixed-events-templating.conf" );
String fileContent = Utils.readFileContent( f );
MonitoringRunnable task = new MonitoringRunnable( this.agentInterface, HANDLERS );
this.agentInterface.setScopedInstance( new Instance( "root" ));
File propertiesFile = TestUtils.findTestFile( "/mixed-events-templating.properties" );
Assert.assertTrue( propertiesFile.exists());
Properties params = Utils.readPropertiesFile( propertiesFile );
List<MonitoringHandlerRun> handlers = task.extractRuleSections( f, fileContent, params );
Assert.assertEquals( 2, handlers.size());
// Test template expansion of "= {{ accept_passive_checks }}"
// with "accept_passive_checks" property set to 1
MonitoringHandlerRun bean = handlers.get( 0 );
Assert.assertEquals( "nagios", bean.handlerName );
Assert.assertTrue( bean.rawRulesText.endsWith( "= 1" ));
// Test template expansion of "/tmp/{{ a-directory-to-not-delete }}"
// with "a-directory-to-not-delete" property set to "roboconf"
bean = handlers.get( 1 );
Assert.assertEquals( "file", bean.handlerName );
Assert.assertTrue( bean.rawRulesText.contains( "/tmp/roboconf" ));
}
@Test
public void testExtractRuleSections_incompleteRule() throws Exception {
String fileContent = MonitoringRunnable.RULE_BEGINNING;
MonitoringRunnable task = new MonitoringRunnable( this.agentInterface, HANDLERS );
this.agentInterface.setScopedInstance( new Instance( "root" ));
List<MonitoringHandlerRun> handlers = task.extractRuleSections( new File( "test" ), fileContent, null );
Assert.assertEquals( 0, handlers.size());
}
@Test
public void testExtractRuleSections_invalidRule() throws Exception {
String fileContent = MonitoringRunnable.RULE_BEGINNING + " file event id with spaces]";
MonitoringRunnable task = new MonitoringRunnable( this.agentInterface, HANDLERS );
this.agentInterface.setScopedInstance( new Instance( "root" ));
List<MonitoringHandlerRun> handlers = task.extractRuleSections( new File( "test" ), fileContent, null );
Assert.assertEquals( 0, handlers.size());
}
@Test
public void testExtractRuleSections_unknownParser() throws Exception {
String fileContent = MonitoringRunnable.RULE_BEGINNING + " unknown event-id]\nok";
MonitoringRunnable task = new MonitoringRunnable( this.agentInterface, HANDLERS );
this.agentInterface.setScopedInstance( new Instance( "root" ));
List<MonitoringHandlerRun> handlers = task.extractRuleSections( new File( "test" ), fileContent, null );
Assert.assertEquals( 1, handlers.size());
MonitoringHandlerRun bean = handlers.get( 0 );
Assert.assertEquals( "unknown", bean.handlerName );
Assert.assertEquals( "event-id", bean.eventId );
Assert.assertEquals( "ok", bean.rawRulesText );
}
@Test
public void testWholeChain_instancesStarted() throws Exception {
testTheCommonChain( InstanceStatus.DEPLOYED_STARTED, "/file-events.conf" );
ArgumentCaptor<Message> msgCapture = ArgumentCaptor.forClass( Message.class );
Mockito.verify( this.messagingClient, Mockito.times( 1 )).sendMessageToTheDm( msgCapture.capture());
Assert.assertEquals( MsgNotifAutonomic.class, msgCapture.getValue().getClass());
MsgNotifAutonomic msg = (MsgNotifAutonomic) msgCapture.getValue();
Assert.assertEquals( this.agentInterface.getApplicationName(), msg.getApplicationName());
Assert.assertEquals( "myRuleName", msg.getEventName());
Assert.assertEquals( "/" + this.agentInterface.getScopedInstance().getName(), msg.getScopedInstancePath());
Assert.assertTrue( msg.getEventInfo().toLowerCase().contains( "does not exist" ));
}
@Test
public void testWholeChain_instancesNotStarted() throws Exception {
testTheCommonChain( InstanceStatus.DEPLOYED_STOPPED, "/file-events.conf" );
Mockito.verify( this.messagingClient, Mockito.times( 0 )).sendMessageToTheDm( Mockito.any( Message.class ));
}
@Test
public void testWholeChain_noHandler() throws Exception {
testTheCommonChain( InstanceStatus.DEPLOYED_STARTED, "/unknown-events.conf" );
Mockito.verify( this.messagingClient, Mockito.times( 0 )).sendMessageToTheDm( Mockito.any( Message.class ));
}
@Test
public void testWholeChain_messagingError() throws Exception {
Mockito.doThrow( new IOException( "For test" )).when( this.messagingClient ).sendMessageToTheDm( Mockito.any( Message.class ));
testTheCommonChain( InstanceStatus.DEPLOYED_STARTED, "/file-events.conf" );
// No exception is thrown
}
@Test
public void testWholeChain_noModelYet() throws Exception {
Mockito.verify( this.messagingClient, Mockito.times( 0 )).sendMessageToTheDm( Mockito.any( Message.class ));
MonitoringRunnable task = new MonitoringRunnable( this.agentInterface, HANDLERS );
task.run();
Mockito.verify( this.messagingClient, Mockito.times( 0 )).sendMessageToTheDm( Mockito.any( Message.class ));
}
private void testTheCommonChain( InstanceStatus status, String file ) throws Exception {
// Create a model
Instance rootInstance = new Instance( "root" ).component( new Component( "Root" ).installerName( Constants.TARGET_INSTALLER ));
Instance childInstance = new Instance( "child" ).component( new Component( "Child" ).installerName( "whatever" ));
InstanceHelpers.insertChild( rootInstance, childInstance );
this.agentInterface.setScopedInstance( rootInstance );
rootInstance.setStatus( status );
childInstance.setStatus( status );
// Create the resources
File dir = InstanceHelpers.findInstanceDirectoryOnAgent( childInstance );
Utils.deleteFilesRecursively( dir );
Assert.assertTrue( dir.mkdirs());
File f = TestUtils.findTestFile( file );
String tmpDirLocation = System.getProperty( "java.io.tmpdir" ).replace( "\\", "/" ).replaceAll( "/?$", "" );
String updatedContent = Utils.readFileContent( f ).replace( "%TMP%", tmpDirLocation );
File measureFile = new File( dir, childInstance.getComponent().getName() + ".measures" );
Utils.writeStringInto( updatedContent, measureFile );
Assert.assertTrue( measureFile.exists());
// Run the task
Mockito.verify( this.messagingClient, Mockito.times( 0 )).sendMessageToTheDm( Mockito.any( Message.class ));
MonitoringRunnable task = new MonitoringRunnable( this.agentInterface, HANDLERS );
task.run();
Utils.deleteFilesRecursively( dir );
Assert.assertFalse( dir.exists());
File temporaryDirectory = new File( tmpDirLocation, "rbcf-test" );
Utils.deleteFilesRecursively( temporaryDirectory );
}
}