#!/usr/bin/python # Copyright 2016 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Unittests for test_runner.py.""" import collections import json import os import sys import unittest import test_runner class TestCase(unittest.TestCase): """Test case which supports installing mocks. Uninstalls on tear down.""" def __init__(self, *args, **kwargs): """Initializes a new instance of this class.""" super(TestCase, self).__init__(*args, **kwargs) # Maps object to a dict which maps names of mocked members to their # original values. self._mocks = collections.OrderedDict() def mock(self, obj, member, mock): """Installs mock in place of the named member of the given obj. Args: obj: Any object. member: String naming the attribute of the object to mock. mock: The mock to install. """ self._mocks.setdefault(obj, collections.OrderedDict()).setdefault( member, getattr(obj, member)) setattr(obj, member, mock) def tearDown(self, *args, **kwargs): """Uninstalls mocks.""" super(TestCase, self).tearDown(*args, **kwargs) for obj in self._mocks: for member, original_value in self._mocks[obj].iteritems(): setattr(obj, member, original_value) class GetKIFTestFilterTest(TestCase): """Tests for test_runner.get_kif_test_filter.""" def test_correct(self): """Ensures correctness of filter.""" tests = [ 'KIF.test1', 'KIF.test2', ] expected = 'NAME:test1|test2' self.assertEqual(test_runner.get_kif_test_filter(tests), expected) def test_correct_inverted(self): """Ensures correctness of inverted filter.""" tests = [ 'KIF.test1', 'KIF.test2', ] expected = '-NAME:test1|test2' self.assertEqual( test_runner.get_kif_test_filter(tests, invert=True), expected) class GetGTestFilterTest(TestCase): """Tests for test_runner.get_gtest_filter.""" def test_correct(self): """Ensures correctness of filter.""" tests = [ 'test.1', 'test.2', ] expected = 'test.1:test.2' self.assertEqual(test_runner.get_gtest_filter(tests), expected) def test_correct_inverted(self): """Ensures correctness of inverted filter.""" tests = [ 'test.1', 'test.2', ] expected = '-test.1:test.2' self.assertEqual( test_runner.get_gtest_filter(tests, invert=True), expected) class SimulatorTestRunnerTest(TestCase): """Tests for test_runner.SimulatorTestRunner.""" def test_app_not_found(self): """Ensures AppNotFoundError is raised.""" def exists(path): if path == 'fake-app': return False return True def find_xcode(version): return {'found': True} def check_output(command): return 'fake-bundle-id' self.mock(test_runner.os.path, 'exists', exists) self.mock(test_runner.find_xcode, 'find_xcode', find_xcode) self.mock(test_runner.subprocess, 'check_output', check_output) self.assertRaises( test_runner.AppNotFoundError, test_runner.SimulatorTestRunner, 'fake-app', 'fake-iossim', 'platform', 'os', 'xcode-version', 'out-dir', ) def test_iossim_not_found(self): """Ensures SimulatorNotFoundError is raised.""" def exists(path): if path == 'fake-iossim': return False return True def find_xcode(version): return {'found': True} def check_output(command): return 'fake-bundle-id' self.mock(test_runner.os.path, 'exists', exists) self.mock(test_runner.find_xcode, 'find_xcode', find_xcode) self.mock(test_runner.subprocess, 'check_output', check_output) self.assertRaises( test_runner.SimulatorNotFoundError, test_runner.SimulatorTestRunner, 'fake-app', 'fake-iossim', 'platform', 'os', 'xcode-version', 'out-dir', ) def test_init(self): """Ensures instance is created.""" def exists(path): return True def find_xcode(version): return {'found': True} def check_output(command): return 'fake-bundle-id' self.mock(test_runner.os.path, 'exists', exists) self.mock(test_runner.find_xcode, 'find_xcode', find_xcode) self.mock(test_runner.subprocess, 'check_output', check_output) tr = test_runner.SimulatorTestRunner( 'fake-app', 'fake-iossim', 'platform', 'os', 'xcode-version', 'out-dir', ) self.failUnless(tr) def test_startup_crash(self): """Ensures test is relaunched once on startup crash.""" def exists(path): return True def find_xcode(version): return {'found': True} def check_output(command): return 'fake-bundle-id' def set_up(self): return @staticmethod def _run(command): return collections.namedtuple('result', ['crashed', 'crashed_test'])( crashed=True, crashed_test=None) def tear_down(self): return self.mock(test_runner.os.path, 'exists', exists) self.mock(test_runner.find_xcode, 'find_xcode', find_xcode) self.mock(test_runner.subprocess, 'check_output', check_output) self.mock(test_runner.SimulatorTestRunner, 'set_up', set_up) self.mock(test_runner.TestRunner, '_run', _run) self.mock(test_runner.SimulatorTestRunner, 'tear_down', tear_down) tr = test_runner.SimulatorTestRunner( 'fake-app', 'fake-iossim', 'platform', 'os', 'xcode-version', 'out-dir', ) self.assertRaises(test_runner.AppLaunchError, tr.launch) def test_relaunch(self): """Ensures test is relaunched on test crash until tests complete.""" def exists(path): return True def find_xcode(version): return {'found': True} def check_output(command): return 'fake-bundle-id' def set_up(self): return @staticmethod def _run(command): result = collections.namedtuple( 'result', [ 'crashed', 'crashed_test', 'failed_tests', 'flaked_tests', 'passed_tests', ], ) if '-e' not in command: # First run, has no test filter supplied. Mock a crash. return result( crashed=True, crashed_test='c', failed_tests={'b': ['b-out'], 'c': ['Did not complete.']}, flaked_tests={'d': ['d-out']}, passed_tests=['a'], ) else: return result( crashed=False, crashed_test=None, failed_tests={}, flaked_tests={}, passed_tests=[], ) def tear_down(self): return self.mock(test_runner.os.path, 'exists', exists) self.mock(test_runner.find_xcode, 'find_xcode', find_xcode) self.mock(test_runner.subprocess, 'check_output', check_output) self.mock(test_runner.SimulatorTestRunner, 'set_up', set_up) self.mock(test_runner.TestRunner, '_run', _run) self.mock(test_runner.SimulatorTestRunner, 'tear_down', tear_down) tr = test_runner.SimulatorTestRunner( 'fake-app', 'fake-iossim', 'platform', 'os', 'xcode-version', 'out-dir', ) tr.launch() self.failUnless(tr.logs) if __name__ == '__main__': unittest.main()