/// <summary>
        /// Sends an operation to the server while observing it's durability requirements using async/await
        /// </summary>
        /// <typeparam name="T">The value for T.</typeparam>
        /// <param name="operation">A binary memcached operation - must be a mutation operation.</param>
        /// <param name="deletion">True if mutation is a deletion.</param>
        /// <param name="replicateTo">The durability requirement for replication.</param>
        /// <param name="persistTo">The durability requirement for persistence.</param>
        /// <returns>The <see cref="Task{IOperationResult}"/> to be awaited on with it's <see cref="Durability"/> status.</returns>
        public override async Task <IOperationResult <T> > SendWithDurabilityAsync <T>(IOperation <T> operation, bool deletion, ReplicateTo replicateTo, PersistTo persistTo)
        {
            //Is the cluster configured for Data services?
            if (!ConfigInfo.IsDataCapable)
            {
                throw new ServiceNotSupportedException("The cluster does not support Data services.");
            }

            var result = await SendWithRetryAsync(operation);

            if (result.Success)
            {
                var config = ConfigInfo.ClientConfig.BucketConfigs[BucketName];

                var observer = new KeyObserver(ConfigInfo,
                                               ClusterController.Transcoder,
                                               config.ObserveInterval, config.ObserveTimeout);

                var observed = await observer.ObserveAsync(operation.Key, result.Cas, deletion, replicateTo, persistTo);

                result.Durability = observed
                    ? Durability.Satisfied
                    : Durability.NotSatisfied;
            }
            else
            {
                result.Durability = Durability.NotSatisfied;
            }
            return(result);
        }
        public void When_Observing_Key_During_Remove_Durability_Constraint_Is_Reached()
        {
            var configuration = new ClientConfiguration
            {
                Servers = new List<Uri>
                {
                    new Uri(ConfigurationManager.AppSettings["bootstrapUrl"])
                }
            };
            configuration.Initialize();

            var provider = new CarrierPublicationProvider(
                configuration,
                (pool) => new PooledIOService(pool),
                (config, endpoint) => new ConnectionPool<Connection>(config, endpoint),
                SaslFactory.GetFactory(),
                new DefaultConverter(),
#pragma warning disable 618
                new DefaultTranscoder(new DefaultConverter(), new DefaultSerializer()));
#pragma warning restore 618

            var configInfo = provider.GetConfig("default");

            var clusterController = new Mock<IClusterController>();
            clusterController.Setup(x => x.Transcoder).Returns(new DefaultTranscoder());

            var pending = new ConcurrentDictionary<uint, IOperation>();

            var observer = new KeyObserver(pending, configInfo, clusterController.Object, 10, 500);
            var constraintReached = observer.ObserveRemove("Test_Timeout_Remove", 0, ReplicateTo.Zero, PersistTo.One);
            Assert.IsTrue(constraintReached);
        }
        public void When_Observing_Key_During_Remove_Durability_Constraint_Is_Reached()
        {
            var configuration = new ClientConfiguration
            {
                Servers = new List<Uri>
                {
                    new Uri(ConfigurationManager.AppSettings["bootstrapUrl"])
                }
            };
            configuration.Initialize();

            var provider = new CarrierPublicationProvider(
                configuration,
                (pool) => new DefaultIOStrategy(pool),
                (config, endpoint) => new ConnectionPool<EapConnection>(config, endpoint),
                SaslFactory.GetFactory3(),
                new AutoByteConverter(),
                new TypeSerializer(new AutoByteConverter()));

            var configInfo = provider.GetConfig("default");

            var observer = new KeyObserver(configInfo, 10, 500);
            var constraintReached = observer.ObserveRemove("Test_Timeout_Remove", 0, ReplicateTo.Zero, PersistTo.One);
            Assert.IsTrue(constraintReached);
        }
        public void When_Observing_Key_During_Add_Durability_Constraint_Is_Reached()
        {
            var configuration = new ClientConfiguration
            {
                Servers = new List<Uri>
                {
                    new Uri(ConfigurationManager.AppSettings["bootstrapUrl"])
                }
            };
            configuration.Initialize();

            var provider = new CarrierPublicationProvider(
                configuration,
                (pool) => new DefaultIOStrategy(pool),
                (config, endpoint) => new ConnectionPool<EapConnection>(config, endpoint),
                SaslFactory.GetFactory3(),
                new AutoByteConverter(),
                new TypeSerializer(new AutoByteConverter()));

            var configInfo = provider.GetConfig("default");

            ulong cas = 0;
            using (var cluster = new CouchbaseCluster(configuration))
            {
                using (var bucket = cluster.OpenBucket())
                {
                    bucket.Remove("Test_Timeout_Add");
                    bucket.Insert("Test_Timeout_Add", "");
                    cas = bucket.Upsert("Test_Timeout_Add", "").Cas;
                }
            }
            var observer = new KeyObserver(configInfo, 10, 500);
            var constraintReached = observer.ObserveAdd("Test_Timeout_Add", cas, ReplicateTo.One, PersistTo.One);
            Assert.IsTrue(constraintReached);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Sends an operation to the server while observing it's durability requirements
        /// </summary>
        /// <typeparam name="T">The value for T.</typeparam>
        /// <param name="operation">A binary memcached operation - must be a mutation operation.</param>
        /// <param name="deletion">True if mutation is a deletion.</param>
        /// <param name="replicateTo">The durability requirement for replication.</param>
        /// <param name="persistTo">The durability requirement for persistence.</param>
        /// <returns>The <see cref="IOperationResult{T}"/> with it's <see cref="Durability"/> status.</returns>
        public override IOperationResult <T> SendWithDurability <T>(IOperation <T> operation, bool deletion, ReplicateTo replicateTo, PersistTo persistTo)
        {
            var result = SendWithRetry(operation);

            if (result.Success)
            {
                var config   = ConfigInfo.ClientConfig.BucketConfigs[BucketName];
                var observer = new KeyObserver(ConfigInfo,
                                               ClusterController.Transcoder,
                                               config.ObserveInterval, config.ObserveTimeout);

                var observed = observer.Observe(operation.Key, result.Cas, deletion, replicateTo, persistTo);
                result.Durability = observed
                    ? Durability.Satisfied
                    : Durability.NotSatisfied;
            }
            else
            {
                result.Durability = Durability.NotSatisfied;
            }
            return(result);
        }
        public async void When_Observing_Key_During_AddAsync_Durability_Constraint_Is_Reached()
        {
            var configuration = new ClientConfiguration
            {
                Servers = new List<Uri>
                {
                    new Uri(ConfigurationManager.AppSettings["bootstrapUrl"])
                }
            };
            configuration.Initialize();

            var provider = new CarrierPublicationProvider(
                configuration,
                (pool) => new PooledIOService(pool),
                (config, endpoint) => new ConnectionPool<Connection>(config, endpoint),
                SaslFactory.GetFactory(),
                new DefaultConverter(),
                new DefaultTranscoder(new DefaultConverter()));

            var configInfo = provider.GetConfig("default");

            var key = "Test_Timeout_Add_Async";
            ulong cas = 0;
            using (var cluster = new Cluster(configuration))
            {
                using (var bucket = cluster.OpenBucket())
                {
                    bucket.Remove(key);
                    bucket.Insert(key, "");
                    cas = bucket.Upsert(key, "").Cas;
                }
            }
            var observer = new KeyObserver(configInfo, 10, 500);
            var constraintReached = await observer.ObserveAddAsync(key, cas, ReplicateTo.Zero, PersistTo.Zero);
            Assert.IsTrue(constraintReached);
        }
 public void When_No_Replicas_Are_Found_GetReplicas_Returns_Empty_List()
 {
     var vBucket = new VBucket(null, 0, 0, new[] { -1, -1, -1 });
     var expected = new int[] {};
     var observer = new KeyObserver(null, 10, 500);
     var actual = observer.GetReplicas(vBucket, ReplicateTo.One, PersistTo.Two);
     Assert.AreEqual(expected, actual);
     Assert.AreEqual(expected.Count(), actual.Count());
 }
        public async Task Test_Timeout_Add_PersistTo_Master_Async()
        {
            var configuration = new ClientConfiguration
            {
                Servers = new List<Uri>
                {
                    new Uri(ConfigurationManager.AppSettings["bootstrapUrl"])
                }
            };
            configuration.Initialize();

            var provider = new CarrierPublicationProvider(
                configuration,
                (pool) => new PooledIOService(pool),
                (config, endpoint) => new ConnectionPool<Connection>(config, endpoint),
                SaslFactory.GetFactory(),
                new DefaultConverter(),
                new DefaultTranscoder(new DefaultConverter()));

            var configInfo = provider.GetConfig("default");

            var key = "Test_Timeout_Add_PersistTo_Master_Async";
            IOperationResult result;
            using (var cluster = new Cluster(configuration))
            {
                using (var bucket = cluster.OpenBucket())
                {
                    bucket.Remove(key);
                    result = bucket.Insert(key, "");
                }
            }

            var clusterController = new Mock<IClusterController>();
            clusterController.Setup(x => x.Transcoder).Returns(new DefaultTranscoder());

            var pending = new ConcurrentDictionary<uint, IOperation>();

            var observer = new KeyObserver(pending, configInfo, clusterController.Object, 10, 500);
            using (var cts = new CancellationTokenSource(configuration.ObserveTimeout))
            {
                var constraintReached =
                    await observer.ObserveAddAsync(key, result.Cas, ReplicateTo.Zero, PersistTo.Zero, cts);
                Assert.IsTrue(constraintReached);
            }
        }
        public void When_PersistTo_Is_Greater_Than_ReplicateTo_Length_Of_Replicas_Is_PersistTo()
        {
            var vBucket = new VBucket(null, 0, 0, new[] { 0, 2, 1 }, 0, new VBucketServerMap { ServerList = new string[] { } }, "default");
            var expected = new[] { 0, 2 };

            var clusterController = new Mock<IClusterController>();
            clusterController.Setup(x => x.Transcoder).Returns(new DefaultTranscoder());
            var pending = new ConcurrentDictionary<uint, IOperation>();
            var observer = new KeyObserver(pending, null, clusterController.Object, 10, 500);

            var actual = observer.GetReplicas(vBucket, ReplicateTo.One, PersistTo.Two);

            Assert.AreEqual(expected, actual);
            Assert.AreEqual(actual.Count, (int)PersistTo.Two);
        }
 public void When_PersistTo_Is_Greater_Than_ReplicateTo_Length_Of_Replicas_Is_PersistTo()
 {
     var vBucket = new VBucket(null, 0, 0, new[] { 0, 2, 1 });
     var expected = new[] { 0, 2 };
     var observer = new KeyObserver(null, 10, 500);
     var actual = observer.GetReplicas(vBucket, ReplicateTo.One, PersistTo.Two);
     Assert.AreEqual(expected, actual);
     Assert.AreEqual(actual.Count, (int)PersistTo.Two);
 }
        /// <summary>
        /// Sends an operation to the server while observing its durability requirements using async/await
        /// </summary>
        /// <param name="operation">A binary memcached operation - must be a mutation operation.</param>
        /// <param name="deletion">True if mutation is a deletion.</param>
        /// <param name="replicateTo">The durability requirement for replication.</param>
        /// <param name="persistTo">The durability requirement for persistence.</param>
        /// <returns>The <see cref="Task{IOperationResult}"/> to be awaited on with its <see cref="Durability"/> status.</returns>
        /// <exception cref="ServiceNotSupportedException">The cluster does not support Data services.</exception>
        public override async Task <IOperationResult> SendWithDurabilityAsync(IOperation operation, bool deletion, ReplicateTo replicateTo, PersistTo persistTo)
        {
            IOperationResult result;

            try
            {
                //Is the cluster configured for Data services?
                if (!ConfigInfo.IsDataCapable)
                {
                    throw new ServiceNotSupportedException(
                              ExceptionUtil.GetMessage(ExceptionUtil.ServiceNotSupportedMsg, "Data"));
                }

                result = await SendWithRetryAsync(operation).ContinueOnAnyContext();

                if (result.Success)
                {
                    var config = ConfigInfo.ClientConfig.BucketConfigs[BucketName];
                    using (var cts = new CancellationTokenSource(config.ObserveTimeout))
                    {
                        if (ConfigInfo.SupportsEnhancedDurability)
                        {
                            var seqnoObserver = new KeySeqnoObserver(operation.Key, Pending, ConfigInfo,
                                                                     ClusterController,
                                                                     config.ObserveInterval, (uint)config.ObserveTimeout);

                            var observed = await seqnoObserver.ObserveAsync(result.Token, replicateTo, persistTo, cts)
                                           .ContinueOnAnyContext();

                            result.Durability = observed ? Durability.Satisfied : Durability.NotSatisfied;
                            ((OperationResult)result).Success = result.Durability == Durability.Satisfied;
                        }
                        else
                        {
                            var observer = new KeyObserver(Pending, ConfigInfo, ClusterController,
                                                           config.ObserveInterval, config.ObserveTimeout);

                            var observed = await observer.ObserveAsync(operation.Key, result.Cas,
                                                                       deletion, replicateTo, persistTo, cts).ContinueOnAnyContext();

                            result.Durability = observed ? Durability.Satisfied : Durability.NotSatisfied;
                            ((OperationResult)result).Success = result.Durability == Durability.Satisfied;
                        }
                    }
                }
                else
                {
                    result.Durability = Durability.NotSatisfied;
                    ((OperationResult)result).Success = result.Durability == Durability.Satisfied;
                }
            }
            catch (TaskCanceledException e)
            {
                result = new OperationResult
                {
                    Id         = operation.Key,
                    Exception  = e,
                    Status     = ResponseStatus.OperationTimeout,
                    Durability = Durability.NotSatisfied,
                    Success    = false
                };
            }
            catch (ReplicaNotConfiguredException e)
            {
                result = new OperationResult
                {
                    Id         = operation.Key,
                    Exception  = e,
                    Status     = ResponseStatus.NoReplicasFound,
                    Durability = Durability.NotSatisfied,
                    Success    = false
                };
            }
            catch (DocumentMutationLostException e)
            {
                result = new OperationResult
                {
                    Id         = operation.Key,
                    Exception  = e,
                    Status     = ResponseStatus.DocumentMutationLost,
                    Durability = Durability.NotSatisfied,
                    Success    = false
                };
            }
            catch (DocumentMutationException e)
            {
                result = new OperationResult
                {
                    Id         = operation.Key,
                    Exception  = e,
                    Status     = ResponseStatus.DocumentMutationDetected,
                    Durability = Durability.NotSatisfied,
                    Success    = false
                };
            }
            catch (Exception e)
            {
                result = new OperationResult
                {
                    Id        = operation.Key,
                    Exception = e,
                    Status    = ResponseStatus.ClientFailure,
                    Success   = false
                };
            }
            return(result);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Sends an operation to the server while observing it's durability requirements using async/await
        /// </summary>
        /// <typeparam name="T">The value for T.</typeparam>
        /// <param name="operation">A binary memcached operation - must be a mutation operation.</param>
        /// <param name="deletion">True if mutation is a deletion.</param>
        /// <param name="replicateTo">The durability requirement for replication.</param>
        /// <param name="persistTo">The durability requirement for persistence.</param>
        /// <returns>The <see cref="Task{IOperationResult}"/> to be awaited on with it's <see cref="Durability"/> status.</returns>
        /// <exception cref="ServiceNotSupportedException">The cluster does not support Data services.</exception>
        public override async Task <IOperationResult <T> > SendWithDurabilityAsync <T>(IOperation <T> operation, bool deletion, ReplicateTo replicateTo, PersistTo persistTo)
        {
            //Is the cluster configured for Data services?
            if (!ConfigInfo.IsDataCapable)
            {
                throw new ServiceNotSupportedException("The cluster does not support Data services.");
            }

            IOperationResult <T> result;

            try
            {
                result = await SendWithRetryAsync(operation);

                if (result.Success)
                {
                    var config = ConfigInfo.ClientConfig.BucketConfigs[BucketName];

                    if (ConfigInfo.SupportsEnhancedDurability)
                    {
                        var seqnoObserver = new KeySeqnoObserver(ConfigInfo, ClusterController.Transcoder,
                                                                 config.ObserveInterval, (uint)config.ObserveTimeout);

                        var observed = await seqnoObserver.ObserveAsync(result.Token, replicateTo, persistTo);

                        result.Durability = observed ? Durability.Satisfied : Durability.NotSatisfied;
                    }
                    else
                    {
                        var observer = new KeyObserver(ConfigInfo, ClusterController.Transcoder,
                                                       config.ObserveInterval, config.ObserveTimeout);

                        var observed =
                            await observer.ObserveAsync(operation.Key, result.Cas, deletion, replicateTo, persistTo);

                        result.Durability = observed ? Durability.Satisfied : Durability.NotSatisfied;
                    }
                }
                else
                {
                    result.Durability = Durability.NotSatisfied;
                }
            }
            catch (ReplicaNotConfiguredException e)
            {
                result = new OperationResult <T>
                {
                    Exception  = e,
                    Status     = ResponseStatus.NoReplicasFound,
                    Durability = Durability.NotSatisfied
                };
            }
            catch (DocumentMutationLostException e)
            {
                result = new OperationResult <T>
                {
                    Exception  = e,
                    Status     = ResponseStatus.DocumentMutationLost,
                    Durability = Durability.NotSatisfied
                };
            }
            catch (Exception e)
            {
                result = new OperationResult <T>
                {
                    Exception = e,
                    Status    = ResponseStatus.ClientFailure
                };
            }
            return(result);
        }
        /// <summary>
        /// Sends an operation to the server while observing it's durability requirements
        /// </summary>
        /// <param name="operation">A binary memcached operation - must be a mutation operation.</param>
        /// <param name="deletion">True if mutation is a deletion.</param>
        /// <param name="replicateTo">The durability requirement for replication.</param>
        /// <param name="persistTo">The durability requirement for persistence.</param>
        /// <returns>The <see cref="IOperationResult"/> with it's <see cref="Durability"/> status.</returns>
        /// <exception cref="ServiceNotSupportedException">The cluster does not support Data services.</exception>
        public override IOperationResult SendWithDurability(IOperation operation, bool deletion, ReplicateTo replicateTo, PersistTo persistTo)
        {
            IOperationResult result;

            try
            {
                //Is the cluster configured for Data services?
                if (!ConfigInfo.IsDataCapable)
                {
                    throw new ServiceNotSupportedException(
                              ExceptionUtil.GetMessage(ExceptionUtil.ServiceNotSupportedMsg, "Data"));
                }

                result = SendWithRetry(operation);
                if (result.Success)
                {
                    var config = ConfigInfo.ClientConfig.BucketConfigs[BucketName];

                    if (ConfigInfo.SupportsEnhancedDurability)
                    {
                        var seqnoObserver = new KeySeqnoObserver(operation.Key, Pending, ConfigInfo, ClusterController,
                                                                 config.ObserveInterval, (uint)config.ObserveTimeout);

                        var observed = seqnoObserver.Observe(result.Token, replicateTo, persistTo);
                        result.Durability = observed ? Durability.Satisfied : Durability.NotSatisfied;
                    }
                    else
                    {
                        var observer = new KeyObserver(Pending, ConfigInfo, ClusterController, config.ObserveInterval, config.ObserveTimeout);
                        var observed = observer.Observe(operation.Key, result.Cas, deletion, replicateTo, persistTo);
                        result.Durability = observed ? Durability.Satisfied : Durability.NotSatisfied;
                    }
                }
                else
                {
                    result.Durability = Durability.NotSatisfied;
                }
            }
            catch (ReplicaNotConfiguredException e)
            {
                result = new OperationResult
                {
                    Id         = operation.Key,
                    Exception  = e,
                    Status     = ResponseStatus.NoReplicasFound,
                    Durability = Durability.NotSatisfied,
                    OpCode     = operation.OperationCode
                };
            }
            catch (DocumentMutationLostException e)
            {
                result = new OperationResult
                {
                    Id         = operation.Key,
                    Exception  = e,
                    Status     = ResponseStatus.DocumentMutationLost,
                    Durability = Durability.NotSatisfied,
                    OpCode     = operation.OperationCode
                };
            }
            catch (Exception e)
            {
                result = new OperationResult
                {
                    Id        = operation.Key,
                    Exception = e,
                    Status    = ResponseStatus.ClientFailure,
                    OpCode    = operation.OperationCode
                };
            }
            return(result);
        }
        public void When_No_Replicas_Are_Found_GetReplicas_Returns_Empty_List()
        {
            var vBucket = new VBucket(null, 0, 0, new[] { -1, -1, -1 }, 0, new VBucketServerMap { ServerList = new string[] { } }, "default");
            var expected = new int[] {};

            var clusterController = new Mock<IClusterController>();
            clusterController.Setup(x => x.Transcoder).Returns(new DefaultTranscoder());
            var pending = new ConcurrentDictionary<uint, IOperation>();
            var observer = new KeyObserver(pending, null, clusterController.Object, 10, 500);

            var actual = observer.GetReplicas(vBucket, ReplicateTo.One, PersistTo.Two);

            Assert.AreEqual(expected, actual);
            Assert.AreEqual(expected.Count(), actual.Count());
        }
        public async void Test_Timeout_Add_PersistTo_Master_Async()
        {
            var configuration = new ClientConfiguration
            {
                Servers = new List<Uri>
                {
                    new Uri(ConfigurationManager.AppSettings["bootstrapUrl"])
                }
            };
            configuration.Initialize();

            var provider = new CarrierPublicationProvider(
                configuration,
                (pool) => new DefaultIOStrategy(pool),
                (config, endpoint) => new ConnectionPool<Connection>(config, endpoint),
                SaslFactory.GetFactory3(),
                new DefaultConverter(),
                new DefaultTranscoder(new DefaultConverter()));

            var configInfo = provider.GetConfig("default");

            var key = "Test_Timeout_Add_PersistTo_Master_Async";
            IOperationResult result;
            using (var cluster = new Cluster(configuration))
            {
                using (var bucket = cluster.OpenBucket())
                {
                    bucket.Remove(key);
                    result = bucket.Insert(key, "");
                }
            }

            var observer = new KeyObserver(configInfo, 10, 500);
            var constraintReached = await observer.ObserveAddAsync(key, result.Cas, ReplicateTo.Zero, PersistTo.Zero);
            Assert.IsTrue(constraintReached);
        }
        public async void When_Mutation_Happens_Observe_Fails_Async()
        {
            var configuration = new ClientConfiguration
            {
                Servers = new List<Uri>
                {
                    new Uri(ConfigurationManager.AppSettings["bootstrapUrl"])
                }
            };
            configuration.Initialize();

            var provider = new CarrierPublicationProvider(
                configuration,
                (pool) => new DefaultIOStrategy(pool),
                (config, endpoint) => new ConnectionPool<Connection>(config, endpoint),
                SaslFactory.GetFactory3(),
                new DefaultConverter(),
                new DefaultTranscoder(new DefaultConverter()));

            var configInfo = provider.GetConfig("default");

            var key = "When_Mutation_Happens_Observe_Fails_async";
            ulong cas = 0;
            using (var cluster = new Cluster(configuration))
            {
                using (var bucket = cluster.OpenBucket())
                {
                    bucket.Remove(key);
                    cas = bucket.Insert(key, "").Cas;
                    bucket.Upsert(key, "");
                }
            }
            var observer = new KeyObserver(configInfo, 10, 500);
            var constraintReached = await observer.ObserveAddAsync(key, cas, ReplicateTo.One, PersistTo.One);
            Assert.IsFalse(constraintReached);
        }
        public void When_Observing_Key_During_Add_Durability_Constraint_Is_Reached()
        {
            var configuration = new ClientConfiguration
            {
                Servers = new List<Uri>
                {
                    new Uri(ConfigurationManager.AppSettings["bootstrapUrl"])
                }
            };
            configuration.Initialize();

            var provider = new CarrierPublicationProvider(
                configuration,
                (pool) => new PooledIOService(pool),
                (config, endpoint) => new ConnectionPool<Connection>(config, endpoint),
                SaslFactory.GetFactory(),
                new DefaultConverter(),
                new DefaultTranscoder(new DefaultConverter()));

            var configInfo = provider.GetConfig("default");

            ulong cas = 0;
                using (var cluster = new Cluster(configuration))
                {
                    using (var bucket = cluster.OpenBucket())
                    {
                        bucket.Remove("Test_Timeout_Add");
                        bucket.Insert("Test_Timeout_Add", "");
                        cas = bucket.Upsert("Test_Timeout_Add", "").Cas;
                    }
                }
            var clusterController = new Mock<IClusterController>();
            clusterController.Setup(x => x.Transcoder).Returns(new DefaultTranscoder());

            var pending = new ConcurrentDictionary<uint, IOperation>();

            var observer = new KeyObserver(pending, configInfo, clusterController.Object, 10, 500);
            var constraintReached = observer.ObserveAdd("Test_Timeout_Add", cas, ReplicateTo.Zero, PersistTo.Zero);
            Assert.IsTrue(constraintReached);
        }