# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Tests for chromite.lib.cloud_trace."""

import os

from chromite.lib import cloud_trace
from chromite.lib import cros_test_lib


class SpanTest(cros_test_lib.MockTestCase):
  """Tests for the Span class."""

  def testToDict(self):
    """Tests that Span instances can be turned into dicts."""
    traceId = 'deadbeefdeadbeefdeadbeefdeadbeef'
    span = cloud_trace.Span(spanId='1234', traceId=traceId, name='Test span')
    self.assertEqual(dict(span), {
        'labels': {},
        'spanId': '1234',
        'name': 'Test span'
    })


class SpanStackTest(cros_test_lib.MockTestCase):
  """Tests for the SpanStack class."""

  def setUp(self):
    self.log_span_mock = self.PatchObject(cloud_trace, 'LogSpan')

  def testLogSingleSpan(self):
    """Tests that SpanStack.Span logs a span and sends it."""
    stack = cloud_trace.SpanStack()
    context = stack.Span('foo')
    self.assertEqual(0, self.log_span_mock.call_count)
    with context:
      self.assertEqual(0, self.log_span_mock.call_count)
    self.assertEqual(1, self.log_span_mock.call_count)

  def testCallLogSpanAtCloseOfStack(self):
    """Test that LogSpans is called after each span is popped."""
    stack = cloud_trace.SpanStack()
    with stack.Span('foo'):
      self.assertEqual(0, self.log_span_mock.call_count)
      with stack.Span('bar'):
        self.assertEqual(0, self.log_span_mock.call_count)
        with stack.Span('zap'):
          self.assertEqual(0, self.log_span_mock.call_count)
        self.assertEqual(1, self.log_span_mock.call_count)
      self.assertEqual(2, self.log_span_mock.call_count)
    self.assertEqual(3, self.log_span_mock.call_count)

  def testSpannedDecorator(self):
    """Tests that @stack.Spanned() works."""
    stack = cloud_trace.SpanStack()
    @stack.Spanned('foo')
    def decorated():
      pass

    self.assertEqual(0, self.log_span_mock.call_count)
    decorated()
    self.assertEqual(1, self.log_span_mock.call_count)


class SpanLogTest(cros_test_lib.MockTestCase, cros_test_lib.TempDirTestCase):
  """Tests that spans can be logged correctly."""

  def setUp(self):
    self._old_log = cloud_trace.SPANS_LOG
    cloud_trace.SPANS_LOG = os.path.join(self.tempdir, '{pid}.json')

  def tearDown(self):
    cloud_trace.SPANS_LOG = self._old_log

  def testCanSendLog(self):
    """Tests that Spans are sent to a log."""
    stack = cloud_trace.SpanStack()
    with stack.Span('foo'):
      pass
    self.assertExists(cloud_trace.SPANS_LOG.format(pid=os.getpid()))


class CloudTraceContextTest(cros_test_lib.MockTestCase):
  """Tests the CLOUD_TRACE_CONTEXT environment variable functionality.."""
  def setUp(self):
    self.log_span_mock = self.PatchObject(cloud_trace, 'LogSpan')
    os_mock = self.PatchObject(cloud_trace, 'os')
    os_mock.environ = self.env = {}

  def testHeaderValue(self):
    """Tests that the header value makes sense."""
    trace_id = 'deadbeef12345678deadbeef12345678'
    stack = cloud_trace.SpanStack(
        traceId=trace_id,
        parentSpanId='0',
        global_context='deadbeefdeadbeefdeadbeefdeadbeef/0;o=1')

    self.assertTrue(stack.enabled)
    self.assertEqual(stack.traceId, trace_id)
    self.assertEqual(stack.last_span_id, '0')

  def testCloudTraceContextPattern(self):
    """Tests that the regex matches an example context."""
    trace_id = 'deadbeef12345678deadbeef12345678'
    global_context = '{trace_id}/0;o=1'.format(trace_id=trace_id)
    self.assertTrue(bool(
        cloud_trace.SpanStack.CLOUD_TRACE_CONTEXT_PATTERN.match(
            global_context)))

    # pylint: disable=protected-access
    result = cloud_trace.SpanStack._ParseCloudTraceContext(global_context)
    self.assertEqual(result, {
        'traceId': trace_id,
        'parentSpanId': '0',
        'options': '1'
    })

  def testInitReadsEnvironment(self):
    """Tests that SpanStack reads the enivornment on init."""
    trace_id = 'deadbeef12345678deadbeef12345678'
    global_context = '{trace_id}/0;o=1'.format(trace_id=trace_id)
    old_env = self.env.get(cloud_trace.SpanStack.CLOUD_TRACE_CONTEXT_ENV)
    try:
      self.env[cloud_trace.SpanStack.CLOUD_TRACE_CONTEXT_ENV] = global_context
      stack = cloud_trace.SpanStack()
      self.assertEqual(stack.traceId, trace_id)
      self.assertEqual(stack.last_span_id, '0')
    finally:
      if old_env is not None:
        self.env[cloud_trace.SpanStack.CLOUD_TRACE_CONTEXT_ENV] = old_env

  def testEnvironmentContextManager(self):
    """Tests that the environment context manager works."""
    trace_id = 'deadbeef12345678deadbeef12345678'
    stack = cloud_trace.SpanStack(
        global_context='{trace_id}/0;o=1'.format(trace_id=trace_id))

    old_env = self.env.get(cloud_trace.SpanStack.CLOUD_TRACE_CONTEXT_ENV)
    with stack.EnvironmentContext():
      new_env = self.env.get(cloud_trace.SpanStack.CLOUD_TRACE_CONTEXT_ENV)
    after_env = self.env.get(cloud_trace.SpanStack.CLOUD_TRACE_CONTEXT_ENV)

    self.assertEqual(old_env, after_env)
    # Note the lack of a /0; the /0 is optional.
    self.assertEqual(new_env, 'deadbeef12345678deadbeef12345678;o=1')

  def testSpanContextEnabled(self):
    """Tests that the span context manager updates the environment."""
    trace_id = 'deadbeef12345678deadbeef12345678'
    stack = cloud_trace.SpanStack(
        traceId=trace_id,
        parentSpanId='0',
        global_context='deadbeefdeadbeefdeadbeefdeadbeef/0;o=1')

    self.assertTrue(stack.enabled)
    old_env = self.env.get(cloud_trace.SpanStack.CLOUD_TRACE_CONTEXT_ENV)
    with stack.Span('foo') as span:
      new_env = self.env.get(cloud_trace.SpanStack.CLOUD_TRACE_CONTEXT_ENV)
      self.assertTrue(new_env.startswith('deadbeef12345678deadbeef12345678/'))
      self.assertEqual(span.parentSpanId, '0')
      self.assertEqual(span.traceId, trace_id)
    after_env = self.env.get(cloud_trace.SpanStack.CLOUD_TRACE_CONTEXT_ENV)

    self.assertEqual(self.log_span_mock.call_count, 1)
    self.assertEqual(old_env, after_env)

  def testSpanContextDisabled(self):
    """Tests that o=1 in the global_context disables the spanstack."""
    trace_id = 'deadbeef12345678deadbeef12345678'
    stack = cloud_trace.SpanStack(
        traceId=trace_id,
        parentSpanId='0',
        global_context='deadbeefdeadbeefdeadbeefdeadbeef/0;o=0')

    self.assertFalse(stack.enabled)
    with stack.Span('foo') as span:
      self.assertEqual(span.parentSpanId, '0')
      self.assertEqual(span.traceId, trace_id)
    self.assertEqual(self.log_span_mock.call_count, 0)
