redis-server 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +38 -0
- data/README.md +33 -0
- data/bin/redis +114 -0
- data/redis/Makefile +5 -0
- data/redis/extconf.rb +3 -0
- data/redis/redis-2.2.11/00-RELEASENOTES +199 -0
- data/redis/redis-2.2.11/BUGS +1 -0
- data/redis/redis-2.2.11/CONTRIBUTING +13 -0
- data/redis/redis-2.2.11/COPYING +10 -0
- data/redis/redis-2.2.11/Changelog +1032 -0
- data/redis/redis-2.2.11/INSTALL +30 -0
- data/redis/redis-2.2.11/Makefile +22 -0
- data/redis/redis-2.2.11/README +83 -0
- data/redis/redis-2.2.11/TODO +4 -0
- data/redis/redis-2.2.11/client-libraries/README +11 -0
- data/redis/redis-2.2.11/deps/hiredis/COPYING +10 -0
- data/redis/redis-2.2.11/deps/hiredis/Makefile +115 -0
- data/redis/redis-2.2.11/deps/hiredis/README.md +311 -0
- data/redis/redis-2.2.11/deps/hiredis/TODO +2 -0
- data/redis/redis-2.2.11/deps/hiredis/adapters/ae.h +95 -0
- data/redis/redis-2.2.11/deps/hiredis/adapters/libev.h +113 -0
- data/redis/redis-2.2.11/deps/hiredis/adapters/libevent.h +76 -0
- data/redis/redis-2.2.11/deps/hiredis/async.c +321 -0
- data/redis/redis-2.2.11/deps/hiredis/async.h +112 -0
- data/redis/redis-2.2.11/deps/hiredis/example-ae.c +53 -0
- data/redis/redis-2.2.11/deps/hiredis/example-libev.c +47 -0
- data/redis/redis-2.2.11/deps/hiredis/example-libevent.c +48 -0
- data/redis/redis-2.2.11/deps/hiredis/example.c +67 -0
- data/redis/redis-2.2.11/deps/hiredis/fmacros.h +15 -0
- data/redis/redis-2.2.11/deps/hiredis/hiredis.c +1058 -0
- data/redis/redis-2.2.11/deps/hiredis/hiredis.h +170 -0
- data/redis/redis-2.2.11/deps/hiredis/net.c +170 -0
- data/redis/redis-2.2.11/deps/hiredis/net.h +43 -0
- data/redis/redis-2.2.11/deps/hiredis/sds.c +479 -0
- data/redis/redis-2.2.11/deps/hiredis/sds.h +77 -0
- data/redis/redis-2.2.11/deps/hiredis/test.c +479 -0
- data/redis/redis-2.2.11/deps/hiredis/util.h +40 -0
- data/redis/redis-2.2.11/deps/linenoise/Makefile +10 -0
- data/redis/redis-2.2.11/deps/linenoise/README.markdown +45 -0
- data/redis/redis-2.2.11/deps/linenoise/example.c +27 -0
- data/redis/redis-2.2.11/deps/linenoise/linenoise.c +609 -0
- data/redis/redis-2.2.11/deps/linenoise/linenoise.h +55 -0
- data/redis/redis-2.2.11/design-documents/REDIS-CLUSTER +214 -0
- data/redis/redis-2.2.11/design-documents/REDIS-CLUSTER-2 +343 -0
- data/redis/redis-2.2.11/doc/AppendCommand.html +48 -0
- data/redis/redis-2.2.11/doc/AppendOnlyFileHowto.html +41 -0
- data/redis/redis-2.2.11/doc/AuthCommand.html +39 -0
- data/redis/redis-2.2.11/doc/Benchmarks.html +129 -0
- data/redis/redis-2.2.11/doc/BgrewriteaofCommand.html +41 -0
- data/redis/redis-2.2.11/doc/BgsaveCommand.html +39 -0
- data/redis/redis-2.2.11/doc/BlpopCommand.html +51 -0
- data/redis/redis-2.2.11/doc/BrpoplpushCommand.html +39 -0
- data/redis/redis-2.2.11/doc/CommandReference.html +47 -0
- data/redis/redis-2.2.11/doc/Comparisons.html +42 -0
- data/redis/redis-2.2.11/doc/ConfigCommand.html +76 -0
- data/redis/redis-2.2.11/doc/Configuration.html +38 -0
- data/redis/redis-2.2.11/doc/ConnectionHandlingSidebar.html +36 -0
- data/redis/redis-2.2.11/doc/ControlCommandsSidebar.html +36 -0
- data/redis/redis-2.2.11/doc/Credits.html +38 -0
- data/redis/redis-2.2.11/doc/DbsizeCommand.html +38 -0
- data/redis/redis-2.2.11/doc/DelCommand.html +41 -0
- data/redis/redis-2.2.11/doc/DesignPatterns.html +37 -0
- data/redis/redis-2.2.11/doc/EventLibray.html +44 -0
- data/redis/redis-2.2.11/doc/ExistsCommand.html +42 -0
- data/redis/redis-2.2.11/doc/ExpireCommand.html +96 -0
- data/redis/redis-2.2.11/doc/FAQ.html +70 -0
- data/redis/redis-2.2.11/doc/Features.html +38 -0
- data/redis/redis-2.2.11/doc/FlushallCommand.html +39 -0
- data/redis/redis-2.2.11/doc/FlushdbCommand.html +39 -0
- data/redis/redis-2.2.11/doc/FromSqlToDataStructures.html +37 -0
- data/redis/redis-2.2.11/doc/GenericCommandsSidebar.html +36 -0
- data/redis/redis-2.2.11/doc/GetCommand.html +39 -0
- data/redis/redis-2.2.11/doc/GetbitCommand.html +39 -0
- data/redis/redis-2.2.11/doc/GetsetCommand.html +38 -0
- data/redis/redis-2.2.11/doc/HackingStrings.html +83 -0
- data/redis/redis-2.2.11/doc/HashCommandsSidebar.html +36 -0
- data/redis/redis-2.2.11/doc/Hashes.html +37 -0
- data/redis/redis-2.2.11/doc/HdelCommand.html +39 -0
- data/redis/redis-2.2.11/doc/HexistsCommand.html +39 -0
- data/redis/redis-2.2.11/doc/HgetCommand.html +39 -0
- data/redis/redis-2.2.11/doc/HgetallCommand.html +40 -0
- data/redis/redis-2.2.11/doc/HincrbyCommand.html +45 -0
- data/redis/redis-2.2.11/doc/HlenCommand.html +38 -0
- data/redis/redis-2.2.11/doc/HmgetCommand.html +40 -0
- data/redis/redis-2.2.11/doc/HmsetCommand.html +40 -0
- data/redis/redis-2.2.11/doc/HsetCommand.html +40 -0
- data/redis/redis-2.2.11/doc/HsetnxCommand.html +41 -0
- data/redis/redis-2.2.11/doc/IncrCommand.html +43 -0
- data/redis/redis-2.2.11/doc/InfoCommand.html +48 -0
- data/redis/redis-2.2.11/doc/IntroductionToRedisDataTypes.html +152 -0
- data/redis/redis-2.2.11/doc/KeysCommand.html +43 -0
- data/redis/redis-2.2.11/doc/LastsaveCommand.html +39 -0
- data/redis/redis-2.2.11/doc/LindexCommand.html +40 -0
- data/redis/redis-2.2.11/doc/ListCommandsSidebar.html +36 -0
- data/redis/redis-2.2.11/doc/Lists.html +42 -0
- data/redis/redis-2.2.11/doc/LlenCommand.html +41 -0
- data/redis/redis-2.2.11/doc/LpopCommand.html +41 -0
- data/redis/redis-2.2.11/doc/LrangeCommand.html +47 -0
- data/redis/redis-2.2.11/doc/LremCommand.html +41 -0
- data/redis/redis-2.2.11/doc/LsetCommand.html +38 -0
- data/redis/redis-2.2.11/doc/LtrimCommand.html +47 -0
- data/redis/redis-2.2.11/doc/MgetCommand.html +52 -0
- data/redis/redis-2.2.11/doc/MonitorCommand.html +63 -0
- data/redis/redis-2.2.11/doc/MoveCommand.html +42 -0
- data/redis/redis-2.2.11/doc/MsetCommand.html +44 -0
- data/redis/redis-2.2.11/doc/MultiExecCommand.html +166 -0
- data/redis/redis-2.2.11/doc/NonexistentCommands.html +51 -0
- data/redis/redis-2.2.11/doc/ObjectHashMappers.html +39 -0
- data/redis/redis-2.2.11/doc/Pipelining.html +36 -0
- data/redis/redis-2.2.11/doc/ProgrammingExamples.html +38 -0
- data/redis/redis-2.2.11/doc/ProtocolSpecification.html +137 -0
- data/redis/redis-2.2.11/doc/PublishSubscribe.html +115 -0
- data/redis/redis-2.2.11/doc/QuickStart.html +68 -0
- data/redis/redis-2.2.11/doc/QuitCommand.html +38 -0
- data/redis/redis-2.2.11/doc/README.html +119 -0
- data/redis/redis-2.2.11/doc/RandomkeyCommand.html +39 -0
- data/redis/redis-2.2.11/doc/Redis0100ChangeLog.html +67 -0
- data/redis/redis-2.2.11/doc/Redis0900ChangeLog.html +56 -0
- data/redis/redis-2.2.11/doc/RedisBigData.html +61 -0
- data/redis/redis-2.2.11/doc/RedisCLI.html +37 -0
- data/redis/redis-2.2.11/doc/RedisEventLibrary.html +70 -0
- data/redis/redis-2.2.11/doc/RedisGuides.html +37 -0
- data/redis/redis-2.2.11/doc/RedisInternals.html +38 -0
- data/redis/redis-2.2.11/doc/RedisPipelining.html +93 -0
- data/redis/redis-2.2.11/doc/RedisStatus.html +56 -0
- data/redis/redis-2.2.11/doc/Redis_1_2_0_Changelog.html +40 -0
- data/redis/redis-2.2.11/doc/Redis_2_0_0_Changelog.html +62 -0
- data/redis/redis-2.2.11/doc/Redis_2_0_Whats_new.html +59 -0
- data/redis/redis-2.2.11/doc/RenameCommand.html +39 -0
- data/redis/redis-2.2.11/doc/RenamenxCommand.html +42 -0
- data/redis/redis-2.2.11/doc/ReplicationHowto.html +43 -0
- data/redis/redis-2.2.11/doc/ReplyTypes.html +42 -0
- data/redis/redis-2.2.11/doc/RoadMap.html +38 -0
- data/redis/redis-2.2.11/doc/RpoplpushCommand.html +44 -0
- data/redis/redis-2.2.11/doc/RpushCommand.html +40 -0
- data/redis/redis-2.2.11/doc/SaddCommand.html +41 -0
- data/redis/redis-2.2.11/doc/SaveCommand.html +39 -0
- data/redis/redis-2.2.11/doc/ScardCommand.html +41 -0
- data/redis/redis-2.2.11/doc/SdiffCommand.html +45 -0
- data/redis/redis-2.2.11/doc/SdiffstoreCommand.html +38 -0
- data/redis/redis-2.2.11/doc/SelectCommand.html +39 -0
- data/redis/redis-2.2.11/doc/SetCommand.html +39 -0
- data/redis/redis-2.2.11/doc/SetCommandsSidebar.html +36 -0
- data/redis/redis-2.2.11/doc/SetbitCommand.html +45 -0
- data/redis/redis-2.2.11/doc/SetexCommand.html +42 -0
- data/redis/redis-2.2.11/doc/SetnxCommand.html +51 -0
- data/redis/redis-2.2.11/doc/SetrangeCommand.html +58 -0
- data/redis/redis-2.2.11/doc/Sets.html +36 -0
- data/redis/redis-2.2.11/doc/ShutdownCommand.html +39 -0
- data/redis/redis-2.2.11/doc/SideBar.html +36 -0
- data/redis/redis-2.2.11/doc/SinterCommand.html +40 -0
- data/redis/redis-2.2.11/doc/SinterstoreCommand.html +39 -0
- data/redis/redis-2.2.11/doc/SismemberCommand.html +42 -0
- data/redis/redis-2.2.11/doc/SlaveofCommand.html +41 -0
- data/redis/redis-2.2.11/doc/SmembersCommand.html +38 -0
- data/redis/redis-2.2.11/doc/SmoveCommand.html +44 -0
- data/redis/redis-2.2.11/doc/SortCommand.html +75 -0
- data/redis/redis-2.2.11/doc/SortedSetCommandsSidebar.html +36 -0
- data/redis/redis-2.2.11/doc/SortedSets.html +36 -0
- data/redis/redis-2.2.11/doc/Speed.html +38 -0
- data/redis/redis-2.2.11/doc/SponsorshipHistory.html +38 -0
- data/redis/redis-2.2.11/doc/SpopCommand.html +40 -0
- data/redis/redis-2.2.11/doc/SrandmemberCommand.html +40 -0
- data/redis/redis-2.2.11/doc/SremCommand.html +42 -0
- data/redis/redis-2.2.11/doc/StringCommandsSidebar.html +36 -0
- data/redis/redis-2.2.11/doc/Strings.html +37 -0
- data/redis/redis-2.2.11/doc/StrlenCommand.html +39 -0
- data/redis/redis-2.2.11/doc/SubstrCommand.html +52 -0
- data/redis/redis-2.2.11/doc/SunionCommand.html +40 -0
- data/redis/redis-2.2.11/doc/SunionstoreCommand.html +38 -0
- data/redis/redis-2.2.11/doc/SupportedLanguages.html +60 -0
- data/redis/redis-2.2.11/doc/SupportedPlatforms.html +37 -0
- data/redis/redis-2.2.11/doc/TemplateCommand.html +38 -0
- data/redis/redis-2.2.11/doc/TtlCommand.html +38 -0
- data/redis/redis-2.2.11/doc/TwitterAlikeExample.html +250 -0
- data/redis/redis-2.2.11/doc/TypeCommand.html +46 -0
- data/redis/redis-2.2.11/doc/UnstableSource.html +39 -0
- data/redis/redis-2.2.11/doc/VirtualMemorySpecification.html +156 -0
- data/redis/redis-2.2.11/doc/VirtualMemoryUserGuide.html +66 -0
- data/redis/redis-2.2.11/doc/ZaddCommand.html +43 -0
- data/redis/redis-2.2.11/doc/ZcardCommand.html +41 -0
- data/redis/redis-2.2.11/doc/ZincrbyCommand.html +42 -0
- data/redis/redis-2.2.11/doc/ZrangeCommand.html +42 -0
- data/redis/redis-2.2.11/doc/ZrangebyscoreCommand.html +77 -0
- data/redis/redis-2.2.11/doc/ZrankCommand.html +43 -0
- data/redis/redis-2.2.11/doc/ZremCommand.html +42 -0
- data/redis/redis-2.2.11/doc/ZremrangebyrankCommand.html +39 -0
- data/redis/redis-2.2.11/doc/ZremrangebyscoreCommand.html +39 -0
- data/redis/redis-2.2.11/doc/ZscoreCommand.html +41 -0
- data/redis/redis-2.2.11/doc/ZunionCommand.html +42 -0
- data/redis/redis-2.2.11/doc/ZunionstoreCommand.html +43 -0
- data/redis/redis-2.2.11/doc/index.html +43 -0
- data/redis/redis-2.2.11/doc/redis.png +0 -0
- data/redis/redis-2.2.11/doc/style.css +25 -0
- data/redis/redis-2.2.11/redis.conf +417 -0
- data/redis/redis-2.2.11/src/Makefile +177 -0
- data/redis/redis-2.2.11/src/adlist.c +325 -0
- data/redis/redis-2.2.11/src/adlist.h +92 -0
- data/redis/redis-2.2.11/src/ae.c +390 -0
- data/redis/redis-2.2.11/src/ae.h +117 -0
- data/redis/redis-2.2.11/src/ae_epoll.c +91 -0
- data/redis/redis-2.2.11/src/ae_kqueue.c +93 -0
- data/redis/redis-2.2.11/src/ae_select.c +72 -0
- data/redis/redis-2.2.11/src/anet.c +347 -0
- data/redis/redis-2.2.11/src/anet.h +57 -0
- data/redis/redis-2.2.11/src/aof.c +675 -0
- data/redis/redis-2.2.11/src/config.c +627 -0
- data/redis/redis-2.2.11/src/config.h +64 -0
- data/redis/redis-2.2.11/src/db.c +543 -0
- data/redis/redis-2.2.11/src/debug.c +314 -0
- data/redis/redis-2.2.11/src/dict.c +721 -0
- data/redis/redis-2.2.11/src/dict.h +156 -0
- data/redis/redis-2.2.11/src/fmacros.h +15 -0
- data/redis/redis-2.2.11/src/help.h +638 -0
- data/redis/redis-2.2.11/src/intset.c +422 -0
- data/redis/redis-2.2.11/src/intset.h +19 -0
- data/redis/redis-2.2.11/src/lzf.h +100 -0
- data/redis/redis-2.2.11/src/lzfP.h +159 -0
- data/redis/redis-2.2.11/src/lzf_c.c +295 -0
- data/redis/redis-2.2.11/src/lzf_d.c +150 -0
- data/redis/redis-2.2.11/src/mkreleasehdr.sh +9 -0
- data/redis/redis-2.2.11/src/multi.c +268 -0
- data/redis/redis-2.2.11/src/networking.c +899 -0
- data/redis/redis-2.2.11/src/object.c +484 -0
- data/redis/redis-2.2.11/src/pqsort.c +197 -0
- data/redis/redis-2.2.11/src/pqsort.h +15 -0
- data/redis/redis-2.2.11/src/pubsub.c +267 -0
- data/redis/redis-2.2.11/src/rdb.c +1020 -0
- data/redis/redis-2.2.11/src/redis-benchmark.c +530 -0
- data/redis/redis-2.2.11/src/redis-check-aof.c +185 -0
- data/redis/redis-2.2.11/src/redis-check-dump.c +681 -0
- data/redis/redis-2.2.11/src/redis-cli.c +773 -0
- data/redis/redis-2.2.11/src/redis.c +1677 -0
- data/redis/redis-2.2.11/src/redis.h +1022 -0
- data/redis/redis-2.2.11/src/release.c +13 -0
- data/redis/redis-2.2.11/src/replication.c +557 -0
- data/redis/redis-2.2.11/src/sds.c +639 -0
- data/redis/redis-2.2.11/src/sds.h +78 -0
- data/redis/redis-2.2.11/src/sha1.c +276 -0
- data/redis/redis-2.2.11/src/sha1.h +17 -0
- data/redis/redis-2.2.11/src/solarisfixes.h +22 -0
- data/redis/redis-2.2.11/src/sort.c +389 -0
- data/redis/redis-2.2.11/src/syncio.c +154 -0
- data/redis/redis-2.2.11/src/t_hash.c +476 -0
- data/redis/redis-2.2.11/src/t_list.c +986 -0
- data/redis/redis-2.2.11/src/t_set.c +610 -0
- data/redis/redis-2.2.11/src/t_string.c +438 -0
- data/redis/redis-2.2.11/src/t_zset.c +1084 -0
- data/redis/redis-2.2.11/src/testhelp.h +54 -0
- data/redis/redis-2.2.11/src/util.c +243 -0
- data/redis/redis-2.2.11/src/valgrind.sup +5 -0
- data/redis/redis-2.2.11/src/version.h +1 -0
- data/redis/redis-2.2.11/src/vm.c +1149 -0
- data/redis/redis-2.2.11/src/ziplist.c +1323 -0
- data/redis/redis-2.2.11/src/ziplist.h +15 -0
- data/redis/redis-2.2.11/src/zipmap.c +455 -0
- data/redis/redis-2.2.11/src/zipmap.h +48 -0
- data/redis/redis-2.2.11/src/zmalloc.c +278 -0
- data/redis/redis-2.2.11/src/zmalloc.h +47 -0
- data/redis/redis-2.2.11/tests/assets/default.conf +308 -0
- data/redis/redis-2.2.11/tests/integration/aof.tcl +104 -0
- data/redis/redis-2.2.11/tests/integration/redis-cli.tcl +208 -0
- data/redis/redis-2.2.11/tests/integration/replication.tcl +98 -0
- data/redis/redis-2.2.11/tests/support/redis.tcl +241 -0
- data/redis/redis-2.2.11/tests/support/server.tcl +294 -0
- data/redis/redis-2.2.11/tests/support/test.tcl +190 -0
- data/redis/redis-2.2.11/tests/support/tmpfile.tcl +15 -0
- data/redis/redis-2.2.11/tests/support/util.tcl +296 -0
- data/redis/redis-2.2.11/tests/test_helper.tcl +221 -0
- data/redis/redis-2.2.11/tests/unit/auth.tcl +15 -0
- data/redis/redis-2.2.11/tests/unit/basic.tcl +616 -0
- data/redis/redis-2.2.11/tests/unit/cas.tcl +135 -0
- data/redis/redis-2.2.11/tests/unit/expire.tcl +74 -0
- data/redis/redis-2.2.11/tests/unit/other.tcl +240 -0
- data/redis/redis-2.2.11/tests/unit/printver.tcl +6 -0
- data/redis/redis-2.2.11/tests/unit/protocol.tcl +62 -0
- data/redis/redis-2.2.11/tests/unit/pubsub.tcl +195 -0
- data/redis/redis-2.2.11/tests/unit/quit.tcl +40 -0
- data/redis/redis-2.2.11/tests/unit/sort.tcl +189 -0
- data/redis/redis-2.2.11/tests/unit/type/hash.tcl +300 -0
- data/redis/redis-2.2.11/tests/unit/type/list.tcl +819 -0
- data/redis/redis-2.2.11/tests/unit/type/set.tcl +334 -0
- data/redis/redis-2.2.11/tests/unit/type/zset.tcl +587 -0
- data/redis/redis-2.2.11/utils/build-static-symbols.tcl +22 -0
- data/redis/redis-2.2.11/utils/generate-command-help.rb +112 -0
- data/redis/redis-2.2.11/utils/mktarball.sh +13 -0
- data/redis/redis-2.2.11/utils/redis-copy.rb +78 -0
- data/redis/redis-2.2.11/utils/redis-sha1.rb +52 -0
- data/redis/redis-2.2.11/utils/redis_init_script +42 -0
- metadata +362 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
/* SDSLib, A C dynamic strings library
|
2
|
+
*
|
3
|
+
* Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are met:
|
8
|
+
*
|
9
|
+
* * Redistributions of source code must retain the above copyright notice,
|
10
|
+
* this list of conditions and the following disclaimer.
|
11
|
+
* * Redistributions in binary form must reproduce the above copyright
|
12
|
+
* notice, this list of conditions and the following disclaimer in the
|
13
|
+
* documentation and/or other materials provided with the distribution.
|
14
|
+
* * Neither the name of Redis nor the names of its contributors may be used
|
15
|
+
* to endorse or promote products derived from this software without
|
16
|
+
* specific prior written permission.
|
17
|
+
*
|
18
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
23
|
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
24
|
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
25
|
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
26
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
27
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
28
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
*/
|
30
|
+
|
31
|
+
#ifndef __SDS_H
|
32
|
+
#define __SDS_H
|
33
|
+
|
34
|
+
#include <sys/types.h>
|
35
|
+
#include <stdarg.h>
|
36
|
+
|
37
|
+
typedef char *sds;
|
38
|
+
|
39
|
+
struct sdshdr {
|
40
|
+
int len;
|
41
|
+
int free;
|
42
|
+
char buf[];
|
43
|
+
};
|
44
|
+
|
45
|
+
sds sdsnewlen(const void *init, size_t initlen);
|
46
|
+
sds sdsnew(const char *init);
|
47
|
+
sds sdsempty();
|
48
|
+
size_t sdslen(const sds s);
|
49
|
+
sds sdsdup(const sds s);
|
50
|
+
void sdsfree(sds s);
|
51
|
+
size_t sdsavail(sds s);
|
52
|
+
sds sdscatlen(sds s, const void *t, size_t len);
|
53
|
+
sds sdscat(sds s, const char *t);
|
54
|
+
sds sdscpylen(sds s, char *t, size_t len);
|
55
|
+
sds sdscpy(sds s, char *t);
|
56
|
+
|
57
|
+
sds sdscatvprintf(sds s, const char *fmt, va_list ap);
|
58
|
+
#ifdef __GNUC__
|
59
|
+
sds sdscatprintf(sds s, const char *fmt, ...)
|
60
|
+
__attribute__((format(printf, 2, 3)));
|
61
|
+
#else
|
62
|
+
sds sdscatprintf(sds s, const char *fmt, ...);
|
63
|
+
#endif
|
64
|
+
|
65
|
+
sds sdstrim(sds s, const char *cset);
|
66
|
+
sds sdsrange(sds s, int start, int end);
|
67
|
+
void sdsupdatelen(sds s);
|
68
|
+
int sdscmp(sds s1, sds s2);
|
69
|
+
sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count);
|
70
|
+
void sdsfreesplitres(sds *tokens, int count);
|
71
|
+
void sdstolower(sds s);
|
72
|
+
void sdstoupper(sds s);
|
73
|
+
sds sdsfromlonglong(long long value);
|
74
|
+
sds sdscatrepr(sds s, char *p, size_t len);
|
75
|
+
sds *sdssplitargs(char *line, int *argc);
|
76
|
+
|
77
|
+
#endif
|
@@ -0,0 +1,479 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <stdlib.h>
|
3
|
+
#include <string.h>
|
4
|
+
#include <strings.h>
|
5
|
+
#include <sys/time.h>
|
6
|
+
#include <assert.h>
|
7
|
+
#include <unistd.h>
|
8
|
+
#include <signal.h>
|
9
|
+
|
10
|
+
#include "hiredis.h"
|
11
|
+
|
12
|
+
/* The following lines make up our testing "framework" :) */
|
13
|
+
static int tests = 0, fails = 0;
|
14
|
+
#define test(_s) { printf("#%02d ", ++tests); printf(_s); }
|
15
|
+
#define test_cond(_c) if(_c) printf("PASSED\n"); else {printf("FAILED\n"); fails++;}
|
16
|
+
|
17
|
+
static long long usec(void) {
|
18
|
+
struct timeval tv;
|
19
|
+
gettimeofday(&tv,NULL);
|
20
|
+
return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
|
21
|
+
}
|
22
|
+
|
23
|
+
static int use_unix = 0;
|
24
|
+
static redisContext *blocking_context = NULL;
|
25
|
+
static void __connect(redisContext **target) {
|
26
|
+
*target = blocking_context = (use_unix ?
|
27
|
+
redisConnectUnix("/tmp/redis.sock") : redisConnect((char*)"127.0.0.1", 6379));
|
28
|
+
if (blocking_context->err) {
|
29
|
+
printf("Connection error: %s\n", blocking_context->errstr);
|
30
|
+
exit(1);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
static void test_format_commands() {
|
35
|
+
char *cmd;
|
36
|
+
int len;
|
37
|
+
|
38
|
+
test("Format command without interpolation: ");
|
39
|
+
len = redisFormatCommand(&cmd,"SET foo bar");
|
40
|
+
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 &&
|
41
|
+
len == 4+4+(3+2)+4+(3+2)+4+(3+2));
|
42
|
+
free(cmd);
|
43
|
+
|
44
|
+
test("Format command with %%s string interpolation: ");
|
45
|
+
len = redisFormatCommand(&cmd,"SET %s %s","foo","bar");
|
46
|
+
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 &&
|
47
|
+
len == 4+4+(3+2)+4+(3+2)+4+(3+2));
|
48
|
+
free(cmd);
|
49
|
+
|
50
|
+
test("Format command with %%s and an empty string: ");
|
51
|
+
len = redisFormatCommand(&cmd,"SET %s %s","foo","");
|
52
|
+
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 &&
|
53
|
+
len == 4+4+(3+2)+4+(3+2)+4+(0+2));
|
54
|
+
free(cmd);
|
55
|
+
|
56
|
+
test("Format command with %%b string interpolation: ");
|
57
|
+
len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"b\0r",3);
|
58
|
+
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len) == 0 &&
|
59
|
+
len == 4+4+(3+2)+4+(3+2)+4+(3+2));
|
60
|
+
free(cmd);
|
61
|
+
|
62
|
+
test("Format command with %%b and an empty string: ");
|
63
|
+
len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"",0);
|
64
|
+
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 &&
|
65
|
+
len == 4+4+(3+2)+4+(3+2)+4+(0+2));
|
66
|
+
free(cmd);
|
67
|
+
|
68
|
+
test("Format command with literal %%: ");
|
69
|
+
len = redisFormatCommand(&cmd,"SET %% %%");
|
70
|
+
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$1\r\n%\r\n$1\r\n%\r\n",len) == 0 &&
|
71
|
+
len == 4+4+(3+2)+4+(1+2)+4+(1+2));
|
72
|
+
free(cmd);
|
73
|
+
|
74
|
+
test("Format command with printf-delegation (long long): ");
|
75
|
+
len = redisFormatCommand(&cmd,"key:%08lld",1234ll);
|
76
|
+
test_cond(strncmp(cmd,"*1\r\n$12\r\nkey:00001234\r\n",len) == 0 &&
|
77
|
+
len == 4+5+(12+2));
|
78
|
+
free(cmd);
|
79
|
+
|
80
|
+
test("Format command with printf-delegation (float): ");
|
81
|
+
len = redisFormatCommand(&cmd,"v:%06.1f",12.34f);
|
82
|
+
test_cond(strncmp(cmd,"*1\r\n$8\r\nv:0012.3\r\n",len) == 0 &&
|
83
|
+
len == 4+4+(8+2));
|
84
|
+
free(cmd);
|
85
|
+
|
86
|
+
test("Format command with printf-delegation and extra interpolation: ");
|
87
|
+
len = redisFormatCommand(&cmd,"key:%d %b",1234,"foo",3);
|
88
|
+
test_cond(strncmp(cmd,"*2\r\n$8\r\nkey:1234\r\n$3\r\nfoo\r\n",len) == 0 &&
|
89
|
+
len == 4+4+(8+2)+4+(3+2));
|
90
|
+
free(cmd);
|
91
|
+
|
92
|
+
test("Format command with wrong printf format and extra interpolation: ");
|
93
|
+
len = redisFormatCommand(&cmd,"key:%08p %b",1234,"foo",3);
|
94
|
+
test_cond(strncmp(cmd,"*2\r\n$6\r\nkey:8p\r\n$3\r\nfoo\r\n",len) == 0 &&
|
95
|
+
len == 4+4+(6+2)+4+(3+2));
|
96
|
+
free(cmd);
|
97
|
+
|
98
|
+
const char *argv[3];
|
99
|
+
argv[0] = "SET";
|
100
|
+
argv[1] = "foo\0xxx";
|
101
|
+
argv[2] = "bar";
|
102
|
+
size_t lens[3] = { 3, 7, 3 };
|
103
|
+
int argc = 3;
|
104
|
+
|
105
|
+
test("Format command by passing argc/argv without lengths: ");
|
106
|
+
len = redisFormatCommandArgv(&cmd,argc,argv,NULL);
|
107
|
+
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 &&
|
108
|
+
len == 4+4+(3+2)+4+(3+2)+4+(3+2));
|
109
|
+
free(cmd);
|
110
|
+
|
111
|
+
test("Format command by passing argc/argv with lengths: ");
|
112
|
+
len = redisFormatCommandArgv(&cmd,argc,argv,lens);
|
113
|
+
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 &&
|
114
|
+
len == 4+4+(3+2)+4+(7+2)+4+(3+2));
|
115
|
+
free(cmd);
|
116
|
+
}
|
117
|
+
|
118
|
+
static void test_blocking_connection() {
|
119
|
+
redisContext *c;
|
120
|
+
redisReply *reply;
|
121
|
+
int major, minor;
|
122
|
+
|
123
|
+
test("Returns error when host cannot be resolved: ");
|
124
|
+
c = redisConnect((char*)"idontexist.local", 6379);
|
125
|
+
test_cond(c->err == REDIS_ERR_OTHER &&
|
126
|
+
strcmp(c->errstr,"Can't resolve: idontexist.local") == 0);
|
127
|
+
redisFree(c);
|
128
|
+
|
129
|
+
test("Returns error when the port is not open: ");
|
130
|
+
c = redisConnect((char*)"localhost", 56380);
|
131
|
+
test_cond(c->err == REDIS_ERR_IO &&
|
132
|
+
strcmp(c->errstr,"Connection refused") == 0);
|
133
|
+
redisFree(c);
|
134
|
+
|
135
|
+
__connect(&c);
|
136
|
+
test("Is able to deliver commands: ");
|
137
|
+
reply = redisCommand(c,"PING");
|
138
|
+
test_cond(reply->type == REDIS_REPLY_STATUS &&
|
139
|
+
strcasecmp(reply->str,"pong") == 0)
|
140
|
+
freeReplyObject(reply);
|
141
|
+
|
142
|
+
/* Switch to DB 9 for testing, now that we know we can chat. */
|
143
|
+
reply = redisCommand(c,"SELECT 9");
|
144
|
+
freeReplyObject(reply);
|
145
|
+
|
146
|
+
/* Make sure the DB is emtpy */
|
147
|
+
reply = redisCommand(c,"DBSIZE");
|
148
|
+
if (reply->type != REDIS_REPLY_INTEGER || reply->integer != 0) {
|
149
|
+
printf("Database #9 is not empty, test can not continue\n");
|
150
|
+
exit(1);
|
151
|
+
}
|
152
|
+
freeReplyObject(reply);
|
153
|
+
|
154
|
+
test("Is a able to send commands verbatim: ");
|
155
|
+
reply = redisCommand(c,"SET foo bar");
|
156
|
+
test_cond (reply->type == REDIS_REPLY_STATUS &&
|
157
|
+
strcasecmp(reply->str,"ok") == 0)
|
158
|
+
freeReplyObject(reply);
|
159
|
+
|
160
|
+
test("%%s String interpolation works: ");
|
161
|
+
reply = redisCommand(c,"SET %s %s","foo","hello world");
|
162
|
+
freeReplyObject(reply);
|
163
|
+
reply = redisCommand(c,"GET foo");
|
164
|
+
test_cond(reply->type == REDIS_REPLY_STRING &&
|
165
|
+
strcmp(reply->str,"hello world") == 0);
|
166
|
+
freeReplyObject(reply);
|
167
|
+
|
168
|
+
test("%%b String interpolation works: ");
|
169
|
+
reply = redisCommand(c,"SET %b %b","foo",3,"hello\x00world",11);
|
170
|
+
freeReplyObject(reply);
|
171
|
+
reply = redisCommand(c,"GET foo");
|
172
|
+
test_cond(reply->type == REDIS_REPLY_STRING &&
|
173
|
+
memcmp(reply->str,"hello\x00world",11) == 0)
|
174
|
+
|
175
|
+
test("Binary reply length is correct: ");
|
176
|
+
test_cond(reply->len == 11)
|
177
|
+
freeReplyObject(reply);
|
178
|
+
|
179
|
+
test("Can parse nil replies: ");
|
180
|
+
reply = redisCommand(c,"GET nokey");
|
181
|
+
test_cond(reply->type == REDIS_REPLY_NIL)
|
182
|
+
freeReplyObject(reply);
|
183
|
+
|
184
|
+
/* test 7 */
|
185
|
+
test("Can parse integer replies: ");
|
186
|
+
reply = redisCommand(c,"INCR mycounter");
|
187
|
+
test_cond(reply->type == REDIS_REPLY_INTEGER && reply->integer == 1)
|
188
|
+
freeReplyObject(reply);
|
189
|
+
|
190
|
+
test("Can parse multi bulk replies: ");
|
191
|
+
freeReplyObject(redisCommand(c,"LPUSH mylist foo"));
|
192
|
+
freeReplyObject(redisCommand(c,"LPUSH mylist bar"));
|
193
|
+
reply = redisCommand(c,"LRANGE mylist 0 -1");
|
194
|
+
test_cond(reply->type == REDIS_REPLY_ARRAY &&
|
195
|
+
reply->elements == 2 &&
|
196
|
+
!memcmp(reply->element[0]->str,"bar",3) &&
|
197
|
+
!memcmp(reply->element[1]->str,"foo",3))
|
198
|
+
freeReplyObject(reply);
|
199
|
+
|
200
|
+
/* m/e with multi bulk reply *before* other reply.
|
201
|
+
* specifically test ordering of reply items to parse. */
|
202
|
+
test("Can handle nested multi bulk replies: ");
|
203
|
+
freeReplyObject(redisCommand(c,"MULTI"));
|
204
|
+
freeReplyObject(redisCommand(c,"LRANGE mylist 0 -1"));
|
205
|
+
freeReplyObject(redisCommand(c,"PING"));
|
206
|
+
reply = (redisCommand(c,"EXEC"));
|
207
|
+
test_cond(reply->type == REDIS_REPLY_ARRAY &&
|
208
|
+
reply->elements == 2 &&
|
209
|
+
reply->element[0]->type == REDIS_REPLY_ARRAY &&
|
210
|
+
reply->element[0]->elements == 2 &&
|
211
|
+
!memcmp(reply->element[0]->element[0]->str,"bar",3) &&
|
212
|
+
!memcmp(reply->element[0]->element[1]->str,"foo",3) &&
|
213
|
+
reply->element[1]->type == REDIS_REPLY_STATUS &&
|
214
|
+
strcasecmp(reply->element[1]->str,"pong") == 0);
|
215
|
+
freeReplyObject(reply);
|
216
|
+
|
217
|
+
{
|
218
|
+
/* Find out Redis version to determine the path for the next test */
|
219
|
+
const char *field = "redis_version:";
|
220
|
+
char *p, *eptr;
|
221
|
+
|
222
|
+
reply = redisCommand(c,"INFO");
|
223
|
+
p = strstr(reply->str,field);
|
224
|
+
major = strtol(p+strlen(field),&eptr,10);
|
225
|
+
p = eptr+1; /* char next to the first "." */
|
226
|
+
minor = strtol(p,&eptr,10);
|
227
|
+
freeReplyObject(reply);
|
228
|
+
}
|
229
|
+
|
230
|
+
test("Returns I/O error when the connection is lost: ");
|
231
|
+
reply = redisCommand(c,"QUIT");
|
232
|
+
if (major >= 2 && minor > 0) {
|
233
|
+
/* > 2.0 returns OK on QUIT and read() should be issued once more
|
234
|
+
* to know the descriptor is at EOF. */
|
235
|
+
test_cond(strcasecmp(reply->str,"OK") == 0 &&
|
236
|
+
redisGetReply(c,(void**)&reply) == REDIS_ERR);
|
237
|
+
freeReplyObject(reply);
|
238
|
+
} else {
|
239
|
+
test_cond(reply == NULL);
|
240
|
+
}
|
241
|
+
|
242
|
+
/* On 2.0, QUIT will cause the connection to be closed immediately and
|
243
|
+
* the read(2) for the reply on QUIT will set the error to EOF.
|
244
|
+
* On >2.0, QUIT will return with OK and another read(2) needed to be
|
245
|
+
* issued to find out the socket was closed by the server. In both
|
246
|
+
* conditions, the error will be set to EOF. */
|
247
|
+
assert(c->err == REDIS_ERR_EOF &&
|
248
|
+
strcmp(c->errstr,"Server closed the connection") == 0);
|
249
|
+
|
250
|
+
/* Clean up context and reconnect again */
|
251
|
+
redisFree(c);
|
252
|
+
__connect(&c);
|
253
|
+
}
|
254
|
+
|
255
|
+
static void test_reply_reader() {
|
256
|
+
void *reader;
|
257
|
+
void *reply;
|
258
|
+
char *err;
|
259
|
+
int ret;
|
260
|
+
|
261
|
+
test("Error handling in reply parser: ");
|
262
|
+
reader = redisReplyReaderCreate();
|
263
|
+
redisReplyReaderFeed(reader,(char*)"@foo\r\n",6);
|
264
|
+
ret = redisReplyReaderGetReply(reader,NULL);
|
265
|
+
err = redisReplyReaderGetError(reader);
|
266
|
+
test_cond(ret == REDIS_ERR &&
|
267
|
+
strcasecmp(err,"Protocol error, got \"@\" as reply type byte") == 0);
|
268
|
+
redisReplyReaderFree(reader);
|
269
|
+
|
270
|
+
/* when the reply already contains multiple items, they must be free'd
|
271
|
+
* on an error. valgrind will bark when this doesn't happen. */
|
272
|
+
test("Memory cleanup in reply parser: ");
|
273
|
+
reader = redisReplyReaderCreate();
|
274
|
+
redisReplyReaderFeed(reader,(char*)"*2\r\n",4);
|
275
|
+
redisReplyReaderFeed(reader,(char*)"$5\r\nhello\r\n",11);
|
276
|
+
redisReplyReaderFeed(reader,(char*)"@foo\r\n",6);
|
277
|
+
ret = redisReplyReaderGetReply(reader,NULL);
|
278
|
+
err = redisReplyReaderGetError(reader);
|
279
|
+
test_cond(ret == REDIS_ERR &&
|
280
|
+
strcasecmp(err,"Protocol error, got \"@\" as reply type byte") == 0);
|
281
|
+
redisReplyReaderFree(reader);
|
282
|
+
|
283
|
+
test("Set error on nested multi bulks with depth > 1: ");
|
284
|
+
reader = redisReplyReaderCreate();
|
285
|
+
redisReplyReaderFeed(reader,(char*)"*1\r\n",4);
|
286
|
+
redisReplyReaderFeed(reader,(char*)"*1\r\n",4);
|
287
|
+
redisReplyReaderFeed(reader,(char*)"*1\r\n",4);
|
288
|
+
ret = redisReplyReaderGetReply(reader,NULL);
|
289
|
+
err = redisReplyReaderGetError(reader);
|
290
|
+
test_cond(ret == REDIS_ERR &&
|
291
|
+
strncasecmp(err,"No support for",14) == 0);
|
292
|
+
redisReplyReaderFree(reader);
|
293
|
+
|
294
|
+
test("Works with NULL functions for reply: ");
|
295
|
+
reader = redisReplyReaderCreate();
|
296
|
+
redisReplyReaderSetReplyObjectFunctions(reader,NULL);
|
297
|
+
redisReplyReaderFeed(reader,(char*)"+OK\r\n",5);
|
298
|
+
ret = redisReplyReaderGetReply(reader,&reply);
|
299
|
+
test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS);
|
300
|
+
redisReplyReaderFree(reader);
|
301
|
+
|
302
|
+
test("Works when a single newline (\\r\\n) covers two calls to feed: ");
|
303
|
+
reader = redisReplyReaderCreate();
|
304
|
+
redisReplyReaderSetReplyObjectFunctions(reader,NULL);
|
305
|
+
redisReplyReaderFeed(reader,(char*)"+OK\r",4);
|
306
|
+
ret = redisReplyReaderGetReply(reader,&reply);
|
307
|
+
assert(ret == REDIS_OK && reply == NULL);
|
308
|
+
redisReplyReaderFeed(reader,(char*)"\n",1);
|
309
|
+
ret = redisReplyReaderGetReply(reader,&reply);
|
310
|
+
test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS);
|
311
|
+
redisReplyReaderFree(reader);
|
312
|
+
}
|
313
|
+
|
314
|
+
static void test_throughput() {
|
315
|
+
int i;
|
316
|
+
long long t1, t2;
|
317
|
+
redisContext *c = blocking_context;
|
318
|
+
redisReply **replies;
|
319
|
+
|
320
|
+
test("Throughput:\n");
|
321
|
+
for (i = 0; i < 500; i++)
|
322
|
+
freeReplyObject(redisCommand(c,"LPUSH mylist foo"));
|
323
|
+
|
324
|
+
replies = malloc(sizeof(redisReply*)*1000);
|
325
|
+
t1 = usec();
|
326
|
+
for (i = 0; i < 1000; i++) {
|
327
|
+
replies[i] = redisCommand(c,"PING");
|
328
|
+
assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS);
|
329
|
+
}
|
330
|
+
t2 = usec();
|
331
|
+
for (i = 0; i < 1000; i++) freeReplyObject(replies[i]);
|
332
|
+
free(replies);
|
333
|
+
printf("\t(1000x PING: %.2fs)\n", (t2-t1)/1000000.0);
|
334
|
+
|
335
|
+
replies = malloc(sizeof(redisReply*)*1000);
|
336
|
+
t1 = usec();
|
337
|
+
for (i = 0; i < 1000; i++) {
|
338
|
+
replies[i] = redisCommand(c,"LRANGE mylist 0 499");
|
339
|
+
assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY);
|
340
|
+
assert(replies[i] != NULL && replies[i]->elements == 500);
|
341
|
+
}
|
342
|
+
t2 = usec();
|
343
|
+
for (i = 0; i < 1000; i++) freeReplyObject(replies[i]);
|
344
|
+
free(replies);
|
345
|
+
printf("\t(1000x LRANGE with 500 elements: %.2fs)\n", (t2-t1)/1000000.0);
|
346
|
+
}
|
347
|
+
|
348
|
+
static void cleanup() {
|
349
|
+
redisContext *c = blocking_context;
|
350
|
+
redisReply *reply;
|
351
|
+
|
352
|
+
/* Make sure we're on DB 9 */
|
353
|
+
reply = redisCommand(c,"SELECT 9");
|
354
|
+
assert(reply != NULL); freeReplyObject(reply);
|
355
|
+
reply = redisCommand(c,"FLUSHDB");
|
356
|
+
assert(reply != NULL); freeReplyObject(reply);
|
357
|
+
redisFree(c);
|
358
|
+
}
|
359
|
+
|
360
|
+
// static long __test_callback_flags = 0;
|
361
|
+
// static void __test_callback(redisContext *c, void *privdata) {
|
362
|
+
// ((void)c);
|
363
|
+
// /* Shift to detect execution order */
|
364
|
+
// __test_callback_flags <<= 8;
|
365
|
+
// __test_callback_flags |= (long)privdata;
|
366
|
+
// }
|
367
|
+
//
|
368
|
+
// static void __test_reply_callback(redisContext *c, redisReply *reply, void *privdata) {
|
369
|
+
// ((void)c);
|
370
|
+
// /* Shift to detect execution order */
|
371
|
+
// __test_callback_flags <<= 8;
|
372
|
+
// __test_callback_flags |= (long)privdata;
|
373
|
+
// if (reply) freeReplyObject(reply);
|
374
|
+
// }
|
375
|
+
//
|
376
|
+
// static redisContext *__connect_nonblock() {
|
377
|
+
// /* Reset callback flags */
|
378
|
+
// __test_callback_flags = 0;
|
379
|
+
// return redisConnectNonBlock("127.0.0.1", 6379, NULL);
|
380
|
+
// }
|
381
|
+
//
|
382
|
+
// static void test_nonblocking_connection() {
|
383
|
+
// redisContext *c;
|
384
|
+
// int wdone = 0;
|
385
|
+
//
|
386
|
+
// test("Calls command callback when command is issued: ");
|
387
|
+
// c = __connect_nonblock();
|
388
|
+
// redisSetCommandCallback(c,__test_callback,(void*)1);
|
389
|
+
// redisCommand(c,"PING");
|
390
|
+
// test_cond(__test_callback_flags == 1);
|
391
|
+
// redisFree(c);
|
392
|
+
//
|
393
|
+
// test("Calls disconnect callback on redisDisconnect: ");
|
394
|
+
// c = __connect_nonblock();
|
395
|
+
// redisSetDisconnectCallback(c,__test_callback,(void*)2);
|
396
|
+
// redisDisconnect(c);
|
397
|
+
// test_cond(__test_callback_flags == 2);
|
398
|
+
// redisFree(c);
|
399
|
+
//
|
400
|
+
// test("Calls disconnect callback and free callback on redisFree: ");
|
401
|
+
// c = __connect_nonblock();
|
402
|
+
// redisSetDisconnectCallback(c,__test_callback,(void*)2);
|
403
|
+
// redisSetFreeCallback(c,__test_callback,(void*)4);
|
404
|
+
// redisFree(c);
|
405
|
+
// test_cond(__test_callback_flags == ((2 << 8) | 4));
|
406
|
+
//
|
407
|
+
// test("redisBufferWrite against empty write buffer: ");
|
408
|
+
// c = __connect_nonblock();
|
409
|
+
// test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1);
|
410
|
+
// redisFree(c);
|
411
|
+
//
|
412
|
+
// test("redisBufferWrite against not yet connected fd: ");
|
413
|
+
// c = __connect_nonblock();
|
414
|
+
// redisCommand(c,"PING");
|
415
|
+
// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
|
416
|
+
// strncmp(c->error,"write:",6) == 0);
|
417
|
+
// redisFree(c);
|
418
|
+
//
|
419
|
+
// test("redisBufferWrite against closed fd: ");
|
420
|
+
// c = __connect_nonblock();
|
421
|
+
// redisCommand(c,"PING");
|
422
|
+
// redisDisconnect(c);
|
423
|
+
// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
|
424
|
+
// strncmp(c->error,"write:",6) == 0);
|
425
|
+
// redisFree(c);
|
426
|
+
//
|
427
|
+
// test("Process callbacks in the right sequence: ");
|
428
|
+
// c = __connect_nonblock();
|
429
|
+
// redisCommandWithCallback(c,__test_reply_callback,(void*)1,"PING");
|
430
|
+
// redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING");
|
431
|
+
// redisCommandWithCallback(c,__test_reply_callback,(void*)3,"PING");
|
432
|
+
//
|
433
|
+
// /* Write output buffer */
|
434
|
+
// wdone = 0;
|
435
|
+
// while(!wdone) {
|
436
|
+
// usleep(500);
|
437
|
+
// redisBufferWrite(c,&wdone);
|
438
|
+
// }
|
439
|
+
//
|
440
|
+
// /* Read until at least one callback is executed (the 3 replies will
|
441
|
+
// * arrive in a single packet, causing all callbacks to be executed in
|
442
|
+
// * a single pass). */
|
443
|
+
// while(__test_callback_flags == 0) {
|
444
|
+
// assert(redisBufferRead(c) == REDIS_OK);
|
445
|
+
// redisProcessCallbacks(c);
|
446
|
+
// }
|
447
|
+
// test_cond(__test_callback_flags == 0x010203);
|
448
|
+
// redisFree(c);
|
449
|
+
//
|
450
|
+
// test("redisDisconnect executes pending callbacks with NULL reply: ");
|
451
|
+
// c = __connect_nonblock();
|
452
|
+
// redisSetDisconnectCallback(c,__test_callback,(void*)1);
|
453
|
+
// redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING");
|
454
|
+
// redisDisconnect(c);
|
455
|
+
// test_cond(__test_callback_flags == 0x0201);
|
456
|
+
// redisFree(c);
|
457
|
+
// }
|
458
|
+
|
459
|
+
int main(int argc, char **argv) {
|
460
|
+
if (argc > 1) {
|
461
|
+
if (strcmp(argv[1],"-s") == 0)
|
462
|
+
use_unix = 1;
|
463
|
+
}
|
464
|
+
|
465
|
+
signal(SIGPIPE, SIG_IGN);
|
466
|
+
test_format_commands();
|
467
|
+
test_blocking_connection();
|
468
|
+
test_reply_reader();
|
469
|
+
// test_nonblocking_connection();
|
470
|
+
test_throughput();
|
471
|
+
cleanup();
|
472
|
+
|
473
|
+
if (fails == 0) {
|
474
|
+
printf("ALL TESTS PASSED\n");
|
475
|
+
} else {
|
476
|
+
printf("*** %d TESTS FAILED ***\n", fails);
|
477
|
+
}
|
478
|
+
return 0;
|
479
|
+
}
|