@@ -512,3 +512,151 @@ passed
512
512
request chunk headers: {"foo":"bar"}
513
513
--- no_error_log
514
514
[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