| /* |
| * 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. |
| */ |
| |
| using System; |
| using System.Threading; |
| |
| namespace Apache.Geode.Client.UnitTests |
| { |
| using NUnit.Framework; |
| using Apache.Geode.DUnitFramework; |
| |
| [TestFixture] |
| [Category("unicast_only")] |
| public class AckMixTests : UnitTests |
| { |
| private TallyListener m_listener = new TallyListener(); |
| private AckMixRegionWrapper m_regionw; |
| private const string RegionName = "ConfusedScope"; |
| |
| private UnitProcess m_client1, m_client2; |
| |
| protected override ClientBase[] GetClients() |
| { |
| m_client1 = new UnitProcess(); |
| m_client2 = new UnitProcess(); |
| return new ClientBase[] { m_client1, m_client2 }; |
| } |
| |
| #region Private functions |
| |
| private void Init() |
| { |
| Properties dsysConfig = new Properties(); |
| dsysConfig.Insert("ack-wait-threshold", "5"); |
| CacheHelper.InitConfig(dsysConfig); |
| } |
| |
| #endregion |
| |
| #region Functions called by the tests |
| |
| public void CreateRegionNOIL(int clientNum, bool ack) |
| { |
| Init(); |
| string ackStr; |
| if (ack) |
| { |
| ackStr = "with-ack"; |
| } |
| else |
| { |
| ackStr = "no-ack"; |
| } |
| Util.Log("Creating region in client {0}, " + ackStr + |
| ", no-mirror, cache, no-interestlist, with-listener", clientNum); |
| CacheHelper.CreateILRegion(RegionName, ack, true, m_listener); |
| m_regionw = new AckMixRegionWrapper(RegionName); |
| } |
| |
| //Verify no events received by the process |
| public void VerifyNoEvents() |
| { |
| Util.Log("Verifying TallyListener has received nothing."); |
| Assert.AreEqual(0, m_listener.Creates, "Should be no creates"); |
| Assert.AreEqual(0, m_listener.Updates, "Should be no updates"); |
| Assert.IsNull(m_listener.LastKey, "Should be no key"); |
| Assert.IsNull(m_listener.LastValue, "Should be no value"); |
| } |
| |
| public void SendCreate() |
| { |
| Util.Log("put(1,1) from Client 1 noack"); |
| m_regionw.Put(1, 1); |
| m_listener.ShowTallies(); |
| } |
| |
| //Test cache didn't stored update |
| public void TestCreateFromAck() |
| { |
| Util.Log("test(1, -1) in Client 2 ack"); |
| m_regionw.Test(1, -1); |
| |
| // now define something of our own to test create going the other way. |
| Util.Log("put(2,2) from Client 2"); |
| m_regionw.Put(2, 2); |
| Assert.AreEqual(1, m_listener.Creates, "Should be 1 create."); |
| // send update from ACK to NOACK |
| Util.Log("put(1,3) from Client 2"); |
| |
| Thread.Sleep(10000); // see if we can drop the incoming create before we define the key. |
| m_regionw.Test(1, -1); |
| |
| m_regionw.Put(1, 3); |
| Assert.AreEqual(2, m_listener.Creates, "Should be 2 creates."); |
| m_listener.ShowTallies(); |
| } |
| |
| public void TestCreateFromNoAck() |
| { |
| Util.Log("test( 2, -1 ) in Client 1"); |
| m_regionw.Test(2, -1); |
| Util.Log("test( 1, 3 ) in Client 1"); |
| m_regionw.Test(1, 3); |
| |
| // Now Updates from Client 1 to Client 2. |
| Util.Log("put( 1, 5) from Client 1"); |
| m_regionw.Put(1, 5); |
| m_listener.ShowTallies(); |
| } |
| |
| public void TestUpdateFromAck() |
| { |
| Util.Log("test( 1, 5 ) in Client 2"); |
| m_regionw.Test(1, 5, true); |
| } |
| |
| public void TestEventCount(int clientNum) |
| { |
| Util.Log("check Client {0} event count.", clientNum); |
| m_listener.ShowTallies(); |
| Assert.AreEqual(2, m_listener.ExpectCreates(2), "Should have been 2 creates."); |
| Assert.AreEqual(1, m_listener.ExpectUpdates(1), "Should have been 1 update."); |
| } |
| |
| public void TestTimeoutSetup() |
| { |
| Util.Log("creating after timeout key to verify."); |
| m_regionw.Put(40000, 1); |
| m_regionw.SetupTimeout(m_listener); |
| } |
| |
| public void TestPutTimeout(int newVal) |
| { |
| Util.Log("checking that timeout works."); |
| try |
| { |
| m_listener.IgnoreTimeout = true; |
| m_regionw.RequestTimeout(); |
| Assert.Fail("Should have thrown TimeoutException."); |
| } |
| catch (TimeoutException) |
| { |
| // good.. expected this... now sleep a bit and move on. |
| Util.Log("Expected: Received TimeoutException ( good news. )"); |
| m_listener.IgnoreTimeout = false; |
| Thread.Sleep(10000); // other process should be clear by now. |
| m_regionw.Put(40000, newVal); // Make sure we succeed with this next put. |
| Util.Log("Sent update to key 40000."); |
| } |
| catch (Exception ex) |
| { |
| Util.Log(ex.ToString()); |
| Assert.Fail(ex.Message); |
| } |
| } |
| |
| public void TestAfterPutTimeout(int newVal) |
| { |
| Util.Log("verifing values made it through from TestTimeout."); |
| m_regionw.CheckTimeout(); |
| m_regionw.Test(40000, newVal); |
| } |
| |
| #endregion |
| |
| [Test] |
| public void AckMix() |
| { |
| m_client1.Call(CreateRegionNOIL, 1, false); |
| m_client2.Call(CreateRegionNOIL, 2, true); |
| |
| m_client1.Call(VerifyNoEvents); |
| m_client2.Call(VerifyNoEvents); |
| |
| m_client1.Call(SendCreate); |
| m_client2.Call(TestCreateFromAck); |
| |
| m_client1.Call(TestCreateFromNoAck); |
| m_client2.Call(TestUpdateFromAck); |
| |
| m_client1.Call(TestEventCount, 1); |
| m_client2.Call(TestEventCount, 2); |
| |
| m_client1.Call(TestTimeoutSetup); |
| m_client2.Call(TestPutTimeout, 4000); |
| |
| m_client1.Call(TestAfterPutTimeout, 4000); |
| m_client2.Call(TestPutTimeout, 5000); |
| |
| m_client1.Call(TestAfterPutTimeout, 5000); |
| } |
| } |
| |
| class AckMixRegionWrapper : RegionWrapper |
| { |
| private bool m_timeoutUpdate; |
| |
| private static CacheableString timeoutKey = |
| new CacheableString("timeout"); |
| |
| public AckMixRegionWrapper(string name) |
| : base(name) |
| { |
| m_timeoutUpdate = false; |
| } |
| |
| public void RequestTimeout() |
| { |
| string timeoutValue = "timeout"; |
| if (m_timeoutUpdate) |
| { |
| timeoutValue = "timeoutUpdate"; |
| } |
| DateTime start = DateTime.Now; |
| TimeSpan span; |
| try |
| { |
| m_region.Put(timeoutKey, timeoutValue); |
| span = DateTime.Now - start; |
| Util.Log("put took {0} millis value({1})", span.TotalMilliseconds, timeoutValue); |
| } |
| catch |
| { |
| span = DateTime.Now - start; |
| Util.Log("put took {0} millis value({1})", span.TotalMilliseconds, timeoutValue); |
| m_timeoutUpdate = true; |
| throw; |
| } |
| } |
| |
| public void CheckTimeout() |
| { |
| string timeoutValue = "timeout"; |
| if (m_timeoutUpdate) |
| { |
| timeoutValue = "timeoutUpdate"; |
| } |
| CacheableString val = m_region.Get(timeoutKey) as CacheableString; |
| Assert.AreEqual(timeoutValue, val.ToString()); |
| m_timeoutUpdate = true; |
| } |
| |
| public void SetupTimeout(TallyListener listener) |
| { |
| listener.IgnoreTimeout = true; |
| m_region.Put(timeoutKey, timeoutKey); |
| listener.IgnoreTimeout = false; |
| } |
| } |
| } |