/**
* This file is part of Graylog.
*
* Graylog is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Graylog is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Graylog. If not, see <http://www.gnu.org/licenses/>.
*/
package org.graylog2.plugin;
import com.google.common.eventbus.EventBus;
import org.graylog2.audit.NullAuditEventSender;
import org.graylog2.plugin.lifecycles.Lifecycle;
import org.graylog2.shared.SuppressForbidden;
import org.joda.time.DateTimeZone;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class ServerStatusTest {
@Rule
public final TemporaryFolder temporaryFolder = new TemporaryFolder();
@Rule
public final MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock private BaseConfiguration config;
@Mock private EventBus eventBus;
private ServerStatus status;
private File tempFile;
@Before
public void setUp() throws Exception {
tempFile = temporaryFolder.newFile();
when(config.getNodeIdFile()).thenReturn(tempFile.getPath());
status = new ServerStatus(config, Collections.singleton(ServerStatus.Capability.MASTER), eventBus, NullAuditEventSender::new);
}
@Test
public void testGetNodeId() throws Exception {
assertEquals(status.getNodeId().toString(), new String(Files.readAllBytes(tempFile.toPath()), StandardCharsets.UTF_8));
}
@Test
public void testGetLifecycle() throws Exception {
assertEquals(status.getLifecycle(), Lifecycle.UNINITIALIZED);
}
@Test
public void testSetLifecycleRunning() throws Exception {
status.start();
assertTrue(status.isProcessing());
verify(eventBus).post(Lifecycle.RUNNING);
}
@Test
public void testSetLifecycleUninitialized() throws Exception {
assertFalse(status.isProcessing());
verify(eventBus, never()).post(Lifecycle.UNINITIALIZED);
}
@Test
public void testSetLifecycleStarting() throws Exception {
status.initialize();
assertFalse(status.isProcessing());
verify(eventBus).post(Lifecycle.STARTING);
}
@Test
public void testSetLifecyclePaused() throws Exception {
status.pauseMessageProcessing(false);
assertFalse(status.isProcessing());
verify(eventBus).post(Lifecycle.PAUSED);
}
@Test
public void testAwaitRunning() throws Exception {
final Runnable runnable = mock(Runnable.class);
final CountDownLatch startLatch = new CountDownLatch(1);
final CountDownLatch stopLatch = new CountDownLatch(1);
new Thread(new Runnable() {
@Override
public void run() {
try {
startLatch.countDown();
status.awaitRunning(runnable);
} finally {
stopLatch.countDown();
}
}
}).start();
startLatch.await(5, TimeUnit.SECONDS);
verify(runnable, never()).run();
status.start();
stopLatch.await(5, TimeUnit.SECONDS);
verify(runnable).run();
}
@Test
public void testAwaitRunningWithException() throws Exception {
final Runnable runnable = mock(Runnable.class);
final CountDownLatch startLatch = new CountDownLatch(1);
final CountDownLatch stopLatch = new CountDownLatch(1);
final AtomicBoolean exceptionCaught = new AtomicBoolean(false);
new Thread(new Runnable() {
@Override
public void run() {
try {
startLatch.countDown();
status.awaitRunning(runnable);
exceptionCaught.set(true);
} finally {
stopLatch.countDown();
}
}
}).start();
startLatch.await(5, TimeUnit.SECONDS);
status.start();
stopLatch.await(5, TimeUnit.SECONDS);
assertTrue(exceptionCaught.get());
}
@Test
public void testGetStartedAt() throws Exception {
assertNotNull(status.getStartedAt());
}
@Test
@SuppressForbidden("Deliberate invocation")
public void testGetTimezone() throws Exception {
assertEquals(status.getTimezone(), DateTimeZone.getDefault());
}
@Test
public void testAddCapability() throws Exception {
assertEquals(status.addCapability(ServerStatus.Capability.SERVER), status);
assertTrue(status.hasCapabilities(ServerStatus.Capability.MASTER, ServerStatus.Capability.SERVER));
}
@Test
public void testAddCapabilities() throws Exception {
assertEquals(status.addCapabilities(ServerStatus.Capability.LOCALMODE), status);
assertTrue(status.hasCapabilities(ServerStatus.Capability.MASTER, ServerStatus.Capability.LOCALMODE));
}
@Test
public void testPauseMessageProcessing() throws Exception {
status.pauseMessageProcessing();
assertEquals(status.getLifecycle(), Lifecycle.PAUSED);
assertTrue(status.processingPauseLocked());
}
@Test
public void testPauseMessageProcessingWithLock() throws Exception {
status.pauseMessageProcessing(true);
assertEquals(status.getLifecycle(), Lifecycle.PAUSED);
assertTrue(status.processingPauseLocked());
}
@Test
public void testPauseMessageProcessingWithoutLock() throws Exception {
status.pauseMessageProcessing(false);
assertEquals(status.getLifecycle(), Lifecycle.PAUSED);
assertFalse(status.processingPauseLocked());
}
@Test
public void testPauseMessageProcessingNotOverridingLock() throws Exception {
status.pauseMessageProcessing(true);
status.pauseMessageProcessing(false);
assertTrue(status.processingPauseLocked());
}
@Test
public void testResumeMessageProcessingWithoutLock() throws Exception {
status.pauseMessageProcessing(false);
status.resumeMessageProcessing();
assertEquals(status.getLifecycle(), Lifecycle.RUNNING);
}
@Test(expected = ProcessingPauseLockedException.class)
public void testResumeMessageProcessingWithLock() throws Exception {
status.pauseMessageProcessing(true);
status.resumeMessageProcessing();
}
@Test
public void testUnlockProcessingPause() throws Exception {
status.pauseMessageProcessing(true);
assertTrue(status.processingPauseLocked());
status.unlockProcessingPause();
assertFalse(status.processingPauseLocked());
}
@Test
public void testSetLocalMode() throws Exception {
status.setLocalMode(false);
assertFalse(status.hasCapability(ServerStatus.Capability.LOCALMODE));
status.setLocalMode(true);
assertTrue(status.hasCapability(ServerStatus.Capability.LOCALMODE));
}
}