(t *testing.T)
| 1850 | } |
| 1851 | |
| 1852 | func (s) TestCZSubChannelConnectivityState(t *testing.T) { |
| 1853 | e := tcpClearRREnv |
| 1854 | te := newTest(t, e) |
| 1855 | te.startServer(&testServer{security: e.security}) |
| 1856 | r := manual.NewBuilderWithScheme("whatever") |
| 1857 | r.InitialState(resolver.State{Addresses: []resolver.Address{{Addr: te.srvAddr}}}) |
| 1858 | te.resolverScheme = r.Scheme() |
| 1859 | cc := te.clientConn(grpc.WithResolvers(r)) |
| 1860 | defer te.tearDown() |
| 1861 | tc := testgrpc.NewTestServiceClient(cc) |
| 1862 | // make sure the connection is up |
| 1863 | ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) |
| 1864 | defer cancel() |
| 1865 | if _, err := tc.EmptyCall(ctx, &testpb.Empty{}); err != nil { |
| 1866 | t.Fatalf("TestService/EmptyCall(_, _) = _, %v, want _, <nil>", err) |
| 1867 | } |
| 1868 | te.srv.Stop() |
| 1869 | |
| 1870 | var subConn int64 |
| 1871 | if err := verifyResultWithDelay(func() (bool, error) { |
| 1872 | // we need to obtain the SubChannel id before it gets deleted from Channel's children list (due |
| 1873 | // to effect of r.UpdateState(resolver.State{Addresses:[]resolver.Address{}})) |
| 1874 | if subConn == 0 { |
| 1875 | tcs, _ := channelz.GetTopChannels(0, 0) |
| 1876 | if len(tcs) != 1 { |
| 1877 | return false, fmt.Errorf("there should only be one top channel, not %d", len(tcs)) |
| 1878 | } |
| 1879 | subChans := tcs[0].SubChans() |
| 1880 | if len(subChans) != 1 { |
| 1881 | return false, fmt.Errorf("there should be 1 subchannel not %d", len(subChans)) |
| 1882 | } |
| 1883 | for k := range subChans { |
| 1884 | // get the SubChannel id for further trace inquiry. |
| 1885 | subConn = k |
| 1886 | t.Logf("SubChannel Id is %d", subConn) |
| 1887 | } |
| 1888 | } |
| 1889 | scm := channelz.GetSubChannel(subConn) |
| 1890 | if scm == nil { |
| 1891 | return false, fmt.Errorf("subChannel should still exist due to parent's trace reference") |
| 1892 | } |
| 1893 | trace := scm.Trace() |
| 1894 | if trace == nil { |
| 1895 | return false, fmt.Errorf("trace for SubChannel should not be empty") |
| 1896 | } |
| 1897 | if len(trace.Events) == 0 { |
| 1898 | return false, fmt.Errorf("there should be at least one trace event for subChannel not 0") |
| 1899 | } |
| 1900 | var ready, connecting, transient, shutdown int |
| 1901 | t.Log("SubChannel trace events seen so far...") |
| 1902 | for _, e := range trace.Events { |
| 1903 | t.Log(e.Desc) |
| 1904 | if strings.Contains(e.Desc, fmt.Sprintf("Subchannel Connectivity change to %v", connectivity.TransientFailure)) { |
| 1905 | transient++ |
| 1906 | } |
| 1907 | } |
| 1908 | // Make sure the SubChannel has already seen transient failure before shutting it down through |
| 1909 | // r.UpdateState(resolver.State{Addresses:[]resolver.Address{}}). |
nothing calls this directly
no test coverage detected