github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/blunder/api_test.go (about)

     1  // Copyright (c) 2015-2021, NVIDIA CORPORATION.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package blunder
     5  
     6  import (
     7  	"fmt"
     8  	"testing"
     9  
    10  	"golang.org/x/sys/unix"
    11  
    12  	"github.com/swiftstack/ProxyFS/conf"
    13  	"github.com/swiftstack/ProxyFS/logger"
    14  	"github.com/swiftstack/ProxyFS/transitions"
    15  )
    16  
    17  var testConfMap conf.ConfMap
    18  
    19  func testSetup(t *testing.T) {
    20  	var (
    21  		err             error
    22  		testConfStrings []string
    23  	)
    24  
    25  	testConfStrings = []string{
    26  		"Stats.IPAddr=localhost",
    27  		"Stats.UDPPort=52184",
    28  		"Stats.BufferLength=100",
    29  		"Stats.MaxLatency=1s",
    30  		"Logging.LogFilePath=/dev/null",
    31  		"Cluster.WhoAmI=nobody",
    32  		"FSGlobals.VolumeGroupList=",
    33  		"FSGlobals.CheckpointHeaderConsensusAttempts=5",
    34  		"FSGlobals.MountRetryLimit=6",
    35  		"FSGlobals.MountRetryDelay=1s",
    36  		"FSGlobals.MountRetryExpBackoff=2",
    37  		"FSGlobals.LogCheckpointHeaderPosts=true",
    38  		"FSGlobals.TryLockBackoffMin=10ms",
    39  		"FSGlobals.TryLockBackoffMax=50ms",
    40  		"FSGlobals.TryLockSerializationThreshhold=5",
    41  		"FSGlobals.SymlinkMax=32",
    42  		"FSGlobals.CoalesceElementChunkSize=16",
    43  	}
    44  
    45  	testConfMap, err = conf.MakeConfMapFromStrings(testConfStrings)
    46  	if nil != err {
    47  		t.Fatalf("conf.MakeConfMapFromStrings() failed: %v", err)
    48  	}
    49  
    50  	err = transitions.Up(testConfMap)
    51  	if nil != err {
    52  		t.Fatalf("transitions.Up() failed: %v", err)
    53  	}
    54  }
    55  
    56  func testTeardown(t *testing.T) {
    57  	var (
    58  		err error
    59  	)
    60  
    61  	err = transitions.Down(testConfMap)
    62  	if nil != err {
    63  		t.Fatalf("transitions.Down() failed: %v", err)
    64  	}
    65  }
    66  
    67  func TestValues(t *testing.T) {
    68  	errConstant := NotPermError
    69  	expectedValue := int(unix.EPERM)
    70  	if errConstant.Value() != expectedValue {
    71  		logger.Fatalf("Error, %s != %d", errConstant.String(), expectedValue)
    72  	}
    73  	// XXX TODO: add the rest of the values
    74  }
    75  
    76  func checkValue(testInfo string, actualVal int, expectedVal int) bool {
    77  	if actualVal != expectedVal {
    78  		logger.Fatalf("Error, %s value was %d, expected %d", testInfo, actualVal, expectedVal)
    79  		return false
    80  	}
    81  	return true
    82  }
    83  
    84  func TestDefaultErrno(t *testing.T) {
    85  	testSetup(t)
    86  
    87  	// Nil error test
    88  	var err error
    89  
    90  	// Now try to get error val out of err. We should get a default value, since error value hasn't been set.
    91  	errno := Errno(err)
    92  
    93  	// Since err is nil, the default value should be successErrno
    94  	checkValue("nil error", errno, successErrno)
    95  
    96  	// IsSuccess should return true and IsNotSuccess should return false
    97  	if !IsSuccess(err) {
    98  		logger.Fatalf("Error, IsSuccess() returned false for error %v (errno %v)", ErrorString(err), Errno(err))
    99  	}
   100  	if IsNotSuccess(err) {
   101  		logger.Fatalf("Error, IsNotSuccess() returned true for error %v", ErrorString(err))
   102  	}
   103  
   104  	// Non-nil error test
   105  	err = fmt.Errorf("This is an ordinary error")
   106  
   107  	// Since err is non-nil, the default value should be failureErrno (-1)
   108  	errno = Errno(err)
   109  	checkValue("non-nil error", errno, failureErrno)
   110  
   111  	// IsSuccess should return false and IsNotSuccess should return true
   112  	if IsSuccess(err) {
   113  		logger.Fatalf("Error, IsSuccess() returned true for error %v (errno %v)", ErrorString(err), Errno(err))
   114  	}
   115  	if !IsNotSuccess(err) {
   116  		logger.Fatalf("Error, IsNotSuccess() returned false for error %v", ErrorString(err))
   117  	}
   118  
   119  	// Specific error test
   120  	err = AddError(err, InvalidArgError)
   121  	errno = Errno(err)
   122  	checkValue("specific error", errno, InvalidArgError.Value())
   123  
   124  	testTeardown(t)
   125  }
   126  
   127  func TestAddValue(t *testing.T) {
   128  	testSetup(t)
   129  
   130  	// Add value to a nil error (not recommended as a strategy, but it needs to work anyway)
   131  	var err error
   132  	err = AddError(err, ReadOnlyError)
   133  	errno := Errno(err)
   134  	checkValue("specific error", errno, ReadOnlyError.Value())
   135  	if !hasErrnoValue(err) {
   136  		logger.Fatalf("Error, hasErrnoValue returned false for error %v", ErrorString(err))
   137  	}
   138  	// Validate the Is* APIs on what started as a nil error
   139  	if !Is(err, ReadOnlyError) {
   140  		logger.Fatalf("Error, Is() returned false for error %v is NameTooLongError", ErrorString(err))
   141  	}
   142  	if Is(err, NotFoundError) {
   143  		logger.Fatalf("Error, Is() returned true for error %v is IsDirError", ErrorString(err))
   144  	}
   145  	if !IsNot(err, InvalidArgError) {
   146  		logger.Fatalf("Error, IsNot() returned false for error %v is IsDirError", ErrorString(err))
   147  	}
   148  	if IsSuccess(err) {
   149  		logger.Fatalf("Error, IsSuccess() returned true for error %v", ErrorString(err))
   150  	}
   151  	if !IsNotSuccess(err) {
   152  		logger.Fatalf("Error, IsNotSuccess() returned false for error %v", ErrorString(err))
   153  	}
   154  
   155  	// Add value to a non-nil error
   156  	err = fmt.Errorf("This is an ordinary error")
   157  	err = AddError(err, NameTooLongError)
   158  	errno = Errno(err)
   159  	checkValue("specific error", errno, NameTooLongError.Value())
   160  	if !hasErrnoValue(err) {
   161  		logger.Fatalf("Error, hasErrnoValue returned false for error %v", ErrorString(err))
   162  	}
   163  	// Validate the Is* APIs on what started as a non-nil error
   164  	if !Is(err, NameTooLongError) {
   165  		logger.Fatalf("Error, Is() returned false for error %v is NameTooLongError", ErrorString(err))
   166  	}
   167  	if Is(err, IsDirError) {
   168  		logger.Fatalf("Error, Is() returned true for error %v is IsDirError", ErrorString(err))
   169  	}
   170  	if !IsNot(err, IsDirError) {
   171  		logger.Fatalf("Error, IsNot() returned false for error %v is IsDirError", ErrorString(err))
   172  	}
   173  	if IsSuccess(err) {
   174  		logger.Fatalf("Error, IsSuccess() returned true for error %v", ErrorString(err))
   175  	}
   176  	if !IsNotSuccess(err) {
   177  		logger.Fatalf("Error, IsNotSuccess() returned false for error %v", ErrorString(err))
   178  	}
   179  
   180  	// Add a different value to a non-nil error
   181  	err = AddError(err, ReadOnlyError)
   182  	errno = Errno(err)
   183  	checkValue("specific error", errno, ReadOnlyError.Value())
   184  	if !hasErrnoValue(err) {
   185  		logger.Fatalf("Error, hasErrnoValue returned false for error %v", ErrorString(err))
   186  	}
   187  	if !Is(err, ReadOnlyError) {
   188  		logger.Fatalf("Error, Is() returned false for error %v is NameTooLongError", ErrorString(err))
   189  	}
   190  
   191  	testTeardown(t)
   192  }
   193  
   194  func TestHTTPCode(t *testing.T) {
   195  	testSetup(t)
   196  
   197  	// Nil error test
   198  	// Add http code to a nil error (not recommended as a strategy, but it needs to work anyway)
   199  	var err error
   200  
   201  	// Now try to get http code out of err. We should get a default value, since error value hasn't been set.
   202  	code := HTTPCode(err)
   203  
   204  	// Since err is nil, the default value should be 200 OK
   205  	checkValue("nil error", code, 200)
   206  
   207  	// Non-nil error test
   208  	err = fmt.Errorf("This is an ordinary error")
   209  
   210  	// Err is non-nil but http code is not set, the default value should be 500
   211  	code = HTTPCode(err)
   212  	checkValue("non-nil error", code, 500)
   213  
   214  	// Specific error test
   215  	err = AddHTTPCode(err, 400)
   216  	code = HTTPCode(err)
   217  	checkValue("specific error", code, 400)
   218  
   219  	testTeardown(t)
   220  }