123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787 |
- package env
- import (
- "fmt"
- "reflect"
- "sync"
- "testing"
- )
- func TestSetError(t *testing.T) {
- envParent := NewEnv()
- envChild := envParent.NewEnv()
- err := envChild.Set("a", "a")
- if err == nil {
- t.Errorf("Set error - received: %v - expected: %v", err, fmt.Errorf("undefined symbol 'a'"))
- } else if err.Error() != "undefined symbol 'a'" {
- t.Errorf("Set error - received: %v - expected: %v", err, fmt.Errorf("undefined symbol 'a'"))
- }
- }
- func TestAddrError(t *testing.T) {
- envParent := NewEnv()
- envChild := envParent.NewEnv()
- _, err := envChild.Addr("a")
- if err == nil {
- t.Errorf("Addr error - received: %v - expected: %v", err, fmt.Errorf("undefined symbol 'a'"))
- } else if err.Error() != "undefined symbol 'a'" {
- t.Errorf("Addr error - received: %v - expected: %v", err, fmt.Errorf("undefined symbol 'a'"))
- }
- }
- func TestDefineGlobalValue(t *testing.T) {
- envParent := NewEnv()
- envChild := envParent.NewEnv()
- err := envChild.DefineGlobalValue("a", reflect.ValueOf("a"))
- if err != nil {
- t.Fatal("DefineGlobalValue error:", err)
- }
- var value interface{}
- value, err = envParent.Get("a")
- if err != nil {
- t.Fatal("Get error:", err)
- }
- v, ok := value.(string)
- if !ok {
- t.Fatalf("value - received: %T - expected: %T", value, "a")
- }
- if v != "a" {
- t.Fatalf("value - received: %v - expected: %v", v, "a")
- }
- }
- func TestDefineAndGet(t *testing.T) {
- var err error
- var value interface{}
- tests := []struct {
- testInfo string
- varName string
- varDefineValue interface{}
- varGetValue interface{}
- varKind reflect.Kind
- defineError error
- getError error
- }{
- {testInfo: "nil", varName: "a", varDefineValue: reflect.Value{}, varGetValue: reflect.Value{}, varKind: reflect.Invalid},
- {testInfo: "nil", varName: "a", varDefineValue: nil, varGetValue: nil, varKind: reflect.Interface},
- {testInfo: "bool", varName: "a", varDefineValue: true, varGetValue: true, varKind: reflect.Bool},
- {testInfo: "int16", varName: "a", varDefineValue: int16(1), varGetValue: int16(1), varKind: reflect.Int16},
- {testInfo: "int32", varName: "a", varDefineValue: int32(1), varGetValue: int32(1), varKind: reflect.Int32},
- {testInfo: "int64", varName: "a", varDefineValue: int64(1), varGetValue: int64(1), varKind: reflect.Int64},
- {testInfo: "uint32", varName: "a", varDefineValue: uint32(1), varGetValue: uint32(1), varKind: reflect.Uint32},
- {testInfo: "uint64", varName: "a", varDefineValue: uint64(1), varGetValue: uint64(1), varKind: reflect.Uint64},
- {testInfo: "float32", varName: "a", varDefineValue: float32(1), varGetValue: float32(1), varKind: reflect.Float32},
- {testInfo: "float64", varName: "a", varDefineValue: float64(1), varGetValue: float64(1), varKind: reflect.Float64},
- {testInfo: "string", varName: "a", varDefineValue: "a", varGetValue: "a", varKind: reflect.String},
- {testInfo: "string with dot", varName: "a.a", varDefineValue: "a", varGetValue: nil, varKind: reflect.Interface, defineError: ErrSymbolContainsDot, getError: fmt.Errorf("undefined symbol 'a.a'")},
- {testInfo: "string with quotes", varName: "a", varDefineValue: `"a"`, varGetValue: `"a"`, varKind: reflect.String},
- }
- // DefineAndGet
- for _, test := range tests {
- env := NewEnv()
- err = env.Define(test.varName, test.varDefineValue)
- if err != nil && test.defineError != nil {
- if err.Error() != test.defineError.Error() {
- t.Errorf("DefineAndGet %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- } else if err != test.defineError {
- t.Errorf("DefineAndGet %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- value, err = env.Get(test.varName)
- if err != nil && test.getError != nil {
- if err.Error() != test.getError.Error() {
- t.Errorf("DefineAndGet %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
- continue
- }
- } else if err != test.getError {
- t.Errorf("DefineAndGet %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
- continue
- }
- if value != test.varGetValue {
- t.Errorf("DefineAndGet %v - value check - received %#v expected: %#v", test.testInfo, value, test.varGetValue)
- }
- }
- // DefineAndGet NewEnv
- for _, test := range tests {
- envParent := NewEnv()
- envChild := envParent.NewEnv()
- err = envParent.Define(test.varName, test.varDefineValue)
- if err != nil && test.defineError != nil {
- if err.Error() != test.defineError.Error() {
- t.Errorf("DefineAndGet NewEnv %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- } else if err != test.defineError {
- t.Errorf("DefineAndGet NewEnv %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- value, err = envChild.Get(test.varName)
- if err != nil && test.getError != nil {
- if err.Error() != test.getError.Error() {
- t.Errorf("DefineAndGet NewEnv %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
- continue
- }
- } else if err != test.getError {
- t.Errorf("DefineAndGet NewEnv %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
- continue
- }
- if value != test.varGetValue {
- t.Errorf("DefineAndGet NewEnv %v - value check - received %#v expected: %#v", test.testInfo, value, test.varGetValue)
- }
- }
- // DefineAndGet DefineGlobal
- for _, test := range tests {
- envParent := NewEnv()
- envChild := envParent.NewEnv()
- err = envChild.DefineGlobal(test.varName, test.varDefineValue)
- if err != nil && test.defineError != nil {
- if err.Error() != test.defineError.Error() {
- t.Errorf("DefineAndGet DefineGlobal %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- } else if err != test.defineError {
- t.Errorf("DefineAndGet DefineGlobal %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- value, err = envParent.Get(test.varName)
- if err != nil && test.getError != nil {
- if err.Error() != test.getError.Error() {
- t.Errorf("DefineAndGet DefineGlobal %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
- continue
- }
- } else if err != test.getError {
- t.Errorf("DefineAndGet DefineGlobal %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
- continue
- }
- if value != test.varGetValue {
- t.Errorf("DefineAndGet DefineGlobal %v - value check - received %#v expected: %#v", test.testInfo, value, test.varGetValue)
- }
- }
- }
- func TestDefineModify(t *testing.T) {
- var err error
- var value interface{}
- tests := []struct {
- testInfo string
- varName string
- varDefineValue interface{}
- varGetValue interface{}
- varKind reflect.Kind
- defineError error
- getError error
- }{
- {testInfo: "nil", varName: "a", varDefineValue: nil, varGetValue: nil, varKind: reflect.Interface},
- {testInfo: "bool", varName: "a", varDefineValue: true, varGetValue: true, varKind: reflect.Bool},
- {testInfo: "int64", varName: "a", varDefineValue: int64(1), varGetValue: int64(1), varKind: reflect.Int64},
- {testInfo: "float64", varName: "a", varDefineValue: float64(1), varGetValue: float64(1), varKind: reflect.Float64},
- {testInfo: "string", varName: "a", varDefineValue: "a", varGetValue: "a", varKind: reflect.String},
- }
- changeTests := []struct {
- varDefineValue interface{}
- varGetValue interface{}
- varKind reflect.Kind
- defineError error
- getError error
- }{
- {varDefineValue: nil, varGetValue: nil, varKind: reflect.Interface},
- {varDefineValue: "a", varGetValue: "a", varKind: reflect.String},
- {varDefineValue: int64(1), varGetValue: int64(1), varKind: reflect.Int64},
- {varDefineValue: float64(1), varGetValue: float64(1), varKind: reflect.Float64},
- {varDefineValue: true, varGetValue: true, varKind: reflect.Bool},
- }
- // DefineModify
- for _, test := range tests {
- env := NewEnv()
- err = env.Define(test.varName, test.varDefineValue)
- if err != nil && test.defineError != nil {
- if err.Error() != test.defineError.Error() {
- t.Errorf("DefineModify %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- } else if err != test.defineError {
- t.Errorf("DefineModify %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- value, err = env.Get(test.varName)
- if err != nil && test.getError != nil {
- if err.Error() != test.getError.Error() {
- t.Errorf("DefineModify %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
- continue
- }
- } else if err != test.getError {
- t.Errorf("DefineModify %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
- continue
- }
- if value != test.varGetValue {
- t.Errorf("DefineModify %v - value check - received %#v expected: %#v", test.testInfo, value, test.varGetValue)
- }
- // DefineModify changeTest
- for _, changeTest := range changeTests {
- err = env.Set(test.varName, changeTest.varDefineValue)
- if err != nil && changeTest.defineError != nil {
- if err.Error() != changeTest.defineError.Error() {
- t.Errorf("DefineModify changeTest %v - Set error - received: %v - expected: %v", test.testInfo, err, changeTest.defineError)
- continue
- }
- } else if err != changeTest.defineError {
- t.Errorf("DefineModify changeTest %v - Set error - received: %v - expected: %v", test.testInfo, err, changeTest.defineError)
- continue
- }
- value, err = env.Get(test.varName)
- if err != nil && changeTest.getError != nil {
- if err.Error() != changeTest.getError.Error() {
- t.Errorf("DefineModify changeTest %v - Get error - received: %v - expected: %v", test.testInfo, err, changeTest.getError)
- continue
- }
- } else if err != changeTest.getError {
- t.Errorf("DefineModify changeTest %v - Get error - received: %v - expected: %v", test.testInfo, err, changeTest.getError)
- continue
- }
- if value != changeTest.varGetValue {
- t.Errorf("DefineModify changeTest %v - value check - received %#v expected: %#v", test.testInfo, value, changeTest.varGetValue)
- }
- }
- }
- // DefineModify envParent
- for _, test := range tests {
- envParent := NewEnv()
- envChild := envParent.NewEnv()
- err = envParent.Define(test.varName, test.varDefineValue)
- if err != nil && test.defineError != nil {
- if err.Error() != test.defineError.Error() {
- t.Errorf("DefineModify envParent %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- } else if err != test.defineError {
- t.Errorf("DefineModify envParent %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- value, err = envChild.Get(test.varName)
- if err != nil && test.getError != nil {
- if err.Error() != test.getError.Error() {
- t.Errorf("DefineModify envParent %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
- continue
- }
- } else if err != test.getError {
- t.Errorf("DefineModify envParent %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
- continue
- }
- if value != test.varGetValue {
- t.Errorf("DefineModify envParent %v - value check - received %#v expected: %#v", test.testInfo, value, test.varGetValue)
- }
- for _, changeTest := range changeTests {
- err = envParent.Set(test.varName, changeTest.varDefineValue)
- if err != nil && changeTest.defineError != nil {
- if err.Error() != changeTest.defineError.Error() {
- t.Errorf("DefineModify envParent changeTest %v - Set error - received: %v - expected: %v", test.testInfo, err, changeTest.defineError)
- continue
- }
- } else if err != changeTest.defineError {
- t.Errorf("DefineModify envParent changeTest %v - Set error - received: %v - expected: %v", test.testInfo, err, changeTest.defineError)
- continue
- }
- value, err = envChild.Get(test.varName)
- if err != nil && changeTest.getError != nil {
- if err.Error() != changeTest.getError.Error() {
- t.Errorf("DefineModify envParent changeTest %v - Get error - received: %v - expected: %v", test.testInfo, err, changeTest.getError)
- continue
- }
- } else if err != changeTest.getError {
- t.Errorf("ChanDefineModify envParent changeTestgeTest %v - Get error - received: %v - expected: %v", test.testInfo, err, changeTest.getError)
- continue
- }
- if value != changeTest.varGetValue {
- t.Errorf("DefineModify envParent changeTest %v - value check - received %#v expected: %#v", test.testInfo, value, changeTest.varGetValue)
- }
- }
- }
- // DefineModify envChild
- for _, test := range tests {
- envParent := NewEnv()
- envChild := envParent.NewEnv()
- err = envParent.Define(test.varName, test.varDefineValue)
- if err != nil && test.defineError != nil {
- if err.Error() != test.defineError.Error() {
- t.Errorf("DefineModify envChild %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- } else if err != test.defineError {
- t.Errorf("DefineModify envChild %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- value, err = envChild.Get(test.varName)
- if err != nil && test.getError != nil {
- if err.Error() != test.getError.Error() {
- t.Errorf("DefineModify envChild %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
- continue
- }
- } else if err != test.getError {
- t.Errorf("DefineModify envChild %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
- continue
- }
- if value != test.varGetValue {
- t.Errorf("DefineModify envChild %v - value check - received %#v expected: %#v", test.testInfo, value, test.varGetValue)
- }
- for _, changeTest := range changeTests {
- err = envChild.Set(test.varName, changeTest.varDefineValue)
- if err != nil && changeTest.defineError != nil {
- if err.Error() != changeTest.defineError.Error() {
- t.Errorf("DefineModify envChild changeTest %v - Set error - received: %v - expected: %v", test.testInfo, err, changeTest.defineError)
- continue
- }
- } else if err != changeTest.defineError {
- t.Errorf("DefineModify envChild changeTest %v - Set error - received: %v - expected: %v", test.testInfo, err, changeTest.defineError)
- continue
- }
- value, err = envChild.Get(test.varName)
- if err != nil && changeTest.getError != nil {
- if err.Error() != changeTest.getError.Error() {
- t.Errorf("DefineModify envChild changeTest %v - Get error - received: %v - expected: %v", test.testInfo, err, changeTest.getError)
- continue
- }
- } else if err != changeTest.getError {
- t.Errorf("ChanDefineModify envChild changeTestgeTest %v - Get error - received: %v - expected: %v", test.testInfo, err, changeTest.getError)
- continue
- }
- if value != changeTest.varGetValue {
- t.Errorf("DefineModify envChild changeTest %v - value check - received %#v expected: %#v", test.testInfo, value, changeTest.varGetValue)
- }
- }
- }
- }
- func TestAddr(t *testing.T) {
- var err error
- tests := []struct {
- testInfo string
- varName string
- varDefineValue interface{}
- defineError error
- addrError error
- }{
- {testInfo: "nil", varName: "a", varDefineValue: nil, addrError: nil},
- {testInfo: "string", varName: "a", varDefineValue: "a", addrError: fmt.Errorf("unaddressable")},
- {testInfo: "int64", varName: "a", varDefineValue: int64(1), addrError: fmt.Errorf("unaddressable")},
- {testInfo: "float64", varName: "a", varDefineValue: float64(1), addrError: fmt.Errorf("unaddressable")},
- {testInfo: "bool", varName: "a", varDefineValue: true, addrError: fmt.Errorf("unaddressable")},
- }
- // TestAddr
- for _, test := range tests {
- envParent := NewEnv()
- envChild := envParent.NewEnv()
- err = envParent.Define(test.varName, test.varDefineValue)
- if err != nil && test.defineError != nil {
- if err.Error() != test.defineError.Error() {
- t.Errorf("TestAddr %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- } else if err != test.defineError {
- t.Errorf("TestAddr %v - Define error - received: %v - expected: %v", test.testInfo, err, test.defineError)
- continue
- }
- _, err = envChild.Addr(test.varName)
- if err != nil && test.addrError != nil {
- if err.Error() != test.addrError.Error() {
- t.Errorf("TestAddr %v - Addr error - received: %v - expected: %v", test.testInfo, err, test.addrError)
- continue
- }
- } else if err != test.addrError {
- t.Errorf("TestAddr %v - Addr error - received: %v - expected: %v", test.testInfo, err, test.addrError)
- continue
- }
- }
- }
- func TestDelete(t *testing.T) {
- // empty
- env := NewEnv()
- env.Delete("a")
- // add & delete a
- env.Define("a", "a")
- env.Delete("a")
- value, err := env.Get("a")
- expectedError := "undefined symbol 'a'"
- if err == nil || err.Error() != expectedError {
- t.Errorf("Get error - received: %v - expected: %v", err, expectedError)
- }
- if value != nil {
- t.Errorf("Get value - received: %#v - expected: %#v", value, nil)
- }
- }
- func TestDeleteGlobal(t *testing.T) {
- // empty
- env := NewEnv()
- env.DeleteGlobal("a")
- // add & delete a
- env.Define("a", "a")
- env.DeleteGlobal("a")
- value, err := env.Get("a")
- expectedError := "undefined symbol 'a'"
- if err == nil || err.Error() != expectedError {
- t.Errorf("Get error - received: %v - expected: %v", err, expectedError)
- }
- if value != nil {
- t.Errorf("Get value - received: %#v - expected: %#v", value, nil)
- }
- // parent & child, var in child, delete in parent
- envChild := env.NewEnv()
- envChild.Define("a", "a")
- env.DeleteGlobal("a")
- value, err = envChild.Get("a")
- if err != nil {
- t.Errorf("Get error - received: %v - expected: %v", err, nil)
- }
- if value != "a" {
- t.Errorf("Get value - received: %#v - expected: %#v", value, "a")
- }
- // parent & child, var in child, delete in child
- envChild.DeleteGlobal("a")
- value, err = envChild.Get("a")
- if err == nil || err.Error() != expectedError {
- t.Errorf("Get error - received: %v - expected: %v", err, expectedError)
- }
- if value != nil {
- t.Errorf("Get value - received: %#v - expected: %#v", value, nil)
- }
- // parent & child, var in parent, delete in child
- env.Define("a", "a")
- envChild.DeleteGlobal("a")
- value, err = envChild.Get("a")
- if err == nil || err.Error() != expectedError {
- t.Errorf("Get error - received: %v - expected: %v", err, expectedError)
- }
- if value != nil {
- t.Errorf("Get value - received: %#v - expected: %#v", value, nil)
- }
- // parent & child, var in parent, delete in parent
- env.Define("a", "a")
- env.DeleteGlobal("a")
- value, err = envChild.Get("a")
- if err == nil || err.Error() != expectedError {
- t.Errorf("Get error - received: %v - expected: %v", err, expectedError)
- }
- if value != nil {
- t.Errorf("Get value - received: %#v - expected: %#v", value, nil)
- }
- }
- func TestRaceCreateSameVariable(t *testing.T) {
- // Test creating same variable in parallel
- waitChan := make(chan struct{}, 1)
- var waitGroup sync.WaitGroup
- env := NewEnv()
- for i := 0; i < 100; i++ {
- waitGroup.Add(1)
- go func(i int) {
- <-waitChan
- err := env.Define("a", i)
- if err != nil {
- t.Errorf("Define error: %v", err)
- }
- _, err = env.Get("a")
- if err != nil {
- t.Errorf("Get error: %v", err)
- }
- waitGroup.Done()
- }(i)
- }
- close(waitChan)
- waitGroup.Wait()
- _, err := env.Get("a")
- if err != nil {
- t.Errorf("Get error: %v", err)
- }
- }
- func TestRaceCreateDifferentVariables(t *testing.T) {
- // Test creating different variables in parallel
- waitChan := make(chan struct{}, 1)
- var waitGroup sync.WaitGroup
- env := NewEnv()
- for i := 0; i < 100; i++ {
- waitGroup.Add(1)
- go func(i int) {
- <-waitChan
- err := env.Define(fmt.Sprint(i), i)
- if err != nil {
- t.Errorf("Define error: %v", err)
- }
- _, err = env.Get(fmt.Sprint(i))
- if err != nil {
- t.Errorf("Get error: %v", err)
- }
- waitGroup.Done()
- }(i)
- }
- close(waitChan)
- waitGroup.Wait()
- for i := 0; i < 100; i++ {
- _, err := env.Get(fmt.Sprint(i))
- if err != nil {
- t.Errorf("Get error: %v", err)
- }
- }
- }
- func TestRaceReadDifferentVariables(t *testing.T) {
- // Test reading different variables in parallel
- waitChan := make(chan struct{}, 1)
- var waitGroup sync.WaitGroup
- env := NewEnv()
- for i := 0; i < 100; i++ {
- err := env.Define(fmt.Sprint(i), i)
- if err != nil {
- t.Errorf("Define error: %v", err)
- }
- _, err = env.Get(fmt.Sprint(i))
- if err != nil {
- t.Errorf("Get error: %v", err)
- }
- }
- for i := 0; i < 100; i++ {
- waitGroup.Add(1)
- go func(i int) {
- <-waitChan
- _, err := env.Get(fmt.Sprint(i))
- if err != nil {
- t.Errorf("Get error: %v", err)
- }
- waitGroup.Done()
- }(i)
- }
- close(waitChan)
- waitGroup.Wait()
- }
- func TestRaceSetSameVariable(t *testing.T) {
- // Test setting same variable in parallel
- waitChan := make(chan struct{}, 1)
- var waitGroup sync.WaitGroup
- env := NewEnv()
- err := env.Define("a", 0)
- if err != nil {
- t.Errorf("Define error: %v", err)
- }
- _, err = env.Get("a")
- if err != nil {
- t.Errorf("Get error: %v", err)
- }
- for i := 0; i < 100; i++ {
- waitGroup.Add(1)
- go func(i int) {
- <-waitChan
- err := env.Set("a", i)
- if err != nil {
- t.Errorf("Set error: %v", err)
- }
- waitGroup.Done()
- }(i)
- }
- close(waitChan)
- waitGroup.Wait()
- _, err = env.Get("a")
- if err != nil {
- t.Errorf("Get error: %v", err)
- }
- }
- func TestRaceSetSameVariableNewEnv(t *testing.T) {
- // Test setting same variable in parallel with NewEnv
- waitChan := make(chan struct{}, 1)
- var waitGroup sync.WaitGroup
- env := NewEnv()
- err := env.Define("a", 0)
- if err != nil {
- t.Errorf("Define error: %v", err)
- }
- _, err = env.Get("a")
- if err != nil {
- t.Errorf("Get error: %v", err)
- }
- for i := 0; i < 100; i++ {
- waitGroup.Add(1)
- go func(i int) {
- <-waitChan
- env = env.NewEnv().NewEnv()
- err := env.Set("a", i)
- if err != nil {
- t.Errorf("Set error: %v", err)
- }
- waitGroup.Done()
- }(i)
- }
- }
- func TestRaceDefineAndSetSameVariable(t *testing.T) {
- // Test defining and setting same variable in parallel
- for i := 0; i < 100; i++ {
- raceDefineAndSetSameVariable(t)
- }
- }
- func raceDefineAndSetSameVariable(t *testing.T) {
- waitChan := make(chan struct{}, 1)
- var waitGroup sync.WaitGroup
- envParent := NewEnv()
- envChild := envParent.NewEnv()
- for i := 0; i < 2; i++ {
- waitGroup.Add(1)
- go func() {
- <-waitChan
- err := envParent.Set("a", 1)
- if err != nil && err.Error() != "undefined symbol 'a'" {
- t.Errorf("Set error: %v", err)
- }
- waitGroup.Done()
- }()
- waitGroup.Add(1)
- go func() {
- <-waitChan
- err := envParent.Define("a", 2)
- if err != nil {
- t.Errorf("Define error: %v", err)
- }
- waitGroup.Done()
- }()
- waitGroup.Add(1)
- go func() {
- <-waitChan
- err := envChild.Set("a", 3)
- if err != nil && err.Error() != "undefined symbol 'a'" {
- t.Errorf("Set error: %v", err)
- }
- waitGroup.Done()
- }()
- waitGroup.Add(1)
- go func() {
- <-waitChan
- err := envChild.Define("a", 4)
- if err != nil {
- t.Errorf("Define error: %v", err)
- }
- waitGroup.Done()
- }()
- }
- close(waitChan)
- waitGroup.Wait()
- _, err := envParent.Get("a") // value of a could be 1, 2, or 3
- if err != nil {
- t.Errorf("Get error: %v", err)
- }
- _, err = envChild.Get("a") // value of a could be 3 or 4
- if err != nil {
- t.Errorf("Get error: %v", err)
- }
- }
- func BenchmarkDefine(b *testing.B) {
- var err error
- env := NewEnv()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- err := env.Define("a", 1)
- if err != nil {
- b.Errorf("Set error: %v", err)
- }
- }
- b.StopTimer()
- _, err = env.Get("a")
- if err != nil {
- b.Errorf("Get error: %v", err)
- }
- }
- func BenchmarkSet(b *testing.B) {
- env := NewEnv()
- err := env.Define("a", 1)
- if err != nil {
- b.Errorf("Define error: %v", err)
- }
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- err = env.Set("a", 1)
- if err != nil {
- b.Errorf("Set error: %v", err)
- }
- }
- b.StopTimer()
- _, err = env.Get("a")
- if err != nil {
- b.Errorf("Get error: %v", err)
- }
- }
|