Open
Description
What version of Cassandra are you using?
n/a
What version of Gocql are you using?
master
What did you do?
// hostfilter.go
type datacenterRegexFilter struct { pattern *regexp.Regexp }
func (d *datacenterRegexFilter) Accept(host *gocql.HostInfo) bool {
return d.pattern.MatchString(host.DataCenter())
}
var _ gocql.HostFilter = (*datacenterRegexFilter)(nil)
// hostfilter_test.go
func TestDatacenterRegexHostFilter(t *testing.T) {
f := &datacenterRegexFilter{pattern: regexp.MustCompile("us-east-1a|us-east-1d")}
assert.True(t, f.Accept(&gocql.HostInfo{
// dataCenter: "us-east-1a"
}))
}
What did you expect to see?
Test is successful
What did you see instead?
Because dataCenter
is unexported and there is no setter, this test cannot be written. The tests for other host filters can be written because they create new *HostInfo
structs inline by assigning to unexported fields. But implementations that use the HostFilter
interface to provide a custom filter cannot be tested without boilerplate code.
Host filters that only filter on the connection address can use the public setter SetConnectAddress
. However filters that use other fields like dataCenter
cannot use the unexported setters like setDataCenter
.
An extremely ugly workaround is possible by using unsafe, however gocql should provide an API to do this:
// https://github.com/gocql/gocql/issues/1311
hostInfo := &gocql.HostInfo{}
hostInfoValue := reflect.Indirect(reflect.ValueOf(hostInfo))
reflectPtr := unsafe.Pointer(hostInfoValue.FieldByName("dataCenter").UnsafeAddr())
var strPtr *string
strPtr = (*string)(reflectPtr)
*strPtr = "us-east-1a"