github.com/criteo-forks/consul@v1.4.5-criteonogrpc/api/snapshot_test.go (about) 1 package api 2 3 import ( 4 "bytes" 5 "strings" 6 "testing" 7 ) 8 9 func TestAPI_Snapshot(t *testing.T) { 10 t.Parallel() 11 c, s := makeClient(t) 12 defer s.Stop() 13 14 // Place an initial key into the store. 15 kv := c.KV() 16 key := &KVPair{Key: testKey(), Value: []byte("hello")} 17 if _, err := kv.Put(key, nil); err != nil { 18 t.Fatalf("err: %v", err) 19 } 20 21 // Make sure it reads back. 22 pair, _, err := kv.Get(key.Key, nil) 23 if err != nil { 24 t.Fatalf("err: %v", err) 25 } 26 if pair == nil { 27 t.Fatalf("expected value: %#v", pair) 28 } 29 if !bytes.Equal(pair.Value, []byte("hello")) { 30 t.Fatalf("unexpected value: %#v", pair) 31 } 32 33 // Take a snapshot. 34 snapshot := c.Snapshot() 35 snap, qm, err := snapshot.Save(nil) 36 if err != nil { 37 t.Fatalf("err: %v", err) 38 } 39 defer snap.Close() 40 41 // Sanity check th query metadata. 42 if qm.LastIndex == 0 || !qm.KnownLeader || 43 qm.RequestTime == 0 { 44 t.Fatalf("bad: %v", qm) 45 } 46 47 // Overwrite the key's value. 48 key.Value = []byte("goodbye") 49 if _, err := kv.Put(key, nil); err != nil { 50 t.Fatalf("err: %v", err) 51 } 52 53 // Read the key back and look for the new value. 54 pair, _, err = kv.Get(key.Key, nil) 55 if err != nil { 56 t.Fatalf("err: %v", err) 57 } 58 if pair == nil { 59 t.Fatalf("expected value: %#v", pair) 60 } 61 if !bytes.Equal(pair.Value, []byte("goodbye")) { 62 t.Fatalf("unexpected value: %#v", pair) 63 } 64 65 // Restore the snapshot. 66 if err := snapshot.Restore(nil, snap); err != nil { 67 t.Fatalf("err: %v", err) 68 } 69 70 // Read the key back and look for the original value. 71 pair, _, err = kv.Get(key.Key, nil) 72 if err != nil { 73 t.Fatalf("err: %v", err) 74 } 75 if pair == nil { 76 t.Fatalf("expected value: %#v", pair) 77 } 78 if !bytes.Equal(pair.Value, []byte("hello")) { 79 t.Fatalf("unexpected value: %#v", pair) 80 } 81 } 82 83 func TestAPI_Snapshot_Options(t *testing.T) { 84 t.Parallel() 85 c, s := makeACLClient(t) 86 defer s.Stop() 87 88 // Try to take a snapshot with a bad token. 89 snapshot := c.Snapshot() 90 _, _, err := snapshot.Save(&QueryOptions{Token: "anonymous"}) 91 if err == nil || !strings.Contains(err.Error(), "Permission denied") { 92 t.Fatalf("err: %v", err) 93 } 94 95 // Now try an unknown DC. 96 _, _, err = snapshot.Save(&QueryOptions{Datacenter: "nope"}) 97 if err == nil || !strings.Contains(err.Error(), "No path to datacenter") { 98 t.Fatalf("err: %v", err) 99 } 100 101 // This should work with a valid token. 102 snap, _, err := snapshot.Save(&QueryOptions{Token: "root"}) 103 if err != nil { 104 t.Fatalf("err: %v", err) 105 } 106 defer snap.Close() 107 108 // This should work with a stale snapshot. This doesn't have good feedback 109 // that the stale option was sent, but it makes sure nothing bad happens. 110 snap, _, err = snapshot.Save(&QueryOptions{Token: "root", AllowStale: true}) 111 if err != nil { 112 t.Fatalf("err: %v", err) 113 } 114 defer snap.Close() 115 116 // Try to restore a snapshot with a bad token. 117 null := bytes.NewReader([]byte("")) 118 err = snapshot.Restore(&WriteOptions{Token: "anonymous"}, null) 119 if err == nil || !strings.Contains(err.Error(), "Permission denied") { 120 t.Fatalf("err: %v", err) 121 } 122 123 // Now try an unknown DC. 124 null = bytes.NewReader([]byte("")) 125 err = snapshot.Restore(&WriteOptions{Datacenter: "nope"}, null) 126 if err == nil || !strings.Contains(err.Error(), "No path to datacenter") { 127 t.Fatalf("err: %v", err) 128 } 129 130 // This should work. 131 if err := snapshot.Restore(&WriteOptions{Token: "root"}, snap); err != nil { 132 t.Fatalf("err: %v", err) 133 } 134 }