text: import mock
  import unittest2
  import urllib
  import urllib2
  
  from mlabns.util import constants
  from mlabns.util import message
  from mlabns.util import prometheus_status
  
  
  class ParseSliverToolStatusTest(unittest2.TestCase):
  
      def test_parse_sliver_tool_status_returns_successfully_parsed_tuple(self):
          status = {
              "metric": {
                  "experiment": "ndt.iupui",
                  "machine": "mlab1-abc01.mlab-oti.measurement-lab.org"
              },
              "value": [1522782427.81, "1"]
          }
          expected_parsed_status = (
              'ndt-iupui-mlab1-abc01.mlab-oti.measurement-lab.org', '1',
              constants.PROMETHEUS_TOOL_EXTRA)
          actual_parsed_status = prometheus_status.parse_sliver_tool_status(
              status)
  
          self.assertTupleEqual(expected_parsed_status, actual_parsed_status)
  
      def test_parse_sliver_tool_status_raises_PrometheusStatusUnparseableError_because_of_illformatted_status(
              self):
          status = 'mock status'
  
          with self.assertRaises(
                  prometheus_status.PrometheusStatusUnparseableError):
              prometheus_status.parse_sliver_tool_status(status)
  
  
  class GetSliceInfoTest(unittest2.TestCase):
  
      def setUp(self):
          self.prometheus_base_url = 'https://prom.mock.mlab.net/api/?query='
  
      def test_get_slice_info_returns_none_with_nonexistent_tool(self):
          retrieved = prometheus_status.get_slice_info(self.prometheus_base_url,
                                                       'nonexistent_tool', '')
          self.assertIsNone(retrieved)
  
      def test_get_slice_info_returns_valid_objects_when_tools_stored(self):
          ndt_url_ipv4 = self.prometheus_base_url + urllib.quote_plus(
              prometheus_status.QUERIES['ndt'])
          ndt_url_ipv6 = self.prometheus_base_url + urllib.quote_plus(
              prometheus_status.QUERIES['ndt_ipv6'])
          neubot_url_ipv4 = self.prometheus_base_url + urllib.quote_plus(
              prometheus_status.QUERIES['neubot'])
          neubot_url_ipv6 = self.prometheus_base_url + urllib.quote_plus(
              prometheus_status.QUERIES['neubot_ipv6'])
          expected_slice_data = {
              'ndt': {
                  'info':
                  prometheus_status.PrometheusSliceInfo(ndt_url_ipv4, 'ndt', ''),
                  'info_ipv6': prometheus_status.PrometheusSliceInfo(
                      ndt_url_ipv6, 'ndt', '_ipv6'),
              },
              'neubot': {
                  'info': prometheus_status.PrometheusSliceInfo(neubot_url_ipv4,
                                                                'neubot', ''),
                  'info_ipv6': prometheus_status.PrometheusSliceInfo(
                      neubot_url_ipv6, 'neubot', '_ipv6'),
              }
          }
  
          retrieved = prometheus_status.get_slice_info(self.prometheus_base_url,
                                                       'ndt', '')
          self.assertEqual(expected_slice_data['ndt']['info'], retrieved)
  
          retrieved = prometheus_status.get_slice_info(self.prometheus_base_url,
                                                       'ndt', '_ipv6')
          self.assertEqual(expected_slice_data['ndt']['info_ipv6'], retrieved)
  
          retrieved = prometheus_status.get_slice_info(self.prometheus_base_url,
                                                       'neubot', '')
          self.assertEqual(expected_slice_data['neubot']['info'], retrieved)
  
          retrieved = prometheus_status.get_slice_info(self.prometheus_base_url,
                                                       'neubot', '_ipv6')
          self.assertEqual(expected_slice_data['neubot']['info_ipv6'], retrieved)
  
  
  class StatusUpdateHandlerTest(unittest2.TestCase):
  
      def setUp(self):
          self.mock_response = mock.Mock()
          self.mock_response.msg = 'mock message'
          self.mock_response.code = '200'
  
      @mock.patch.object(urllib2.OpenerDirector, 'open', autospec=True)
      def test_get_slice_status_returns_none_with_invalid_json(self, mock_open):
          self.mock_response.read.return_value = '{lol, not valid json'
          mock_open.return_value = self.mock_response
          result = prometheus_status.get_slice_status(
              'https://prometheus.measurementlab.mock.net',
              urllib2.OpenerDirector())
          self.assertIsNone(result)
  
      @mock.patch.object(urllib2.OpenerDirector, 'open', autospec=True)
      @mock.patch.object(prometheus_status, 'parse_sliver_tool_status')
      def test_get_slice_status_returns_populated_dictionary_when_it_gets_valid_statuses(
              self, mock_parse_sliver_tool_status, mock_open):
          self.mock_response.read.return_value = """
          {
              "status": "success",
              "data": {
                  "resultType": "vector",
                  "result": [
                      { "metric": {
                            "experiment": "mock",
                            "machine": "mlab1-xyz01.mlab-oti.measurement-lab.org" },
                        "value": [1522782427.81, "1"]
                      },
                      { "metric": {
                            "experiment": "mock",
                            "machine": "mlab2-xyz01.mlab-oti.measurement-lab.org" },
                        "value": [1522773427.51, "0"]
                      }
                  ]
              }
          }"""
          mock_open.return_value = self.mock_response
  
          mock_parse_sliver_tool_status.side_effect = [
              ('mock-mlab1-xyz01.mlab-oti.measurement-lab.org', '1',
               constants.PROMETHEUS_TOOL_EXTRA),
              ('mock-mlab2-xyz01.mlab-oti.measurement-lab.org', '0',
               constants.PROMETHEUS_TOOL_EXTRA)
          ]
  
          expected_status = {
              'mock-mlab1-xyz01.mlab-oti.measurement-lab.org': {
                  'status': message.STATUS_ONLINE,
                  'tool_extra': constants.PROMETHEUS_TOOL_EXTRA
              },
              'mock-mlab2-xyz01.mlab-oti.measurement-lab.org': {
                  'status': message.STATUS_OFFLINE,
                  'tool_extra': constants.PROMETHEUS_TOOL_EXTRA
              }
          }
  
          actual_status = prometheus_status.get_slice_status(
              'https://prometheus.measurementlab.mock.net',
              urllib2.OpenerDirector())
          self.assertDictEqual(actual_status, expected_status)
  
      @mock.patch.object(urllib2.OpenerDirector, 'open', autospec=True)
      def test_get_slice_status_returns_none_when_a_HTTPError_is_raised_by_urlopen(
              self, mock_open):
  
          # urllib2.HTTPError() requires 6 arguments. Subclassing to override
          # __init__ makes instantiating this easier.
          class MockHttpError(urllib2.HTTPError):
  
              def __init__(self, cause):
                  self.cause = cause
  
          self.mock_response.read.side_effect = MockHttpError('mock http error')
          mock_open.return_value = self.mock_response
          self.assertIsNone(prometheus_status.get_slice_status(
              'https://prometheus.measurementlab.mock.net',
              urllib2.OpenerDirector()))
  
  
  if __name__ == '__main__':
      unittest2.main()
  