199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest lldb process launch flags.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprechtfrom __future__ import print_function
699451b44SJordan Rupprecht
799451b44SJordan Rupprechtimport os
899451b44SJordan Rupprecht
999451b44SJordan Rupprechtimport lldb
1099451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
1199451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1299451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
1399451b44SJordan Rupprecht
1499451b44SJordan Rupprechtimport six
1599451b44SJordan Rupprecht
1699451b44SJordan Rupprecht
1799451b44SJordan Rupprechtclass ProcessLaunchTestCase(TestBase):
1899451b44SJordan Rupprecht    NO_DEBUG_INFO_TESTCASE = True
1999451b44SJordan Rupprecht
2099451b44SJordan Rupprecht    def setUp(self):
2199451b44SJordan Rupprecht        # Call super's setUp().
2299451b44SJordan Rupprecht        TestBase.setUp(self)
2399451b44SJordan Rupprecht        self.runCmd("settings set auto-confirm true")
2499451b44SJordan Rupprecht
2599451b44SJordan Rupprecht    def tearDown(self):
2699451b44SJordan Rupprecht        self.runCmd("settings clear auto-confirm")
2799451b44SJordan Rupprecht        TestBase.tearDown(self)
2899451b44SJordan Rupprecht
2966ae40ebSRaphael Isemann    @skipIfRemote
3099451b44SJordan Rupprecht    def test_io(self):
3199451b44SJordan Rupprecht        """Test that process launch I/O redirection flags work properly."""
3299451b44SJordan Rupprecht        self.build()
3399451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
3499451b44SJordan Rupprecht        self.expect("file " + exe,
3599451b44SJordan Rupprecht                    patterns=["Current executable set to .*a.out"])
3699451b44SJordan Rupprecht
3799451b44SJordan Rupprecht        in_file = os.path.join(self.getSourceDir(), "input-file.txt")
3899451b44SJordan Rupprecht        out_file = lldbutil.append_to_process_working_directory(self, "output-test.out")
3999451b44SJordan Rupprecht        err_file = lldbutil.append_to_process_working_directory(self, "output-test.err")
4099451b44SJordan Rupprecht
4199451b44SJordan Rupprecht        # Make sure the output files do not exist before launching the process
4299451b44SJordan Rupprecht        try:
4399451b44SJordan Rupprecht            os.remove(out_file)
4499451b44SJordan Rupprecht        except OSError:
4599451b44SJordan Rupprecht            pass
4699451b44SJordan Rupprecht
4799451b44SJordan Rupprecht        try:
4899451b44SJordan Rupprecht            os.remove(err_file)
4999451b44SJordan Rupprecht        except OSError:
5099451b44SJordan Rupprecht            pass
5199451b44SJordan Rupprecht
5299451b44SJordan Rupprecht        launch_command = "process launch -i '{0}' -o '{1}' -e '{2}' -w '{3}'".format(
5399451b44SJordan Rupprecht                in_file, out_file, err_file, self.get_process_working_directory())
5499451b44SJordan Rupprecht
5599451b44SJordan Rupprecht        if lldb.remote_platform:
5699451b44SJordan Rupprecht            self.runCmd('platform put-file "{local}" "{remote}"'.format(
5799451b44SJordan Rupprecht                local=in_file, remote=in_file))
5899451b44SJordan Rupprecht
5999451b44SJordan Rupprecht        self.expect(launch_command,
6099451b44SJordan Rupprecht                    patterns=["Process .* launched: .*a.out"])
6199451b44SJordan Rupprecht
6299451b44SJordan Rupprecht        success = True
6399451b44SJordan Rupprecht        err_msg = ""
6499451b44SJordan Rupprecht
6599451b44SJordan Rupprecht        out = lldbutil.read_file_on_target(self, out_file)
6699451b44SJordan Rupprecht        if out != "This should go to stdout.\n":
6799451b44SJordan Rupprecht            success = False
6899451b44SJordan Rupprecht            err_msg = err_msg + "    ERROR: stdout file does not contain correct output.\n"
6999451b44SJordan Rupprecht
7099451b44SJordan Rupprecht
7199451b44SJordan Rupprecht        err = lldbutil.read_file_on_target(self, err_file)
7299451b44SJordan Rupprecht        if err != "This should go to stderr.\n":
7399451b44SJordan Rupprecht            success = False
7499451b44SJordan Rupprecht            err_msg = err_msg + "    ERROR: stderr file does not contain correct output.\n"
7599451b44SJordan Rupprecht
7699451b44SJordan Rupprecht        if not success:
7799451b44SJordan Rupprecht            self.fail(err_msg)
7899451b44SJordan Rupprecht
7999451b44SJordan Rupprecht    # rdar://problem/9056462
8099451b44SJordan Rupprecht    # The process launch flag '-w' for setting the current working directory
8199451b44SJordan Rupprecht    # not working?
8266ae40ebSRaphael Isemann    @skipIfRemote
8398257c30SMichał Górny    @expectedFailureAll(oslist=["freebsd", "linux"], bugnumber="llvm.org/pr20265")
8499451b44SJordan Rupprecht    @expectedFailureNetBSD
8599451b44SJordan Rupprecht    def test_set_working_dir_nonexisting(self):
8699451b44SJordan Rupprecht        """Test that '-w dir' fails to set the working dir when running the inferior with a dir which doesn't exist."""
8799451b44SJordan Rupprecht        d = {'CXX_SOURCES': 'print_cwd.cpp'}
8899451b44SJordan Rupprecht        self.build(dictionary=d)
8999451b44SJordan Rupprecht        self.setTearDownCleanup(d)
9099451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
9199451b44SJordan Rupprecht        self.runCmd("file " + exe)
9299451b44SJordan Rupprecht
9399451b44SJordan Rupprecht        mywd = 'my_working_dir'
9499451b44SJordan Rupprecht        out_file_name = "my_working_dir_test.out"
9599451b44SJordan Rupprecht        err_file_name = "my_working_dir_test.err"
9699451b44SJordan Rupprecht
9799451b44SJordan Rupprecht        my_working_dir_path = self.getBuildArtifact(mywd)
9899451b44SJordan Rupprecht        out_file_path = os.path.join(my_working_dir_path, out_file_name)
9999451b44SJordan Rupprecht        err_file_path = os.path.join(my_working_dir_path, err_file_name)
10099451b44SJordan Rupprecht
10199451b44SJordan Rupprecht        # Check that we get an error when we have a nonexisting path
10299451b44SJordan Rupprecht        invalid_dir_path = mywd + 'z'
10399451b44SJordan Rupprecht        launch_command = "process launch -w %s -o %s -e %s" % (
10499451b44SJordan Rupprecht            invalid_dir_path, out_file_path, err_file_path)
10599451b44SJordan Rupprecht
10699451b44SJordan Rupprecht        self.expect(
10799451b44SJordan Rupprecht            launch_command, error=True, patterns=[
10899451b44SJordan Rupprecht                "error:.* No such file or directory: %s" %
10999451b44SJordan Rupprecht                invalid_dir_path])
11099451b44SJordan Rupprecht
11166ae40ebSRaphael Isemann    @skipIfRemote
11299451b44SJordan Rupprecht    def test_set_working_dir_existing(self):
11399451b44SJordan Rupprecht        """Test that '-w dir' sets the working dir when running the inferior."""
11499451b44SJordan Rupprecht        d = {'CXX_SOURCES': 'print_cwd.cpp'}
11599451b44SJordan Rupprecht        self.build(dictionary=d)
11699451b44SJordan Rupprecht        self.setTearDownCleanup(d)
11799451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
11899451b44SJordan Rupprecht        self.runCmd("file " + exe)
11999451b44SJordan Rupprecht
12099451b44SJordan Rupprecht        mywd = 'my_working_dir'
12199451b44SJordan Rupprecht        out_file_name = "my_working_dir_test.out"
12299451b44SJordan Rupprecht        err_file_name = "my_working_dir_test.err"
12399451b44SJordan Rupprecht
12499451b44SJordan Rupprecht        my_working_dir_path = self.getBuildArtifact(mywd)
12599451b44SJordan Rupprecht        lldbutil.mkdir_p(my_working_dir_path)
12699451b44SJordan Rupprecht        out_file_path = os.path.join(my_working_dir_path, out_file_name)
12799451b44SJordan Rupprecht        err_file_path = os.path.join(my_working_dir_path, err_file_name)
12899451b44SJordan Rupprecht
12999451b44SJordan Rupprecht        # Make sure the output files do not exist before launching the process
13099451b44SJordan Rupprecht        try:
13199451b44SJordan Rupprecht            os.remove(out_file_path)
13299451b44SJordan Rupprecht            os.remove(err_file_path)
13399451b44SJordan Rupprecht        except OSError:
13499451b44SJordan Rupprecht            pass
13599451b44SJordan Rupprecht
13699451b44SJordan Rupprecht        launch_command = "process launch -w %s -o %s -e %s" % (
13799451b44SJordan Rupprecht            my_working_dir_path, out_file_path, err_file_path)
13899451b44SJordan Rupprecht
13999451b44SJordan Rupprecht        self.expect(launch_command,
14099451b44SJordan Rupprecht                    patterns=["Process .* launched: .*a.out"])
14199451b44SJordan Rupprecht
14299451b44SJordan Rupprecht        success = True
14399451b44SJordan Rupprecht        err_msg = ""
14499451b44SJordan Rupprecht
14599451b44SJordan Rupprecht        # Check to see if the 'stdout' file was created
14699451b44SJordan Rupprecht        try:
14799451b44SJordan Rupprecht            out_f = open(out_file_path)
14899451b44SJordan Rupprecht        except IOError:
14999451b44SJordan Rupprecht            success = False
15099451b44SJordan Rupprecht            err_msg = err_msg + "ERROR: stdout file was not created.\n"
15199451b44SJordan Rupprecht        else:
15299451b44SJordan Rupprecht            # Check to see if the 'stdout' file contains the right output
15399451b44SJordan Rupprecht            line = out_f.readline()
15499451b44SJordan Rupprecht            if self.TraceOn():
15599451b44SJordan Rupprecht                print("line:", line)
15699451b44SJordan Rupprecht            if not re.search(mywd, line):
15799451b44SJordan Rupprecht                success = False
15899451b44SJordan Rupprecht                err_msg = err_msg + "The current working directory was not set correctly.\n"
15999451b44SJordan Rupprecht                out_f.close()
16099451b44SJordan Rupprecht
16199451b44SJordan Rupprecht        # Try to delete the 'stdout' and 'stderr' files
16299451b44SJordan Rupprecht        try:
16399451b44SJordan Rupprecht            os.remove(out_file_path)
16499451b44SJordan Rupprecht            os.remove(err_file_path)
16599451b44SJordan Rupprecht        except OSError:
16699451b44SJordan Rupprecht            pass
16799451b44SJordan Rupprecht
16899451b44SJordan Rupprecht        if not success:
16999451b44SJordan Rupprecht            self.fail(err_msg)
17099451b44SJordan Rupprecht
17199451b44SJordan Rupprecht    def test_environment_with_special_char(self):
17299451b44SJordan Rupprecht        """Test that environment variables containing '*' and '}' are handled correctly by the inferior."""
17399451b44SJordan Rupprecht        source = 'print_env.cpp'
17499451b44SJordan Rupprecht        d = {'CXX_SOURCES': source}
17599451b44SJordan Rupprecht        self.build(dictionary=d)
17699451b44SJordan Rupprecht        self.setTearDownCleanup(d)
17799451b44SJordan Rupprecht
17899451b44SJordan Rupprecht        evil_var = 'INIT*MIDDLE}TAIL'
17999451b44SJordan Rupprecht
18054c26872SRaphael Isemann        target = self.createTestTarget()
18199451b44SJordan Rupprecht        main_source_spec = lldb.SBFileSpec(source)
18299451b44SJordan Rupprecht        breakpoint = target.BreakpointCreateBySourceRegex(
18399451b44SJordan Rupprecht            '// Set breakpoint here.', main_source_spec)
18499451b44SJordan Rupprecht
18599451b44SJordan Rupprecht        process = target.LaunchSimple(None,
18699451b44SJordan Rupprecht                                      ['EVIL=' + evil_var],
18799451b44SJordan Rupprecht                                      self.get_process_working_directory())
18899451b44SJordan Rupprecht        self.assertEqual(
18999451b44SJordan Rupprecht            process.GetState(),
19099451b44SJordan Rupprecht            lldb.eStateStopped,
19199451b44SJordan Rupprecht            PROCESS_STOPPED)
19299451b44SJordan Rupprecht
19399451b44SJordan Rupprecht        threads = lldbutil.get_threads_stopped_at_breakpoint(
19499451b44SJordan Rupprecht            process, breakpoint)
19599451b44SJordan Rupprecht        self.assertEqual(len(threads), 1)
19699451b44SJordan Rupprecht        frame = threads[0].GetFrameAtIndex(0)
19799451b44SJordan Rupprecht        sbvalue = frame.EvaluateExpression("evil")
19899451b44SJordan Rupprecht        value = sbvalue.GetSummary().strip('"')
19999451b44SJordan Rupprecht
20099451b44SJordan Rupprecht        self.assertEqual(value, evil_var)
20199451b44SJordan Rupprecht        process.Continue()
202*1b8c7352SJonas Devlieghere        self.assertState(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
203