#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""Unit tests for the triggering classes."""

# pytype: skip-file

import collections
import json
import os.path
import pickle
import random
import unittest

import yaml

import apache_beam as beam
from apache_beam import coders
from apache_beam.options.pipeline_options import PipelineOptions
from apache_beam.options.pipeline_options import StandardOptions
from apache_beam.options.pipeline_options import TypeOptions
from apache_beam.portability import common_urns
from apache_beam.runners import pipeline_context
from apache_beam.runners.direct.clock import TestClock
from apache_beam.testing.test_pipeline import TestPipeline
from apache_beam.testing.test_stream import TestStream
from apache_beam.testing.util import assert_that
from apache_beam.testing.util import equal_to
from apache_beam.transforms import WindowInto
from apache_beam.transforms import ptransform
from apache_beam.transforms import trigger
from apache_beam.transforms.core import Windowing
from apache_beam.transforms.trigger import AccumulationMode
from apache_beam.transforms.trigger import AfterAll
from apache_beam.transforms.trigger import AfterAny
from apache_beam.transforms.trigger import AfterCount
from apache_beam.transforms.trigger import AfterEach
from apache_beam.transforms.trigger import AfterProcessingTime
from apache_beam.transforms.trigger import AfterWatermark
from apache_beam.transforms.trigger import Always
from apache_beam.transforms.trigger import DataLossReason
from apache_beam.transforms.trigger import DefaultTrigger
from apache_beam.transforms.trigger import GeneralTriggerDriver
from apache_beam.transforms.trigger import InMemoryUnmergedState
from apache_beam.transforms.trigger import Repeatedly
from apache_beam.transforms.trigger import TriggerFn
from apache_beam.transforms.trigger import _Never
from apache_beam.transforms.window import FixedWindows
from apache_beam.transforms.window import GlobalWindows
from apache_beam.transforms.window import IntervalWindow
from apache_beam.transforms.window import Sessions
from apache_beam.transforms.window import TimestampCombiner
from apache_beam.transforms.window import TimestampedValue
from apache_beam.transforms.window import WindowedValue
from apache_beam.transforms.window import WindowFn
from apache_beam.utils.timestamp import MAX_TIMESTAMP
from apache_beam.utils.timestamp import MIN_TIMESTAMP
from apache_beam.utils.timestamp import Duration
from apache_beam.utils.windowed_value import PaneInfoTiming


class CustomTimestampingFixedWindowsWindowFn(FixedWindows):
  """WindowFn for testing custom timestamping."""
  def get_transformed_output_time(self, unused_window, input_timestamp):
    return input_timestamp + 100


class TriggerTest(unittest.TestCase):
  def run_trigger_simple(
      self,
      window_fn,
      trigger_fn,
      accumulation_mode,
      timestamped_data,
      expected_panes,
      *groupings,
      **kwargs):
    # Groupings is a list of integers indicating the (uniform) size of bundles
    # to try. For example, if timestamped_data has elements [a, b, c, d, e]
    # then groupings=(5, 2) would first run the test with everything in the same
    # bundle, and then re-run the test with bundling [a, b], [c, d], [e].
    # A negative value will reverse the order, e.g. -2 would result in bundles
    # [e, d], [c, b], [a].  This is useful for deterministic triggers in testing
    # that the output is not a function of ordering or bundling.
    # If empty, defaults to bundles of size 1 in the given order.
    late_data = kwargs.pop('late_data', [])
    assert not kwargs

    def bundle_data(data, size):
      if size < 0:
        data = list(data)[::-1]
        size = -size
      bundle = []
      for timestamp, elem in data:
        windows = window_fn.assign(WindowFn.AssignContext(timestamp, elem))
        bundle.append(WindowedValue(elem, timestamp, windows))
        if len(bundle) == size:
          yield bundle
          bundle = []
      if bundle:
        yield bundle

    if not groupings:
      groupings = [1]
    for group_by in groupings:
      self.run_trigger(
          window_fn,
          trigger_fn,
          accumulation_mode,
          bundle_data(timestamped_data, group_by),
          bundle_data(late_data, group_by),
          expected_panes)

  def run_trigger(
      self,
      window_fn,
      trigger_fn,
      accumulation_mode,
      bundles,
      late_bundles,
      expected_panes):
    actual_panes = collections.defaultdict(list)
    allowed_lateness = Duration(
        micros=int(common_urns.constants.MAX_TIMESTAMP_MILLIS.constant) * 1000)
    driver = GeneralTriggerDriver(
        Windowing(
            window_fn,
            trigger_fn,
            accumulation_mode,
            allowed_lateness=allowed_lateness),
        TestClock())
    state = InMemoryUnmergedState()

    for bundle in bundles:
      for wvalue in driver.process_elements(state,
                                            bundle,
                                            MIN_TIMESTAMP,
                                            MIN_TIMESTAMP):
        window, = wvalue.windows
        self.assertEqual(window.max_timestamp(), wvalue.timestamp)
        actual_panes[window].append(set(wvalue.value))

    while state.timers:
      for timer_window, (name, time_domain, timestamp,
                         _) in state.get_and_clear_timers():
        for wvalue in driver.process_timer(timer_window,
                                           name,
                                           time_domain,
                                           timestamp,
                                           state,
                                           MIN_TIMESTAMP):
          window, = wvalue.windows
          self.assertEqual(window.max_timestamp(), wvalue.timestamp)
          actual_panes[window].append(set(wvalue.value))

    for bundle in late_bundles:
      for wvalue in driver.process_elements(state,
                                            bundle,
                                            MAX_TIMESTAMP,
                                            MAX_TIMESTAMP):
        window, = wvalue.windows
        self.assertEqual(window.max_timestamp(), wvalue.timestamp)
        actual_panes[window].append(set(wvalue.value))

      while state.timers:
        for timer_window, (name, time_domain, timestamp,
                           _) in state.get_and_clear_timers():
          for wvalue in driver.process_timer(timer_window,
                                             name,
                                             time_domain,
                                             timestamp,
                                             state,
                                             MAX_TIMESTAMP):
            window, = wvalue.windows
            self.assertEqual(window.max_timestamp(), wvalue.timestamp)
            actual_panes[window].append(set(wvalue.value))

    self.assertEqual(expected_panes, actual_panes)

  def test_fixed_watermark(self):
    self.run_trigger_simple(
        FixedWindows(10),  # pyformat break
        AfterWatermark(),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (2, 'b'), (13, 'c')],
        {
            IntervalWindow(0, 10): [set('ab')],
            IntervalWindow(10, 20): [set('c')]
        },
        1,
        2,
        3,
        -3,
        -2,
        -1)

  def test_fixed_watermark_with_early(self):
    self.run_trigger_simple(
        FixedWindows(10),  # pyformat break
        AfterWatermark(early=AfterCount(2)),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (2, 'b'), (3, 'c')],
        {IntervalWindow(0, 10): [set('ab'), set('abc')]},
        2)
    self.run_trigger_simple(
        FixedWindows(10),  # pyformat break
        AfterWatermark(early=AfterCount(2)),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (2, 'b'), (3, 'c')],
        {IntervalWindow(0, 10): [set('abc'), set('abc')]},
        3)

  def test_fixed_watermark_with_early_late(self):
    self.run_trigger_simple(
        FixedWindows(100),  # pyformat break
        AfterWatermark(early=AfterCount(3), late=AfterCount(2)),
        AccumulationMode.DISCARDING,
        zip(range(9), 'abcdefghi'),
        {
            IntervalWindow(0, 100): [
                set('abcd'),
                set('efgh'),  # early
                set('i'),  # on time
                set('vw'),
                set('xy')  # late
            ]
        },
        2,
        late_data=zip(range(5), 'vwxyz'))

  def test_sessions_watermark_with_early_late(self):
    self.run_trigger_simple(
        Sessions(10),  # pyformat break
        AfterWatermark(early=AfterCount(2), late=AfterCount(1)),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (15, 'b'), (7, 'c'), (30, 'd')],
        {
            IntervalWindow(1, 25): [
                set('abc'),  # early
                set('abc'),  # on time
                set('abcxy')  # late
            ],
            IntervalWindow(30, 40): [
                set('d'),  # on time
            ],
            IntervalWindow(1, 40): [
                set('abcdxyz')  # late
            ],
        },
        2,
        late_data=[(1, 'x'), (2, 'y'), (21, 'z')])

  def test_fixed_after_count(self):
    self.run_trigger_simple(
        FixedWindows(10),  # pyformat break
        AfterCount(2),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (2, 'b'), (3, 'c'), (11, 'z')],
        {IntervalWindow(0, 10): [set('ab')]},
        1,
        2)
    self.run_trigger_simple(
        FixedWindows(10),  # pyformat break
        AfterCount(2),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (2, 'b'), (3, 'c'), (11, 'z')],
        {IntervalWindow(0, 10): [set('abc')]},
        3,
        4)

  def test_fixed_after_first(self):
    self.run_trigger_simple(
        FixedWindows(10),  # pyformat break
        AfterAny(AfterCount(2), AfterWatermark()),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (2, 'b'), (3, 'c')],
        {IntervalWindow(0, 10): [set('ab')]},
        1,
        2)
    self.run_trigger_simple(
        FixedWindows(10),  # pyformat break
        AfterAny(AfterCount(5), AfterWatermark()),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (2, 'b'), (3, 'c')],
        {IntervalWindow(0, 10): [set('abc')]},
        1,
        2,
        late_data=[(1, 'x'), (2, 'y'), (3, 'z')])

  def test_repeatedly_after_first(self):
    self.run_trigger_simple(
        FixedWindows(100),  # pyformat break
        Repeatedly(AfterAny(AfterCount(3), AfterWatermark())),
        AccumulationMode.ACCUMULATING,
        zip(range(7), 'abcdefg'),
        {
            IntervalWindow(0, 100): [
                set('abc'),
                set('abcdef'),
                set('abcdefg'),
                set('abcdefgx'),
                set('abcdefgxy'),
                set('abcdefgxyz')
            ]
        },
        1,
        late_data=zip(range(3), 'xyz'))

  def test_sessions_after_all(self):
    self.run_trigger_simple(
        Sessions(10),  # pyformat break
        AfterAll(AfterCount(2), AfterWatermark()),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (2, 'b'), (3, 'c')],
        {IntervalWindow(1, 13): [set('abc')]},
        1,
        2)
    self.run_trigger_simple(
        Sessions(10),  # pyformat break
        AfterAll(AfterCount(5), AfterWatermark()),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (2, 'b'), (3, 'c')],
        {IntervalWindow(1, 13): [set('abcxy')]},
        1,
        2,
        late_data=[(1, 'x'), (2, 'y'), (3, 'z')])

  def test_sessions_default(self):
    self.run_trigger_simple(
        Sessions(10),  # pyformat break
        DefaultTrigger(),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (2, 'b')],
        {IntervalWindow(1, 12): [set('ab')]},
        1,
        2,
        -2,
        -1)

    self.run_trigger_simple(
        Sessions(10),  # pyformat break
        AfterWatermark(),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (2, 'b'), (15, 'c'), (16, 'd'), (30, 'z'), (9, 'e'),
         (10, 'f'), (30, 'y')],
        {
            IntervalWindow(1, 26): [set('abcdef')],
            IntervalWindow(30, 40): [set('yz')]
        },
        1,
        2,
        3,
        4,
        5,
        6,
        -4,
        -2,
        -1)

  def test_sessions_watermark(self):
    self.run_trigger_simple(
        Sessions(10),  # pyformat break
        AfterWatermark(),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (2, 'b')],
        {IntervalWindow(1, 12): [set('ab')]},
        1,
        2,
        -2,
        -1)

  def test_sessions_after_count(self):
    self.run_trigger_simple(
        Sessions(10),  # pyformat break
        AfterCount(2),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (15, 'b'), (6, 'c'), (30, 's'), (31, 't'), (50, 'z'),
         (50, 'y')],
        {
            IntervalWindow(1, 25): [set('abc')],
            IntervalWindow(30, 41): [set('st')],
            IntervalWindow(50, 60): [set('yz')]
        },
        1,
        2,
        3)

  def test_sessions_repeatedly_after_count(self):
    self.run_trigger_simple(
        Sessions(10),  # pyformat break
        Repeatedly(AfterCount(2)),
        AccumulationMode.ACCUMULATING,
        [(1, 'a'), (15, 'b'), (6, 'c'), (2, 'd'), (7, 'e')],
        {IntervalWindow(1, 25): [set('abc'), set('abcde')]},
        1,
        3)
    self.run_trigger_simple(
        Sessions(10),  # pyformat break
        Repeatedly(AfterCount(2)),
        AccumulationMode.DISCARDING,
        [(1, 'a'), (15, 'b'), (6, 'c'), (2, 'd'), (7, 'e')],
        {IntervalWindow(1, 25): [set('abc'), set('de')]},
        1,
        3)

  def test_sessions_after_each(self):
    self.run_trigger_simple(
        Sessions(10),  # pyformat break
        AfterEach(AfterCount(2), AfterCount(3)),
        AccumulationMode.ACCUMULATING,
        zip(range(10), 'abcdefghij'),
        {
            IntervalWindow(0, 11): [set('ab')],
            IntervalWindow(0, 15): [set('abcdef')]
        },
        2)

    self.run_trigger_simple(
        Sessions(10),  # pyformat break
        Repeatedly(AfterEach(AfterCount(2), AfterCount(3))),
        AccumulationMode.ACCUMULATING,
        zip(range(10), 'abcdefghij'),
        {
            IntervalWindow(0, 11): [set('ab')],
            IntervalWindow(0, 15): [set('abcdef')],
            IntervalWindow(0, 17): [set('abcdefgh')]
        },
        2)

  def test_picklable_output(self):
    global_window = (trigger.GlobalWindow(), )
    driver = trigger.BatchGlobalTriggerDriver()
    unpicklable = (WindowedValue(k, 0, global_window) for k in range(10))
    with self.assertRaises(TypeError):
      pickle.dumps(unpicklable)
    for unwindowed in driver.process_elements(None, unpicklable, None, None):
      self.assertEqual(
          pickle.loads(pickle.dumps(unwindowed)).value, list(range(10)))


class MayLoseDataTest(unittest.TestCase):
  def _test(self, trigger, lateness, expected):
    windowing = WindowInto(
        GlobalWindows(),
        trigger=trigger,
        accumulation_mode=AccumulationMode.ACCUMULATING,
        allowed_lateness=lateness).windowing
    self.assertEqual(trigger.may_lose_data(windowing), expected)

  def test_default_trigger(self):
    self._test(DefaultTrigger(), 0, DataLossReason.NO_POTENTIAL_LOSS)

  def test_after_processing(self):
    self._test(AfterProcessingTime(42), 0, DataLossReason.MAY_FINISH)

  def test_always(self):
    self._test(Always(), 0, DataLossReason.NO_POTENTIAL_LOSS)

  def test_never(self):
    self._test(_Never(), 0, DataLossReason.NO_POTENTIAL_LOSS)

  def test_after_watermark_no_allowed_lateness(self):
    self._test(AfterWatermark(), 0, DataLossReason.NO_POTENTIAL_LOSS)

  def test_after_watermark_no_late_trigger(self):
    self._test(AfterWatermark(), 60, DataLossReason.MAY_FINISH)

  def test_after_watermark_no_allowed_lateness_safe_late(self):
    self._test(
        AfterWatermark(late=DefaultTrigger()),
        0,
        DataLossReason.NO_POTENTIAL_LOSS)

  def test_after_watermark_allowed_lateness_safe_late(self):
    self._test(
        AfterWatermark(late=DefaultTrigger()),
        60,
        DataLossReason.NO_POTENTIAL_LOSS)

  def test_after_count(self):
    self._test(AfterCount(42), 0, DataLossReason.MAY_FINISH)

  def test_repeatedly_safe_underlying(self):
    self._test(
        Repeatedly(DefaultTrigger()), 0, DataLossReason.NO_POTENTIAL_LOSS)

  def test_repeatedly_unsafe_underlying(self):
    self._test(Repeatedly(AfterCount(42)), 0, DataLossReason.NO_POTENTIAL_LOSS)

  def test_after_any_one_may_finish(self):
    self._test(
        AfterAny(AfterCount(42), DefaultTrigger()),
        0,
        DataLossReason.MAY_FINISH)

  def test_after_any_all_safe(self):
    self._test(
        AfterAny(Repeatedly(AfterCount(42)), DefaultTrigger()),
        0,
        DataLossReason.NO_POTENTIAL_LOSS)

  def test_after_all_some_may_finish(self):
    self._test(
        AfterAll(AfterCount(1), DefaultTrigger()),
        0,
        DataLossReason.NO_POTENTIAL_LOSS)

  def test_afer_all_all_may_finish(self):
    self._test(
        AfterAll(AfterCount(42), AfterProcessingTime(42)),
        0,
        DataLossReason.MAY_FINISH)

  def test_after_each_at_least_one_safe(self):
    self._test(
        AfterEach(AfterCount(1), DefaultTrigger(), AfterCount(2)),
        0,
        DataLossReason.NO_POTENTIAL_LOSS)

  def test_after_each_all_may_finish(self):
    self._test(
        AfterEach(AfterCount(1), AfterCount(2), AfterCount(3)),
        0,
        DataLossReason.MAY_FINISH)


class RunnerApiTest(unittest.TestCase):
  def test_trigger_encoding(self):
    for trigger_fn in (DefaultTrigger(),
                       AfterAll(AfterCount(1), AfterCount(10)),
                       AfterAny(AfterCount(10), AfterCount(100)),
                       AfterWatermark(early=AfterCount(1000)),
                       AfterWatermark(early=AfterCount(1000),
                                      late=AfterCount(1)),
                       Repeatedly(AfterCount(100)),
                       trigger.OrFinally(AfterCount(3), AfterCount(10))):
      context = pipeline_context.PipelineContext()
      self.assertEqual(
          trigger_fn,
          TriggerFn.from_runner_api(trigger_fn.to_runner_api(context), context))


class ContinuationTriggerTest(unittest.TestCase):
  def test_after_all(self):
    self.assertEqual(
        AfterAll(AfterCount(2), AfterCount(5)).get_continuation_trigger(),
        AfterAll(AfterCount(1), AfterCount(1)))

  def test_after_any(self):
    self.assertEqual(
        AfterAny(AfterCount(2), AfterCount(5)).get_continuation_trigger(),
        AfterAny(AfterCount(1), AfterCount(1)))

  def test_after_count(self):
    self.assertEqual(AfterCount(1).get_continuation_trigger(), AfterCount(1))
    self.assertEqual(AfterCount(100).get_continuation_trigger(), AfterCount(1))

  def test_after_each(self):
    self.assertEqual(
        AfterEach(AfterCount(2), AfterCount(5)).get_continuation_trigger(),
        Repeatedly(AfterAny(AfterCount(1), AfterCount(1))))

  def test_after_processing_time(self):
    from apache_beam.transforms.trigger import _AfterSynchronizedProcessingTime
    self.assertEqual(
        AfterProcessingTime(10).get_continuation_trigger(),
        _AfterSynchronizedProcessingTime())

  def test_after_watermark(self):
    self.assertEqual(
        AfterWatermark().get_continuation_trigger(), AfterWatermark())
    self.assertEqual(
        AfterWatermark(early=AfterCount(10),
                       late=AfterCount(20)).get_continuation_trigger(),
        AfterWatermark(early=AfterCount(1), late=AfterCount(1)))

  def test_always(self):
    self.assertEqual(Always().get_continuation_trigger(), Always())

  def test_default(self):
    self.assertEqual(
        DefaultTrigger().get_continuation_trigger(), DefaultTrigger())

  def test_never(self):
    self.assertEqual(_Never().get_continuation_trigger(), _Never())

  def test_repeatedly(self):
    self.assertEqual(
        Repeatedly(AfterCount(10)).get_continuation_trigger(),
        Repeatedly(AfterCount(1)))


class TriggerPipelineTest(unittest.TestCase):
  def test_after_processing_time(self):
    test_options = PipelineOptions(
        flags=['--allow_unsafe_triggers', '--streaming'])
    with TestPipeline(options=test_options) as p:

      total_elements_in_trigger = 4
      processing_time_delay = 2
      window_size = 10

      # yapf: disable
      test_stream = TestStream()
      for i in range(total_elements_in_trigger):
        (test_stream
         .advance_processing_time(
            processing_time_delay / total_elements_in_trigger)
         .add_elements([('key', i)])
         )

      test_stream.advance_processing_time(processing_time_delay)

      # Add dropped elements
      (test_stream
         .advance_processing_time(0.1)
         .add_elements([('key', "dropped-1")])
         .advance_processing_time(0.1)
         .add_elements([('key', "dropped-2")])
      )

      (test_stream
       .advance_processing_time(processing_time_delay)
       .advance_watermark_to_infinity()
       )
      # yapf: enable

      results = (
          p
          | test_stream
          | beam.WindowInto(
              FixedWindows(window_size),
              trigger=AfterProcessingTime(processing_time_delay),
              accumulation_mode=AccumulationMode.DISCARDING)
          | beam.GroupByKey()
          | beam.Map(lambda x: x[1]))
      assert_that(results, equal_to([list(range(total_elements_in_trigger))]))

  def test_repeatedly_after_processing_time(self):
    test_options = PipelineOptions(flags=['--streaming'])
    with TestPipeline(options=test_options) as p:
      total_elements = 7
      processing_time_delay = 2
      window_size = 10
      # yapf: disable
      test_stream = TestStream()
      for i in range(total_elements):
        (test_stream
         .advance_processing_time(processing_time_delay - 0.01)
         .add_elements([('key', i)])
         )

      (test_stream
       .advance_processing_time(processing_time_delay)
       .advance_watermark_to_infinity()
       )
      # yapf: enable

      results = (
          p
          | test_stream
          | beam.WindowInto(
              FixedWindows(window_size),
              trigger=Repeatedly(AfterProcessingTime(processing_time_delay)),
              accumulation_mode=AccumulationMode.DISCARDING)
          | beam.GroupByKey()
          | beam.Map(lambda x: x[1]))

      expected = [[i, i + 1]
                  for i in range(total_elements - total_elements % 2)
                  if i % 2 == 0]
      expected += [] if total_elements % 2 == 0 else [[total_elements - 1]]

      assert_that(results, equal_to(expected))

  def test_after_count(self):
    test_options = PipelineOptions(flags=['--allow_unsafe_triggers'])
    with TestPipeline(options=test_options) as p:

      def construct_timestamped(k, t):
        return TimestampedValue((k, t), t)

      def format_result(k, vs):
        return ('%s-%s' % (k, len(list(vs))), set(vs))

      result = (
          p
          | beam.Create([1, 2, 3, 4, 5, 10, 11])
          | beam.FlatMap(lambda t: [('A', t), ('B', t + 5)])
          | beam.MapTuple(construct_timestamped)
          | beam.WindowInto(
              FixedWindows(10),
              trigger=AfterCount(3),
              accumulation_mode=AccumulationMode.DISCARDING)
          | beam.GroupByKey()
          | beam.MapTuple(format_result))
      assert_that(
          result,
          equal_to(
              list({
                  'A-5': {1, 2, 3, 4, 5},
                  # A-10, A-11 never emitted due to AfterCount(3) never firing.
                  'B-4': {6, 7, 8, 9},
                  'B-3': {10, 15, 16},
              }.items())))

  def test_after_count_streaming(self):
    test_options = PipelineOptions(
        flags=['--allow_unsafe_triggers', '--streaming'])
    with TestPipeline(options=test_options) as p:
      # yapf: disable
      test_stream = (
          TestStream()
          .advance_watermark_to(0)
          .add_elements([('A', 1), ('A', 2), ('A', 3)])
          .add_elements([('A', 4), ('A', 5), ('A', 6)])
          .add_elements([('B', 1), ('B', 2), ('B', 3)])
          .advance_watermark_to_infinity())
      # yapf: enable

      results = (
          p
          | test_stream
          | beam.WindowInto(
              FixedWindows(10),
              trigger=AfterCount(3),
              accumulation_mode=AccumulationMode.ACCUMULATING)
          | beam.GroupByKey())

      assert_that(
          results,
          equal_to(
              list({
                  'A': [1, 2, 3],  # 4 - 6 discarded because trigger finished
                  'B': [1, 2, 3]
              }.items())))

  def test_always(self):
    # Pin to FnApiRunner since portable runner could trigger differently if
    # using bundle sizes of greater than 1.
    with TestPipeline('FnApiRunner') as p:

      def construct_timestamped(k, t):
        return TimestampedValue((k, t), t)

      def format_result(k, vs):
        return ('%s-%s' % (k, len(list(vs))), set(vs))

      result = (
          p
          | beam.Create([1, 1, 2, 3, 4, 5, 10, 11])
          | beam.FlatMap(lambda t: [('A', t), ('B', t + 5)])
          | beam.MapTuple(construct_timestamped)
          | beam.WindowInto(
              FixedWindows(10),
              trigger=Always(),
              accumulation_mode=AccumulationMode.DISCARDING)
          | beam.GroupByKey()
          | beam.MapTuple(format_result))
      assert_that(
          result,
          equal_to(
              list({
                  'A-2': {10, 11},  # Elements out of windows are also emitted.
                  'A-6': {1, 2, 3, 4, 5},  # A,1 is emitted twice.
                  'B-5': {6, 7, 8, 9},  # B,6 is emitted twice.
                  'B-3': {10, 15, 16},
              }.items())))

  def test_never(self):
    with TestPipeline() as p:

      def construct_timestamped(k, t):
        return TimestampedValue((k, t), t)

      def format_result(k, vs):
        return ('%s-%s' % (k, len(list(vs))), set(vs))

      result = (
          p
          | beam.Create([1, 1, 2, 3, 4, 5, 10, 11])
          | beam.FlatMap(lambda t: [('A', t), ('B', t + 5)])
          | beam.MapTuple(construct_timestamped)
          | beam.WindowInto(
              FixedWindows(10),
              trigger=_Never(),
              accumulation_mode=AccumulationMode.DISCARDING)
          | beam.GroupByKey()
          | beam.MapTuple(format_result))
      assert_that(
          result,
          equal_to(
              list({
                  'A-2': {10, 11},
                  'A-6': {1, 2, 3, 4, 5},
                  'B-5': {6, 7, 8, 9},
                  'B-3': {10, 15, 16},
              }.items())))

  def test_multiple_accumulating_firings(self):
    # PCollection will contain elements from 1 to 10.
    elements = [i for i in range(1, 11)]

    ts = TestStream().advance_watermark_to(0)
    for i in elements:
      ts.add_elements([('key', str(i))])
      if i % 5 == 0:
        ts.advance_watermark_to(i)
        ts.advance_processing_time(5)
    ts.advance_watermark_to_infinity()

    options = PipelineOptions()
    options.view_as(StandardOptions).streaming = True
    with TestPipeline(options=options) as p:
      records = (
          p
          | ts
          | beam.WindowInto(
              FixedWindows(10),
              accumulation_mode=trigger.AccumulationMode.ACCUMULATING,
              trigger=AfterWatermark(
                  early=AfterAll(AfterCount(1), AfterProcessingTime(5))))
          | beam.GroupByKey()
          | beam.FlatMap(lambda x: x[1]))

      # The trigger should fire twice. Once after 5 seconds, and once after 10.
      # The firings should accumulate the output.
      first_firing = [str(i) for i in elements if i <= 5]
      second_firing = [str(i) for i in elements]
      assert_that(records, equal_to(first_firing + second_firing))

  def test_on_pane_watermark_hold_no_pipeline_stall(self):
    """A regression test added for
    ttps://issues.apache.org/jira/browse/BEAM-10054."""
    START_TIMESTAMP = 1534842000

    test_stream = TestStream()
    test_stream.add_elements(['a'])
    test_stream.advance_processing_time(START_TIMESTAMP + 1)
    test_stream.advance_watermark_to(START_TIMESTAMP + 1)
    test_stream.add_elements(['b'])
    test_stream.advance_processing_time(START_TIMESTAMP + 2)
    test_stream.advance_watermark_to(START_TIMESTAMP + 2)

    with TestPipeline(options=PipelineOptions(
        ['--streaming', '--allow_unsafe_triggers'])) as p:
      # pylint: disable=expression-not-assigned
      (
          p
          | 'TestStream' >> test_stream
          | 'timestamp' >>
          beam.Map(lambda x: beam.window.TimestampedValue(x, START_TIMESTAMP))
          | 'kv' >> beam.Map(lambda x: (x, x))
          | 'window_1m' >> beam.WindowInto(
              beam.window.FixedWindows(60),
              trigger=trigger.AfterAny(
                  trigger.AfterProcessingTime(3600), trigger.AfterWatermark()),
              accumulation_mode=trigger.AccumulationMode.DISCARDING)
          | 'group_by_key' >> beam.GroupByKey()
          | 'filter' >> beam.Map(lambda x: x))


class TranscriptTest(unittest.TestCase):

  # We must prepend an underscore to this name so that the open-source unittest
  # runner does not execute this method directly as a test.
  @classmethod
  def _create_test(cls, spec):
    counter = 0
    name = spec.get('name', 'unnamed')
    unique_name = 'test_' + name
    while hasattr(cls, unique_name):
      counter += 1
      unique_name = 'test_%s_%d' % (name, counter)
    test_method = lambda self: self._run_log_test(spec)
    test_method.__name__ = unique_name
    test_method.__test__ = True
    setattr(cls, unique_name, test_method)

  # We must prepend an underscore to this name so that the open-source unittest
  # runner does not execute this method directly as a test.
  @classmethod
  def _create_tests(cls, transcript_filename):
    for spec in yaml.load_all(open(transcript_filename),
                              Loader=yaml.SafeLoader):
      cls._create_test(spec)

  def _run_log_test(self, spec):
    if 'error' in spec:
      self.assertRaisesRegex(Exception, spec['error'], self._run_log, spec)
    else:
      self._run_log(spec)

  def _run_log(self, spec):
    def parse_int_list(s):
      """Parses strings like '[1, 2, 3]'."""
      s = s.strip()
      assert s[0] == '[' and s[-1] == ']', s
      if not s[1:-1].strip():
        return []
      return [int(x) for x in s[1:-1].split(',')]

    def split_args(s):
      """Splits 'a, b, [c, d]' into ['a', 'b', '[c, d]']."""
      args = []
      start = 0
      depth = 0
      for ix in range(len(s)):
        c = s[ix]
        if c in '({[':
          depth += 1
        elif c in ')}]':
          depth -= 1
        elif c == ',' and depth == 0:
          args.append(s[start:ix].strip())
          start = ix + 1
      assert depth == 0, s
      args.append(s[start:].strip())
      return args

    def parse(s, names):
      """Parse (recursive) 'Foo(arg, kw=arg)' for Foo in the names dict."""
      s = s.strip()
      if s in names:
        return names[s]
      elif s[0] == '[':
        return parse_int_list(s)
      elif '(' in s:
        assert s[-1] == ')', s
        callee = parse(s[:s.index('(')], names)
        posargs = []
        kwargs = {}
        for arg in split_args(s[s.index('(') + 1:-1]):
          if '=' in arg:
            kw, value = arg.split('=', 1)
            kwargs[kw] = parse(value, names)
          else:
            posargs.append(parse(arg, names))
        return callee(*posargs, **kwargs)
      else:
        try:
          return int(s)
        except ValueError:
          raise ValueError('Unknown function: %s' % s)

    def parse_fn(s, names):
      """Like parse(), but implicitly calls no-arg constructors."""
      fn = parse(s, names)
      if isinstance(fn, type):
        return fn()
      return fn

    # pylint: disable=wrong-import-order, wrong-import-position
    from apache_beam.transforms import window as window_module

    # pylint: enable=wrong-import-order, wrong-import-position
    window_fn_names = dict(window_module.__dict__)
    # yapf: disable
    window_fn_names.update({
        'CustomTimestampingFixedWindowsWindowFn':
            CustomTimestampingFixedWindowsWindowFn
    })
    # yapf: enable
    trigger_names = {'Default': DefaultTrigger}
    trigger_names.update(trigger.__dict__)

    window_fn = parse_fn(
        spec.get('window_fn', 'GlobalWindows'), window_fn_names)
    trigger_fn = parse_fn(spec.get('trigger_fn', 'Default'), trigger_names)
    accumulation_mode = getattr(
        AccumulationMode, spec.get('accumulation_mode', 'ACCUMULATING').upper())
    timestamp_combiner = getattr(
        TimestampCombiner,
        spec.get('timestamp_combiner', 'OUTPUT_AT_EOW').upper())
    allowed_lateness = spec.get('allowed_lateness', 0.000)

    def only_element(xs):
      x, = list(xs)
      return x

    transcript = [only_element(line.items()) for line in spec['transcript']]

    self._execute(
        window_fn,
        trigger_fn,
        accumulation_mode,
        timestamp_combiner,
        allowed_lateness,
        transcript,
        spec)


def _windowed_value_info(windowed_value):
  # Currently some runners operate at the millisecond level, and some at the
  # microsecond level.  Trigger transcript timestamps are expressed as
  # integral units of the finest granularity, whatever that may be.
  # In these tests we interpret them as integral seconds and then truncate
  # the results to integral seconds to allow for portability across
  # different sub-second resolutions.
  window, = windowed_value.windows
  return {
      'window': [int(window.start), int(window.max_timestamp())],
      'values': sorted(windowed_value.value),
      'timestamp': int(windowed_value.timestamp),
      'index': windowed_value.pane_info.index,
      'nonspeculative_index': windowed_value.pane_info.nonspeculative_index,
      'early': windowed_value.pane_info.timing == PaneInfoTiming.EARLY,
      'late': windowed_value.pane_info.timing == PaneInfoTiming.LATE,
      'final': windowed_value.pane_info.is_last,
  }


def _windowed_value_info_map_fn(
    k,
    vs,
    window=beam.DoFn.WindowParam,
    t=beam.DoFn.TimestampParam,
    p=beam.DoFn.PaneInfoParam):
  return (
      k,
      _windowed_value_info(
          WindowedValue(vs, windows=[window], timestamp=t, pane_info=p)))


def _windowed_value_info_check(actual, expected, key=None):

  key_string = ' for %s' % key if key else ''

  def format(panes):
    return '\n[%s]\n' % '\n '.join(
        str(pane)
        for pane in sorted(panes, key=lambda pane: pane.get('timestamp', None)))

  if len(actual) > len(expected):
    raise AssertionError(
        'Unexpected output%s: expected %s but got %s' %
        (key_string, format(expected), format(actual)))
  elif len(expected) > len(actual):
    raise AssertionError(
        'Unmatched output%s: expected %s but got %s' %
        (key_string, format(expected), format(actual)))
  else:

    def diff(actual, expected):
      for key in sorted(expected.keys(), reverse=True):
        if key in actual:
          if actual[key] != expected[key]:
            return key

    for output in actual:
      diffs = [diff(output, pane) for pane in expected]
      if all(diffs):
        raise AssertionError(
            'Unmatched output%s: %s not found in %s (diffs in %s)' %
            (key_string, output, format(expected), diffs))


class _ConcatCombineFn(beam.CombineFn):
  create_accumulator = lambda self: []  # type: ignore[var-annotated]
  add_input = lambda self, acc, element: acc.append(element) or acc
  merge_accumulators = lambda self, accs: sum(accs, [])  # type: ignore[var-annotated]
  extract_output = lambda self, acc: acc


class TriggerDriverTranscriptTest(TranscriptTest):
  def _execute(
      self,
      window_fn,
      trigger_fn,
      accumulation_mode,
      timestamp_combiner,
      allowed_lateness,
      transcript,
      unused_spec):

    driver = GeneralTriggerDriver(
        Windowing(
            window_fn,
            trigger_fn,
            accumulation_mode,
            timestamp_combiner,
            allowed_lateness),
        TestClock())
    state = InMemoryUnmergedState()
    output = []
    watermark = MIN_TIMESTAMP

    def fire_timers():
      to_fire = state.get_and_clear_timers(watermark)
      while to_fire:
        for timer_window, (name, time_domain, t_timestamp, _) in to_fire:
          for wvalue in driver.process_timer(timer_window,
                                             name,
                                             time_domain,
                                             t_timestamp,
                                             state):
            output.append(_windowed_value_info(wvalue))
        to_fire = state.get_and_clear_timers(watermark)

    for action, params in transcript:

      if action != 'expect':
        # Fail if we have output that was not expected in the transcript.
        self.assertEqual([],
                         output,
                         msg='Unexpected output: %s before %s: %s' %
                         (output, action, params))

      if action == 'input':
        bundle = [
            WindowedValue(t, t, window_fn.assign(WindowFn.AssignContext(t, t)))
            for t in params
        ]
        output = [
            _windowed_value_info(wv) for wv in driver.process_elements(
                state, bundle, watermark, watermark)
        ]
        fire_timers()

      elif action == 'watermark':
        watermark = params
        fire_timers()

      elif action == 'expect':
        for expected_output in params:
          for candidate in output:
            if all(candidate[k] == expected_output[k] for k in candidate
                   if k in expected_output):
              output.remove(candidate)
              break
          else:
            self.fail('Unmatched output %s in %s' % (expected_output, output))

      elif action == 'state':
        # TODO(robertwb): Implement once we support allowed lateness.
        pass

      else:
        self.fail('Unknown action: ' + action)

    # Fail if we have output that was not expected in the transcript.
    self.assertEqual([], output, msg='Unexpected output: %s' % output)


class BaseTestStreamTranscriptTest(TranscriptTest):
  """A suite of TestStream-based tests based on trigger transcript entries.
  """
  def _execute(
      self,
      window_fn,
      trigger_fn,
      accumulation_mode,
      timestamp_combiner,
      allowed_lateness,
      transcript,
      spec):

    runner_name = TestPipeline().runner.__class__.__name__
    if runner_name in spec.get('broken_on', ()):
      self.skipTest('Known to be broken on %s' % runner_name)

    is_order_agnostic = (
        isinstance(trigger_fn, DefaultTrigger) and
        accumulation_mode == AccumulationMode.ACCUMULATING)

    if is_order_agnostic:
      reshuffle_seed = random.randrange(1 << 20)
      keys = [
          'original',
          'reversed',
          'reshuffled(%s)' % reshuffle_seed,
          'one-element-bundles',
          'one-element-bundles-reversed',
          'two-element-bundles'
      ]
    else:
      keys = ['key1', 'key2']

    # Elements are encoded as a json strings to allow other languages to
    # decode elements while executing the test stream.
    # TODO(https://github.com/apache/beam/issues/19934): Eliminate these
    # gymnastics.
    test_stream = TestStream(coder=coders.StrUtf8Coder()).with_output_types(str)
    for action, params in transcript:
      if action == 'expect':
        test_stream.add_elements([json.dumps(('expect', params))])
      else:
        test_stream.add_elements([json.dumps(('expect', []))])
        if action == 'input':

          def keyed(key, values):
            return [json.dumps(('input', (key, v))) for v in values]

          if is_order_agnostic:
            # Must match keys above.
            test_stream.add_elements(keyed('original', params))
            test_stream.add_elements(keyed('reversed', reversed(params)))
            r = random.Random(reshuffle_seed)
            reshuffled = list(params)
            r.shuffle(reshuffled)
            test_stream.add_elements(
                keyed('reshuffled(%s)' % reshuffle_seed, reshuffled))
            for v in params:
              test_stream.add_elements(keyed('one-element-bundles', [v]))
            for v in reversed(params):
              test_stream.add_elements(
                  keyed('one-element-bundles-reversed', [v]))
            for ix in range(0, len(params), 2):
              test_stream.add_elements(
                  keyed('two-element-bundles', params[ix:ix + 2]))
          else:
            for key in keys:
              test_stream.add_elements(keyed(key, params))
        elif action == 'watermark':
          test_stream.advance_watermark_to(params)
        elif action == 'clock':
          test_stream.advance_processing_time(params)
        elif action == 'state':
          pass  # Requires inspection of implementation details.
        else:
          raise ValueError('Unexpected action: %s' % action)
    test_stream.add_elements([json.dumps(('expect', []))])
    test_stream.advance_watermark_to_infinity()

    read_test_stream = test_stream | beam.Map(json.loads)

    class Check(beam.DoFn):
      """A StatefulDoFn that verifies outputs are produced as expected.

      This DoFn takes in two kinds of inputs, actual outputs and
      expected outputs.  When an actual output is received, it is buffered
      into state, and when an expected output is received, this buffered
      state is retrieved and compared against the expected value(s) to ensure
      they match.

      The key is ignored, but all items must be on the same key to share state.
      """
      def __init__(self, allow_out_of_order=True):
        # Some runners don't support cross-stage TestStream semantics.
        self.allow_out_of_order = allow_out_of_order

      def process(
          self,
          element,
          seen=beam.DoFn.StateParam(
              beam.transforms.userstate.BagStateSpec(
                  'seen', beam.coders.FastPrimitivesCoder())),
          expected=beam.DoFn.StateParam(
              beam.transforms.userstate.BagStateSpec(
                  'expected', beam.coders.FastPrimitivesCoder()))):
        key, (action, data) = element

        if self.allow_out_of_order:
          if action == 'expect' and not list(seen.read()):
            if data:
              expected.add(data)
            return
          elif action == 'actual' and list(expected.read()):
            seen.add(data)
            all_data = list(seen.read())
            all_expected = list(expected.read())
            if len(all_data) == len(all_expected[0]):
              expected.clear()
              for expect in all_expected[1:]:
                expected.add(expect)
              action, data = 'expect', all_expected[0]
            else:
              return

        if action == 'actual':
          seen.add(data)

        elif action == 'expect':
          actual = list(seen.read())
          seen.clear()
          _windowed_value_info_check(actual, data, key)

        else:
          raise ValueError('Unexpected action: %s' % action)

    @ptransform.ptransform_fn
    def CheckAggregation(inputs_and_expected, aggregation):
      # Split the test stream into a branch of to-be-processed elements, and
      # a branch of expected results.
      inputs, expected = (
          inputs_and_expected
          | beam.MapTuple(
              lambda tag, value: beam.pvalue.TaggedOutput(tag, value),
              ).with_outputs('input', 'expect'))

      # Process the inputs with the given windowing to produce actual outputs.
      outputs = (
          inputs
          | beam.MapTuple(
              lambda key, value: TimestampedValue((key, value), value))
          | beam.WindowInto(
              window_fn,
              trigger=trigger_fn,
              accumulation_mode=accumulation_mode,
              timestamp_combiner=timestamp_combiner,
              allowed_lateness=allowed_lateness)
          | aggregation
          | beam.MapTuple(_windowed_value_info_map_fn)
          # Place outputs back into the global window to allow flattening
          # and share a single state in Check.
          | 'Global' >> beam.WindowInto(beam.transforms.window.GlobalWindows()))
      # Feed both the expected and actual outputs to Check() for comparison.
      tagged_expected = (
          expected | beam.FlatMap(
              lambda value: [(key, ('expect', value)) for key in keys]))
      tagged_outputs = (
          outputs | beam.MapTuple(lambda key, value: (key, ('actual', value))))
      # pylint: disable=expression-not-assigned
      ([tagged_expected, tagged_outputs]
       | beam.Flatten()
       | beam.ParDo(Check(self.allow_out_of_order)))

    with TestPipeline() as p:
      # TODO(https://github.com/apache/beam/issues/19933): Pass this during
      # pipeline construction.
      p._options.view_as(StandardOptions).streaming = True
      p._options.view_as(TypeOptions).allow_unsafe_triggers = True

      # We can have at most one test stream per pipeline, so we share it.
      inputs_and_expected = p | read_test_stream
      _ = inputs_and_expected | CheckAggregation(beam.GroupByKey())
      _ = inputs_and_expected | CheckAggregation(
          beam.CombinePerKey(_ConcatCombineFn()))


class TestStreamTranscriptTest(BaseTestStreamTranscriptTest):
  allow_out_of_order = False


class WeakTestStreamTranscriptTest(BaseTestStreamTranscriptTest):
  allow_out_of_order = True


class BatchTranscriptTest(TranscriptTest):
  def _execute(
      self,
      window_fn,
      trigger_fn,
      accumulation_mode,
      timestamp_combiner,
      allowed_lateness,
      transcript,
      spec):
    if timestamp_combiner == TimestampCombiner.OUTPUT_AT_EARLIEST_TRANSFORMED:
      self.skipTest(
          'Non-fnapi timestamp combiner: %s' % spec.get('timestamp_combiner'))

    if accumulation_mode != AccumulationMode.ACCUMULATING:
      self.skipTest('Batch mode only makes sense for accumulating.')

    watermark = MIN_TIMESTAMP
    for action, params in transcript:
      if action == 'watermark':
        watermark = params
      elif action == 'input':
        if any(t <= watermark for t in params):
          self.skipTest('Batch mode never has late data.')

    inputs = sum([vs for action, vs in transcript if action == 'input'], [])
    final_panes_by_window = {}
    for action, params in transcript:
      if action == 'expect':
        for expected in params:
          trimmed = {}
          for field in ('window', 'values', 'timestamp'):
            if field in expected:
              trimmed[field] = expected[field]
          final_panes_by_window[tuple(expected['window'])] = trimmed
    final_panes = list(final_panes_by_window.values())

    if window_fn.is_merging():
      merged_away = set()

      class MergeContext(WindowFn.MergeContext):
        def merge(_, to_be_merged, merge_result):
          for window in to_be_merged:
            if window != merge_result:
              merged_away.add(window)

      all_windows = [IntervalWindow(*pane['window']) for pane in final_panes]
      window_fn.merge(MergeContext(all_windows))
      final_panes = [
          pane for pane in final_panes
          if IntervalWindow(*pane['window']) not in merged_away
      ]

    # TODO(https://github.com/apache/beam/issues/34549): This test relies on
    # the correct error message being reported, but because of how it is
    # structured Prism often fails on splitting at the same time as it fails
    # on an element, leading to good logs but potentially inconsistent error
    # messages. Its not a bug, but it does mess with regex matching.
    with TestPipeline('FnApiRunner') as p:
      input_pc = (
          p
          | beam.Create(inputs)
          | beam.Map(lambda t: TimestampedValue(('key', t), t))
          | beam.WindowInto(
              window_fn,
              trigger=trigger_fn,
              accumulation_mode=accumulation_mode,
              timestamp_combiner=timestamp_combiner,
              allowed_lateness=allowed_lateness))

      grouped = input_pc | 'Grouped' >> (
          beam.GroupByKey()
          | beam.MapTuple(_windowed_value_info_map_fn)
          | beam.MapTuple(lambda _, value: value))

      combined = input_pc | 'Combined' >> (
          beam.CombinePerKey(_ConcatCombineFn())
          | beam.MapTuple(_windowed_value_info_map_fn)
          | beam.MapTuple(lambda _, value: value))

      assert_that(
          grouped,
          lambda actual: _windowed_value_info_check(actual, final_panes),
          label='CheckGrouped')

      assert_that(
          combined,
          lambda actual: _windowed_value_info_check(actual, final_panes),
          label='CheckCombined')


TRANSCRIPT_TEST_FILE = os.path.join(
    os.path.dirname(__file__),
    '..',
    'testing',
    'data',
    'trigger_transcripts.yaml')
if os.path.exists(TRANSCRIPT_TEST_FILE):
  TriggerDriverTranscriptTest._create_tests(TRANSCRIPT_TEST_FILE)
  TestStreamTranscriptTest._create_tests(TRANSCRIPT_TEST_FILE)
  WeakTestStreamTranscriptTest._create_tests(TRANSCRIPT_TEST_FILE)
  BatchTranscriptTest._create_tests(TRANSCRIPT_TEST_FILE)

if __name__ == '__main__':
  unittest.main()
