Ejemplo n.º 1
0
        public void SerializationThrows()
        {
            var serializerMoq = new Mock<ISerializer<TestType>>();
            serializerMoq.Setup(s => s.FromBytes(It.IsAny<byte[]>())).Throws(new SerializationException());
            serializerMoq.Setup(s => s.ToBytes(It.IsAny<TestType>())).Throws(new SerializationException());
            serializerMoq.Setup(s => s.TypeFlag).Returns(314);

            Exception raised = null;

            var config = new MemcacheClientConfiguration
            {
                ClusterFactory = c => _clusterMock,
            };
            var serialiserMoqObj = serializerMoq.Object;
            config.SetSerializer(serialiserMoqObj);
            var client = new MemcacheClient(config);
            client.CallbackError += e => raised = e;

            // test that the throws of the serializer is synchronously propagated
            Assert.Throws(typeof(SerializationException), () => client.Set("Hello", new TestType(), TimeSpan.Zero));

            // test that the failing serializer does not synchronously throws but sends a CallbackError event
            _responseHeader = new MemcacheResponseHeader
            {
                ExtraLength = 4,
                TotalBodyLength = 4,
                Opcode = Opcode.Get,
            };
            _extra = new byte[] { 0, 0, 0, 0};
            Assert.True(client.Get("Hello", (Status s, TestType v) => { }));
            Assert.IsNotNull(raised);
            Assert.IsInstanceOf<SerializationException>(raised);
        }
Ejemplo n.º 2
0
        public void QueueFullTest()
        {
            var config = new Configuration.MemcacheClientConfiguration
            {
                QueueLength = 1,
            };
            int transportAvailablized = 0;

            using (var serverMock = new ServerMock())
                using (var transportToTest = new MemcacheTransport(serverMock.ListenEndPoint, config, t => { }, t => Interlocked.Increment(ref transportAvailablized), false, null))
                {
                    var requestHeader = new MemcacheResponseHeader
                    {
                        Cas             = 1,
                        DataType        = 2,
                        ExtraLength     = 4,
                        KeyLength       = 0,
                        Opaque          = 42,
                        Opcode          = Opcode.Get,
                        Status          = Headers.Status.KeyNotFound,
                        TotalBodyLength = 4,
                    };
                    requestHeader.ToData(serverMock.ResponseHeader);
                    serverMock.ResponseBody = new byte[4];

                    serverMock.ReceiveMutex = new ManualResetEventSlim();
                    var clientMutex = new ManualResetEventSlim();
                    var request1    = new GetRequest
                    {
                        RequestId     = (uint)42,
                        Key           = "Hello, world".Select(c => (byte)c).ToArray(),
                        RequestOpcode = Opcode.Get,
                        CallBack      = (r, v) => clientMutex.Set(),
                    };
                    var request2 = new GetRequest
                    {
                        RequestId     = (uint)42,
                        Key           = "Hello, world".Select(c => (byte)c).ToArray(),
                        RequestOpcode = Opcode.Get,
                        CallBack      = (r, v) => { },
                    };

                    // we sent a first request and let the server wait before respond
                    Assert.IsTrue(transportToTest.TrySend(request1), "The first request failed to be sent");
                    Assert.That(() => transportAvailablized, Is.EqualTo(2).After(1000, 50));
                    // we check that the queue is full, and the transport fail to send a new request
                    Assert.IsFalse(transportToTest.TrySend(request2), "The second request should not have been sent");
                    // unblocks both server response and callback from client
                    serverMock.ReceiveMutex.Set();
                    Assert.IsTrue(clientMutex.Wait(1000), "The response callback has not been triggered for the first request");
                    // make sure that we triggered the transport available after the queue is not full anymore
                    Assert.That(() => transportAvailablized, Is.EqualTo(3).After(1000, 50));
                    // checks if we can send a new request since the queue is not full anymore
                    Assert.IsTrue(transportToTest.TrySend(request2), "The third request failed to be sent");
                    Assert.That(() => transportAvailablized, Is.EqualTo(4).After(1000, 50));
                }
        }
Ejemplo n.º 3
0
        public void RedundantGetRequestFailTest()
        {
            Status status = Status.UnknownCommand;

            var headerFail = new MemcacheResponseHeader {
                Opcode = Opcode.Get, Status = Status.KeyNotFound
            };

            // 1. Test redundancy = 3 and all gets are failing, the last on InternalError

            var request = new GetRequest
            {
                Key            = "Hello".Select(c => (byte)c).ToArray(),
                RequestId      = 0,
                CallBack       = (s, m) => status = s,
                CallBackPolicy = CallBackPolicy.AnyOK,
                Replicas       = 2,
            };

            var queryBuffer = request.GetQueryBuffer();

            CollectionAssert.AreEqual(GET_QUERY, queryBuffer, "The get query buffer is different from the expected one");

            Assert.DoesNotThrow(() => request.HandleResponse(headerFail, null, GET_FLAG, GET_MESSAGE), "Handle request should not throw an exception");
            Assert.AreEqual(Status.UnknownCommand, status, "Callback should not be called after the first failed get");

            Assert.DoesNotThrow(() => request.HandleResponse(headerFail, null, GET_FLAG, GET_MESSAGE), "Handle request should not throw an exception");
            Assert.AreEqual(Status.UnknownCommand, status, "Callback should not be called after the second failed get");

            Assert.DoesNotThrow(() => request.Fail(), "Handle request should not throw an exception");
            Assert.AreEqual(Status.InternalError, status, "Returned status should be InternalError");

            // 2. Test redundancy = 3 and all gets are failing, the last on KeyNotFound

            request = new GetRequest
            {
                Key            = "Hello".Select(c => (byte)c).ToArray(),
                RequestId      = 0,
                CallBack       = (s, m) => status = s,
                CallBackPolicy = CallBackPolicy.AnyOK,
                Replicas       = 2,
            };
            status = Status.UnknownCommand;

            Assert.DoesNotThrow(() => request.Fail(), "Handle request should not throw an exception");
            Assert.AreEqual(Status.UnknownCommand, status, "Callback should not be called after the first failed get");

            Assert.DoesNotThrow(() => request.Fail(), "Handle request should not throw an exception");
            Assert.AreEqual(Status.UnknownCommand, status, "Callback should not be called after the second failed get");

            Assert.DoesNotThrow(() => request.HandleResponse(headerFail, null, GET_FLAG, GET_MESSAGE), "Handle request should not throw an exception");
            Assert.AreEqual(Status.KeyNotFound, status, "Returned status should be KeynotFound");
        }
Ejemplo n.º 4
0
        public void RedundantSetRequestFailTest()
        {
            Status status  = Status.UnknownCommand;
            var    request = new SetRequest
            {
                Key            = @"Hello",
                Message        = System.Text.UTF8Encoding.Default.GetBytes(@"World"),
                RequestId      = 0,
                Expire         = TimeSpan.FromHours(1),
                CallBack       = (s) => status = s,
                CallBackPolicy = CallBackPolicy.AllOK,
                Replicas       = 1,
            };

            var headerOK = new MemcacheResponseHeader {
                Opcode = Opcode.Set, Status = Status.NoError
            };
            var headerFail = new MemcacheResponseHeader {
                Opcode = Opcode.Set, Status = Status.OutOfMemory
            };

            var queryBuffer = request.GetQueryBuffer();

            CollectionAssert.AreEqual(SET_QUERY, queryBuffer, "The set query buffer is different from the expected one");

            // 1. First reponse is OK, second is failing

            Assert.DoesNotThrow(() => request.HandleResponse(headerOK, null, SET_EXTRA, SET_MESSAGE));
            Assert.AreEqual(Status.UnknownCommand, status, "Callback should not be called on the first OK response");
            Assert.DoesNotThrow(() => request.Fail());
            Assert.AreEqual(Status.InternalError, status, "The status sent by a fail should be InternalError");

            // 2. First response is failing, second one is OK

            status  = Status.UnknownCommand;
            request = new SetRequest
            {
                Key            = @"Hello",
                Message        = System.Text.UTF8Encoding.Default.GetBytes(@"World"),
                RequestId      = 0,
                Expire         = TimeSpan.FromHours(1),
                CallBack       = (s) => status = s,
                CallBackPolicy = CallBackPolicy.AllOK,
                Replicas       = 1,
            };

            Assert.DoesNotThrow(() => request.HandleResponse(headerFail, null, SET_EXTRA, SET_MESSAGE));
            Assert.AreEqual(Status.OutOfMemory, status, "Callback should be called on the first failed response");
            status = Status.UnknownCommand;
            Assert.DoesNotThrow(() => request.HandleResponse(headerOK, null, SET_EXTRA, SET_MESSAGE));
            Assert.AreEqual(Status.UnknownCommand, status, "Callback should not be called on the responses following a fail");
        }
Ejemplo n.º 5
0
        public void NoOpRequestFailTest()
        {
            Status status = Status.UnknownCommand;
            var request = new NoOpRequest
            {
                Callback = (h) => status = h.Status,
            };

            var queryBuffer = request.GetQueryBuffer();

            var header = new MemcacheResponseHeader { Opcode = Opcode.NoOp, Status = Status.NoError };
            Assert.DoesNotThrow(request.Fail);
            Assert.AreEqual(Status.InternalError, status);
        }
Ejemplo n.º 6
0
        public void Fail()
        {
            if (Callback != null)
            {
                var response = new MemcacheResponseHeader
                {
                    Opcode = Opcode.NoOp,
                    Status = Status.InternalError,
                    Opaque = RequestId
                };

                Callback(response);
            }
        }
Ejemplo n.º 7
0
        public void Fail()
        {
            if (Callback != null)
            {
                var response = new MemcacheResponseHeader
                {
                    Opcode = Opcode.NoOp,
                    Status = Status.InternalError,
                    Opaque = RequestId
                };

                Callback(response);
            }
        }
Ejemplo n.º 8
0
 public void HandleResponse(MemcacheResponseHeader header, string key, byte[] extra, byte[] message)
 {
     if (key != null)
     {
         if (_result == null)
         {
             _result = new Dictionary <string, string>();
         }
         _result.Add(key, message != null ? UTF8Encoding.Default.GetString(message) : null);
     }
     else if (Callback != null)
     {
         Callback(_result);
     }
 }
Ejemplo n.º 9
0
        public void NoOpRequestOkTest()
        {
            Status status = Status.UnknownCommand;
            var request = new NoOpRequest
            {
                Callback = (h) => status = h.Status,
            };

            var queryBuffer = request.GetQueryBuffer();
            Assert.IsNotNull(queryBuffer);
            CollectionAssert.AreEqual(NOOP_QUERY, queryBuffer, "The noop query buffer is different of the expected one");

            var header = new MemcacheResponseHeader { Opcode = Opcode.NoOp, Status = Status.NoError };
            Assert.DoesNotThrow(() => request.HandleResponse(header, null, null, null));
            Assert.AreEqual(Status.NoError, status);
        }
Ejemplo n.º 10
0
        public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message)
        {
            if (key != null)
            {
                if (_result == null)
                    _result = new Dictionary<string, string>();

                var keyAsString = Encoding.UTF8.GetString(key);
                var messageAsString = message != null ? Encoding.UTF8.GetString(message) : null;
                _result.Add(keyAsString, messageAsString);
            }
            else if (Callback != null)
            {
                Callback(_result);
            }
        }
Ejemplo n.º 11
0
        public void RedundantSetRequestFailTest()
        {
            Status status = Status.UnknownCommand;
            var request = new SetRequest
            {
                Key = "Hello".Select(c => (byte)c).ToArray(),
                Message = System.Text.Encoding.UTF8.GetBytes(@"World"),
                RequestId = 0,
                Expire = TimeSpan.FromHours(1),
                CallBack = (s) => status = s,
                CallBackPolicy = CallBackPolicy.AllOK,
                Replicas = 1,
            };

            var headerOK = new MemcacheResponseHeader { Opcode = Opcode.Set, Status = Status.NoError };
            var headerFail = new MemcacheResponseHeader { Opcode = Opcode.Set, Status = Status.OutOfMemory };

            var queryBuffer = request.GetQueryBuffer();
            CollectionAssert.AreEqual(SET_QUERY, queryBuffer, "The set query buffer is different from the expected one");

            // 1. First reponse is OK, second is failing

            Assert.DoesNotThrow(() => request.HandleResponse(headerOK, null, SET_EXTRA, SET_MESSAGE));
            Assert.AreEqual(Status.UnknownCommand, status, "Callback should not be called on the first OK response");
            Assert.DoesNotThrow(() => request.Fail());
            Assert.AreEqual(Status.InternalError, status, "The status sent by a fail should be InternalError");

            // 2. First response is failing, second one is OK

            status = Status.UnknownCommand;
            request = new SetRequest
            {
                Key = "Hello".Select(c => (byte)c).ToArray(),
                Message = System.Text.Encoding.UTF8.GetBytes(@"World"),
                RequestId = 0,
                Expire = TimeSpan.FromHours(1),
                CallBack = (s) => status = s,
                CallBackPolicy = CallBackPolicy.AllOK,
                Replicas = 1,
            };

            Assert.DoesNotThrow(() => request.HandleResponse(headerFail, null, SET_EXTRA, SET_MESSAGE));
            Assert.AreEqual(Status.OutOfMemory, status, "Callback should be called on the first failed response");
            status = Status.UnknownCommand;
            Assert.DoesNotThrow(() => request.HandleResponse(headerOK, null, SET_EXTRA, SET_MESSAGE));
            Assert.AreEqual(Status.UnknownCommand, status, "Callback should not be called on the responses following a fail");
        }
Ejemplo n.º 12
0
        public void NoOpRequestFailTest()
        {
            Status status  = Status.UnknownCommand;
            var    request = new NoOpRequest
            {
                Callback = (h) => status = h.Status,
            };

            var queryBuffer = request.GetQueryBuffer();

            var header = new MemcacheResponseHeader {
                Opcode = Opcode.NoOp, Status = Status.NoError
            };

            Assert.DoesNotThrow(request.Fail);
            Assert.AreEqual(Status.InternalError, status);
        }
        public void SaslPlainTextRequestOkTest()
        {
            Status status = Status.UnknownCommand;
            var request = new SaslPlainRequest
            {
                Callback = s => status = s,
                User = @"user",
                Password = @"password",
                Zone = @"zone",
            };

            var queryBuffer = request.GetQueryBuffer();
            CollectionAssert.AreEqual(SASL_PLAIN_QUERY, queryBuffer, "The sasl plain text query buffer is different of the expected one");

            var header = new MemcacheResponseHeader { Opcode = Opcode.StepAuth, Status = Status.NoError };
            Assert.DoesNotThrow(() => request.HandleResponse(header, null, null, null));
            Assert.AreEqual(Status.NoError, status);
        }
Ejemplo n.º 14
0
        public bool TrySend(IMemcacheRequest request, int timeout)
        {
            LastRequest = request;
            TrySendCounter++;

            if (timeout == 0)
            {
                var response = new MemcacheResponseHeader
                {
                    Status      = DefaultResponse,
                    ExtraLength = 4,
                };

                LastRequest.HandleResponse(response, request.Key, new byte[4], new byte[0]);
            }

            return(true);
        }
Ejemplo n.º 15
0
        private IMemcacheRequest DequeueToMatch(MemcacheResponseHeader header)
        {
            if (header.Opcode.IsQuiet())
            {
                throw new MemcacheException("No way we can match a quiet request !");
            }

            IMemcacheRequest result;

            // hacky case on partial response for stat command
            if (header.Opcode == Opcode.Stat && header.TotalBodyLength != 0 && header.Status == Status.NoError)
            {
                if (!_pendingRequests.TryPeek(out result))
                {
                    throw new MemcacheException("Received a response when no request is pending");
                }
            }
            else
            {
                if (!_pendingRequests.TryDequeue(out result))
                {
                    throw new MemcacheException("Received a response when no request is pending");
                }
            }

            if (result.RequestId != header.Opaque)
            {
                try
                {
                    result.Fail();
                }
                catch (Exception e)
                {
                    if (TransportError != null)
                    {
                        TransportError(e);
                    }
                }
                throw new MemcacheException("Received a response that doesn't match with the sent request queue : sent " + result + " received " + header);
            }

            AvailableInReceive();
            return(result);
        }
Ejemplo n.º 16
0
        public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message)
        {
            if (key != null)
            {
                if (_result == null)
                {
                    _result = new Dictionary <string, string>();
                }

                var keyAsString     = Encoding.UTF8.GetString(key);
                var messageAsString = message != null?Encoding.UTF8.GetString(message) : null;

                _result.Add(keyAsString, messageAsString);
            }
            else if (Callback != null)
            {
                Callback(_result);
            }
        }
Ejemplo n.º 17
0
        public void GetRequestTest()
        {
            byte[] message = null;
            var    request = new GetRequest {
                Key = @"Hello", RequestId = 0, CallBack = (s, m) => message = m, CallBackPolicy = CallBackPolicy.AnyOK
            };

            var queryBuffer = request.GetQueryBuffer();

            CollectionAssert.AreEqual(GET_QUERY, queryBuffer, "The get query buffer is different from the expected one");

            var header = new MemcacheResponseHeader {
                Opcode = Opcode.Get, Status = Status.NoError
            };

            Assert.DoesNotThrow(() => request.HandleResponse(header, null, GET_FLAG, GET_MESSAGE), "Handle request should not throw an exception");

            Assert.AreSame(GET_MESSAGE, message, "Sent message and the one returned by the request are different");
        }
Ejemplo n.º 18
0
        private void ReceiveBody(Socket socket, byte[] headerBytes)
        {
            _currentResponse = new MemcacheResponseHeader(headerBytes);

            var body = _currentResponse.TotalBodyLength == 0 ? null : new byte[_currentResponse.TotalBodyLength];

            _receiveBodyAsynchEvtArgs.SetBuffer(body, 0, (int)_currentResponse.TotalBodyLength);

            try
            {
                if (_currentResponse.TotalBodyLength == 0 || !_socket.ReceiveAsync(_receiveBodyAsynchEvtArgs))
                {
                    OnReceiveBodyComplete(_socket, _receiveBodyAsynchEvtArgs);
                }
            }
            catch (Exception e)
            {
                TransportFailureOnReceive(e);
            }
        }
Ejemplo n.º 19
0
        public void HandleResponse(MemcacheResponseHeader header, string key, byte[] extra, byte[] message)
        {
            if (header.Status == Status.NoError)
            {
                if (extra == null || extra.Length == 0)
                {
                    throw new MemcacheException("The get command flag is not present !");
                }
                else if (extra.Length != 4)
                {
                    throw new MemcacheException("The get command flag is the wrong size !");
                }
                Flag = extra.CopyToUInt(0);
            }

            if (CallCallback(header.Status) && CallBack != null)
            {
                CallBack(header.Status, message);
            }
        }
Ejemplo n.º 20
0
        public void NoOpRequestOkTest()
        {
            Status status  = Status.UnknownCommand;
            var    request = new NoOpRequest
            {
                Callback = (h) => status = h.Status,
            };

            var queryBuffer = request.GetQueryBuffer();

            Assert.IsNotNull(queryBuffer);
            CollectionAssert.AreEqual(NOOP_QUERY, queryBuffer, "The noop query buffer is different of the expected one");

            var header = new MemcacheResponseHeader {
                Opcode = Opcode.NoOp, Status = Status.NoError
            };

            Assert.DoesNotThrow(() => request.HandleResponse(header, null, null, null));
            Assert.AreEqual(Status.NoError, status);
        }
Ejemplo n.º 21
0
        public void DeleteRequestTest()
        {
            Status status  = Status.UnknownCommand;
            var    request = new DeleteRequest
            {
                Key       = "Hello".Select(c => (byte)c).ToArray(),
                RequestId = 0,
                CallBack  = (s) => status = s,
            };

            var queryBuffer = request.GetQueryBuffer();

            Assert.IsNotNull(queryBuffer);
            CollectionAssert.AreEqual(DELETE_QUERY, queryBuffer, "The delete query buffer is different of the expected one");

            var header = new MemcacheResponseHeader {
                Opcode = Opcode.Delete, Status = Status.NoError
            };

            Assert.DoesNotThrow(() => request.HandleResponse(header, null, null, null));
            Assert.AreEqual(Status.NoError, status);
        }
        public void SaslPlainTextRequestOkTest()
        {
            Status status  = Status.UnknownCommand;
            var    request = new SaslPlainRequest
            {
                Callback = s => status = s,
                User     = @"user",
                Password = @"password",
                Zone     = @"zone",
            };

            var queryBuffer = request.GetQueryBuffer();

            CollectionAssert.AreEqual(SASL_PLAIN_QUERY, queryBuffer, "The sasl plain text query buffer is different of the expected one");

            var header = new MemcacheResponseHeader {
                Opcode = Opcode.StepAuth, Status = Status.NoError
            };

            Assert.DoesNotThrow(() => request.HandleResponse(header, null, null, null));
            Assert.AreEqual(Status.NoError, status);
        }
Ejemplo n.º 23
0
        private void ReceiveBody(byte[] headerBytes)
        {
            _currentResponse = new MemcacheResponseHeader(headerBytes);

            long sizeToRead = Math.Min(_pinnedBufferSize, _currentResponse.TotalBodyLength);

            var bodyStream = _currentResponse.TotalBodyLength == 0 ? null : new MemoryStream((int)_currentResponse.TotalBodyLength);

            _receiveBodyAsyncEvtArgs.SetBuffer(0, (int)sizeToRead);
            _receiveBodyAsyncEvtArgs.UserToken = bodyStream;

            try
            {
                if (_currentResponse.TotalBodyLength == 0 || !_socket.ReceiveAsync(_receiveBodyAsyncEvtArgs))
                {
                    OnReceiveBodyComplete(_socket, _receiveBodyAsyncEvtArgs);
                }
            }
            catch (Exception e)
            {
                TransportFailureOnReceive(e);
            }
        }
Ejemplo n.º 24
0
        public void SerializationThrows()
        {
            var serializerMoq = new Mock <ISerializer <TestType> >();

            serializerMoq.Setup(s => s.FromBytes(It.IsAny <byte[]>())).Throws(new SerializationException());
            serializerMoq.Setup(s => s.ToBytes(It.IsAny <TestType>())).Throws(new SerializationException());
            serializerMoq.Setup(s => s.TypeFlag).Returns(314);

            Exception raised = null;

            var config = new MemcacheClientConfiguration
            {
                ClusterFactory = c => _clusterMock,
            };
            var serialiserMoqObj = serializerMoq.Object;

            config.SetSerializer(serialiserMoqObj);
            var client = new MemcacheClient(config);

            client.CallbackError += e => raised = e;

            // test that the throws of the serializer is synchronously propagated
            Assert.Throws(typeof(SerializationException), () => client.Set("Hello", new TestType(), TimeSpan.Zero));

            // test that the failing serializer does not synchronously throws but sends a CallbackError event
            _responseHeader = new MemcacheResponseHeader
            {
                ExtraLength     = 4,
                TotalBodyLength = 4,
                Opcode          = Opcode.Get,
            };
            _extra = new byte[] { 0, 0, 0, 0 };
            Assert.True(client.Get("Hello", (Status s, TestType v) => { }));
            Assert.IsNotNull(raised);
            Assert.IsInstanceOf <SerializationException>(raised);
        }
Ejemplo n.º 25
0
        private void ReceiveBody(byte[] headerBytes)
        {
            _currentResponse = new MemcacheResponseHeader(headerBytes);

            var body = _currentResponse.TotalBodyLength == 0 ? null : new byte[_currentResponse.TotalBodyLength];
            _receiveBodyAsynchEvtArgs.SetBuffer(body, 0, (int)_currentResponse.TotalBodyLength);

            try
            {
                if (_currentResponse.TotalBodyLength == 0 || !_socket.ReceiveAsync(_receiveBodyAsynchEvtArgs))
                    OnReceiveBodyComplete(_socket, _receiveBodyAsynchEvtArgs);
            }
            catch (Exception e)
            {
                TransportFailureOnReceive(e);
            }
        }
Ejemplo n.º 26
0
 public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message)
 {
     // nothing to handle on a quit response
 }
Ejemplo n.º 27
0
 // nothing to do on set response
 public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message)
 {
     if (CallCallback(header.Status) && CallBack != null)
         CallBack(header.Status);
 }
Ejemplo n.º 28
0
        public void DeleteRequestTest()
        {
            Status status = Status.UnknownCommand;
            var request = new DeleteRequest
            {
                Key = "Hello".Select(c => (byte)c).ToArray(),
                RequestId = 0,
                CallBack = (s) => status = s,
            };

            var queryBuffer = request.GetQueryBuffer();
            Assert.IsNotNull(queryBuffer);
            CollectionAssert.AreEqual(DELETE_QUERY, queryBuffer, "The delete query buffer is different of the expected one");

            var header = new MemcacheResponseHeader { Opcode = Opcode.Delete, Status = Status.NoError };
            Assert.DoesNotThrow(() => request.HandleResponse(header, null, null, null));
            Assert.AreEqual(Status.NoError, status);
        }
Ejemplo n.º 29
0
        public void Setup()
        {
            var nodeMock = new Mock<IMemcacheNode>();
            nodeMock.Setup(n => n.EndPoint).Returns(new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1 }), 11211));
            nodeMock.Setup(n => n.IsDead).Returns(false);
            nodeMock.Setup(n => n.TrySend(It.IsAny<IMemcacheRequest>(), It.IsAny<int>()))
                .Callback((IMemcacheRequest req, int timeout) => req.HandleResponse(_responseHeader, _key, _extra, _message))
                .Returns(true);
            _nodeMock = nodeMock.Object;

            var locatorMoq = new Mock<INodeLocator>();
            locatorMoq.Setup(l => l.Locate(It.IsAny<IMemcacheRequest>())).Returns(Enumerable.Repeat(_nodeMock, 1));
            _locatorMock = locatorMoq.Object;

            var clusterMoq = new Mock<IMemcacheCluster>();
            clusterMoq.Setup(c => c.Locator).Returns(_locatorMock);
            clusterMoq.Setup(c => c.Nodes).Returns(Enumerable.Repeat(_nodeMock, 1));
            _clusterMock = clusterMoq.Object;

            _key = null;
            _extra = null;
            _message = null;
            _responseHeader = default(MemcacheResponseHeader);
        }
Ejemplo n.º 30
0
 public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message)
 {
     ResponseHeader = header;
     Extra = extra;
     Message = message;
     Mutex.Set();
 }
Ejemplo n.º 31
0
        private IMemcacheRequest DequeueToMatch(MemcacheResponseHeader header)
        {
            if (header.Opcode.IsQuiet())
                throw new MemcacheException("No way we can match a quiet request !");

            IMemcacheRequest result;

            // hacky case on partial response for stat command
            if (header.Opcode == Opcode.Stat && header.TotalBodyLength != 0 && header.Status == Status.NoError)
            {
                if (!_pendingRequests.TryPeek(out result))
                    throw new MemcacheException("Received a response when no request is pending");
            }
            else
            {
                if (!_pendingRequests.TryDequeue(out result))
                    throw new MemcacheException("Received a response when no request is pending");
            }

            if (result.RequestId != header.Opaque)
            {
                try
                {
                    result.Fail();
                }
                catch (Exception e)
                {
                    if (TransportError != null)
                        TransportError(e);
                }
                throw new MemcacheException("Received a response that doesn't match with the sent request queue : sent " + result + " received " + header);
            }

            AvailableInReceive();
            return result;
        }
Ejemplo n.º 32
0
        public void SetRequestTest()
        {
            Status status = Status.UnknownCommand;
            var request = new SetRequest
            {
                Key = "Hello".Select(c => (byte)c).ToArray(),
                Message = System.Text.Encoding.UTF8.GetBytes(@"World"),
                RequestId = 0,
                Expire = TimeSpan.FromHours(1),
                CallBack = (s) => status = s,
                CallBackPolicy = CallBackPolicy.AllOK
            };

            Assert.AreEqual(Opcode.Set, request.RequestOpcode);

            var queryBuffer = request.GetQueryBuffer();
            CollectionAssert.AreEqual(SET_QUERY, queryBuffer, "The set query buffer is different from the expected one");

            var header = new MemcacheResponseHeader { Opcode = Opcode.Set, Status = Status.NoError };
            Assert.DoesNotThrow(() => request.HandleResponse(header, null, SET_EXTRA, SET_MESSAGE));
            Assert.AreEqual(Status.NoError, status);
        }
Ejemplo n.º 33
0
        public void MemcacheSocketTest([Values(0, 2, 10)]int maxByteSentByServer)
        {
            using (var serverMock = new ServerMock())
            {
                var endPoint = serverMock.ListenEndPoint;
                serverMock.MaxSent = maxByteSentByServer;

                // random header
                var requestHeader = new MemcacheRequestHeader
                {
                    Cas = 1,
                    DataType = 2,
                    ExtraLength = 5,
                    KeyLength = 3,
                    Opaque = 42,
                    Opcode = Opcode.Increment,
                    TotalBodyLength = 12,
                };
                // body with the size defined in the header
                var requestBody = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };

                // build the request buffer
                var requestBuffer = new byte[MemcacheRequestHeader.Size + requestHeader.TotalBodyLength];
                requestHeader.ToData(requestBuffer);
                Array.Copy(requestBody, 0, requestBuffer, MemcacheRequestHeader.Size, requestHeader.TotalBodyLength);

                // build the response header
                var responseHeader = new MemcacheResponseHeader
                {
                    Cas = 8,
                    DataType = 12,
                    ExtraLength = 3,
                    KeyLength = 0,
                    // must be the same or it will crash : TODO add a test to ensure we detect this fail
                    Opaque = requestHeader.Opaque,
                    Status = Status.UnknownCommand,
                    Opcode = Opcode.Prepend,
                    TotalBodyLength = 15,
                };
                // body with the size defined in the header
                var responseExtra = new byte[] { 1, 2, 3 };
                var responseMessage = new byte[] { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

                // build the request buffer
                var responseBody = new byte[responseHeader.TotalBodyLength];
                Array.Copy(responseExtra, 0, responseBody, 0, responseHeader.ExtraLength);
                Array.Copy(responseMessage, 0, responseBody, responseHeader.ExtraLength, responseHeader.TotalBodyLength - responseHeader.ExtraLength);

                // set the things to answer to the server
                serverMock.ResponseBody = responseBody;
                responseHeader.ToData(serverMock.ResponseHeader);

                var request = new RequestMock
                {
                    QueryBuffer = requestBuffer,
                    RequestId = requestHeader.Opaque
                    /*ResponseHeader = responseHeader,
                    Message = responseMessage,
                    Extra = responseExtra,*/
                };

                using (var transport = new MemcacheTransport(endPoint, new MemcacheClientConfiguration(), _ => { }, _ => { }, false, null))
                {
                    Assert.IsTrue(transport.TrySend(request));

                    Assert.IsTrue(request.Mutex.Wait(TimeSpan.FromSeconds(10)), "The request has not been completed on less than 10 sec");

                    // and now, assert that we sent what we had to send and we received what the server sent
                    Assert.AreEqual(requestHeader, serverMock.LastReceivedHeader, "Sent header differ from header received by the server");
                    CollectionAssert.AreEqual(requestBody, serverMock.LastReceivedBody, "Sent body is different than received by the server");

                    Assert.AreEqual(responseHeader, request.ResponseHeader, "Received header differ from header sent by the server");
                    CollectionAssert.AreEqual(responseExtra, request.Extra, "Received extra is different than sent by the server");
                    CollectionAssert.AreEqual(responseMessage, request.Message, "Received message is different than sent by the server");
                }
            }
        }
Ejemplo n.º 34
0
 public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message)
 {
     // nothing to handle on a quit response
 }
Ejemplo n.º 35
0
 public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 36
0
 public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 37
0
        public void RedundantGetRequestTest()
        {
            byte[] message = null;
            Status status  = Status.UnknownCommand;

            var headerOK = new MemcacheResponseHeader {
                Opcode = Opcode.Get, Status = Status.NoError
            };
            var headerFail = new MemcacheResponseHeader {
                Opcode = Opcode.Get, Status = Status.KeyNotFound
            };

            // 1. Test redundancy = 3 and all gets are successful

            var request = new GetRequest {
                Key = @"Hello", RequestId = 0, CallBack = (s, m) => { message = m; status = s; }, CallBackPolicy = CallBackPolicy.AnyOK, Replicas = 2
            };

            var queryBuffer = request.GetQueryBuffer();

            CollectionAssert.AreEqual(GET_QUERY, queryBuffer, "The get query buffer is different from the expected one");

            Assert.DoesNotThrow(() => request.HandleResponse(headerOK, null, GET_FLAG, GET_MESSAGE), "Handle request should not throw an exception");
            Assert.AreEqual(Status.NoError, status, "Returned status should be NoError after the first successful get");
            Assert.AreSame(GET_MESSAGE, message, "Sent message and the one returned by the request are different");

            status = Status.UnknownCommand;
            Assert.DoesNotThrow(() => request.HandleResponse(headerOK, null, GET_FLAG, GET_MESSAGE), "Handle request should not throw an exception");
            Assert.AreEqual(Status.UnknownCommand, status, "The callback should not be called a second time");

            status = Status.UnknownCommand;
            Assert.DoesNotThrow(() => request.HandleResponse(headerOK, null, GET_FLAG, GET_MESSAGE), "Handle request should not throw an exception");
            Assert.AreEqual(Status.UnknownCommand, status, "The callback should not be called a second time");

            // 2. Test redundancy = 3, the first get is failing

            request = new GetRequest {
                Key = @"Hello", RequestId = 0, CallBack = (s, m) => { message = m; status = s; }, CallBackPolicy = CallBackPolicy.AnyOK, Replicas = 2
            };
            status = Status.UnknownCommand;

            Assert.DoesNotThrow(() => request.HandleResponse(headerFail, null, GET_FLAG, GET_MESSAGE), "Handle request should not throw an exception");
            Assert.AreEqual(Status.UnknownCommand, status, "Callback should not be called after the first failed get");

            Assert.DoesNotThrow(() => request.HandleResponse(headerOK, null, GET_FLAG, GET_MESSAGE), "Handle request should not throw an exception");
            Assert.AreEqual(Status.NoError, status, "Returned status should be NoError after the first successful get");
            Assert.AreSame(GET_MESSAGE, message, "Sent message and the one returned by the request are different");

            status = Status.UnknownCommand;
            Assert.DoesNotThrow(() => request.HandleResponse(headerOK, null, GET_FLAG, GET_MESSAGE), "Handle request should not throw an exception");
            Assert.AreEqual(Status.UnknownCommand, status, "The callback should not be called a second time");

            // 3. Test redundancy = 3, the first and second gets are failing

            request = new GetRequest {
                Key = @"Hello", RequestId = 0, CallBack = (s, m) => { message = m; status = s; }, CallBackPolicy = CallBackPolicy.AnyOK, Replicas = 2
            };
            status = Status.UnknownCommand;

            Assert.DoesNotThrow(() => request.HandleResponse(headerFail, null, GET_FLAG, GET_MESSAGE), "Handle request should not throw an exception");
            Assert.AreEqual(Status.UnknownCommand, status, "Callback should not be called after the first failed get");

            Assert.DoesNotThrow(() => request.Fail(), "Handle request should not throw an exception");
            Assert.AreEqual(Status.UnknownCommand, status, "Callback should not be called after the second failed get");

            Assert.DoesNotThrow(() => request.HandleResponse(headerOK, null, GET_FLAG, GET_MESSAGE), "Handle request should not throw an exception");
            Assert.AreEqual(Status.NoError, status, "Returned status should be NoError after the first successful get");
            Assert.AreSame(GET_MESSAGE, message, "Sent message and the one returned by the request are different");
        }
Ejemplo n.º 38
0
        public void QueueFullTest()
        {
            var config = new Configuration.MemcacheClientConfiguration
            {
                QueueLength = 1,
            };
            int transportAvailablized = 0;

            using (var serverMock = new ServerMock())
            using (var transportToTest = new MemcacheTransport(serverMock.ListenEndPoint, config, t => { }, t => Interlocked.Increment(ref transportAvailablized), false, null))
            {
                var requestHeader = new MemcacheResponseHeader
                {
                    Cas = 1,
                    DataType = 2,
                    ExtraLength = 4,
                    KeyLength = 0,
                    Opaque = 42,
                    Opcode = Opcode.Get,
                    Status = Headers.Status.KeyNotFound,
                    TotalBodyLength = 4,
                };
                requestHeader.ToData(serverMock.ResponseHeader);
                serverMock.ResponseBody = new byte[4];

                serverMock.ReceiveMutex = new ManualResetEventSlim();
                var clientMutex = new ManualResetEventSlim();
                var request1 = new GetRequest
                {
                    RequestId = (uint)42,
                    Key = "Hello, world".Select(c => (byte)c).ToArray(),
                    RequestOpcode = Opcode.Get,
                    CallBack = (r, v) => clientMutex.Set(),
                };
                var request2 = new GetRequest
                {
                    RequestId = (uint)42,
                    Key = "Hello, world".Select(c => (byte)c).ToArray(),
                    RequestOpcode = Opcode.Get,
                    CallBack = (r, v) => { },
                };

                // we sent a first request and let the server wait before respond
                Assert.IsTrue(transportToTest.TrySend(request1), "The first request failed to be sent");
                Assert.That(() => transportAvailablized, Is.EqualTo(2).After(1000, 50));
                // we check that the queue is full, and the transport fail to send a new request
                Assert.IsFalse(transportToTest.TrySend(request2), "The second request should not have been sent");
                // unblocks both server response and callback from client
                serverMock.ReceiveMutex.Set();
                Assert.IsTrue(clientMutex.Wait(1000), "The response callback has not been triggered for the first request");
                // make sure that we triggered the transport available after the queue is not full anymore
                Assert.That(() => transportAvailablized, Is.EqualTo(3).After(1000, 50));
                // checks if we can send a new request since the queue is not full anymore
                Assert.IsTrue(transportToTest.TrySend(request2), "The third request failed to be sent");
                Assert.That(() => transportAvailablized, Is.EqualTo(4).After(1000, 50));
            }
        }
Ejemplo n.º 39
0
 private void OnMemcacheResponse(MemcacheResponseHeader h, IMemcacheRequest e)
 {
     if (MemcacheResponse != null)
         MemcacheResponse(h, e);
 }
Ejemplo n.º 40
0
        public void MemcacheSocketTest([Values(0, 2, 10)] int maxByteSentByServer)
        {
            using (var serverMock = new ServerMock())
            {
                var endPoint = serverMock.ListenEndPoint;
                serverMock.MaxSent = maxByteSentByServer;

                // random header
                var requestHeader = new MemcacheRequestHeader
                {
                    Cas             = 1,
                    DataType        = 2,
                    ExtraLength     = 5,
                    KeyLength       = 3,
                    Opaque          = 42,
                    Opcode          = Opcode.Increment,
                    TotalBodyLength = 12,
                };
                // body with the size defined in the header
                var requestBody = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };

                // build the request buffer
                var requestBuffer = new byte[MemcacheRequestHeader.Size + requestHeader.TotalBodyLength];
                requestHeader.ToData(requestBuffer);
                Array.Copy(requestBody, 0, requestBuffer, MemcacheRequestHeader.Size, requestHeader.TotalBodyLength);

                // build the response header
                var responseHeader = new MemcacheResponseHeader
                {
                    Cas         = 8,
                    DataType    = 12,
                    ExtraLength = 3,
                    KeyLength   = 0,
                    // must be the same or it will crash : TODO add a test to ensure we detect this fail
                    Opaque          = requestHeader.Opaque,
                    Status          = Status.UnknownCommand,
                    Opcode          = Opcode.Prepend,
                    TotalBodyLength = 15,
                };
                // body with the size defined in the header
                var responseExtra   = new byte[] { 1, 2, 3 };
                var responseMessage = new byte[] { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

                // build the request buffer
                var responseBody = new byte[responseHeader.TotalBodyLength];
                Array.Copy(responseExtra, 0, responseBody, 0, responseHeader.ExtraLength);
                Array.Copy(responseMessage, 0, responseBody, responseHeader.ExtraLength, responseHeader.TotalBodyLength - responseHeader.ExtraLength);

                // set the things to answer to the server
                serverMock.ResponseBody = responseBody;
                responseHeader.ToData(serverMock.ResponseHeader);

                var request = new RequestMock
                {
                    QueryBuffer = requestBuffer,
                    RequestId   = requestHeader.Opaque

                                  /*ResponseHeader = responseHeader,
                                   * Message = responseMessage,
                                   * Extra = responseExtra,*/
                };

                using (var transport = new MemcacheTransport(endPoint, new MemcacheClientConfiguration(), _ => { }, _ => { }, false, null))
                {
                    Assert.IsTrue(transport.TrySend(request));

                    Assert.IsTrue(request.Mutex.Wait(TimeSpan.FromSeconds(10)), "The request has not been completed on less than 10 sec");

                    // and now, assert that we sent what we had to send and we received what the server sent
                    Assert.AreEqual(requestHeader, serverMock.LastReceivedHeader, "Sent header differ from header received by the server");
                    CollectionAssert.AreEqual(requestBody, serverMock.LastReceivedBody, "Sent body is different than received by the server");

                    Assert.AreEqual(responseHeader, request.ResponseHeader, "Received header differ from header sent by the server");
                    CollectionAssert.AreEqual(responseExtra, request.Extra, "Received extra is different than sent by the server");
                    CollectionAssert.AreEqual(responseMessage, request.Message, "Received message is different than sent by the server");
                }
            }
        }
Ejemplo n.º 41
0
 public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message)
 {
 }
Ejemplo n.º 42
0
        public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message)
        {
            if (header.Status == Status.NoError)
            {
                if (extra == null || extra.Length == 0)
                    throw new MemcacheException("The get command flag is not present !");

                if (extra.Length != 4)
                    throw new MemcacheException("The get command flag is the wrong size !");

                Flag = extra.CopyToUInt(0);
            }

            if (CallCallback(header.Status) && CallBack != null)
                CallBack(header.Status, message);
        }