summaryrefslogtreecommitdiffstats
path: root/debuginfo-tests/dexter/feature_tests
diff options
context:
space:
mode:
Diffstat (limited to 'debuginfo-tests/dexter/feature_tests')
-rw-r--r--debuginfo-tests/dexter/feature_tests/Readme.md4
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/penalty/expect_program_state.cpp37
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/penalty/expect_step_kinds.cpp27
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/penalty/expect_step_order.cpp18
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/penalty/expect_watch_type.cpp54
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/penalty/expect_watch_value.cpp21
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/penalty/unreachable.cpp16
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/perfect/expect_program_state.cpp52
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/direction.cpp33
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/func.cpp25
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/func_external.cpp25
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/recursive.cpp26
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/small_loop.cpp25
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_order.cpp18
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/perfect/expect_watch_type.cpp52
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/perfect/expect_watch_value.cpp39
-rw-r--r--debuginfo-tests/dexter/feature_tests/commands/perfect/unreachable.cpp16
-rw-r--r--debuginfo-tests/dexter/feature_tests/lit.local.cfg8
-rw-r--r--debuginfo-tests/dexter/feature_tests/subtools/clang-opt-bisect/clang-opt-bisect.cpp17
-rw-r--r--debuginfo-tests/dexter/feature_tests/subtools/help/help.test10
-rw-r--r--debuginfo-tests/dexter/feature_tests/subtools/list-debuggers/list-debuggers.test7
-rw-r--r--debuginfo-tests/dexter/feature_tests/subtools/test/err_paren.cpp22
-rw-r--r--debuginfo-tests/dexter/feature_tests/subtools/test/err_paren_mline.cpp25
-rw-r--r--debuginfo-tests/dexter/feature_tests/subtools/test/err_syntax.cpp21
-rw-r--r--debuginfo-tests/dexter/feature_tests/subtools/test/err_syntax_mline.cpp25
-rw-r--r--debuginfo-tests/dexter/feature_tests/subtools/test/err_type.cpp21
-rw-r--r--debuginfo-tests/dexter/feature_tests/subtools/test/err_type_mline.cpp25
-rw-r--r--debuginfo-tests/dexter/feature_tests/subtools/view.cpp21
-rw-r--r--debuginfo-tests/dexter/feature_tests/unittests/run.test9
29 files changed, 699 insertions, 0 deletions
diff --git a/debuginfo-tests/dexter/feature_tests/Readme.md b/debuginfo-tests/dexter/feature_tests/Readme.md
new file mode 100644
index 00000000000..303aa3cfd0f
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/Readme.md
@@ -0,0 +1,4 @@
+# DExTer feature tests
+
+This directory is home to dexter feature and regression tests to be run with
+llvm-lit. \ No newline at end of file
diff --git a/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_program_state.cpp b/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_program_state.cpp
new file mode 100644
index 00000000000..2d7c202f407
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_program_state.cpp
@@ -0,0 +1,37 @@
+// Purpose:
+// Check that \DexExpectProgramState correctly applies a penalty when
+// an expected program state is never found.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: not %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -glldb" -- %s \
+// RUN: | FileCheck %s
+// CHECK: expect_program_state.cpp:
+
+int GCD(int lhs, int rhs)
+{
+ if (rhs == 0) // DexLabel('check')
+ return lhs;
+ return GCD(rhs, lhs % rhs);
+}
+
+int main()
+{
+ return GCD(111, 259);
+}
+
+/*
+DexExpectProgramState({
+ 'frames': [
+ {
+ 'location': {
+ 'lineno': 'check'
+ },
+ 'watches': {
+ 'lhs': '0', 'rhs': '0'
+ }
+ },
+ ]
+})
+*/
diff --git a/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_step_kinds.cpp b/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_step_kinds.cpp
new file mode 100644
index 00000000000..54f363e6fd0
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_step_kinds.cpp
@@ -0,0 +1,27 @@
+// Purpose:
+// Check that \DexExpectStepKind correctly applies a penalty when
+// unexpected step kinds are encountered.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: not %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: expect_step_kinds.cpp:
+
+int abs(int i){
+ return i < 0? i * -1: i;
+}
+
+int main()
+{
+ volatile int x = 2;
+ for (int i = 0; i < x; ++i) {
+ abs(i);
+ }
+ return 0;
+}
+
+// DexExpectStepKind('FUNC', 5)
+// DexExpectStepKind('FUNC_EXTERNAL', 2)
+// DexExpectStepKind('VERTICAL_BACKWARD', 2)
diff --git a/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_step_order.cpp b/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_step_order.cpp
new file mode 100644
index 00000000000..84d2ab81d55
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_step_order.cpp
@@ -0,0 +1,18 @@
+// Purpose:
+// Check that \DexExpectStepOrder correctly applies a penalty for steps
+// found out of expected order.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: not %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: expect_step_order.cpp:
+
+int main()
+{
+ volatile int x = 1; // DexExpectStepOrder(3)
+ volatile int y = 1; // DexExpectStepOrder(1)
+ volatile int z = 1; // DexExpectStepOrder(2)
+ return 0;
+}
diff --git a/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_watch_type.cpp b/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_watch_type.cpp
new file mode 100644
index 00000000000..a619a6d224f
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_watch_type.cpp
@@ -0,0 +1,54 @@
+// Purpose:
+// Check that \DexExpectWatchType applies penalties when expected
+// types are not found and unexpected types are.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: not %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: expect_watch_type.cpp:
+
+template<class T>
+class Doubled {
+public:
+ Doubled(const T & to_double)
+ : m_member(to_double * 2) {}
+
+ T GetVal() {
+ T to_return = m_member; // DexLabel('gv_start')
+ return to_return; // DexLabel('gv_end')
+ }
+
+ static T static_doubler(const T & to_double) {
+ T result = 0; // DexLabel('sd_start')
+ result = to_double * 2;
+ return result; // DexLabel('sd_end')
+ }
+
+private:
+ T m_member;
+};
+
+int main() {
+ auto myInt = Doubled<int>(5); // DexLabel('main_start')
+ auto myDouble = Doubled<double>(5.5);
+ auto staticallyDoubledInt = Doubled<int>::static_doubler(5);
+ auto staticallyDoubledDouble = Doubled<double>::static_doubler(5.5);
+ return int(double(myInt.GetVal())
+ + double(staticallyDoubledInt)
+ + myDouble.GetVal()
+ + staticallyDoubledDouble); // DexLabel('main_end')
+}
+
+
+// DexExpectWatchType('m_member', 'int', 'double', from_line='gv_start', to_line='gv_end')
+
+// THIS COMMAND should create a penalty for a missing type 'const double' and unexpected type 'const double &'
+// DexExpectWatchType('to_double', 'const double', 'const int &', from_line='sd_start', to_line='sd_end')
+
+// DexExpectWatchType('myInt', 'Doubled<int>', from_line='main_start', to_line='main_end')
+// DexExpectWatchType('myDouble', 'Doubled<double>', from_line='main_start', to_line='main_end')
+// DexExpectWatchType('staticallyDoubledInt', 'int', from_line='main_start', to_line='main_end')
+// DexExpectWatchType('staticallyDoubledDouble', 'double', from_line='main_start', to_line='main_end')
+
diff --git a/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_watch_value.cpp b/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_watch_value.cpp
new file mode 100644
index 00000000000..ea30bc53a1b
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/penalty/expect_watch_value.cpp
@@ -0,0 +1,21 @@
+// Purpose:
+// Check that \DexExpectWatchValue correctly applies a penalty when
+// expected values are not found.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: not %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: expect_watch_value.cpp:
+
+int main()
+{
+ for (int i = 0; i < 3; ++i)
+ int a = i; // DexLabel('loop')
+ return 0; // DexLabel('ret')
+}
+
+// DexExpectWatchValue('i', '0', '1', '2', on_line='loop')
+// DexExpectWatchValue('i', '3', on_line='ret')
+// ---------------------^ out of scope
diff --git a/debuginfo-tests/dexter/feature_tests/commands/penalty/unreachable.cpp b/debuginfo-tests/dexter/feature_tests/commands/penalty/unreachable.cpp
new file mode 100644
index 00000000000..b089e6f6498
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/penalty/unreachable.cpp
@@ -0,0 +1,16 @@
+// Purpose:
+// Check that \DexUnreachable correctly applies a penalty if the command
+// line is stepped on.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: not %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: unreachable.cpp:
+
+int
+main()
+{
+ return 1; // DexUnreachable()
+}
diff --git a/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_program_state.cpp b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_program_state.cpp
new file mode 100644
index 00000000000..71d56bcc448
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_program_state.cpp
@@ -0,0 +1,52 @@
+// Purpose:
+// Check that \DexExpectWatchValue applies no penalties when expected
+// program states are found.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -glldb" -- %s \
+// RUN: | FileCheck %s
+// CHECK: expect_program_state.cpp:
+
+int GCD(int lhs, int rhs)
+{
+ if (rhs == 0)
+ return lhs; // DexLabel('check')
+ return GCD(rhs, lhs % rhs);
+}
+
+int main()
+{
+ return GCD(111, 259);
+}
+
+/*
+DexExpectProgramState({
+ 'frames': [
+ {
+ 'location': {
+ 'lineno': 'check'
+ },
+ 'watches': {
+ 'lhs': '37', 'rhs': '0'
+ }
+ },
+ {
+ 'watches': {
+ 'lhs': {'value': '111'}, 'rhs': {'value': '37'}
+ }
+ },
+ {
+ 'watches': {
+ 'lhs': {'value': '259'}, 'rhs': {'value': '111'}
+ }
+ },
+ {
+ 'watches': {
+ 'lhs': {'value': '111'}, 'rhs': {'value': '259'}
+ }
+ }
+ ]
+})
+*/
diff --git a/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/direction.cpp b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/direction.cpp
new file mode 100644
index 00000000000..a4fa5330f35
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/direction.cpp
@@ -0,0 +1,33 @@
+// Purpose:
+// Check that \DexExpectStepKind correctly counts 'VERTICAL_BACKWARD' steps
+// for a trivial test. Expect one 'VERTICAL_BACKWARD' for every step onto
+// a lesser source line number in the same function. Expect one
+// 'VERTICAL_FORWARD' for every step onto a greater source line number in
+// the same function.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: direction.cpp:
+
+int func(int i) {
+ return i; // step 7, 9, 11
+}
+
+int main()
+{
+ for (int i = 0; i < 2; ++i) { // step 1: FUNC, step 3, 5: VERTICAL_BACKWARD
+ i = i; // step 2, 4: VERTICAL_FORWARD
+ }
+ // ---------1 - step 6: VERTICAL_FORWARD
+ // ---------|---------2 - step 8: HORIZONTAL_FORWARD
+ // ----3----|---------| - step 10: HORIZONTAL_BACKWARD
+ return func(func(0) + func(1));
+}
+
+// DexExpectStepKind('VERTICAL_BACKWARD', 2)
+// DexExpectStepKind('VERTICAL_FORWARD', 3)
+// DexExpectStepKind('HORIZONTAL_FORWARD', 1)
+// DexExpectStepKind('HORIZONTAL_BACKWARD', 1)
diff --git a/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/func.cpp b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/func.cpp
new file mode 100644
index 00000000000..46a13143c50
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/func.cpp
@@ -0,0 +1,25 @@
+// Purpose:
+// Check that \DexExpectStepKind correctly counts 'FUNC' steps for a
+// trivial test. Expect one 'FUNC' per call to a function which is defined
+// in one of the source files in the test directory.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: func.cpp:
+
+int func(int i) {
+ return i;
+}
+
+int main()
+{
+ func(0);
+ func(1);
+ return 0;
+}
+
+// main, func, func
+// DexExpectStepKind('FUNC', 3)
diff --git a/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/func_external.cpp b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/func_external.cpp
new file mode 100644
index 00000000000..4ca8d1e746d
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/func_external.cpp
@@ -0,0 +1,25 @@
+// Purpose:
+// Check that \DexExpectStepKind correctly counts 'FUNC_EXTERNAL' steps
+// for a trivial test. Expect one 'FUNC_EXTERNAL' per external call.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: func_external.cpp:
+
+#include <cstdlib>
+
+int func(int i){
+ return abs(i);
+}
+
+int main()
+{
+ func(0);
+ func(1);
+ return 0;
+}
+
+// DexExpectStepKind('FUNC_EXTERNAL', 2)
diff --git a/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/recursive.cpp b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/recursive.cpp
new file mode 100644
index 00000000000..dd4af84363b
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/recursive.cpp
@@ -0,0 +1,26 @@
+// Purpose:
+// Check that \DexExpectStepKind correctly handles recursive calls.
+// Specifically, ensure recursive calls count towards 'FUNC' and not
+// 'VERTICAL_BACKWARD'.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: recursive.cpp:
+
+int func(int i) {
+ if (i > 1)
+ return i + func(i - 1);
+ return i;
+}
+
+int main()
+{
+ return func(3);
+}
+
+// main, func, func, func
+// DexExpectStepKind('FUNC', 4)
+// DexExpectStepKind('VERTICAL_BACKWARD', 0)
diff --git a/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/small_loop.cpp b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/small_loop.cpp
new file mode 100644
index 00000000000..b85aab1d848
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind/small_loop.cpp
@@ -0,0 +1,25 @@
+// Purpose:
+// Check that \DexExpectStepKind correctly counts function calls in loops
+// where the last source line in the loop is a call. Expect steps out
+// of a function to a line before the call to count as 'VERTICAL_BACKWARD'.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: small_loop.cpp:
+
+int func(int i){
+ return i;
+}
+
+int main()
+{
+ for (int i = 0; i < 2; ++i) {
+ func(i);
+ }
+ return 0;
+}
+
+// DexExpectStepKind('VERTICAL_BACKWARD', 2)
diff --git a/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_order.cpp b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_order.cpp
new file mode 100644
index 00000000000..cadc0387d9b
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_order.cpp
@@ -0,0 +1,18 @@
+// Purpose:
+// Check that \DexExpectStepOrder applies no penalty when the expected
+// order is found.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: expect_step_order.cpp:
+
+int main()
+{
+ volatile int x = 1; // DexExpectStepOrder(1)
+ volatile int y = 1; // DexExpectStepOrder(2)
+ volatile int z = 1; // DexExpectStepOrder(3)
+ return 0;
+}
diff --git a/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_watch_type.cpp b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_watch_type.cpp
new file mode 100644
index 00000000000..b98ef28ad98
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_watch_type.cpp
@@ -0,0 +1,52 @@
+// Purpose:
+// Check that \DexExpectWatchType applies no penalties when expected
+// types are found.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: expect_watch_type.cpp:
+
+template<class T>
+class Doubled {
+public:
+ Doubled(const T & to_double)
+ : m_member(to_double * 2) {}
+
+ T GetVal() {
+ T to_return = m_member; // DexLabel('gv_start')
+ return to_return; // DexLabel('gv_end')
+ }
+
+ static T static_doubler(const T & to_double) {
+ T result = 0; // DexLabel('sd_start')
+ result = to_double * 2;
+ return result; // DexLabel('sd_end')
+ }
+
+private:
+ T m_member;
+};
+
+int main() {
+ auto myInt = Doubled<int>(5); // DexLabel('main_start')
+ auto myDouble = Doubled<double>(5.5);
+ auto staticallyDoubledInt = Doubled<int>::static_doubler(5);
+ auto staticallyDoubledDouble = Doubled<double>::static_doubler(5.5);
+ return int(double(myInt.GetVal())
+ + double(staticallyDoubledInt)
+ + myDouble.GetVal()
+ + staticallyDoubledDouble); // DexLabel('main_end')
+}
+
+// DexExpectWatchType('m_member', 'int', 'double', from_line='gv_start', to_line='gv_end')
+
+// DexExpectWatchType('to_double', 'const int &', 'const double &', from_line='sd_start', to_line='sd_end')
+
+// DexExpectWatchType('myInt', 'Doubled<int>', from_line='main_start', to_line='main_end')
+// DexExpectWatchType('myDouble', 'Doubled<double>', from_line='main_start', to_line='main_end')
+// DexExpectWatchType('staticallyDoubledInt', 'int', from_line='main_start', to_line='main_end')
+// DexExpectWatchType('staticallyDoubledDouble', 'double', from_line='main_start', to_line='main_end')
+
diff --git a/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_watch_value.cpp b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_watch_value.cpp
new file mode 100644
index 00000000000..7f4c365cab6
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/perfect/expect_watch_value.cpp
@@ -0,0 +1,39 @@
+// Purpose:
+// Check that \DexExpectWatchValue applies no penalties when expected
+// values are found.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: expect_watch_value.cpp:
+
+unsigned long Factorial(int n) {
+ volatile unsigned long fac = 1; // DexLabel('entry')
+
+ for (int i = 1; i <= n; ++i)
+ fac *= i; // DexLabel('loop')
+
+ return fac; // DexLabel('ret')
+}
+
+int main()
+{
+ return Factorial(8);
+}
+
+/*
+DexExpectWatchValue('n', '8', on_line='entry')
+DexExpectWatchValue('i',
+ '1', '2', '3', '4', '5', '6', '7', '8',
+ on_line='loop')
+
+DexExpectWatchValue('fac',
+ '1', '2', '6', '24', '120', '720', '5040',
+ on_line='loop')
+
+DexExpectWatchValue('n', '8', on_line='loop')
+DexExpectWatchValue('fac', '40320', on_line='ret')
+DexExpectWatchValue('n', '8', on_line='ret')
+*/
diff --git a/debuginfo-tests/dexter/feature_tests/commands/perfect/unreachable.cpp b/debuginfo-tests/dexter/feature_tests/commands/perfect/unreachable.cpp
new file mode 100644
index 00000000000..c53e07fe4a4
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/perfect/unreachable.cpp
@@ -0,0 +1,16 @@
+// Purpose:
+// Check that \DexUnreachable has no effect if the command line is never
+// stepped on.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: unreachable.cpp:
+
+int main()
+{
+ return 0;
+ return 1; // DexUnreachable()
+}
diff --git a/debuginfo-tests/dexter/feature_tests/lit.local.cfg b/debuginfo-tests/dexter/feature_tests/lit.local.cfg
new file mode 100644
index 00000000000..39ead87cf3c
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/lit.local.cfg
@@ -0,0 +1,8 @@
+config.name = "DExTer feature tests"
+config.suffixes = ['.cpp', '.c', '.test']
+
+# Dexter requires python3
+
+import sys
+if sys.version_info.major < 3:
+ config.unsupported = True
diff --git a/debuginfo-tests/dexter/feature_tests/subtools/clang-opt-bisect/clang-opt-bisect.cpp b/debuginfo-tests/dexter/feature_tests/subtools/clang-opt-bisect/clang-opt-bisect.cpp
new file mode 100644
index 00000000000..bc625da0e53
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/subtools/clang-opt-bisect/clang-opt-bisect.cpp
@@ -0,0 +1,17 @@
+// Purpose:
+// Check the `clang-opt-bisect` tool runs with typical input.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: true
+// RUN: %dexter clang-opt-bisect --debugger 'lldb' --builder 'clang' \
+// RUN: --cflags "-O0 -g" -- %s \
+// RUN: | FileCheck %s
+// CHECK: running pass 0
+// CHECK: wrote{{.*}}per_pass_score
+// CHECK: wrote{{.*}}pass-summary
+// CHECK: wrote{{.*}}overall-pass-summary
+
+int main() {
+ return 0;
+}
diff --git a/debuginfo-tests/dexter/feature_tests/subtools/help/help.test b/debuginfo-tests/dexter/feature_tests/subtools/help/help.test
new file mode 100644
index 00000000000..e008147b7cc
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/subtools/help/help.test
@@ -0,0 +1,10 @@
+Purpose:
+ Check the `help` subtool runs.
+
+RUN: %dexter help | FileCheck %s
+CHECK: The following subtools are available:
+CHECK: clang-opt-bisect
+CHECK: help
+CHECK: list-debuggers
+CHECK: test
+CHECK: view
diff --git a/debuginfo-tests/dexter/feature_tests/subtools/list-debuggers/list-debuggers.test b/debuginfo-tests/dexter/feature_tests/subtools/list-debuggers/list-debuggers.test
new file mode 100644
index 00000000000..c8f4a890275
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/subtools/list-debuggers/list-debuggers.test
@@ -0,0 +1,7 @@
+Purpose:
+ Check the `list-debuggers` subtool runs.
+
+RUN: %dexter list-debuggers | FileCheck %s
+CHECK: lldb
+CHECK: vs2015
+CHECK: vs2017
diff --git a/debuginfo-tests/dexter/feature_tests/subtools/test/err_paren.cpp b/debuginfo-tests/dexter/feature_tests/subtools/test/err_paren.cpp
new file mode 100644
index 00000000000..25421f397d1
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/subtools/test/err_paren.cpp
@@ -0,0 +1,22 @@
+// Purpose:
+// Check that parsing bad commands gives a useful error.
+// - Unbalanced parenthesis
+// Check directives are in check.txt to prevent dexter reading any embedded
+// commands.
+//
+// Note: Despite using 'lldb' as the debugger, lldb is not actually required
+// as the test should finish before lldb would be invoked.
+//
+// RUN: not %dexter test --builder 'clang' --debugger 'lldb' \
+// RUN: --cflags "-O0 -g" -v -- %s \
+// RUN: | FileCheck %s --match-full-lines --strict-whitespace
+//
+// CHECK:parser error:{{.*}}err_paren.cpp(22): Unbalanced parenthesis starting here
+// CHECK:// {{Dex}}ExpectWatchValue(
+// CHECK: ^
+
+int main(){
+ return 0;
+}
+
+// DexExpectWatchValue(
diff --git a/debuginfo-tests/dexter/feature_tests/subtools/test/err_paren_mline.cpp b/debuginfo-tests/dexter/feature_tests/subtools/test/err_paren_mline.cpp
new file mode 100644
index 00000000000..051ee12fb11
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/subtools/test/err_paren_mline.cpp
@@ -0,0 +1,25 @@
+// Purpose:
+// Check that parsing bad commands gives a useful error.
+// - Unbalanced parenthesis over multiple lines
+// Check directives are in check.txt to prevent dexter reading any embedded
+// commands.
+//
+// Note: Despite using 'lldb' as the debugger, lldb is not actually required
+// as the test should finish before lldb would be invoked.
+//
+// RUN: not %dexter test --builder 'clang' --debugger "lldb" \
+// RUN: --cflags "-O0 -g" -v -- %s \
+// RUN: | FileCheck %s --match-full-lines --strict-whitespace
+//
+// CHECK:parser error:{{.*}}err_paren_mline.cpp(23): Unbalanced parenthesis starting here
+// CHECK:{{Dex}}ExpectWatchValue(
+// CHECK: ^
+
+int main(){
+ return 0;
+}
+
+/*
+DexExpectWatchValue(
+ 1
+*/
diff --git a/debuginfo-tests/dexter/feature_tests/subtools/test/err_syntax.cpp b/debuginfo-tests/dexter/feature_tests/subtools/test/err_syntax.cpp
new file mode 100644
index 00000000000..5092eb7e216
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/subtools/test/err_syntax.cpp
@@ -0,0 +1,21 @@
+// Purpose:
+// Check that parsing bad commands gives a useful error.
+// - Syntax error (misplaced ',')
+// Check directives are in check.txt to prevent dexter reading any embedded
+// commands.
+//
+// Note: Despite using 'lldb' as the debugger, lldb is not actually required
+// as the test should finish before lldb would be invoked.
+//
+// RUN: not %dexter test --builder 'clang' --debugger "lldb" \
+// RUN: --cflags "-O0 -g" -v -- %s \
+// RUN: | FileCheck %s --match-full-lines --strict-whitespace
+//
+// CHECK:parser error:{{.*}}err_syntax.cpp(21): invalid syntax
+// CHECK:// {{Dex}}ExpectWatchValue(,'a', 3, 3, 3, 3, on_line=0)
+// CHECK: ^
+
+int main(){
+ return 0;
+}
+// DexExpectWatchValue(,'a', 3, 3, 3, 3, on_line=0)
diff --git a/debuginfo-tests/dexter/feature_tests/subtools/test/err_syntax_mline.cpp b/debuginfo-tests/dexter/feature_tests/subtools/test/err_syntax_mline.cpp
new file mode 100644
index 00000000000..919528fd847
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/subtools/test/err_syntax_mline.cpp
@@ -0,0 +1,25 @@
+// Purpose:
+// Check that parsing bad commands gives a useful error.
+// - Syntax error (misplaced ',') over multiple lines
+// Check directives are in check.txt to prevent dexter reading any embedded
+// commands.
+//
+// Note: Despite using 'lldb' as the debugger, lldb is not actually required
+// as the test should finish before lldb would be invoked.
+//
+// RUN: not %dexter test --builder 'clang' --debugger "lldb" \
+// RUN: --cflags "-O0 -g" -v -- %s \
+// RUN: | FileCheck %s --match-full-lines --strict-whitespace
+//
+// CHECK:parser error:{{.*}}err_syntax_mline.cpp(24): invalid syntax
+// CHECK: ,'a', 3, 3, 3, 3, on_line=0)
+// CHECK: ^
+
+int main(){
+ return 0;
+}
+
+/*
+DexExpectWatchValue(
+ ,'a', 3, 3, 3, 3, on_line=0)
+*/
diff --git a/debuginfo-tests/dexter/feature_tests/subtools/test/err_type.cpp b/debuginfo-tests/dexter/feature_tests/subtools/test/err_type.cpp
new file mode 100644
index 00000000000..58a4f33404d
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/subtools/test/err_type.cpp
@@ -0,0 +1,21 @@
+// Purpose:
+// Check that parsing bad commands gives a useful error.
+// - Type error (missing args)
+// Check directives are in check.txt to prevent dexter reading any embedded
+// commands.
+//
+// Note: Despite using 'lldb' as the debugger, lldb is not actually required
+// as the test should finish before lldb would be invoked.
+//
+// RUN: not %dexter test --builder 'clang' --debugger "lldb" \
+// RUN: --cflags "-O0 -g" -v -- %s \
+// RUN: | FileCheck %s --match-full-lines --strict-whitespace
+//
+// CHECK:parser error:{{.*}}err_type.cpp(21): expected at least two args
+// CHECK:// {{Dex}}ExpectWatchValue()
+// CHECK: ^
+
+int main(){
+ return 0;
+}
+// DexExpectWatchValue()
diff --git a/debuginfo-tests/dexter/feature_tests/subtools/test/err_type_mline.cpp b/debuginfo-tests/dexter/feature_tests/subtools/test/err_type_mline.cpp
new file mode 100644
index 00000000000..66e422ed629
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/subtools/test/err_type_mline.cpp
@@ -0,0 +1,25 @@
+// Purpose:
+// Check that parsing bad commands gives a useful error.
+// - Type error (missing args) over multple lines
+// Check directives are in check.txt to prevent dexter reading any embedded
+// commands.
+//
+// Note: Despite using 'lldb' as the debugger, lldb is not actually required
+// as the test should finish before lldb would be invoked.
+//
+// RUN: not %dexter test --builder 'clang' --debugger "lldb" \
+// RUN: --cflags "-O0 -g" -v -- %s \
+// RUN: | FileCheck %s --match-full-lines --strict-whitespace
+//
+// CHECK:parser error:{{.*}}err_type_mline.cpp(22): expected at least two args
+// CHECK:{{Dex}}ExpectWatchValue(
+// CHECK: ^
+
+int main(){
+ return 0;
+}
+/*
+DexExpectWatchValue(
+ 'a'
+)
+*/
diff --git a/debuginfo-tests/dexter/feature_tests/subtools/view.cpp b/debuginfo-tests/dexter/feature_tests/subtools/view.cpp
new file mode 100644
index 00000000000..9c4f2573361
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/subtools/view.cpp
@@ -0,0 +1,21 @@
+// Purpose:
+// Check the `view` subtool works with typical inputs.
+//
+// REQUIRES: system-linux, lldb
+//
+// RUN: %dexter test --fail-lt 1.0 -w \
+// RUN: --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" \
+// RUN: --results %t -- %s
+//
+// RUN: %dexter view %t/view.cpp.dextIR | FileCheck %s
+// CHECK: ## BEGIN
+// CHECK: ## END
+//
+// # [TODO] This doesn't run if FileCheck fails!
+// RUN: rm -rf %t
+
+int main() {
+ int a = 0;
+ return 0; //DexLabel('ret')
+}
+// DexExpectWatchValue('a', '0', on_line='ret')
diff --git a/debuginfo-tests/dexter/feature_tests/unittests/run.test b/debuginfo-tests/dexter/feature_tests/unittests/run.test
new file mode 100644
index 00000000000..d7f9d17ac36
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/unittests/run.test
@@ -0,0 +1,9 @@
+Purpose:
+ Run DExTer unit tests.
+
+# Dexter returns 1 when no subtools are specified.
+RUN: not %dexter --unittest=show-all 2>&1 | FileCheck %s
+
+CHECK: Ran {{[0-9]+}} tests
+CHECK-EMPTY:
+CHECK-NEXT: OK
OpenPOWER on IntegriCloud