github.com/cilium/cilium@v1.16.2/pkg/lock/lockfile/lockfile_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  // this only runs on linux, since that supports per-file-descriptor posix advisory locking
     5  //go:build linux
     6  
     7  package lockfile
     8  
     9  import (
    10  	"context"
    11  	"path/filepath"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/stretchr/testify/assert"
    16  )
    17  
    18  func TestLockfile(t *testing.T) {
    19  	dir := t.TempDir()
    20  	path := filepath.Join(dir, "lockfile")
    21  
    22  	// Test lockfile creation
    23  	lf, err := NewLockfile(path)
    24  	assert.NoError(t, err)
    25  	assert.FileExists(t, path)
    26  	defer lf.Close()
    27  
    28  	err = lf.Lock(context.Background(), true)
    29  	assert.NoError(t, err)
    30  
    31  	err = lf.Unlock()
    32  	assert.NoError(t, err)
    33  }
    34  
    35  func TestLockfileShared(t *testing.T) {
    36  	dir := t.TempDir()
    37  	path := filepath.Join(dir, "lockfile")
    38  
    39  	// Now, ensure that shared locks work: take two shared locks
    40  	shared1, err := NewLockfile(path)
    41  	assert.NoError(t, err)
    42  	assert.NoError(t, shared1.Lock(context.Background(), false))
    43  	defer shared1.Close()
    44  
    45  	shared2, err := NewLockfile(path)
    46  	assert.NoError(t, err)
    47  	assert.NoError(t, shared2.TryLock(false))
    48  	defer shared2.Close()
    49  
    50  	// Try and take an exclusive lock; it will fail
    51  	exclusive, err := NewLockfile(path)
    52  	assert.NoError(t, err)
    53  	assert.Error(t, exclusive.TryLock(true))
    54  	defer exclusive.Close()
    55  
    56  	// Now, unlock
    57  	assert.NoError(t, shared1.Unlock())
    58  	assert.NoError(t, shared2.Unlock())
    59  
    60  	// Take an exclusive lock
    61  	assert.NoError(t, exclusive.TryLock(true))
    62  
    63  	// Ensure we can't take a shared lock with an exclusive one
    64  	assert.Error(t, shared1.TryLock(false))
    65  }
    66  
    67  func TestLockfileCancel(t *testing.T) {
    68  	dir := t.TempDir()
    69  	path := filepath.Join(dir, "lockfile")
    70  
    71  	// take an exclusive lock
    72  	exclusive, err := NewLockfile(path)
    73  	assert.NoError(t, err)
    74  	defer exclusive.Close()
    75  	assert.NoError(t, exclusive.Lock(context.Background(), true))
    76  
    77  	// try and take another, but it will time out
    78  	fail, err := NewLockfile(path)
    79  	assert.NoError(t, err)
    80  	defer fail.Close()
    81  
    82  	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
    83  	defer cancel()
    84  
    85  	err = fail.Lock(ctx, true) // this will fail
    86  	assert.ErrorContains(t, err, "deadline")
    87  
    88  	exclusive.Unlock()
    89  }