You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UITest.java 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package com.vaadin.ui;
  2. import java.util.Properties;
  3. import java.util.concurrent.ConcurrentLinkedQueue;
  4. import java.util.concurrent.CountDownLatch;
  5. import java.util.concurrent.locks.Lock;
  6. import java.util.concurrent.locks.ReentrantLock;
  7. import javax.servlet.ServletConfig;
  8. import org.junit.Assert;
  9. import org.junit.Test;
  10. import com.vaadin.server.DefaultDeploymentConfiguration;
  11. import com.vaadin.server.MockServletConfig;
  12. import com.vaadin.server.MockVaadinSession;
  13. import com.vaadin.server.VaadinRequest;
  14. import com.vaadin.server.VaadinServlet;
  15. import com.vaadin.server.VaadinServletService;
  16. import com.vaadin.server.VaadinSession;
  17. import com.vaadin.server.communication.PushConnection;
  18. import com.vaadin.shared.communication.PushMode;
  19. public class UITest {
  20. @Test
  21. public void removeFromSessionWithExternalLock() throws Exception {
  22. // See https://dev.vaadin.com/ticket/18436
  23. final UI ui = new UI() {
  24. @Override
  25. protected void init(VaadinRequest request) {
  26. }
  27. };
  28. final Lock externalLock = new ReentrantLock();
  29. ServletConfig servletConfig = new MockServletConfig();
  30. VaadinServlet servlet = new VaadinServlet();
  31. servlet.init(servletConfig);
  32. DefaultDeploymentConfiguration deploymentConfiguration = new DefaultDeploymentConfiguration(
  33. UI.class, new Properties());
  34. MockVaadinSession session = new MockVaadinSession(
  35. new VaadinServletService(servlet, deploymentConfiguration));
  36. session.lock();
  37. ui.setSession(session);
  38. ui.getPushConfiguration().setPushMode(PushMode.MANUAL);
  39. ui.setPushConnection(new PushConnection() {
  40. private boolean connected = true;
  41. @Override
  42. public void push() {
  43. }
  44. @Override
  45. public boolean isConnected() {
  46. return connected;
  47. }
  48. @Override
  49. public void disconnect() {
  50. externalLock.lock();
  51. try {
  52. connected = false;
  53. } finally {
  54. externalLock.unlock();
  55. }
  56. }
  57. });
  58. session.unlock();
  59. final CountDownLatch websocketReachedCheckpoint = new CountDownLatch(1);
  60. final CountDownLatch uiDisconnectReachedCheckpoint = new CountDownLatch(
  61. 1);
  62. final VaadinSession uiSession = ui.getSession();
  63. final ConcurrentLinkedQueue<Exception> exceptions = new ConcurrentLinkedQueue<Exception>();
  64. // Simulates the websocket close thread
  65. Runnable websocketClose = new Runnable() {
  66. @Override
  67. public void run() {
  68. externalLock.lock();
  69. // Wait for disconnect thread to lock VaadinSession
  70. websocketReachedCheckpoint.countDown();
  71. try {
  72. uiDisconnectReachedCheckpoint.await();
  73. } catch (InterruptedException e) {
  74. e.printStackTrace();
  75. exceptions.add(e);
  76. return;
  77. }
  78. uiSession.lock();
  79. externalLock.unlock();
  80. }
  81. };
  82. Runnable disconnectPushFromUI = new Runnable() {
  83. @Override
  84. public void run() {
  85. uiSession.lock();
  86. // Wait for websocket thread to lock external lock
  87. uiDisconnectReachedCheckpoint.countDown();
  88. try {
  89. websocketReachedCheckpoint.await();
  90. } catch (InterruptedException e) {
  91. e.printStackTrace();
  92. exceptions.add(e);
  93. return;
  94. }
  95. ui.setSession(null);
  96. uiSession.unlock();
  97. }
  98. };
  99. Thread websocketThread = new Thread(websocketClose);
  100. websocketThread.start();
  101. Thread uiDisconnectThread = new Thread(disconnectPushFromUI);
  102. uiDisconnectThread.start();
  103. websocketThread.join(5000);
  104. uiDisconnectThread.join(5000);
  105. if (websocketThread.isAlive() || uiDisconnectThread.isAlive()) {
  106. websocketThread.interrupt();
  107. uiDisconnectThread.interrupt();
  108. Assert.fail("Threads are still running");
  109. }
  110. if (!exceptions.isEmpty()) {
  111. for (Exception e : exceptions) {
  112. e.printStackTrace();
  113. }
  114. Assert.fail("There were exceptions in the threads");
  115. }
  116. Assert.assertNull(ui.getSession());
  117. // PushConnection is set to null in another thread. We need to wait for
  118. // that to happen
  119. for (int i = 0; i < 10; i++) {
  120. if (ui.getPushConnection() == null) {
  121. break;
  122. }
  123. Thread.sleep(500);
  124. }
  125. Assert.assertNull(ui.getPushConnection());
  126. }
  127. }