func TestExecute(t *testing.T) { conn := ConnectToTestDb(t) if conn == nil { return } defer conn.Close() rst, err := conn.Exec("select 1") assert.Nil(t, err) assert.NotNil(t, rst) assert.Equal(t, 1, len(rst)) rst, err = conn.Exec("select missing") assert.NotNil(t, err) assert.Nil(t, rst) rst, err = conn.Exec("print 'pero'") assert.Nil(t, err) assert.NotNil(t, rst) assert.True(t, strings.Contains(conn.Message, "pero")) assert.Equal(t, 1, len(rst)) assert.Equal(t, 0, len(rst[0].Rows)) rst, err = conn.Exec("sp_help 'authors'") assert.Nil(t, err) assert.NotNil(t, rst) assert.Equal(t, 9, len(rst)) }
func Test_EnableDebugTopics(t *testing.T) { assert.Equal(t, 0, int(defaultlogger.debug)) EnableDebugTopics([]string{"ast", "build"}) assert.Equal(t, AST|BUILD, defaultlogger.debug) EnableDebugTopics([]string{" dag", ""}) assert.Equal(t, AST|DAG|BUILD, defaultlogger.debug) }
func Test_SequenceAction_create(t *testing.T) { rt := &Runtime{} action := NewSequenceAction() assert.Equal(t, 0, len(action.subactions)) // Execute() on an empty SequenceAction does nothing, silently assert.Nil(t, action.Execute(rt)) // action 1 is a bare string: "ls -lR foo/bar" cmd := dsl.NewASTString("\"ls -lR foo/bar\"") action.AddCommand(cmd) // action 2: a = "foo" assign := dsl.NewASTAssignment( "a", dsl.NewASTString("foo")) action.AddAssignment(assign) // action 3: remove("*.o") fcall := dsl.NewASTFunctionCall( dsl.NewASTString("remove"), []dsl.ASTExpression{dsl.NewASTString("\"*.c\"")}) action.AddFunctionCall(fcall) assert.Equal(t, 3, len(action.subactions)) assert.Equal(t, "ls -lR foo/bar", action.subactions[0].(*CommandAction).raw.ValueString()) }
func TestMethodString(t *testing.T) { responseWriter := new(http_test.TestResponseWriter) testRequest, _ := http.NewRequest("get", "http://goweb.org/people/123", nil) codecService := new(codecservices.WebCodecService) c := NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, "GET", c.MethodString()) responseWriter = new(http_test.TestResponseWriter) testRequest, _ = http.NewRequest("put", "http://goweb.org/people/123", nil) c = NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, "PUT", c.MethodString()) responseWriter = new(http_test.TestResponseWriter) testRequest, _ = http.NewRequest("DELETE", "http://goweb.org/people/123", nil) c = NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, "DELETE", c.MethodString()) responseWriter = new(http_test.TestResponseWriter) testRequest, _ = http.NewRequest("anything", "http://goweb.org/people/123", nil) c = NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, "ANYTHING", c.MethodString()) }
func TestPPUWriteMask(t *testing.T) { p := NewPPU() assert.Equal(t, p.Masks.Grayscale, false) p.Write(0xff, PPUMASK) assert.Equal(t, p.Masks.Grayscale, true) }
// full build (all targets), one action fails func Test_BuildState_BuildTargets_one_failure(t *testing.T) { sig := []byte{0} graph, executed := setupBuild(false, sig) db := makeFakeDB(graph, sig) // fail to build misc.{c,h} -> misc.o: that will stop the build rule := graph.Lookup("misc.o").BuildRule().(*dag.StubRule) rule.SetFail(true) expect := []buildexpect{ {"tool1.o", dag.BUILT}, {"misc.o", dag.FAILED}, } opts := BuildOptions{} bstate := NewBuildState(graph, db, opts) goal := graph.MakeNodeSet("tool1", "tool2") err := bstate.BuildTargets(goal) assert.NotNil(t, err) assertBuild(t, graph, expect, *executed) // we didn't even think about building util.o, tool1, etc: an // earlier node failed and the build terminates on first failure assert.Equal(t, dag.UNKNOWN, graph.Lookup("util.o").State()) assert.Equal(t, dag.UNKNOWN, graph.Lookup("tool1").State()) assert.Equal(t, dag.UNKNOWN, graph.Lookup("tool2").State()) }
func TestImpossibleComputer_Move(t *testing.T) { var computer = NewImpossibleComputer() var board = NewBoard() computer.SetMark("X") t.Log("#Move returns any winning move") AddMarks(board, "X", 1, 4) AddMarks(board, "O", 0, 2, 3) assert.Equal(t, computer.Move(*board), 7) t.Log("#Move blocks any winning move") board.Reset() AddMarks(board, "X", 0, 6) AddMarks(board, "O", 3, 4) assert.Equal(t, computer.Move(*board), 5) fakeMinimax := new(FakeMinimax) computer.Minimax = fakeMinimax t.Log("#Move uses the highest of Minimax scores") board.Reset() fakeMinimax.StubScores = map[int]int{1: 0, 3: 1, 4: -1, 5: 0} assert.Equal(t, computer.Move(*board), 3) fakeMinimax.StubScores = map[int]int{1: -1, 3: -1, 4: -1, 5: 0} assert.Equal(t, computer.Move(*board), 5) }
func Test_FileNode_Expand(t *testing.T) { ns := types.NewValueMap() node := NewFileNode("foobar") xnode, err := node.ActionExpand(ns, nil) assert.Nil(t, err) assert.Equal(t, node, xnode) err = node.NodeExpand(ns) assert.Nil(t, err) assert.Equal(t, "foobar", node.Name()) // test that ActionExpand() follows variable references node = NewFileNode("$foo$bar") xnode, err = node.ActionExpand(ns, nil) assert.Equal(t, "undefined variable 'foo' in string", err.Error()) // make it so "$foo$bar" expands to "$foo", and ensure that // expansion stops there // XXX argh: currently this expands to "'$'foo": hmmmmm // ns.Assign("foo", types.MakeFuString("$")) // ns.Assign("bar", types.MakeFuString("foo")) // xnode, err = node.ActionExpand(ns, nil) // assert.Nil(t, err) // assert.Equal(t, "$foo", xnode.String()) }
func TestCleanSegmentName(t *testing.T) { assert.Equal(t, "id", cleanSegmentName("id")) assert.Equal(t, "id", cleanSegmentName("{id}")) assert.Equal(t, "id", cleanSegmentName("[id]")) }
func TestRegexPath(t *testing.T) { pattern := `^[a-z]+\[[0-9]+\]$` matcherFunc := RegexPath(pattern) var ctx context.Context var decision MatcherFuncDecision ctx = context_test.MakeTestContextWithPath("adam[23]") decision, _ = matcherFunc(ctx) assert.Equal(t, Match, decision, "adam[23] should match") ctx = context_test.MakeTestContextWithPath("eve[7]") decision, _ = matcherFunc(ctx) assert.Equal(t, Match, decision, "eve[7] should match") ctx = context_test.MakeTestContextWithPath("Job[23]") decision, _ = matcherFunc(ctx) assert.Equal(t, NoMatch, decision, "Job[23] should NOT match") ctx = context_test.MakeTestContextWithPath("snakey") decision, _ = matcherFunc(ctx) assert.Equal(t, NoMatch, decision, "snakey should NOT match") }
func Test_diffCharsToLines(t *testing.T) { dmp := New() // Convert chars up to lines. diffs := []Diff{ Diff{DiffEqual, "\u0001\u0002\u0001"}, Diff{DiffInsert, "\u0002\u0001\u0002"}} tmpVector := []string{"", "alpha\n", "beta\n"} actual := dmp.DiffCharsToLines(diffs, tmpVector) assertDiffEqual(t, []Diff{ Diff{DiffEqual, "alpha\nbeta\nalpha\n"}, Diff{DiffInsert, "beta\nalpha\nbeta\n"}}, actual) // More than 256 to reveal any 8-bit limitations. n := 257 tmpVector = []string{} lineList := []rune{} charList := []rune{} for x := 1; x <= n; x++ { tmpVector = append(tmpVector, string(x)+"\n") lineList = append(lineList, rune(x), '\n') charList = append(charList, rune(x)) } assert.Equal(t, n, len(tmpVector)) assert.Equal(t, n, len(charList)) tmpVector = append([]string{""}, tmpVector...) diffs = []Diff{Diff{DiffDelete, string(charList)}} actual = dmp.DiffCharsToLines(diffs, tmpVector) assertDiffEqual(t, []Diff{ Diff{DiffDelete, string(lineList)}}, actual) }
// hmmmm: interface-wise, this tests that FinderNode.Add() returns an // object whose CommandString() behaves sensibly... but in // implementation terms, it's really a test of FuList.CommandString() func Test_FinderNode_Add_CommandString(t *testing.T) { finder1 := NewFinderNode("*.c", "*.h") finder2 := NewFinderNode("doc/???.txt") finder3 := NewFinderNode() sum1, err := finder1.Add(finder2) assert.Nil(t, err) assert.Equal(t, "'*.c' '*.h' 'doc/???.txt'", sum1.CommandString()) sum2, err := finder3.Add(sum1) assert.Nil(t, err) assert.Equal(t, "'*.c' '*.h' 'doc/???.txt'", sum2.CommandString()) assert.False(t, sum1.Equal(sum2)) sum2b, err := finder3.Add(sum1) assert.Nil(t, err) assert.True(t, sum2.Equal(sum2b), "expected equal ListNodes:\nsum2 = %T %v\nsum2b = %T %v", sum2, sum2, sum2b, sum2b) // This is a silly thing to do, and perhaps we should filter out // the duplicate patterns... but I don't think so. If the user // constructs something silly, we do something silly. sum3, err := sum1.Add(sum2) assert.Nil(t, err) assert.Equal(t, "'*.c' '*.h' 'doc/???.txt' '*.c' '*.h' 'doc/???.txt'", sum3.CommandString()) }
func Test_FuFunction_CheckArgs_minmax(t *testing.T) { fn := NewVariadicFunction("bar", 2, 4, nil) val := MakeFuString("a") args := MakeBasicArgs(nil, []FuObject{val}, nil) err := fn.CheckArgs(args) assert.Equal(t, "function bar() requires at least 2 arguments (got 1)", err.Error()) // 2 args are good args.args = append(args.args, val) err = fn.CheckArgs(args) assert.Nil(t, err) // 3 args are good args.args = append(args.args, val) err = fn.CheckArgs(args) assert.Nil(t, err) // 4 args are good args.args = append(args.args, val) err = fn.CheckArgs(args) assert.Nil(t, err) // but 5 args is *right out* args.args = append(args.args, val) err = fn.CheckArgs(args) assert.Equal(t, "function bar() takes at most 4 arguments (got 5)", err.Error()) }
func Test_FuFunction_CheckArgs_fixed(t *testing.T) { val := MakeFuString("a") args := MakeBasicArgs(nil, []FuObject{}, nil) fn := NewFixedFunction("meep", 0, nil) err := fn.CheckArgs(args) assert.Nil(t, err) args.args = append(args.args, val) err = fn.CheckArgs(args) assert.Equal(t, "function meep() takes no arguments (got 1)", err.Error()) fn = NewFixedFunction("foo", 2, nil) args.args = args.args[:0] err = fn.CheckArgs(args) assert.Equal(t, "function foo() takes exactly 2 arguments (got 0)", err.Error()) args.args = append(args.args, val) err = fn.CheckArgs(args) assert.Equal(t, "function foo() takes exactly 2 arguments (got 1)", err.Error()) args.args = append(args.args, val) err = fn.CheckArgs(args) assert.Nil(t, err) args.args = append(args.args, val) err = fn.CheckArgs(args) assert.Equal(t, "function foo() takes exactly 2 arguments (got 3)", err.Error()) }
func Test_BuiltinList(t *testing.T) { blist := BuiltinList{} fn, ok := blist.Lookup("foo") assert.False(t, ok) assert.Nil(t, fn) callable := types.NewFixedFunction("foo", 3, nil) blist.builtins = append(blist.builtins, callable) fn, ok = blist.Lookup("foo") assert.True(t, ok) assert.Equal(t, callable, fn) blist.builtins = append( blist.builtins, types.NewFixedFunction("bar", 0, nil)) blist.builtins = append( blist.builtins, types.NewFixedFunction("bop", 0, nil)) blist.builtins = append( blist.builtins, types.NewFixedFunction("bam", 0, nil)) blist.builtins = append( blist.builtins, types.NewFixedFunction("pow", 0, nil)) assert.Equal(t, 5, blist.NumBuiltins()) actual := make([]string, 0, 5) visit := func(name string, code types.FuObject) error { actual = append(actual, name) if name == "bam" { return errors.New("bam!") } return nil } err := blist.ForEach(visit) assert.Equal(t, []string{"foo", "bar", "bop", "bam"}, actual) assert.Equal(t, "bam!", err.Error()) }
func TestErrorHandlerGetsUsedOnError(t *testing.T) { responseWriter := new(http_test.TestResponseWriter) testRequest, _ := http.NewRequest("GET", "http://stretchr.org/goweb", nil) codecService := new(codecservices.WebCodecService) handler := NewHttpHandler(codecService) errorHandler := new(handlers_test.TestHandler) handler.SetErrorHandler(errorHandler) errorHandler.On("Handle", mock.Anything).Return(false, nil) // make a handler throw an error var theError error = errors.New("Test error") handler.Map(func(c context.Context) error { return theError }) handler.ServeHTTP(responseWriter, testRequest) if mock.AssertExpectationsForObjects(t, errorHandler.Mock) { // get the first context ctx := errorHandler.Calls[0].Arguments[0].(context.Context) // make sure the error data field was set assert.Equal(t, theError.Error(), ctx.Data().Get("error").(HandlerError).Error(), "the error should be set in the data with the 'error' key") assert.Equal(t, responseWriter, ctx.HttpResponseWriter()) assert.Equal(t, testRequest, ctx.HttpRequest()) } }
func TestMapStaticFile(t *testing.T) { codecService := new(codecservices.WebCodecService) h := NewHttpHandler(codecService) h.MapStaticFile("/static-file", "/location/of/static-file") assert.Equal(t, 1, len(h.HandlersPipe())) staticHandler := h.HandlersPipe()[0].(*PathMatchHandler) if assert.Equal(t, 1, len(staticHandler.HttpMethods)) { assert.Equal(t, goweb_http.MethodGet, staticHandler.HttpMethods[0]) } var ctx context.Context var willHandle bool ctx = context_test.MakeTestContextWithPath("/static-file") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("static-file") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("static-file/") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("static-file/something-else") willHandle, _ = staticHandler.WillHandle(ctx) assert.False(t, willHandle, "Static handler NOT should handle") }
func TestPrependPreHandler(t *testing.T) { handler1 := new(handlers_test.TestHandler) handler2 := new(handlers_test.TestHandler) codecService := new(codecservices.WebCodecService) h := NewHttpHandler(codecService) handler1.TestData().Set("id", 1) handler2.TestData().Set("id", 2) handler1.On("WillHandle", mock.Anything).Return(true, nil) handler1.On("Handle", mock.Anything).Return(false, nil) handler2.On("WillHandle", mock.Anything).Return(true, nil) handler2.On("Handle", mock.Anything).Return(false, nil) h.PrependPreHandler(handler1) h.PrependPreHandler(handler2) h.Handlers.Handle(nil) assert.Equal(t, 2, len(h.PreHandlersPipe())) assert.Equal(t, 2, h.PreHandlersPipe()[0].(*handlers_test.TestHandler).TestData().Get("id")) assert.Equal(t, 1, h.PreHandlersPipe()[1].(*handlers_test.TestHandler).TestData().Get("id")) mock.AssertExpectationsForObjects(t, handler1.Mock) }
// full build of all targets, all actions succeed func Test_BuildState_BuildTargets_all_changed(t *testing.T) { // This is actually an unusual case: we rebuild all targets // because all sources have changed. A much more likely reason for // a full build is that all targets are missing, e.g. a fresh // working dir. oldsig := []byte{0} newsig := []byte{1} graph, executed := setupBuild(true, newsig) db := makeFakeDB(graph, oldsig) expect := []buildexpect{ {"tool1.o", dag.BUILT}, {"misc.o", dag.BUILT}, {"util.o", dag.BUILT}, {"tool1", dag.BUILT}, {"tool2.o", dag.BUILT}, {"tool2", dag.BUILT}, } bstate := NewBuildState(graph, db, BuildOptions{}) goal := graph.MakeNodeSet("tool1", "tool2") err := bstate.BuildTargets(goal) assert.Nil(t, err) assertBuild(t, graph, expect, *executed) assert.Equal(t, dag.SOURCE, graph.Lookup("tool2.c").State()) assert.Equal(t, dag.SOURCE, graph.Lookup("misc.h").State()) assert.Equal(t, dag.SOURCE, graph.Lookup("util.c").State()) }
func TestNewDateTypesParam(t *testing.T) { conn := ConnectToTestDb(t) err := createProcedure(conn, "test_sp_with_datetimeoffset_param", ` (@p1 datetimeoffset, @p2 date, @p3 time, @p4 datetime2) as DECLARE @datetime datetime = @p1; SELECT @datetime, @p1, @p2, @p3, @p4 return `) assert.Nil(t, err) p1 := "2025-12-10 12:32:10.1237000 +01:00" p2 := "2025-12-10" p3 := "12:30" p4 := "2025-12-10 12:32:10" rst, err := conn.ExecSp("test_sp_with_datetimeoffset_param", p1, p2, p3, p4) assert.Nil(t, err) assert.NotNil(t, rst) rst.Next() var op1, op2, op3, op4 string var dt time.Time err = rst.Scan(&dt, &op1, &op2, &op3, &op4) assert.Nil(t, err) assert.Equal(t, "2025-12-10T12:32:10+01:00", dt.Format(time.RFC3339)) assert.Equal(t, "2025-12-10 12:32:10.1237000 +01:00", op1) assert.Equal(t, "2025-12-10", op2) assert.Equal(t, "12:30:00.0000000", op3) assert.Equal(t, "2025-12-10 12:32:10.0000000", op4) }
func TestChannelClientClose(t *testing.T) { sm, cm := newServerAndClient() wg := &sync.WaitGroup{} wg.Add(1) go func() { defer wg.Done() c, err := sm.Accept() assert.NoError(t, err) b := make([]byte, 4) _, err = c.Read(b) assert.NoError(t, err) _, err = c.Read(b) assert.Equal(t, io.EOF, err) }() c, err := cm.Dial() assert.NoError(t, err) _, err = c.Write([]byte("PING")) assert.NoError(t, err) err = c.Close() assert.NoError(t, err) assert.NoError(t, err) _, err = c.Write([]byte("PING")) assert.Equal(t, io.EOF, err) wg.Wait() }
func TestExecSpInputParams2(t *testing.T) { conn := ConnectToTestDb(t) err := createProcedure(conn, "test_input_params2", "@p1 nvarchar(255), @p2 varchar(255), @p3 nvarchar(255), @p4 nchar(10), @p5 varbinary(10) as select @p1, @p2, @p3, @p4, @p5; return") assert.Nil(t, err) want := "£¢§‹›†€" wantp2 := "abc" wantp3 := "šđčćžabc" wantp4 := "šđčćžabcde" wantp3 = "FK Ventspils v Nõmme Kalju FC" wantp5 := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} rst, err := conn.ExecSp("test_input_params2", want, wantp2, wantp3, wantp4, wantp5) assert.Nil(t, err) assert.NotNil(t, rst) if rst == nil { return } assert.True(t, rst.HasResults()) var got, gotp2, gotp3, gotp4 string var gotp5 []byte result := rst.results[0] result.Next() result.Scan(&got, &gotp2, &gotp3, &gotp4, &gotp5) assert.Equal(t, want, got) assert.Equal(t, wantp2, gotp2) assert.Equal(t, wantp3, gotp3) assert.Equal(t, wantp4, gotp4) assert.Equal(t, wantp5, gotp5) //PrintResults(rst.Results) }
func TestPPUWriteCtrl(t *testing.T) { p := NewPPU() assert.Equal(t, p.Ctrl.VRAMAddressInc, uint8(VRAM_INC_ACROSS)) p.Write(0xff, PPUCTRL) assert.Equal(t, p.Ctrl.VRAMAddressInc, uint8(0x01)) }
func Test_FuString_ActionExpand(t *testing.T) { ns := makeNamespace("foo", "hello", "meep", "blorf") input := MakeFuString("meep meep!") output, err := input.ActionExpand(ns, nil) assert.Nil(t, err) assert.Equal(t, input, output) input = MakeFuString("meep $foo blah") output, err = input.ActionExpand(ns, nil) assert.Nil(t, err) assert.Equal(t, "meep hello blah", output.ValueString()) input = MakeFuString("hello ${foo} $meep") output, err = input.ActionExpand(ns, nil) assert.Nil(t, err) assert.Equal(t, "hello hello blorf", output.ValueString()) ns.Assign("foo", nil) output, err = input.ActionExpand(ns, nil) assert.Nil(t, err) assert.Equal(t, "hello blorf", output.ValueString()) ns.Assign("foo", MakeFuString("ping$pong")) output, err = input.ActionExpand(ns, nil) assert.Equal(t, "undefined variable 'pong' in string", err.Error()) assert.Nil(t, output) }
func TestReadingStatusSetsTheAddressLatch(t *testing.T) { p := NewPPU() assert.Equal(t, p.AddressLatch, false) p.Read(PPUSTATUS) assert.Equal(t, p.AddressLatch, true) }
func Test_FuString_Add_strings(t *testing.T) { s1 := MakeFuString("hello") s2 := MakeFuString("world") var result FuObject var err error // s1 + s1 result, err = s1.Add(s1) assert.Nil(t, err) assert.Equal(t, "hellohello", result.(FuString).value) // s1 + s2 result, err = s1.Add(s2) assert.Nil(t, err) assert.Equal(t, "helloworld", result.(FuString).value) // s1 + s2 + s1 + s2 // (equivalent to ((s1.Add(s2)).Add(s1)).Add(s2), except we have // to worry about error handling) result, err = s1.Add(s2) assert.Nil(t, err) result, err = result.Add(s1) assert.Nil(t, err) result, err = result.Add(s2) assert.Nil(t, err) assert.Equal(t, "helloworldhelloworld", result.(FuString).value) // neither s1 nor s2 is affected by all this adding assert.Equal(t, "hello", s1.value) assert.Equal(t, "world", s2.value) }
func TestPath_cleanPath(t *testing.T) { assert.Equal(t, "people/123/books", cleanPath("/people/123/books/")) assert.Equal(t, "people/123/books", cleanPath("//people/123/books/")) assert.Equal(t, "people/123/books", cleanPath("//people/123/books////")) }
func TestGoTo2SqlDataType(t *testing.T) { var checker = func(value interface{}, sqlType string, sqlFormatedValue string) { actualSqlType, actualSqlFormatedValue := go2SqlDataType(value) assert.Equal(t, actualSqlType, sqlType) assert.Equal(t, actualSqlFormatedValue, sqlFormatedValue) } checker(123, "int", "123") checker(int64(123), "bigint", "123") checker(int8(123), "tinyint", "123") checker(123.23, "real", "123.23") checker(float64(123.23), "real", "123.23") checker("iso medo", "nvarchar (8)", "'iso medo'") checker("iso medo isn't", "nvarchar (14)", "'iso medo isn''t'") tm := time.Unix(1136239445, 0) checker(tm, "datetimeoffset", "'2006-01-02T23:04:05+01:00'") checker([]byte{1, 2, 3, 4, 5, 6, 7, 8}, "varbinary (8)", "0x0102030405060708") checker("", "nvarchar (1)", "''") checker(true, "bit", "1") checker(false, "bit", "0") }
func TestSortAndFormat(t *testing.T) { johnsmith := map[string]string{"firstname": "john", "lastname": "smith"} assert.Equal(t, "firstname=john&lastname=smith", sortAndFormat(johnsmith, "&", ""), "convert map to URL string") assert.Equal(t, "firstname=\"john\",lastname=\"smith\"", sortAndFormat(johnsmith, ",", "\""), "convert map to URL string") }
func TestPoolBlock(t *testing.T) { p, _ := NewConnPool(testDbConnStr(2)) c1, _ := p.Get() c2, _ := p.Get() //check that poolGuard channel is full full := false select { case p.poolGuard <- true: default: full = true } assert.True(t, full) go func() { c3, _ := p.Get() assert.Equal(t, c2, c3) c4, _ := p.Get() assert.Equal(t, c1, c4) p.Release(c3) p.Release(c4) p.Close() }() p.Release(c1) p.Release(c2) }