github.com/jojicluka/consul-api@v1.4.5/snapshot/archive_test.go (about)

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