blob: 147e79f9bb2c79fc7dc6b6d070459d7cc682e4dc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
namespace Apache.Ignite.Core.Tests.Cache
{
using System;
using System.IO;
using System.Linq;
using Apache.Ignite.Core.Cache.Configuration;
using Apache.Ignite.Core.Common;
using Apache.Ignite.Core.Configuration;
using NUnit.Framework;
using DataPageEvictionMode = Apache.Ignite.Core.Configuration.DataPageEvictionMode;
/// <summary>
/// Tests disk persistence.
/// </summary>
public class PersistenceTest
{
/** Temp dir for WAL. */
private readonly string _tempDir = TestUtils.GetTempDirectoryName();
/// <summary>
/// Sets up the test.
/// </summary>
[SetUp]
public void SetUp()
{
TestUtils.ClearWorkDir();
}
/// <summary>
/// Tears down the test.
/// </summary>
[TearDown]
public void TearDown()
{
Ignition.StopAll(true);
if (Directory.Exists(_tempDir))
{
Directory.Delete(_tempDir, true);
}
TestUtils.ClearWorkDir();
}
/// <summary>
/// Tests that cache data survives node restart.
/// </summary>
[Test]
public void TestCacheDataSurvivesNodeRestart()
{
var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
{
DataStorageConfiguration = new DataStorageConfiguration
{
StoragePath = Path.Combine(_tempDir, "Store"),
WalPath = Path.Combine(_tempDir, "WalStore"),
WalArchivePath = Path.Combine(_tempDir, "WalArchive"),
MetricsEnabled = true,
DefaultDataRegionConfiguration = new DataRegionConfiguration
{
PageEvictionMode = DataPageEvictionMode.Disabled,
Name = DataStorageConfiguration.DefaultDataRegionName,
PersistenceEnabled = true
},
DataRegionConfigurations = new[]
{
new DataRegionConfiguration
{
Name = "volatileRegion",
PersistenceEnabled = false
}
}
}
};
const string cacheName = "persistentCache";
const string volatileCacheName = "volatileCache";
// Start Ignite, put data, stop.
using (var ignite = Ignition.Start(cfg))
{
ignite.GetCluster().SetActive(true);
// Create cache with default region (persistence enabled), add data.
var cache = ignite.CreateCache<int, int>(cacheName);
cache[1] = 1;
// Check some metrics.
CheckDataStorageMetrics(ignite);
// Create cache with non-persistent region.
var volatileCache = ignite.CreateCache<int, int>(new CacheConfiguration
{
Name = volatileCacheName,
DataRegionName = "volatileRegion"
});
volatileCache[2] = 2;
}
// Verify directories.
Assert.IsTrue(Directory.Exists(cfg.DataStorageConfiguration.StoragePath));
Assert.IsTrue(Directory.Exists(cfg.DataStorageConfiguration.WalPath));
Assert.IsTrue(Directory.Exists(cfg.DataStorageConfiguration.WalArchivePath));
// Start Ignite, verify data survival.
using (var ignite = Ignition.Start(cfg))
{
ignite.GetCluster().SetActive(true);
// Persistent cache already exists and contains data.
var cache = ignite.GetCache<int, int>(cacheName);
Assert.AreEqual(1, cache[1]);
// Non-persistent cache does not exist.
var ex = Assert.Throws<ArgumentException>(() => ignite.GetCache<int, int>(volatileCacheName));
Assert.AreEqual("Cache doesn't exist: volatileCache", ex.Message);
}
// Delete store directory.
Directory.Delete(_tempDir, true);
// Start Ignite, verify data loss.
using (var ignite = Ignition.Start(cfg))
{
ignite.GetCluster().SetActive(true);
Assert.IsFalse(ignite.GetCacheNames().Contains(cacheName));
}
}
/// <summary>
/// Checks that data storage metrics reflect some write operations.
/// </summary>
private static void CheckDataStorageMetrics(IIgnite ignite)
{
var metrics = ignite.GetDataStorageMetrics();
Assert.Greater(metrics.WalLoggingRate, 0);
}
/// <summary>
/// Tests the grid activation with persistence (inactive by default).
/// </summary>
[Test]
public void TestGridActivationWithPersistence()
{
var cfg = GetPersistentConfiguration();
// Default config, inactive by default (IsActiveOnStart is ignored when persistence is enabled).
using (var ignite = Ignition.Start(cfg))
{
CheckIsActive(ignite, false);
ignite.GetCluster().SetActive(true);
CheckIsActive(ignite, true);
ignite.GetCluster().SetActive(false);
CheckIsActive(ignite, false);
}
}
/// <summary>
/// Tests the grid activation without persistence (active by default).
/// </summary>
[Test]
public void TestGridActivationNoPersistence()
{
var cfg = TestUtils.GetTestConfiguration();
Assert.IsTrue(cfg.IsActiveOnStart);
using (var ignite = Ignition.Start(cfg))
{
CheckIsActive(ignite, true);
ignite.GetCluster().SetActive(false);
CheckIsActive(ignite, false);
ignite.GetCluster().SetActive(true);
CheckIsActive(ignite, true);
}
cfg.IsActiveOnStart = false;
using (var ignite = Ignition.Start(cfg))
{
CheckIsActive(ignite, false);
ignite.GetCluster().SetActive(true);
CheckIsActive(ignite, true);
ignite.GetCluster().SetActive(false);
CheckIsActive(ignite, false);
}
}
/// <summary>
/// Tests the baseline topology.
/// </summary>
[Test]
public void TestBaselineTopology()
{
var cfg1 = new IgniteConfiguration(GetPersistentConfiguration())
{
ConsistentId = "node1"
};
var cfg2 = new IgniteConfiguration(GetPersistentConfiguration())
{
ConsistentId = "node2",
IgniteInstanceName = "2"
};
using (var ignite = Ignition.Start(cfg1))
{
// Start and stop to bump topology version.
Ignition.Start(cfg2);
Ignition.Stop(cfg2.IgniteInstanceName, true);
var cluster = ignite.GetCluster();
Assert.AreEqual(3, cluster.TopologyVersion);
// Can not set baseline while inactive.
var ex = Assert.Throws<IgniteException>(() => cluster.SetBaselineTopology(2));
Assert.AreEqual("Changing BaselineTopology on inactive cluster is not allowed.", ex.Message);
// Set with version.
cluster.SetActive(true);
cluster.SetBaselineTopology(2);
var res = cluster.GetBaselineTopology();
CollectionAssert.AreEquivalent(new[] {"node1", "node2"}, res.Select(x => x.ConsistentId));
cluster.SetBaselineTopology(1);
Assert.AreEqual("node1", cluster.GetBaselineTopology().Single().ConsistentId);
// Set with nodes.
cluster.SetBaselineTopology(res);
res = cluster.GetBaselineTopology();
CollectionAssert.AreEquivalent(new[] { "node1", "node2" }, res.Select(x => x.ConsistentId));
cluster.SetBaselineTopology(cluster.GetTopology(1));
Assert.AreEqual("node1", cluster.GetBaselineTopology().Single().ConsistentId);
// Set to two nodes.
cluster.SetBaselineTopology(cluster.GetTopology(2));
}
// Check auto activation on cluster restart.
using (var ignite = Ignition.Start(cfg1))
using (Ignition.Start(cfg2))
{
var cluster = ignite.GetCluster();
Assert.IsTrue(cluster.IsActive());
var res = cluster.GetBaselineTopology();
CollectionAssert.AreEquivalent(new[] { "node1", "node2" }, res.Select(x => x.ConsistentId));
}
}
/// <summary>
/// Tests the wal disable/enable functionality.
/// </summary>
[Test]
public void TestWalDisableEnable()
{
using (var ignite = Ignition.Start(GetPersistentConfiguration()))
{
var cluster = ignite.GetCluster();
cluster.SetActive(true);
var cache = ignite.CreateCache<int, int>("foo");
Assert.IsTrue(cluster.IsWalEnabled(cache.Name));
cache[1] = 1;
cluster.DisableWal(cache.Name);
Assert.IsFalse(cluster.IsWalEnabled(cache.Name));
cache[2] = 2;
cluster.EnableWal(cache.Name);
Assert.IsTrue(cluster.IsWalEnabled(cache.Name));
Assert.AreEqual(1, cache[1]);
Assert.AreEqual(2, cache[2]);
// Check exceptions.
var ex = Assert.Throws<IgniteException>(() => cluster.IsWalEnabled("bar"));
Assert.AreEqual("Cache not found: bar", ex.Message);
ex = Assert.Throws<IgniteException>(() => cluster.DisableWal("bar"));
Assert.AreEqual("Cache doesn't exist: bar", ex.Message);
ex = Assert.Throws<IgniteException>(() => cluster.EnableWal("bar"));
Assert.AreEqual("Cache doesn't exist: bar", ex.Message);
}
}
/// <summary>
/// Checks active state.
/// </summary>
private static void CheckIsActive(IIgnite ignite, bool isActive)
{
Assert.AreEqual(isActive, ignite.GetCluster().IsActive());
if (isActive)
{
var cache = ignite.GetOrCreateCache<int, int>("default");
cache[1] = 1;
Assert.AreEqual(1, cache[1]);
}
else
{
var ex = Assert.Throws<IgniteException>(() => ignite.GetOrCreateCache<int, int>("default"));
Assert.AreEqual("Can not perform the operation because the cluster is inactive.",
ex.Message.Substring(0, 62));
}
}
/// <summary>
/// Gets the persistent configuration.
/// </summary>
private static IgniteConfiguration GetPersistentConfiguration()
{
return new IgniteConfiguration(TestUtils.GetTestConfiguration())
{
DataStorageConfiguration = new DataStorageConfiguration
{
DefaultDataRegionConfiguration = new DataRegionConfiguration
{
PersistenceEnabled = true,
Name = "foo"
}
}
};
}
}
}