gitee.com/quant1x/gox@v1.21.2/cache/mmap_test.go (about)

     1  // Copyright 2011 Evan Shaw. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // These tests are adapted from gommap: http://labix.org/gommap
     6  // Copyright (c) 2010, Gustavo Niemeyer <gustavo@niemeyer.net>
     7  
     8  package cache
     9  
    10  import (
    11  	"bytes"
    12  	"io/ioutil"
    13  	"os"
    14  	"path/filepath"
    15  	"testing"
    16  )
    17  
    18  var testData = []byte("0123456789ABCDEF")
    19  var testPath = filepath.Join(os.TempDir(), "testdata")
    20  
    21  func init() {
    22  	f := openFile(os.O_RDWR | os.O_CREATE | os.O_TRUNC)
    23  	f.Write(testData)
    24  	f.Close()
    25  }
    26  
    27  func openFile(flags int) *os.File {
    28  	f, err := os.OpenFile(testPath, flags, 0644)
    29  	if err != nil {
    30  		panic(err.Error())
    31  	}
    32  	return f
    33  }
    34  
    35  func TestUnmap(t *testing.T) {
    36  	f := openFile(os.O_RDONLY)
    37  	defer f.Close()
    38  	mmap, err := FileMap(f, RDONLY, 0)
    39  	if err != nil {
    40  		t.Errorf("error mapping: %s", err)
    41  	}
    42  	if err := mmap.Unmap(); err != nil {
    43  		t.Errorf("error unmapping: %s", err)
    44  	}
    45  }
    46  
    47  func TestReadWrite(t *testing.T) {
    48  	f := openFile(os.O_RDWR)
    49  	defer f.Close()
    50  	mmap, err := FileMap(f, RDWR, 0)
    51  	if err != nil {
    52  		t.Errorf("error mapping: %s", err)
    53  	}
    54  	defer mmap.Unmap()
    55  	if !bytes.Equal(testData, mmap) {
    56  		t.Errorf("mmap != testData: %q, %q", mmap, testData)
    57  	}
    58  
    59  	mmap[9] = 'X'
    60  	mmap.Flush()
    61  
    62  	fileData, err := ioutil.ReadAll(f)
    63  	if err != nil {
    64  		t.Errorf("error reading file: %s", err)
    65  	}
    66  	if !bytes.Equal(fileData, []byte("012345678XABCDEF")) {
    67  		t.Errorf("file wasn't modified")
    68  	}
    69  
    70  	// leave things how we found them
    71  	mmap[9] = '9'
    72  	mmap.Flush()
    73  }
    74  
    75  func TestProtFlagsAndErr(t *testing.T) {
    76  	f := openFile(os.O_RDONLY)
    77  	defer f.Close()
    78  	if _, err := FileMap(f, RDWR, 0); err == nil {
    79  		t.Errorf("expected error")
    80  	}
    81  }
    82  
    83  func TestFlags(t *testing.T) {
    84  	f := openFile(os.O_RDWR)
    85  	defer f.Close()
    86  	mmap, err := FileMap(f, COPY, 0)
    87  	if err != nil {
    88  		t.Errorf("error mapping: %s", err)
    89  	}
    90  	defer mmap.Unmap()
    91  
    92  	mmap[9] = 'X'
    93  	mmap.Flush()
    94  
    95  	fileData, err := ioutil.ReadAll(f)
    96  	if err != nil {
    97  		t.Errorf("error reading file: %s", err)
    98  	}
    99  	if !bytes.Equal(fileData, testData) {
   100  		t.Errorf("file was modified")
   101  	}
   102  }
   103  
   104  // Test that we can map files from non-0 offsets
   105  // The page size on most Unixes is 4KB, but on Windows it's 64KB
   106  func TestNonZeroOffset(t *testing.T) {
   107  	const pageSize = 65536
   108  
   109  	// Create a 2-page sized file
   110  	bigFilePath := filepath.Join(os.TempDir(), "nonzero")
   111  	fileobj, err := os.OpenFile(bigFilePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
   112  	if err != nil {
   113  		panic(err.Error())
   114  	}
   115  
   116  	bigData := make([]byte, 2*pageSize, 2*pageSize)
   117  	fileobj.Write(bigData)
   118  	fileobj.Close()
   119  
   120  	// FileMap the first page by itself
   121  	fileobj, err = os.OpenFile(bigFilePath, os.O_RDONLY, 0)
   122  	if err != nil {
   123  		panic(err.Error())
   124  	}
   125  	m, err := MapRegion(fileobj, pageSize, RDONLY, 0, 0)
   126  	if err != nil {
   127  		t.Errorf("error mapping file: %s", err)
   128  	}
   129  	m.Unmap()
   130  	fileobj.Close()
   131  
   132  	// FileMap the second page by itself
   133  	fileobj, err = os.OpenFile(bigFilePath, os.O_RDONLY, 0)
   134  	if err != nil {
   135  		panic(err.Error())
   136  	}
   137  	m, err = MapRegion(fileobj, pageSize, RDONLY, 0, pageSize)
   138  	if err != nil {
   139  		t.Errorf("error mapping file: %s", err)
   140  	}
   141  	err = m.Unmap()
   142  	if err != nil {
   143  		t.Error(err)
   144  	}
   145  
   146  	m, err = MapRegion(fileobj, pageSize, RDONLY, 0, 1)
   147  	if err == nil {
   148  		t.Error("expect error because offset is not multiple of page size")
   149  	}
   150  
   151  	fileobj.Close()
   152  }
   153  
   154  func TestAnonymousMapping(t *testing.T) {
   155  	const size = 4 * 1024
   156  
   157  	// Make an anonymous region
   158  	mem, err := MapRegion(nil, size, RDWR, ANON, 0)
   159  	if err != nil {
   160  		t.Fatalf("failed to allocate memory for buffer: %v", err)
   161  	}
   162  
   163  	// Check memory writable
   164  	for i := 0; i < size; i++ {
   165  		mem[i] = 0x55
   166  	}
   167  
   168  	// And unmap it
   169  	err = mem.Unmap()
   170  	if err != nil {
   171  		t.Fatalf("failed to unmap memory for buffer: %v", err)
   172  	}
   173  }