Skip to content
Snippets Groups Projects
Commit 10d9cd90 authored by ribeaudc's avatar ribeaudc
Browse files

add:

- IProcess, ProcessRunner and its unit test

SVN: 2186
parent e1a64340
No related branches found
No related tags found
No related merge requests found
/*
* Copyright 2007 ETH Zuerich, CISD
*
* 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 ch.systemsx.cisd.common.utilities;
/**
* A <code>Runnable</code> extension that describes a process.
*
* @author Christian Ribeaud
*/
public interface IProcess extends Runnable
{
/**
* Whether this <code>IProcess</code> exited successfully.
* <p>
* Is typically called after {@link Runnable#run()} has performed.
* </p>
*
* @return <code>true</code> if this <code>IProcess</code> succeeds, terminating so the whole running process.
*/
public boolean succeeded();
/**
* The number of times we should try if this <code>IProcess</code> failed.
* <p>
* This is a static method: it only gets called once during the initialization process.
* </p>
*/
public int getMaxRetryOnFailure();
/**
* The number of milliseconds we should wait before re-executing {@link Runnable#run()}.
* <p>
* This is a static method: it only gets called once during the initialization process.
* </p>
*/
public long getMillisToSleepOnFailure();
}
/*
* Copyright 2007 ETH Zuerich, CISD
*
* 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 ch.systemsx.cisd.common.utilities;
import ch.systemsx.cisd.common.exceptions.CheckedExceptionTunnel;
/**
* This class takes cares of running encapsulated {@link IProcess}.
*
* @author Christian Ribeaud
*/
public final class ProcessRunner
{
public ProcessRunner(final IProcess process)
{
runProcess(process);
}
final static void runProcess(final IProcess process)
{
final int maxRetryOnFailure = process.getMaxRetryOnFailure();
final long millisToSleepOnFailure = process.getMillisToSleepOnFailure();
assert millisToSleepOnFailure > -1;
int counter = 0;
do
{
process.run();
if (counter > 0 && millisToSleepOnFailure > 0)
{
try
{
Thread.sleep(millisToSleepOnFailure);
} catch (InterruptedException ex)
{
throw new CheckedExceptionTunnel(ex);
}
}
} while (++counter < maxRetryOnFailure && process.succeeded() == false);
}
}
/*
* Copyright 2007 ETH Zuerich, CISD
*
* 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 ch.systemsx.cisd.common.utilities;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
* Test cases for the {@link ProcessRunner}.
*
* @author Christian Ribeaud
*/
public class ProcessRunnerTest
{
private Mockery context;
private IProcess process;
@BeforeMethod
public final void beforeMethod()
{
context = new Mockery();
process = context.mock(IProcess.class);
}
@AfterMethod
public final void afterMethod()
{
// To following line of code should also be called at the end of each test method.
// Otherwise one do not known which test failed.
context.assertIsSatisfied();
}
@Test
public final void testRunSuccessfulProcess()
{
context.checking(new Expectations()
{
{
one(process).run();
one(process).succeeded();
will(returnValue(true));
one(process).getMillisToSleepOnFailure();
will(returnValue(1L));
one(process).getMaxRetryOnFailure();
will(returnValue(2));
}
});
new ProcessRunner(process);
context.assertIsSatisfied();
}
@Test
public final void testRunUnsuccessfulProcess()
{
final int tries = 3;
context.checking(new Expectations()
{
{
exactly(tries).of(process).run();
exactly(tries - 1).of(process).succeeded();
will(returnValue(false));
one(process).getMillisToSleepOnFailure();
will(returnValue(1L));
one(process).getMaxRetryOnFailure();
will(returnValue(tries));
}
});
new ProcessRunner(process);
context.assertIsSatisfied();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment