@@ -512,3 +512,151 @@ passed
512512request chunk headers: {"foo":"bar"}
513513--- no_error_log
514514[error]
515+
516+
517+
518+ === TEST 13: watch response which http chunk contains partial etcd event response
519+ --- http_config eval: $::HttpConfig
520+ --- config
521+ location /version {
522+ content_by_lua_block {
523+ ngx.say('{"etcdserver":"3.4.0","etcdcluster":"3.4.0"}')
524+ }
525+ }
526+
527+ location /v3/watch {
528+ content_by_lua_block {
529+ -- payload get from tcpdump while running TEST 3 and split the event response into two chunks
530+
531+ ngx.say('{"result":{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"271","raft_term":"7"},"created":true}}')
532+ ngx.flush()
533+ ngx.sleep(0.1)
534+
535+ -- partial event without trailing new line
536+ ngx.print('{"result":{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437",')
537+ ngx.flush()
538+ ngx.print('"revision":"272","raft_term":"7"},"events"')
539+ ngx.flush()
540+
541+ -- key = /test, value = bcd3
542+ ngx.say(':[{"kv":{"key":"L3Rlc3Q=","create_revision":"156","mod_revision":"272","version":"44","value":"ImJjZDMi"}}]}}')
543+ ngx.flush()
544+
545+ -- ensure client timeout
546+ ngx.sleep(1)
547+ }
548+ }
549+
550+ location /t {
551+ content_by_lua_block {
552+ local etcd, err = require("resty.etcd").new({
553+ protocol = "v3",
554+ http_host = {
555+ "http://127.0.0.1:" .. ngx.var.server_port,
556+ },
557+ })
558+ check_res(etcd, err)
559+
560+ local cur_time = ngx.now()
561+ local body_chunk_fun, err = etcd:watch("/test", {timeout = 0.5})
562+ if not body_chunk_fun then
563+ ngx.say("failed to watch: ", err)
564+ end
565+
566+ local idx = 0
567+ while true do
568+ local chunk, err = body_chunk_fun()
569+
570+ if not chunk then
571+ if err then
572+ ngx.say(err)
573+ end
574+ break
575+ end
576+
577+ idx = idx + 1
578+ ngx.say(idx, ": ", require("cjson").encode(chunk.result))
579+ end
580+ }
581+ }
582+ --- request
583+ GET /t
584+ --- no_error_log
585+ [error]
586+ --- response_body_like eval
587+ qr/1:.*"created":true.*
588+ 2:.*"value":"bcd3".*
589+ timeout/
590+ --- timeout: 5
591+
592+
593+
594+ === TEST 14: watch response which one http chunk contains multiple events chunk
595+ --- http_config eval: $::HttpConfig
596+ --- config
597+ location /version {
598+ content_by_lua_block {
599+ ngx.say('{"etcdserver":"3.4.0","etcdcluster":"3.4.0"}')
600+ }
601+ }
602+
603+ location /v3/watch {
604+ content_by_lua_block {
605+ -- payload get from tcpdump while running TEST 5 and merge two event response into one http chunk
606+
607+ ngx.say('{"result":{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"290","raft_term":"8"},"created":true}}')
608+ ngx.flush()
609+ ngx.sleep(0.1)
610+
611+ -- one http chunk contains multiple event response, note the new line at the end of first event response
612+ -- key1 = /wdir/, value1 = bcd4
613+ -- key2 = /wdir/a, value2 = bcd4a
614+ ngx.say('{"result":{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"292","raft_term":"8"},"events":[{"kv":{"key":"L3dkaXIv","create_revision":"31","mod_revision":"292","version":"22","value":"ImJjZDQi"}}]}}\n{"result":{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"293","raft_term":"8"},"events":[{"kv":{"key":"L3dkaXIvYQ==","create_revision":"293","mod_revision":"293","version":"1","value":"ImJjZDRhIg=="}}]}}')
615+ ngx.flush()
616+
617+ -- ensure client timeout
618+ ngx.sleep(1)
619+ }
620+ }
621+
622+ location /t {
623+ content_by_lua_block {
624+ local etcd, err = require("resty.etcd").new({
625+ protocol = "v3",
626+ http_host = {
627+ "http://127.0.0.1:" .. ngx.var.server_port,
628+ },
629+ })
630+ check_res(etcd, err)
631+
632+ local cur_time = ngx.now()
633+ local body_chunk_fun, err = etcd:watch("/", {timeout = 0.5})
634+ if not body_chunk_fun then
635+ ngx.say("failed to watch: ", err)
636+ end
637+
638+ local idx = 0
639+ while true do
640+ local chunk, err = body_chunk_fun()
641+
642+ if not chunk then
643+ if err then
644+ ngx.say(err)
645+ end
646+ break
647+ end
648+
649+ idx = idx + 1
650+ ngx.say(idx, ": ", require("cjson").encode(chunk.result))
651+ end
652+ }
653+ }
654+ --- request
655+ GET /t
656+ --- no_error_log
657+ [error]
658+ --- response_body_like eval
659+ qr/1:.*"created":true.*
660+ 2:.*"value":"bcd4".*"value":"bcd4a".*
661+ timeout/
662+ --- timeout: 5
0 commit comments