console: add testClearAndPrintWhileAnotherClearExecution to hunt down concurrent...
[idea/community.git] / platform / platform-tests / testSrc / com / intellij / execution / impl / ConsoleViewImplTest.java
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.execution.impl;
17
18 import com.intellij.execution.process.ProcessHandler;
19 import com.intellij.execution.ui.ConsoleViewContentType;
20 import com.intellij.ide.DataManager;
21 import com.intellij.openapi.actionSystem.DataContext;
22 import com.intellij.openapi.editor.Editor;
23 import com.intellij.openapi.editor.actionSystem.EditorActionManager;
24 import com.intellij.openapi.editor.actionSystem.TypedAction;
25 import com.intellij.openapi.project.Project;
26 import com.intellij.openapi.util.Disposer;
27 import com.intellij.psi.search.GlobalSearchScope;
28 import com.intellij.testFramework.LightPlatformTestCase;
29 import com.intellij.testFramework.TestDataProvider;
30 import com.intellij.util.Alarm;
31 import com.intellij.util.TimeoutUtil;
32 import com.intellij.util.ui.UIUtil;
33 import org.jetbrains.annotations.NotNull;
34 import org.jetbrains.annotations.Nullable;
35
36 import java.io.OutputStream;
37 import java.util.concurrent.CountDownLatch;
38
39 public class ConsoleViewImplTest extends LightPlatformTestCase {
40
41   private ConsoleViewImpl myConsole;
42
43   @Override
44   public void setUp() throws Exception {
45     super.setUp();
46     myConsole = createConsole();
47   }
48
49   @Override
50   public void tearDown() throws Exception {
51     try {
52       Disposer.dispose(myConsole);
53     }
54     finally {
55       super.tearDown();
56     }
57   }
58
59   public void testTypeText() throws Exception {
60     ConsoleViewImpl console = myConsole;
61     console.print("Initial", ConsoleViewContentType.NORMAL_OUTPUT);
62     console.flushDeferredText();
63     console.clear();
64     console.print("Hi", ConsoleViewContentType.NORMAL_OUTPUT);
65     assertEquals(2, console.getContentSize());
66   }
67
68   public void testConsolePrintsSomethingAfterDoubleClear() throws Exception {
69     ConsoleViewImpl console = myConsole;
70     Alarm alarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
71     CountDownLatch latch = new CountDownLatch(1);
72     alarm.addRequest(() -> {
73       console.clear();
74       console.clear();
75       console.print("Test", ConsoleViewContentType.NORMAL_OUTPUT);
76       latch.countDown();
77     }, 0);
78     latch.await();
79     UIUtil.dispatchAllInvocationEvents();
80     TimeoutUtil.sleep(ConsoleViewImpl.DEFAULT_FLUSH_DELAY);
81     UIUtil.dispatchAllInvocationEvents();
82     assertFalse(console.hasDeferredOutput());
83     assertEquals("Test", console.getText());
84   }
85
86   public void testClearAndPrintWhileAnotherClearExecution() throws Exception {
87     ConsoleViewImpl console = myConsole;
88     Alarm alarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
89     for (int i = 0; i < 100; i++) {
90       // To speed up test execution, set -Dconsole.flush.delay.ms=5 to reduce ConsoleViewImpl.DEFAULT_FLUSH_DELAY
91       System.out.println("Attempt #" + i);
92       console.clear(); // 1-st clear
93       CountDownLatch latch = new CountDownLatch(1);
94       alarm.addRequest(() -> {
95         console.clear(); // 2-nd clear
96         console.print("Test", ConsoleViewContentType.NORMAL_OUTPUT);
97         latch.countDown();
98       }, 0);
99       UIUtil.dispatchAllInvocationEvents(); // flush 1-st clear request
100       latch.await();
101       UIUtil.dispatchAllInvocationEvents(); // flush 2-nd clear request
102       TimeoutUtil.sleep(ConsoleViewImpl.DEFAULT_FLUSH_DELAY);
103       UIUtil.dispatchAllInvocationEvents(); // flush print request
104       // Need more investigation: sometimes console.hasDeferredOutput() is true
105       while (console.hasDeferredOutput()) {
106         TimeoutUtil.sleep(10);
107         UIUtil.dispatchAllInvocationEvents();
108       }
109       //uncomment the next assertion to see probably failing test
110       //assertEquals("Test", console.getText());
111     }
112   }
113
114   public void testTypeInEmptyConsole() throws Exception {
115     ConsoleViewImpl console = myConsole;
116     console.clear();
117     EditorActionManager actionManager = EditorActionManager.getInstance();
118     DataContext dataContext = DataManager.getInstance().getDataContext(console.getComponent());
119     TypedAction action = actionManager.getTypedAction();
120     action.actionPerformed(console.getEditor(), 'h', dataContext);
121     assertEquals(1, console.getContentSize());
122   }
123
124   public void testTypingAfterMultipleCR() throws Exception {
125     final EditorActionManager actionManager = EditorActionManager.getInstance();
126     final TypedAction typedAction = actionManager.getTypedAction();
127     final TestDataProvider dataContext = new TestDataProvider(getProject());
128
129     final ConsoleViewImpl console = myConsole;
130     final Editor editor = console.getEditor();
131     console.print("System output\n", ConsoleViewContentType.SYSTEM_OUTPUT);
132     console.print("\r\r\r\r\r\r\r", ConsoleViewContentType.NORMAL_OUTPUT);
133     console.flushDeferredText();
134
135     typedAction.actionPerformed(editor, '1', dataContext);
136     typedAction.actionPerformed(editor, '2', dataContext);
137
138     assertEquals("System output\n12", editor.getDocument().getText());
139   }
140
141   @NotNull
142   private static ConsoleViewImpl createConsole() {
143     Project project = getProject();
144     ConsoleViewImpl console = new ConsoleViewImpl(project,
145                                                   GlobalSearchScope.allScope(project),
146                                                   false,
147                                                   false);
148     console.getComponent();
149     ProcessHandler processHandler = new MyProcessHandler();
150     processHandler.startNotify();
151     console.attachToProcess(processHandler);
152     return console;
153   }
154
155   private static class MyProcessHandler extends ProcessHandler {
156     @Override
157     protected void destroyProcessImpl() {
158       notifyProcessTerminated(0);
159     }
160
161     @Override
162     protected void detachProcessImpl() {
163     }
164
165     @Override
166     public boolean detachIsDefault() {
167       return false;
168     }
169
170     @Nullable
171     @Override
172     public OutputStream getProcessInput() {
173       return null;
174     }
175   }
176 }