github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/shm/shm_test.go (about)

     1  package shm_test
     2  
     3  import (
     4  	"github.com/angenalZZZ/gofunc/data/shm"
     5  	"io"
     6  	"reflect"
     7  	"strings"
     8  	"sync"
     9  	"testing"
    10  )
    11  
    12  func create(t *testing.T, tag string, size int32) *shm.SharedMemory {
    13  	t.Helper()
    14  
    15  	m, err := shm.Create(tag, size)
    16  	if err != nil {
    17  		t.Fatalf("fail: create shared memroy %v", err)
    18  	}
    19  	return m
    20  }
    21  
    22  func open(t *testing.T, tag string, size int32) *shm.SharedMemory {
    23  	t.Helper()
    24  
    25  	m, err := shm.Open(tag, size)
    26  	if err != nil {
    27  		t.Fatalf("fail: open shared memroy %v", err)
    28  	}
    29  	return m
    30  }
    31  
    32  func TestNewOpen(t *testing.T) {
    33  	for d := uint(1); d <= 30; d++ {
    34  		size := int32(1) << d
    35  
    36  		// create shared memory
    37  		w, err := shm.Create("test_t", size)
    38  		if err != nil {
    39  			t.Errorf("warn: fail create %d byte shared memroy %v", size, err)
    40  			continue
    41  		}
    42  
    43  		// open shared memory
    44  		r, err := shm.Open("test_t", size)
    45  		if err != nil {
    46  			w.Close()
    47  			t.Errorf("warn: fail open %d byte shared memroy %v", size, err)
    48  			continue
    49  		}
    50  
    51  		w.Close()
    52  		r.Close()
    53  	}
    54  }
    55  
    56  func TestReadWriteAt(t *testing.T) {
    57  	tests := []struct {
    58  		size int
    59  		data string
    60  	}{
    61  		{size: 1, data: "a"},                      // single
    62  		{size: 63, data: strings.Repeat("a", 63)}, // full - 1
    63  		{size: 64, data: strings.Repeat("b", 64)}, // full
    64  		{size: 64, data: strings.Repeat("c", 65)}, // shrink
    65  	}
    66  
    67  	// create shared memory
    68  	w := create(t, "test_t", 64)
    69  	defer w.Close()
    70  
    71  	// open shared memory
    72  	r := open(t, "test_t", 64)
    73  	defer r.Close()
    74  
    75  	// read/write test
    76  	for _, tt := range tests {
    77  		data := []byte(tt.data)
    78  
    79  		n, err := w.WriteAt(data, 0)
    80  		if err != nil {
    81  			t.Fatalf("fail: write shared memroy %v", err)
    82  		}
    83  		if n != tt.size {
    84  			t.Fatalf("fail: write shared memroy %d byte, want %d byte", n, tt.size)
    85  		}
    86  
    87  		buf := make([]byte, len(data))
    88  		n, err = r.ReadAt(buf, 0)
    89  		if err != nil {
    90  			t.Fatalf("fail: read shared memroy %v", err)
    91  		}
    92  		if n != tt.size {
    93  			t.Fatalf("fail: read shared memroy %d byte, want %d byte", n, tt.size)
    94  		}
    95  		if !reflect.DeepEqual(buf[:tt.size], data[:tt.size]) {
    96  			t.Fatalf("fail: read shared memroy %v, want %v", buf[:tt.size], data[:tt.size])
    97  		}
    98  	}
    99  }
   100  
   101  func TestReadWriteAt_OverPosition(t *testing.T) {
   102  	tests := []struct {
   103  		pos  int
   104  		succ bool
   105  	}{
   106  		{pos: 0, succ: true},
   107  		{pos: 63, succ: true},
   108  		{pos: 64, succ: false},
   109  	}
   110  
   111  	// create shared memory
   112  	w := create(t, "test_t", 64)
   113  	defer w.Close()
   114  
   115  	// open shared memory
   116  	r := open(t, "test_t", 64)
   117  	defer r.Close()
   118  
   119  	// write dummy
   120  	{
   121  		data := []byte(strings.Repeat("a", 64))
   122  		n, err := w.WriteAt(data, 0)
   123  		if err != nil {
   124  			t.Fatalf("fail: write shared memroy %v", err)
   125  		}
   126  		if n != 64 {
   127  			t.Fatalf("fail: write shared memroy %d byte, want %d byte", n, 64)
   128  		}
   129  	}
   130  
   131  	// read/write test
   132  	for _, tt := range tests {
   133  		data := []byte("b")
   134  		n, err := w.WriteAt(data, int64(tt.pos))
   135  		if tt.succ {
   136  			// success
   137  			if err != nil {
   138  				t.Fatalf("fail: write shared memroy %v", err)
   139  			}
   140  			if n != 1 {
   141  				t.Fatalf("fail: write shared memroy %d byte, want %d byte", n, 1)
   142  			}
   143  		} else {
   144  			// fail
   145  			if err != io.EOF {
   146  				t.Fatalf("fail: write shared memroy raise %v, want %v", err, io.EOF)
   147  			}
   148  		}
   149  
   150  		buf := make([]byte, 1)
   151  		n, err = r.ReadAt(buf, int64(tt.pos))
   152  		if tt.succ {
   153  			// success
   154  			if err != nil {
   155  				t.Fatalf("fail: read shared memroy %v", err)
   156  			}
   157  			if n != 1 {
   158  				t.Fatalf("fail: read shared memroy %d byte, want %d byte", n, 1)
   159  			}
   160  			if !reflect.DeepEqual(buf, data) {
   161  				t.Fatalf("fail: read shared memroy %v, want %v", buf, data)
   162  			}
   163  		} else {
   164  			// fail
   165  			if err != io.EOF {
   166  				t.Fatalf("fail: read shared memroy raise %v, want %v", err, io.EOF)
   167  			}
   168  		}
   169  	}
   170  }
   171  
   172  func TestReadWriteAt_MultiThreads(t *testing.T) {
   173  	tests := []struct {
   174  		size int
   175  		data string
   176  	}{
   177  		{size: 1, data: "a"},                      // single
   178  		{size: 63, data: strings.Repeat("a", 63)}, // full - 1
   179  		{size: 64, data: strings.Repeat("b", 64)}, // full
   180  		{size: 64, data: strings.Repeat("c", 65)}, // shrink
   181  	}
   182  
   183  	// create shared memory
   184  	w := create(t, "test_t", 64)
   185  	defer w.Close()
   186  
   187  	// open shared memory
   188  	r := open(t, "test_t", 64)
   189  	defer r.Close()
   190  
   191  	wg := new(sync.WaitGroup)
   192  	written := make(chan bool)
   193  	readone := make(chan bool)
   194  
   195  	// write thread
   196  	wg.Add(1)
   197  	go func() {
   198  		defer wg.Done()
   199  		for _, tt := range tests {
   200  			// write data
   201  			data := []byte(tt.data)
   202  			n, err := w.WriteAt(data, 0)
   203  			if err != nil {
   204  				written <- false
   205  				t.Fatalf("fail: write shared memroy %v", err)
   206  			}
   207  			if n != tt.size {
   208  				written <- false
   209  				t.Fatalf("fail: write shared memroy %d byte, want %d byte", n, tt.size)
   210  			}
   211  			written <- true
   212  
   213  			// wait
   214  			succ := <-readone
   215  			if !succ {
   216  				return
   217  			}
   218  		}
   219  	}()
   220  
   221  	// read thread
   222  	wg.Add(1)
   223  	go func() {
   224  		defer wg.Done()
   225  		for _, tt := range tests {
   226  			// wait
   227  			succ := <-written
   228  			if !succ {
   229  				return
   230  			}
   231  
   232  			// read data
   233  			data := []byte(tt.data)
   234  			buf := make([]byte, len(data))
   235  			n, err := r.ReadAt(buf, 0)
   236  			if err != nil {
   237  				readone <- false
   238  				t.Fatalf("fail: read shared memroy %v", err)
   239  			}
   240  			if n != tt.size {
   241  				readone <- false
   242  				t.Fatalf("fail: read shared memroy %d byte, want %d byte", n, tt.size)
   243  			}
   244  			if !reflect.DeepEqual(buf[:tt.size], data[:tt.size]) {
   245  				readone <- false
   246  				t.Fatalf("fail: read shared memroy %v, want %v", buf[:tt.size], data[:tt.size])
   247  			}
   248  			readone <- true
   249  		}
   250  	}()
   251  
   252  	wg.Wait()
   253  }
   254  
   255  func TestReadWrite(t *testing.T) {
   256  	tests := []struct {
   257  		succ bool
   258  		data string
   259  	}{
   260  		{succ: true, data: "a"},                     // single
   261  		{succ: true, data: strings.Repeat("b", 63)}, // full
   262  		{succ: false, data: "c"},                    // overflow (EOF)
   263  	}
   264  
   265  	// create shared memory
   266  	w := create(t, "test_t", 64)
   267  	defer w.Close()
   268  
   269  	// open shared memory
   270  	r := open(t, "test_t", 64)
   271  	defer r.Close()
   272  
   273  	// read/write test
   274  	for _, tt := range tests {
   275  		data := []byte(tt.data)
   276  
   277  		n, err := w.Write(data)
   278  		if tt.succ {
   279  			// success
   280  			if err != nil {
   281  				t.Fatalf("fail: write shared memroy %v", err)
   282  			}
   283  			if n != len(data) {
   284  				t.Fatalf("fail: write shared memroy %d byte, want %d byte", n, len(data))
   285  			}
   286  		} else {
   287  			// fail
   288  			if err != io.EOF {
   289  				t.Fatalf("fail: write shared memroy raise %v, want %v", err, io.EOF)
   290  			}
   291  		}
   292  
   293  		buf := make([]byte, len(data))
   294  		n, err = r.Read(buf)
   295  		if tt.succ {
   296  			// success
   297  			if err != nil {
   298  				t.Fatalf("fail: read shared memroy %v", err)
   299  			}
   300  			if n != len(data) {
   301  				t.Fatalf("fail: read shared memroy %d byte, want %d byte", n, len(data))
   302  			}
   303  			if !reflect.DeepEqual(buf, data) {
   304  				t.Fatalf("fail: read shared memroy %v, want %v", buf, data)
   305  			}
   306  		} else {
   307  			// fail
   308  			if err != io.EOF {
   309  				t.Fatalf("fail: read shared memroy raise %v, want %v", err, io.EOF)
   310  			}
   311  		}
   312  	}
   313  }
   314  
   315  func TestReadWrite_MultiThreads(t *testing.T) {
   316  	tests := []struct {
   317  		size int
   318  		data string
   319  	}{
   320  		{size: 1, data: "a"},                      // single
   321  		{size: 62, data: strings.Repeat("a", 62)}, // full - 1
   322  		{size: 1, data: strings.Repeat("b", 10)},  // shrink
   323  	}
   324  
   325  	// create shared memory
   326  	w := create(t, "test_t", 64)
   327  	defer w.Close()
   328  
   329  	// open shared memory
   330  	r := open(t, "test_t", 64)
   331  	defer r.Close()
   332  
   333  	wg := new(sync.WaitGroup)
   334  	written := make(chan bool)
   335  	readone := make(chan bool)
   336  
   337  	// write thread
   338  	wg.Add(1)
   339  	go func() {
   340  		defer wg.Done()
   341  		for _, tt := range tests {
   342  			// write data
   343  			data := []byte(tt.data)
   344  			n, err := w.Write(data)
   345  			if err != nil {
   346  				written <- false
   347  				t.Fatalf("fail: write shared memroy %v", err)
   348  			}
   349  			if n != tt.size {
   350  				written <- false
   351  				t.Fatalf("fail: write shared memroy %d byte, want %d byte", n, tt.size)
   352  			}
   353  			written <- true
   354  
   355  			// wait
   356  			succ := <-readone
   357  			if !succ {
   358  				return
   359  			}
   360  		}
   361  	}()
   362  
   363  	// read thread
   364  	wg.Add(1)
   365  	go func() {
   366  		defer wg.Done()
   367  		for _, tt := range tests {
   368  			// wait
   369  			succ := <-written
   370  			if !succ {
   371  				return
   372  			}
   373  
   374  			// read data
   375  			data := []byte(tt.data)
   376  			buf := make([]byte, len(data))
   377  			n, err := r.Read(buf)
   378  			if err != nil {
   379  				readone <- false
   380  				t.Fatalf("fail: read shared memroy %v", err)
   381  			}
   382  			if n != tt.size {
   383  				readone <- false
   384  				t.Fatalf("fail: read shared memroy %d byte, want %d byte", n, tt.size)
   385  			}
   386  			if !reflect.DeepEqual(buf[:tt.size], data[:tt.size]) {
   387  				readone <- false
   388  				t.Fatalf("fail: read shared memroy %v, want %v", buf[:tt.size], data[:tt.size])
   389  			}
   390  			readone <- true
   391  		}
   392  	}()
   393  
   394  	wg.Wait()
   395  }