context_ut.cpp 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #include "context.h"
  2. #include <library/cpp/testing/unittest/registar.h>
  3. #include <util/generic/deque.h>
  4. #include <util/generic/yexception.h>
  5. Y_UNIT_TEST_SUITE(TestContext) {
  6. template <class F>
  7. static TContClosure Wrap(F& f) {
  8. struct TW: public ITrampoLine {
  9. inline TW(F* ff) noexcept
  10. : F_(ff)
  11. {
  12. }
  13. void DoRun() override {
  14. (*F_)();
  15. }
  16. F* F_;
  17. char Buf[1000000];
  18. };
  19. static TDeque<TW> w;
  20. auto& tw = w.emplace_back(&f);
  21. return {&tw, TArrayRef(tw.Buf, sizeof(tw.Buf))};
  22. }
  23. Y_UNIT_TEST(TestExceptionSafety) {
  24. TExceptionSafeContext main;
  25. TExceptionSafeContext* volatile nextPtr = nullptr;
  26. bool hasUncaught = true;
  27. auto func = [&]() {
  28. hasUncaught = UncaughtException();
  29. nextPtr->SwitchTo(&main);
  30. };
  31. auto closure = Wrap(func);
  32. TExceptionSafeContext next(closure);
  33. nextPtr = &next;
  34. struct THelper {
  35. inline ~THelper() {
  36. M->SwitchTo(N);
  37. }
  38. TExceptionSafeContext* M;
  39. TExceptionSafeContext* N;
  40. };
  41. bool throwed = false;
  42. try {
  43. THelper helper{&main, &next};
  44. throw 1;
  45. } catch (...) {
  46. throwed = true;
  47. }
  48. UNIT_ASSERT(throwed);
  49. UNIT_ASSERT(!hasUncaught);
  50. }
  51. } // Y_UNIT_TEST_SUITE(TestContext)