chromium/build/android/pylib/instrumentation/instrumentation_test_instance_test.py

#!/usr/bin/env vpython3
# Copyright 2014 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unit tests for instrumentation_test_instance."""

# pylint: disable=protected-access


import collections
import tempfile
import unittest

from pylib.base import base_test_result
from pylib.instrumentation import instrumentation_test_instance

import mock  # pylint: disable=import-error

_INSTRUMENTATION_TEST_INSTANCE_PATH = (
    'pylib.instrumentation.instrumentation_test_instance.%s')

class InstrumentationTestInstanceTest(unittest.TestCase):

  @staticmethod
  def createTestInstance():
    c = _INSTRUMENTATION_TEST_INSTANCE_PATH % 'InstrumentationTestInstance'
    # yapf: disable
    with mock.patch('%s._initializeApkAttributes' % c), (
         mock.patch('%s._initializeDataDependencyAttributes' % c)), (
         mock.patch('%s._initializeTestFilterAttributes' %c)), (
         mock.patch('%s._initializeFlagAttributes' % c)), (
         mock.patch('%s._initializeTestControlAttributes' % c)), (
         mock.patch('%s._initializeTestCoverageAttributes' % c)), (
         mock.patch('%s._initializeSkiaGoldAttributes' % c)):
      # yapf: enable
      return instrumentation_test_instance.InstrumentationTestInstance(
          mock.MagicMock(), mock.MagicMock(), lambda s: None)

  _FlagAttributesArgs = collections.namedtuple('_FlagAttributesArgs', [
      'command_line_flags', 'device_flags_file', 'strict_mode',
      'use_apk_under_test_flags_file', 'coverage_dir'
  ])

  def createFlagAttributesArgs(self,
                               command_line_flags=None,
                               device_flags_file=None,
                               strict_mode=None,
                               use_apk_under_test_flags_file=False,
                               coverage_dir=None):
    return self._FlagAttributesArgs(command_line_flags, device_flags_file,
                                    strict_mode, use_apk_under_test_flags_file,
                                    coverage_dir)

  def test_initializeFlagAttributes_commandLineFlags(self):
    o = self.createTestInstance()
    args = self.createFlagAttributesArgs(command_line_flags=['--foo', '--bar'])
    o._initializeFlagAttributes(args)
    self.assertEqual(o._flags, ['--enable-test-intents', '--foo', '--bar'])

  def test_initializeFlagAttributes_deviceFlagsFile(self):
    o = self.createTestInstance()
    with tempfile.NamedTemporaryFile(mode='w') as flags_file:
      flags_file.write('\n'.join(['--foo', '--bar']))
      flags_file.flush()

      args = self.createFlagAttributesArgs(device_flags_file=flags_file.name)
      o._initializeFlagAttributes(args)
      self.assertEqual(o._flags, ['--enable-test-intents', '--foo', '--bar'])

  def test_initializeFlagAttributes_strictModeOn(self):
    o = self.createTestInstance()
    args = self.createFlagAttributesArgs(strict_mode='on')
    o._initializeFlagAttributes(args)
    self.assertEqual(o._flags, ['--enable-test-intents', '--strict-mode=on'])

  def test_initializeFlagAttributes_strictModeOn_coverageOn(self):
    o = self.createTestInstance()
    args = self.createFlagAttributesArgs(
        strict_mode='on', coverage_dir='/coverage/dir')
    o._initializeFlagAttributes(args)
    self.assertEqual(o._flags, ['--enable-test-intents'])

  def test_initializeFlagAttributes_strictModeOff(self):
    o = self.createTestInstance()
    args = self.createFlagAttributesArgs(strict_mode='off')
    o._initializeFlagAttributes(args)
    self.assertEqual(o._flags, ['--enable-test-intents'])

  def testGetTests_noFilter(self):
    o = self.createTestInstance()
    raw_tests = [
      {
        'annotations': {'Feature': {'value': ['Foo']}},
        'class': 'org.chromium.test.SampleTest',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
          {
            'annotations': {'MediumTest': None},
            'method': 'testMethod2',
          },
        ],
      },
      {
        'annotations': {'Feature': {'value': ['Bar']}},
        'class': 'org.chromium.test.SampleTest2',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
        ],
      }
    ]

    expected_tests = [
      {
        'annotations': {
          'Feature': {'value': ['Foo']},
          'SmallTest': None,
        },
        'class': 'org.chromium.test.SampleTest',
        'method': 'testMethod1',
      },
      {
        'annotations': {
          'Feature': {'value': ['Foo']},
          'MediumTest': None,
        },
        'class': 'org.chromium.test.SampleTest',
        'method': 'testMethod2',
      },
      {
        'annotations': {
          'Feature': {'value': ['Bar']},
          'SmallTest': None,
        },
        'class': 'org.chromium.test.SampleTest2',
        'method': 'testMethod1',
      },
    ]

    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGetTests_simpleGtestFilter(self):
    o = self.createTestInstance()
    raw_tests = [
      {
        'annotations': {'Feature': {'value': ['Foo']}},
        'class': 'org.chromium.test.SampleTest',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
          {
            'annotations': {'MediumTest': None},
            'method': 'testMethod2',
          },
        ],
      }
    ]

    expected_tests = [
      {
        'annotations': {
          'Feature': {'value': ['Foo']},
          'SmallTest': None,
        },
        'class': 'org.chromium.test.SampleTest',
        'method': 'testMethod1',
      },
    ]

    o._test_filters = ['org.chromium.test.SampleTest.testMethod1']
    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGetTests_simpleGtestPositiveAndNegativeFilter(self):
    o = self.createTestInstance()
    raw_tests = [{
        'annotations': {
            'Feature': {
                'value': ['Foo']
            }
        },
        'class':
        'org.chromium.test.SampleTest',
        'superclass':
        'java.lang.Object',
        'methods': [
            {
                'annotations': {
                    'SmallTest': None
                },
                'method': 'testMethod1',
            },
            {
                'annotations': {
                    'MediumTest': None
                },
                'method': 'testMethod2',
            },
        ],
    }, {
        'annotations': {
            'Feature': {
                'value': ['Foo']
            }
        },
        'class':
        'org.chromium.test.SampleTest2',
        'superclass':
        'java.lang.Object',
        'methods': [{
            'annotations': {
                'SmallTest': None
            },
            'method': 'testMethod1',
        }],
    }]

    expected_tests = [
        {
            'annotations': {
                'Feature': {
                    'value': ['Foo']
                },
                'SmallTest': None,
            },
            'class': 'org.chromium.test.SampleTest',
            'method': 'testMethod1',
        },
    ]

    o._test_filters = [
        'org.chromium.test.SampleTest.*'\
          '-org.chromium.test.SampleTest.testMethod2'
    ]
    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGetTests_multipleGtestPositiveAndNegativeFilter(self):
    o = self.createTestInstance()
    raw_tests = [{
        'annotations': {
            'Feature': {
                'value': ['Foo']
            }
        },
        'class':
        'org.chromium.test.SampleTest',
        'superclass':
        'java.lang.Object',
        'methods': [
            {
                'annotations': {
                    'SmallTest': None
                },
                'method': 'testMethod1',
            },
            {
                'annotations': {
                    'MediumTest': None
                },
                'method': 'testMethod2',
            },
        ],
    }, {
        'annotations': {
            'Feature': {
                'value': ['Foo']
            }
        },
        'class':
        'org.chromium.test.SampleTest2',
        'superclass':
        'java.lang.Object',
        'methods': [{
            'annotations': {
                'SmallTest': None
            },
            'method': 'testMethod1',
        }],
    }]

    expected_tests = [
        {
            'annotations': {
                'Feature': {
                    'value': ['Foo']
                },
                'SmallTest': None,
            },
            'class': 'org.chromium.test.SampleTest',
            'method': 'testMethod1',
        },
    ]

    o._test_filters = [
        'org.chromium.test.SampleTest*testMethod1',
        'org.chromium.test.SampleTest.*'\
          '-org.chromium.test.SampleTest.testMethod2'
    ]
    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGetTests_simpleGtestUnqualifiedNameFilter(self):
    o = self.createTestInstance()
    raw_tests = [
      {
        'annotations': {'Feature': {'value': ['Foo']}},
        'class': 'org.chromium.test.SampleTest',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
          {
            'annotations': {'MediumTest': None},
            'method': 'testMethod2',
          },
        ],
      }
    ]

    expected_tests = [
      {
        'annotations': {
          'Feature': {'value': ['Foo']},
          'SmallTest': None,
        },
        'class': 'org.chromium.test.SampleTest',
        'method': 'testMethod1',
      },
    ]

    o._test_filters = ['SampleTest.testMethod1']
    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGetTests_parameterizedTestGtestFilter(self):
    o = self.createTestInstance()
    raw_tests = [
      {
        'annotations': {'Feature': {'value': ['Foo']}},
        'class': 'org.chromium.test.SampleTest',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1__sandboxed_mode',
          },
        ],
      },
      {
        'annotations': {'Feature': {'value': ['Bar']}},
        'class': 'org.chromium.test.SampleTest2',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
        ],
      }
    ]

    expected_tests = [
      {
        'annotations': {
          'Feature': {'value': ['Foo']},
          'SmallTest': None,
        },
        'class': 'org.chromium.test.SampleTest',
        'method': 'testMethod1',
      },
      {
        'annotations': {
          'Feature': {'value': ['Foo']},
          'SmallTest': None,
        },
        'class': 'org.chromium.test.SampleTest',
        'method': 'testMethod1__sandboxed_mode',
      },
    ]

    o._junit4_runner_class = 'J4Runner'
    o._test_filters = ['org.chromium.test.SampleTest.testMethod1']
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGetTests_wildcardGtestFilter(self):
    o = self.createTestInstance()
    raw_tests = [
      {
        'annotations': {'Feature': {'value': ['Foo']}},
        'class': 'org.chromium.test.SampleTest',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
          {
            'annotations': {'MediumTest': None},
            'method': 'testMethod2',
          },
        ],
      },
      {
        'annotations': {'Feature': {'value': ['Bar']}},
        'class': 'org.chromium.test.SampleTest2',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
        ],
      }
    ]

    expected_tests = [
      {
        'annotations': {
          'Feature': {'value': ['Bar']},
          'SmallTest': None,
        },
        'class': 'org.chromium.test.SampleTest2',
        'method': 'testMethod1',
      },
    ]

    o._test_filters = ['org.chromium.test.SampleTest2.*']
    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGetTests_negativeGtestFilter(self):
    o = self.createTestInstance()
    raw_tests = [
      {
        'annotations': {'Feature': {'value': ['Foo']}},
        'class': 'org.chromium.test.SampleTest',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
          {
            'annotations': {'MediumTest': None},
            'method': 'testMethod2',
          },
        ],
      },
      {
        'annotations': {'Feature': {'value': ['Bar']}},
        'class': 'org.chromium.test.SampleTest2',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
        ],
      }
    ]

    expected_tests = [
      {
        'annotations': {
          'Feature': {'value': ['Foo']},
          'MediumTest': None,
        },
        'class': 'org.chromium.test.SampleTest',
        'method': 'testMethod2',
      },
      {
        'annotations': {
          'Feature': {'value': ['Bar']},
          'SmallTest': None,
        },
        'class': 'org.chromium.test.SampleTest2',
        'method': 'testMethod1',
      },
    ]

    o._test_filters = ['*-org.chromium.test.SampleTest.testMethod1']
    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGetTests_annotationFilter(self):
    o = self.createTestInstance()
    raw_tests = [
      {
        'annotations': {'Feature': {'value': ['Foo']}},
        'class': 'org.chromium.test.SampleTest',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
          {
            'annotations': {'MediumTest': None},
            'method': 'testMethod2',
          },
        ],
      },
      {
        'annotations': {'Feature': {'value': ['Bar']}},
        'class': 'org.chromium.test.SampleTest2',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
        ],
      }
    ]

    expected_tests = [
      {
        'annotations': {
          'Feature': {'value': ['Foo']},
          'SmallTest': None,
        },
        'class': 'org.chromium.test.SampleTest',
        'method': 'testMethod1',
      },
      {
        'annotations': {
          'Feature': {'value': ['Bar']},
          'SmallTest': None,
        },
        'class': 'org.chromium.test.SampleTest2',
        'method': 'testMethod1',
      },
    ]

    o._annotations = [('SmallTest', None)]
    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGetTests_excludedAnnotationFilter(self):
    o = self.createTestInstance()
    raw_tests = [
      {
        'annotations': {'Feature': {'value': ['Foo']}},
        'class': 'org.chromium.test.SampleTest',
        'superclass': 'junit.framework.TestCase',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
          {
            'annotations': {'MediumTest': None},
            'method': 'testMethod2',
          },
        ],
      },
      {
        'annotations': {'Feature': {'value': ['Bar']}},
        'class': 'org.chromium.test.SampleTest2',
        'superclass': 'junit.framework.TestCase',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
        ],
      }
    ]

    expected_tests = [
        {
            'annotations': {
                'Feature': {
                    'value': ['Foo']
                },
                'MediumTest': None,
            },
            'class': 'org.chromium.test.SampleTest',
            'method': 'testMethod2',
        },
    ]

    o._excluded_annotations = [('SmallTest', None)]
    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGetTests_excludedDoNotReviveAnnotation(self):
    o = self.createTestInstance()
    raw_tests = [{
        'annotations': {
            'Feature': {
                'value': ['Foo']
            }
        },
        'class':
        'org.chromium.test.SampleTest',
        'superclass':
        'junit.framework.TestCase',
        'methods': [
            {
                'annotations': {
                    'DisabledTest': None,
                    'DoNotRevive': {
                        'reason': 'sample reason'
                    },
                },
                'method': 'testMethod1',
            },
            {
                'annotations': {
                    'FlakyTest': None,
                },
                'method': 'testMethod2',
            },
        ],
    }, {
        'annotations': {
            'Feature': {
                'value': ['Bar']
            }
        },
        'class':
        'org.chromium.test.SampleTest2',
        'superclass':
        'junit.framework.TestCase',
        'methods': [
            {
                'annotations': {
                    'FlakyTest': None,
                    'DoNotRevive': {
                        'reason': 'sample reason'
                    },
                },
                'method': 'testMethod1',
            },
        ],
    }, {
        'annotations': {
            'Feature': {
                'value': ['Baz']
            }
        },
        'class':
        'org.chromium.test.SampleTest3',
        'superclass':
        'junit.framework.TestCase',
        'methods': [
            {
                'annotations': {
                    'FlakyTest': None,
                    'Manual': {
                        'message': 'sample message'
                    },
                },
                'method': 'testMethod1',
            },
        ],
    }]

    expected_tests = [
        {
            'annotations': {
                'Feature': {
                    'value': ['Foo']
                },
                'FlakyTest': None,
            },
            'class': 'org.chromium.test.SampleTest',
            'method': 'testMethod2',
        },
    ]

    o._excluded_annotations = [('DoNotRevive', None), ('Manual', None)]
    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGetTests_annotationSimpleValueFilter(self):
    o = self.createTestInstance()
    raw_tests = [
      {
        'annotations': {'Feature': {'value': ['Foo']}},
        'class': 'org.chromium.test.SampleTest',
        'superclass': 'junit.framework.TestCase',
        'methods': [
          {
            'annotations': {
              'SmallTest': None,
              'TestValue': '1',
            },
            'method': 'testMethod1',
          },
          {
            'annotations': {
              'MediumTest': None,
              'TestValue': '2',
            },
            'method': 'testMethod2',
          },
        ],
      },
      {
        'annotations': {'Feature': {'value': ['Bar']}},
        'class': 'org.chromium.test.SampleTest2',
        'superclass': 'junit.framework.TestCase',
        'methods': [
          {
            'annotations': {
              'SmallTest': None,
              'TestValue': '3',
            },
            'method': 'testMethod1',
          },
        ],
      }
    ]

    expected_tests = [
        {
            'annotations': {
                'Feature': {
                    'value': ['Foo']
                },
                'SmallTest': None,
                'TestValue': '1',
            },
            'class': 'org.chromium.test.SampleTest',
            'method': 'testMethod1',
        },
    ]

    o._annotations = [('TestValue', '1')]
    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGetTests_annotationDictValueFilter(self):
    o = self.createTestInstance()
    raw_tests = [
      {
        'annotations': {'Feature': {'value': ['Foo']}},
        'class': 'org.chromium.test.SampleTest',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
          {
            'annotations': {'MediumTest': None},
            'method': 'testMethod2',
          },
        ],
      },
      {
        'annotations': {'Feature': {'value': ['Bar']}},
        'class': 'org.chromium.test.SampleTest2',
        'superclass': 'java.lang.Object',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
        ],
      }
    ]

    expected_tests = [
      {
        'annotations': {
          'Feature': {'value': ['Bar']},
          'SmallTest': None,
        },
        'class': 'org.chromium.test.SampleTest2',
        'method': 'testMethod1',
      },
    ]

    o._annotations = [('Feature', 'Bar')]
    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGetTestName(self):
    test = {
      'annotations': {
        'RunWith': {'value': 'class J4Runner'},
        'SmallTest': {},
        'Test': {'expected': 'class org.junit.Test$None',
                 'timeout': '0'},
                 'UiThreadTest': {}},
      'class': 'org.chromium.TestA',
      'method': 'testSimple'}
    unqualified_class_test = {
      'class': test['class'].split('.')[-1],
      'method': test['method']
    }

    self.assertEqual(instrumentation_test_instance.GetTestName(test, sep='.'),
                     'org.chromium.TestA.testSimple')
    self.assertEqual(
        instrumentation_test_instance.GetTestName(unqualified_class_test,
                                                  sep='.'), 'TestA.testSimple')

  def testGetUniqueTestName(self):
    test = {
      'annotations': {
        'RunWith': {'value': 'class J4Runner'},
        'SmallTest': {},
        'Test': {'expected': 'class org.junit.Test$None', 'timeout': '0'},
                 'UiThreadTest': {}},
      'class': 'org.chromium.TestA',
      'flags': ['enable_features=abc'],
      'method': 'testSimple'}
    self.assertEqual(
        instrumentation_test_instance.GetUniqueTestName(test, sep='.'),
        'org.chromium.TestA.testSimple_with_enable_features=abc')

  def testGetTestNameWithoutParameterSuffix(self):
    test = {
      'annotations': {
        'RunWith': {'value': 'class J4Runner'},
        'SmallTest': {},
        'Test': {'expected': 'class org.junit.Test$None', 'timeout': '0'},
                 'UiThreadTest': {}},
      'class': 'org.chromium.TestA__sandbox_mode',
      'flags': 'enable_features=abc',
      'method': 'testSimple'}
    unqualified_class_test = {
      'class': test['class'].split('.')[-1],
      'method': test['method']
    }
    self.assertEqual(
        instrumentation_test_instance.GetTestNameWithoutParameterSuffix(
            test, sep='.'), 'org.chromium.TestA')
    self.assertEqual(
        instrumentation_test_instance.GetTestNameWithoutParameterSuffix(
            unqualified_class_test, sep='.'), 'TestA')

  def testGetTests_multipleAnnotationValuesRequested(self):
    o = self.createTestInstance()
    raw_tests = [
      {
        'annotations': {'Feature': {'value': ['Foo']}},
        'class': 'org.chromium.test.SampleTest',
        'superclass': 'junit.framework.TestCase',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
          {
            'annotations': {
              'Feature': {'value': ['Baz']},
              'MediumTest': None,
            },
            'method': 'testMethod2',
          },
        ],
      },
      {
        'annotations': {'Feature': {'value': ['Bar']}},
        'class': 'org.chromium.test.SampleTest2',
        'superclass': 'junit.framework.TestCase',
        'methods': [
          {
            'annotations': {'SmallTest': None},
            'method': 'testMethod1',
          },
        ],
      }
    ]

    expected_tests = [
        {
            'annotations': {
                'Feature': {
                    'value': ['Baz']
                },
                'MediumTest': None,
            },
            'class': 'org.chromium.test.SampleTest',
            'method': 'testMethod2',
        },
        {
            'annotations': {
                'Feature': {
                    'value': ['Bar']
                },
                'SmallTest': None,
            },
            'class': 'org.chromium.test.SampleTest2',
            'method': 'testMethod1',
        },
    ]

    o._annotations = [('Feature', 'Bar'), ('Feature', 'Baz')]
    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)

    self.assertEqual(actual_tests, expected_tests)

  def testGenerateTestResults_noStatus(self):
    results = instrumentation_test_instance.GenerateTestResults(
        None, None, [], 1000, None, None)
    self.assertEqual([], results)

  def testGenerateTestResults_testPassed(self):
    statuses = [
      (1, {
        'class': 'test.package.TestClass',
        'test': 'testMethod',
      }),
      (0, {
        'class': 'test.package.TestClass',
        'test': 'testMethod',
      }),
    ]
    results = instrumentation_test_instance.GenerateTestResults(
        None, None, statuses, 1000, None, None)
    self.assertEqual(1, len(results))
    self.assertEqual(base_test_result.ResultType.PASS, results[0].GetType())

  def testGenerateTestResults_testFailed(self):
    statuses = [
        (1, {
            'class': 'test.package.TestClass',
            'test': 'testMethod',
        }),
        (-2, {
            'class': 'test.package.TestClass',
            'test': 'testMethod',
        }),
    ]
    results = instrumentation_test_instance.GenerateTestResults(
        None, None, statuses, 1000, None, None)
    self.assertEqual(1, len(results))
    self.assertEqual(base_test_result.ResultType.FAIL, results[0].GetType())

  def testGenerateTestResults_testUnknownException(self):
    stacktrace = 'long\nstacktrace'
    statuses = [
        (1, {
            'class': 'test.package.TestClass',
            'test': 'testMethod',
        }),
        (-1, {
            'class': 'test.package.TestClass',
            'test': 'testMethod',
            'stack': stacktrace,
        }),
    ]
    results = instrumentation_test_instance.GenerateTestResults(
        None, None, statuses, 1000, None, None)
    self.assertEqual(1, len(results))
    self.assertEqual(base_test_result.ResultType.FAIL, results[0].GetType())
    self.assertEqual(stacktrace, results[0].GetLog())

  def testGenerateTestResults_testSkipped_true(self):
    statuses = [
        (1, {
            'class': 'test.package.TestClass',
            'test': 'testMethod',
        }),
        (-3, {
            'class': 'test.package.TestClass',
            'test': 'testMethod',
        }),
    ]
    results = instrumentation_test_instance.GenerateTestResults(
        None, None, statuses, 1000, None, None)
    self.assertEqual(1, len(results))
    self.assertEqual(base_test_result.ResultType.SKIP, results[0].GetType())

  def testGenerateTestResults_beforeClassFailure(self):
    stacktrace = 'long\nstacktrace'
    statuses = [
        (1, {
            'class': 'test.package.TestClass',
            'test': 'null',
        }),
        (-2, {
            'class': 'test.package.TestClass',
            'test': 'null',
            'stack': stacktrace,
        }),
        (1, {
            'class': 'test.package.TestClass',
            'test': 'testMethod1',
        }),
        (0, {
            'class': 'test.package.TestClass',
            'test': 'testMethod1',
        }),
        (1, {
            'class': 'test.package.TestClass',
            'test': 'testMethod2',
        }),
        (0, {
            'class': 'test.package.TestClass',
            'test': 'testMethod2',
        }),
    ]
    results = instrumentation_test_instance.GenerateTestResults(
        None, None, statuses, 1000, None, None)
    self.assertEqual(2, len(results))
    self.assertEqual(base_test_result.ResultType.FAIL, results[0].GetType())
    self.assertEqual(base_test_result.ResultType.FAIL, results[1].GetType())
    self.assertEqual(stacktrace, results[0].GetLog())
    self.assertEqual(stacktrace, results[1].GetLog())

  def testGenerateTestResults_afterClassFailure(self):
    stacktrace = 'long\nstacktrace'
    statuses = [
        (1, {
            'class': 'test.package.TestClass',
            'test': 'testMethod1',
        }),
        (0, {
            'class': 'test.package.TestClass',
            'test': 'testMethod1',
        }),
        (1, {
            'class': 'test.package.TestClass',
            'test': 'testMethod2',
        }),
        (-3, {
            'class': 'test.package.TestClass',
            'test': 'testMethod2',
        }),
        (1, {
            'class': 'test.package.TestClass',
            'test': 'null',
        }),
        (-2, {
            'class': 'test.package.TestClass',
            'test': 'null',
            'stack': stacktrace,
        }),
    ]
    results = instrumentation_test_instance.GenerateTestResults(
        None, None, statuses, 1000, None, None)
    self.assertEqual(2, len(results))
    self.assertEqual(base_test_result.ResultType.FAIL, results[0].GetType())
    self.assertEqual(base_test_result.ResultType.SKIP, results[1].GetType())
    self.assertEqual(stacktrace, results[0].GetLog())

  def testParameterizedCommandLineFlagsSwitches(self):
    o = self.createTestInstance()
    raw_tests = [{
        'annotations': {
            'ParameterizedCommandLineFlags$Switches': {
                'value': ['enable-features=abc', 'enable-features=def']
            }
        },
        'class':
        'org.chromium.test.SampleTest',
        'superclass':
        'java.lang.Object',
        'methods': [
            {
                'annotations': {
                    'SmallTest': None
                },
                'method': 'testMethod1',
            },
            {
                'annotations': {
                    'MediumTest': None,
                    'ParameterizedCommandLineFlags$Switches': {
                        'value': ['enable-features=ghi', 'enable-features=jkl']
                    },
                },
                'method': 'testMethod2',
            },
            {
                'annotations': {
                    'MediumTest': None,
                    'ParameterizedCommandLineFlags$Switches': {
                        'value': []
                    },
                },
                'method': 'testMethod3',
            },
            {
                'annotations': {
                    'MediumTest': None,
                    'SkipCommandLineParameterization': None,
                },
                'method': 'testMethod4',
            },
        ],
    }]

    expected_tests = [
        {
            'annotations': {},
            'class': 'org.chromium.test.SampleTest',
            'flags': ['--enable-features=abc', '--enable-features=def'],
            'method': 'testMethod1'
        },
        {
            'annotations': {},
            'class': 'org.chromium.test.SampleTest',
            'flags': ['--enable-features=ghi', '--enable-features=jkl'],
            'method': 'testMethod2'
        },
        {
            'annotations': {},
            'class': 'org.chromium.test.SampleTest',
            'method': 'testMethod3'
        },
        {
            'annotations': {},
            'class': 'org.chromium.test.SampleTest',
            'method': 'testMethod4'
        },
    ]
    for i in range(4):
      expected_tests[i]['annotations'].update(raw_tests[0]['annotations'])
      expected_tests[i]['annotations'].update(
          raw_tests[0]['methods'][i]['annotations'])

    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)
    self.assertEqual(actual_tests, expected_tests)

  def testParameterizedCommandLineFlags(self):
    o = self.createTestInstance()
    raw_tests = [{
        'annotations': {
            'ParameterizedCommandLineFlags': {
                'value': [
                    {
                        'ParameterizedCommandLineFlags$Switches': {
                            'value': [
                                'enable-features=abc',
                                'force-fieldtrials=trial/group'
                            ],
                        }
                    },
                    {
                        'ParameterizedCommandLineFlags$Switches': {
                            'value': [
                                'enable-features=abc2',
                                'force-fieldtrials=trial/group2'
                            ],
                        }
                    },
                ],
            },
        },
        'class':
        'org.chromium.test.SampleTest',
        'superclass':
        'java.lang.Object',
        'methods': [
            {
                'annotations': {
                    'SmallTest': None
                },
                'method': 'testMethod1',
            },
            {
                'annotations': {
                    'MediumTest': None,
                    'ParameterizedCommandLineFlags': {
                        'value': [{
                            'ParameterizedCommandLineFlags$Switches': {
                                'value': ['enable-features=def']
                            }
                        }],
                    },
                },
                'method': 'testMethod2',
            },
            {
                'annotations': {
                    'MediumTest': None,
                    'ParameterizedCommandLineFlags': {
                        'value': [],
                    },
                },
                'method': 'testMethod3',
            },
            {
                'annotations': {
                    'MediumTest': None,
                    'SkipCommandLineParameterization': None,
                },
                'method': 'testMethod4',
            },
        ],
    }]

    expected_tests = [
        {
            'annotations': {},
            'class': 'org.chromium.test.SampleTest',
            'flags':
            ['--enable-features=abc', '--force-fieldtrials=trial/group'],
            'method': 'testMethod1'
        },
        {
            'annotations': {},
            'class': 'org.chromium.test.SampleTest',
            'flags': ['--enable-features=def'],
            'method': 'testMethod2'
        },
        {
            'annotations': {},
            'class': 'org.chromium.test.SampleTest',
            'method': 'testMethod3'
        },
        {
            'annotations': {},
            'class': 'org.chromium.test.SampleTest',
            'method': 'testMethod4'
        },
        {
            'annotations': {},
            'class':
            'org.chromium.test.SampleTest',
            'flags': [
                '--enable-features=abc2',
                '--force-fieldtrials=trial/group2',
            ],
            'method':
            'testMethod1'
        },
    ]
    for i in range(4):
      expected_tests[i]['annotations'].update(raw_tests[0]['annotations'])
      expected_tests[i]['annotations'].update(
          raw_tests[0]['methods'][i]['annotations'])
    expected_tests[4]['annotations'].update(raw_tests[0]['annotations'])
    expected_tests[4]['annotations'].update(
        raw_tests[0]['methods'][0]['annotations'])

    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)
    self.assertEqual(actual_tests, expected_tests)

  def testDifferentCommandLineParameterizations(self):
    o = self.createTestInstance()
    raw_tests = [{
        'annotations': {},
        'class':
        'org.chromium.test.SampleTest',
        'superclass':
        'java.lang.Object',
        'methods': [
            {
                'annotations': {
                    'SmallTest': None,
                    'ParameterizedCommandLineFlags': {
                        'value': [
                            {
                                'ParameterizedCommandLineFlags$Switches': {
                                    'value': ['a1', 'a2'],
                                }
                            },
                        ],
                    },
                },
                'method': 'testMethod2',
            },
            {
                'annotations': {
                    'SmallTest': None,
                    'ParameterizedCommandLineFlags$Switches': {
                        'value': ['b1', 'b2'],
                    },
                },
                'method': 'testMethod3',
            },
        ],
    }]

    expected_tests = [
        {
            'annotations': {},
            'class': 'org.chromium.test.SampleTest',
            'flags': ['--a1', '--a2'],
            'method': 'testMethod2'
        },
        {
            'annotations': {},
            'class': 'org.chromium.test.SampleTest',
            'flags': ['--b1', '--b2'],
            'method': 'testMethod3'
        },
    ]
    for i in range(2):
      expected_tests[i]['annotations'].update(
          raw_tests[0]['methods'][i]['annotations'])

    o._junit4_runner_class = 'J4Runner'
    actual_tests = o.ProcessRawTests(raw_tests)
    self.assertEqual(actual_tests, expected_tests)

  def testMultipleCommandLineParameterizations_raises(self):
    o = self.createTestInstance()
    raw_tests = [
        {
            'annotations': {
                'ParameterizedCommandLineFlags': {
                    'value': [
                        {
                            'ParameterizedCommandLineFlags$Switches': {
                                'value': [
                                    'enable-features=abc',
                                    'force-fieldtrials=trial/group',
                                ],
                            }
                        },
                    ],
                },
            },
            'class':
            'org.chromium.test.SampleTest',
            'superclass':
            'java.lang.Object',
            'methods': [
                {
                    'annotations': {
                        'SmallTest': None,
                        'ParameterizedCommandLineFlags$Switches': {
                            'value': [
                                'enable-features=abc',
                                'force-fieldtrials=trial/group',
                            ],
                        },
                    },
                    'method': 'testMethod1',
                },
            ],
        },
    ]

    o._junit4_runner_class = 'J4Runner'
    self.assertRaises(
        instrumentation_test_instance.CommandLineParameterizationException,
        o.ProcessRawTests, [raw_tests[0]])


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