Example #1
0
 def test_execute_sql_future(self):
     stub = spanner_pb2_grpc.SpannerStub(self.channel)
     session = stub.CreateSession(
         spanner_pb2.CreateSessionRequest(database=_DATABASE))
     self.assertEqual(1, len(self.channel._channel_refs))
     self.assertEqual(1, self.channel._channel_refs[0]._affinity_ref)
     self.assertEqual(0, self.channel._channel_refs[0]._active_stream_ref)
     self.assertIsNotNone(session)
     rendezvous = stub.ExecuteSql.future(
         spanner_pb2.ExecuteSqlRequest(session=session.name, sql=_TEST_SQL))
     self.assertEqual(1, len(self.channel._channel_refs))
     self.assertEqual(1, self.channel._channel_refs[0]._affinity_ref)
     self.assertEqual(1, self.channel._channel_refs[0]._active_stream_ref)
     result_set = rendezvous.result()
     self.assertEqual(1, len(self.channel._channel_refs))
     self.assertEqual(1, self.channel._channel_refs[0]._affinity_ref)
     self.assertEqual(0, self.channel._channel_refs[0]._active_stream_ref)
     self.assertIsNotNone(result_set)
     self.assertEqual(1, len(result_set.rows))
     self.assertEqual(_TEST_COLUMN_DATA,
                      result_set.rows[0].values[0].string_value)
     stub.DeleteSession(spanner_pb2.DeleteSessionRequest(name=session.name))
     self.assertEqual(1, len(self.channel._channel_refs))
     self.assertEqual(0, self.channel._channel_refs[0]._affinity_ref)
     self.assertEqual(0, self.channel._channel_refs[0]._active_stream_ref)
Example #2
0
 def test_create_list_delete_session(self):
     stub = spanner_pb2_grpc.SpannerStub(self.channel)
     session = stub.CreateSession(
         spanner_pb2.CreateSessionRequest(database=_DATABASE))
     self.assertIsNotNone(session)
     self.assertEqual(1, len(self.channel._channel_refs))
     self.assertEqual(1, self.channel._channel_refs[0]._affinity_ref)
     self.assertEqual(0, self.channel._channel_refs[0]._active_stream_ref)
     sessions = stub.ListSessions(
         spanner_pb2.ListSessionsRequest(database=_DATABASE))
     self.assertIsNotNone(sessions.sessions)
     self.assertIn(session.name, (s.name for s in sessions.sessions))
     self.assertEqual(1, len(self.channel._channel_refs))
     self.assertEqual(1, self.channel._channel_refs[0]._affinity_ref)
     self.assertEqual(0, self.channel._channel_refs[0]._active_stream_ref)
     stub.DeleteSession(spanner_pb2.DeleteSessionRequest(name=session.name))
     self.assertEqual(1, len(self.channel._channel_refs))
     self.assertEqual(0, self.channel._channel_refs[0]._affinity_ref)
     self.assertEqual(0, self.channel._channel_refs[0]._active_stream_ref)
     sessions = stub.ListSessions(
         spanner_pb2.ListSessionsRequest(database=_DATABASE))
     self.assertNotIn(session.name, (s.name for s in sessions.sessions))
     self.assertEqual(1, len(self.channel._channel_refs))
     self.assertEqual(0, self.channel._channel_refs[0]._affinity_ref)
     self.assertEqual(0, self.channel._channel_refs[0]._active_stream_ref)
Example #3
0
 def test_create_session_reuse_channel(self):
     stub = spanner_pb2_grpc.SpannerStub(self.channel)
     for _ in range(_DEFAULT_MAX_CHANNELS_PER_TARGET * 2):
         session = stub.CreateSession(
             spanner_pb2.CreateSessionRequest(database=_DATABASE))
         self.assertIsNotNone(session)
         self.assertEqual(1, len(self.channel._channel_refs))
         stub.DeleteSession(
             spanner_pb2.DeleteSessionRequest(name=session.name))
Example #4
0
 def test_bound_after_unbind(self):
     stub = spanner_pb2_grpc.SpannerStub(self.channel)
     session = stub.CreateSession(
         spanner_pb2.CreateSessionRequest(database=_DATABASE))
     self.assertEqual(1, len(self.channel._channel_ref_by_affinity_key))
     stub.DeleteSession(spanner_pb2.DeleteSessionRequest(name=session.name))
     self.assertEqual(0, len(self.channel._channel_ref_by_affinity_key))
     with self.assertRaises(Exception) as context:
         stub.GetSession(spanner_pb2.GetSessionRequest(name=session.name))
     self.assertEqual(grpc.StatusCode.NOT_FOUND, context.exception.code())
Example #5
0
    def test_bound_unbind_with_invalid_affinity_key(self):
        stub = spanner_pb2_grpc.SpannerStub(self.channel)

        with self.assertRaises(Exception) as context:
            stub.GetSession(spanner_pb2.GetSessionRequest(name='random_name'))
        self.assertEqual(grpc.StatusCode.INVALID_ARGUMENT,
                         context.exception.code())

        with self.assertRaises(Exception) as context:
            stub.DeleteSession(
                spanner_pb2.DeleteSessionRequest(name='random_name'))
        self.assertEqual(grpc.StatusCode.INVALID_ARGUMENT,
                         context.exception.code())
Example #6
0
def _execute_probe(api, use_extension=False):
    """Execute a probe function given certain Cloud api and probe name.

  Args:
    api: the name of the api provider, e.g. "spanner", "firestore".
    use_extension: option to use grpc-gcp extension when creating channel.

  Raises:
    NotImplementedError: An error occurred when api does not match any records.
  """
    util = StackdriverUtil(api)

    if api == 'spanner':
        channel = _get_stub_channel(_SPANNER_TARGET, use_extension)
        stub = spanner_pb2_grpc.SpannerStub(channel)
        probe_functions = spanner_probes.PROBE_FUNCTIONS
    elif api == 'firestore':
        channel = _get_stub_channel(_FIRESTORE_TARGET)
        stub = firestore_pb2_grpc.FirestoreStub(channel)
        probe_functions = firestore_probes.PROBE_FUNCTIONS
    else:
        raise NotImplementedError('gRPC prober is not implemented for %s !' %
                                  api)

    total = len(probe_functions)
    success = 0
    metrics = {}

    # Execute all probes for given api
    for probe_name in probe_functions:
        probe_function = probe_functions[probe_name]
        try:
            probe_function(stub, metrics)
            success += 1
        except Exception:  # pylint: disable=broad-except
            # report any kind of exception to Stackdriver
            util.report_error(traceback.format_exc())

    if success == total:
        util.set_success(True)

    # Summarize metrics
    util.add_metrics_dict(metrics)
    util.output_metrics()

    # Fail this probe if any function fails
    if success != total:
        sys.exit(1)
Example #7
0
    def test_channel_connectivity_invalid_target(self):
        config = config = grpc_gcp.api_config_from_text_pb(
            pkg_resources.resource_string(__name__, 'spanner.grpc.config'))
        http_request = Request()
        credentials, _ = google.auth.default([_OAUTH_SCOPE], http_request)
        invalid_channel = self._create_secure_gcp_channel(
            credentials,
            http_request,
            'localhost:1234',
            options=[(grpc_gcp.API_CONFIG_CHANNEL_ARG, config)])

        callback = _Callback()
        invalid_channel.subscribe(callback.update_first, try_to_connect=False)

        stub = spanner_pb2_grpc.SpannerStub(invalid_channel)
        with self.assertRaises(Exception) as context:
            stub.CreateSession(
                spanner_pb2.CreateSessionRequest(database=_DATABASE))
        self.assertEqual(grpc.StatusCode.UNAVAILABLE, context.exception.code())
        first_connectivities = callback.block_until_connectivities_satisfy(
            lambda connectivities: len(connectivities) >= 3)
        self.assertEqual(grpc.ChannelConnectivity.IDLE,
                         first_connectivities[0])
        self.assertIn(grpc.ChannelConnectivity.CONNECTING,
                      first_connectivities)
        self.assertIn(grpc.ChannelConnectivity.TRANSIENT_FAILURE,
                      first_connectivities)

        invalid_channel.subscribe(callback.update_second, try_to_connect=True)
        second_connectivities = callback.block_until_connectivities_satisfy(
            lambda connectivities: len(connectivities) >= 3, False)
        self.assertNotIn(grpc.ChannelConnectivity.IDLE, second_connectivities)
        self.assertIn(grpc.ChannelConnectivity.CONNECTING,
                      second_connectivities)
        self.assertIn(grpc.ChannelConnectivity.TRANSIENT_FAILURE,
                      second_connectivities)

        self.assertEqual(2, len(invalid_channel._subscribers))
        invalid_channel.unsubscribe(callback.update_first)
        invalid_channel.unsubscribe(callback.update_second)
        self.assertEqual(0, len(invalid_channel._subscribers))
Example #8
0
 def test_create_session_new_channel(self):
     stub = spanner_pb2_grpc.SpannerStub(self.channel)
     futures = []
     for i in range(_DEFAULT_MAX_CHANNELS_PER_TARGET):
         futures.append(
             stub.CreateSession.future(
                 spanner_pb2.CreateSessionRequest(database=_DATABASE)))
         self.assertEqual(i + 1, len(self.channel._channel_refs))
     for future in futures:
         stub.DeleteSession(
             spanner_pb2.DeleteSessionRequest(name=future.result().name))
     futures = []
     for i in range(_DEFAULT_MAX_CHANNELS_PER_TARGET):
         futures.append(
             stub.CreateSession.future(
                 spanner_pb2.CreateSessionRequest(database=_DATABASE)))
         self.assertEqual(_DEFAULT_MAX_CHANNELS_PER_TARGET,
                          len(self.channel._channel_refs))
     for future in futures:
         stub.DeleteSession(
             spanner_pb2.DeleteSessionRequest(name=future.result().name))
Example #9
0
    def test_channel_connectivity_multiple_subchannels(self):
        callback = _Callback()

        self.channel.subscribe(callback.update_first, try_to_connect=False)
        stub = spanner_pb2_grpc.SpannerStub(self.channel)
        futures = []
        for _ in range(2):
            futures.append(
                stub.CreateSession.future(
                    spanner_pb2.CreateSessionRequest(database=_DATABASE)))
        connectivities = callback.block_until_connectivities_satisfy(
            lambda connectivities: grpc.ChannelConnectivity.READY in
            connectivities)

        self.assertEqual(2, len(self.channel._channel_refs))
        self.assertSequenceEqual((grpc.ChannelConnectivity.IDLE,
                                  grpc.ChannelConnectivity.CONNECTING,
                                  grpc.ChannelConnectivity.READY),
                                 connectivities)
        for future in futures:
            stub.DeleteSession(
                spanner_pb2.DeleteSessionRequest(name=future.result().name))
Example #10
0
    def test_channel_connectivity(self):
        callback = _Callback()

        self.channel.subscribe(callback.update_first, try_to_connect=False)
        stub = spanner_pb2_grpc.SpannerStub(self.channel)
        session = stub.CreateSession(
            spanner_pb2.CreateSessionRequest(database=_DATABASE))
        connectivities = callback.block_until_connectivities_satisfy(
            lambda connectivities: grpc.ChannelConnectivity.READY in
            connectivities)
        self.assertEqual(3, len(connectivities))
        self.assertSequenceEqual((grpc.ChannelConnectivity.IDLE,
                                  grpc.ChannelConnectivity.CONNECTING,
                                  grpc.ChannelConnectivity.READY),
                                 connectivities)
        stub.DeleteSession(spanner_pb2.DeleteSessionRequest(name=session.name))

        self.channel.unsubscribe(callback.update_first)
        session = stub.CreateSession(
            spanner_pb2.CreateSessionRequest(database=_DATABASE))
        self.assertEqual(3, len(connectivities))
        stub.DeleteSession(spanner_pb2.DeleteSessionRequest(name=session.name))
def _create_stub(channel):
    stub = spanner_pb2_grpc.SpannerStub(channel)
    return stub
Example #12
0
    def test_concurrent_streams_watermark(self):
        stub = spanner_pb2_grpc.SpannerStub(self.channel)
        watermark = 2
        self.channel._max_concurrent_streams_low_watermark = watermark
        self.assertEqual(self.channel._max_concurrent_streams_low_watermark,
                         watermark)

        session_list = []
        rendezvous_list = []

        # When active streams have not reached the concurrent_streams_watermark,
        # gRPC calls should be reusing the same channel.
        for i in range(watermark):
            session = stub.CreateSession(
                spanner_pb2.CreateSessionRequest(database=_DATABASE))
            self.assertEqual(1, len(self.channel._channel_refs))
            self.assertEqual(i + 1,
                             self.channel._channel_refs[0]._affinity_ref)
            self.assertEqual(i,
                             self.channel._channel_refs[0]._active_stream_ref)
            self.assertIsNotNone(session)
            session_list.append(session)

            rendezvous = stub.ExecuteStreamingSql(
                spanner_pb2.ExecuteSqlRequest(session=session.name,
                                              sql=_TEST_SQL))
            self.assertEqual(1, len(self.channel._channel_refs))
            self.assertEqual(i + 1,
                             self.channel._channel_refs[0]._affinity_ref)
            self.assertEqual(i + 1,
                             self.channel._channel_refs[0]._active_stream_ref)
            rendezvous_list.append(rendezvous)

        # When active streams reach the concurrent_streams_watermark,
        # channel pool will create a new channel.
        another_session = stub.CreateSession(
            spanner_pb2.CreateSessionRequest(database=_DATABASE))
        self.assertEqual(2, len(self.channel._channel_refs))
        self.assertEqual(2, self.channel._channel_refs[0]._affinity_ref)
        self.assertEqual(2, self.channel._channel_refs[0]._active_stream_ref)
        self.assertEqual(1, self.channel._channel_refs[1]._affinity_ref)
        self.assertEqual(0, self.channel._channel_refs[1]._active_stream_ref)
        self.assertIsNotNone(another_session)
        session_list.append(another_session)

        another_rendezvous = stub.ExecuteStreamingSql(
            spanner_pb2.ExecuteSqlRequest(session=another_session.name,
                                          sql=_TEST_SQL))
        self.assertEqual(2, len(self.channel._channel_refs))
        self.assertEqual(2, self.channel._channel_refs[0]._affinity_ref)
        self.assertEqual(2, self.channel._channel_refs[0]._active_stream_ref)
        self.assertEqual(1, self.channel._channel_refs[1]._affinity_ref)
        self.assertEqual(1, self.channel._channel_refs[1]._active_stream_ref)
        rendezvous_list.append(another_rendezvous)

        # Iterate through the rendezous list to clean active streams.
        for rendezvous in rendezvous_list:
            for _ in rendezvous:
                continue

        # After cleaning, previously created channels will remain in the pool.
        self.assertEqual(2, len(self.channel._channel_refs))
        self.assertEqual(2, self.channel._channel_refs[0]._affinity_ref)
        self.assertEqual(0, self.channel._channel_refs[0]._active_stream_ref)
        self.assertEqual(1, self.channel._channel_refs[1]._affinity_ref)
        self.assertEqual(0, self.channel._channel_refs[1]._active_stream_ref)

        # Delete all sessions to clean affinity.
        for session in session_list:
            stub.DeleteSession(
                spanner_pb2.DeleteSessionRequest(name=session.name))

        self.assertEqual(2, len(self.channel._channel_refs))
        self.assertEqual(0, self.channel._channel_refs[0]._affinity_ref)
        self.assertEqual(0, self.channel._channel_refs[0]._active_stream_ref)
        self.assertEqual(0, self.channel._channel_refs[1]._affinity_ref)
        self.assertEqual(0, self.channel._channel_refs[1]._active_stream_ref)