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  }