github.com/hernad/nomad@v1.6.112/helper/snapshot/archive_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package snapshot 5 6 import ( 7 "bytes" 8 "crypto/rand" 9 "fmt" 10 "io" 11 "os" 12 "reflect" 13 "strings" 14 "testing" 15 16 "github.com/hashicorp/raft" 17 ) 18 19 func TestArchive(t *testing.T) { 20 // Create some fake snapshot data. 21 metadata := raft.SnapshotMeta{ 22 Index: 2005, 23 Term: 2011, 24 Configuration: raft.Configuration{ 25 Servers: []raft.Server{ 26 { 27 Suffrage: raft.Voter, 28 ID: raft.ServerID("hello"), 29 Address: raft.ServerAddress("127.0.0.1:8300"), 30 }, 31 }, 32 }, 33 Size: 1024, 34 } 35 var snap bytes.Buffer 36 var expected bytes.Buffer 37 both := io.MultiWriter(&snap, &expected) 38 if _, err := io.Copy(both, io.LimitReader(rand.Reader, 1024)); err != nil { 39 t.Fatalf("err: %v", err) 40 } 41 42 // Write out the snapshot. 43 var archive bytes.Buffer 44 if err := write(&archive, &metadata, &snap); err != nil { 45 t.Fatalf("err: %v", err) 46 } 47 48 // Read the snapshot back. 49 var newMeta raft.SnapshotMeta 50 var newSnap bytes.Buffer 51 if err := read(&archive, &newMeta, &newSnap); err != nil { 52 t.Fatalf("err: %v", err) 53 } 54 55 // Check the contents. 56 if !reflect.DeepEqual(newMeta, metadata) { 57 t.Fatalf("bad: %#v", newMeta) 58 } 59 var buf bytes.Buffer 60 if _, err := io.Copy(&buf, &newSnap); err != nil { 61 t.Fatalf("err: %v", err) 62 } 63 if !bytes.Equal(buf.Bytes(), expected.Bytes()) { 64 t.Fatalf("snapshot contents didn't match") 65 } 66 } 67 68 func TestArchive_GoodData(t *testing.T) { 69 paths := []string{ 70 "./testdata/snapshot/spaces-meta.tar", 71 } 72 for i, p := range paths { 73 f, err := os.Open(p) 74 if err != nil { 75 t.Fatalf("err: %v", err) 76 } 77 defer f.Close() 78 79 var metadata raft.SnapshotMeta 80 err = read(f, &metadata, io.Discard) 81 if err != nil { 82 t.Fatalf("case %d: should've read the snapshot, but didn't: %v", i, err) 83 } 84 } 85 } 86 87 func TestArchive_BadData(t *testing.T) { 88 cases := []struct { 89 Name string 90 Error string 91 }{ 92 {"./testdata/snapshot/empty.tar", "failed checking integrity of snapshot"}, 93 {"./testdata/snapshot/extra.tar", "unexpected file \"nope\""}, 94 {"./testdata/snapshot/missing-meta.tar", "hash check failed for \"meta.json\""}, 95 {"./testdata/snapshot/missing-state.tar", "hash check failed for \"state.bin\""}, 96 {"./testdata/snapshot/missing-sha.tar", "file missing"}, 97 {"./testdata/snapshot/corrupt-meta.tar", "hash check failed for \"meta.json\""}, 98 {"./testdata/snapshot/corrupt-state.tar", "hash check failed for \"state.bin\""}, 99 {"./testdata/snapshot/corrupt-sha.tar", "list missing hash for \"nope\""}, 100 } 101 for i, c := range cases { 102 f, err := os.Open(c.Name) 103 if err != nil { 104 t.Fatalf("err: %v", err) 105 } 106 defer f.Close() 107 108 var metadata raft.SnapshotMeta 109 err = read(f, &metadata, io.Discard) 110 if err == nil || !strings.Contains(err.Error(), c.Error) { 111 t.Fatalf("case %d (%s): %v", i, c.Name, err) 112 } 113 } 114 } 115 116 func TestArchive_hashList(t *testing.T) { 117 hl := newHashList() 118 for i := 0; i < 16; i++ { 119 h := hl.Add(fmt.Sprintf("file-%d", i)) 120 if _, err := io.CopyN(h, rand.Reader, 32); err != nil { 121 t.Fatalf("err: %v", err) 122 } 123 } 124 125 // Do a normal round trip. 126 var buf bytes.Buffer 127 if err := hl.Encode(&buf); err != nil { 128 t.Fatalf("err: %v", err) 129 } 130 if err := hl.DecodeAndVerify(&buf); err != nil { 131 t.Fatalf("err: %v", err) 132 } 133 134 // Have a local hash that isn't in the file. 135 buf.Reset() 136 if err := hl.Encode(&buf); err != nil { 137 t.Fatalf("err: %v", err) 138 } 139 hl.Add("nope") 140 err := hl.DecodeAndVerify(&buf) 141 if err == nil || !strings.Contains(err.Error(), "file missing for \"nope\"") { 142 t.Fatalf("err: %v", err) 143 } 144 145 // Have a hash in the file that we haven't seen locally. 146 buf.Reset() 147 if err := hl.Encode(&buf); err != nil { 148 t.Fatalf("err: %v", err) 149 } 150 delete(hl.hashes, "nope") 151 err = hl.DecodeAndVerify(&buf) 152 if err == nil || !strings.Contains(err.Error(), "list missing hash for \"nope\"") { 153 t.Fatalf("err: %v", err) 154 } 155 }