blob: bc0321e7f6d979bb08d7fad9a3de8e97716a67e0 [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.
*/
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable MemberCanBePrivate.Global
namespace Apache.Ignite.Core.Tests
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Schema;
using Apache.Ignite.Core.Binary;
using Apache.Ignite.Core.Cache.Affinity.Rendezvous;
using Apache.Ignite.Core.Cache.Configuration;
using Apache.Ignite.Core.Cache.Eviction;
using Apache.Ignite.Core.Cache.Expiry;
using Apache.Ignite.Core.Cache.Store;
using Apache.Ignite.Core.Common;
using Apache.Ignite.Core.Communication.Tcp;
using Apache.Ignite.Core.DataStructures.Configuration;
using Apache.Ignite.Core.Discovery.Tcp;
using Apache.Ignite.Core.Discovery.Tcp.Multicast;
using Apache.Ignite.Core.Events;
using Apache.Ignite.Core.Impl.Common;
using Apache.Ignite.Core.Lifecycle;
using Apache.Ignite.Core.Log;
using Apache.Ignite.Core.Plugin.Cache;
using Apache.Ignite.Core.Tests.Binary;
using Apache.Ignite.Core.Tests.Plugin;
using Apache.Ignite.Core.Transactions;
using Apache.Ignite.NLog;
using NUnit.Framework;
/// <summary>
/// Tests <see cref="IgniteConfiguration"/> serialization.
/// </summary>
public class IgniteConfigurationSerializerTest
{
/// <summary>
/// Tests the predefined XML.
/// </summary>
[Test]
public void TestPredefinedXml()
{
var xml = @"<igniteConfig workDirectory='c:' JvmMaxMemoryMb='1024' MetricsLogFrequency='0:0:10' isDaemon='true' isLateAffinityAssignment='false' springConfigUrl='c:\myconfig.xml' autoGenerateIgniteInstanceName='true'>
<localhost>127.1.1.1</localhost>
<binaryConfiguration compactFooter='false' keepDeserialized='true'>
<nameMapper type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+NameMapper' bar='testBar' />
<idMapper type='Apache.Ignite.Core.Tests.Binary.IdMapper' />
<types>
<string>Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+FooClass, Apache.Ignite.Core.Tests</string>
</types>
<typeConfigurations>
<binaryTypeConfiguration affinityKeyFieldName='affKeyFieldName' isEnum='true' keepDeserialized='True' typeName='typeName'>
<idMapper type='Apache.Ignite.Core.Tests.Binary.IdMapper, Apache.Ignite.Core.Tests' />
<nameMapper type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+NameMapper, Apache.Ignite.Core.Tests' />
<serializer type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+TestSerializer, Apache.Ignite.Core.Tests' />
</binaryTypeConfiguration>
</typeConfigurations>
</binaryConfiguration>
<discoverySpi type='TcpDiscoverySpi' joinTimeout='0:1:0' localAddress='192.168.1.1' localPort='6655'>
<ipFinder type='TcpDiscoveryMulticastIpFinder' addressRequestAttempts='7' />
</discoverySpi>
<communicationSpi type='TcpCommunicationSpi' ackSendThreshold='33' idleConnectionTimeout='0:1:2' />
<jvmOptions><string>-Xms1g</string><string>-Xmx4g</string></jvmOptions>
<lifecycleHandlers>
<iLifecycleHandler type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+LifecycleBean' foo='15' />
</lifecycleHandlers>
<cacheConfiguration>
<cacheConfiguration cacheMode='Replicated' readThrough='true' writeThrough='true' enableStatistics='true' writeBehindCoalescing='false' partitionLossPolicy='ReadWriteAll'>
<queryEntities>
<queryEntity keyType='System.Int32' valueType='System.String' tableName='myTable'>
<fields>
<queryField name='length' fieldType='System.Int32' isKeyField='true' />
</fields>
<aliases>
<queryAlias fullName='somefield.field' alias='shortField' />
</aliases>
<indexes>
<queryIndex name='idx' indexType='Geospatial'>
<fields>
<queryIndexField name='indexFld' isDescending='true' />
</fields>
</queryIndex>
</indexes>
</queryEntity>
</queryEntities>
<evictionPolicy type='LruEvictionPolicy' batchSize='1' maxSize='2' maxMemorySize='3' />
<nearConfiguration nearStartSize='7'>
<evictionPolicy type='FifoEvictionPolicy' batchSize='10' maxSize='20' maxMemorySize='30' />
</nearConfiguration>
<affinityFunction type='RendezvousAffinityFunction' partitions='99' excludeNeighbors='true' />
<expiryPolicyFactory type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+MyPolicyFactory, Apache.Ignite.Core.Tests' />
<pluginConfigurations><iCachePluginConfiguration type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+MyPluginConfiguration, Apache.Ignite.Core.Tests' /></pluginConfigurations>
</cacheConfiguration>
<cacheConfiguration name='secondCache' />
</cacheConfiguration>
<includedEventTypes>
<int>42</int>
<int>TaskFailed</int>
<int>JobFinished</int>
</includedEventTypes>
<userAttributes>
<pair key='myNode' value='true' />
<pair key='foo'><value type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+FooClass, Apache.Ignite.Core.Tests'><bar>Baz</bar></value></pair>
</userAttributes>
<atomicConfiguration backups='2' cacheMode='Local' atomicSequenceReserveSize='250' />
<transactionConfiguration defaultTransactionConcurrency='Optimistic' defaultTransactionIsolation='RepeatableRead' defaultTimeout='0:1:2' pessimisticTransactionLogSize='15' pessimisticTransactionLogLinger='0:0:33' />
<logger type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+TestLogger, Apache.Ignite.Core.Tests' />
<pluginConfigurations>
<iPluginConfiguration type='Apache.Ignite.Core.Tests.Plugin.TestIgnitePluginConfiguration, Apache.Ignite.Core.Tests' />
</pluginConfigurations>
<eventStorageSpi type='MemoryEventStorageSpi' expirationTimeout='00:00:23.45' maxEventCount='129' />
<memoryConfiguration concurrencyLevel='3' defaultMemoryPolicyName='dfPlc' pageSize='45' systemCacheInitialSize='67' systemCacheMaxSize='68'>
<memoryPolicies>
<memoryPolicyConfiguration emptyPagesPoolSize='1' evictionThreshold='0.2' name='dfPlc' pageEvictionMode='RandomLru' initialSize='89' maxSize='98' swapFilePath='abc' />
</memoryPolicies>
</memoryConfiguration>
</igniteConfig>";
var cfg = IgniteConfiguration.FromXml(xml);
Assert.AreEqual("c:", cfg.WorkDirectory);
Assert.AreEqual("127.1.1.1", cfg.Localhost);
Assert.IsTrue(cfg.IsDaemon);
Assert.IsFalse(cfg.IsLateAffinityAssignment);
Assert.AreEqual(1024, cfg.JvmMaxMemoryMb);
Assert.AreEqual(TimeSpan.FromSeconds(10), cfg.MetricsLogFrequency);
Assert.AreEqual(TimeSpan.FromMinutes(1), ((TcpDiscoverySpi)cfg.DiscoverySpi).JoinTimeout);
Assert.AreEqual("192.168.1.1", ((TcpDiscoverySpi)cfg.DiscoverySpi).LocalAddress);
Assert.AreEqual(6655, ((TcpDiscoverySpi)cfg.DiscoverySpi).LocalPort);
Assert.AreEqual(7,
((TcpDiscoveryMulticastIpFinder) ((TcpDiscoverySpi) cfg.DiscoverySpi).IpFinder).AddressRequestAttempts);
Assert.AreEqual(new[] { "-Xms1g", "-Xmx4g" }, cfg.JvmOptions);
Assert.AreEqual(15, ((LifecycleBean) cfg.LifecycleHandlers.Single()).Foo);
Assert.AreEqual("testBar", ((NameMapper) cfg.BinaryConfiguration.NameMapper).Bar);
Assert.AreEqual(
"Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+FooClass, Apache.Ignite.Core.Tests",
cfg.BinaryConfiguration.Types.Single());
Assert.IsFalse(cfg.BinaryConfiguration.CompactFooter);
Assert.AreEqual(new[] {42, EventType.TaskFailed, EventType.JobFinished}, cfg.IncludedEventTypes);
Assert.AreEqual(@"c:\myconfig.xml", cfg.SpringConfigUrl);
Assert.IsTrue(cfg.AutoGenerateIgniteInstanceName);
Assert.AreEqual("secondCache", cfg.CacheConfiguration.Last().Name);
var cacheCfg = cfg.CacheConfiguration.First();
Assert.AreEqual(CacheMode.Replicated, cacheCfg.CacheMode);
Assert.IsTrue(cacheCfg.ReadThrough);
Assert.IsTrue(cacheCfg.WriteThrough);
Assert.IsInstanceOf<MyPolicyFactory>(cacheCfg.ExpiryPolicyFactory);
Assert.IsTrue(cacheCfg.EnableStatistics);
Assert.IsFalse(cacheCfg.WriteBehindCoalescing);
Assert.AreEqual(PartitionLossPolicy.ReadWriteAll, cacheCfg.PartitionLossPolicy);
var queryEntity = cacheCfg.QueryEntities.Single();
Assert.AreEqual(typeof(int), queryEntity.KeyType);
Assert.AreEqual(typeof(string), queryEntity.ValueType);
Assert.AreEqual("myTable", queryEntity.TableName);
Assert.AreEqual("length", queryEntity.Fields.Single().Name);
Assert.AreEqual(typeof(int), queryEntity.Fields.Single().FieldType);
Assert.IsTrue(queryEntity.Fields.Single().IsKeyField);
Assert.AreEqual("somefield.field", queryEntity.Aliases.Single().FullName);
Assert.AreEqual("shortField", queryEntity.Aliases.Single().Alias);
Assert.AreEqual(QueryIndexType.Geospatial, queryEntity.Indexes.Single().IndexType);
Assert.AreEqual("indexFld", queryEntity.Indexes.Single().Fields.Single().Name);
Assert.AreEqual(true, queryEntity.Indexes.Single().Fields.Single().IsDescending);
var nearCfg = cacheCfg.NearConfiguration;
Assert.IsNotNull(nearCfg);
Assert.AreEqual(7, nearCfg.NearStartSize);
var plc = nearCfg.EvictionPolicy as FifoEvictionPolicy;
Assert.IsNotNull(plc);
Assert.AreEqual(10, plc.BatchSize);
Assert.AreEqual(20, plc.MaxSize);
Assert.AreEqual(30, plc.MaxMemorySize);
var plc2 = cacheCfg.EvictionPolicy as LruEvictionPolicy;
Assert.IsNotNull(plc2);
Assert.AreEqual(1, plc2.BatchSize);
Assert.AreEqual(2, plc2.MaxSize);
Assert.AreEqual(3, plc2.MaxMemorySize);
var af = cacheCfg.AffinityFunction as RendezvousAffinityFunction;
Assert.IsNotNull(af);
Assert.AreEqual(99, af.Partitions);
Assert.IsTrue(af.ExcludeNeighbors);
Assert.AreEqual(new Dictionary<string, object>
{
{"myNode", "true"},
{"foo", new FooClass {Bar = "Baz"}}
}, cfg.UserAttributes);
var atomicCfg = cfg.AtomicConfiguration;
Assert.AreEqual(2, atomicCfg.Backups);
Assert.AreEqual(CacheMode.Local, atomicCfg.CacheMode);
Assert.AreEqual(250, atomicCfg.AtomicSequenceReserveSize);
var tx = cfg.TransactionConfiguration;
Assert.AreEqual(TransactionConcurrency.Optimistic, tx.DefaultTransactionConcurrency);
Assert.AreEqual(TransactionIsolation.RepeatableRead, tx.DefaultTransactionIsolation);
Assert.AreEqual(new TimeSpan(0,1,2), tx.DefaultTimeout);
Assert.AreEqual(15, tx.PessimisticTransactionLogSize);
Assert.AreEqual(TimeSpan.FromSeconds(33), tx.PessimisticTransactionLogLinger);
var comm = cfg.CommunicationSpi as TcpCommunicationSpi;
Assert.IsNotNull(comm);
Assert.AreEqual(33, comm.AckSendThreshold);
Assert.AreEqual(new TimeSpan(0, 1, 2), comm.IdleConnectionTimeout);
Assert.IsInstanceOf<TestLogger>(cfg.Logger);
var binType = cfg.BinaryConfiguration.TypeConfigurations.Single();
Assert.AreEqual("typeName", binType.TypeName);
Assert.AreEqual("affKeyFieldName", binType.AffinityKeyFieldName);
Assert.IsTrue(binType.IsEnum);
Assert.AreEqual(true, binType.KeepDeserialized);
Assert.IsInstanceOf<IdMapper>(binType.IdMapper);
Assert.IsInstanceOf<NameMapper>(binType.NameMapper);
Assert.IsInstanceOf<TestSerializer>(binType.Serializer);
var plugins = cfg.PluginConfigurations;
Assert.IsNotNull(plugins);
Assert.IsNotNull(plugins.Cast<TestIgnitePluginConfiguration>().SingleOrDefault());
Assert.IsNotNull(cacheCfg.PluginConfigurations.Cast<MyPluginConfiguration>().SingleOrDefault());
var eventStorage = cfg.EventStorageSpi as MemoryEventStorageSpi;
Assert.IsNotNull(eventStorage);
Assert.AreEqual(23.45, eventStorage.ExpirationTimeout.TotalSeconds);
Assert.AreEqual(129, eventStorage.MaxEventCount);
var memCfg = cfg.MemoryConfiguration;
Assert.IsNotNull(memCfg);
Assert.AreEqual(3, memCfg.ConcurrencyLevel);
Assert.AreEqual("dfPlc", memCfg.DefaultMemoryPolicyName);
Assert.AreEqual(45, memCfg.PageSize);
Assert.AreEqual(67, memCfg.SystemCacheInitialSize);
Assert.AreEqual(68, memCfg.SystemCacheMaxSize);
var memPlc = memCfg.MemoryPolicies.Single();
Assert.AreEqual(1, memPlc.EmptyPagesPoolSize);
Assert.AreEqual(0.2, memPlc.EvictionThreshold);
Assert.AreEqual("dfPlc", memPlc.Name);
Assert.AreEqual(DataPageEvictionMode.RandomLru, memPlc.PageEvictionMode);
Assert.AreEqual("abc", memPlc.SwapFilePath);
Assert.AreEqual(89, memPlc.InitialSize);
Assert.AreEqual(98, memPlc.MaxSize);
}
/// <summary>
/// Tests the serialize deserialize.
/// </summary>
[Test]
public void TestSerializeDeserialize()
{
// Test custom
CheckSerializeDeserialize(GetTestConfig());
// Test custom with different culture to make sure numbers are serialized properly
RunWithCustomCulture(() => CheckSerializeDeserialize(GetTestConfig()));
// Test default
CheckSerializeDeserialize(new IgniteConfiguration());
}
/// <summary>
/// Tests that all properties are present in the schema.
/// </summary>
[Test]
[SuppressMessage("ReSharper", "PossibleNullReferenceException")]
public void TestAllPropertiesArePresentInSchema()
{
var schema = XDocument.Load("IgniteConfigurationSection.xsd")
.Root.Elements()
.Single(x => x.Attribute("name").Value == "igniteConfiguration");
var type = typeof(IgniteConfiguration);
CheckPropertyIsPresentInSchema(type, schema);
}
/// <summary>
/// Checks the property is present in schema.
/// </summary>
// ReSharper disable once UnusedParameter.Local
private static void CheckPropertyIsPresentInSchema(Type type, XElement schema)
{
Func<string, string> toLowerCamel = x => char.ToLowerInvariant(x[0]) + x.Substring(1);
foreach (var prop in type.GetProperties())
{
if (!prop.CanWrite)
continue; // Read-only properties are not configured in XML.
if (prop.GetCustomAttributes(typeof(ObsoleteAttribute), true).Any())
continue; // Skip deprecated.
var propType = prop.PropertyType;
var isCollection = propType.IsGenericType &&
propType.GetGenericTypeDefinition() == typeof(ICollection<>);
if (isCollection)
propType = propType.GetGenericArguments().First();
var propName = toLowerCamel(prop.Name);
Assert.IsTrue(schema.Descendants().Select(x => x.Attribute("name"))
.Any(x => x != null && x.Value == propName),
"Property is missing in XML schema: " + propName);
var isComplexProp = propType.Namespace != null && propType.Namespace.StartsWith("Apache.Ignite.Core");
if (isComplexProp)
CheckPropertyIsPresentInSchema(propType, schema);
}
}
/// <summary>
/// Tests the schema validation.
/// </summary>
[Test]
public void TestSchemaValidation()
{
CheckSchemaValidation();
RunWithCustomCulture(CheckSchemaValidation);
// Check invalid xml
const string invalidXml =
@"<igniteConfiguration xmlns='http://ignite.apache.org/schema/dotnet/IgniteConfigurationSection'>
<binaryConfiguration /><binaryConfiguration />
</igniteConfiguration>";
Assert.Throws<XmlSchemaValidationException>(() => CheckSchemaValidation(invalidXml));
}
/// <summary>
/// Tests the XML conversion.
/// </summary>
[Test]
public void TestToXml()
{
// Empty config
Assert.AreEqual("<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n<igniteConfiguration " +
"xmlns=\"http://ignite.apache.org/schema/dotnet/IgniteConfigurationSection\" />",
new IgniteConfiguration().ToXml());
// Some properties
var cfg = new IgniteConfiguration
{
IgniteInstanceName = "myGrid",
ClientMode = true,
CacheConfiguration = new[]
{
new CacheConfiguration("myCache")
{
CacheMode = CacheMode.Replicated,
QueryEntities = new[]
{
new QueryEntity(typeof(int)),
new QueryEntity(typeof(int), typeof(string))
}
}
},
IncludedEventTypes = new[]
{
EventType.CacheEntryCreated,
EventType.CacheNodesLeft
}
};
Assert.AreEqual(FixLineEndings(@"<?xml version=""1.0"" encoding=""utf-16""?>
<igniteConfiguration clientMode=""true"" igniteInstanceName=""myGrid"" xmlns=""http://ignite.apache.org/schema/dotnet/IgniteConfigurationSection"">
<cacheConfiguration>
<cacheConfiguration cacheMode=""Replicated"" name=""myCache"">
<queryEntities>
<queryEntity valueType=""System.Int32"" valueTypeName=""java.lang.Integer"" />
<queryEntity keyType=""System.Int32"" keyTypeName=""java.lang.Integer"" valueType=""System.String"" valueTypeName=""java.lang.String"" />
</queryEntities>
</cacheConfiguration>
</cacheConfiguration>
<includedEventTypes>
<int>CacheEntryCreated</int>
<int>CacheNodesLeft</int>
</includedEventTypes>
</igniteConfiguration>"), cfg.ToXml());
// Custom section name and indent
var sb = new StringBuilder();
var settings = new XmlWriterSettings
{
Indent = true,
IndentChars = " "
};
using (var xmlWriter = XmlWriter.Create(sb, settings))
{
cfg.ToXml(xmlWriter, "igCfg");
}
Assert.AreEqual(FixLineEndings(@"<?xml version=""1.0"" encoding=""utf-16""?>
<igCfg clientMode=""true"" igniteInstanceName=""myGrid"" xmlns=""http://ignite.apache.org/schema/dotnet/IgniteConfigurationSection"">
<cacheConfiguration>
<cacheConfiguration cacheMode=""Replicated"" name=""myCache"">
<queryEntities>
<queryEntity valueType=""System.Int32"" valueTypeName=""java.lang.Integer"" />
<queryEntity keyType=""System.Int32"" keyTypeName=""java.lang.Integer"" valueType=""System.String"" valueTypeName=""java.lang.String"" />
</queryEntities>
</cacheConfiguration>
</cacheConfiguration>
<includedEventTypes>
<int>CacheEntryCreated</int>
<int>CacheNodesLeft</int>
</includedEventTypes>
</igCfg>"), sb.ToString());
}
/// <summary>
/// Tests the deserialization.
/// </summary>
[Test]
public void TestFromXml()
{
// Empty section.
var cfg = IgniteConfiguration.FromXml("<x />");
AssertReflectionEqual(new IgniteConfiguration(), cfg);
// Empty section with XML header.
cfg = IgniteConfiguration.FromXml("<?xml version=\"1.0\" encoding=\"utf-16\"?><x />");
AssertReflectionEqual(new IgniteConfiguration(), cfg);
// Simple test.
cfg = IgniteConfiguration.FromXml(@"<igCfg igniteInstanceName=""myGrid"" clientMode=""true"" />");
AssertReflectionEqual(new IgniteConfiguration {IgniteInstanceName = "myGrid", ClientMode = true}, cfg);
// Invalid xml.
var ex = Assert.Throws<ConfigurationErrorsException>(() =>
IgniteConfiguration.FromXml(@"<igCfg foo=""bar"" />"));
Assert.AreEqual("Invalid IgniteConfiguration attribute 'foo=bar', there is no such property " +
"on 'Apache.Ignite.Core.IgniteConfiguration'", ex.Message);
// Xml reader.
using (var xmlReader = XmlReader.Create(
new StringReader(@"<igCfg igniteInstanceName=""myGrid"" clientMode=""true"" />")))
{
cfg = IgniteConfiguration.FromXml(xmlReader);
}
AssertReflectionEqual(new IgniteConfiguration { IgniteInstanceName = "myGrid", ClientMode = true }, cfg);
}
/// <summary>
/// Ensures windows-style \r\n line endings in a string literal.
/// Git settings may cause string literals in both styles.
/// </summary>
private static string FixLineEndings(string s)
{
return s.Split('\n').Select(x => x.TrimEnd('\r'))
.Aggregate((acc, x) => string.Format("{0}\r\n{1}", acc, x));
}
/// <summary>
/// Checks the schema validation.
/// </summary>
private static void CheckSchemaValidation()
{
var sb = new StringBuilder();
using (var xmlWriter = XmlWriter.Create(sb))
{
IgniteConfigurationXmlSerializer.Serialize(GetTestConfig(), xmlWriter, "igniteConfiguration");
}
CheckSchemaValidation(sb.ToString());
}
/// <summary>
/// Checks the schema validation.
/// </summary>
/// <param name="xml">The XML.</param>
private static void CheckSchemaValidation(string xml)
{
var document = new XmlDocument();
document.Schemas.Add("http://ignite.apache.org/schema/dotnet/IgniteConfigurationSection",
XmlReader.Create("IgniteConfigurationSection.xsd"));
document.Load(new StringReader(xml));
document.Validate(null);
}
/// <summary>
/// Checks the serialize deserialize.
/// </summary>
/// <param name="cfg">The config.</param>
private static void CheckSerializeDeserialize(IgniteConfiguration cfg)
{
var resCfg = SerializeDeserialize(cfg);
AssertReflectionEqual(cfg, resCfg);
}
/// <summary>
/// Serializes and deserializes a config.
/// </summary>
private static IgniteConfiguration SerializeDeserialize(IgniteConfiguration cfg)
{
var xml = cfg.ToXml();
return IgniteConfiguration.FromXml(xml);
}
/// <summary>
/// Asserts equality with reflection.
/// </summary>
private static void AssertReflectionEqual(object x, object y)
{
var type = x.GetType();
Assert.AreEqual(type, y.GetType());
if (type.IsValueType || type == typeof (string) || type.IsSubclassOf(typeof (Type)))
{
Assert.AreEqual(x, y);
return;
}
var props = type.GetProperties().Where(p => p.GetIndexParameters().Length == 0);
foreach (var propInfo in props)
{
var propType = propInfo.PropertyType;
var xVal = propInfo.GetValue(x, null);
var yVal = propInfo.GetValue(y, null);
if (xVal == null || yVal == null)
{
Assert.IsNull(xVal);
Assert.IsNull(yVal);
}
else if (propType != typeof(string) && propType.IsGenericType &&
(propType.GetGenericTypeDefinition() == typeof(ICollection<>) ||
propType.GetGenericTypeDefinition() == typeof(IDictionary<,>) ))
{
var xCol = ((IEnumerable) xVal).OfType<object>().ToList();
var yCol = ((IEnumerable) yVal).OfType<object>().ToList();
Assert.AreEqual(xCol.Count, yCol.Count);
for (int i = 0; i < xCol.Count; i++)
AssertReflectionEqual(xCol[i], yCol[i]);
}
else
{
AssertReflectionEqual(xVal, yVal);
}
}
}
/// <summary>
/// Gets the test configuration.
/// </summary>
private static IgniteConfiguration GetTestConfig()
{
return new IgniteConfiguration
{
IgniteInstanceName = "gridName",
JvmOptions = new[] {"1", "2"},
Localhost = "localhost11",
JvmClasspath = "classpath",
Assemblies = new[] {"asm1", "asm2", "asm3"},
BinaryConfiguration = new BinaryConfiguration
{
TypeConfigurations = new[]
{
new BinaryTypeConfiguration
{
IsEnum = true,
KeepDeserialized = true,
AffinityKeyFieldName = "affKeyFieldName",
TypeName = "typeName",
IdMapper = new IdMapper(),
NameMapper = new NameMapper(),
Serializer = new TestSerializer()
},
new BinaryTypeConfiguration
{
IsEnum = false,
KeepDeserialized = false,
AffinityKeyFieldName = "affKeyFieldName",
TypeName = "typeName2",
Serializer = new BinaryReflectiveSerializer()
}
},
Types = new[] {typeof (string).FullName},
IdMapper = new IdMapper(),
KeepDeserialized = true,
NameMapper = new NameMapper(),
Serializer = new TestSerializer()
},
CacheConfiguration = new[]
{
new CacheConfiguration("cacheName")
{
AtomicityMode = CacheAtomicityMode.Transactional,
Backups = 15,
CacheMode = CacheMode.Replicated,
CacheStoreFactory = new TestCacheStoreFactory(),
CopyOnRead = false,
EagerTtl = false,
Invalidate = true,
KeepBinaryInStore = true,
LoadPreviousValue = true,
LockTimeout = TimeSpan.FromSeconds(56),
LongQueryWarningTimeout = TimeSpan.FromSeconds(99),
MaxConcurrentAsyncOperations = 24,
QueryEntities = new[]
{
new QueryEntity
{
Fields = new[]
{
new QueryField("field", typeof (int)) { IsKeyField = true }
},
Indexes = new[]
{
new QueryIndex("field") {IndexType = QueryIndexType.FullText}
},
Aliases = new[]
{
new QueryAlias("field.field", "fld")
},
KeyType = typeof (string),
ValueType = typeof (long),
TableName = "table-1",
KeyFieldName = "k",
ValueFieldName = "v"
},
},
ReadFromBackup = false,
RebalanceBatchSize = 33,
RebalanceDelay = TimeSpan.MaxValue,
RebalanceMode = CacheRebalanceMode.Sync,
RebalanceThrottle = TimeSpan.FromHours(44),
RebalanceTimeout = TimeSpan.FromMinutes(8),
SqlEscapeAll = true,
WriteBehindBatchSize = 45,
WriteBehindEnabled = true,
WriteBehindFlushFrequency = TimeSpan.FromSeconds(55),
WriteBehindFlushSize = 66,
WriteBehindFlushThreadCount = 2,
WriteBehindCoalescing = false,
WriteSynchronizationMode = CacheWriteSynchronizationMode.FullAsync,
NearConfiguration = new NearCacheConfiguration
{
NearStartSize = 5,
EvictionPolicy = new FifoEvictionPolicy
{
BatchSize = 19, MaxMemorySize = 1024, MaxSize = 555
}
},
EvictionPolicy = new LruEvictionPolicy
{
BatchSize = 18, MaxMemorySize = 1023, MaxSize = 554
},
AffinityFunction = new RendezvousAffinityFunction
{
ExcludeNeighbors = true,
Partitions = 48
},
ExpiryPolicyFactory = new MyPolicyFactory(),
EnableStatistics = true,
PluginConfigurations = new[]
{
new MyPluginConfiguration()
},
MemoryPolicyName = "somePolicy",
PartitionLossPolicy = PartitionLossPolicy.ReadOnlyAll
}
},
ClientMode = true,
DiscoverySpi = new TcpDiscoverySpi
{
NetworkTimeout = TimeSpan.FromSeconds(1),
SocketTimeout = TimeSpan.FromSeconds(2),
AckTimeout = TimeSpan.FromSeconds(3),
JoinTimeout = TimeSpan.FromSeconds(4),
MaxAckTimeout = TimeSpan.FromSeconds(5),
IpFinder = new TcpDiscoveryMulticastIpFinder
{
TimeToLive = 110,
MulticastGroup = "multicastGroup",
AddressRequestAttempts = 10,
MulticastPort = 987,
ResponseTimeout = TimeSpan.FromDays(1),
LocalAddress = "127.0.0.2",
Endpoints = new[] {"", "abc"}
},
ClientReconnectDisabled = true,
ForceServerMode = true,
IpFinderCleanFrequency = TimeSpan.FromMinutes(7),
LocalAddress = "127.0.0.1",
LocalPort = 49900,
LocalPortRange = 13,
ReconnectCount = 11,
StatisticsPrintFrequency = TimeSpan.FromSeconds(20),
ThreadPriority = 6,
TopologyHistorySize = 1234567
},
IgniteHome = "igniteHome",
IncludedEventTypes = EventType.CacheQueryAll,
JvmDllPath = @"c:\jvm",
JvmInitialMemoryMb = 1024,
JvmMaxMemoryMb = 2048,
LifecycleHandlers = new[] {new LifecycleBean(), new LifecycleBean()},
MetricsExpireTime = TimeSpan.FromSeconds(15),
MetricsHistorySize = 45,
MetricsLogFrequency = TimeSpan.FromDays(2),
MetricsUpdateFrequency = TimeSpan.MinValue,
NetworkSendRetryCount = 7,
NetworkSendRetryDelay = TimeSpan.FromSeconds(98),
NetworkTimeout = TimeSpan.FromMinutes(4),
SuppressWarnings = true,
WorkDirectory = @"c:\work",
IsDaemon = true,
UserAttributes = Enumerable.Range(1, 10).ToDictionary(x => x.ToString(),
x => x%2 == 0 ? (object) x : new FooClass {Bar = x.ToString()}),
AtomicConfiguration = new AtomicConfiguration
{
CacheMode = CacheMode.Replicated,
AtomicSequenceReserveSize = 200,
Backups = 2
},
TransactionConfiguration = new TransactionConfiguration
{
PessimisticTransactionLogSize = 23,
DefaultTransactionIsolation = TransactionIsolation.ReadCommitted,
DefaultTimeout = TimeSpan.FromDays(2),
DefaultTransactionConcurrency = TransactionConcurrency.Optimistic,
PessimisticTransactionLogLinger = TimeSpan.FromHours(3)
},
CommunicationSpi = new TcpCommunicationSpi
{
LocalPort = 47501,
MaxConnectTimeout = TimeSpan.FromSeconds(34),
MessageQueueLimit = 15,
ConnectTimeout = TimeSpan.FromSeconds(17),
IdleConnectionTimeout = TimeSpan.FromSeconds(19),
SelectorsCount = 8,
ReconnectCount = 33,
SocketReceiveBufferSize = 512,
AckSendThreshold = 99,
DirectBuffer = false,
DirectSendBuffer = true,
LocalPortRange = 45,
LocalAddress = "127.0.0.1",
TcpNoDelay = false,
SlowClientQueueLimit = 98,
SocketSendBufferSize = 2045,
UnacknowledgedMessagesBufferSize = 3450
},
IsLateAffinityAssignment = false,
SpringConfigUrl = "test",
Logger = new IgniteNLogLogger(),
FailureDetectionTimeout = TimeSpan.FromMinutes(2),
ClientFailureDetectionTimeout = TimeSpan.FromMinutes(3),
PluginConfigurations = new[] {new TestIgnitePluginConfiguration() },
EventStorageSpi = new MemoryEventStorageSpi
{
ExpirationTimeout = TimeSpan.FromMilliseconds(12345),
MaxEventCount = 257
},
MemoryConfiguration = new MemoryConfiguration
{
ConcurrencyLevel = 3,
DefaultMemoryPolicyName = "somePolicy",
PageSize = 4,
SystemCacheInitialSize = 5,
SystemCacheMaxSize = 6,
MemoryPolicies = new[]
{
new MemoryPolicyConfiguration
{
Name = "myDefaultPlc",
PageEvictionMode = DataPageEvictionMode.Random2Lru,
InitialSize = 245 * 1024 * 1024,
MaxSize = 345 * 1024 * 1024,
EvictionThreshold = 0.88,
EmptyPagesPoolSize = 77,
SwapFilePath = "myPath1"
},
new MemoryPolicyConfiguration
{
Name = "customPlc",
PageEvictionMode = DataPageEvictionMode.RandomLru,
EvictionThreshold = 0.77,
EmptyPagesPoolSize = 66,
SwapFilePath = "somePath2"
}
}
}
};
}
/// <summary>
/// Runs the with custom culture.
/// </summary>
/// <param name="action">The action.</param>
private static void RunWithCustomCulture(Action action)
{
RunWithCulture(action, CultureInfo.InvariantCulture);
RunWithCulture(action, CultureInfo.GetCultureInfo("ru-RU"));
}
/// <summary>
/// Runs the with culture.
/// </summary>
/// <param name="action">The action.</param>
/// <param name="cultureInfo">The culture information.</param>
private static void RunWithCulture(Action action, CultureInfo cultureInfo)
{
var oldCulture = Thread.CurrentThread.CurrentCulture;
try
{
Thread.CurrentThread.CurrentCulture = cultureInfo;
action();
}
finally
{
Thread.CurrentThread.CurrentCulture = oldCulture;
}
}
/// <summary>
/// Test bean.
/// </summary>
public class LifecycleBean : ILifecycleHandler
{
/// <summary>
/// Gets or sets the foo.
/// </summary>
/// <value>
/// The foo.
/// </value>
public int Foo { get; set; }
/// <summary>
/// This method is called when lifecycle event occurs.
/// </summary>
/// <param name="evt">Lifecycle event.</param>
public void OnLifecycleEvent(LifecycleEventType evt)
{
// No-op.
}
}
/// <summary>
/// Test mapper.
/// </summary>
public class NameMapper : IBinaryNameMapper
{
/// <summary>
/// Gets or sets the bar.
/// </summary>
/// <value>
/// The bar.
/// </value>
public string Bar { get; set; }
/// <summary>
/// Gets the type name.
/// </summary>
/// <param name="name">The name.</param>
/// <returns>
/// Type name.
/// </returns>
public string GetTypeName(string name)
{
return name;
}
/// <summary>
/// Gets the field name.
/// </summary>
/// <param name="name">The name.</param>
/// <returns>
/// Field name.
/// </returns>
public string GetFieldName(string name)
{
return name;
}
}
/// <summary>
/// Serializer.
/// </summary>
public class TestSerializer : IBinarySerializer
{
/** <inheritdoc /> */
public void WriteBinary(object obj, IBinaryWriter writer)
{
// No-op.
}
/** <inheritdoc /> */
public void ReadBinary(object obj, IBinaryReader reader)
{
// No-op.
}
}
/// <summary>
/// Test class.
/// </summary>
public class FooClass
{
public string Bar { get; set; }
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return string.Equals(Bar, ((FooClass) obj).Bar);
}
public override int GetHashCode()
{
return Bar != null ? Bar.GetHashCode() : 0;
}
public static bool operator ==(FooClass left, FooClass right)
{
return Equals(left, right);
}
public static bool operator !=(FooClass left, FooClass right)
{
return !Equals(left, right);
}
}
/// <summary>
/// Test factory.
/// </summary>
public class TestCacheStoreFactory : IFactory<ICacheStore>
{
/// <summary>
/// Creates an instance of the cache store.
/// </summary>
/// <returns>
/// New instance of the cache store.
/// </returns>
public ICacheStore CreateInstance()
{
return null;
}
}
/// <summary>
/// Test logger.
/// </summary>
public class TestLogger : ILogger
{
/** <inheritdoc /> */
public void Log(LogLevel level, string message, object[] args, IFormatProvider formatProvider, string category,
string nativeErrorInfo, Exception ex)
{
throw new NotImplementedException();
}
/** <inheritdoc /> */
public bool IsEnabled(LogLevel level)
{
throw new NotImplementedException();
}
}
/// <summary>
/// Test factory.
/// </summary>
public class MyPolicyFactory : IFactory<IExpiryPolicy>
{
/** <inheritdoc /> */
public IExpiryPolicy CreateInstance()
{
throw new NotImplementedException();
}
}
public class MyPluginConfiguration : ICachePluginConfiguration
{
int? ICachePluginConfiguration.CachePluginConfigurationClosureFactoryId
{
get { return 0; }
}
void ICachePluginConfiguration.WriteBinary(IBinaryRawWriter writer)
{
throw new NotImplementedException();
}
}
}
}