(go) ssh.AuthMethod 的深度平等
(go) Deep equality for ssh.AuthMethod
我正在使用 crypto/ssh 包,我正在尝试为构造 ClientConfig 的方法编写单元测试。
单元中的断言之一是返回的 ClientConfig
与预期深度相等。
断言失败,因为 ClientConfig
的 Auth
和 HostKeyCallback
字段并不完全相等。
HostKeyCallback
被硬编码为 ssh.InsecureIgnoreHostKey()
。
我现在正在测试的唯一身份验证方法是使用密码,我已验证密码字符串是否正确。
我试图在操场上乱搞(参见 here),但我不明白为什么在这些情况下没有深度平等。
package main
import (
"fmt"
"reflect"
"golang.org/x/crypto/ssh"
)
func main() {
pass := "bar"
auth := []ssh.AuthMethod{ssh.Password(pass)}
authLiteral := []ssh.AuthMethod{ssh.Password("bar")}
if reflect.DeepEqual(authLiteral, auth) {
fmt.Println("authentication methods are equal")
} else {
fmt.Println("authentication methods are not equal")
}
callback1 := ssh.InsecureIgnoreHostKey()
callback2 := ssh.InsecureIgnoreHostKey()
if reflect.DeepEqual(callback1, callback2) {
fmt.Println("callbacks are equal")
} else {
fmt.Println("callbacks are not equal")
}
}
authentication methods are not equal
callbacks are not equal
有人可以解释一下这些结果吗?
如果您能建议我如何对这种情况进行单元测试,我也将不胜感激。
作为 Go 实现附带的 , this is formally disallowed. (Still, it might be nice if reflect.DeepEqual
,它做了一些我在下面做的事情。因为它是自带实现的,所以实现者可以用专门的知识来写。)
当然,最终,machine-level 实现了一些 指向函数的指针,其参数类型为 T1,T 2, ... Tna 返回值类型为R1, R2, ... Rnr。但是我们没有被告知什么表示是。它可能是单个 unsafe.Pointer
值,也可能是 thunk 的某种内联扩展。所以我们不知道这里要比较多少字节。
如果您愿意做出相当危险的/non-portable假设,并在证明不充分时更新它们,那么是一种“作弊”的方法这里。我在 Go Playground 上创建了 this example,它产生了所需的输出。这只是偶然,还是这真的适用于你的 Go 实现?
正文也在下方。使用风险自负!
package main
import (
"fmt"
"unsafe"
)
func dummy1() {}
func dummy2() {}
func main() {
fmt.Println("dummy1 == dummy2 =>", qe(dummy1, dummy2))
fmt.Println("dummy1 == dummy1 =>", qe(dummy1, dummy1))
}
// "questionably equal", for function pointers
func qe(a, b func()) bool {
pp1 := (*unsafe.Pointer)(unsafe.Pointer(&a))
pp2 := (*unsafe.Pointer)(unsafe.Pointer(&b))
p1 := *pp1
p2 := *pp2
return p1 == p2
}
我正在使用 crypto/ssh 包,我正在尝试为构造 ClientConfig 的方法编写单元测试。
单元中的断言之一是返回的 ClientConfig
与预期深度相等。
断言失败,因为 ClientConfig
的 Auth
和 HostKeyCallback
字段并不完全相等。
HostKeyCallback
被硬编码为 ssh.InsecureIgnoreHostKey()
。
我现在正在测试的唯一身份验证方法是使用密码,我已验证密码字符串是否正确。
我试图在操场上乱搞(参见 here),但我不明白为什么在这些情况下没有深度平等。
package main
import (
"fmt"
"reflect"
"golang.org/x/crypto/ssh"
)
func main() {
pass := "bar"
auth := []ssh.AuthMethod{ssh.Password(pass)}
authLiteral := []ssh.AuthMethod{ssh.Password("bar")}
if reflect.DeepEqual(authLiteral, auth) {
fmt.Println("authentication methods are equal")
} else {
fmt.Println("authentication methods are not equal")
}
callback1 := ssh.InsecureIgnoreHostKey()
callback2 := ssh.InsecureIgnoreHostKey()
if reflect.DeepEqual(callback1, callback2) {
fmt.Println("callbacks are equal")
} else {
fmt.Println("callbacks are not equal")
}
}
authentication methods are not equal
callbacks are not equal
有人可以解释一下这些结果吗? 如果您能建议我如何对这种情况进行单元测试,我也将不胜感激。
作为 Go 实现附带的 reflect.DeepEqual
,它做了一些我在下面做的事情。因为它是自带实现的,所以实现者可以用专门的知识来写。)
当然,最终,machine-level 实现了一些 指向函数的指针,其参数类型为 T1,T 2, ... Tna 返回值类型为R1, R2, ... Rnr。但是我们没有被告知什么表示是。它可能是单个 unsafe.Pointer
值,也可能是 thunk 的某种内联扩展。所以我们不知道这里要比较多少字节。
如果您愿意做出相当危险的/non-portable假设,并在证明不充分时更新它们,那么是一种“作弊”的方法这里。我在 Go Playground 上创建了 this example,它产生了所需的输出。这只是偶然,还是这真的适用于你的 Go 实现?
正文也在下方。使用风险自负!
package main
import (
"fmt"
"unsafe"
)
func dummy1() {}
func dummy2() {}
func main() {
fmt.Println("dummy1 == dummy2 =>", qe(dummy1, dummy2))
fmt.Println("dummy1 == dummy1 =>", qe(dummy1, dummy1))
}
// "questionably equal", for function pointers
func qe(a, b func()) bool {
pp1 := (*unsafe.Pointer)(unsafe.Pointer(&a))
pp2 := (*unsafe.Pointer)(unsafe.Pointer(&b))
p1 := *pp1
p2 := *pp2
return p1 == p2
}