xds_server_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. /*
  2. *
  3. * Copyright 2020 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package xds
  19. import (
  20. "context"
  21. "crypto/tls"
  22. "crypto/x509"
  23. "errors"
  24. "fmt"
  25. "net"
  26. "os"
  27. "strings"
  28. "testing"
  29. "time"
  30. "google.golang.org/grpc/credentials"
  31. "google.golang.org/grpc/credentials/tls/certprovider"
  32. xdsinternal "google.golang.org/grpc/internal/credentials/xds"
  33. "google.golang.org/grpc/testdata"
  34. )
  35. func makeClientTLSConfig(t *testing.T, mTLS bool) *tls.Config {
  36. t.Helper()
  37. pemData, err := os.ReadFile(testdata.Path("x509/server_ca_cert.pem"))
  38. if err != nil {
  39. t.Fatal(err)
  40. }
  41. roots := x509.NewCertPool()
  42. roots.AppendCertsFromPEM(pemData)
  43. var certs []tls.Certificate
  44. if mTLS {
  45. cert, err := tls.LoadX509KeyPair(testdata.Path("x509/client1_cert.pem"), testdata.Path("x509/client1_key.pem"))
  46. if err != nil {
  47. t.Fatal(err)
  48. }
  49. certs = append(certs, cert)
  50. }
  51. return &tls.Config{
  52. Certificates: certs,
  53. RootCAs: roots,
  54. ServerName: "*.test.example.com",
  55. // Setting this to true completely turns off the certificate validation
  56. // on the client side. So, the client side handshake always seems to
  57. // succeed. But if we want to turn this ON, we will need to generate
  58. // certificates which work with localhost, or supply a custom
  59. // verification function. So, the server credentials tests will rely
  60. // solely on the success/failure of the server-side handshake.
  61. InsecureSkipVerify: true,
  62. }
  63. }
  64. // Helper function to create a real TLS server credentials which is used as
  65. // fallback credentials from multiple tests.
  66. func makeFallbackServerCreds(t *testing.T) credentials.TransportCredentials {
  67. t.Helper()
  68. creds, err := credentials.NewServerTLSFromFile(testdata.Path("x509/server1_cert.pem"), testdata.Path("x509/server1_key.pem"))
  69. if err != nil {
  70. t.Fatal(err)
  71. }
  72. return creds
  73. }
  74. type errorCreds struct {
  75. credentials.TransportCredentials
  76. }
  77. // TestServerCredsWithoutFallback verifies that the call to
  78. // NewServerCredentials() fails when no fallback is specified.
  79. func (s) TestServerCredsWithoutFallback(t *testing.T) {
  80. if _, err := NewServerCredentials(ServerOptions{}); err == nil {
  81. t.Fatal("NewServerCredentials() succeeded without specifying fallback")
  82. }
  83. }
  84. type wrapperConn struct {
  85. net.Conn
  86. xdsHI *xdsinternal.HandshakeInfo
  87. deadline time.Time
  88. handshakeInfoErr error
  89. }
  90. func (wc *wrapperConn) XDSHandshakeInfo() (*xdsinternal.HandshakeInfo, error) {
  91. return wc.xdsHI, wc.handshakeInfoErr
  92. }
  93. func (wc *wrapperConn) GetDeadline() time.Time {
  94. return wc.deadline
  95. }
  96. func newWrappedConn(conn net.Conn, xdsHI *xdsinternal.HandshakeInfo, deadline time.Time) *wrapperConn {
  97. return &wrapperConn{Conn: conn, xdsHI: xdsHI, deadline: deadline}
  98. }
  99. // TestServerCredsInvalidHandshakeInfo verifies scenarios where the passed in
  100. // HandshakeInfo is invalid because it does not contain the expected certificate
  101. // providers.
  102. func (s) TestServerCredsInvalidHandshakeInfo(t *testing.T) {
  103. opts := ServerOptions{FallbackCreds: &errorCreds{}}
  104. creds, err := NewServerCredentials(opts)
  105. if err != nil {
  106. t.Fatalf("NewServerCredentials(%v) failed: %v", opts, err)
  107. }
  108. info := xdsinternal.NewHandshakeInfo(&fakeProvider{}, nil)
  109. conn := newWrappedConn(nil, info, time.Time{})
  110. if _, _, err := creds.ServerHandshake(conn); err == nil {
  111. t.Fatal("ServerHandshake succeeded without identity certificate provider in HandshakeInfo")
  112. }
  113. }
  114. // TestServerCredsProviderFailure verifies the cases where an expected
  115. // certificate provider is missing in the HandshakeInfo value in the context.
  116. func (s) TestServerCredsProviderFailure(t *testing.T) {
  117. opts := ServerOptions{FallbackCreds: &errorCreds{}}
  118. creds, err := NewServerCredentials(opts)
  119. if err != nil {
  120. t.Fatalf("NewServerCredentials(%v) failed: %v", opts, err)
  121. }
  122. tests := []struct {
  123. desc string
  124. rootProvider certprovider.Provider
  125. identityProvider certprovider.Provider
  126. wantErr string
  127. }{
  128. {
  129. desc: "erroring identity provider",
  130. identityProvider: &fakeProvider{err: errors.New("identity provider error")},
  131. wantErr: "identity provider error",
  132. },
  133. {
  134. desc: "erroring root provider",
  135. identityProvider: &fakeProvider{km: &certprovider.KeyMaterial{}},
  136. rootProvider: &fakeProvider{err: errors.New("root provider error")},
  137. wantErr: "root provider error",
  138. },
  139. }
  140. for _, test := range tests {
  141. t.Run(test.desc, func(t *testing.T) {
  142. info := xdsinternal.NewHandshakeInfo(test.rootProvider, test.identityProvider)
  143. conn := newWrappedConn(nil, info, time.Time{})
  144. if _, _, err := creds.ServerHandshake(conn); err == nil || !strings.Contains(err.Error(), test.wantErr) {
  145. t.Fatalf("ServerHandshake() returned error: %q, wantErr: %q", err, test.wantErr)
  146. }
  147. })
  148. }
  149. }
  150. // TestServerCredsHandshake_XDSHandshakeInfoError verifies the case where the
  151. // call to XDSHandshakeInfo() from the ServerHandshake() method returns an
  152. // error, and the test verifies that the ServerHandshake() fails with the
  153. // expected error.
  154. func (s) TestServerCredsHandshake_XDSHandshakeInfoError(t *testing.T) {
  155. opts := ServerOptions{FallbackCreds: &errorCreds{}}
  156. creds, err := NewServerCredentials(opts)
  157. if err != nil {
  158. t.Fatalf("NewServerCredentials(%v) failed: %v", opts, err)
  159. }
  160. // Create a test server which uses the xDS server credentials created above
  161. // to perform TLS handshake on incoming connections.
  162. ts := newTestServerWithHandshakeFunc(func(rawConn net.Conn) handshakeResult {
  163. // Create a wrapped conn which returns a nil HandshakeInfo and a non-nil error.
  164. conn := newWrappedConn(rawConn, nil, time.Now().Add(defaultTestTimeout))
  165. hiErr := errors.New("xdsHandshakeInfo error")
  166. conn.handshakeInfoErr = hiErr
  167. // Invoke the ServerHandshake() method on the xDS credentials and verify
  168. // that the error returned by the XDSHandshakeInfo() method on the
  169. // wrapped conn is returned here.
  170. _, _, err := creds.ServerHandshake(conn)
  171. if !errors.Is(err, hiErr) {
  172. return handshakeResult{err: fmt.Errorf("ServerHandshake() returned err: %v, wantErr: %v", err, hiErr)}
  173. }
  174. return handshakeResult{}
  175. })
  176. defer ts.stop()
  177. // Dial the test server, but don't trigger the TLS handshake. This will
  178. // cause ServerHandshake() to fail.
  179. rawConn, err := net.Dial("tcp", ts.address)
  180. if err != nil {
  181. t.Fatalf("net.Dial(%s) failed: %v", ts.address, err)
  182. }
  183. defer rawConn.Close()
  184. // Read handshake result from the testServer which will return an error if
  185. // the handshake succeeded.
  186. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  187. defer cancel()
  188. val, err := ts.hsResult.Receive(ctx)
  189. if err != nil {
  190. t.Fatalf("testServer failed to return handshake result: %v", err)
  191. }
  192. hsr := val.(handshakeResult)
  193. if hsr.err != nil {
  194. t.Fatalf("testServer handshake failure: %v", hsr.err)
  195. }
  196. }
  197. // TestServerCredsHandshakeTimeout verifies the case where the client does not
  198. // send required handshake data before the deadline set on the net.Conn passed
  199. // to ServerHandshake().
  200. func (s) TestServerCredsHandshakeTimeout(t *testing.T) {
  201. opts := ServerOptions{FallbackCreds: &errorCreds{}}
  202. creds, err := NewServerCredentials(opts)
  203. if err != nil {
  204. t.Fatalf("NewServerCredentials(%v) failed: %v", opts, err)
  205. }
  206. // Create a test server which uses the xDS server credentials created above
  207. // to perform TLS handshake on incoming connections.
  208. ts := newTestServerWithHandshakeFunc(func(rawConn net.Conn) handshakeResult {
  209. hi := xdsinternal.NewHandshakeInfo(makeRootProvider(t, "x509/client_ca_cert.pem"), makeIdentityProvider(t, "x509/server2_cert.pem", "x509/server2_key.pem"))
  210. hi.SetRequireClientCert(true)
  211. // Create a wrapped conn which can return the HandshakeInfo created
  212. // above with a very small deadline.
  213. d := time.Now().Add(defaultTestShortTimeout)
  214. rawConn.SetDeadline(d)
  215. conn := newWrappedConn(rawConn, hi, d)
  216. // ServerHandshake() on the xDS credentials is expected to fail.
  217. if _, _, err := creds.ServerHandshake(conn); err == nil {
  218. return handshakeResult{err: errors.New("ServerHandshake() succeeded when expected to timeout")}
  219. }
  220. return handshakeResult{}
  221. })
  222. defer ts.stop()
  223. // Dial the test server, but don't trigger the TLS handshake. This will
  224. // cause ServerHandshake() to fail.
  225. rawConn, err := net.Dial("tcp", ts.address)
  226. if err != nil {
  227. t.Fatalf("net.Dial(%s) failed: %v", ts.address, err)
  228. }
  229. defer rawConn.Close()
  230. // Read handshake result from the testServer and expect a failure result.
  231. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  232. defer cancel()
  233. val, err := ts.hsResult.Receive(ctx)
  234. if err != nil {
  235. t.Fatalf("testServer failed to return handshake result: %v", err)
  236. }
  237. hsr := val.(handshakeResult)
  238. if hsr.err != nil {
  239. t.Fatalf("testServer handshake failure: %v", hsr.err)
  240. }
  241. }
  242. // TestServerCredsHandshakeFailure verifies the case where the server-side
  243. // credentials uses a root certificate which does not match the certificate
  244. // presented by the client, and hence the handshake must fail.
  245. func (s) TestServerCredsHandshakeFailure(t *testing.T) {
  246. opts := ServerOptions{FallbackCreds: &errorCreds{}}
  247. creds, err := NewServerCredentials(opts)
  248. if err != nil {
  249. t.Fatalf("NewServerCredentials(%v) failed: %v", opts, err)
  250. }
  251. // Create a test server which uses the xDS server credentials created above
  252. // to perform TLS handshake on incoming connections.
  253. ts := newTestServerWithHandshakeFunc(func(rawConn net.Conn) handshakeResult {
  254. // Create a HandshakeInfo which has a root provider which does not match
  255. // the certificate sent by the client.
  256. hi := xdsinternal.NewHandshakeInfo(makeRootProvider(t, "x509/server_ca_cert.pem"), makeIdentityProvider(t, "x509/client2_cert.pem", "x509/client2_key.pem"))
  257. hi.SetRequireClientCert(true)
  258. // Create a wrapped conn which can return the HandshakeInfo and
  259. // configured deadline to the xDS credentials' ServerHandshake()
  260. // method.
  261. conn := newWrappedConn(rawConn, hi, time.Now().Add(defaultTestTimeout))
  262. // ServerHandshake() on the xDS credentials is expected to fail.
  263. if _, _, err := creds.ServerHandshake(conn); err == nil {
  264. return handshakeResult{err: errors.New("ServerHandshake() succeeded when expected to fail")}
  265. }
  266. return handshakeResult{}
  267. })
  268. defer ts.stop()
  269. // Dial the test server, and trigger the TLS handshake.
  270. rawConn, err := net.Dial("tcp", ts.address)
  271. if err != nil {
  272. t.Fatalf("net.Dial(%s) failed: %v", ts.address, err)
  273. }
  274. defer rawConn.Close()
  275. tlsConn := tls.Client(rawConn, makeClientTLSConfig(t, true))
  276. tlsConn.SetDeadline(time.Now().Add(defaultTestTimeout))
  277. if err := tlsConn.Handshake(); err != nil {
  278. t.Fatal(err)
  279. }
  280. // Read handshake result from the testServer which will return an error if
  281. // the handshake succeeded.
  282. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  283. defer cancel()
  284. val, err := ts.hsResult.Receive(ctx)
  285. if err != nil {
  286. t.Fatalf("testServer failed to return handshake result: %v", err)
  287. }
  288. hsr := val.(handshakeResult)
  289. if hsr.err != nil {
  290. t.Fatalf("testServer handshake failure: %v", hsr.err)
  291. }
  292. }
  293. // TestServerCredsHandshakeSuccess verifies success handshake cases.
  294. func (s) TestServerCredsHandshakeSuccess(t *testing.T) {
  295. tests := []struct {
  296. desc string
  297. fallbackCreds credentials.TransportCredentials
  298. rootProvider certprovider.Provider
  299. identityProvider certprovider.Provider
  300. requireClientCert bool
  301. }{
  302. {
  303. desc: "fallback",
  304. fallbackCreds: makeFallbackServerCreds(t),
  305. },
  306. {
  307. desc: "TLS",
  308. fallbackCreds: &errorCreds{},
  309. identityProvider: makeIdentityProvider(t, "x509/server2_cert.pem", "x509/server2_key.pem"),
  310. },
  311. {
  312. desc: "mTLS",
  313. fallbackCreds: &errorCreds{},
  314. identityProvider: makeIdentityProvider(t, "x509/server2_cert.pem", "x509/server2_key.pem"),
  315. rootProvider: makeRootProvider(t, "x509/client_ca_cert.pem"),
  316. requireClientCert: true,
  317. },
  318. }
  319. for _, test := range tests {
  320. t.Run(test.desc, func(t *testing.T) {
  321. // Create an xDS server credentials.
  322. opts := ServerOptions{FallbackCreds: test.fallbackCreds}
  323. creds, err := NewServerCredentials(opts)
  324. if err != nil {
  325. t.Fatalf("NewServerCredentials(%v) failed: %v", opts, err)
  326. }
  327. // Create a test server which uses the xDS server credentials
  328. // created above to perform TLS handshake on incoming connections.
  329. ts := newTestServerWithHandshakeFunc(func(rawConn net.Conn) handshakeResult {
  330. // Create a HandshakeInfo with information from the test table.
  331. hi := xdsinternal.NewHandshakeInfo(test.rootProvider, test.identityProvider)
  332. hi.SetRequireClientCert(test.requireClientCert)
  333. // Create a wrapped conn which can return the HandshakeInfo and
  334. // configured deadline to the xDS credentials' ServerHandshake()
  335. // method.
  336. conn := newWrappedConn(rawConn, hi, time.Now().Add(defaultTestTimeout))
  337. // Invoke the ServerHandshake() method on the xDS credentials
  338. // and make some sanity checks before pushing the result for
  339. // inspection by the main test body.
  340. _, ai, err := creds.ServerHandshake(conn)
  341. if err != nil {
  342. return handshakeResult{err: fmt.Errorf("ServerHandshake() failed: %v", err)}
  343. }
  344. if ai.AuthType() != "tls" {
  345. return handshakeResult{err: fmt.Errorf("ServerHandshake returned authType %q, want %q", ai.AuthType(), "tls")}
  346. }
  347. info, ok := ai.(credentials.TLSInfo)
  348. if !ok {
  349. return handshakeResult{err: fmt.Errorf("ServerHandshake returned authInfo of type %T, want %T", ai, credentials.TLSInfo{})}
  350. }
  351. return handshakeResult{connState: info.State}
  352. })
  353. defer ts.stop()
  354. // Dial the test server, and trigger the TLS handshake.
  355. rawConn, err := net.Dial("tcp", ts.address)
  356. if err != nil {
  357. t.Fatalf("net.Dial(%s) failed: %v", ts.address, err)
  358. }
  359. defer rawConn.Close()
  360. tlsConn := tls.Client(rawConn, makeClientTLSConfig(t, test.requireClientCert))
  361. tlsConn.SetDeadline(time.Now().Add(defaultTestTimeout))
  362. if err := tlsConn.Handshake(); err != nil {
  363. t.Fatal(err)
  364. }
  365. // Read the handshake result from the testServer which contains the
  366. // TLS connection state on the server-side and compare it with the
  367. // one received on the client-side.
  368. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  369. defer cancel()
  370. val, err := ts.hsResult.Receive(ctx)
  371. if err != nil {
  372. t.Fatalf("testServer failed to return handshake result: %v", err)
  373. }
  374. hsr := val.(handshakeResult)
  375. if hsr.err != nil {
  376. t.Fatalf("testServer handshake failure: %v", hsr.err)
  377. }
  378. // AuthInfo contains a variety of information. We only verify a
  379. // subset here. This is the same subset which is verified in TLS
  380. // credentials tests.
  381. if err := compareConnState(tlsConn.ConnectionState(), hsr.connState); err != nil {
  382. t.Fatal(err)
  383. }
  384. })
  385. }
  386. }
  387. func (s) TestServerCredsProviderSwitch(t *testing.T) {
  388. opts := ServerOptions{FallbackCreds: &errorCreds{}}
  389. creds, err := NewServerCredentials(opts)
  390. if err != nil {
  391. t.Fatalf("NewServerCredentials(%v) failed: %v", opts, err)
  392. }
  393. // The first time the handshake function is invoked, it returns a
  394. // HandshakeInfo which is expected to fail. Further invocations return a
  395. // HandshakeInfo which is expected to succeed.
  396. cnt := 0
  397. // Create a test server which uses the xDS server credentials created above
  398. // to perform TLS handshake on incoming connections.
  399. ts := newTestServerWithHandshakeFunc(func(rawConn net.Conn) handshakeResult {
  400. cnt++
  401. var hi *xdsinternal.HandshakeInfo
  402. if cnt == 1 {
  403. // Create a HandshakeInfo which has a root provider which does not match
  404. // the certificate sent by the client.
  405. hi = xdsinternal.NewHandshakeInfo(makeRootProvider(t, "x509/server_ca_cert.pem"), makeIdentityProvider(t, "x509/client2_cert.pem", "x509/client2_key.pem"))
  406. hi.SetRequireClientCert(true)
  407. // Create a wrapped conn which can return the HandshakeInfo and
  408. // configured deadline to the xDS credentials' ServerHandshake()
  409. // method.
  410. conn := newWrappedConn(rawConn, hi, time.Now().Add(defaultTestTimeout))
  411. // ServerHandshake() on the xDS credentials is expected to fail.
  412. if _, _, err := creds.ServerHandshake(conn); err == nil {
  413. return handshakeResult{err: errors.New("ServerHandshake() succeeded when expected to fail")}
  414. }
  415. return handshakeResult{}
  416. }
  417. hi = xdsinternal.NewHandshakeInfo(makeRootProvider(t, "x509/client_ca_cert.pem"), makeIdentityProvider(t, "x509/server1_cert.pem", "x509/server1_key.pem"))
  418. hi.SetRequireClientCert(true)
  419. // Create a wrapped conn which can return the HandshakeInfo and
  420. // configured deadline to the xDS credentials' ServerHandshake()
  421. // method.
  422. conn := newWrappedConn(rawConn, hi, time.Now().Add(defaultTestTimeout))
  423. // Invoke the ServerHandshake() method on the xDS credentials
  424. // and make some sanity checks before pushing the result for
  425. // inspection by the main test body.
  426. _, ai, err := creds.ServerHandshake(conn)
  427. if err != nil {
  428. return handshakeResult{err: fmt.Errorf("ServerHandshake() failed: %v", err)}
  429. }
  430. if ai.AuthType() != "tls" {
  431. return handshakeResult{err: fmt.Errorf("ServerHandshake returned authType %q, want %q", ai.AuthType(), "tls")}
  432. }
  433. info, ok := ai.(credentials.TLSInfo)
  434. if !ok {
  435. return handshakeResult{err: fmt.Errorf("ServerHandshake returned authInfo of type %T, want %T", ai, credentials.TLSInfo{})}
  436. }
  437. return handshakeResult{connState: info.State}
  438. })
  439. defer ts.stop()
  440. for i := 0; i < 5; i++ {
  441. // Dial the test server, and trigger the TLS handshake.
  442. rawConn, err := net.Dial("tcp", ts.address)
  443. if err != nil {
  444. t.Fatalf("net.Dial(%s) failed: %v", ts.address, err)
  445. }
  446. defer rawConn.Close()
  447. tlsConn := tls.Client(rawConn, makeClientTLSConfig(t, true))
  448. tlsConn.SetDeadline(time.Now().Add(defaultTestTimeout))
  449. if err := tlsConn.Handshake(); err != nil {
  450. t.Fatal(err)
  451. }
  452. // Read the handshake result from the testServer which contains the
  453. // TLS connection state on the server-side and compare it with the
  454. // one received on the client-side.
  455. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  456. defer cancel()
  457. val, err := ts.hsResult.Receive(ctx)
  458. if err != nil {
  459. t.Fatalf("testServer failed to return handshake result: %v", err)
  460. }
  461. hsr := val.(handshakeResult)
  462. if hsr.err != nil {
  463. t.Fatalf("testServer handshake failure: %v", hsr.err)
  464. }
  465. if i == 0 {
  466. // We expect the first handshake to fail. So, we skip checks which
  467. // compare connection state.
  468. continue
  469. }
  470. // AuthInfo contains a variety of information. We only verify a
  471. // subset here. This is the same subset which is verified in TLS
  472. // credentials tests.
  473. if err := compareConnState(tlsConn.ConnectionState(), hsr.connState); err != nil {
  474. t.Fatal(err)
  475. }
  476. }
  477. }
  478. // TestServerClone verifies the Clone() method on client credentials.
  479. func (s) TestServerClone(t *testing.T) {
  480. opts := ServerOptions{FallbackCreds: makeFallbackServerCreds(t)}
  481. orig, err := NewServerCredentials(opts)
  482. if err != nil {
  483. t.Fatalf("NewServerCredentials(%v) failed: %v", opts, err)
  484. }
  485. // The credsImpl does not have any exported fields, and it does not make
  486. // sense to use any cmp options to look deep into. So, all we make sure here
  487. // is that the cloned object points to a different location in memory.
  488. if clone := orig.Clone(); clone == orig {
  489. t.Fatal("return value from Clone() doesn't point to new credentials instance")
  490. }
  491. }