| //===-- 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/PythonDataObjects.h" |
| #include "Plugins/ScriptInterpreter/Python/PythonExceptionState.h" |
| #include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h" |
| #include "Plugins/ScriptInterpreter/Python/lldb-python.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(); |
| } |