I am very new to akka and trying to model a solution for a problem.
Consider I have a DiskMonitorActor which looks like
public final class DiskMonitorActor extends UntypedActor {
private final File assetsDirectory;
private final long thresholdPercentage;
private final LoggingAdapter logging =
Logging.getLogger(getContext().system(), this);
public DiskMonitorActor(final File assetsDirectory, final long
thresholdPercentage) {
this.assetsDirectory = assetsDirectory;
this.thresholdPercentage = thresholdPercentage;
}
public static Props props(final File assetsDirectory, final long
thresholdPercentage) {
return Props.create(new Creator<DiskMonitorActor>(){
private static final long serialVersionUID = 1L;
public DiskMonitorActor create() throws Exception {
return new DiskMonitorActor(assetsDirectory, thresholdPercentage);
}
});
}
@Override
public void onReceive(final Object message) throws Exception {
if (message instanceof DiskMonitorMessage) {
logging.info("disk: {}, total space: {}, usable space: {}",
assetsDirectory.getAbsolutePath(),
assetsDirectory.getTotalSpace(),
assetsDirectory.getUsableSpace());
if (isThresholdExceeded()) {
logging.error("Disk full. Available Space {}",
assetsDirectory.getFreeSpace());
throw new DiskException("disk capacity reached threshold.");
}
} else {
unhandled(message);
}
}
private boolean isThresholdExceeded() {
final long usedBytes = assetsDirectory.getTotalSpace() -
assetsDirectory.getUsableSpace();
final long thresholdBytes = assetsDirectory.getTotalSpace() *
thresholdPercentage / 100;
return usedBytes >= thresholdBytes;
}
}
I am able to unit test this as
public class DiskMonitorActorTest {
@Mock
private File assetsDirectory;
@Rule
public TestName testName = new TestName();
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void testDiskMonitorWhenThresholdReached() throws Exception {
when(assetsDirectory.getAbsolutePath()).thenReturn("test/file/path");
when(assetsDirectory.getTotalSpace()).thenReturn(100L);
when(assetsDirectory.getUsableSpace()).thenReturn(10L);
final Props props = DiskMonitorActor.props(assetsDirectory, 10L);
final ActorSystem system = ActorSystem.create("system");
final TestActorRef<DiskMonitorActor> actorRef =
TestActorRef.create(system, props, testName.getMethodName());
final DiskMonitorActor diskMonitorActor = actorRef.underlyingActor();
expectedException.expect(DiskException.class);
expectedException.expectMessage("disk capacity reached threshold.");
diskMonitorActor.onReceive(new DiskMonitorMessage());
}
}
I have a TenantMonitor which is supposed to monitor DiskMonitor (for any
exception) and take preventive actions, if necessary. It looks like
public class TenantMonitorActor extends UntypedActor {
private static final String TENANT_MONITORING_CONF =
"tenant.monitoring.conf";
private final LoggingAdapter logging =
Logging.getLogger(getContext().system(), this);
private static final SupervisorStrategy strategy =
new OneForOneStrategy(1, Duration.create(1, TimeUnit.SECONDS),
new Function<Throwable, Directive>() {
public Directive apply(final Throwable param)
throws Exception {
if (param instanceof DiskException) {
return stop();
}
return restart();
}
});
@Override
public void onReceive(final Object message) throws Exception {
if (message instanceof TenantMonitorMessage) {
logging.info("Tenant Monitor Setup");
setUpMonitoring();
}
}
@Override
public SupervisorStrategy supervisorStrategy() {
return strategy;
}
private void setUpMonitoring() {
final Config monitoringConf =
ConfigFactory.load(TENANT_MONITORING_CONF);
setupDiskMonitoring(monitoringConf);
}
private void setupDiskMonitoring(final Config monitoringConf) {
final String diskLocationKey = "tenant.monitoring.disk.location";
final String thresholdPercentKey =
"tenant.monitoring.disk.error.threshold.percent";
final Props diskMonitorProps =
DiskMonitorActor.props(getAssetsDirectory(monitoringConf,
diskLocationKey),
monitoringConf.getLong(thresholdPercentKey));
final ActorRef diskMonitorActorRef =
getContext().actorOf(diskMonitorProps, "diskMonitor");
final FiniteDuration start = Duration.create(0, TimeUnit.SECONDS);
final String schedulerKey = "tenant.monitoring.disk.schedule.seconds";
final FiniteDuration recurring =
Duration.create(monitoringConf.getInt(schedulerKey),
TimeUnit.SECONDS);
final ActorSystem system = getContext().system();
system.scheduler()
.schedule(start, recurring, diskMonitorActorRef,
new DiskMonitorMessage(), system.dispatcher(), null);
}
protected File getAssetsDirectory(final Config monitoringConf, final
String diskLocationKey) {
return new File(monitoringConf.getString(diskLocationKey));
}
}
The part where I am stuck is how do I inject failures when testing it?
Specifically I am looking for help on
1. How do I test this Monitor for specific failures and make sure
correct action is called
2. How could I have written this code in a better way
Thanks a lot
+ Harit Himanshu
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ:
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.