github.com/git-lfs/git-lfs@v2.5.2+incompatible/lfs/gitscanner_pointerscanner_test.go (about)

     1  package lfs
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/sha256"
     6  	"fmt"
     7  	"io"
     8  	"math/rand"
     9  	"testing"
    10  
    11  	"github.com/git-lfs/git-lfs/git"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func TestPointerScannerWithValidOutput(t *testing.T) {
    17  	blobs := []*Pointer{
    18  		&Pointer{
    19  			Version: "https://git-lfs.github.com/spec/v1",
    20  			Oid:     "e71eefd918ea175b8f362611f981f648dbf9888ff74865077cb4c9077728f350",
    21  			Size:    123,
    22  			OidType: "sha256",
    23  		},
    24  		&Pointer{
    25  			Version: "https://git-lfs.github.com/spec/v1",
    26  			Oid:     "0eb69b651be65d5a61d6bebf2c53c811a5bf8031951111000e2077f4d7fe43b1",
    27  			Size:    132,
    28  			OidType: "sha256",
    29  		},
    30  	}
    31  
    32  	reader := fakeReaderWithRandoData(t, blobs)
    33  	if reader == nil {
    34  		return
    35  	}
    36  
    37  	scanner := &PointerScanner{
    38  		scanner: git.NewObjectScannerFrom(reader),
    39  	}
    40  
    41  	for i := 0; i < 5; i++ {
    42  		assertNextEmptyPointer(t, scanner)
    43  	}
    44  
    45  	assertNextPointer(t, scanner, "e71eefd918ea175b8f362611f981f648dbf9888ff74865077cb4c9077728f350")
    46  
    47  	for i := 0; i < 5; i++ {
    48  		assertNextEmptyPointer(t, scanner)
    49  	}
    50  
    51  	assertNextPointer(t, scanner, "0eb69b651be65d5a61d6bebf2c53c811a5bf8031951111000e2077f4d7fe43b1")
    52  
    53  	for i := 0; i < 5; i++ {
    54  		assertNextEmptyPointer(t, scanner)
    55  	}
    56  
    57  	assert.False(t, scanner.Scan(""))
    58  	assert.Nil(t, scanner.Err())
    59  	assert.Nil(t, scanner.Pointer())
    60  }
    61  
    62  func TestPointerScannerWithLargeBlobs(t *testing.T) {
    63  	buf := bytes.NewBuffer(make([]byte, 0, 1025))
    64  	sha := sha256.New()
    65  	rng := rand.New(rand.NewSource(0))
    66  
    67  	_, err := io.CopyN(io.MultiWriter(sha, buf), rng, 1025)
    68  	require.Nil(t, err)
    69  
    70  	fake := bytes.NewBuffer(nil)
    71  	writeFakeBuffer(t, fake, buf.Bytes(), buf.Len())
    72  
    73  	scanner := &PointerScanner{
    74  		scanner: git.NewObjectScannerFrom(fake),
    75  	}
    76  
    77  	require.True(t, scanner.Scan(""))
    78  	assert.Nil(t, scanner.Pointer())
    79  	assert.Equal(t, fmt.Sprintf("%x", sha.Sum(nil)), scanner.ContentsSha())
    80  
    81  	assert.False(t, scanner.Scan(""))
    82  	assert.Nil(t, scanner.Err())
    83  	assert.Nil(t, scanner.Pointer())
    84  }
    85  
    86  func assertNextPointer(t *testing.T, scanner *PointerScanner, oid string) {
    87  	assert.True(t, scanner.Scan(""))
    88  	assert.Nil(t, scanner.Err())
    89  
    90  	p := scanner.Pointer()
    91  
    92  	assert.NotNil(t, p)
    93  	assert.Equal(t, oid, p.Oid)
    94  }
    95  
    96  func assertNextEmptyPointer(t *testing.T, scanner *PointerScanner) {
    97  	assert.True(t, scanner.Scan(""))
    98  	assert.Nil(t, scanner.Err())
    99  
   100  	assert.Nil(t, scanner.Pointer())
   101  }
   102  
   103  func fakeReaderWithRandoData(t *testing.T, blobs []*Pointer) io.Reader {
   104  	buf := &bytes.Buffer{}
   105  	rngbuf := make([]byte, 1000) // just under blob size cutoff
   106  	rng := rand.New(rand.NewSource(0))
   107  
   108  	for i := 0; i < 5; i++ {
   109  		n, err := io.ReadFull(rng, rngbuf)
   110  		if err != nil {
   111  			t.Fatalf("error reading from rng: %+v", err)
   112  		}
   113  		writeFakeBuffer(t, buf, rngbuf, n)
   114  	}
   115  
   116  	for _, b := range blobs {
   117  		ptrtext := b.Encoded()
   118  		writeFakeBuffer(t, buf, []byte(ptrtext), len(ptrtext))
   119  		for i := 0; i < 5; i++ {
   120  			n, err := io.ReadFull(rng, rngbuf)
   121  			if err != nil {
   122  				t.Fatalf("error reading from rng: %+v", err)
   123  			}
   124  			writeFakeBuffer(t, buf, rngbuf, n)
   125  		}
   126  	}
   127  
   128  	return bytes.NewBuffer(buf.Bytes())
   129  }
   130  
   131  func writeFakeBuffer(t *testing.T, buf *bytes.Buffer, by []byte, size int) {
   132  	header := fmt.Sprintf("0000000000000000000000000000000000000000 blob %d", size)
   133  	t.Log(header)
   134  	buf.WriteString(header + "\n")
   135  	buf.Write(by)
   136  	buf.Write([]byte("\n"))
   137  }