summaryrefslogtreecommitdiffstats
path: root/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp')
-rw-r--r--unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp b/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp
new file mode 100644
index 0000000..a0a6f98
--- /dev/null
+++ b/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp
@@ -0,0 +1,174 @@
+//===-- PythonExceptionStateTest.cpp ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "Plugins/ScriptInterpreter/Python/lldb-python.h"
+#include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
+#include "Plugins/ScriptInterpreter/Python/PythonExceptionState.h"
+#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
+
+#include "PythonTestSuite.h"
+
+using namespace lldb_private;
+
+class PythonExceptionStateTest : public PythonTestSuite
+{
+ public:
+ protected:
+ void
+ RaiseException()
+ {
+ PyErr_SetString(PyExc_RuntimeError, "PythonExceptionStateTest test error");
+ }
+};
+
+TEST_F(PythonExceptionStateTest, TestExceptionStateChecking)
+{
+ PyErr_Clear();
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+
+ RaiseException();
+ EXPECT_TRUE(PythonExceptionState::HasErrorOccurred());
+
+ PyErr_Clear();
+}
+
+TEST_F(PythonExceptionStateTest, TestAcquisitionSemantics)
+{
+ PyErr_Clear();
+ PythonExceptionState no_error(false);
+ EXPECT_FALSE(no_error.IsError());
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+
+ PyErr_Clear();
+ RaiseException();
+ PythonExceptionState error(false);
+ EXPECT_TRUE(error.IsError());
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+ error.Discard();
+
+ PyErr_Clear();
+ RaiseException();
+ error.Acquire(false);
+ EXPECT_TRUE(error.IsError());
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+
+ PyErr_Clear();
+}
+
+TEST_F(PythonExceptionStateTest, TestDiscardSemantics)
+{
+ PyErr_Clear();
+
+ // Test that discarding an exception does not restore the exception
+ // state even when auto-restore==true is set
+ RaiseException();
+ PythonExceptionState error(true);
+ EXPECT_TRUE(error.IsError());
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+
+ error.Discard();
+ EXPECT_FALSE(error.IsError());
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+}
+
+TEST_F(PythonExceptionStateTest, TestResetSemantics)
+{
+ PyErr_Clear();
+
+ // Resetting when auto-restore is true should restore.
+ RaiseException();
+ PythonExceptionState error(true);
+ EXPECT_TRUE(error.IsError());
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+ error.Reset();
+ EXPECT_FALSE(error.IsError());
+ EXPECT_TRUE(PythonExceptionState::HasErrorOccurred());
+
+ PyErr_Clear();
+
+ // Resetting when auto-restore is false should discard.
+ RaiseException();
+ PythonExceptionState error2(false);
+ EXPECT_TRUE(error2.IsError());
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+ error2.Reset();
+ EXPECT_FALSE(error2.IsError());
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+
+ PyErr_Clear();
+}
+
+TEST_F(PythonExceptionStateTest, TestManualRestoreSemantics)
+{
+ PyErr_Clear();
+ RaiseException();
+ PythonExceptionState error(false);
+ EXPECT_TRUE(error.IsError());
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+
+ error.Restore();
+ EXPECT_FALSE(error.IsError());
+ EXPECT_TRUE(PythonExceptionState::HasErrorOccurred());
+
+ PyErr_Clear();
+}
+
+TEST_F(PythonExceptionStateTest, TestAutoRestoreSemantics)
+{
+ PyErr_Clear();
+ // Test that using the auto-restore flag correctly restores the exception
+ // state on destruction, and not using the auto-restore flag correctly
+ // does NOT restore the state on destruction.
+ {
+ RaiseException();
+ PythonExceptionState error(false);
+ EXPECT_TRUE(error.IsError());
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+ }
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+
+ PyErr_Clear();
+ {
+ RaiseException();
+ PythonExceptionState error(true);
+ EXPECT_TRUE(error.IsError());
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+ }
+ EXPECT_TRUE(PythonExceptionState::HasErrorOccurred());
+
+ PyErr_Clear();
+}
+
+TEST_F(PythonExceptionStateTest, TestAutoRestoreChanged)
+{
+ // Test that if we re-acquire with different auto-restore semantics,
+ // that the new semantics are respected.
+ PyErr_Clear();
+
+ RaiseException();
+ PythonExceptionState error(false);
+ EXPECT_TRUE(error.IsError());
+
+ error.Reset();
+ EXPECT_FALSE(error.IsError());
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+
+ RaiseException();
+ error.Acquire(true);
+ EXPECT_TRUE(error.IsError());
+ EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
+
+ error.Reset();
+ EXPECT_FALSE(error.IsError());
+ EXPECT_TRUE(PythonExceptionState::HasErrorOccurred());
+
+ PyErr_Clear();
+} \ No newline at end of file
OpenPOWER on IntegriCloud