github.com/jfrog/jfrog-cli-go@v1.22.1-0.20200318093948-4826ef344ffd/utils/lock/lock_test.go (about)

     1  package lock
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/jfrog/jfrog-cli-go/utils/log"
     6  	"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
     7  	"math"
     8  	"os"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  func init() {
    14  	log.SetDefaultLogger()
    15  }
    16  
    17  /*
    18  	The lock mechanism prefers earlier lock requests. If two locks requests have same time stamps, it'll take the one with the smaller PID first.
    19  	Here we test the functionality of a real process with a real PID and a dummy process with MaxInt pid.
    20  */
    21  func TestLockSmallerPid(t *testing.T) {
    22  	// First creating the first lock object with special pid number that doesn't exists.
    23  	firstLock, _ := getLock(math.MaxInt32, t)
    24  	// Creating a second lock object with the running PID
    25  	secondLock, folderName := getLock(os.Getpid(), t)
    26  
    27  	// Confirming that only two locks are located in the lock directory
    28  	files, err := fileutils.ListFiles(folderName, false)
    29  	if err != nil {
    30  		t.Error(err)
    31  	}
    32  
    33  	if len(files) != 2 {
    34  		t.Error("Expected 2 files but got ", len(files))
    35  	}
    36  
    37  	// Performing lock. This should work since the first lock PID is not running. The Lock() will remove it.
    38  	err = secondLock.Lock()
    39  	if err != nil {
    40  		t.Error(err)
    41  	}
    42  	// Unlocking to remove the lock file.
    43  	err = secondLock.Unlock()
    44  	if err != nil {
    45  		t.Error(err)
    46  	}
    47  
    48  	// If timestamp equals, secondLock.Lock() is not expected to delete first lock's file, since os.Getpid() < math.MaxInt32.
    49  	if firstLock.currentTime == secondLock.currentTime {
    50  		err = firstLock.Unlock()
    51  		if err != nil {
    52  			t.Error(err)
    53  		}
    54  	}
    55  
    56  	// Confirming that no locks are located in the lock directory
    57  	files, err = fileutils.ListFiles(folderName, false)
    58  	if err != nil {
    59  		t.Error(err)
    60  	}
    61  	if len(files) != 0 {
    62  		t.Error("Expected 0 files but got", len(files), files)
    63  	}
    64  }
    65  
    66  /*
    67  	The lock mechanism prefers earlier lock requests. If two locks requests have same time stamps, it'll take the one with the smaller PID first.
    68  	Here we test the functionality of a real process with a real PID and a dummy process with -1 pid.
    69  */
    70  func TestLockBiggerPid(t *testing.T) {
    71  	// First creating the first lock object with special pid number that doesn't exists.
    72  	getLock(-1, t)
    73  	// Creating a second lock object with the running PID
    74  	secondLock, folderName := getLock(os.Getpid(), t)
    75  
    76  	// Confirming that only two locks are located in the lock directory
    77  	files, err := fileutils.ListFiles(folderName, false)
    78  	if err != nil {
    79  		t.Error(err)
    80  	}
    81  
    82  	if len(files) != 2 {
    83  		t.Error("Expected 2 files but got ", len(files), files)
    84  	}
    85  
    86  	// Performing lock. This should work since the first lock PID is not running. The Lock() will remove it.
    87  	err = secondLock.Lock()
    88  	if err != nil {
    89  		t.Error(err)
    90  	}
    91  	// Unlocking to remove the lock file.
    92  	err = secondLock.Unlock()
    93  	if err != nil {
    94  		t.Error(err)
    95  	}
    96  
    97  	// Confirming that no locks are located in the lock directory
    98  	files, err = fileutils.ListFiles(folderName, false)
    99  	if err != nil {
   100  		t.Error(err)
   101  	}
   102  	if len(files) != 0 {
   103  		t.Error("Expected 0 files but got", len(files), files)
   104  	}
   105  }
   106  
   107  func TestUnlock(t *testing.T) {
   108  	lock := new(Lock)
   109  	err := lock.CreateNewLockFile()
   110  	if err != nil {
   111  		t.Error(err)
   112  	}
   113  
   114  	exists, err := fileutils.IsFileExists(lock.fileName, false)
   115  	if err != nil {
   116  		t.Error(err)
   117  	}
   118  
   119  	if !exists {
   120  		t.Errorf("File %s is missing", lock.fileName)
   121  	}
   122  
   123  	lock.Unlock()
   124  
   125  	exists, err = fileutils.IsFileExists(lock.fileName, false)
   126  	if err != nil {
   127  		t.Error(err)
   128  	}
   129  
   130  	if exists {
   131  		t.Errorf("File %s exists, but it should have been removed by Unlock", lock.fileName)
   132  	}
   133  }
   134  
   135  func TestCreateFile(t *testing.T) {
   136  	pid := os.Getpid()
   137  	lock, folderName := getLock(pid, t)
   138  
   139  	exists, err := fileutils.IsFileExists(lock.fileName, false)
   140  	if err != nil {
   141  		t.Error(err)
   142  		t.FailNow()
   143  	}
   144  
   145  	if !exists {
   146  		t.Error("Lock wan't created.")
   147  		t.FailNow()
   148  	}
   149  
   150  	files, err := fileutils.ListFiles(folderName, false)
   151  	if err != nil {
   152  		t.Error(err)
   153  		t.FailNow()
   154  	}
   155  
   156  	if len(files) != 1 {
   157  		t.Error(fmt.Errorf("Expected one file, got %d.", len(files)))
   158  		t.FailNow()
   159  	}
   160  
   161  	if files[0] != lock.fileName {
   162  		t.Error(fmt.Errorf("Expected filename %s, got %s", lock.fileName, files[0]))
   163  	}
   164  	// Removing the created lock file
   165  	err = lock.Unlock()
   166  	if err != nil {
   167  		t.Error(err)
   168  	}
   169  }
   170  
   171  func getLock(pid int, t *testing.T) (Lock, string) {
   172  	currentTime := time.Now().UnixNano()
   173  	lock := Lock{
   174  		pid:         pid,
   175  		currentTime: currentTime,
   176  	}
   177  	folderName, err := CreateLockDir()
   178  	if err != nil {
   179  		t.Error(err)
   180  		t.FailNow()
   181  	}
   182  	err = lock.CreateFile(folderName, pid)
   183  	if err != nil {
   184  		t.Error(err)
   185  		t.FailNow()
   186  	}
   187  
   188  	return lock, folderName
   189  }