github.com/mattn/anko@v0.1.10/env/envValues_test.go (about) 1 package env 2 3 import ( 4 "fmt" 5 "reflect" 6 "sync" 7 "testing" 8 ) 9 10 func TestSetError(t *testing.T) { 11 envParent := NewEnv() 12 envChild := envParent.NewEnv() 13 err := envChild.Set("a", "a") 14 if err == nil { 15 t.Errorf("Set error - received: %v - expected: %v", err, fmt.Errorf("undefined symbol 'a'")) 16 } else if err.Error() != "undefined symbol 'a'" { 17 t.Errorf("Set error - received: %v - expected: %v", err, fmt.Errorf("undefined symbol 'a'")) 18 } 19 } 20 21 func TestAddrError(t *testing.T) { 22 envParent := NewEnv() 23 envChild := envParent.NewEnv() 24 _, err := envChild.Addr("a") 25 if err == nil { 26 t.Errorf("Addr error - received: %v - expected: %v", err, fmt.Errorf("undefined symbol 'a'")) 27 } else if err.Error() != "undefined symbol 'a'" { 28 t.Errorf("Addr error - received: %v - expected: %v", err, fmt.Errorf("undefined symbol 'a'")) 29 } 30 } 31 32 func TestDefineGlobalValue(t *testing.T) { 33 envParent := NewEnv() 34 envChild := envParent.NewEnv() 35 err := envChild.DefineGlobalValue("a", reflect.ValueOf("a")) 36 if err != nil { 37 t.Fatal("DefineGlobalValue error:", err) 38 } 39 40 var value interface{} 41 value, err = envParent.Get("a") 42 if err != nil { 43 t.Fatal("Get error:", err) 44 } 45 v, ok := value.(string) 46 if !ok { 47 t.Fatalf("value - received: %T - expected: %T", value, "a") 48 } 49 if v != "a" { 50 t.Fatalf("value - received: %v - expected: %v", v, "a") 51 } 52 } 53 54 func TestDefineAndGet(t *testing.T) { 55 var err error 56 var value interface{} 57 tests := []struct { 58 testInfo string 59 varName string 60 varDefineValue interface{} 61 varGetValue interface{} 62 varKind reflect.Kind 63 defineError error 64 getError error 65 }{ 66 {testInfo: "nil", varName: "a", varDefineValue: reflect.Value{}, varGetValue: reflect.Value{}, varKind: reflect.Invalid}, 67 {testInfo: "nil", varName: "a", varDefineValue: nil, varGetValue: nil, varKind: reflect.Interface}, 68 {testInfo: "bool", varName: "a", varDefineValue: true, varGetValue: true, varKind: reflect.Bool}, 69 {testInfo: "int16", varName: "a", varDefineValue: int16(1), varGetValue: int16(1), varKind: reflect.Int16}, 70 {testInfo: "int32", varName: "a", varDefineValue: int32(1), varGetValue: int32(1), varKind: reflect.Int32}, 71 {testInfo: "int64", varName: "a", varDefineValue: int64(1), varGetValue: int64(1), varKind: reflect.Int64}, 72 {testInfo: "uint32", varName: "a", varDefineValue: uint32(1), varGetValue: uint32(1), varKind: reflect.Uint32}, 73 {testInfo: "uint64", varName: "a", varDefineValue: uint64(1), varGetValue: uint64(1), varKind: reflect.Uint64}, 74 {testInfo: "float32", varName: "a", varDefineValue: float32(1), varGetValue: float32(1), varKind: reflect.Float32}, 75 {testInfo: "float64", varName: "a", varDefineValue: float64(1), varGetValue: float64(1), varKind: reflect.Float64}, 76 {testInfo: "string", varName: "a", varDefineValue: "a", varGetValue: "a", varKind: reflect.String}, 77 78 {testInfo: "string with dot", varName: "a.a", varDefineValue: "a", varGetValue: nil, varKind: reflect.Interface, defineError: ErrSymbolContainsDot, getError: fmt.Errorf("undefined symbol 'a.a'")}, 79 {testInfo: "string with quotes", varName: "a", varDefineValue: `"a"`, varGetValue: `"a"`, varKind: reflect.String}, 80 } 81 82 // DefineAndGet 83 for _, test := range tests { 84 env := NewEnv() 85 86 err = env.Define(test.varName, test.varDefineValue) 87 if err != nil && test.defineError != nil { 88 if err.Error() != test.defineError.Error() { 89 t.Errorf("DefineAndGet %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 90 continue 91 } 92 } else if err != test.defineError { 93 t.Errorf("DefineAndGet %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 94 continue 95 } 96 97 value, err = env.Get(test.varName) 98 if err != nil && test.getError != nil { 99 if err.Error() != test.getError.Error() { 100 t.Errorf("DefineAndGet %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError) 101 continue 102 } 103 } else if err != test.getError { 104 t.Errorf("DefineAndGet %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError) 105 continue 106 } 107 if value != test.varGetValue { 108 t.Errorf("DefineAndGet %v - value check - received %#v expected: %#v", test.testInfo, value, test.varGetValue) 109 } 110 } 111 112 // DefineAndGet NewEnv 113 for _, test := range tests { 114 envParent := NewEnv() 115 envChild := envParent.NewEnv() 116 117 err = envParent.Define(test.varName, test.varDefineValue) 118 if err != nil && test.defineError != nil { 119 if err.Error() != test.defineError.Error() { 120 t.Errorf("DefineAndGet NewEnv %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 121 continue 122 } 123 } else if err != test.defineError { 124 t.Errorf("DefineAndGet NewEnv %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 125 continue 126 } 127 128 value, err = envChild.Get(test.varName) 129 if err != nil && test.getError != nil { 130 if err.Error() != test.getError.Error() { 131 t.Errorf("DefineAndGet NewEnv %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError) 132 continue 133 } 134 } else if err != test.getError { 135 t.Errorf("DefineAndGet NewEnv %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError) 136 continue 137 } 138 if value != test.varGetValue { 139 t.Errorf("DefineAndGet NewEnv %v - value check - received %#v expected: %#v", test.testInfo, value, test.varGetValue) 140 } 141 } 142 143 // DefineAndGet DefineGlobal 144 for _, test := range tests { 145 envParent := NewEnv() 146 envChild := envParent.NewEnv() 147 148 err = envChild.DefineGlobal(test.varName, test.varDefineValue) 149 if err != nil && test.defineError != nil { 150 if err.Error() != test.defineError.Error() { 151 t.Errorf("DefineAndGet DefineGlobal %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 152 continue 153 } 154 } else if err != test.defineError { 155 t.Errorf("DefineAndGet DefineGlobal %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 156 continue 157 } 158 159 value, err = envParent.Get(test.varName) 160 if err != nil && test.getError != nil { 161 if err.Error() != test.getError.Error() { 162 t.Errorf("DefineAndGet DefineGlobal %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError) 163 continue 164 } 165 } else if err != test.getError { 166 t.Errorf("DefineAndGet DefineGlobal %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError) 167 continue 168 } 169 if value != test.varGetValue { 170 t.Errorf("DefineAndGet DefineGlobal %v - value check - received %#v expected: %#v", test.testInfo, value, test.varGetValue) 171 } 172 } 173 174 } 175 176 func TestGetValueSymbols(t *testing.T) { 177 var symbols []string 178 values := map[string]interface{}{ 179 "a": int64(1), 180 "b": float64(1), 181 "c": true, 182 "d": "a", 183 } 184 185 env := NewEnv() 186 for s, v := range values { 187 env.Define(s, v) 188 } 189 190 symbols = env.GetValueSymbols() 191 if len(symbols) != len(values) { 192 t.Errorf("Expected %d symbols, received %d", len(values), len(symbols)) 193 } 194 195 for _, symbol := range symbols { 196 _, ok := values[symbol] 197 if !ok { 198 t.Errorf("Missing %s symbol", symbol) 199 } 200 } 201 } 202 203 func TestDefineModify(t *testing.T) { 204 var err error 205 var value interface{} 206 tests := []struct { 207 testInfo string 208 varName string 209 varDefineValue interface{} 210 varGetValue interface{} 211 varKind reflect.Kind 212 defineError error 213 getError error 214 }{ 215 {testInfo: "nil", varName: "a", varDefineValue: nil, varGetValue: nil, varKind: reflect.Interface}, 216 {testInfo: "bool", varName: "a", varDefineValue: true, varGetValue: true, varKind: reflect.Bool}, 217 {testInfo: "int64", varName: "a", varDefineValue: int64(1), varGetValue: int64(1), varKind: reflect.Int64}, 218 {testInfo: "float64", varName: "a", varDefineValue: float64(1), varGetValue: float64(1), varKind: reflect.Float64}, 219 {testInfo: "string", varName: "a", varDefineValue: "a", varGetValue: "a", varKind: reflect.String}, 220 } 221 changeTests := []struct { 222 varDefineValue interface{} 223 varGetValue interface{} 224 varKind reflect.Kind 225 defineError error 226 getError error 227 }{ 228 {varDefineValue: nil, varGetValue: nil, varKind: reflect.Interface}, 229 {varDefineValue: "a", varGetValue: "a", varKind: reflect.String}, 230 {varDefineValue: int64(1), varGetValue: int64(1), varKind: reflect.Int64}, 231 {varDefineValue: float64(1), varGetValue: float64(1), varKind: reflect.Float64}, 232 {varDefineValue: true, varGetValue: true, varKind: reflect.Bool}, 233 } 234 235 // DefineModify 236 for _, test := range tests { 237 env := NewEnv() 238 239 err = env.Define(test.varName, test.varDefineValue) 240 if err != nil && test.defineError != nil { 241 if err.Error() != test.defineError.Error() { 242 t.Errorf("DefineModify %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 243 continue 244 } 245 } else if err != test.defineError { 246 t.Errorf("DefineModify %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 247 continue 248 } 249 250 value, err = env.Get(test.varName) 251 if err != nil && test.getError != nil { 252 if err.Error() != test.getError.Error() { 253 t.Errorf("DefineModify %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError) 254 continue 255 } 256 } else if err != test.getError { 257 t.Errorf("DefineModify %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError) 258 continue 259 } 260 if value != test.varGetValue { 261 t.Errorf("DefineModify %v - value check - received %#v expected: %#v", test.testInfo, value, test.varGetValue) 262 } 263 264 // DefineModify changeTest 265 for _, changeTest := range changeTests { 266 err = env.Set(test.varName, changeTest.varDefineValue) 267 if err != nil && changeTest.defineError != nil { 268 if err.Error() != changeTest.defineError.Error() { 269 t.Errorf("DefineModify changeTest %v - Set error - received: %v - expected: %v", test.testInfo, err, changeTest.defineError) 270 continue 271 } 272 } else if err != changeTest.defineError { 273 t.Errorf("DefineModify changeTest %v - Set error - received: %v - expected: %v", test.testInfo, err, changeTest.defineError) 274 continue 275 } 276 277 value, err = env.Get(test.varName) 278 if err != nil && changeTest.getError != nil { 279 if err.Error() != changeTest.getError.Error() { 280 t.Errorf("DefineModify changeTest %v - Get error - received: %v - expected: %v", test.testInfo, err, changeTest.getError) 281 continue 282 } 283 } else if err != changeTest.getError { 284 t.Errorf("DefineModify changeTest %v - Get error - received: %v - expected: %v", test.testInfo, err, changeTest.getError) 285 continue 286 } 287 if value != changeTest.varGetValue { 288 t.Errorf("DefineModify changeTest %v - value check - received %#v expected: %#v", test.testInfo, value, changeTest.varGetValue) 289 } 290 } 291 } 292 293 // DefineModify envParent 294 for _, test := range tests { 295 envParent := NewEnv() 296 envChild := envParent.NewEnv() 297 298 err = envParent.Define(test.varName, test.varDefineValue) 299 if err != nil && test.defineError != nil { 300 if err.Error() != test.defineError.Error() { 301 t.Errorf("DefineModify envParent %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 302 continue 303 } 304 } else if err != test.defineError { 305 t.Errorf("DefineModify envParent %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 306 continue 307 } 308 309 value, err = envChild.Get(test.varName) 310 if err != nil && test.getError != nil { 311 if err.Error() != test.getError.Error() { 312 t.Errorf("DefineModify envParent %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError) 313 continue 314 } 315 } else if err != test.getError { 316 t.Errorf("DefineModify envParent %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError) 317 continue 318 } 319 if value != test.varGetValue { 320 t.Errorf("DefineModify envParent %v - value check - received %#v expected: %#v", test.testInfo, value, test.varGetValue) 321 } 322 323 for _, changeTest := range changeTests { 324 err = envParent.Set(test.varName, changeTest.varDefineValue) 325 if err != nil && changeTest.defineError != nil { 326 if err.Error() != changeTest.defineError.Error() { 327 t.Errorf("DefineModify envParent changeTest %v - Set error - received: %v - expected: %v", test.testInfo, err, changeTest.defineError) 328 continue 329 } 330 } else if err != changeTest.defineError { 331 t.Errorf("DefineModify envParent changeTest %v - Set error - received: %v - expected: %v", test.testInfo, err, changeTest.defineError) 332 continue 333 } 334 335 value, err = envChild.Get(test.varName) 336 if err != nil && changeTest.getError != nil { 337 if err.Error() != changeTest.getError.Error() { 338 t.Errorf("DefineModify envParent changeTest %v - Get error - received: %v - expected: %v", test.testInfo, err, changeTest.getError) 339 continue 340 } 341 } else if err != changeTest.getError { 342 t.Errorf("ChanDefineModify envParent changeTestgeTest %v - Get error - received: %v - expected: %v", test.testInfo, err, changeTest.getError) 343 continue 344 } 345 if value != changeTest.varGetValue { 346 t.Errorf("DefineModify envParent changeTest %v - value check - received %#v expected: %#v", test.testInfo, value, changeTest.varGetValue) 347 } 348 } 349 } 350 351 // DefineModify envChild 352 for _, test := range tests { 353 envParent := NewEnv() 354 envChild := envParent.NewEnv() 355 356 err = envParent.Define(test.varName, test.varDefineValue) 357 if err != nil && test.defineError != nil { 358 if err.Error() != test.defineError.Error() { 359 t.Errorf("DefineModify envChild %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 360 continue 361 } 362 } else if err != test.defineError { 363 t.Errorf("DefineModify envChild %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 364 continue 365 } 366 367 value, err = envChild.Get(test.varName) 368 if err != nil && test.getError != nil { 369 if err.Error() != test.getError.Error() { 370 t.Errorf("DefineModify envChild %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError) 371 continue 372 } 373 } else if err != test.getError { 374 t.Errorf("DefineModify envChild %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError) 375 continue 376 } 377 if value != test.varGetValue { 378 t.Errorf("DefineModify envChild %v - value check - received %#v expected: %#v", test.testInfo, value, test.varGetValue) 379 } 380 381 for _, changeTest := range changeTests { 382 err = envChild.Set(test.varName, changeTest.varDefineValue) 383 if err != nil && changeTest.defineError != nil { 384 if err.Error() != changeTest.defineError.Error() { 385 t.Errorf("DefineModify envChild changeTest %v - Set error - received: %v - expected: %v", test.testInfo, err, changeTest.defineError) 386 continue 387 } 388 } else if err != changeTest.defineError { 389 t.Errorf("DefineModify envChild changeTest %v - Set error - received: %v - expected: %v", test.testInfo, err, changeTest.defineError) 390 continue 391 } 392 393 value, err = envChild.Get(test.varName) 394 if err != nil && changeTest.getError != nil { 395 if err.Error() != changeTest.getError.Error() { 396 t.Errorf("DefineModify envChild changeTest %v - Get error - received: %v - expected: %v", test.testInfo, err, changeTest.getError) 397 continue 398 } 399 } else if err != changeTest.getError { 400 t.Errorf("ChanDefineModify envChild changeTestgeTest %v - Get error - received: %v - expected: %v", test.testInfo, err, changeTest.getError) 401 continue 402 } 403 if value != changeTest.varGetValue { 404 t.Errorf("DefineModify envChild changeTest %v - value check - received %#v expected: %#v", test.testInfo, value, changeTest.varGetValue) 405 } 406 } 407 } 408 } 409 410 func TestAddr(t *testing.T) { 411 var err error 412 tests := []struct { 413 testInfo string 414 varName string 415 varDefineValue interface{} 416 defineError error 417 addrError error 418 }{ 419 {testInfo: "nil", varName: "a", varDefineValue: nil, addrError: nil}, 420 {testInfo: "string", varName: "a", varDefineValue: "a", addrError: fmt.Errorf("unaddressable")}, 421 {testInfo: "int64", varName: "a", varDefineValue: int64(1), addrError: fmt.Errorf("unaddressable")}, 422 {testInfo: "float64", varName: "a", varDefineValue: float64(1), addrError: fmt.Errorf("unaddressable")}, 423 {testInfo: "bool", varName: "a", varDefineValue: true, addrError: fmt.Errorf("unaddressable")}, 424 } 425 426 // TestAddr 427 for _, test := range tests { 428 envParent := NewEnv() 429 envChild := envParent.NewEnv() 430 431 err = envParent.Define(test.varName, test.varDefineValue) 432 if err != nil && test.defineError != nil { 433 if err.Error() != test.defineError.Error() { 434 t.Errorf("TestAddr %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 435 continue 436 } 437 } else if err != test.defineError { 438 t.Errorf("TestAddr %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError) 439 continue 440 } 441 442 _, err = envChild.Addr(test.varName) 443 if err != nil && test.addrError != nil { 444 if err.Error() != test.addrError.Error() { 445 t.Errorf("TestAddr %v - Addr error - received: %v - expected: %v", test.testInfo, err, test.addrError) 446 continue 447 } 448 } else if err != test.addrError { 449 t.Errorf("TestAddr %v - Addr error - received: %v - expected: %v", test.testInfo, err, test.addrError) 450 continue 451 } 452 } 453 } 454 455 func TestDelete(t *testing.T) { 456 // empty 457 env := NewEnv() 458 env.Delete("a") 459 460 // add & delete a 461 env.Define("a", "a") 462 env.Delete("a") 463 464 value, err := env.Get("a") 465 expectedError := "undefined symbol 'a'" 466 if err == nil || err.Error() != expectedError { 467 t.Errorf("Get error - received: %v - expected: %v", err, expectedError) 468 } 469 if value != nil { 470 t.Errorf("Get value - received: %#v - expected: %#v", value, nil) 471 } 472 } 473 474 func TestDeleteGlobal(t *testing.T) { 475 // empty 476 env := NewEnv() 477 env.DeleteGlobal("a") 478 479 // add & delete a 480 env.Define("a", "a") 481 env.DeleteGlobal("a") 482 483 value, err := env.Get("a") 484 expectedError := "undefined symbol 'a'" 485 if err == nil || err.Error() != expectedError { 486 t.Errorf("Get error - received: %v - expected: %v", err, expectedError) 487 } 488 if value != nil { 489 t.Errorf("Get value - received: %#v - expected: %#v", value, nil) 490 } 491 492 // parent & child, var in child, delete in parent 493 envChild := env.NewEnv() 494 envChild.Define("a", "a") 495 env.DeleteGlobal("a") 496 497 value, err = envChild.Get("a") 498 if err != nil { 499 t.Errorf("Get error - received: %v - expected: %v", err, nil) 500 } 501 if value != "a" { 502 t.Errorf("Get value - received: %#v - expected: %#v", value, "a") 503 } 504 505 // parent & child, var in child, delete in child 506 envChild.DeleteGlobal("a") 507 508 value, err = envChild.Get("a") 509 if err == nil || err.Error() != expectedError { 510 t.Errorf("Get error - received: %v - expected: %v", err, expectedError) 511 } 512 if value != nil { 513 t.Errorf("Get value - received: %#v - expected: %#v", value, nil) 514 } 515 516 // parent & child, var in parent, delete in child 517 env.Define("a", "a") 518 envChild.DeleteGlobal("a") 519 520 value, err = envChild.Get("a") 521 if err == nil || err.Error() != expectedError { 522 t.Errorf("Get error - received: %v - expected: %v", err, expectedError) 523 } 524 if value != nil { 525 t.Errorf("Get value - received: %#v - expected: %#v", value, nil) 526 } 527 528 // parent & child, var in parent, delete in parent 529 env.Define("a", "a") 530 env.DeleteGlobal("a") 531 532 value, err = envChild.Get("a") 533 if err == nil || err.Error() != expectedError { 534 t.Errorf("Get error - received: %v - expected: %v", err, expectedError) 535 } 536 if value != nil { 537 t.Errorf("Get value - received: %#v - expected: %#v", value, nil) 538 } 539 } 540 541 func TestRaceCreateSameVariable(t *testing.T) { 542 // Test creating same variable in parallel 543 544 waitChan := make(chan struct{}, 1) 545 var waitGroup sync.WaitGroup 546 547 env := NewEnv() 548 549 for i := 0; i < 100; i++ { 550 waitGroup.Add(1) 551 go func(i int) { 552 <-waitChan 553 err := env.Define("a", i) 554 if err != nil { 555 t.Errorf("Define error: %v", err) 556 } 557 _, err = env.Get("a") 558 if err != nil { 559 t.Errorf("Get error: %v", err) 560 } 561 waitGroup.Done() 562 }(i) 563 } 564 565 close(waitChan) 566 waitGroup.Wait() 567 568 _, err := env.Get("a") 569 if err != nil { 570 t.Errorf("Get error: %v", err) 571 } 572 } 573 574 func TestRaceCreateDifferentVariables(t *testing.T) { 575 // Test creating different variables in parallel 576 577 waitChan := make(chan struct{}, 1) 578 var waitGroup sync.WaitGroup 579 580 env := NewEnv() 581 582 for i := 0; i < 100; i++ { 583 waitGroup.Add(1) 584 go func(i int) { 585 <-waitChan 586 err := env.Define(fmt.Sprint(i), i) 587 if err != nil { 588 t.Errorf("Define error: %v", err) 589 } 590 _, err = env.Get(fmt.Sprint(i)) 591 if err != nil { 592 t.Errorf("Get error: %v", err) 593 } 594 waitGroup.Done() 595 }(i) 596 } 597 598 close(waitChan) 599 waitGroup.Wait() 600 601 for i := 0; i < 100; i++ { 602 _, err := env.Get(fmt.Sprint(i)) 603 if err != nil { 604 t.Errorf("Get error: %v", err) 605 } 606 } 607 } 608 609 func TestRaceReadDifferentVariables(t *testing.T) { 610 // Test reading different variables in parallel 611 612 waitChan := make(chan struct{}, 1) 613 var waitGroup sync.WaitGroup 614 615 env := NewEnv() 616 617 for i := 0; i < 100; i++ { 618 err := env.Define(fmt.Sprint(i), i) 619 if err != nil { 620 t.Errorf("Define error: %v", err) 621 } 622 _, err = env.Get(fmt.Sprint(i)) 623 if err != nil { 624 t.Errorf("Get error: %v", err) 625 } 626 } 627 628 for i := 0; i < 100; i++ { 629 waitGroup.Add(1) 630 go func(i int) { 631 <-waitChan 632 _, err := env.Get(fmt.Sprint(i)) 633 if err != nil { 634 t.Errorf("Get error: %v", err) 635 } 636 waitGroup.Done() 637 }(i) 638 } 639 640 close(waitChan) 641 waitGroup.Wait() 642 } 643 644 func TestRaceSetSameVariable(t *testing.T) { 645 // Test setting same variable in parallel 646 647 waitChan := make(chan struct{}, 1) 648 var waitGroup sync.WaitGroup 649 650 env := NewEnv() 651 652 err := env.Define("a", 0) 653 if err != nil { 654 t.Errorf("Define error: %v", err) 655 } 656 _, err = env.Get("a") 657 if err != nil { 658 t.Errorf("Get error: %v", err) 659 } 660 661 for i := 0; i < 100; i++ { 662 waitGroup.Add(1) 663 go func(i int) { 664 <-waitChan 665 err := env.Set("a", i) 666 if err != nil { 667 t.Errorf("Set error: %v", err) 668 } 669 waitGroup.Done() 670 }(i) 671 } 672 673 close(waitChan) 674 waitGroup.Wait() 675 676 _, err = env.Get("a") 677 if err != nil { 678 t.Errorf("Get error: %v", err) 679 } 680 } 681 682 func TestRaceSetSameVariableNewEnv(t *testing.T) { 683 // Test setting same variable in parallel with NewEnv 684 685 waitChan := make(chan struct{}, 1) 686 var waitGroup sync.WaitGroup 687 688 env := NewEnv() 689 690 err := env.Define("a", 0) 691 if err != nil { 692 t.Errorf("Define error: %v", err) 693 } 694 _, err = env.Get("a") 695 if err != nil { 696 t.Errorf("Get error: %v", err) 697 } 698 699 for i := 0; i < 100; i++ { 700 waitGroup.Add(1) 701 go func(i int) { 702 <-waitChan 703 env = env.NewEnv().NewEnv() 704 err := env.Set("a", i) 705 if err != nil { 706 t.Errorf("Set error: %v", err) 707 } 708 waitGroup.Done() 709 }(i) 710 } 711 } 712 713 func TestRaceDefineAndSetSameVariable(t *testing.T) { 714 // Test defining and setting same variable in parallel 715 for i := 0; i < 100; i++ { 716 raceDefineAndSetSameVariable(t) 717 } 718 } 719 720 func raceDefineAndSetSameVariable(t *testing.T) { 721 waitChan := make(chan struct{}, 1) 722 var waitGroup sync.WaitGroup 723 724 envParent := NewEnv() 725 envChild := envParent.NewEnv() 726 727 for i := 0; i < 2; i++ { 728 waitGroup.Add(1) 729 go func() { 730 <-waitChan 731 err := envParent.Set("a", 1) 732 if err != nil && err.Error() != "undefined symbol 'a'" { 733 t.Errorf("Set error: %v", err) 734 } 735 waitGroup.Done() 736 }() 737 waitGroup.Add(1) 738 go func() { 739 <-waitChan 740 err := envParent.Define("a", 2) 741 if err != nil { 742 t.Errorf("Define error: %v", err) 743 } 744 waitGroup.Done() 745 }() 746 waitGroup.Add(1) 747 go func() { 748 <-waitChan 749 err := envChild.Set("a", 3) 750 if err != nil && err.Error() != "undefined symbol 'a'" { 751 t.Errorf("Set error: %v", err) 752 } 753 waitGroup.Done() 754 }() 755 waitGroup.Add(1) 756 go func() { 757 <-waitChan 758 err := envChild.Define("a", 4) 759 if err != nil { 760 t.Errorf("Define error: %v", err) 761 } 762 waitGroup.Done() 763 }() 764 } 765 766 close(waitChan) 767 waitGroup.Wait() 768 769 _, err := envParent.Get("a") // value of a could be 1, 2, or 3 770 if err != nil { 771 t.Errorf("Get error: %v", err) 772 } 773 _, err = envChild.Get("a") // value of a could be 3 or 4 774 if err != nil { 775 t.Errorf("Get error: %v", err) 776 } 777 } 778 779 func BenchmarkDefine(b *testing.B) { 780 var err error 781 env := NewEnv() 782 b.ResetTimer() 783 for i := 0; i < b.N; i++ { 784 err := env.Define("a", 1) 785 if err != nil { 786 b.Errorf("Set error: %v", err) 787 } 788 } 789 b.StopTimer() 790 _, err = env.Get("a") 791 if err != nil { 792 b.Errorf("Get error: %v", err) 793 } 794 } 795 796 func BenchmarkSet(b *testing.B) { 797 env := NewEnv() 798 err := env.Define("a", 1) 799 if err != nil { 800 b.Errorf("Define error: %v", err) 801 } 802 b.ResetTimer() 803 for i := 0; i < b.N; i++ { 804 err = env.Set("a", 1) 805 if err != nil { 806 b.Errorf("Set error: %v", err) 807 } 808 } 809 b.StopTimer() 810 _, err = env.Get("a") 811 if err != nil { 812 b.Errorf("Get error: %v", err) 813 } 814 }