You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/09/04 15:31:38 UTC
[06/37] ignite git commit: IGNITE-1348: Moved GridGain's .Net module
to Ignite.
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs
new file mode 100644
index 0000000..39b6b24
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs
@@ -0,0 +1,961 @@
+/*
+ * 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
+{
+ using System;
+ using System.Collections.Concurrent;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading;
+ using System.Threading.Tasks;
+ using Apache.Ignite.Core.Cache.Query;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Events;
+ using Apache.Ignite.Core.Impl;
+ using Apache.Ignite.Core.Impl.Events;
+ using Apache.Ignite.Core.Portable;
+ using Apache.Ignite.Core.Tests.Compute;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// <see cref="IEvents"/> tests.
+ /// </summary>
+ public class EventsTest
+ {
+ /** */
+ private IIgnite _grid1;
+
+ /** */
+ private IIgnite _grid2;
+
+ /** */
+ private IIgnite _grid3;
+
+ /** */
+ private IIgnite[] _grids;
+
+ /** */
+ public static int IdGen;
+
+ [TestFixtureTearDown]
+ public void FixtureTearDown()
+ {
+ StopGrids();
+ }
+
+ /// <summary>
+ /// Executes before each test.
+ /// </summary>
+ [SetUp]
+ public void SetUp()
+ {
+ StartGrids();
+ EventsTestHelper.ListenResult = true;
+ }
+
+ /// <summary>
+ /// Executes after each test.
+ /// </summary>
+ [TearDown]
+ public virtual void TearDown()
+ {
+ try
+ {
+ TestUtils.AssertHandleRegistryIsEmpty(1000, _grid1, _grid2, _grid3);
+ }
+ catch (Exception)
+ {
+ // Restart grids to cleanup
+ StopGrids();
+
+ throw;
+ }
+ finally
+ {
+ EventsTestHelper.AssertFailures();
+
+ if (TestContext.CurrentContext.Test.Name.StartsWith("TestEventTypes"))
+ StopGrids(); // clean events for other tests
+ }
+ }
+
+ /// <summary>
+ /// Tests enable/disable of event types.
+ /// </summary>
+ [Test]
+ public void TestEnableDisable()
+ {
+ var events = _grid1.Events();
+
+ Assert.AreEqual(0, events.GetEnabledEvents().Length);
+
+ Assert.IsFalse(EventType.EvtsCache.Any(events.IsEnabled));
+
+ events.EnableLocal(EventType.EvtsCache);
+
+ Assert.AreEqual(EventType.EvtsCache, events.GetEnabledEvents());
+
+ Assert.IsTrue(EventType.EvtsCache.All(events.IsEnabled));
+
+ events.EnableLocal(EventType.EvtsTaskExecution);
+
+ events.DisableLocal(EventType.EvtsCache);
+
+ Assert.AreEqual(EventType.EvtsTaskExecution, events.GetEnabledEvents());
+ }
+
+ /// <summary>
+ /// Tests LocalListen.
+ /// </summary>
+ [Test]
+ public void TestLocalListen()
+ {
+ var events = _grid1.Events();
+ var listener = EventsTestHelper.GetListener();
+ var eventType = EventType.EvtsTaskExecution;
+
+ events.EnableLocal(eventType);
+
+ events.LocalListen(listener, eventType);
+
+ CheckSend(3); // 3 events per task * 3 grids
+
+ // Check unsubscription for specific event
+ events.StopLocalListen(listener, EventType.EvtTaskReduced);
+
+ CheckSend(2);
+
+ // Unsubscribe from all events
+ events.StopLocalListen(listener);
+
+ CheckNoEvent();
+
+ // Check unsubscription by filter
+ events.LocalListen(listener, EventType.EvtTaskReduced);
+
+ CheckSend();
+
+ EventsTestHelper.ListenResult = false;
+
+ CheckSend(); // one last event will be received for each listener
+
+ CheckNoEvent();
+ }
+
+ /// <summary>
+ /// Tests LocalListen.
+ /// </summary>
+ [Test]
+ [Ignore("IGNITE-879")]
+ public void TestLocalListenRepeatedSubscription()
+ {
+ var events = _grid1.Events();
+ var listener = EventsTestHelper.GetListener();
+ var eventType = EventType.EvtsTaskExecution;
+
+ events.EnableLocal(eventType);
+
+ events.LocalListen(listener, eventType);
+
+ CheckSend(3); // 3 events per task * 3 grids
+
+ events.LocalListen(listener, eventType);
+ events.LocalListen(listener, eventType);
+
+ CheckSend(9);
+
+ events.StopLocalListen(listener, eventType);
+
+ CheckSend(6);
+
+ events.StopLocalListen(listener, eventType);
+
+ CheckSend(3);
+
+ events.StopLocalListen(listener, eventType);
+
+ CheckNoEvent();
+ }
+
+ /// <summary>
+ /// Tests all available event types/classes.
+ /// </summary>
+ [Test, TestCaseSource("TestCases")]
+ public void TestEventTypes(EventTestCase testCase)
+ {
+ var events = _grid1.Events();
+
+ events.EnableLocal(testCase.EventType);
+
+ var listener = EventsTestHelper.GetListener();
+
+ events.LocalListen(listener, testCase.EventType);
+
+ EventsTestHelper.ClearReceived(testCase.EventCount);
+
+ testCase.GenerateEvent(_grid1);
+
+ EventsTestHelper.VerifyReceive(testCase.EventCount, testCase.EventObjectType, testCase.EventType);
+
+ if (testCase.VerifyEvents != null)
+ testCase.VerifyEvents(EventsTestHelper.ReceivedEvents.Reverse(), _grid1);
+
+ // Check stop
+ events.StopLocalListen(listener);
+
+ EventsTestHelper.ClearReceived(0);
+
+ testCase.GenerateEvent(_grid1);
+
+ Thread.Sleep(EventsTestHelper.Timeout);
+ }
+
+ /// <summary>
+ /// Test cases for TestEventTypes: type id + type + event generator.
+ /// </summary>
+ public IEnumerable<EventTestCase> TestCases
+ {
+ get
+ {
+ yield return new EventTestCase
+ {
+ EventType = EventType.EvtsCache,
+ EventObjectType = typeof (CacheEvent),
+ GenerateEvent = g => g.Cache<int, int>(null).Put(1, 1),
+ VerifyEvents = (e, g) => VerifyCacheEvents(e, g),
+ EventCount = 1
+ };
+
+ yield return new EventTestCase
+ {
+ EventType = EventType.EvtsTaskExecution,
+ EventObjectType = typeof (TaskEvent),
+ GenerateEvent = g => GenerateTaskEvent(g),
+ VerifyEvents = (e, g) => VerifyTaskEvents(e),
+ EventCount = 3
+ };
+
+ yield return new EventTestCase
+ {
+ EventType = EventType.EvtsJobExecution,
+ EventObjectType = typeof (JobEvent),
+ GenerateEvent = g => GenerateTaskEvent(g),
+ EventCount = 9
+ };
+
+ yield return new EventTestCase
+ {
+ EventType = new[] {EventType.EvtCacheQueryExecuted},
+ EventObjectType = typeof (CacheQueryExecutedEvent),
+ GenerateEvent = g => GenerateCacheQueryEvent(g),
+ EventCount = 1
+ };
+
+ yield return new EventTestCase
+ {
+ EventType = new[] { EventType.EvtCacheQueryObjectRead },
+ EventObjectType = typeof (CacheQueryReadEvent),
+ GenerateEvent = g => GenerateCacheQueryEvent(g),
+ EventCount = 1
+ };
+ }
+ }
+
+ /// <summary>
+ /// Tests the LocalQuery.
+ /// </summary>
+ [Test]
+ public void TestLocalQuery()
+ {
+ var events = _grid1.Events();
+
+ var eventType = EventType.EvtsTaskExecution;
+
+ events.EnableLocal(eventType);
+
+ var oldEvents = events.LocalQuery();
+
+ GenerateTaskEvent();
+
+ // "Except" works because of overridden equality
+ var qryResult = events.LocalQuery(eventType).Except(oldEvents).ToList();
+
+ Assert.AreEqual(3, qryResult.Count);
+ }
+
+ /// <summary>
+ /// Tests the WaitForLocal.
+ /// </summary>
+ [Test]
+ public void TestWaitForLocal([Values(true, false)] bool async)
+ {
+ var events = _grid1.Events();
+
+ var timeout = TimeSpan.FromSeconds(3);
+
+ if (async)
+ events = events.WithAsync();
+
+ var eventType = EventType.EvtsTaskExecution;
+
+ events.EnableLocal(eventType);
+
+ Func<Func<IEvent>, Task<IEvent>> getWaitTask;
+
+ if (async)
+ getWaitTask = func =>
+ {
+ Assert.IsNull(func());
+ var task = events.GetFuture<IEvent>().ToTask();
+ GenerateTaskEvent();
+ return task;
+ };
+ else
+ getWaitTask = func =>
+ {
+ var task = Task.Factory.StartNew(func);
+ Thread.Sleep(500); // allow task to start and begin waiting for events
+ GenerateTaskEvent();
+ return task;
+ };
+
+ // No params
+ var waitTask = getWaitTask(() => events.WaitForLocal());
+
+ waitTask.Wait(timeout);
+
+ // Event types
+ waitTask = getWaitTask(() => events.WaitForLocal(EventType.EvtTaskReduced));
+
+ Assert.IsTrue(waitTask.Wait(timeout));
+ Assert.IsInstanceOf(typeof(TaskEvent), waitTask.Result);
+ Assert.AreEqual(EventType.EvtTaskReduced, waitTask.Result.Type);
+
+ // Filter
+ waitTask = getWaitTask(() => events.WaitForLocal(
+ new EventFilter<IEvent>((g, e) => e.Type == EventType.EvtTaskReduced)));
+
+ Assert.IsTrue(waitTask.Wait(timeout));
+ Assert.IsInstanceOf(typeof(TaskEvent), waitTask.Result);
+ Assert.AreEqual(EventType.EvtTaskReduced, waitTask.Result.Type);
+
+ // Filter & types
+ waitTask = getWaitTask(() => events.WaitForLocal(
+ new EventFilter<IEvent>((g, e) => e.Type == EventType.EvtTaskReduced), EventType.EvtTaskReduced));
+
+ Assert.IsTrue(waitTask.Wait(timeout));
+ Assert.IsInstanceOf(typeof(TaskEvent), waitTask.Result);
+ Assert.AreEqual(EventType.EvtTaskReduced, waitTask.Result.Type);
+ }
+
+ /// <summary>
+ /// Tests RemoteListen.
+ /// </summary>
+ [Test]
+ public void TestRemoteListen(
+ [Values(true, false)] bool async,
+ [Values(true, false)] bool portable,
+ [Values(true, false)] bool autoUnsubscribe)
+ {
+ foreach (var g in _grids)
+ {
+ g.Events().EnableLocal(EventType.EvtsJobExecution);
+ g.Events().EnableLocal(EventType.EvtsTaskExecution);
+ }
+
+ var events = _grid1.Events();
+
+ var expectedType = EventType.EvtJobStarted;
+
+ var remoteFilter = portable
+ ? (IEventFilter<IEvent>) new RemoteEventPortableFilter(expectedType)
+ : new RemoteEventFilter(expectedType);
+
+ var localListener = EventsTestHelper.GetListener();
+
+ if (async)
+ events = events.WithAsync();
+
+ var listenId = events.RemoteListen(localListener: localListener, remoteFilter: remoteFilter,
+ autoUnsubscribe: autoUnsubscribe);
+
+ if (async)
+ listenId = events.GetFuture<Guid>().Get();
+
+ CheckSend(3, typeof(JobEvent), expectedType);
+
+ _grid3.Events().DisableLocal(EventType.EvtsJobExecution);
+
+ CheckSend(2, typeof(JobEvent), expectedType);
+
+ events.StopRemoteListen(listenId);
+
+ if (async)
+ events.GetFuture().Get();
+
+ CheckNoEvent();
+
+ // Check unsubscription with listener
+ events.RemoteListen(localListener: localListener, remoteFilter: remoteFilter,
+ autoUnsubscribe: autoUnsubscribe);
+
+ if (async)
+ events.GetFuture<Guid>().Get();
+
+ CheckSend(2, typeof(JobEvent), expectedType);
+
+ EventsTestHelper.ListenResult = false;
+
+ CheckSend(1, typeof(JobEvent), expectedType); // one last event
+
+ CheckNoEvent();
+ }
+
+ /// <summary>
+ /// Tests RemoteQuery.
+ /// </summary>
+ [Test]
+ public void TestRemoteQuery([Values(true, false)] bool async)
+ {
+ foreach (var g in _grids)
+ g.Events().EnableLocal(EventType.EvtsJobExecution);
+
+ var events = _grid1.Events();
+
+ var eventFilter = new RemoteEventFilter(EventType.EvtJobStarted);
+
+ var oldEvents = events.RemoteQuery(eventFilter);
+
+ if (async)
+ events = events.WithAsync();
+
+ GenerateTaskEvent();
+
+ var remoteQuery = events.RemoteQuery(eventFilter, EventsTestHelper.Timeout, EventType.EvtsJobExecution);
+
+ if (async)
+ {
+ Assert.IsNull(remoteQuery);
+
+ remoteQuery = events.GetFuture<List<IEvent>>().Get().ToList();
+ }
+
+ var qryResult = remoteQuery.Except(oldEvents).Cast<JobEvent>().ToList();
+
+ Assert.AreEqual(_grids.Length, qryResult.Count);
+
+ Assert.IsTrue(qryResult.All(x => x.Type == EventType.EvtJobStarted));
+ }
+
+ /// <summary>
+ /// Tests serialization.
+ /// </summary>
+ [Test]
+ public void TestSerialization()
+ {
+ var grid = (Ignite) _grid1;
+ var comp = (Impl.Compute.Compute) grid.Cluster.ForLocal().Compute();
+ var locNode = grid.Cluster.LocalNode;
+
+ var expectedGuid = Guid.Parse("00000000-0000-0001-0000-000000000002");
+ var expectedGridGuid = new IgniteGuid(expectedGuid, 3);
+
+ using (var inStream = IgniteManager.Memory.Allocate().Stream())
+ {
+ var result = comp.ExecuteJavaTask<bool>("org.apache.ignite.platform.PlatformEventsWriteEventTask",
+ inStream.MemoryPointer);
+
+ Assert.IsTrue(result);
+
+ inStream.SynchronizeInput();
+
+ var reader = grid.Marshaller.StartUnmarshal(inStream);
+
+ var cacheEvent = EventReader.Read<CacheEvent>(reader);
+ CheckEventBase(cacheEvent);
+ Assert.AreEqual("cacheName", cacheEvent.CacheName);
+ Assert.AreEqual(locNode, cacheEvent.EventNode);
+ Assert.AreEqual(1, cacheEvent.Partition);
+ Assert.AreEqual(true, cacheEvent.IsNear);
+ Assert.AreEqual(2, cacheEvent.Key);
+ Assert.AreEqual(expectedGridGuid, cacheEvent.Xid);
+ Assert.AreEqual(3, cacheEvent.LockId);
+ Assert.AreEqual(4, cacheEvent.NewValue);
+ Assert.AreEqual(true, cacheEvent.HasNewValue);
+ Assert.AreEqual(5, cacheEvent.OldValue);
+ Assert.AreEqual(true, cacheEvent.HasOldValue);
+ Assert.AreEqual(expectedGuid, cacheEvent.SubjectId);
+ Assert.AreEqual("cloClsName", cacheEvent.ClosureClassName);
+ Assert.AreEqual("taskName", cacheEvent.TaskName);
+
+ var qryExecEvent = EventReader.Read<CacheQueryExecutedEvent>(reader);
+ CheckEventBase(qryExecEvent);
+ Assert.AreEqual("qryType", qryExecEvent.QueryType);
+ Assert.AreEqual("cacheName", qryExecEvent.CacheName);
+ Assert.AreEqual("clsName", qryExecEvent.ClassName);
+ Assert.AreEqual("clause", qryExecEvent.Clause);
+ Assert.AreEqual(expectedGuid, qryExecEvent.SubjectId);
+ Assert.AreEqual("taskName", qryExecEvent.TaskName);
+
+ var qryReadEvent = EventReader.Read<CacheQueryReadEvent>(reader);
+ CheckEventBase(qryReadEvent);
+ Assert.AreEqual("qryType", qryReadEvent.QueryType);
+ Assert.AreEqual("cacheName", qryReadEvent.CacheName);
+ Assert.AreEqual("clsName", qryReadEvent.ClassName);
+ Assert.AreEqual("clause", qryReadEvent.Clause);
+ Assert.AreEqual(expectedGuid, qryReadEvent.SubjectId);
+ Assert.AreEqual("taskName", qryReadEvent.TaskName);
+ Assert.AreEqual(1, qryReadEvent.Key);
+ Assert.AreEqual(2, qryReadEvent.Value);
+ Assert.AreEqual(3, qryReadEvent.OldValue);
+ Assert.AreEqual(4, qryReadEvent.Row);
+
+ var cacheRebalancingEvent = EventReader.Read<CacheRebalancingEvent>(reader);
+ CheckEventBase(cacheRebalancingEvent);
+ Assert.AreEqual("cacheName", cacheRebalancingEvent.CacheName);
+ Assert.AreEqual(1, cacheRebalancingEvent.Partition);
+ Assert.AreEqual(locNode, cacheRebalancingEvent.DiscoveryNode);
+ Assert.AreEqual(2, cacheRebalancingEvent.DiscoveryEventType);
+ Assert.AreEqual(3, cacheRebalancingEvent.DiscoveryTimestamp);
+
+ var checkpointEvent = EventReader.Read<CheckpointEvent>(reader);
+ CheckEventBase(checkpointEvent);
+ Assert.AreEqual("cpKey", checkpointEvent.Key);
+
+ var discoEvent = EventReader.Read<DiscoveryEvent>(reader);
+ CheckEventBase(discoEvent);
+ Assert.AreEqual(grid.TopologyVersion, discoEvent.TopologyVersion);
+ Assert.AreEqual(grid.Nodes(), discoEvent.TopologyNodes);
+
+ var jobEvent = EventReader.Read<JobEvent>(reader);
+ CheckEventBase(jobEvent);
+ Assert.AreEqual(expectedGridGuid, jobEvent.JobId);
+ Assert.AreEqual("taskClsName", jobEvent.TaskClassName);
+ Assert.AreEqual("taskName", jobEvent.TaskName);
+ Assert.AreEqual(locNode, jobEvent.TaskNode);
+ Assert.AreEqual(expectedGridGuid, jobEvent.TaskSessionId);
+ Assert.AreEqual(expectedGuid, jobEvent.TaskSubjectId);
+
+ var spaceEvent = EventReader.Read<SwapSpaceEvent>(reader);
+ CheckEventBase(spaceEvent);
+ Assert.AreEqual("space", spaceEvent.Space);
+
+ var taskEvent = EventReader.Read<TaskEvent>(reader);
+ CheckEventBase(taskEvent);
+ Assert.AreEqual(true,taskEvent.Internal);
+ Assert.AreEqual(expectedGuid, taskEvent.SubjectId);
+ Assert.AreEqual("taskClsName", taskEvent.TaskClassName);
+ Assert.AreEqual("taskName", taskEvent.TaskName);
+ Assert.AreEqual(expectedGridGuid, taskEvent.TaskSessionId);
+ }
+ }
+
+ /// <summary>
+ /// Checks base event fields serialization.
+ /// </summary>
+ /// <param name="evt">The evt.</param>
+ private void CheckEventBase(IEvent evt)
+ {
+ var locNode = _grid1.Cluster.LocalNode;
+
+ Assert.AreEqual(locNode, evt.Node);
+ Assert.AreEqual("msg", evt.Message);
+ Assert.AreEqual(EventType.EvtSwapSpaceCleared, evt.Type);
+ Assert.IsNotNullOrEmpty(evt.Name);
+ Assert.AreNotEqual(Guid.Empty, evt.Id.GlobalId);
+ Assert.IsTrue((evt.TimeStamp - DateTime.Now).TotalSeconds < 10);
+ }
+
+ /// <summary>
+ /// Sends events in various ways and verifies correct receive.
+ /// </summary>
+ /// <param name="repeat">Expected event count multiplier.</param>
+ /// <param name="eventObjectType">Expected event object type.</param>
+ /// <param name="eventType">Type of the event.</param>
+ private void CheckSend(int repeat = 1, Type eventObjectType = null, params int[] eventType)
+ {
+ EventsTestHelper.ClearReceived(repeat);
+
+ GenerateTaskEvent();
+
+ EventsTestHelper.VerifyReceive(repeat, eventObjectType ?? typeof (TaskEvent),
+ eventType.Any() ? eventType : EventType.EvtsTaskExecution);
+ }
+
+ /// <summary>
+ /// Checks that no event has arrived.
+ /// </summary>
+ private void CheckNoEvent()
+ {
+ // this will result in an exception in case of a event
+ EventsTestHelper.ClearReceived(0);
+
+ GenerateTaskEvent();
+
+ Thread.Sleep(EventsTestHelper.Timeout);
+
+ EventsTestHelper.AssertFailures();
+ }
+
+ /// <summary>
+ /// Gets the Ignite configuration.
+ /// </summary>
+ private static IgniteConfiguration Configuration(string springConfigUrl)
+ {
+ return new IgniteConfiguration
+ {
+ SpringConfigUrl = springConfigUrl,
+ JvmClasspath = TestUtils.CreateTestClasspath(),
+ JvmOptions = TestUtils.TestJavaOptions(),
+ PortableConfiguration = new PortableConfiguration
+ {
+ TypeConfigurations = new List<PortableTypeConfiguration>
+ {
+ new PortableTypeConfiguration(typeof (RemoteEventPortableFilter))
+ }
+ }
+ };
+ }
+
+ /// <summary>
+ /// Generates the task event.
+ /// </summary>
+ private void GenerateTaskEvent(IIgnite grid = null)
+ {
+ (grid ?? _grid1).Compute().Broadcast(new ComputeAction());
+ }
+
+ /// <summary>
+ /// Verifies the task events.
+ /// </summary>
+ private static void VerifyTaskEvents(IEnumerable<IEvent> events)
+ {
+ var e = events.Cast<TaskEvent>().ToArray();
+
+ // started, reduced, finished
+ Assert.AreEqual(
+ new[] {EventType.EvtTaskStarted, EventType.EvtTaskReduced, EventType.EvtTaskFinished},
+ e.Select(x => x.Type).ToArray());
+ }
+
+ /// <summary>
+ /// Generates the cache query event.
+ /// </summary>
+ private static void GenerateCacheQueryEvent(IIgnite g)
+ {
+ var cache = g.Cache<int, int>(null);
+
+ cache.Clear();
+
+ cache.Put(1, 1);
+
+ cache.Query(new ScanQuery<int, int>()).GetAll();
+ }
+
+ /// <summary>
+ /// Verifies the cache events.
+ /// </summary>
+ private static void VerifyCacheEvents(IEnumerable<IEvent> events, IIgnite grid)
+ {
+ var e = events.Cast<CacheEvent>().ToArray();
+
+ foreach (var cacheEvent in e)
+ {
+ Assert.AreEqual(null, cacheEvent.CacheName);
+ Assert.AreEqual(null, cacheEvent.ClosureClassName);
+ Assert.AreEqual(null, cacheEvent.TaskName);
+ Assert.AreEqual(grid.Cluster.LocalNode, cacheEvent.EventNode);
+ Assert.AreEqual(grid.Cluster.LocalNode, cacheEvent.Node);
+
+ Assert.AreEqual(false, cacheEvent.HasOldValue);
+ Assert.AreEqual(null, cacheEvent.OldValue);
+
+ if (cacheEvent.Type == EventType.EvtCacheObjectPut)
+ {
+ Assert.AreEqual(true, cacheEvent.HasNewValue);
+ Assert.AreEqual(1, cacheEvent.NewValue);
+ }
+ else if (cacheEvent.Type == EventType.EvtCacheEntryCreated)
+ {
+ Assert.AreEqual(false, cacheEvent.HasNewValue);
+ Assert.AreEqual(null, cacheEvent.NewValue);
+ }
+ else
+ {
+ Assert.Fail("Unexpected event type");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Starts the grids.
+ /// </summary>
+ private void StartGrids()
+ {
+ if (_grid1 != null)
+ return;
+
+ _grid1 = Ignition.Start(Configuration("config\\compute\\compute-grid1.xml"));
+ _grid2 = Ignition.Start(Configuration("config\\compute\\compute-grid2.xml"));
+ _grid3 = Ignition.Start(Configuration("config\\compute\\compute-grid3.xml"));
+
+ _grids = new[] {_grid1, _grid2, _grid3};
+ }
+
+ /// <summary>
+ /// Stops the grids.
+ /// </summary>
+ private void StopGrids()
+ {
+ _grid1 = _grid2 = _grid3 = null;
+ _grids = null;
+
+ Ignition.StopAll(true);
+ }
+ }
+
+ /// <summary>
+ /// Event test helper class.
+ /// </summary>
+ [Serializable]
+ public static class EventsTestHelper
+ {
+ /** */
+ public static readonly ConcurrentStack<IEvent> ReceivedEvents = new ConcurrentStack<IEvent>();
+
+ /** */
+ public static readonly ConcurrentStack<string> Failures = new ConcurrentStack<string>();
+
+ /** */
+ public static readonly CountdownEvent ReceivedEvent = new CountdownEvent(0);
+
+ /** */
+ public static readonly ConcurrentStack<Guid> LastNodeIds = new ConcurrentStack<Guid>();
+
+ /** */
+ public static volatile bool ListenResult = true;
+
+ /** */
+ public static readonly TimeSpan Timeout = TimeSpan.FromMilliseconds(800);
+
+ /// <summary>
+ /// Clears received event information.
+ /// </summary>
+ /// <param name="expectedCount">The expected count of events to be received.</param>
+ public static void ClearReceived(int expectedCount)
+ {
+ ReceivedEvents.Clear();
+ ReceivedEvent.Reset(expectedCount);
+ LastNodeIds.Clear();
+ }
+
+ /// <summary>
+ /// Verifies received events against events events.
+ /// </summary>
+ public static void VerifyReceive(int count, Type eventObjectType, params int[] eventTypes)
+ {
+ // check if expected event count has been received; Wait returns false if there were none.
+ Assert.IsTrue(ReceivedEvent.Wait(Timeout),
+ "Failed to receive expected number of events. Remaining count: " + ReceivedEvent.CurrentCount);
+
+ Assert.AreEqual(count, ReceivedEvents.Count);
+
+ Assert.IsTrue(ReceivedEvents.All(x => x.GetType() == eventObjectType));
+
+ Assert.IsTrue(ReceivedEvents.All(x => eventTypes.Contains(x.Type)));
+
+ AssertFailures();
+ }
+
+ /// <summary>
+ /// Gets the event listener.
+ /// </summary>
+ /// <returns>New instance of event listener.</returns>
+ public static IEventFilter<IEvent> GetListener()
+ {
+ return new EventFilter<IEvent>(Listen);
+ }
+
+ /// <summary>
+ /// Combines accumulated failures and throws an assertion, if there are any.
+ /// Clears accumulated failures.
+ /// </summary>
+ public static void AssertFailures()
+ {
+ try
+ {
+ if (Failures.Any())
+ Assert.Fail(Failures.Reverse().Aggregate((x, y) => string.Format("{0}\n{1}", x, y)));
+ }
+ finally
+ {
+ Failures.Clear();
+ }
+ }
+
+ /// <summary>
+ /// Listen method.
+ /// </summary>
+ /// <param name="id">Originating node ID.</param>
+ /// <param name="evt">Event.</param>
+ private static bool Listen(Guid id, IEvent evt)
+ {
+ try
+ {
+ LastNodeIds.Push(id);
+ ReceivedEvents.Push(evt);
+
+ ReceivedEvent.Signal();
+
+ return ListenResult;
+ }
+ catch (Exception ex)
+ {
+ // When executed on remote nodes, these exceptions will not go to sender,
+ // so we have to accumulate them.
+ Failures.Push(string.Format("Exception in Listen (msg: {0}, id: {1}): {2}", evt, id, ex));
+ throw;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Test event filter.
+ /// </summary>
+ [Serializable]
+ public class EventFilter<T> : IEventFilter<T> where T : IEvent
+ {
+ /** */
+ private readonly Func<Guid, T, bool> _invoke;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="RemoteListenEventFilter"/> class.
+ /// </summary>
+ /// <param name="invoke">The invoke delegate.</param>
+ public EventFilter(Func<Guid, T, bool> invoke)
+ {
+ _invoke = invoke;
+ }
+
+ /** <inheritdoc /> */
+ bool IEventFilter<T>.Invoke(Guid nodeId, T evt)
+ {
+ return _invoke(nodeId, evt);
+ }
+
+ /** <inheritdoc /> */
+ public bool Invoke(Guid nodeId, T evt)
+ {
+ throw new Exception("Invalid method");
+ }
+ }
+
+ /// <summary>
+ /// Remote event filter.
+ /// </summary>
+ [Serializable]
+ public class RemoteEventFilter : IEventFilter<IEvent>
+ {
+ /** */
+ private readonly int _type;
+
+ public RemoteEventFilter(int type)
+ {
+ _type = type;
+ }
+
+ /** <inheritdoc /> */
+ public bool Invoke(Guid nodeId, IEvent evt)
+ {
+ return evt.Type == _type;
+ }
+ }
+
+ /// <summary>
+ /// Portable remote event filter.
+ /// </summary>
+ public class RemoteEventPortableFilter : IEventFilter<IEvent>, IPortableMarshalAware
+ {
+ /** */
+ private int _type;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="RemoteEventPortableFilter"/> class.
+ /// </summary>
+ /// <param name="type">The event type.</param>
+ public RemoteEventPortableFilter(int type)
+ {
+ _type = type;
+ }
+
+ /** <inheritdoc /> */
+ public bool Invoke(Guid nodeId, IEvent evt)
+ {
+ return evt.Type == _type;
+ }
+
+ /** <inheritdoc /> */
+ public void WritePortable(IPortableWriter writer)
+ {
+ writer.RawWriter().WriteInt(_type);
+ }
+
+ /** <inheritdoc /> */
+ public void ReadPortable(IPortableReader reader)
+ {
+ _type = reader.RawReader().ReadInt();
+ }
+ }
+
+ /// <summary>
+ /// Event test case.
+ /// </summary>
+ public class EventTestCase
+ {
+ /// <summary>
+ /// Gets or sets the type of the event.
+ /// </summary>
+ public int[] EventType { get; set; }
+
+ /// <summary>
+ /// Gets or sets the type of the event object.
+ /// </summary>
+ public Type EventObjectType { get; set; }
+
+ /// <summary>
+ /// Gets or sets the generate event action.
+ /// </summary>
+ public Action<IIgnite> GenerateEvent { get; set; }
+
+ /// <summary>
+ /// Gets or sets the verify events action.
+ /// </summary>
+ public Action<IEnumerable<IEvent>, IIgnite> VerifyEvents { get; set; }
+
+ /// <summary>
+ /// Gets or sets the event count.
+ /// </summary>
+ public int EventCount { get; set; }
+
+ /** <inheritdoc /> */
+ public override string ToString()
+ {
+ return EventObjectType.ToString();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/ExceptionsTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/ExceptionsTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/ExceptionsTest.cs
new file mode 100644
index 0000000..d90067f
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/ExceptionsTest.cs
@@ -0,0 +1,352 @@
+/*
+ * 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
+{
+ using System;
+ using System.IO;
+ using System.Linq;
+ using System.Runtime.Serialization.Formatters.Binary;
+ using System.Threading.Tasks;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Cluster;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Impl;
+ using Apache.Ignite.Core.Portable;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Tests grid exceptions propagation.
+ /// </summary>
+ public class ExceptionsTest
+ {
+ /// <summary>
+ /// Before test.
+ /// </summary>
+ [SetUp]
+ public void SetUp()
+ {
+ TestUtils.KillProcesses();
+ }
+
+ /// <summary>
+ /// After test.
+ /// </summary>
+ [TearDown]
+ public void TearDown()
+ {
+ Ignition.StopAll(true);
+ }
+
+ /// <summary>
+ /// Tests exceptions.
+ /// </summary>
+ [Test]
+ public void TestExceptions()
+ {
+ var grid = StartGrid();
+
+ try
+ {
+ grid.Cache<object, object>("invalidCacheName");
+
+ Assert.Fail();
+ }
+ catch (Exception e)
+ {
+ Assert.IsTrue(e is ArgumentException);
+ }
+
+ try
+ {
+ grid.Cluster.ForRemotes().Metrics();
+
+ Assert.Fail();
+ }
+ catch (Exception e)
+ {
+ Assert.IsTrue(e is ClusterGroupEmptyException);
+ }
+
+ grid.Dispose();
+
+ try
+ {
+ grid.Cache<object, object>("cache1");
+
+ Assert.Fail();
+ }
+ catch (Exception e)
+ {
+ Assert.IsTrue(e is InvalidOperationException);
+ }
+ }
+
+ /// <summary>
+ /// Tests CachePartialUpdateException keys propagation.
+ /// </summary>
+ [Test]
+ [Category(TestUtils.CategoryIntensive)]
+ public void TestPartialUpdateException()
+ {
+ // Primitive type
+ TestPartialUpdateException(false, (x, g) => x);
+
+ // User type
+ TestPartialUpdateException(false, (x, g) => new PortableEntry(x));
+ }
+
+ /// <summary>
+ /// Tests CachePartialUpdateException keys propagation in portable mode.
+ /// </summary>
+ [Test]
+ [Category(TestUtils.CategoryIntensive)]
+ public void TestPartialUpdateExceptionPortable()
+ {
+ // User type
+ TestPartialUpdateException(false, (x, g) => g.Portables().ToPortable<IPortableObject>(new PortableEntry(x)));
+ }
+
+ /// <summary>
+ /// Tests CachePartialUpdateException serialization.
+ /// </summary>
+ [Test]
+ public void TestPartialUpdateExceptionSerialization()
+ {
+ // Inner exception
+ TestPartialUpdateExceptionSerialization(new CachePartialUpdateException("Msg",
+ new IgniteException("Inner msg")));
+
+ // Primitive keys
+ TestPartialUpdateExceptionSerialization(new CachePartialUpdateException("Msg", new object[] {1, 2, 3}));
+
+ // User type keys
+ TestPartialUpdateExceptionSerialization(new CachePartialUpdateException("Msg",
+ new object[]
+ {
+ new SerializableEntry(1),
+ new SerializableEntry(2),
+ new SerializableEntry(3)
+ }));
+ }
+
+ /// <summary>
+ /// Tests CachePartialUpdateException serialization.
+ /// </summary>
+ private static void TestPartialUpdateExceptionSerialization(Exception ex)
+ {
+ var formatter = new BinaryFormatter();
+
+ var stream = new MemoryStream();
+
+ formatter.Serialize(stream, ex);
+
+ stream.Seek(0, SeekOrigin.Begin);
+
+ var ex0 = (Exception) formatter.Deserialize(stream);
+
+ var updateEx = ((CachePartialUpdateException) ex);
+
+ try
+ {
+ Assert.AreEqual(updateEx.GetFailedKeys<object>(),
+ ((CachePartialUpdateException)ex0).GetFailedKeys<object>());
+ }
+ catch (Exception e)
+ {
+ if (typeof (IgniteException) != e.GetType())
+ throw;
+ }
+
+ while (ex != null && ex0 != null)
+ {
+ Assert.AreEqual(ex0.GetType(), ex.GetType());
+ Assert.AreEqual(ex.Message, ex0.Message);
+
+ ex = ex.InnerException;
+ ex0 = ex0.InnerException;
+ }
+
+ Assert.AreEqual(ex, ex0);
+ }
+
+ /// <summary>
+ /// Tests CachePartialUpdateException keys propagation.
+ /// </summary>
+ [Test]
+ [Category(TestUtils.CategoryIntensive)]
+ public void TestPartialUpdateExceptionAsync()
+ {
+ // Primitive type
+ TestPartialUpdateException(true, (x, g) => x);
+
+ // User type
+ TestPartialUpdateException(true, (x, g) => new PortableEntry(x));
+ }
+
+ /// <summary>
+ /// Tests CachePartialUpdateException keys propagation in portable mode.
+ /// </summary>
+ [Test]
+ [Category(TestUtils.CategoryIntensive)]
+ public void TestPartialUpdateExceptionAsyncPortable()
+ {
+ TestPartialUpdateException(true, (x, g) => g.Portables().ToPortable<IPortableObject>(new PortableEntry(x)));
+ }
+
+ /// <summary>
+ /// Tests CachePartialUpdateException keys propagation.
+ /// </summary>
+ private static void TestPartialUpdateException<TK>(bool async, Func<int, IIgnite, TK> keyFunc)
+ {
+ using (var grid = StartGrid())
+ {
+ var cache = grid.Cache<TK, int>("partitioned_atomic").WithNoRetries();
+
+ if (async)
+ cache = cache.WithAsync();
+
+ if (typeof (TK) == typeof (IPortableObject))
+ cache = cache.WithKeepPortable<TK, int>();
+
+ // Do cache puts in parallel
+ var putTask = Task.Factory.StartNew(() =>
+ {
+ try
+ {
+ // Do a lot of puts so that one fails during Ignite stop
+ for (var i = 0; i < 1000000; i++)
+ {
+ cache.PutAll(Enumerable.Range(1, 100).ToDictionary(k => keyFunc(k, grid), k => i));
+
+ if (async)
+ cache.GetFuture().Get();
+ }
+ }
+ catch (CachePartialUpdateException ex)
+ {
+ var failedKeys = ex.GetFailedKeys<TK>();
+
+ Assert.IsTrue(failedKeys.Any());
+
+ var failedKeysObj = ex.GetFailedKeys<object>();
+
+ Assert.IsTrue(failedKeysObj.Any());
+
+ return;
+ }
+
+ Assert.Fail("CachePartialUpdateException has not been thrown.");
+ });
+
+ while (true)
+ {
+ Ignition.Stop("grid_2", true);
+ StartGrid("grid_2");
+
+ if (putTask.Exception != null)
+ throw putTask.Exception;
+
+ if (putTask.IsCompleted)
+ return;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Starts the grid.
+ /// </summary>
+ private static IIgnite StartGrid(string gridName = null)
+ {
+ return Ignition.Start(new IgniteConfigurationEx
+ {
+ SpringConfigUrl = "config\\native-client-test-cache.xml",
+ JvmOptions = TestUtils.TestJavaOptions(),
+ JvmClasspath = TestUtils.CreateTestClasspath(),
+ GridName = gridName,
+ PortableConfiguration = new PortableConfiguration
+ {
+ TypeConfigurations = new[]
+ {
+ new PortableTypeConfiguration(typeof (PortableEntry))
+ }
+ }
+ });
+ }
+
+ /// <summary>
+ /// Portable entry.
+ /// </summary>
+ private class PortableEntry
+ {
+ /** Value. */
+ private readonly int _val;
+
+ /** <inheritDot /> */
+ public override int GetHashCode()
+ {
+ return _val;
+ }
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="val">Value.</param>
+ public PortableEntry(int val)
+ {
+ _val = val;
+ }
+
+ /** <inheritDoc /> */
+ public override bool Equals(object obj)
+ {
+ return obj is PortableEntry && ((PortableEntry)obj)._val == _val;
+ }
+ }
+
+ /// <summary>
+ /// Portable entry.
+ /// </summary>
+ [Serializable]
+ private class SerializableEntry
+ {
+ /** Value. */
+ private readonly int _val;
+
+ /** <inheritDot /> */
+ public override int GetHashCode()
+ {
+ return _val;
+ }
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="val">Value.</param>
+ public SerializableEntry(int val)
+ {
+ _val = val;
+ }
+
+ /** <inheritDoc /> */
+ public override bool Equals(object obj)
+ {
+ return obj is SerializableEntry && ((SerializableEntry)obj)._val == _val;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/ExecutableTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/ExecutableTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/ExecutableTest.cs
new file mode 100644
index 0000000..9c47cbc
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/ExecutableTest.cs
@@ -0,0 +1,444 @@
+/*
+ * 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 UnusedVariable
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+namespace Apache.Ignite.Core.Tests
+{
+ using System;
+ using System.CodeDom.Compiler;
+ using System.Collections.Generic;
+ using Apache.Ignite.Core.Compute;
+ using Apache.Ignite.Core.Impl;
+ using Apache.Ignite.Core.Portable;
+ using Apache.Ignite.Core.Resource;
+ using Apache.Ignite.Core.Tests.Process;
+ using Microsoft.CSharp;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Tests for executable.
+ /// </summary>
+ [Ignore("IGNITE-1367")]
+ public class ExecutableTest
+ {
+ /** Spring configuration path. */
+ private static readonly string SpringCfgPath = "config\\compute\\compute-standalone.xml";
+
+ /** Min memory Java task. */
+ private const string MinMemTask = "org.apache.ignite.platform.PlatformMinMemoryTask";
+
+ /** Max memory Java task. */
+ private const string MaxMemTask = "org.apache.ignite.platform.PlatformMaxMemoryTask";
+
+ /** Grid. */
+ private IIgnite _grid;
+
+ /// <summary>
+ /// Test fixture set-up routine.
+ /// </summary>
+ [TestFixtureSetUp]
+ public void TestFixtureSetUp()
+ {
+ TestUtils.KillProcesses();
+
+ _grid = Ignition.Start(Configuration(SpringCfgPath));
+ }
+
+ /// <summary>
+ /// Test fixture tear-down routine.
+ /// </summary>
+ [TestFixtureTearDown]
+ public void TestFixtureTearDown()
+ {
+ Ignition.StopAll(true);
+
+ TestUtils.KillProcesses();
+ }
+
+ /// <summary>
+ /// Set-up routine.
+ /// </summary>
+ [SetUp]
+ public void SetUp()
+ {
+ TestUtils.KillProcesses();
+
+ Assert.IsTrue(_grid.WaitTopology(1, 30000));
+
+ IgniteProcess.SaveConfigurationBackup();
+ }
+
+ /// <summary>
+ /// Tear-down routine.
+ /// </summary>
+ [TearDown]
+ public void TearDown()
+ {
+ IgniteProcess.RestoreConfigurationBackup();
+ }
+
+ /// <summary>
+ /// Test data pass through configuration file.
+ /// </summary>
+ [Test]
+ public void TestConfig()
+ {
+ IgniteProcess.ReplaceConfiguration("config\\Ignite.exe.config.test");
+
+ GenerateDll("test-1.dll");
+ GenerateDll("test-2.dll");
+
+ IgniteProcess proc = new IgniteProcess(
+ "-jvmClasspath=" + TestUtils.CreateTestClasspath()
+ );
+
+ Assert.IsTrue(_grid.WaitTopology(2, 30000));
+
+ RemoteConfiguration cfg = RemoteConfig();
+
+ Assert.AreEqual(SpringCfgPath, cfg.SpringConfigUrl);
+ Assert.IsTrue(cfg.JvmOptions.Contains("-DOPT1") && cfg.JvmOptions.Contains("-DOPT2"));
+ Assert.IsTrue(cfg.Assemblies.Contains("test-1.dll") && cfg.Assemblies.Contains("test-2.dll"));
+ Assert.AreEqual(601, cfg.JvmInitialMemoryMb);
+ Assert.AreEqual(702, cfg.JvmMaxMemoryMb);
+ }
+
+ /// <summary>
+ /// Test assemblies passing through command-line.
+ /// </summary>
+ [Test]
+ public void TestAssemblyCmd()
+ {
+ GenerateDll("test-1.dll");
+ GenerateDll("test-2.dll");
+
+ IgniteProcess proc = new IgniteProcess(
+ "-jvmClasspath=" + TestUtils.CreateTestClasspath(),
+ "-springConfigUrl=" + SpringCfgPath,
+ "-assembly=test-1.dll",
+ "-assembly=test-2.dll"
+ );
+
+ Assert.IsTrue(_grid.WaitTopology(2, 30000));
+
+ RemoteConfiguration cfg = RemoteConfig();
+
+ Assert.IsTrue(cfg.Assemblies.Contains("test-1.dll") && cfg.Assemblies.Contains("test-2.dll"));
+ }
+
+ /// <summary>
+ /// Test JVM options passing through command-line.
+ /// </summary>
+ [Test]
+ public void TestJvmOptsCmd()
+ {
+ IgniteProcess proc = new IgniteProcess(
+ "-jvmClasspath=" + TestUtils.CreateTestClasspath(),
+ "-springConfigUrl=" + SpringCfgPath,
+ "-J-DOPT1",
+ "-J-DOPT2"
+ );
+
+ Assert.IsTrue(_grid.WaitTopology(2, 30000));
+
+ RemoteConfiguration cfg = RemoteConfig();
+
+ Assert.IsTrue(cfg.JvmOptions.Contains("-DOPT1") && cfg.JvmOptions.Contains("-DOPT2"));
+ }
+
+ /// <summary>
+ /// Test JVM memory options passing through command-line: raw java options.
+ /// </summary>
+ [Test]
+ public void TestJvmMemoryOptsCmdRaw()
+ {
+ var proc = new IgniteProcess(
+ "-jvmClasspath=" + TestUtils.CreateTestClasspath(),
+ "-springConfigUrl=" + SpringCfgPath,
+ "-J-Xms506m",
+ "-J-Xmx607m"
+ );
+
+ Assert.IsTrue(_grid.WaitTopology(2, 30000));
+
+ var minMem = _grid.Cluster.ForRemotes().Compute().ExecuteJavaTask<long>(MinMemTask, null);
+ Assert.AreEqual((long) 506*1024*1024, minMem);
+
+ var maxMem = _grid.Cluster.ForRemotes().Compute().ExecuteJavaTask<long>(MaxMemTask, null);
+ AssertJvmMaxMemory((long) 607*1024*1024, maxMem);
+ }
+
+ /// <summary>
+ /// Test JVM memory options passing through command-line: custom options.
+ /// </summary>
+ [Test]
+ public void TestJvmMemoryOptsCmdCustom()
+ {
+ var proc = new IgniteProcess(
+ "-jvmClasspath=" + TestUtils.CreateTestClasspath(),
+ "-springConfigUrl=" + SpringCfgPath,
+ "-JvmInitialMemoryMB=615",
+ "-JvmMaxMemoryMB=863"
+ );
+
+ Assert.IsTrue(_grid.WaitTopology(2, 30000));
+
+ var minMem = _grid.Cluster.ForRemotes().Compute().ExecuteJavaTask<long>(MinMemTask, null);
+ Assert.AreEqual((long) 615*1024*1024, minMem);
+
+ var maxMem = _grid.Cluster.ForRemotes().Compute().ExecuteJavaTask<long>(MaxMemTask, null);
+ AssertJvmMaxMemory((long) 863*1024*1024, maxMem);
+ }
+
+ /// <summary>
+ /// Test JVM memory options passing from application configuration.
+ /// </summary>
+ [Test]
+ public void TestJvmMemoryOptsAppConfig()
+ {
+ IgniteProcess.ReplaceConfiguration("config\\Ignite.exe.config.test");
+
+ GenerateDll("test-1.dll");
+ GenerateDll("test-2.dll");
+
+ var proc = new IgniteProcess("-jvmClasspath=" + TestUtils.CreateTestClasspath());
+
+ Assert.IsTrue(_grid.WaitTopology(2, 30000));
+
+ var minMem = _grid.Cluster.ForRemotes().Compute().ExecuteJavaTask<long>(MinMemTask, null);
+ Assert.AreEqual((long) 601*1024*1024, minMem);
+
+ var maxMem = _grid.Cluster.ForRemotes().Compute().ExecuteJavaTask<long>(MaxMemTask, null);
+ AssertJvmMaxMemory((long) 702*1024*1024, maxMem);
+
+ proc.Kill();
+
+ Assert.IsTrue(_grid.WaitTopology(1, 30000));
+
+ // Command line options overwrite config file options
+ // ReSharper disable once RedundantAssignment
+ proc = new IgniteProcess("-jvmClasspath=" + TestUtils.CreateTestClasspath(),
+ "-J-Xms605m", "-J-Xmx706m");
+
+ Assert.IsTrue(_grid.WaitTopology(2, 30000));
+
+ minMem = _grid.Cluster.ForRemotes().Compute().ExecuteJavaTask<long>(MinMemTask, null);
+ Assert.AreEqual((long) 605*1024*1024, minMem);
+
+ maxMem = _grid.Cluster.ForRemotes().Compute().ExecuteJavaTask<long>(MaxMemTask, null);
+ AssertJvmMaxMemory((long) 706*1024*1024, maxMem);
+ }
+
+ /// <summary>
+ /// Test JVM memory options passing through command-line: custom options + raw options.
+ /// </summary>
+ [Test]
+ public void TestJvmMemoryOptsCmdCombined()
+ {
+ var proc = new IgniteProcess(
+ "-jvmClasspath=" + TestUtils.CreateTestClasspath(),
+ "-springConfigUrl=" + SpringCfgPath,
+ "-J-Xms555m",
+ "-J-Xmx666m",
+ "-JvmInitialMemoryMB=128",
+ "-JvmMaxMemoryMB=256"
+ );
+
+ Assert.IsTrue(_grid.WaitTopology(2, 30000));
+
+ // Raw JVM options (Xms/Xmx) should override custom options
+ var minMem = _grid.Cluster.ForRemotes().Compute().ExecuteJavaTask<long>(MinMemTask, null);
+ Assert.AreEqual((long) 555*1024*1024, minMem);
+
+ var maxMem = _grid.Cluster.ForRemotes().Compute().ExecuteJavaTask<long>(MaxMemTask, null);
+ AssertJvmMaxMemory((long) 666*1024*1024, maxMem);
+ }
+
+ /// <summary>
+ /// Get remote node configuration.
+ /// </summary>
+ /// <returns>Configuration.</returns>
+ private RemoteConfiguration RemoteConfig()
+ {
+ return _grid.Cluster.ForRemotes().Compute().Call(new RemoteConfigurationClosure());
+ }
+
+ /// <summary>
+ /// Configuration for node.
+ /// </summary>
+ /// <param name="path">Path to Java XML configuration.</param>
+ /// <returns>Node configuration.</returns>
+ private static IgniteConfiguration Configuration(string path)
+ {
+ IgniteConfiguration cfg = new IgniteConfiguration();
+
+
+ PortableConfiguration portCfg = new PortableConfiguration();
+
+ ICollection<PortableTypeConfiguration> portTypeCfgs = new List<PortableTypeConfiguration>();
+
+ portTypeCfgs.Add(new PortableTypeConfiguration(typeof (RemoteConfiguration)));
+ portTypeCfgs.Add(new PortableTypeConfiguration(typeof (RemoteConfigurationClosure)));
+
+ portCfg.TypeConfigurations = portTypeCfgs;
+
+ cfg.PortableConfiguration = portCfg;
+
+ cfg.JvmClasspath = TestUtils.CreateTestClasspath();
+
+ cfg.JvmOptions = new List<string>
+ {
+ "-ea",
+ "-Xcheck:jni",
+ "-Xms4g",
+ "-Xmx4g",
+ "-DGRIDGAIN_QUIET=false",
+ "-Xnoagent",
+ "-Djava.compiler=NONE",
+ "-Xdebug",
+ "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005",
+ "-XX:+HeapDumpOnOutOfMemoryError"
+ };
+
+ cfg.SpringConfigUrl = path;
+
+ return cfg;
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="outputPath"></param>
+ private static void GenerateDll(string outputPath)
+ {
+ CSharpCodeProvider codeProvider = new CSharpCodeProvider();
+
+#pragma warning disable 0618
+
+ ICodeCompiler icc = codeProvider.CreateCompiler();
+
+#pragma warning restore 0618
+
+ CompilerParameters parameters = new CompilerParameters();
+ parameters.GenerateExecutable = false;
+ parameters.OutputAssembly = outputPath;
+
+ string src = "namespace GridGain.Client.Test { public class Foo {}}";
+
+ CompilerResults results = icc.CompileAssemblyFromSource(parameters, src);
+
+ Assert.False(results.Errors.HasErrors);
+ }
+
+ /// <summary>
+ /// Asserts that JVM maximum memory corresponds to Xmx parameter value.
+ /// </summary>
+ private static void AssertJvmMaxMemory(long expected, long actual)
+ {
+ // allow 20% tolerance because max memory in Java is not exactly equal to Xmx parameter value
+ Assert.LessOrEqual(actual, expected);
+ Assert.Greater(actual, expected/5*4);
+ }
+
+ /// <summary>
+ /// Closure which extracts configuration and passes it back.
+ /// </summary>
+ public class RemoteConfigurationClosure : IComputeFunc<RemoteConfiguration>
+ {
+
+#pragma warning disable 0649
+
+ /** Grid. */
+ [InstanceResource] private IIgnite _grid;
+
+#pragma warning restore 0649
+
+ /** <inheritDoc /> */
+
+ public RemoteConfiguration Invoke()
+ {
+ Ignite grid0 = (Ignite) ((IgniteProxy) _grid).Target;
+
+ IgniteConfiguration cfg = grid0.Configuration;
+
+ RemoteConfiguration res = new RemoteConfiguration
+ {
+ IgniteHome = cfg.IgniteHome,
+ SpringConfigUrl = cfg.SpringConfigUrl,
+ JvmDll = cfg.JvmDllPath,
+ JvmClasspath = cfg.JvmClasspath,
+ JvmOptions = cfg.JvmOptions,
+ Assemblies = cfg.Assemblies,
+ JvmInitialMemoryMb = cfg.JvmInitialMemoryMb,
+ JvmMaxMemoryMb = cfg.JvmMaxMemoryMb
+ };
+
+ Console.WriteLine("RETURNING CFG: " + cfg);
+
+ return res;
+ }
+ }
+
+ /// <summary>
+ /// Configuration.
+ /// </summary>
+ public class RemoteConfiguration
+ {
+ /// <summary>
+ /// GG home.
+ /// </summary>
+ public string IgniteHome { get; set; }
+
+ /// <summary>
+ /// Spring config URL.
+ /// </summary>
+ public string SpringConfigUrl { get; set; }
+
+ /// <summary>
+ /// JVM DLL.
+ /// </summary>
+ public string JvmDll { get; set; }
+
+ /// <summary>
+ /// JVM classpath.
+ /// </summary>
+ public string JvmClasspath { get; set; }
+
+ /// <summary>
+ /// JVM options.
+ /// </summary>
+ public ICollection<string> JvmOptions { get; set; }
+
+ /// <summary>
+ /// Assemblies.
+ /// </summary>
+ public ICollection<string> Assemblies { get; set; }
+
+ /// <summary>
+ /// Minimum JVM memory (Xms).
+ /// </summary>
+ public int JvmInitialMemoryMb { get; set; }
+
+ /// <summary>
+ /// Maximum JVM memory (Xms).
+ /// </summary>
+ public int JvmMaxMemoryMb { get; set; }
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/FutureTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/FutureTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/FutureTest.cs
new file mode 100644
index 0000000..c2815db
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/FutureTest.cs
@@ -0,0 +1,278 @@
+/*
+ * 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
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Threading;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Compute;
+ using Apache.Ignite.Core.Portable;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Future tests.
+ /// </summary>
+ public class FutureTest
+ {
+ /** */
+ private ICache<object, object> _cache;
+
+ /** */
+ private ICompute _compute;
+
+ /// <summary>
+ /// Test fixture set-up routine.
+ /// </summary>
+ [TestFixtureSetUp]
+ public void TestFixtureSetUp()
+ {
+ TestUtils.KillProcesses();
+
+ var grid = Ignition.Start(new IgniteConfiguration
+ {
+ SpringConfigUrl = "config\\compute\\compute-standalone.xml",
+ JvmClasspath = TestUtils.CreateTestClasspath(),
+ JvmOptions = TestUtils.TestJavaOptions(),
+ PortableConfiguration = new PortableConfiguration
+ {
+ TypeConfigurations =
+ new List<PortableTypeConfiguration> { new PortableTypeConfiguration(typeof(Portable)) }
+ }
+ });
+
+ _cache = grid.Cache<object, object>(null).WithAsync();
+
+ _compute = grid.Compute().WithAsync();
+ }
+
+ /// <summary>
+ /// Test fixture tear-down routine.
+ /// </summary>
+ [TestFixtureTearDown]
+ public void TestFixtureTearDown()
+ {
+ TestUtils.KillProcesses();
+ }
+
+ [Test]
+ public void TestListen()
+ {
+ // Listen(Action callback)
+ TestListen((fut, act) => fut.Listen(act));
+
+ // Listen(Action<IFuture> callback)
+ TestListen((fut, act) => ((IFuture)fut).Listen(f =>
+ {
+ Assert.AreEqual(f, fut);
+ act();
+ }));
+
+ // Listen(Action<IFuture<T>> callback)
+ TestListen((fut, act) => fut.Listen(f =>
+ {
+ Assert.AreEqual(f, fut);
+ act();
+ }));
+ }
+
+ private void TestListen(Action<IFuture<object>, Action> listenAction)
+ {
+ _compute.Broadcast(new SleepAction());
+
+ var fut = _compute.GetFuture<object>();
+
+ var listenCount = 0;
+
+ // Multiple subscribers before completion
+ for (var i = 0; i < 10; i++)
+ listenAction(fut, () => Interlocked.Increment(ref listenCount));
+
+ Assert.IsFalse(fut.IsDone);
+
+ Assert.IsNull(fut.Get());
+
+ Thread.Sleep(100); // wait for future completion thread
+
+ Assert.AreEqual(10, listenCount);
+
+ // Multiple subscribers after completion
+ for (var i = 0; i < 10; i++)
+ listenAction(fut, () => Interlocked.Decrement(ref listenCount));
+
+ Assert.AreEqual(0, listenCount);
+ }
+
+ [Test]
+ public void TestToTask()
+ {
+ _cache.Put(1, 1);
+
+ _cache.GetFuture().ToTask().Wait();
+
+ _cache.Get(1);
+
+ var task1 = _cache.GetFuture<int>().ToTask();
+
+ Assert.AreEqual(1, task1.Result);
+
+ Assert.IsTrue(task1.IsCompleted);
+
+ _compute.Broadcast(new SleepAction());
+
+ var task2 = _compute.GetFuture().ToTask();
+
+ Assert.IsFalse(task2.IsCompleted);
+
+ Assert.IsFalse(task2.Wait(100));
+
+ task2.Wait();
+
+ Assert.IsTrue(task2.IsCompleted);
+
+ Assert.AreEqual(null, task2.Result);
+ }
+
+ [Test]
+ public void TestGetWithTimeout()
+ {
+ _compute.Broadcast(new SleepAction());
+
+ var fut = _compute.GetFuture();
+
+ Assert.Throws<TimeoutException>(() => fut.Get(TimeSpan.FromMilliseconds(100)));
+
+ fut.Get(TimeSpan.FromSeconds(1));
+
+ Assert.IsTrue(fut.IsDone);
+ }
+
+ [Test]
+ public void TestToAsyncResult()
+ {
+ _compute.Broadcast(new SleepAction());
+
+ IFuture fut = _compute.GetFuture();
+
+ var asyncRes = fut.ToAsyncResult();
+
+ Assert.IsFalse(asyncRes.IsCompleted);
+
+ Assert.IsTrue(asyncRes.AsyncWaitHandle.WaitOne(1000));
+
+ Assert.IsTrue(asyncRes.IsCompleted);
+ }
+
+ [Test]
+ public void TestFutureTypes()
+ {
+ TestType(false);
+ TestType((byte)11);
+ TestType('x'); // char
+ TestType(2.7d); // double
+ TestType(3.14f); // float
+ TestType(16); // int
+ TestType(17L); // long
+ TestType((short)18);
+
+ TestType(18m); // decimal
+
+ TestType(new Portable { A = 10, B = "foo" });
+ }
+
+ /// <summary>
+ /// Tests future type.
+ /// </summary>
+ private void TestType<T>(T value)
+ {
+ var key = typeof(T).Name;
+
+ _cache.Put(key, value);
+
+ _cache.GetFuture().Get();
+
+ _cache.Get(key);
+
+ Assert.AreEqual(value, _cache.GetFuture<T>().Get());
+ }
+
+ /// <summary>
+ /// Portable test class.
+ /// </summary>
+ private class Portable : IPortableMarshalAware
+ {
+ public int A;
+ public string B;
+
+ /** <inheritDoc /> */
+ public void WritePortable(IPortableWriter writer)
+ {
+ writer.WriteInt("a", A);
+ writer.RawWriter().WriteString(B);
+ }
+
+ /** <inheritDoc /> */
+ public void ReadPortable(IPortableReader reader)
+ {
+ A = reader.ReadInt("a");
+ B = reader.RawReader().ReadString();
+ }
+
+ /** <inheritDoc /> */
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj))
+ return false;
+
+ if (ReferenceEquals(this, obj))
+ return true;
+
+ if (obj.GetType() != GetType())
+ return false;
+
+ var other = (Portable)obj;
+
+ return A == other.A && string.Equals(B, other.B);
+ }
+
+ /** <inheritDoc /> */
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ // ReSharper disable NonReadonlyMemberInGetHashCode
+ return (A * 397) ^ (B != null ? B.GetHashCode() : 0);
+ // ReSharper restore NonReadonlyMemberInGetHashCode
+ }
+ }
+ }
+
+ /// <summary>
+ /// Compute action with a delay to ensure lengthy future execution.
+ /// </summary>
+ [Serializable]
+ private class SleepAction : IComputeAction
+ {
+ public void Invoke()
+ {
+ Thread.Sleep(500);
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/IgniteManagerTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/IgniteManagerTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/IgniteManagerTest.cs
new file mode 100644
index 0000000..5a90c20
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/IgniteManagerTest.cs
@@ -0,0 +1,51 @@
+/*
+ * 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
+{
+ using System;
+ using System.IO;
+ using Apache.Ignite.Core.Impl;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Tests IgniteManager class.
+ /// </summary>
+ public class IgniteManagerTest
+ {
+ /// <summary>
+ /// Tests home dir resolver.
+ /// </summary>
+ [Test]
+ public void TestIgniteHome()
+ {
+ var env = Environment.GetEnvironmentVariable(IgniteManager.EnvIgniteHome);
+
+ Environment.SetEnvironmentVariable(IgniteManager.EnvIgniteHome, null);
+
+ try
+ {
+ Assert.IsTrue(Directory.Exists(IgniteManager.GetIgniteHome(null)));
+ }
+ finally
+ {
+ // Restore
+ Environment.SetEnvironmentVariable(IgniteManager.EnvIgniteHome, env);
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/IgniteStartStopTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/IgniteStartStopTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/IgniteStartStopTest.cs
new file mode 100644
index 0000000..d2b2efa
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/IgniteStartStopTest.cs
@@ -0,0 +1,380 @@
+/*
+ * 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
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Threading;
+ using Apache.Ignite.Core.Common;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Ignite start/stop tests.
+ /// </summary>
+ [Category(TestUtils.CategoryIntensive)]
+ public class IgniteStartStopTest
+ {
+ /// <summary>
+ ///
+ /// </summary>
+ [SetUp]
+ public void SetUp()
+ {
+ TestUtils.KillProcesses();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ [TearDown]
+ public void TearDown()
+ {
+ Ignition.StopAll(true);
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ [Test]
+ public void TestStartDefault()
+ {
+ var cfg = new IgniteConfiguration {JvmClasspath = TestUtils.CreateTestClasspath()};
+
+ var grid = Ignition.Start(cfg);
+
+ Assert.IsNotNull(grid);
+
+ Assert.AreEqual(1, grid.Cluster.Nodes().Count);
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ [Test]
+ public void TestStartWithConfigPath()
+ {
+ var cfg = new IgniteConfiguration
+ {
+ SpringConfigUrl = "config/default-config.xml",
+ JvmClasspath = TestUtils.CreateTestClasspath()
+ };
+
+ var grid = Ignition.Start(cfg);
+
+ Assert.IsNotNull(grid);
+
+ Assert.AreEqual(1, grid.Cluster.Nodes().Count);
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ [Test]
+ public void TestStartGetStop()
+ {
+ var cfgs = new List<string> { "config\\start-test-grid1.xml", "config\\start-test-grid2.xml", "config\\start-test-grid3.xml" };
+
+ var cfg = new IgniteConfiguration
+ {
+ SpringConfigUrl = cfgs[0],
+ JvmOptions = TestUtils.TestJavaOptions(),
+ JvmClasspath = TestUtils.CreateTestClasspath()
+ };
+
+ var grid1 = Ignition.Start(cfg);
+
+ Assert.AreEqual("grid1", grid1.Name);
+
+ cfg.SpringConfigUrl = cfgs[1];
+
+ var grid2 = Ignition.Start(cfg);
+
+ Assert.AreEqual("grid2", grid2.Name);
+
+ cfg.SpringConfigUrl = cfgs[2];
+
+ var grid3 = Ignition.Start(cfg);
+
+ Assert.IsNull(grid3.Name);
+
+ Assert.AreSame(grid1, Ignition.GetIgnite("grid1"));
+
+ Assert.AreSame(grid2, Ignition.GetIgnite("grid2"));
+
+ Assert.AreSame(grid3, Ignition.GetIgnite(null));
+
+ try
+ {
+ Ignition.GetIgnite("invalid_name");
+ }
+ catch (IgniteException e)
+ {
+ Console.WriteLine("Expected exception: " + e);
+ }
+
+ Assert.IsTrue(Ignition.Stop("grid1", true));
+
+ try
+ {
+ Ignition.GetIgnite("grid1");
+ }
+ catch (IgniteException e)
+ {
+ Console.WriteLine("Expected exception: " + e);
+ }
+
+ grid2.Dispose();
+
+ try
+ {
+ Ignition.GetIgnite("grid2");
+ }
+ catch (IgniteException e)
+ {
+ Console.WriteLine("Expected exception: " + e);
+ }
+
+ grid3.Dispose();
+
+ try
+ {
+ Ignition.GetIgnite(null);
+ }
+ catch (IgniteException e)
+ {
+ Console.WriteLine("Expected exception: " + e);
+ }
+
+ foreach (var cfgName in cfgs)
+ {
+ cfg.SpringConfigUrl = cfgName;
+ cfg.JvmOptions = TestUtils.TestJavaOptions();
+
+ Ignition.Start(cfg);
+ }
+
+ foreach (var gridName in new List<string> { "grid1", "grid2", null })
+ Assert.IsNotNull(Ignition.GetIgnite(gridName));
+
+ Ignition.StopAll(true);
+
+ foreach (var gridName in new List<string> { "grid1", "grid2", null })
+ {
+ try
+ {
+ Ignition.GetIgnite(gridName);
+ }
+ catch (IgniteException e)
+ {
+ Console.WriteLine("Expected exception: " + e);
+ }
+ }
+ }
+
+ /*
+ [Test]
+ public void TestStartInvalidJvmOptions()
+ {
+ GridGain.Impl.IgniteManager.DestroyJvm();
+
+ IgniteConfiguration cfg = new IgniteConfiguration();
+
+ cfg.NativeXmlConfig = "config\\start-test-grid1.xml";
+ cfg.NativeJvmOptions = new List<string> { "invalid_option"};
+
+ try
+ {
+ Ignition.Start(cfg);
+
+ Assert.Fail("Start should fail.");
+ }
+ catch (IgniteException e)
+ {
+ Console.WriteLine("Expected exception: " + e);
+ }
+
+ cfg.NativeJvmOptions = new List<string> { "-Xmx1g", "-Xms1g" };
+
+ Ignition.Start(cfg);
+ }
+ */
+
+ /// <summary>
+ ///
+ /// </summary>
+ [Test]
+ public void TestStartTheSameName()
+ {
+ var cfg = new IgniteConfiguration
+ {
+ SpringConfigUrl = "config\\start-test-grid1.xml",
+ JvmOptions = TestUtils.TestJavaOptions(),
+ JvmClasspath = TestUtils.CreateTestClasspath()
+ };
+
+ var grid1 = Ignition.Start(cfg);
+
+ Assert.AreEqual("grid1", grid1.Name);
+
+ try
+ {
+ Ignition.Start(cfg);
+
+ Assert.Fail("Start should fail.");
+ }
+ catch (IgniteException e)
+ {
+ Console.WriteLine("Expected exception: " + e);
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ [Test]
+ public void TestUsageAfterStop()
+ {
+ var cfg = new IgniteConfiguration
+ {
+ SpringConfigUrl = "config\\start-test-grid1.xml",
+ JvmOptions = TestUtils.TestJavaOptions(),
+ JvmClasspath = TestUtils.CreateTestClasspath()
+ };
+
+ var grid = Ignition.Start(cfg);
+
+ Assert.IsNotNull(grid.Cache<int, int>("cache1"));
+
+ grid.Dispose();
+
+ try
+ {
+ grid.Cache<int, int>("cache1");
+
+ Assert.Fail();
+ }
+ catch (InvalidOperationException e)
+ {
+ Console.WriteLine("Expected exception: " + e);
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ [Test]
+ public void TestStartStopLeak()
+ {
+ var cfg = new IgniteConfiguration
+ {
+ SpringConfigUrl = "config\\start-test-grid1.xml",
+ JvmOptions = new List<string> {"-Xcheck:jni", "-Xms256m", "-Xmx256m", "-XX:+HeapDumpOnOutOfMemoryError"},
+ JvmClasspath = TestUtils.CreateTestClasspath()
+ };
+
+ for (var i = 0; i < 20; i++)
+ {
+ Console.WriteLine("Iteration: " + i);
+
+ var grid = Ignition.Start(cfg);
+
+ UseIgnite(grid);
+
+ if (i % 2 == 0) // Try to stop ignite from another thread.
+ {
+ var t = new Thread(() => {
+ grid.Dispose();
+ });
+
+ t.Start();
+
+ t.Join();
+ }
+ else
+ grid.Dispose();
+
+ GC.Collect(); // At the time of writing java references are cleaned from finalizer, so GC is needed.
+ }
+ }
+
+ /// <summary>
+ /// Tests the client mode flag.
+ /// </summary>
+ [Test]
+ public void TestClientMode()
+ {
+ var servCfg = new IgniteConfiguration
+ {
+ SpringConfigUrl = "config\\start-test-grid1.xml",
+ JvmOptions = TestUtils.TestJavaOptions(),
+ JvmClasspath = TestUtils.CreateTestClasspath()
+ };
+
+ var clientCfg = new IgniteConfiguration
+ {
+ SpringConfigUrl = "config\\start-test-grid2.xml",
+ JvmOptions = TestUtils.TestJavaOptions(),
+ JvmClasspath = TestUtils.CreateTestClasspath()
+ };
+
+ try
+ {
+ using (Ignition.Start(servCfg)) // start server-mode ignite first
+ {
+ Ignition.ClientMode = true;
+
+ using (var grid = Ignition.Start(clientCfg))
+ {
+ UseIgnite(grid);
+ }
+ }
+ }
+ finally
+ {
+ Ignition.ClientMode = false;
+ }
+ }
+
+ /// <summary>
+ /// Uses the ignite.
+ /// </summary>
+ /// <param name="ignite">The ignite.</param>
+ private static void UseIgnite(IIgnite ignite)
+ {
+ // Create objects holding references to java objects.
+ var comp = ignite.Compute();
+
+ // ReSharper disable once RedundantAssignment
+ comp = comp.WithKeepPortable();
+
+ var prj = ignite.Cluster.ForOldest();
+
+ Assert.IsTrue(prj.Nodes().Count > 0);
+
+ Assert.IsNotNull(prj.Compute());
+
+ var cache = ignite.Cache<int, int>("cache1");
+
+ Assert.IsNotNull(cache);
+
+ cache.GetAndPut(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/IgnitionTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/IgnitionTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/IgnitionTest.cs
deleted file mode 100644
index a2698d1..0000000
--- a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/IgnitionTest.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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
-{
- using NUnit.Framework;
-
- public class IgnitionTest
- {
- [Test]
- public void Test()
- {
- Assert.IsNotNull(new Ignition());
- }
- }
-}