Skip to content

Commit dd18e4e

Browse files
committed
Add test for very short or incomplete inline command packages.
1 parent 946f0c9 commit dd18e4e

File tree

1 file changed

+67
-9
lines changed

1 file changed

+67
-9
lines changed

test/Garnet.test/InlineCommandlineTests.cs

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace Garnet.test
1111
{
12+
[NonParallelizable]
1213
[TestFixture]
1314
public class InlineCommandlineTests
1415
{
@@ -33,15 +34,16 @@ public void Setup()
3334
public void TearDown()
3435
{
3536
server.Dispose();
37+
client.Close();
3638
client.Dispose();
3739
TestUtils.DeleteDirectory(TestUtils.MethodTestDir);
3840
}
3941

4042
private async Task<string> Send(string message, string suffix = "\r\n")
4143
{
42-
_ = await client.SendAsync(Encoding.UTF8.GetBytes(message + suffix));
44+
_ = await client.SendAsync(Encoding.ASCII.GetBytes(message + suffix));
4345
var received = await client.ReceiveAsync(buffer, SocketFlags.None);
44-
return Encoding.UTF8.GetString(buffer, 0, received);
46+
return Encoding.ASCII.GetString(buffer, 0, received);
4547
}
4648

4749
[Test]
@@ -72,7 +74,7 @@ public async Task InlineCommandParseTest()
7274
// Should fail due to missing argument. We test such failures to ensure
7375
// readhead is not messed up and commands can be placed afterwards.
7476
response = await Send("CLIENT");
75-
ClassicAssert.AreEqual('-', response[0]);
77+
ClassicAssert.AreEqual("-ERR wrong number of arguments for 'CLIENT' command\r\n", response);
7678

7779
// Test client name was actually set
7880
response = await Send("CLIENT GETNAME");
@@ -86,15 +88,15 @@ public async Task InlineCommandParseTest()
8688
response = await Send("PING\nPING");
8789
ClassicAssert.AreEqual("+PONG\r\n+PONG\r\n", response);
8890
// CR is a valid separator
89-
response = await Send("PING\rPING");
91+
response = await Send("PING\rPING", "\n");
9092
ClassicAssert.AreEqual("$4\r\nPING\r\n", response);
9193
// As is TAB
9294
response = await Send("PING\tPING");
9395
ClassicAssert.AreEqual("$4\r\nPING\r\n", response);
9496

9597
// Test command failure
9698
response = await Send("PIN");
97-
ClassicAssert.AreEqual('-', response[0]);
99+
ClassicAssert.AreEqual("-ERR unknown command\r\n", response);
98100

99101
// Test ordinary commands
100102
response = await Send($"SET {key} {value}");
@@ -108,7 +110,7 @@ public async Task InlineCommandParseTest()
108110

109111
// Test command failure in normal RESP doesn't interfere
110112
response = await Send("*1\r\n$3\r\nPIN");
111-
ClassicAssert.AreEqual('-', response[0]);
113+
ClassicAssert.AreEqual("-ERR unknown command\r\n", response);
112114

113115
// Test quit
114116
response = await Send("QUIT");
@@ -137,7 +139,7 @@ public async Task InlineCommandEscapeTest()
137139

138140
// This should lead to quoting failure
139141
response = await Send(@"PING ""\\\""");
140-
ClassicAssert.AreEqual('-', response[0]);
142+
ClassicAssert.AreEqual("-ERR Protocol error: unbalanced quotes in request\r\n", response);
141143
// This should work
142144
response = await Send(@"PING ""\\\\""");
143145
ClassicAssert.AreEqual("$2\r\n\\\\\r\n", response);
@@ -158,6 +160,7 @@ public async Task InlineCommandEscapeTest()
158160
// Test escapes in command position
159161
response = await Send(@"""\x50\x49\x4E\x47""");
160162
ClassicAssert.AreEqual("+PONG\r\n", response);
163+
// Test escapes for lowercase characters
161164
response = await Send(@"""P\i\x6Eg""");
162165
ClassicAssert.AreEqual("+PONG\r\n", response);
163166

@@ -181,7 +184,7 @@ public async Task InlineCommandQuoteTest()
181184
// We need to test failures too to be sure readHead is reset right,
182185
// and that there are no leftovers that would interfere with future commands.
183186
response = await Send("PING 'unfinished quote");
184-
ClassicAssert.AreEqual('-', response[0]);
187+
ClassicAssert.AreEqual("-ERR Protocol error: unbalanced quotes in request\r\n", response);
185188

186189
// Test empty and short strings
187190
response = await Send("ECHO ''");
@@ -191,7 +194,7 @@ public async Task InlineCommandQuoteTest()
191194
ClassicAssert.AreEqual("$1\r\na\r\n", response);
192195

193196
// We can even accept commands formed like this
194-
response = await Send("\"PING\"\tword ");
197+
response = await Send("\"PING\" word");
195198
ClassicAssert.AreEqual("$4\r\nword\r\n", response);
196199
response = await Send("PINg \"hello 'world'!\"");
197200
ClassicAssert.AreEqual("$14\r\nhello 'world'!\r\n", response);
@@ -202,5 +205,60 @@ public async Task InlineCommandQuoteTest()
202205
response = await Send("PING '\"'\"''");
203206
ClassicAssert.AreEqual("$4\r\n\"'\"'\r\n", response);
204207
}
208+
209+
[Test]
210+
public async Task InlineCommandShortlinesTest()
211+
{
212+
var oldTimeout = client.ReceiveTimeout;
213+
client.ReceiveTimeout = 100;
214+
215+
await client.ConnectAsync(TestUtils.EndPoint);
216+
217+
_ = await client.SendAsync(Encoding.ASCII.GetBytes("\r\n"));
218+
try
219+
{
220+
_ = client.Receive(buffer);
221+
Assert.Fail("This should timeout since buffer is not long enough");
222+
}
223+
catch (SocketException ex)
224+
{
225+
// We expect nothing to be emitted.
226+
ClassicAssert.AreEqual(SocketError.TimedOut, ex.SocketErrorCode);
227+
}
228+
229+
_ = await client.SendAsync(Encoding.ASCII.GetBytes("PI"));
230+
try
231+
{
232+
_ = client.Receive(buffer);
233+
Assert.Fail("This should timeout since buffer is not long enough");
234+
}
235+
catch (SocketException ex)
236+
{
237+
// We expect nothing to be emitted.
238+
ClassicAssert.AreEqual(SocketError.TimedOut, ex.SocketErrorCode);
239+
}
240+
241+
// Because there was no linefeed separator for "PI", we should be able to
242+
// complete the command.
243+
var response = await Send("NG", "\n");
244+
ClassicAssert.AreEqual("+PONG\r\n", response);
245+
246+
_ = await client.SendAsync(Encoding.ASCII.GetBytes("A\r\n"));
247+
try
248+
{
249+
_ = client.Receive(buffer);
250+
Assert.Fail("This should timeout since buffer is not long enough");
251+
}
252+
catch (SocketException ex)
253+
{
254+
// We expect nothing to be emitted due to minimum processing length.
255+
ClassicAssert.AreEqual(SocketError.TimedOut, ex.SocketErrorCode);
256+
}
257+
258+
response = await Send("PING");
259+
ClassicAssert.AreEqual("+PONG\r\n", response);
260+
261+
client.ReceiveTimeout = oldTimeout;
262+
}
205263
}
206264
}

0 commit comments

Comments
 (0)