v3_watch_test.go 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213
  1. // Copyright 2016 The etcd Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package integration
  15. import (
  16. "bytes"
  17. "context"
  18. "fmt"
  19. "reflect"
  20. "sort"
  21. "sync"
  22. "testing"
  23. "time"
  24. "go.etcd.io/etcd/etcdserver/api/v3rpc"
  25. pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
  26. "go.etcd.io/etcd/mvcc/mvccpb"
  27. "go.etcd.io/etcd/pkg/testutil"
  28. )
  29. // TestV3WatchFromCurrentRevision tests Watch APIs from current revision.
  30. func TestV3WatchFromCurrentRevision(t *testing.T) {
  31. defer testutil.AfterTest(t)
  32. tests := []struct {
  33. putKeys []string
  34. watchRequest *pb.WatchRequest
  35. wresps []*pb.WatchResponse
  36. }{
  37. // watch the key, matching
  38. {
  39. []string{"foo"},
  40. &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  41. CreateRequest: &pb.WatchCreateRequest{
  42. Key: []byte("foo")}}},
  43. []*pb.WatchResponse{
  44. {
  45. Header: &pb.ResponseHeader{Revision: 2},
  46. Created: false,
  47. Events: []*mvccpb.Event{
  48. {
  49. Type: mvccpb.PUT,
  50. Kv: &mvccpb.KeyValue{Key: []byte("foo"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 2, Version: 1},
  51. },
  52. },
  53. },
  54. },
  55. },
  56. // watch the key, non-matching
  57. {
  58. []string{"foo"},
  59. &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  60. CreateRequest: &pb.WatchCreateRequest{
  61. Key: []byte("helloworld")}}},
  62. []*pb.WatchResponse{},
  63. },
  64. // watch the prefix, matching
  65. {
  66. []string{"fooLong"},
  67. &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  68. CreateRequest: &pb.WatchCreateRequest{
  69. Key: []byte("foo"),
  70. RangeEnd: []byte("fop")}}},
  71. []*pb.WatchResponse{
  72. {
  73. Header: &pb.ResponseHeader{Revision: 2},
  74. Created: false,
  75. Events: []*mvccpb.Event{
  76. {
  77. Type: mvccpb.PUT,
  78. Kv: &mvccpb.KeyValue{Key: []byte("fooLong"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 2, Version: 1},
  79. },
  80. },
  81. },
  82. },
  83. },
  84. // watch the prefix, non-matching
  85. {
  86. []string{"foo"},
  87. &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  88. CreateRequest: &pb.WatchCreateRequest{
  89. Key: []byte("helloworld"),
  90. RangeEnd: []byte("helloworle")}}},
  91. []*pb.WatchResponse{},
  92. },
  93. // watch full range, matching
  94. {
  95. []string{"fooLong"},
  96. &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  97. CreateRequest: &pb.WatchCreateRequest{
  98. Key: []byte(""),
  99. RangeEnd: []byte("\x00")}}},
  100. []*pb.WatchResponse{
  101. {
  102. Header: &pb.ResponseHeader{Revision: 2},
  103. Created: false,
  104. Events: []*mvccpb.Event{
  105. {
  106. Type: mvccpb.PUT,
  107. Kv: &mvccpb.KeyValue{Key: []byte("fooLong"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 2, Version: 1},
  108. },
  109. },
  110. },
  111. },
  112. },
  113. // multiple puts, one watcher with matching key
  114. {
  115. []string{"foo", "foo", "foo"},
  116. &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  117. CreateRequest: &pb.WatchCreateRequest{
  118. Key: []byte("foo")}}},
  119. []*pb.WatchResponse{
  120. {
  121. Header: &pb.ResponseHeader{Revision: 2},
  122. Created: false,
  123. Events: []*mvccpb.Event{
  124. {
  125. Type: mvccpb.PUT,
  126. Kv: &mvccpb.KeyValue{Key: []byte("foo"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 2, Version: 1},
  127. },
  128. },
  129. },
  130. {
  131. Header: &pb.ResponseHeader{Revision: 3},
  132. Created: false,
  133. Events: []*mvccpb.Event{
  134. {
  135. Type: mvccpb.PUT,
  136. Kv: &mvccpb.KeyValue{Key: []byte("foo"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 3, Version: 2},
  137. },
  138. },
  139. },
  140. {
  141. Header: &pb.ResponseHeader{Revision: 4},
  142. Created: false,
  143. Events: []*mvccpb.Event{
  144. {
  145. Type: mvccpb.PUT,
  146. Kv: &mvccpb.KeyValue{Key: []byte("foo"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 4, Version: 3},
  147. },
  148. },
  149. },
  150. },
  151. },
  152. // multiple puts, one watcher with matching prefix
  153. {
  154. []string{"foo", "foo", "foo"},
  155. &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  156. CreateRequest: &pb.WatchCreateRequest{
  157. Key: []byte("foo"),
  158. RangeEnd: []byte("fop")}}},
  159. []*pb.WatchResponse{
  160. {
  161. Header: &pb.ResponseHeader{Revision: 2},
  162. Created: false,
  163. Events: []*mvccpb.Event{
  164. {
  165. Type: mvccpb.PUT,
  166. Kv: &mvccpb.KeyValue{Key: []byte("foo"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 2, Version: 1},
  167. },
  168. },
  169. },
  170. {
  171. Header: &pb.ResponseHeader{Revision: 3},
  172. Created: false,
  173. Events: []*mvccpb.Event{
  174. {
  175. Type: mvccpb.PUT,
  176. Kv: &mvccpb.KeyValue{Key: []byte("foo"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 3, Version: 2},
  177. },
  178. },
  179. },
  180. {
  181. Header: &pb.ResponseHeader{Revision: 4},
  182. Created: false,
  183. Events: []*mvccpb.Event{
  184. {
  185. Type: mvccpb.PUT,
  186. Kv: &mvccpb.KeyValue{Key: []byte("foo"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 4, Version: 3},
  187. },
  188. },
  189. },
  190. },
  191. },
  192. }
  193. for i, tt := range tests {
  194. clus := NewClusterV3(t, &ClusterConfig{Size: 3})
  195. wAPI := toGRPC(clus.RandClient()).Watch
  196. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  197. defer cancel()
  198. wStream, err := wAPI.Watch(ctx)
  199. if err != nil {
  200. t.Fatalf("#%d: wAPI.Watch error: %v", i, err)
  201. }
  202. err = wStream.Send(tt.watchRequest)
  203. if err != nil {
  204. t.Fatalf("#%d: wStream.Send error: %v", i, err)
  205. }
  206. // ensure watcher request created a new watcher
  207. cresp, err := wStream.Recv()
  208. if err != nil {
  209. t.Errorf("#%d: wStream.Recv error: %v", i, err)
  210. clus.Terminate(t)
  211. continue
  212. }
  213. if !cresp.Created {
  214. t.Errorf("#%d: did not create watchid, got %+v", i, cresp)
  215. clus.Terminate(t)
  216. continue
  217. }
  218. if cresp.Canceled {
  219. t.Errorf("#%d: canceled watcher on create %+v", i, cresp)
  220. clus.Terminate(t)
  221. continue
  222. }
  223. createdWatchId := cresp.WatchId
  224. if cresp.Header == nil || cresp.Header.Revision != 1 {
  225. t.Errorf("#%d: header revision got +%v, wanted revison 1", i, cresp)
  226. clus.Terminate(t)
  227. continue
  228. }
  229. // asynchronously create keys
  230. ch := make(chan struct{}, 1)
  231. go func() {
  232. for _, k := range tt.putKeys {
  233. kvc := toGRPC(clus.RandClient()).KV
  234. req := &pb.PutRequest{Key: []byte(k), Value: []byte("bar")}
  235. if _, err := kvc.Put(context.TODO(), req); err != nil {
  236. t.Errorf("#%d: couldn't put key (%v)", i, err)
  237. }
  238. }
  239. ch <- struct{}{}
  240. }()
  241. // check stream results
  242. for j, wresp := range tt.wresps {
  243. resp, err := wStream.Recv()
  244. if err != nil {
  245. t.Errorf("#%d.%d: wStream.Recv error: %v", i, j, err)
  246. }
  247. if resp.Header == nil {
  248. t.Fatalf("#%d.%d: unexpected nil resp.Header", i, j)
  249. }
  250. if resp.Header.Revision != wresp.Header.Revision {
  251. t.Errorf("#%d.%d: resp.Header.Revision got = %d, want = %d", i, j, resp.Header.Revision, wresp.Header.Revision)
  252. }
  253. if wresp.Created != resp.Created {
  254. t.Errorf("#%d.%d: resp.Created got = %v, want = %v", i, j, resp.Created, wresp.Created)
  255. }
  256. if resp.WatchId != createdWatchId {
  257. t.Errorf("#%d.%d: resp.WatchId got = %d, want = %d", i, j, resp.WatchId, createdWatchId)
  258. }
  259. if !reflect.DeepEqual(resp.Events, wresp.Events) {
  260. t.Errorf("#%d.%d: resp.Events got = %+v, want = %+v", i, j, resp.Events, wresp.Events)
  261. }
  262. }
  263. rok, nr := waitResponse(wStream, 1*time.Second)
  264. if !rok {
  265. t.Errorf("unexpected pb.WatchResponse is received %+v", nr)
  266. }
  267. // wait for the client to finish sending the keys before terminating the cluster
  268. <-ch
  269. // can't defer because tcp ports will be in use
  270. clus.Terminate(t)
  271. }
  272. }
  273. // TestV3WatchFutureRevision tests Watch APIs from a future revision.
  274. func TestV3WatchFutureRevision(t *testing.T) {
  275. defer testutil.AfterTest(t)
  276. clus := NewClusterV3(t, &ClusterConfig{Size: 1})
  277. defer clus.Terminate(t)
  278. wAPI := toGRPC(clus.RandClient()).Watch
  279. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  280. defer cancel()
  281. wStream, err := wAPI.Watch(ctx)
  282. if err != nil {
  283. t.Fatalf("wAPI.Watch error: %v", err)
  284. }
  285. wkey := []byte("foo")
  286. wrev := int64(10)
  287. req := &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  288. CreateRequest: &pb.WatchCreateRequest{Key: wkey, StartRevision: wrev}}}
  289. err = wStream.Send(req)
  290. if err != nil {
  291. t.Fatalf("wStream.Send error: %v", err)
  292. }
  293. // ensure watcher request created a new watcher
  294. cresp, err := wStream.Recv()
  295. if err != nil {
  296. t.Fatalf("wStream.Recv error: %v", err)
  297. }
  298. if !cresp.Created {
  299. t.Fatalf("create %v, want %v", cresp.Created, true)
  300. }
  301. kvc := toGRPC(clus.RandClient()).KV
  302. for {
  303. req := &pb.PutRequest{Key: wkey, Value: []byte("bar")}
  304. resp, rerr := kvc.Put(context.TODO(), req)
  305. if rerr != nil {
  306. t.Fatalf("couldn't put key (%v)", rerr)
  307. }
  308. if resp.Header.Revision == wrev {
  309. break
  310. }
  311. }
  312. // ensure watcher request created a new watcher
  313. cresp, err = wStream.Recv()
  314. if err != nil {
  315. t.Fatalf("wStream.Recv error: %v", err)
  316. }
  317. if cresp.Header.Revision != wrev {
  318. t.Fatalf("revision = %d, want %d", cresp.Header.Revision, wrev)
  319. }
  320. if len(cresp.Events) != 1 {
  321. t.Fatalf("failed to receive events")
  322. }
  323. if cresp.Events[0].Kv.ModRevision != wrev {
  324. t.Errorf("mod revision = %d, want %d", cresp.Events[0].Kv.ModRevision, wrev)
  325. }
  326. }
  327. // TestV3WatchWrongRange tests wrong range does not create watchers.
  328. func TestV3WatchWrongRange(t *testing.T) {
  329. defer testutil.AfterTest(t)
  330. clus := NewClusterV3(t, &ClusterConfig{Size: 1})
  331. defer clus.Terminate(t)
  332. wAPI := toGRPC(clus.RandClient()).Watch
  333. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  334. defer cancel()
  335. wStream, err := wAPI.Watch(ctx)
  336. if err != nil {
  337. t.Fatalf("wAPI.Watch error: %v", err)
  338. }
  339. tests := []struct {
  340. key []byte
  341. end []byte
  342. canceled bool
  343. }{
  344. {[]byte("a"), []byte("a"), true}, // wrong range end
  345. {[]byte("b"), []byte("a"), true}, // wrong range end
  346. {[]byte("foo"), []byte{0}, false}, // watch request with 'WithFromKey'
  347. }
  348. for i, tt := range tests {
  349. if err := wStream.Send(&pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  350. CreateRequest: &pb.WatchCreateRequest{Key: tt.key, RangeEnd: tt.end, StartRevision: 1}}}); err != nil {
  351. t.Fatalf("#%d: wStream.Send error: %v", i, err)
  352. }
  353. cresp, err := wStream.Recv()
  354. if err != nil {
  355. t.Fatalf("#%d: wStream.Recv error: %v", i, err)
  356. }
  357. if !cresp.Created {
  358. t.Fatalf("#%d: create %v, want %v", i, cresp.Created, true)
  359. }
  360. if cresp.Canceled != tt.canceled {
  361. t.Fatalf("#%d: canceled %v, want %v", i, tt.canceled, cresp.Canceled)
  362. }
  363. if tt.canceled && cresp.WatchId != -1 {
  364. t.Fatalf("#%d: canceled watch ID %d, want -1", i, cresp.WatchId)
  365. }
  366. }
  367. }
  368. // TestV3WatchCancelSynced tests Watch APIs cancellation from synced map.
  369. func TestV3WatchCancelSynced(t *testing.T) {
  370. defer testutil.AfterTest(t)
  371. testV3WatchCancel(t, 0)
  372. }
  373. // TestV3WatchCancelUnsynced tests Watch APIs cancellation from unsynced map.
  374. func TestV3WatchCancelUnsynced(t *testing.T) {
  375. defer testutil.AfterTest(t)
  376. testV3WatchCancel(t, 1)
  377. }
  378. func testV3WatchCancel(t *testing.T, startRev int64) {
  379. clus := NewClusterV3(t, &ClusterConfig{Size: 3})
  380. defer clus.Terminate(t)
  381. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  382. defer cancel()
  383. wStream, errW := toGRPC(clus.RandClient()).Watch.Watch(ctx)
  384. if errW != nil {
  385. t.Fatalf("wAPI.Watch error: %v", errW)
  386. }
  387. wreq := &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  388. CreateRequest: &pb.WatchCreateRequest{
  389. Key: []byte("foo"), StartRevision: startRev}}}
  390. if err := wStream.Send(wreq); err != nil {
  391. t.Fatalf("wStream.Send error: %v", err)
  392. }
  393. wresp, errR := wStream.Recv()
  394. if errR != nil {
  395. t.Errorf("wStream.Recv error: %v", errR)
  396. }
  397. if !wresp.Created {
  398. t.Errorf("wresp.Created got = %v, want = true", wresp.Created)
  399. }
  400. creq := &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CancelRequest{
  401. CancelRequest: &pb.WatchCancelRequest{
  402. WatchId: wresp.WatchId}}}
  403. if err := wStream.Send(creq); err != nil {
  404. t.Fatalf("wStream.Send error: %v", err)
  405. }
  406. cresp, err := wStream.Recv()
  407. if err != nil {
  408. t.Errorf("wStream.Recv error: %v", err)
  409. }
  410. if !cresp.Canceled {
  411. t.Errorf("cresp.Canceled got = %v, want = true", cresp.Canceled)
  412. }
  413. kvc := toGRPC(clus.RandClient()).KV
  414. if _, err := kvc.Put(context.TODO(), &pb.PutRequest{Key: []byte("foo"), Value: []byte("bar")}); err != nil {
  415. t.Errorf("couldn't put key (%v)", err)
  416. }
  417. // watch got canceled, so this should block
  418. rok, nr := waitResponse(wStream, 1*time.Second)
  419. if !rok {
  420. t.Errorf("unexpected pb.WatchResponse is received %+v", nr)
  421. }
  422. }
  423. // TestV3WatchCurrentPutOverlap ensures current watchers receive all events with
  424. // overlapping puts.
  425. func TestV3WatchCurrentPutOverlap(t *testing.T) {
  426. defer testutil.AfterTest(t)
  427. clus := NewClusterV3(t, &ClusterConfig{Size: 3})
  428. defer clus.Terminate(t)
  429. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  430. defer cancel()
  431. wStream, wErr := toGRPC(clus.RandClient()).Watch.Watch(ctx)
  432. if wErr != nil {
  433. t.Fatalf("wAPI.Watch error: %v", wErr)
  434. }
  435. // last mod_revision that will be observed
  436. nrRevisions := 32
  437. // first revision already allocated as empty revision
  438. var wg sync.WaitGroup
  439. for i := 1; i < nrRevisions; i++ {
  440. wg.Add(1)
  441. go func() {
  442. defer wg.Done()
  443. kvc := toGRPC(clus.RandClient()).KV
  444. req := &pb.PutRequest{Key: []byte("foo"), Value: []byte("bar")}
  445. if _, err := kvc.Put(context.TODO(), req); err != nil {
  446. t.Errorf("couldn't put key (%v)", err)
  447. }
  448. }()
  449. }
  450. // maps watcher to current expected revision
  451. progress := make(map[int64]int64)
  452. wreq := &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  453. CreateRequest: &pb.WatchCreateRequest{Key: []byte("foo"), RangeEnd: []byte("fop")}}}
  454. if err := wStream.Send(wreq); err != nil {
  455. t.Fatalf("first watch request failed (%v)", err)
  456. }
  457. more := true
  458. progress[-1] = 0 // watcher creation pending
  459. for more {
  460. resp, err := wStream.Recv()
  461. if err != nil {
  462. t.Fatalf("wStream.Recv error: %v", err)
  463. }
  464. if resp.Created {
  465. // accept events > header revision
  466. progress[resp.WatchId] = resp.Header.Revision + 1
  467. if resp.Header.Revision == int64(nrRevisions) {
  468. // covered all revisions; create no more watchers
  469. progress[-1] = int64(nrRevisions) + 1
  470. } else if err := wStream.Send(wreq); err != nil {
  471. t.Fatalf("watch request failed (%v)", err)
  472. }
  473. } else if len(resp.Events) == 0 {
  474. t.Fatalf("got events %v, want non-empty", resp.Events)
  475. } else {
  476. wRev, ok := progress[resp.WatchId]
  477. if !ok {
  478. t.Fatalf("got %+v, but watch id shouldn't exist ", resp)
  479. }
  480. if resp.Events[0].Kv.ModRevision != wRev {
  481. t.Fatalf("got %+v, wanted first revision %d", resp, wRev)
  482. }
  483. lastRev := resp.Events[len(resp.Events)-1].Kv.ModRevision
  484. progress[resp.WatchId] = lastRev + 1
  485. }
  486. more = false
  487. for _, v := range progress {
  488. if v <= int64(nrRevisions) {
  489. more = true
  490. break
  491. }
  492. }
  493. }
  494. if rok, nr := waitResponse(wStream, time.Second); !rok {
  495. t.Errorf("unexpected pb.WatchResponse is received %+v", nr)
  496. }
  497. wg.Wait()
  498. }
  499. // TestV3WatchEmptyKey ensures synced watchers see empty key PUTs as PUT events
  500. func TestV3WatchEmptyKey(t *testing.T) {
  501. defer testutil.AfterTest(t)
  502. clus := NewClusterV3(t, &ClusterConfig{Size: 1})
  503. defer clus.Terminate(t)
  504. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  505. defer cancel()
  506. ws, werr := toGRPC(clus.RandClient()).Watch.Watch(ctx)
  507. if werr != nil {
  508. t.Fatal(werr)
  509. }
  510. req := &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  511. CreateRequest: &pb.WatchCreateRequest{
  512. Key: []byte("foo")}}}
  513. if err := ws.Send(req); err != nil {
  514. t.Fatal(err)
  515. }
  516. if _, err := ws.Recv(); err != nil {
  517. t.Fatal(err)
  518. }
  519. // put a key with empty value
  520. kvc := toGRPC(clus.RandClient()).KV
  521. preq := &pb.PutRequest{Key: []byte("foo")}
  522. if _, err := kvc.Put(context.TODO(), preq); err != nil {
  523. t.Fatal(err)
  524. }
  525. // check received PUT
  526. resp, rerr := ws.Recv()
  527. if rerr != nil {
  528. t.Fatal(rerr)
  529. }
  530. wevs := []*mvccpb.Event{
  531. {
  532. Type: mvccpb.PUT,
  533. Kv: &mvccpb.KeyValue{Key: []byte("foo"), CreateRevision: 2, ModRevision: 2, Version: 1},
  534. },
  535. }
  536. if !reflect.DeepEqual(resp.Events, wevs) {
  537. t.Fatalf("got %v, expected %v", resp.Events, wevs)
  538. }
  539. }
  540. func TestV3WatchMultipleWatchersSynced(t *testing.T) {
  541. defer testutil.AfterTest(t)
  542. testV3WatchMultipleWatchers(t, 0)
  543. }
  544. func TestV3WatchMultipleWatchersUnsynced(t *testing.T) {
  545. defer testutil.AfterTest(t)
  546. testV3WatchMultipleWatchers(t, 1)
  547. }
  548. // testV3WatchMultipleWatchers tests multiple watchers on the same key
  549. // and one watcher with matching prefix. It first puts the key
  550. // that matches all watchers, and another key that matches only
  551. // one watcher to test if it receives expected events.
  552. func testV3WatchMultipleWatchers(t *testing.T, startRev int64) {
  553. clus := NewClusterV3(t, &ClusterConfig{Size: 3})
  554. defer clus.Terminate(t)
  555. kvc := toGRPC(clus.RandClient()).KV
  556. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  557. defer cancel()
  558. wStream, errW := toGRPC(clus.RandClient()).Watch.Watch(ctx)
  559. if errW != nil {
  560. t.Fatalf("wAPI.Watch error: %v", errW)
  561. }
  562. watchKeyN := 4
  563. for i := 0; i < watchKeyN+1; i++ {
  564. var wreq *pb.WatchRequest
  565. if i < watchKeyN {
  566. wreq = &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  567. CreateRequest: &pb.WatchCreateRequest{
  568. Key: []byte("foo"), StartRevision: startRev}}}
  569. } else {
  570. wreq = &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  571. CreateRequest: &pb.WatchCreateRequest{
  572. Key: []byte("fo"), RangeEnd: []byte("fp"), StartRevision: startRev}}}
  573. }
  574. if err := wStream.Send(wreq); err != nil {
  575. t.Fatalf("wStream.Send error: %v", err)
  576. }
  577. }
  578. ids := make(map[int64]struct{})
  579. for i := 0; i < watchKeyN+1; i++ {
  580. wresp, err := wStream.Recv()
  581. if err != nil {
  582. t.Fatalf("wStream.Recv error: %v", err)
  583. }
  584. if !wresp.Created {
  585. t.Fatalf("wresp.Created got = %v, want = true", wresp.Created)
  586. }
  587. ids[wresp.WatchId] = struct{}{}
  588. }
  589. if _, err := kvc.Put(context.TODO(), &pb.PutRequest{Key: []byte("foo"), Value: []byte("bar")}); err != nil {
  590. t.Fatalf("couldn't put key (%v)", err)
  591. }
  592. for i := 0; i < watchKeyN+1; i++ {
  593. wresp, err := wStream.Recv()
  594. if err != nil {
  595. t.Fatalf("wStream.Recv error: %v", err)
  596. }
  597. if _, ok := ids[wresp.WatchId]; !ok {
  598. t.Errorf("watchId %d is not created!", wresp.WatchId)
  599. } else {
  600. delete(ids, wresp.WatchId)
  601. }
  602. if len(wresp.Events) == 0 {
  603. t.Errorf("#%d: no events received", i)
  604. }
  605. for _, ev := range wresp.Events {
  606. if string(ev.Kv.Key) != "foo" {
  607. t.Errorf("ev.Kv.Key got = %s, want = foo", ev.Kv.Key)
  608. }
  609. if string(ev.Kv.Value) != "bar" {
  610. t.Errorf("ev.Kv.Value got = %s, want = bar", ev.Kv.Value)
  611. }
  612. }
  613. }
  614. // now put one key that has only one matching watcher
  615. if _, err := kvc.Put(context.TODO(), &pb.PutRequest{Key: []byte("fo"), Value: []byte("bar")}); err != nil {
  616. t.Fatalf("couldn't put key (%v)", err)
  617. }
  618. wresp, err := wStream.Recv()
  619. if err != nil {
  620. t.Errorf("wStream.Recv error: %v", err)
  621. }
  622. if len(wresp.Events) != 1 {
  623. t.Fatalf("len(wresp.Events) got = %d, want = 1", len(wresp.Events))
  624. }
  625. if string(wresp.Events[0].Kv.Key) != "fo" {
  626. t.Errorf("wresp.Events[0].Kv.Key got = %s, want = fo", wresp.Events[0].Kv.Key)
  627. }
  628. // now Recv should block because there is no more events coming
  629. rok, nr := waitResponse(wStream, 1*time.Second)
  630. if !rok {
  631. t.Errorf("unexpected pb.WatchResponse is received %+v", nr)
  632. }
  633. }
  634. func TestV3WatchMultipleEventsTxnSynced(t *testing.T) {
  635. defer testutil.AfterTest(t)
  636. testV3WatchMultipleEventsTxn(t, 0)
  637. }
  638. func TestV3WatchMultipleEventsTxnUnsynced(t *testing.T) {
  639. defer testutil.AfterTest(t)
  640. testV3WatchMultipleEventsTxn(t, 1)
  641. }
  642. // testV3WatchMultipleEventsTxn tests Watch APIs when it receives multiple events.
  643. func testV3WatchMultipleEventsTxn(t *testing.T, startRev int64) {
  644. clus := NewClusterV3(t, &ClusterConfig{Size: 3})
  645. defer clus.Terminate(t)
  646. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  647. defer cancel()
  648. wStream, wErr := toGRPC(clus.RandClient()).Watch.Watch(ctx)
  649. if wErr != nil {
  650. t.Fatalf("wAPI.Watch error: %v", wErr)
  651. }
  652. wreq := &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  653. CreateRequest: &pb.WatchCreateRequest{
  654. Key: []byte("foo"), RangeEnd: []byte("fop"), StartRevision: startRev}}}
  655. if err := wStream.Send(wreq); err != nil {
  656. t.Fatalf("wStream.Send error: %v", err)
  657. }
  658. if resp, err := wStream.Recv(); err != nil || !resp.Created {
  659. t.Fatalf("create response failed: resp=%v, err=%v", resp, err)
  660. }
  661. kvc := toGRPC(clus.RandClient()).KV
  662. txn := pb.TxnRequest{}
  663. for i := 0; i < 3; i++ {
  664. ru := &pb.RequestOp{}
  665. ru.Request = &pb.RequestOp_RequestPut{
  666. RequestPut: &pb.PutRequest{
  667. Key: []byte(fmt.Sprintf("foo%d", i)), Value: []byte("bar")}}
  668. txn.Success = append(txn.Success, ru)
  669. }
  670. tresp, err := kvc.Txn(context.Background(), &txn)
  671. if err != nil {
  672. t.Fatalf("kvc.Txn error: %v", err)
  673. }
  674. if !tresp.Succeeded {
  675. t.Fatalf("kvc.Txn failed: %+v", tresp)
  676. }
  677. events := []*mvccpb.Event{}
  678. for len(events) < 3 {
  679. resp, err := wStream.Recv()
  680. if err != nil {
  681. t.Errorf("wStream.Recv error: %v", err)
  682. }
  683. events = append(events, resp.Events...)
  684. }
  685. sort.Sort(eventsSortByKey(events))
  686. wevents := []*mvccpb.Event{
  687. {
  688. Type: mvccpb.PUT,
  689. Kv: &mvccpb.KeyValue{Key: []byte("foo0"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 2, Version: 1},
  690. },
  691. {
  692. Type: mvccpb.PUT,
  693. Kv: &mvccpb.KeyValue{Key: []byte("foo1"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 2, Version: 1},
  694. },
  695. {
  696. Type: mvccpb.PUT,
  697. Kv: &mvccpb.KeyValue{Key: []byte("foo2"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 2, Version: 1},
  698. },
  699. }
  700. if !reflect.DeepEqual(events, wevents) {
  701. t.Errorf("events got = %+v, want = %+v", events, wevents)
  702. }
  703. rok, nr := waitResponse(wStream, 1*time.Second)
  704. if !rok {
  705. t.Errorf("unexpected pb.WatchResponse is received %+v", nr)
  706. }
  707. }
  708. type eventsSortByKey []*mvccpb.Event
  709. func (evs eventsSortByKey) Len() int { return len(evs) }
  710. func (evs eventsSortByKey) Swap(i, j int) { evs[i], evs[j] = evs[j], evs[i] }
  711. func (evs eventsSortByKey) Less(i, j int) bool { return bytes.Compare(evs[i].Kv.Key, evs[j].Kv.Key) < 0 }
  712. func TestV3WatchMultipleEventsPutUnsynced(t *testing.T) {
  713. defer testutil.AfterTest(t)
  714. clus := NewClusterV3(t, &ClusterConfig{Size: 3})
  715. defer clus.Terminate(t)
  716. kvc := toGRPC(clus.RandClient()).KV
  717. if _, err := kvc.Put(context.TODO(), &pb.PutRequest{Key: []byte("foo0"), Value: []byte("bar")}); err != nil {
  718. t.Fatalf("couldn't put key (%v)", err)
  719. }
  720. if _, err := kvc.Put(context.TODO(), &pb.PutRequest{Key: []byte("foo1"), Value: []byte("bar")}); err != nil {
  721. t.Fatalf("couldn't put key (%v)", err)
  722. }
  723. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  724. defer cancel()
  725. wStream, wErr := toGRPC(clus.RandClient()).Watch.Watch(ctx)
  726. if wErr != nil {
  727. t.Fatalf("wAPI.Watch error: %v", wErr)
  728. }
  729. wreq := &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  730. CreateRequest: &pb.WatchCreateRequest{
  731. Key: []byte("foo"), RangeEnd: []byte("fop"), StartRevision: 1}}}
  732. if err := wStream.Send(wreq); err != nil {
  733. t.Fatalf("wStream.Send error: %v", err)
  734. }
  735. if _, err := kvc.Put(context.TODO(), &pb.PutRequest{Key: []byte("foo0"), Value: []byte("bar")}); err != nil {
  736. t.Fatalf("couldn't put key (%v)", err)
  737. }
  738. if _, err := kvc.Put(context.TODO(), &pb.PutRequest{Key: []byte("foo1"), Value: []byte("bar")}); err != nil {
  739. t.Fatalf("couldn't put key (%v)", err)
  740. }
  741. allWevents := []*mvccpb.Event{
  742. {
  743. Type: mvccpb.PUT,
  744. Kv: &mvccpb.KeyValue{Key: []byte("foo0"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 2, Version: 1},
  745. },
  746. {
  747. Type: mvccpb.PUT,
  748. Kv: &mvccpb.KeyValue{Key: []byte("foo1"), Value: []byte("bar"), CreateRevision: 3, ModRevision: 3, Version: 1},
  749. },
  750. {
  751. Type: mvccpb.PUT,
  752. Kv: &mvccpb.KeyValue{Key: []byte("foo0"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 4, Version: 2},
  753. },
  754. {
  755. Type: mvccpb.PUT,
  756. Kv: &mvccpb.KeyValue{Key: []byte("foo1"), Value: []byte("bar"), CreateRevision: 3, ModRevision: 5, Version: 2},
  757. },
  758. }
  759. events := []*mvccpb.Event{}
  760. for len(events) < 4 {
  761. resp, err := wStream.Recv()
  762. if err != nil {
  763. t.Errorf("wStream.Recv error: %v", err)
  764. }
  765. if resp.Created {
  766. continue
  767. }
  768. events = append(events, resp.Events...)
  769. // if PUT requests are committed by now, first receive would return
  770. // multiple events, but if not, it returns a single event. In SSD,
  771. // it should return 4 events at once.
  772. }
  773. if !reflect.DeepEqual(events, allWevents) {
  774. t.Errorf("events got = %+v, want = %+v", events, allWevents)
  775. }
  776. rok, nr := waitResponse(wStream, 1*time.Second)
  777. if !rok {
  778. t.Errorf("unexpected pb.WatchResponse is received %+v", nr)
  779. }
  780. }
  781. func TestV3WatchMultipleStreamsSynced(t *testing.T) {
  782. defer testutil.AfterTest(t)
  783. testV3WatchMultipleStreams(t, 0)
  784. }
  785. func TestV3WatchMultipleStreamsUnsynced(t *testing.T) {
  786. defer testutil.AfterTest(t)
  787. testV3WatchMultipleStreams(t, 1)
  788. }
  789. // testV3WatchMultipleStreams tests multiple watchers on the same key on multiple streams.
  790. func testV3WatchMultipleStreams(t *testing.T, startRev int64) {
  791. clus := NewClusterV3(t, &ClusterConfig{Size: 3})
  792. defer clus.Terminate(t)
  793. wAPI := toGRPC(clus.RandClient()).Watch
  794. kvc := toGRPC(clus.RandClient()).KV
  795. streams := make([]pb.Watch_WatchClient, 5)
  796. for i := range streams {
  797. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  798. defer cancel()
  799. wStream, errW := wAPI.Watch(ctx)
  800. if errW != nil {
  801. t.Fatalf("wAPI.Watch error: %v", errW)
  802. }
  803. wreq := &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  804. CreateRequest: &pb.WatchCreateRequest{
  805. Key: []byte("foo"), StartRevision: startRev}}}
  806. if err := wStream.Send(wreq); err != nil {
  807. t.Fatalf("wStream.Send error: %v", err)
  808. }
  809. streams[i] = wStream
  810. }
  811. for _, wStream := range streams {
  812. wresp, err := wStream.Recv()
  813. if err != nil {
  814. t.Fatalf("wStream.Recv error: %v", err)
  815. }
  816. if !wresp.Created {
  817. t.Fatalf("wresp.Created got = %v, want = true", wresp.Created)
  818. }
  819. }
  820. if _, err := kvc.Put(context.TODO(), &pb.PutRequest{Key: []byte("foo"), Value: []byte("bar")}); err != nil {
  821. t.Fatalf("couldn't put key (%v)", err)
  822. }
  823. var wg sync.WaitGroup
  824. wg.Add(len(streams))
  825. wevents := []*mvccpb.Event{
  826. {
  827. Type: mvccpb.PUT,
  828. Kv: &mvccpb.KeyValue{Key: []byte("foo"), Value: []byte("bar"), CreateRevision: 2, ModRevision: 2, Version: 1},
  829. },
  830. }
  831. for i := range streams {
  832. go func(i int) {
  833. defer wg.Done()
  834. wStream := streams[i]
  835. wresp, err := wStream.Recv()
  836. if err != nil {
  837. t.Errorf("wStream.Recv error: %v", err)
  838. }
  839. if wresp.WatchId != 0 {
  840. t.Errorf("watchId got = %d, want = 0", wresp.WatchId)
  841. }
  842. if !reflect.DeepEqual(wresp.Events, wevents) {
  843. t.Errorf("wresp.Events got = %+v, want = %+v", wresp.Events, wevents)
  844. }
  845. // now Recv should block because there is no more events coming
  846. rok, nr := waitResponse(wStream, 1*time.Second)
  847. if !rok {
  848. t.Errorf("unexpected pb.WatchResponse is received %+v", nr)
  849. }
  850. }(i)
  851. }
  852. wg.Wait()
  853. }
  854. // waitResponse waits on the given stream for given duration.
  855. // If there is no more events, true and a nil response will be
  856. // returned closing the WatchClient stream. Or the response will
  857. // be returned.
  858. func waitResponse(wc pb.Watch_WatchClient, timeout time.Duration) (bool, *pb.WatchResponse) {
  859. rCh := make(chan *pb.WatchResponse, 1)
  860. donec := make(chan struct{})
  861. defer close(donec)
  862. go func() {
  863. resp, _ := wc.Recv()
  864. select {
  865. case rCh <- resp:
  866. case <-donec:
  867. }
  868. }()
  869. select {
  870. case nr := <-rCh:
  871. return false, nr
  872. case <-time.After(timeout):
  873. }
  874. // didn't get response
  875. wc.CloseSend()
  876. return true, nil
  877. }
  878. func TestWatchWithProgressNotify(t *testing.T) {
  879. // accelerate report interval so test terminates quickly
  880. oldpi := v3rpc.GetProgressReportInterval()
  881. // using atomics to avoid race warnings
  882. v3rpc.SetProgressReportInterval(3 * time.Second)
  883. testInterval := 3 * time.Second
  884. defer func() { v3rpc.SetProgressReportInterval(oldpi) }()
  885. defer testutil.AfterTest(t)
  886. clus := NewClusterV3(t, &ClusterConfig{Size: 3})
  887. defer clus.Terminate(t)
  888. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  889. defer cancel()
  890. wStream, wErr := toGRPC(clus.RandClient()).Watch.Watch(ctx)
  891. if wErr != nil {
  892. t.Fatalf("wAPI.Watch error: %v", wErr)
  893. }
  894. // create two watchers, one with progressNotify set.
  895. wreq := &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  896. CreateRequest: &pb.WatchCreateRequest{Key: []byte("foo"), StartRevision: 1, ProgressNotify: true}}}
  897. if err := wStream.Send(wreq); err != nil {
  898. t.Fatalf("watch request failed (%v)", err)
  899. }
  900. wreq = &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  901. CreateRequest: &pb.WatchCreateRequest{Key: []byte("foo"), StartRevision: 1}}}
  902. if err := wStream.Send(wreq); err != nil {
  903. t.Fatalf("watch request failed (%v)", err)
  904. }
  905. // two creation + one notification
  906. for i := 0; i < 3; i++ {
  907. rok, resp := waitResponse(wStream, testInterval+time.Second)
  908. if resp.Created {
  909. continue
  910. }
  911. if rok {
  912. t.Errorf("failed to receive response from watch stream")
  913. }
  914. if resp.Header.Revision != 1 {
  915. t.Errorf("revision = %d, want 1", resp.Header.Revision)
  916. }
  917. if len(resp.Events) != 0 {
  918. t.Errorf("len(resp.Events) = %d, want 0", len(resp.Events))
  919. }
  920. }
  921. // no more notification
  922. rok, resp := waitResponse(wStream, time.Second)
  923. if !rok {
  924. t.Errorf("unexpected pb.WatchResponse is received %+v", resp)
  925. }
  926. }
  927. // TestV3WatcMultiOpenhClose opens many watchers concurrently on multiple streams.
  928. func TestV3WatchClose(t *testing.T) {
  929. defer testutil.AfterTest(t)
  930. clus := NewClusterV3(t, &ClusterConfig{Size: 1})
  931. defer clus.Terminate(t)
  932. c := clus.Client(0)
  933. wapi := toGRPC(c).Watch
  934. var wg sync.WaitGroup
  935. wg.Add(100)
  936. for i := 0; i < 100; i++ {
  937. go func() {
  938. ctx, cancel := context.WithCancel(context.TODO())
  939. defer func() {
  940. wg.Done()
  941. cancel()
  942. }()
  943. ws, err := wapi.Watch(ctx)
  944. if err != nil {
  945. return
  946. }
  947. cr := &pb.WatchCreateRequest{Key: []byte("a")}
  948. req := &pb.WatchRequest{
  949. RequestUnion: &pb.WatchRequest_CreateRequest{
  950. CreateRequest: cr}}
  951. ws.Send(req)
  952. ws.Recv()
  953. }()
  954. }
  955. clus.Members[0].DropConnections()
  956. wg.Wait()
  957. }
  958. // TestV3WatchWithFilter ensures watcher filters out the events correctly.
  959. func TestV3WatchWithFilter(t *testing.T) {
  960. clus := NewClusterV3(t, &ClusterConfig{Size: 1})
  961. defer clus.Terminate(t)
  962. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  963. defer cancel()
  964. ws, werr := toGRPC(clus.RandClient()).Watch.Watch(ctx)
  965. if werr != nil {
  966. t.Fatal(werr)
  967. }
  968. req := &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  969. CreateRequest: &pb.WatchCreateRequest{
  970. Key: []byte("foo"),
  971. Filters: []pb.WatchCreateRequest_FilterType{pb.WatchCreateRequest_NOPUT},
  972. }}}
  973. if err := ws.Send(req); err != nil {
  974. t.Fatal(err)
  975. }
  976. if _, err := ws.Recv(); err != nil {
  977. t.Fatal(err)
  978. }
  979. recv := make(chan *pb.WatchResponse)
  980. go func() {
  981. // check received PUT
  982. resp, rerr := ws.Recv()
  983. if rerr != nil {
  984. t.Error(rerr)
  985. }
  986. recv <- resp
  987. }()
  988. // put a key with empty value
  989. kvc := toGRPC(clus.RandClient()).KV
  990. preq := &pb.PutRequest{Key: []byte("foo")}
  991. if _, err := kvc.Put(context.TODO(), preq); err != nil {
  992. t.Fatal(err)
  993. }
  994. select {
  995. case <-recv:
  996. t.Fatal("failed to filter out put event")
  997. case <-time.After(100 * time.Millisecond):
  998. }
  999. dreq := &pb.DeleteRangeRequest{Key: []byte("foo")}
  1000. if _, err := kvc.DeleteRange(context.TODO(), dreq); err != nil {
  1001. t.Fatal(err)
  1002. }
  1003. select {
  1004. case resp := <-recv:
  1005. wevs := []*mvccpb.Event{
  1006. {
  1007. Type: mvccpb.DELETE,
  1008. Kv: &mvccpb.KeyValue{Key: []byte("foo"), ModRevision: 3},
  1009. },
  1010. }
  1011. if !reflect.DeepEqual(resp.Events, wevs) {
  1012. t.Fatalf("got %v, expected %v", resp.Events, wevs)
  1013. }
  1014. case <-time.After(100 * time.Millisecond):
  1015. t.Fatal("failed to receive delete event")
  1016. }
  1017. }
  1018. func TestV3WatchWithPrevKV(t *testing.T) {
  1019. defer testutil.AfterTest(t)
  1020. clus := NewClusterV3(t, &ClusterConfig{Size: 1})
  1021. defer clus.Terminate(t)
  1022. wctx, wcancel := context.WithCancel(context.Background())
  1023. defer wcancel()
  1024. tests := []struct {
  1025. key string
  1026. end string
  1027. vals []string
  1028. }{{
  1029. key: "foo",
  1030. end: "fop",
  1031. vals: []string{"bar1", "bar2"},
  1032. }, {
  1033. key: "/abc",
  1034. end: "/abd",
  1035. vals: []string{"first", "second"},
  1036. }}
  1037. for i, tt := range tests {
  1038. kvc := toGRPC(clus.RandClient()).KV
  1039. if _, err := kvc.Put(context.TODO(), &pb.PutRequest{Key: []byte(tt.key), Value: []byte(tt.vals[0])}); err != nil {
  1040. t.Fatal(err)
  1041. }
  1042. ws, werr := toGRPC(clus.RandClient()).Watch.Watch(wctx)
  1043. if werr != nil {
  1044. t.Fatal(werr)
  1045. }
  1046. req := &pb.WatchRequest{RequestUnion: &pb.WatchRequest_CreateRequest{
  1047. CreateRequest: &pb.WatchCreateRequest{
  1048. Key: []byte(tt.key),
  1049. RangeEnd: []byte(tt.end),
  1050. PrevKv: true,
  1051. }}}
  1052. if err := ws.Send(req); err != nil {
  1053. t.Fatal(err)
  1054. }
  1055. if _, err := ws.Recv(); err != nil {
  1056. t.Fatal(err)
  1057. }
  1058. if _, err := kvc.Put(context.TODO(), &pb.PutRequest{Key: []byte(tt.key), Value: []byte(tt.vals[1])}); err != nil {
  1059. t.Fatal(err)
  1060. }
  1061. recv := make(chan *pb.WatchResponse)
  1062. go func() {
  1063. // check received PUT
  1064. resp, rerr := ws.Recv()
  1065. if rerr != nil {
  1066. t.Error(rerr)
  1067. }
  1068. recv <- resp
  1069. }()
  1070. select {
  1071. case resp := <-recv:
  1072. if tt.vals[1] != string(resp.Events[0].Kv.Value) {
  1073. t.Errorf("#%d: unequal value: want=%s, get=%s", i, tt.vals[1], resp.Events[0].Kv.Value)
  1074. }
  1075. if tt.vals[0] != string(resp.Events[0].PrevKv.Value) {
  1076. t.Errorf("#%d: unequal value: want=%s, get=%s", i, tt.vals[0], resp.Events[0].PrevKv.Value)
  1077. }
  1078. case <-time.After(30 * time.Second):
  1079. t.Error("timeout waiting for watch response")
  1080. }
  1081. }
  1082. }