1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#!/usr/bin/env python 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# 3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Copyright 2006, Google Inc. 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# All rights reserved. 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Redistribution and use in source and binary forms, with or without 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# modification, are permitted provided that the following conditions are 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# met: 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# * Redistributions of source code must retain the above copyright 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# notice, this list of conditions and the following disclaimer. 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# * Redistributions in binary form must reproduce the above 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# copyright notice, this list of conditions and the following disclaimer 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# in the documentation and/or other materials provided with the 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# distribution. 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# * Neither the name of Google Inc. nor the names of its 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# contributors may be used to endorse or promote products derived from 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# this software without specific prior written permission. 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville"""Unit test for Google Test's break-on-failure mode. 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleA user can ask Google Test to seg-fault when an assertion fails, using 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleeither the GTEST_BREAK_ON_FAILURE environment variable or the 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville--gtest_break_on_failure flag. This script tests such functionality 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleby invoking gtest_break_on_failure_unittest_ (a program written with 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGoogle Test) with different environments and command line flags. 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville""" 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville__author__ = 'wan@google.com (Zhanyong Wan)' 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport gtest_test_utils 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport os 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport sys 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Constants. 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleIS_WINDOWS = os.name == 'nt' 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# The environment variable for enabling/disabling the break-on-failure mode. 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleBREAK_ON_FAILURE_ENV_VAR = 'GTEST_BREAK_ON_FAILURE' 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# The command line flag for enabling/disabling the break-on-failure mode. 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleBREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure' 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# The environment variable for enabling/disabling the throw-on-failure mode. 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTHROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE' 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# The environment variable for enabling/disabling the catch-exceptions mode. 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCATCH_EXCEPTIONS_ENV_VAR = 'GTEST_CATCH_EXCEPTIONS' 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Path to the gtest_break_on_failure_unittest_ program. 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleEXE_PATH = gtest_test_utils.GetTestExecutablePath( 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 'gtest_break_on_failure_unittest_') 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Utilities. 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef SetEnvVar(env_var, value): 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Sets an environment variable to a given value; unsets it when the 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville given value is None. 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if value is not None: 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville os.environ[env_var] = value 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville elif env_var in os.environ: 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville del os.environ[env_var] 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef Run(command): 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise.""" 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville p = gtest_test_utils.Subprocess(command) 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if p.terminated_by_signal: 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 1 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville else: 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 0 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# The tests. 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass GTestBreakOnFailureUnitTest(gtest_test_utils.TestCase): 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Tests using the GTEST_BREAK_ON_FAILURE environment variable or 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville the --gtest_break_on_failure flag to turn assertion failures into 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville segmentation faults. 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def RunAndVerify(self, env_var_value, flag_value, expect_seg_fault): 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Runs gtest_break_on_failure_unittest_ and verifies that it does 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (or does not) have a seg-fault. 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville env_var_value: value of the GTEST_BREAK_ON_FAILURE environment 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville variable; None if the variable should be unset. 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag_value: value of the --gtest_break_on_failure flag; 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville None if the flag should not be present. 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville expect_seg_fault: 1 if the program is expected to generate a seg-fault; 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 0 otherwise. 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, env_var_value) 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if env_var_value is None: 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville env_var_value_msg = ' is not set' 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville else: 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville env_var_value_msg = '=' + env_var_value 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if flag_value is None: 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag = '' 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville elif flag_value == '0': 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag = '--%s=0' % BREAK_ON_FAILURE_FLAG 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville else: 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag = '--%s' % BREAK_ON_FAILURE_FLAG 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville command = [EXE_PATH] 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if flag: 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville command.append(flag) 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if expect_seg_fault: 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville should_or_not = 'should' 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville else: 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville should_or_not = 'should not' 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville has_seg_fault = Run(command) 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, None) 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville msg = ('when %s%s, an assertion failure in "%s" %s cause a seg-fault.' % 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, ' '.join(command), 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville should_or_not)) 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self.assert_(has_seg_fault == expect_seg_fault, msg) 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def testDefaultBehavior(self): 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Tests the behavior of the default mode.""" 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self.RunAndVerify(env_var_value=None, 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag_value=None, 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville expect_seg_fault=0) 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def testEnvVar(self): 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Tests using the GTEST_BREAK_ON_FAILURE environment variable.""" 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self.RunAndVerify(env_var_value='0', 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag_value=None, 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville expect_seg_fault=0) 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self.RunAndVerify(env_var_value='1', 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag_value=None, 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville expect_seg_fault=1) 163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def testFlag(self): 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Tests using the --gtest_break_on_failure flag.""" 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self.RunAndVerify(env_var_value=None, 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag_value='0', 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville expect_seg_fault=0) 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self.RunAndVerify(env_var_value=None, 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag_value='1', 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville expect_seg_fault=1) 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def testFlagOverridesEnvVar(self): 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Tests that the flag overrides the environment variable.""" 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self.RunAndVerify(env_var_value='0', 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag_value='0', 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville expect_seg_fault=0) 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self.RunAndVerify(env_var_value='0', 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag_value='1', 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville expect_seg_fault=1) 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self.RunAndVerify(env_var_value='1', 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag_value='0', 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville expect_seg_fault=0) 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self.RunAndVerify(env_var_value='1', 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag_value='1', 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville expect_seg_fault=1) 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def testBreakOnFailureOverridesThrowOnFailure(self): 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Tests that gtest_break_on_failure overrides gtest_throw_on_failure.""" 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetEnvVar(THROW_ON_FAILURE_ENV_VAR, '1') 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville try: 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self.RunAndVerify(env_var_value=None, 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag_value='1', 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville expect_seg_fault=1) 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville finally: 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetEnvVar(THROW_ON_FAILURE_ENV_VAR, None) 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if IS_WINDOWS: 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def testCatchExceptionsDoesNotInterfere(self): 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Tests that gtest_catch_exceptions doesn't interfere.""" 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, '1') 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville try: 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self.RunAndVerify(env_var_value='1', 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville flag_value='1', 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville expect_seg_fault=1) 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville finally: 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, None) 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleif __name__ == '__main__': 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville gtest_test_utils.Main() 216