github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/state/file_test.go (about)

     1  // Copyright 2018 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache-2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  package state
     6  
     7  import (
     8  	"path/filepath"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/grailbio/testutil"
    13  )
    14  
    15  // TODO(marius): provide an example test
    16  
    17  func mustOpen(t *testing.T, prefix string) *File {
    18  	f, err := Open(prefix)
    19  	if err != nil {
    20  		t.Fatal(err)
    21  	}
    22  	return f
    23  }
    24  
    25  func mustLock(t *testing.T, f *File) {
    26  	if err := f.Lock(); err != nil {
    27  		t.Fatal(err)
    28  	}
    29  }
    30  
    31  func mustUnlock(t *testing.T, f *File) {
    32  	if err := f.Unlock(); err != nil {
    33  		t.Fatal(err)
    34  	}
    35  }
    36  
    37  func TestFile(t *testing.T) {
    38  	type mystate struct {
    39  		A, B, C string
    40  	}
    41  	dir, cleanup := testutil.TempDir(t, "", "")
    42  	defer cleanup()
    43  	prefix := filepath.Join(dir, "mystate")
    44  	f1 := mustOpen(t, prefix)
    45  	defer f1.Close()
    46  	f2 := mustOpen(t, prefix)
    47  	defer f2.Close()
    48  	var s1, s2 mystate
    49  	if got, want := f1.Unmarshal(&s1), ErrNoState; got != want {
    50  		t.Fatalf("got %v, want %v", got, want)
    51  	}
    52  	s1 = mystate{"A", "B", "C"}
    53  	if err := f1.Marshal(&s1); err != nil {
    54  		t.Fatal(err)
    55  	}
    56  	if err := f2.Unmarshal(&s2); err != nil {
    57  		t.Fatal(err)
    58  	}
    59  	if got, want := s2, s1; got != want {
    60  		t.Fatalf("got %v, want %v", got, want)
    61  	}
    62  	// Can't marshal a func.
    63  	if f1.Marshal(func() {}) == nil {
    64  		t.Fatal("expected error")
    65  	}
    66  	// But this shouldn't affect the state.
    67  	if err := f2.Unmarshal(&s2); err != nil {
    68  		t.Fatal(err)
    69  	}
    70  	if got, want := s2, s1; got != want {
    71  		t.Fatalf("got %v, want %v", got, want)
    72  	}
    73  }
    74  
    75  func TestLock(t *testing.T) {
    76  	dir, cleanup := testutil.TempDir(t, "", "")
    77  	defer cleanup()
    78  	prefix := filepath.Join(dir, "mystate")
    79  	f1 := mustOpen(t, prefix)
    80  	f2 := mustOpen(t, prefix)
    81  
    82  	mustLock(t, f1)
    83  
    84  	ch := make(chan bool)
    85  	go func() {
    86  		mustLock(t, f2)
    87  		ch <- true
    88  		mustUnlock(t, f2)
    89  	}()
    90  
    91  	// Make sure that f2 has not acquired the lock.
    92  	time.Sleep(1 * time.Second)
    93  	select {
    94  	case <-ch:
    95  		t.Fatal("F2 should not have acquired a lock")
    96  	default:
    97  	}
    98  	mustUnlock(t, f1)
    99  	_ = <-ch // make sure that f2 acquires the lock
   100  }