TestCase.cpp revision c50fc4b658c46ef43b1add131391ecdd1f9bd752
1//
2//  TestCase.cpp
3//  PerfTestDriver
4//
5//  Created by Enrico Granata on 3/7/13.
6//  Copyright (c) 2013 Apple Inc. All rights reserved.
7//
8
9#include "TestCase.h"
10#include "Xcode.h"
11
12using namespace lldb::perf;
13
14TestCase::TestCase () :
15m_debugger(),
16m_target(),
17m_process(),
18m_thread(),
19m_listener(),
20m_verbose(false)
21{
22    SBDebugger::Initialize();
23	SBHostOS::ThreadCreated ("<lldb-tester.app.main>");
24	m_debugger = SBDebugger::Create(false);
25	m_listener = m_debugger.GetListener();
26}
27
28void
29TestCase::Setup (int argc, const char** argv)
30{}
31
32bool
33TestCase::Launch (const char** args, const char* cwd)
34{
35	m_process = m_target.LaunchSimple(args,NULL,cwd);
36	m_process.GetBroadcaster().AddListener(m_listener, SBProcess::eBroadcastBitStateChanged | SBProcess::eBroadcastBitInterrupt);
37	return m_process.IsValid ();
38}
39
40void
41TestCase::SetVerbose (bool b)
42{
43    m_verbose = b;
44}
45
46bool
47TestCase::GetVerbose ()
48{
49    return m_verbose;
50}
51
52void
53TestCase::Loop ()
54{
55	int step = 0;
56	SBEvent evt;
57	while (true)
58	{
59		m_listener.WaitForEvent (UINT32_MAX,evt);
60		StateType state = SBProcess::GetStateFromEvent (evt);
61		if (m_verbose)
62			printf("event = %s\n",SBDebugger::StateAsCString(state));
63		if (SBProcess::GetRestartedFromEvent(evt))
64			continue;
65		switch (state)
66		{
67			case eStateInvalid:
68			case eStateDetached:
69			case eStateCrashed:
70			case eStateUnloaded:
71				break;
72			case eStateExited:
73				return;
74			case eStateConnected:
75			case eStateAttaching:
76			case eStateLaunching:
77			case eStateRunning:
78			case eStateStepping:
79				continue;
80			case eStateStopped:
81			case eStateSuspended:
82			{
83				bool fatal = false;
84				for (auto thread_index = 0; thread_index < m_process.GetNumThreads(); thread_index++)
85				{
86					SBThread thread(m_process.GetThreadAtIndex(thread_index));
87					SBFrame frame(thread.GetFrameAtIndex(0));
88					StopReason stop_reason = thread.GetStopReason();
89					if (m_verbose) printf("tid = 0x%llx pc = 0x%llx ",thread.GetThreadID(),frame.GetPC());
90					switch (stop_reason)
91					{
92				        case eStopReasonNone:
93                            if (m_verbose) printf("none\n");
94                            break;
95
96				        case eStopReasonTrace:
97                            if (m_verbose) printf("trace\n");
98                            break;
99
100				        case eStopReasonPlanComplete:
101                            if (m_verbose) printf("plan complete\n");
102                            break;
103				        case eStopReasonThreadExiting:
104                            if (m_verbose) printf("thread exiting\n");
105                            break;
106				        case eStopReasonExec:
107                            if (m_verbose) printf("exec\n");
108                            break;
109						case eStopReasonInvalid:
110                            if (m_verbose) printf("invalid\n");
111                            break;
112			        	case eStopReasonException:
113                            if (m_verbose) printf("exception\n");
114                            fatal = true;
115                            break;
116				        case eStopReasonBreakpoint:
117                            if (m_verbose) printf("breakpoint id = %lld.%lld\n",thread.GetStopReasonDataAtIndex(0),thread.GetStopReasonDataAtIndex(1));
118                            break;
119				        case eStopReasonWatchpoint:
120                            if (m_verbose) printf("watchpoint id = %lld\n",thread.GetStopReasonDataAtIndex(0));
121                            break;
122				        case eStopReasonSignal:
123                            if (m_verbose) printf("signal %d\n",(int)thread.GetStopReasonDataAtIndex(0));
124                            break;
125					}
126				}
127				if (fatal)
128				{
129					if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
130					exit(1);
131				}
132				if (m_verbose)
133					printf("RUNNING STEP %d\n",step);
134				auto action = TestStep(step);
135				step++;
136				switch (action.type)
137				{
138					case ActionWanted::Type::eAWContinue:
139						m_debugger.HandleCommand("continue");
140						break;
141                    case ActionWanted::Type::eAWFinish:
142                        if (action.thread.IsValid() == false)
143                        {
144                            if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
145                            if (m_verbose) printf("[finish invalid] I am gonna die at step %d\n",step);
146                            exit(501);
147                        }
148                        m_process.SetSelectedThread(action.thread);
149                        m_debugger.HandleCommand("finish");
150						break;
151					case ActionWanted::Type::eAWNext:
152                        if (action.thread.IsValid() == false)
153                        {
154                            if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
155                            if (m_verbose) printf("[next invalid] I am gonna die at step %d\n",step);
156                            exit(500);
157                        }
158                        m_process.SetSelectedThread(action.thread);
159                        m_debugger.HandleCommand("next");
160						break;
161					case ActionWanted::Type::eAWKill:
162						if (m_verbose) printf("I want to die\n");
163						m_process.Kill();
164						return;
165				}
166			}
167		}
168	}
169	if (GetVerbose()) printf("I am gonna die at step %d\n",step);
170}
171
172void
173TestCase::Run (TestCase& test, int argc, const char** argv)
174{
175    test.Setup(argc, argv);
176    test.Loop();
177    test.Results();
178}
179