package ldap import ( "testing" "github.com/hashicorp/go-hclog" "github.com/vjeantet/goldap/message" ldap "github.com/vjeantet/ldapserver" ) // recordingWriter captures everything written to it so tests can // assert on the exact sequence of responses a handler produces. type recordingWriter struct { responses []message.ProtocolOp } func (w *recordingWriter) Write(po message.ProtocolOp) { w.responses = append(w.responses, po) } func testLogger() hclog.Logger { return hclog.NewNullLogger() } func TestGuardRecoversPanic(t *testing.T) { s := &server{l: testLogger()} failed := false fail := func(ldap.ResponseWriter) { failed = true } h := s.guard(func(w ldap.ResponseWriter, m *ldap.Message) { panic("boom") }, fail) w := &recordingWriter{} h(w, &ldap.Message{}) if !failed { t.Error("the failure handler was not called after a panic") } } func TestGuardSilentAfterPartialWrite(t *testing.T) { s := &server{l: testLogger()} failed := false fail := func(ldap.ResponseWriter) { failed = true } h := s.guard(func(w ldap.ResponseWriter, m *ldap.Message) { w.Write(ldap.NewSearchResultEntry("cn=test")) panic("boom") }, fail) w := &recordingWriter{} h(w, &ldap.Message{}) if failed { t.Error("the failure handler ran even though a response was already sent") } if len(w.responses) != 1 { t.Errorf("got %d responses, want 1", len(w.responses)) } } func TestGuardPassesThrough(t *testing.T) { s := &server{l: testLogger()} h := s.guard(func(w ldap.ResponseWriter, m *ldap.Message) { w.Write(ldap.NewSearchResultDoneResponse(ldap.LDAPResultSuccess)) }, failSearchError) w := &recordingWriter{} h(w, &ldap.Message{}) if len(w.responses) != 1 { t.Fatalf("got %d responses, want 1", len(w.responses)) } if _, ok := w.responses[0].(message.SearchResultDone); !ok { t.Errorf("response is %T, want message.SearchResultDone", w.responses[0]) } }