github.com/qiniu/go-sdk/v7@v7.27.0/storagev2/downloader/destination/destination_test.go (about)

     1  //go:build unit
     2  // +build unit
     3  
     4  package destination_test
     5  
     6  import (
     7  	"bytes"
     8  	"crypto/md5"
     9  	"errors"
    10  	"io"
    11  	"math/rand"
    12  	"os"
    13  	"sync"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/qiniu/go-sdk/v7/storagev2/downloader/destination"
    18  )
    19  
    20  func TestSeekableDestination(t *testing.T) {
    21  	tmpFile, err := os.CreateTemp("", "test-seekable-destination-*")
    22  	if err != nil {
    23  		t.Fatal(err)
    24  	}
    25  	defer os.Remove(tmpFile.Name())
    26  	defer tmpFile.Close()
    27  
    28  	dest := destination.NewWriteAtCloserDestination(tmpFile, tmpFile.Name())
    29  	parts, err := dest.Split(1024*1024*1024, 1024*1024, nil)
    30  	if err != nil {
    31  		t.Fatal(err)
    32  	}
    33  	if len(parts) != 1024 {
    34  		t.Fatalf("unexpected slices")
    35  	}
    36  
    37  	var (
    38  		wg   sync.WaitGroup
    39  		lock sync.Mutex
    40  	)
    41  
    42  	for i, part := range parts {
    43  		wg.Add(1)
    44  		go func(i int, part destination.Part) {
    45  			defer wg.Done()
    46  
    47  			buf := make([]byte, 1024*1024)
    48  			for j := 0; j < 1024*1024; j++ {
    49  				buf[j] = byte(i % 256)
    50  			}
    51  			var lastDownloaded uint64
    52  			if _, e := part.CopyFrom(bytes.NewReader(buf), func(downloaded uint64) {
    53  				if lastDownloaded > downloaded {
    54  					lock.Lock()
    55  					err = errors.New("unexpected downloading progress")
    56  					lock.Unlock()
    57  				}
    58  				lastDownloaded = downloaded
    59  			}); e != nil {
    60  				lock.Lock()
    61  				err = e
    62  				lock.Unlock()
    63  			}
    64  		}(i, part)
    65  	}
    66  	wg.Wait()
    67  
    68  	if err != nil {
    69  		t.Fatal(err)
    70  	}
    71  
    72  	for i := 0; i < 1024; i++ {
    73  		buf := make([]byte, 1024*1024)
    74  		_, err := tmpFile.Read(buf)
    75  		if err != nil {
    76  			t.Fatal(err)
    77  		}
    78  		for j := 0; j < len(buf); j++ {
    79  			if buf[j] != byte(i%256) {
    80  				t.Fatalf("unexpected buffer content")
    81  			}
    82  		}
    83  	}
    84  }
    85  
    86  func TestUnseekableDestination(t *testing.T) {
    87  	tmpFile, err := os.CreateTemp("", "test-unseekable-destination-*")
    88  	if err != nil {
    89  		t.Fatal(err)
    90  	}
    91  	defer os.Remove(tmpFile.Name())
    92  	defer tmpFile.Close()
    93  
    94  	dest := destination.NewWriteCloserDestination(tmpFile, tmpFile.Name())
    95  	parts, err := dest.Split(1024*1024, 1024, nil)
    96  	if err != nil {
    97  		t.Fatal(err)
    98  	}
    99  	if len(parts) != 1 {
   100  		t.Fatalf("unexpected slices")
   101  	}
   102  
   103  	md5Expected := md5.New()
   104  	r := rand.New(rand.NewSource(time.Now().UnixNano()))
   105  	var lastDownloaded uint64
   106  
   107  	if _, err = parts[0].CopyFrom(io.TeeReader(io.LimitReader(r, 1024*1024), md5Expected), func(downloaded uint64) {
   108  		if lastDownloaded > downloaded {
   109  			t.Fatalf("unexpected downloading progress")
   110  		}
   111  		lastDownloaded = downloaded
   112  	}); err != nil {
   113  		t.Fatal(err)
   114  	}
   115  	if _, err = tmpFile.Seek(0, io.SeekStart); err != nil {
   116  		t.Fatal(err)
   117  	}
   118  
   119  	md5Actual := md5.New()
   120  	if _, err = io.Copy(md5Actual, tmpFile); err != nil {
   121  		t.Fatal(err)
   122  	}
   123  	if !bytes.Equal(md5Expected.Sum(nil), md5Actual.Sum(nil)) {
   124  		t.Fatalf("unexpected md5 checksum")
   125  	}
   126  	if lastDownloaded != 1024*1024 {
   127  		t.Fatalf("unexpected downloading progress")
   128  	}
   129  }