class_docstr: Test class for the AliyunApp
class_docstr_tok: ["Test","class","for","the","AliyunApp"]
docstr: AliyunApp - Test last_timestamp
docstr_tok: ["AliyunApp","-","Test","last_timestamp"]
code: def test_gather_logs_last_timestamp(
      self, client_mock, sleep_mock, batcher_mock, _
  ):
      """AliyunApp - Test last_timestamp"""
      # mock 3 responses
      mock_resps = [
          {
              "NextToken": "50",
              "RequestId": "AAAAAAAA",
              "Events": [
                  {"eventTime": "2018-06-23T19:29:00Z"},
                  {"eventTime": "2018-06-23T19:28:00Z"},
              ],
              "EndTime": "2018-07-23T19:28:00Z",
              "StartTime": "2018-06-23T19:28:30Z",
          },
          {
              "NextToken": "100",
              "RequestId": "BBBBBBBBB",
              "Events": [
                  {"eventTime": "2018-06-24T19:29:00Z"},
                  {"eventTime": "2018-06-24T19:28:00Z"},
              ],
              "EndTime": "2018-07-23T19:28:00Z",
              "StartTime": "2018-06-23T19:28:30Z",
          },
          {
              "NextToken": "150",
              "RequestId": "CCCCCCCC",
              "Events": [
                  {"eventTime": "2018-06-25T19:29:00Z"},
                  {"eventTime": "2018-06-25T19:28:00Z"},
              ],
              "EndTime": "2018-07-23T19:28:00Z",
              "StartTime": "2018-06-23T19:28:30Z",
          },
      ]
      client_mock.side_effect = [
          json.dumps(r, separators=(",", ":")) for r in mock_resps
      ]
  
      # Mock remaining time. _sleep_seconds() methods will be called twice when
      # make a call to gather logs via Aliyun API. Set sleep second to a large number
      # to mimic corner case that there are still more logs to pull while lambda function
      # timeout is reached. In this case, the _last_timestamp stamp should be updated
      # correctly.
      sleep_mock.side_effect = [0, 0, 0, 0, 1000000, 0]
  
      # Mock 3 batcher call to invoke successive lambda function since there are more logs
      batcher_mock.side_effect = [True, True, True]
  
      self._app.gather()
      assert_equal(self._app._poll_count, 3)
      assert_true(self._app._more_to_poll)
      assert_equal(self._app.request.get_NextToken(), "150")
      assert_equal(self._app._last_timestamp, "2018-07-23T19:28:00Z")
  
imports: import json
  import os
  from mock import patch
  from moto import mock_ssm
  from nose.tools import assert_count_equal, assert_equal, assert_false, assert_true, raises
  from aliyunsdkcore.acs_exception.exceptions import ServerException
  from streamalert.apps._apps.aliyun import AliyunApp
  from tests.unit.streamalert.apps.test_helpers import get_event, put_mock_params
  from tests.unit.streamalert.shared.test_config import get_mock_lambda_context
label_desc: Use image node_id 11 for calling the TestAliyunApp obj's underlying member method code with example usage: obj.test_gather_logs_last_timestamp(client_mock, sleep_mock, batcher_mock, _) without return types