1package raft 2 3import ( 4 "bytes" 5 "io" 6 "reflect" 7 "testing" 8) 9 10func TestInmemSnapshotStoreImpl(t *testing.T) { 11 var impl interface{} = &InmemSnapshotStore{} 12 if _, ok := impl.(SnapshotStore); !ok { 13 t.Fatalf("InmemSnapshotStore not a SnapshotStore") 14 } 15} 16 17func TestInmemSnapshotSinkImpl(t *testing.T) { 18 var impl interface{} = &InmemSnapshotSink{} 19 if _, ok := impl.(SnapshotSink); !ok { 20 t.Fatalf("InmemSnapshotSink not a SnapshotSink") 21 } 22} 23 24func TestInmemSS_CreateSnapshot(t *testing.T) { 25 snap := NewInmemSnapshotStore() 26 27 // Check no snapshots 28 snaps, err := snap.List() 29 if err != nil { 30 t.Fatalf("err: %v", err) 31 } 32 if len(snaps) != 0 { 33 t.Fatalf("did not expect any snapshots: %v", snaps) 34 } 35 36 // Create a new sink 37 var configuration Configuration 38 configuration.Servers = append(configuration.Servers, Server{ 39 Suffrage: Voter, 40 ID: ServerID("my id"), 41 Address: ServerAddress("over here"), 42 }) 43 _, trans := NewInmemTransport(NewInmemAddr()) 44 sink, err := snap.Create(SnapshotVersionMax, 10, 3, configuration, 2, trans) 45 if err != nil { 46 t.Fatalf("err: %v", err) 47 } 48 49 // The sink is not done, should not be in a list! 50 snaps, err = snap.List() 51 if err != nil { 52 t.Fatalf("err: %v", err) 53 } 54 if len(snaps) != 1 { 55 t.Fatalf("should always be 1 snapshot: %v", snaps) 56 } 57 58 // Write to the sink 59 _, err = sink.Write([]byte("first\n")) 60 if err != nil { 61 t.Fatalf("err: %v", err) 62 } 63 _, err = sink.Write([]byte("second\n")) 64 if err != nil { 65 t.Fatalf("err: %v", err) 66 } 67 68 // Done! 69 err = sink.Close() 70 if err != nil { 71 t.Fatalf("err: %v", err) 72 } 73 74 // Should have a snapshot! 75 snaps, err = snap.List() 76 if err != nil { 77 t.Fatalf("err: %v", err) 78 } 79 if len(snaps) != 1 { 80 t.Fatalf("expect a snapshots: %v", snaps) 81 } 82 83 // Check the latest 84 latest := snaps[0] 85 if latest.Index != 10 { 86 t.Fatalf("bad snapshot: %v", *latest) 87 } 88 if latest.Term != 3 { 89 t.Fatalf("bad snapshot: %v", *latest) 90 } 91 if !reflect.DeepEqual(latest.Configuration, configuration) { 92 t.Fatalf("bad snapshot: %v", *latest) 93 } 94 if latest.ConfigurationIndex != 2 { 95 t.Fatalf("bad snapshot: %v", *latest) 96 } 97 if latest.Size != 13 { 98 t.Fatalf("bad snapshot: %v", *latest) 99 } 100 101 // Read the snapshot 102 _, r, err := snap.Open(latest.ID) 103 if err != nil { 104 t.Fatalf("err: %v", err) 105 } 106 107 // Read out everything 108 var buf bytes.Buffer 109 if _, err := io.Copy(&buf, r); err != nil { 110 t.Fatalf("err: %v", err) 111 } 112 if err := r.Close(); err != nil { 113 t.Fatalf("err: %v", err) 114 } 115 116 // Ensure a match 117 if bytes.Compare(buf.Bytes(), []byte("first\nsecond\n")) != 0 { 118 t.Fatalf("content mismatch") 119 } 120} 121 122func TestInmemSS_OpenSnapshotTwice(t *testing.T) { 123 snap := NewInmemSnapshotStore() 124 125 // Create a new sink 126 var configuration Configuration 127 configuration.Servers = append(configuration.Servers, Server{ 128 Suffrage: Voter, 129 ID: ServerID("my id"), 130 Address: ServerAddress("over here"), 131 }) 132 _, trans := NewInmemTransport(NewInmemAddr()) 133 sink, err := snap.Create(SnapshotVersionMax, 10, 3, configuration, 2, trans) 134 if err != nil { 135 t.Fatalf("err: %v", err) 136 } 137 138 // Write to the sink 139 _, err = sink.Write([]byte("data\n")) 140 if err != nil { 141 t.Fatalf("err: %v", err) 142 } 143 err = sink.Close() 144 if err != nil { 145 t.Fatalf("err: %v", err) 146 } 147 148 // Read the snapshot a first time 149 _, r, err := snap.Open(sink.ID()) 150 if err != nil { 151 t.Fatalf("err: %v", err) 152 } 153 154 // Read out everything 155 var buf1 bytes.Buffer 156 if _, err = io.Copy(&buf1, r); err != nil { 157 t.Fatalf("err: %v", err) 158 } 159 if err = r.Close(); err != nil { 160 t.Fatalf("err: %v", err) 161 } 162 163 // Ensure a match 164 if bytes.Compare(buf1.Bytes(), []byte("data\n")) != 0 { 165 t.Fatalf("content mismatch") 166 } 167 168 // Read the snapshot a second time. 169 _, r, err = snap.Open(sink.ID()) 170 if err != nil { 171 t.Fatalf("err: %v", err) 172 } 173 174 // Read out everything again 175 var buf2 bytes.Buffer 176 if _, err := io.Copy(&buf2, r); err != nil { 177 t.Fatalf("err: %v", err) 178 } 179 if err := r.Close(); err != nil { 180 t.Fatalf("err: %v", err) 181 } 182 183 // Ensure it's still the same content 184 if bytes.Compare(buf2.Bytes(), []byte("data\n")) != 0 { 185 t.Fatalf("content mismatch") 186 } 187} 188