1 /*
   2  * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package test.javafx.scene.control;
  27 
  28 import static org.junit.Assert.assertEquals;
  29 import static org.junit.Assert.assertTrue;
  30 
  31 import java.lang.ref.Reference;
  32 import java.lang.ref.ReferenceQueue;
  33 import java.lang.ref.WeakReference;
  34 import java.util.ArrayList;
  35 import javafx.geometry.Pos;
  36 import javafx.scene.control.Alert;
  37 import javafx.scene.control.ProgressIndicator;
  38 import javafx.scene.Scene;
  39 import javafx.stage.Stage;
  40 import javafx.scene.layout.HBox;
  41 import javafx.scene.layout.StackPane;
  42 import javafx.scene.layout.VBox;
  43 import com.sun.javafx.tk.Toolkit;
  44 
  45 import org.junit.Before;
  46 import org.junit.Test;
  47 
  48 /**
  49  */
  50 public class ProgressIndicatorTest {
  51     Toolkit tk;
  52 
  53     @Before public void setup() {
  54         tk = Toolkit.getToolkit();
  55     }
  56 
  57     @Test public void progressIndicatorHeightTest() {
  58         ProgressIndicator pi = new ProgressIndicator(0.5);
  59 
  60         HBox hb = new HBox();
  61         hb.setAlignment(Pos.CENTER);
  62         hb.getChildren().addAll(pi);
  63 
  64         Scene scene = new Scene(hb, 400, 400);
  65         Stage stage = new Stage();
  66         stage.setScene(scene);
  67         stage.show();
  68         tk.firePulse();
  69 
  70         // Test the ProgressIndicator height is non zero and
  71         // does not occupy entire height of the scene.
  72         int x = Double.compare(0.0, pi.getHeight());
  73         assertTrue(x != 0);
  74 
  75         x = Double.compare(400.0, pi.getHeight());
  76         assertTrue(x != 0);
  77     }
  78 
  79     @Test public void progressIndicatorWidthTest() {
  80         ProgressIndicator pi = new ProgressIndicator(0.5);
  81 
  82         VBox vb = new VBox();
  83         vb.setAlignment(Pos.CENTER);
  84         vb.getChildren().addAll(pi);
  85 
  86         Scene scene = new Scene(vb, 400, 400);
  87         Stage stage = new Stage();
  88         stage.setScene(scene);
  89         stage.show();
  90 
  91         tk.firePulse();
  92 
  93         // Test the ProgressIndicator width is non zero and
  94         // does not occupy entire width of the scene.
  95         int x = Double.compare(0.0, pi.getWidth());
  96         assertTrue(x != 0);
  97 
  98         x = Double.compare(400.0, pi.getWidth());
  99         assertTrue(x != 0);
 100     }
 101 
 102     final static int TOTAL_PROGRESS_INDICATORS = 10;
 103     private ArrayList<WeakReference<ProgressIndicator>> weakRefArr = 
 104                                       new ArrayList(TOTAL_PROGRESS_INDICATORS);
 105 
 106     @Test public void memoryLeakTest_JDK_8189265_stage() {
 107         testProgressIndicatorObjectsInStage();
 108 
 109         attemptGC(10);
 110 
 111         assertEquals(TOTAL_PROGRESS_INDICATORS, getCleanedUpObjectCount());
 112 
 113         weakRefArr.clear();
 114     }
 115 
 116     @Test public void memoryLeakTest_JDK_8189265_alert() {
 117         testProgressIndicatorObjectsInAlert();
 118 
 119         attemptGC(10);
 120 
 121         assertEquals(TOTAL_PROGRESS_INDICATORS, getCleanedUpObjectCount());
 122 
 123         weakRefArr.clear();
 124     }
 125 
 126     private void testProgressIndicatorObjectsInStage() {
 127         ProgressIndicator pi[] = new ProgressIndicator[TOTAL_PROGRESS_INDICATORS];
 128         HBox hb = new HBox();
 129 
 130         for (int i = 0; i < TOTAL_PROGRESS_INDICATORS; i++) {
 131             pi[i] = new ProgressIndicator();
 132             weakRefArr.add(i, new WeakReference<ProgressIndicator>(pi[i]));
 133             hb.getChildren().add(pi[i]);
 134         }
 135 
 136         Stage stage = new Stage();
 137         Scene scene = new Scene(hb);
 138         stage.setScene(scene);
 139         stage.show();
 140 
 141         tk.firePulse();
 142 
 143         stage.close();
 144         tk.firePulse();
 145     }
 146 
 147     private void testProgressIndicatorObjectsInAlert() {
 148         ProgressIndicator pi[] = new ProgressIndicator[TOTAL_PROGRESS_INDICATORS];
 149         StackPane root = new StackPane();
 150 
 151         for (int i = 0; i < TOTAL_PROGRESS_INDICATORS; i++) {
 152             pi[i] = new ProgressIndicator();
 153             weakRefArr.add(i, new WeakReference<ProgressIndicator>(pi[i]));
 154             root.getChildren().add(pi[i]);
 155         }
 156 
 157         Alert dialog = new Alert(Alert.AlertType.INFORMATION);
 158         dialog.getDialogPane().setContent(root);
 159         dialog.show();
 160         tk.firePulse();
 161 
 162         dialog.close();
 163         tk.firePulse();
 164     }
 165 
 166     private void attemptGC(int n) {
 167         // Attempt gc n times
 168         for (int i = 0; i < n; i++) {
 169             System.gc();
 170             System.runFinalization();
 171             try {
 172                 Thread.sleep(500);
 173             } catch (InterruptedException e) {
 174                 System.err.println("InterruptedException occurred during Thread.sleep()");
 175             }
 176         }
 177     }
 178 
 179     private int getCleanedUpObjectCount() {
 180         int count = 0;
 181         for (int i = 0; i < TOTAL_PROGRESS_INDICATORS; i++) {
 182             if (weakRefArr.get(i).get() == null) {
 183                 count++;
 184             }
 185         }
 186         return count;
 187     }
 188 }