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); }
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)); } }
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"); }
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"); }
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 Fail() { if (Callback != null) { var response = new MemcacheResponseHeader { Opcode = Opcode.NoOp, Status = Status.InternalError, Opaque = RequestId }; Callback(response); } }
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); } }
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); }
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); } }
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"); }
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); }
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); }
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); }
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); } }
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"); }
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); } }
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); } }
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); }
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); } }
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); }
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); } }
public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message) { // nothing to handle on a quit response }
// 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); }
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); }
public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message) { ResponseHeader = header; Extra = extra; Message = message; Mutex.Set(); }
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; }
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); }
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"); } } }
public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message) { throw new NotImplementedException(); }
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"); }
private void OnMemcacheResponse(MemcacheResponseHeader h, IMemcacheRequest e) { if (MemcacheResponse != null) MemcacheResponse(h, e); }
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"); } } }
public void HandleResponse(MemcacheResponseHeader header, byte[] key, byte[] extra, byte[] message) { }
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); }