1// +build int 2 3package main 4 5import ( 6 "strings" 7 "testing" 8 "time" 9) 10 11func TestKeys(t *testing.T) { 12 testRaw(t, func(c *client) { 13 c.Do("SET", "one", "1") 14 c.Do("SET", "two", "2") 15 c.Do("SET", "three", "3") 16 c.Do("SET", "four", "4") 17 c.DoSorted("KEYS", `*o*`) 18 c.DoSorted("KEYS", `t??`) 19 c.DoSorted("KEYS", `t?*`) 20 c.DoSorted("KEYS", `*`) 21 c.DoSorted("KEYS", `t*`) 22 c.DoSorted("KEYS", `t\*`) 23 c.DoSorted("KEYS", `[tf]*`) 24 25 // zero length key 26 c.Do("SET", "", "nothing") 27 c.Do("GET", "") 28 29 // Simple failure cases 30 c.Do("KEYS") 31 c.Do("KEYS", "foo", "bar") 32 }) 33 34 testRaw(t, func(c *client) { 35 c.Do("SET", "[one]", "1") 36 c.Do("SET", "two", "2") 37 c.DoSorted("KEYS", `[\[o]*`) 38 c.DoSorted("KEYS", `\[*`) 39 c.DoSorted("KEYS", `*o*`) 40 c.DoSorted("KEYS", `[]*`) // nothing 41 }) 42} 43 44func TestRandom(t *testing.T) { 45 testRaw(t, func(c *client) { 46 c.Do("RANDOMKEY") 47 // A random key from a DB with a single key. We can test that. 48 c.Do("SET", "one", "1") 49 c.Do("RANDOMKEY") 50 51 // Simple failure cases 52 c.Do("RANDOMKEY", "bar") 53 }) 54} 55 56func TestUnknownCommand(t *testing.T) { 57 testRaw(t, func(c *client) { 58 c.Do("nosuch") 59 c.Do("noSUCH") 60 c.Do("noSUCH", "1", "2", "3") 61 }) 62} 63 64func TestQuit(t *testing.T) { 65 testRaw(t, func(c *client) { 66 c.Do("QUIT") 67 }) 68} 69 70func TestExists(t *testing.T) { 71 testRaw(t, func(c *client) { 72 c.Do("SET", "a", "3") 73 c.Do("HSET", "b", "c", "d") 74 c.Do("EXISTS", "a", "b") 75 c.Do("EXISTS", "a", "b", "q") 76 c.Do("EXISTS", "a", "b", "b", "b", "a", "q") 77 78 // Error cases 79 c.Do("EXISTS") 80 }) 81} 82 83func TestRename(t *testing.T) { 84 testRaw(t, func(c *client) { 85 // No 'a' key 86 c.Do("RENAME", "a", "b") 87 88 // Move a key with the TTL. 89 c.Do("SET", "a", "3") 90 c.Do("EXPIRE", "a", "123") 91 c.Do("SET", "b", "12") 92 c.Do("RENAME", "a", "b") 93 c.Do("EXISTS", "a") 94 c.Do("GET", "a") 95 c.Do("TYPE", "a") 96 c.Do("TTL", "a") 97 c.Do("EXISTS", "b") 98 c.Do("GET", "b") 99 c.Do("TYPE", "b") 100 c.Do("TTL", "b") 101 102 // move a key without TTL 103 c.Do("SET", "nottl", "3") 104 c.Do("RENAME", "nottl", "stillnottl") 105 c.Do("TTL", "nottl") 106 c.Do("TTL", "stillnottl") 107 108 // Error cases 109 c.Do("RENAME") 110 c.Do("RENAME", "a") 111 c.Do("RENAME", "a", "b", "toomany") 112 }) 113} 114 115func TestRenamenx(t *testing.T) { 116 testRaw(t, func(c *client) { 117 // No 'a' key 118 c.Do("RENAMENX", "a", "b") 119 120 c.Do("SET", "a", "value") 121 c.Do("SET", "str", "value") 122 c.Do("RENAMENX", "a", "str") 123 c.Do("EXISTS", "a") 124 c.Do("EXISTS", "str") 125 c.Do("GET", "a") 126 c.Do("GET", "str") 127 128 c.Do("RENAMENX", "a", "nosuch") 129 c.Do("EXISTS", "a") 130 c.Do("EXISTS", "nosuch") 131 132 // Error cases 133 c.Do("RENAMENX") 134 c.Do("RENAMENX", "a") 135 c.Do("RENAMENX", "a", "b", "toomany") 136 }) 137} 138 139func TestScan(t *testing.T) { 140 testRaw(t, func(c *client) { 141 // No keys yet 142 c.Do("SCAN", "0") 143 144 c.Do("SET", "key", "value") 145 c.Do("SCAN", "0") 146 c.Do("SCAN", "0", "COUNT", "12") 147 c.Do("SCAN", "0", "cOuNt", "12") 148 149 c.Do("SET", "anotherkey", "value") 150 c.Do("SCAN", "0", "MATCH", "anoth*") 151 c.Do("SCAN", "0", "MATCH", "anoth*", "COUNT", "100") 152 c.Do("SCAN", "0", "COUNT", "100", "MATCH", "anoth*") 153 154 // Can't really test multiple keys. 155 // c.Do("SET", "key2", "value2") 156 // c.Do("SCAN", "0") 157 158 // Error cases 159 c.Do("SCAN") 160 c.Do("SCAN", "noint") 161 c.Do("SCAN", "0", "COUNT", "noint") 162 c.Do("SCAN", "0", "COUNT") 163 c.Do("SCAN", "0", "MATCH") 164 c.Do("SCAN", "0", "garbage") 165 c.Do("SCAN", "0", "COUNT", "12", "MATCH", "foo", "garbage") 166 }) 167} 168 169func TestFastForward(t *testing.T) { 170 testRaw(t, func(c *client) { 171 c.Do("SET", "key1", "value") 172 c.Do("SET", "key", "value", "PX", "100") 173 c.DoSorted("KEYS", "*") 174 time.Sleep(200 * time.Millisecond) 175 c.miniredis.FastForward(200 * time.Millisecond) 176 c.DoSorted("KEYS", "*") 177 }) 178 179 testRaw(t, func(c *client) { 180 c.Do("SET", "key1", "value", "PX", "-100") 181 c.Do("SET", "key2", "value", "EX", "-100") 182 c.Do("SET", "key3", "value", "EX", "0") 183 c.DoSorted("KEYS", "*") 184 185 c.Do("SET", "key4", "value") 186 c.DoSorted("KEYS", "*") 187 c.Do("EXPIRE", "key4", "-100") 188 c.DoSorted("KEYS", "*") 189 190 c.Do("SET", "key4", "value") 191 c.DoSorted("KEYS", "*") 192 c.Do("EXPIRE", "key4", "0") 193 c.DoSorted("KEYS", "*") 194 }) 195} 196 197func TestProto(t *testing.T) { 198 testRaw(t, func(c *client) { 199 c.Do("ECHO", strings.Repeat("X", 1<<24)) 200 }) 201} 202 203func TestSwapdb(t *testing.T) { 204 testRaw(t, func(c *client) { 205 c.Do("SET", "key1", "val1") 206 c.Do("SWAPDB", "0", "1") 207 c.Do("SELECT", "1") 208 c.Do("GET", "key1") 209 210 c.Do("SWAPDB", "1", "1") 211 c.Do("GET", "key1") 212 213 c.Do("SWAPDB") 214 c.Do("SWAPDB", "1") 215 c.Do("SWAPDB", "1", "2", "3") 216 c.Do("SWAPDB", "foo", "2") 217 c.Do("SWAPDB", "1", "bar") 218 c.Do("SWAPDB", "foo", "bar") 219 c.Do("SWAPDB", "-1", "2") 220 c.Do("SWAPDB", "1", "-2") 221 // c.Do("SWAPDB", "1", "1000") // miniredis has no upperlimit 222 }) 223 224 // SWAPDB with transactions 225 testRaw2(t, func(c1, c2 *client) { 226 c1.Do("SET", "foo", "foooooo") 227 228 c1.Do("MULTI") 229 c1.Do("SWAPDB", "0", "2") 230 c1.Do("GET", "foo") 231 c2.Do("GET", "foo") 232 233 c1.Do("EXEC") 234 c1.Do("GET", "foo") 235 c2.Do("GET", "foo") 236 }) 237} 238 239func TestDel(t *testing.T) { 240 testRaw(t, func(c *client) { 241 c.Do("SET", "one", "1") 242 c.Do("SET", "two", "2") 243 c.Do("SET", "three", "3") 244 c.Do("SET", "four", "4") 245 c.Do("DEL", "one") 246 c.DoSorted("KEYS", "*") 247 248 c.Do("DEL", "twoooo") 249 c.DoSorted("KEYS", "*") 250 251 c.Do("DEL", "two", "four") 252 c.DoSorted("KEYS", "*") 253 254 c.Do("DEL") 255 c.DoSorted("KEYS", "*") 256 }) 257} 258 259func TestUnlink(t *testing.T) { 260 testRaw(t, func(c *client) { 261 c.Do("SET", "one", "1") 262 c.Do("SET", "two", "2") 263 c.Do("SET", "three", "3") 264 c.Do("SET", "four", "4") 265 c.Do("UNLINK", "one") 266 c.DoSorted("KEYS", "*") 267 268 c.Do("UNLINK", "twoooo") 269 c.DoSorted("KEYS", "*") 270 271 c.Do("UNLINK", "two", "four") 272 c.DoSorted("KEYS", "*") 273 274 c.Do("UNLINK") 275 c.DoSorted("KEYS", "*") 276 }) 277} 278 279func TestTouch(t *testing.T) { 280 testRaw(t, func(c *client) { 281 c.Do("SET", "a", "some value") 282 c.Do("TOUCH", "a") 283 c.Do("GET", "a") 284 c.Do("TTL", "a") 285 286 c.Do("TOUCH", "a", "foobar", "a") 287 288 c.Do("TOUCH") 289 }) 290} 291 292func TestPersist(t *testing.T) { 293 testRaw(t, func(c *client) { 294 c.Do("SET", "foo", "bar") 295 c.Do("EXPIRE", "foo", "12") 296 c.Do("TTL", "foo") 297 c.Do("PERSIST", "foo") 298 c.Do("TTL", "foo") 299 }) 300} 301