199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTests basic Main Thread Checker support (detecting a main-thread-only violation).
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprechtimport lldb
699451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
799451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
899451b44SJordan Rupprechtimport lldbsuite.test.lldbutil as lldbutil
999451b44SJordan Rupprechtfrom lldbsuite.test.lldbplatformutil import *
1099451b44SJordan Rupprechtimport json
1199451b44SJordan Rupprecht
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprechtclass MTCSimpleTestCase(TestBase):
1499451b44SJordan Rupprecht
1599451b44SJordan Rupprecht    @skipUnlessDarwin
16*587a3979SAdrian Prantl    @skipIf(compiler="clang", compiler_version=['<', '9.0'])
1799451b44SJordan Rupprecht    def test(self):
1899451b44SJordan Rupprecht        self.mtc_dylib_path = findMainThreadCheckerDylib()
1999451b44SJordan Rupprecht        if self.mtc_dylib_path == "":
2099451b44SJordan Rupprecht            self.skipTest("This test requires libMainThreadChecker.dylib")
2199451b44SJordan Rupprecht
2299451b44SJordan Rupprecht        self.build()
2399451b44SJordan Rupprecht        self.mtc_tests()
2499451b44SJordan Rupprecht
2599451b44SJordan Rupprecht    @skipIf(archs=['i386'])
26*587a3979SAdrian Prantl    @skipIf(compiler="clang", compiler_version=['<', '9.0'])
2799451b44SJordan Rupprecht    def mtc_tests(self):
28b3a0c4d7SRaphael Isemann        self.assertNotEqual(self.mtc_dylib_path, "")
2999451b44SJordan Rupprecht
3099451b44SJordan Rupprecht        # Load the test
3199451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
3299451b44SJordan Rupprecht        self.expect("file " + exe, patterns=["Current executable set to .*a.out"])
3399451b44SJordan Rupprecht
3499451b44SJordan Rupprecht        self.runCmd("env DYLD_INSERT_LIBRARIES=%s" % self.mtc_dylib_path)
3599451b44SJordan Rupprecht        self.runCmd("run")
3699451b44SJordan Rupprecht
3799451b44SJordan Rupprecht        process = self.dbg.GetSelectedTarget().process
3899451b44SJordan Rupprecht        thread = process.GetSelectedThread()
3999451b44SJordan Rupprecht        frame = thread.GetSelectedFrame()
4099451b44SJordan Rupprecht
4199451b44SJordan Rupprecht        view = "NSView" if lldbplatformutil.getPlatform() == "macosx" else "UIView"
4299451b44SJordan Rupprecht
4399451b44SJordan Rupprecht        self.expect("thread info",
4499451b44SJordan Rupprecht                    substrs=['stop reason = -[' + view +
4599451b44SJordan Rupprecht                             ' superview] must be used from main thread only'])
4699451b44SJordan Rupprecht
4799451b44SJordan Rupprecht        self.expect(
4899451b44SJordan Rupprecht            "thread info -s",
4999451b44SJordan Rupprecht            substrs=[
5099451b44SJordan Rupprecht                "api_name",
5199451b44SJordan Rupprecht                "class_name",
5299451b44SJordan Rupprecht                "description",
5399451b44SJordan Rupprecht                "instrumentation_class",
5499451b44SJordan Rupprecht                "selector"
5599451b44SJordan Rupprecht            ])
5699451b44SJordan Rupprecht        self.assertEqual(thread.GetStopReason(), lldb.eStopReasonInstrumentation)
5799451b44SJordan Rupprecht        output_lines = self.res.GetOutput().split('\n')
5899451b44SJordan Rupprecht        json_line = '\n'.join(output_lines[2:])
5999451b44SJordan Rupprecht        data = json.loads(json_line)
6099451b44SJordan Rupprecht        self.assertEqual(data["instrumentation_class"], "MainThreadChecker")
6199451b44SJordan Rupprecht        self.assertEqual(data["api_name"], "-[" + view + " superview]")
6299451b44SJordan Rupprecht        self.assertEqual(data["class_name"], view)
6399451b44SJordan Rupprecht        self.assertEqual(data["selector"], "superview")
6499451b44SJordan Rupprecht        self.assertEqual(data["description"], "-[" + view + " superview] must be used from main thread only")
65