// Copyright (C) 2015 The Android Open Source Project
//
// 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 com.ericsson.gerrit.plugins.highavailability;

import static com.ericsson.gerrit.plugins.highavailability.Configuration.CACHE_SECTION;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.CLEANUP_INTERVAL_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.CLUSTER_NAME_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.CONNECTION_TIMEOUT_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_CLEANUP_INTERVAL_MS;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_CLUSTER_NAME;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_MAX_TRIES;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_PEER_INFO_STRATEGY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_RETRY_INTERVAL;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_SHARED_DIRECTORY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_SKIP_INTERFACE_LIST;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_SYNCHRONIZE;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_THREAD_POOL_SIZE;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_TIMEOUT_MS;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.EVENT_SECTION;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.HTTP_SECTION;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.INDEX_SECTION;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.JGROUPS_SECTION;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.JGROUPS_SUBSECTION;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.MAIN_SECTION;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.MAX_TRIES_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.MY_URL_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.PASSWORD_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.PEER_INFO_SECTION;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.RETRY_INTERVAL_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.SHARED_DIRECTORY_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.SKIP_INTERFACE_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.SOCKET_TIMEOUT_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.STATIC_SUBSECTION;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.STRATEGY_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.SYNCHRONIZE_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.THREAD_POOL_SIZE_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.URL_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.USER_KEY;
import static com.ericsson.gerrit.plugins.highavailability.Configuration.WEBSESSION_SECTION;
import static com.google.common.truth.Truth.assertThat;
import static java.net.InetAddress.getLocalHost;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.ericsson.gerrit.plugins.highavailability.peers.jgroups.MyUrlProvider;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.ProvisionException;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.eclipse.jgit.lib.Config;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class ConfigurationTest {
  private static final String PASS = "fakePass";
  private static final String USER = "fakeUser";
  private static final String URL = "fakeUrl";
  private static final String EMPTY = "";
  private static final int TIMEOUT = 5000;
  private static final int MAX_TRIES = 5;
  private static final int RETRY_INTERVAL = 1000;
  private static final int THREAD_POOL_SIZE = 1;
  private static final String SHARED_DIRECTORY = "/some/directory";
  private static final Path SHARED_DIR_PATH = Paths.get(SHARED_DIRECTORY);
  private static final String RELATIVE_SHARED_DIRECTORY = "relative/dir";
  private static final Path SITE_PATH = Paths.get("/site_path");
  private static final String ERROR_MESSAGE = "some error message";

  @Mock private PluginConfigFactory cfgFactoryMock;
  @Mock private Config configMock;
  @Mock private Config serverConfigMock;
  private SitePaths site;
  private Configuration configuration;
  private String pluginName = "high-availability";

  @Rule public ExpectedException exception = ExpectedException.none();

  @Before
  public void setUp() throws IOException {
    when(cfgFactoryMock.getGlobalPluginConfig(pluginName)).thenReturn(configMock);
    when(configMock.getString(MAIN_SECTION, null, SHARED_DIRECTORY_KEY))
        .thenReturn(SHARED_DIRECTORY);
    when(configMock.getEnum(PEER_INFO_SECTION, null, STRATEGY_KEY, DEFAULT_PEER_INFO_STRATEGY))
        .thenReturn(DEFAULT_PEER_INFO_STRATEGY);
    when(configMock.getStringList(JGROUPS_SECTION, null, SKIP_INTERFACE_KEY))
        .thenReturn(new String[] {});
    site = new SitePaths(SITE_PATH);
  }

  private void initializeConfiguration() {
    configuration = new Configuration(cfgFactoryMock, pluginName, site);
  }

  @Test
  public void testGetPeerInfoStrategy() {
    initializeConfiguration();
    assertThat(configuration.peerInfo().strategy()).isSameAs(DEFAULT_PEER_INFO_STRATEGY);

    when(configMock.getEnum(PEER_INFO_SECTION, null, STRATEGY_KEY, DEFAULT_PEER_INFO_STRATEGY))
        .thenReturn(Configuration.PeerInfoStrategy.JGROUPS);
    initializeConfiguration();
    assertThat(configuration.peerInfo().strategy())
        .isSameAs(Configuration.PeerInfoStrategy.JGROUPS);
  }

  @Test
  public void testGetUrl() throws Exception {
    initializeConfiguration();
    assertThat(configuration.peerInfoStatic().url()).isEqualTo(EMPTY);

    when(configMock.getString(PEER_INFO_SECTION, STATIC_SUBSECTION, URL_KEY)).thenReturn(URL);
    initializeConfiguration();
    assertThat(configuration.peerInfoStatic().url()).isEqualTo(URL);
  }

  @Test
  public void testGetUrlIsDroppingTrailingSlash() throws Exception {
    when(configMock.getString(PEER_INFO_SECTION, STATIC_SUBSECTION, URL_KEY)).thenReturn(URL + "/");
    initializeConfiguration();
    assertThat(configuration).isNotNull();
    assertThat(configuration.peerInfoStatic().url()).isEqualTo(URL);
  }

  @Test
  public void testJGroupsPeerInfoNullWhenStaticPeerInfoConfig() throws Exception {
    initializeConfiguration();
    assertThat(configuration.peerInfoJGroups()).isNull();
  }

  @Test
  public void testGetJGroupsChannel() throws Exception {
    when(configMock.getEnum(PEER_INFO_SECTION, null, STRATEGY_KEY, DEFAULT_PEER_INFO_STRATEGY))
        .thenReturn(Configuration.PeerInfoStrategy.JGROUPS);
    initializeConfiguration();
    assertThat(configuration.jgroups().clusterName()).isEqualTo(DEFAULT_CLUSTER_NAME);

    when(configMock.getString(JGROUPS_SECTION, null, CLUSTER_NAME_KEY)).thenReturn("foo");
    initializeConfiguration();
    assertThat(configuration.jgroups().clusterName()).isEqualTo("foo");
  }

  @Test
  public void testGetJGroupsSkipInterface() throws Exception {
    when(configMock.getEnum(PEER_INFO_SECTION, null, STRATEGY_KEY, DEFAULT_PEER_INFO_STRATEGY))
        .thenReturn(Configuration.PeerInfoStrategy.JGROUPS);
    initializeConfiguration();
    assertThat(configuration.jgroups().skipInterface()).isEqualTo(DEFAULT_SKIP_INTERFACE_LIST);

    when(configMock.getStringList(JGROUPS_SECTION, null, SKIP_INTERFACE_KEY))
        .thenReturn(new String[] {"lo*", "eth0"});
    initializeConfiguration();
    assertThat(configuration.jgroups().skipInterface()).containsAllOf("lo*", "eth0").inOrder();
  }

  @Test
  public void testGetJGroupsMyUrl() throws Exception {
    when(configMock.getEnum(PEER_INFO_SECTION, null, STRATEGY_KEY, DEFAULT_PEER_INFO_STRATEGY))
        .thenReturn(Configuration.PeerInfoStrategy.JGROUPS);
    initializeConfiguration();
    assertThat(configuration.peerInfoJGroups().myUrl()).isNull();

    when(configMock.getString(PEER_INFO_SECTION, JGROUPS_SUBSECTION, MY_URL_KEY)).thenReturn(URL);
    initializeConfiguration();
    assertThat(configuration.peerInfoJGroups().myUrl()).isEqualTo(URL);

    when(configMock.getString(PEER_INFO_SECTION, JGROUPS_SUBSECTION, MY_URL_KEY))
        .thenReturn(URL + "/");
    initializeConfiguration();
    assertThat(configuration.peerInfoJGroups().myUrl()).isEqualTo(URL);
  }

  @Test
  public void testGetJGroupsMyUrlFromListenUrlWhenNoListenUrlSpecified() throws Exception {
    when(configMock.getEnum(PEER_INFO_SECTION, null, STRATEGY_KEY, DEFAULT_PEER_INFO_STRATEGY))
        .thenReturn(Configuration.PeerInfoStrategy.JGROUPS);
    initializeConfiguration();

    when(serverConfigMock.getStringList("httpd", null, "listenUrl")).thenReturn(new String[] {});

    exception.expect(ProvisionException.class);
    exception.expectMessage("exactly 1 value configured; found 0");
    getMyUrlProvider();
  }

  @Test
  public void testGetJGroupsMyUrlFromListenUrlWhenMultipleListenUrlsSpecified() throws Exception {
    when(configMock.getEnum(PEER_INFO_SECTION, null, STRATEGY_KEY, DEFAULT_PEER_INFO_STRATEGY))
        .thenReturn(Configuration.PeerInfoStrategy.JGROUPS);
    initializeConfiguration();

    when(serverConfigMock.getStringList("httpd", null, "listenUrl"))
        .thenReturn(new String[] {"a", "b"});

    exception.expect(ProvisionException.class);
    exception.expectMessage("exactly 1 value configured; found 2");
    getMyUrlProvider();
  }

  @Test
  public void testGetJGroupsMyUrlFromListenUrlWhenReverseProxyConfigured() throws Exception {
    when(configMock.getEnum(PEER_INFO_SECTION, null, STRATEGY_KEY, DEFAULT_PEER_INFO_STRATEGY))
        .thenReturn(Configuration.PeerInfoStrategy.JGROUPS);
    initializeConfiguration();

    when(serverConfigMock.getStringList("httpd", null, "listenUrl"))
        .thenReturn(new String[] {"proxy-https://foo"});

    exception.expect(ProvisionException.class);
    exception.expectMessage("when configured as reverse-proxy");
    getMyUrlProvider();
  }

  @Test
  public void testGetJGroupsMyUrlFromListenUrlWhenWildcardConfigured() throws Exception {
    when(configMock.getEnum(PEER_INFO_SECTION, null, STRATEGY_KEY, DEFAULT_PEER_INFO_STRATEGY))
        .thenReturn(Configuration.PeerInfoStrategy.JGROUPS);
    initializeConfiguration();

    when(serverConfigMock.getStringList("httpd", null, "listenUrl"))
        .thenReturn(new String[] {"https://*"});

    exception.expect(ProvisionException.class);
    exception.expectMessage("when configured with wildcard");
    getMyUrlProvider();
  }

  @Test
  public void testGetJGroupsMyUrlOverridesListenUrl() throws Exception {
    when(configMock.getEnum(PEER_INFO_SECTION, null, STRATEGY_KEY, DEFAULT_PEER_INFO_STRATEGY))
        .thenReturn(Configuration.PeerInfoStrategy.JGROUPS);
    when(configMock.getString(PEER_INFO_SECTION, JGROUPS_SUBSECTION, MY_URL_KEY)).thenReturn(URL);
    initializeConfiguration();
    assertThat(configuration.peerInfoJGroups().myUrl()).isEqualTo(URL);

    verify(serverConfigMock, never()).getStringList("httpd", null, "listenUrl");
    assertThat(getMyUrlProvider().get()).isEqualTo(URL);
  }

  @Test
  public void testGetJGroupsMyUrlFromListenUrl() throws Exception {
    when(configMock.getEnum(PEER_INFO_SECTION, null, STRATEGY_KEY, DEFAULT_PEER_INFO_STRATEGY))
        .thenReturn(Configuration.PeerInfoStrategy.JGROUPS);
    when(configMock.getString(PEER_INFO_SECTION, JGROUPS_SUBSECTION, MY_URL_KEY)).thenReturn(null);
    initializeConfiguration();
    assertThat(configuration.peerInfoJGroups().myUrl()).isNull();

    when(serverConfigMock.getStringList("httpd", null, "listenUrl"))
        .thenReturn(new String[] {"https://foo:8080"});

    String hostName = getLocalHost().getHostName();
    String expected = "https://" + hostName + ":8080";
    assertThat(getMyUrlProvider().get()).isEqualTo(expected);

    when(serverConfigMock.getStringList("httpd", null, "listenUrl"))
        .thenReturn(new String[] {"https://foo"});

    expected = "https://" + hostName;
    assertThat(getMyUrlProvider().get()).isEqualTo(expected);

    when(serverConfigMock.getStringList("httpd", null, "listenUrl"))
        .thenReturn(new String[] {"https://foo/"});

    assertThat(getMyUrlProvider().get()).isEqualTo(expected);
  }

  private MyUrlProvider getMyUrlProvider() {
    return new MyUrlProvider(serverConfigMock, configuration);
  }

  @Test
  public void testGetUser() throws Exception {
    initializeConfiguration();
    assertThat(configuration.http().user()).isEqualTo(EMPTY);

    when(configMock.getString(HTTP_SECTION, null, USER_KEY)).thenReturn(USER);
    initializeConfiguration();
    assertThat(configuration.http().user()).isEqualTo(USER);
  }

  @Test
  public void testGetPassword() throws Exception {
    initializeConfiguration();
    assertThat(configuration.http().password()).isEqualTo(EMPTY);

    when(configMock.getString(HTTP_SECTION, null, PASSWORD_KEY)).thenReturn(PASS);
    initializeConfiguration();
    assertThat(configuration.http().password()).isEqualTo(PASS);
  }

  @Test
  public void testGetConnectionTimeout() throws Exception {
    initializeConfiguration();
    assertThat(configuration.http().connectionTimeout()).isEqualTo(0);

    when(configMock.getInt(HTTP_SECTION, CONNECTION_TIMEOUT_KEY, DEFAULT_TIMEOUT_MS))
        .thenReturn(TIMEOUT);
    initializeConfiguration();
    assertThat(configuration.http().connectionTimeout()).isEqualTo(TIMEOUT);

    when(configMock.getInt(HTTP_SECTION, CONNECTION_TIMEOUT_KEY, DEFAULT_TIMEOUT_MS))
        .thenThrow(new IllegalArgumentException(ERROR_MESSAGE));
    initializeConfiguration();
    assertThat(configuration.http().connectionTimeout()).isEqualTo(DEFAULT_TIMEOUT_MS);
  }

  @Test
  public void testGetSocketTimeout() throws Exception {
    initializeConfiguration();
    assertThat(configuration.http().socketTimeout()).isEqualTo(0);

    when(configMock.getInt(HTTP_SECTION, SOCKET_TIMEOUT_KEY, DEFAULT_TIMEOUT_MS))
        .thenReturn(TIMEOUT);
    initializeConfiguration();
    assertThat(configuration.http().socketTimeout()).isEqualTo(TIMEOUT);

    when(configMock.getInt(HTTP_SECTION, SOCKET_TIMEOUT_KEY, DEFAULT_TIMEOUT_MS))
        .thenThrow(new IllegalArgumentException(ERROR_MESSAGE));
    initializeConfiguration();
    assertThat(configuration.http().socketTimeout()).isEqualTo(DEFAULT_TIMEOUT_MS);
  }

  @Test
  public void testGetMaxTries() throws Exception {
    initializeConfiguration();
    assertThat(configuration.http().maxTries()).isEqualTo(0);

    when(configMock.getInt(HTTP_SECTION, MAX_TRIES_KEY, DEFAULT_MAX_TRIES)).thenReturn(MAX_TRIES);
    initializeConfiguration();
    assertThat(configuration.http().maxTries()).isEqualTo(MAX_TRIES);

    when(configMock.getInt(HTTP_SECTION, MAX_TRIES_KEY, DEFAULT_MAX_TRIES))
        .thenThrow(new IllegalArgumentException(ERROR_MESSAGE));
    initializeConfiguration();
    assertThat(configuration.http().maxTries()).isEqualTo(DEFAULT_MAX_TRIES);
  }

  @Test
  public void testGetRetryInterval() throws Exception {
    initializeConfiguration();
    assertThat(configuration.http().retryInterval()).isEqualTo(0);

    when(configMock.getInt(HTTP_SECTION, RETRY_INTERVAL_KEY, DEFAULT_RETRY_INTERVAL))
        .thenReturn(RETRY_INTERVAL);
    initializeConfiguration();
    assertThat(configuration.http().retryInterval()).isEqualTo(RETRY_INTERVAL);

    when(configMock.getInt(HTTP_SECTION, RETRY_INTERVAL_KEY, DEFAULT_RETRY_INTERVAL))
        .thenThrow(new IllegalArgumentException(ERROR_MESSAGE));
    initializeConfiguration();
    assertThat(configuration.http().retryInterval()).isEqualTo(DEFAULT_RETRY_INTERVAL);
  }

  @Test
  public void testGetIndexThreadPoolSize() throws Exception {
    initializeConfiguration();
    assertThat(configuration.index().threadPoolSize()).isEqualTo(0);

    when(configMock.getInt(INDEX_SECTION, THREAD_POOL_SIZE_KEY, DEFAULT_THREAD_POOL_SIZE))
        .thenReturn(THREAD_POOL_SIZE);
    initializeConfiguration();
    assertThat(configuration.index().threadPoolSize()).isEqualTo(THREAD_POOL_SIZE);

    when(configMock.getInt(INDEX_SECTION, THREAD_POOL_SIZE_KEY, DEFAULT_THREAD_POOL_SIZE))
        .thenThrow(new IllegalArgumentException(ERROR_MESSAGE));
    initializeConfiguration();
    assertThat(configuration.index().threadPoolSize()).isEqualTo(DEFAULT_THREAD_POOL_SIZE);
  }

  @Test
  public void testGetIndexSynchronize() throws Exception {
    when(configMock.getBoolean(INDEX_SECTION, SYNCHRONIZE_KEY, DEFAULT_SYNCHRONIZE))
        .thenReturn(true);
    initializeConfiguration();
    assertThat(configuration.index().synchronize()).isTrue();

    when(configMock.getBoolean(INDEX_SECTION, SYNCHRONIZE_KEY, DEFAULT_SYNCHRONIZE))
        .thenReturn(false);
    initializeConfiguration();
    assertThat(configuration.index().synchronize()).isFalse();

    when(configMock.getBoolean(INDEX_SECTION, SYNCHRONIZE_KEY, DEFAULT_SYNCHRONIZE))
        .thenThrow(new IllegalArgumentException(ERROR_MESSAGE));
    initializeConfiguration();
    assertThat(configuration.index().synchronize()).isTrue();
  }

  @Test
  public void testGetCacheThreadPoolSize() throws Exception {
    initializeConfiguration();
    assertThat(configuration.cache().threadPoolSize()).isEqualTo(0);

    when(configMock.getInt(CACHE_SECTION, THREAD_POOL_SIZE_KEY, DEFAULT_THREAD_POOL_SIZE))
        .thenReturn(THREAD_POOL_SIZE);
    initializeConfiguration();
    assertThat(configuration.cache().threadPoolSize()).isEqualTo(THREAD_POOL_SIZE);

    when(configMock.getInt(CACHE_SECTION, THREAD_POOL_SIZE_KEY, DEFAULT_THREAD_POOL_SIZE))
        .thenThrow(new IllegalArgumentException(ERROR_MESSAGE));
    initializeConfiguration();
    assertThat(configuration.cache().threadPoolSize()).isEqualTo(DEFAULT_THREAD_POOL_SIZE);
  }

  @Test
  public void testGetCacheSynchronize() throws Exception {
    when(configMock.getBoolean(CACHE_SECTION, SYNCHRONIZE_KEY, DEFAULT_SYNCHRONIZE))
        .thenReturn(true);
    initializeConfiguration();
    assertThat(configuration.cache().synchronize()).isTrue();

    when(configMock.getBoolean(CACHE_SECTION, SYNCHRONIZE_KEY, DEFAULT_SYNCHRONIZE))
        .thenReturn(false);
    initializeConfiguration();
    assertThat(configuration.cache().synchronize()).isFalse();

    when(configMock.getBoolean(CACHE_SECTION, SYNCHRONIZE_KEY, DEFAULT_SYNCHRONIZE))
        .thenThrow(new IllegalArgumentException(ERROR_MESSAGE));
    initializeConfiguration();
    assertThat(configuration.cache().synchronize()).isTrue();
  }

  @Test
  public void testGetEventSynchronize() throws Exception {
    when(configMock.getBoolean(EVENT_SECTION, SYNCHRONIZE_KEY, DEFAULT_SYNCHRONIZE))
        .thenReturn(true);
    initializeConfiguration();
    assertThat(configuration.event().synchronize()).isTrue();

    when(configMock.getBoolean(EVENT_SECTION, SYNCHRONIZE_KEY, DEFAULT_SYNCHRONIZE))
        .thenReturn(false);
    initializeConfiguration();
    assertThat(configuration.event().synchronize()).isFalse();

    when(configMock.getBoolean(EVENT_SECTION, SYNCHRONIZE_KEY, DEFAULT_SYNCHRONIZE))
        .thenThrow(new IllegalArgumentException(ERROR_MESSAGE));
    initializeConfiguration();
    assertThat(configuration.event().synchronize()).isTrue();
  }

  @Test
  public void testGetDefaultSharedDirectory() throws Exception {
    when(cfgFactoryMock.getGlobalPluginConfig(pluginName)).thenReturn(configMock);
    when(configMock.getString(MAIN_SECTION, null, SHARED_DIRECTORY_KEY)).thenReturn(null);
    when(configMock.getEnum(PEER_INFO_SECTION, null, STRATEGY_KEY, DEFAULT_PEER_INFO_STRATEGY))
        .thenReturn(DEFAULT_PEER_INFO_STRATEGY);
    when(configMock.getStringList(JGROUPS_SECTION, null, SKIP_INTERFACE_KEY))
        .thenReturn(new String[] {});

    initializeConfiguration();
    assertEquals(configuration.main().sharedDirectory(), site.resolve(DEFAULT_SHARED_DIRECTORY));
  }

  @Test
  public void testGetSharedDirectory() throws Exception {
    initializeConfiguration();
    assertEquals(configuration.main().sharedDirectory(), SHARED_DIR_PATH);
  }

  @Test
  public void testRelativeSharedDir() {
    when(configMock.getString(MAIN_SECTION, null, SHARED_DIRECTORY_KEY))
        .thenReturn(RELATIVE_SHARED_DIRECTORY);
    initializeConfiguration();

    assertEquals(
        configuration.main().sharedDirectory(), SITE_PATH.resolve(RELATIVE_SHARED_DIRECTORY));
  }

  @Test
  public void testGetCleanupInterval() throws Exception {
    initializeConfiguration();
    assertThat(configuration.websession().cleanupInterval()).isEqualTo(DEFAULT_CLEANUP_INTERVAL_MS);

    when(configMock.getString(WEBSESSION_SECTION, null, CLEANUP_INTERVAL_KEY))
        .thenReturn("30 seconds");
    initializeConfiguration();
    assertThat(configuration.websession().cleanupInterval()).isEqualTo(SECONDS.toMillis(30));
  }

  @Test
  public void testGetWebsessionSynchronize() throws Exception {
    when(configMock.getBoolean(WEBSESSION_SECTION, SYNCHRONIZE_KEY, DEFAULT_SYNCHRONIZE))
        .thenReturn(true);
    initializeConfiguration();
    assertThat(configuration.websession().synchronize()).isTrue();

    when(configMock.getBoolean(WEBSESSION_SECTION, SYNCHRONIZE_KEY, DEFAULT_SYNCHRONIZE))
        .thenReturn(false);
    initializeConfiguration();
    assertThat(configuration.websession().synchronize()).isFalse();

    when(configMock.getBoolean(WEBSESSION_SECTION, SYNCHRONIZE_KEY, DEFAULT_SYNCHRONIZE))
        .thenThrow(new IllegalArgumentException(ERROR_MESSAGE));
    initializeConfiguration();
    assertThat(configuration.websession().synchronize()).isTrue();
  }
}
