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 }