1 /*
   2  * Copyright (c) 2018, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @bug 8153732
  27  * @requires (os.family == "Windows")
  28  * @summary Windows remote printer changes do not reflect in lookupPrintServices()
  29  * @run main/manual RemotePrinterStatusRefresh
  30  */
  31 
  32 import java.awt.GridBagConstraints;
  33 import java.awt.GridBagLayout;
  34 import java.awt.event.ActionEvent;
  35 import java.awt.print.PageFormat;
  36 import java.awt.print.Paper;
  37 import java.awt.print.PrinterException;
  38 import java.util.concurrent.CountDownLatch;
  39 import java.util.concurrent.TimeUnit;
  40 import javax.swing.BorderFactory;
  41 import javax.swing.Box;
  42 import javax.swing.JButton;
  43 import javax.swing.JFrame;
  44 import javax.swing.JLabel;
  45 import javax.swing.JPanel;
  46 import javax.swing.JTextArea;
  47 import javax.swing.SwingUtilities;
  48 import java.awt.print.PrinterJob;
  49 import javax.print.PrintService;
  50 
  51 public class RemotePrinterStatusRefresh
  52 {
  53     private static TestUI test = null;
  54     public static void main(String args[]) throws Exception {
  55         final CountDownLatch latch = new CountDownLatch(1);
  56 
  57         // Test UI creation
  58         test = new TestUI(latch);
  59 
  60         SwingUtilities.invokeAndWait(new Runnable() {
  61             @Override
  62             public void run() {
  63                 try {
  64                     test.createUI();
  65                 } catch (Exception e) {
  66                     throw new RuntimeException(e);
  67                 }
  68             }
  69         });
  70 
  71         // RemotePrinterStatusRefresh creation
  72         RemotePrinterStatusRefresh RemotePrinterStatusRefresh = new RemotePrinterStatusRefresh();
  73         SwingUtilities.invokeAndWait(() -> {
  74             collectPrintersList(test.resultsTextArea, true);
  75         });
  76 
  77         // 8 min = 480000 msec
  78         if(waitForFlag(480000)) {
  79             SwingUtilities.invokeAndWait(() -> {
  80                 collectPrintersList(test.resultsTextArea, false);
  81             });
  82         } else {
  83             dispose();
  84             throw new RuntimeException("No new network printer got added/removed!! Test timed out!!");
  85         }
  86 
  87         boolean status = latch.await(1, TimeUnit.MINUTES);
  88         if (!status) {
  89             dispose();
  90             throw new RuntimeException("Test timed out.");
  91         }
  92 
  93         if (test.testResult == false) {
  94             dispose();
  95             throw new RuntimeException("Test Failed.");
  96         }
  97 
  98         dispose();
  99     }
 100 
 101     public static void dispose() throws Exception {
 102         SwingUtilities.invokeAndWait(() -> {
 103             test.disposeUI();
 104         });
 105     }
 106 
 107     public static boolean waitForFlag (long maxTimeoutInMsec) throws Exception {
 108         while(!test.isAdded && maxTimeoutInMsec > 0) {
 109             maxTimeoutInMsec -= 100;
 110             Thread.sleep(100);
 111         }
 112 
 113         if(maxTimeoutInMsec <= 0) {
 114             return false;
 115         } else {
 116             return true;
 117         }
 118     }
 119 
 120     private static void collectPrintersList(JTextArea textArea, boolean before) {
 121         if(before) {
 122             System.out.println("List of printers(before): ");
 123             textArea.setText("List of printers(before): \n");
 124             for (PrintService printServiceBefore : PrinterJob.lookupPrintServices()) {
 125                 System.out.println(printServiceBefore);
 126                 textArea.append(printServiceBefore.toString());
 127                 textArea.append("\n");
 128             }
 129         } else {
 130             textArea.append("\n");
 131             System.out.println("List of printers(after): ");
 132             textArea.append("List of printers(after): \n");
 133             for (PrintService printServiceAfter : PrinterJob.lookupPrintServices()) {
 134                 System.out.println(printServiceAfter);
 135                 textArea.append(printServiceAfter.toString());
 136                 textArea.append("\n");
 137             }
 138         }
 139     }
 140 }
 141 
 142 class TestUI {
 143     private static JFrame mainFrame;
 144     private static JPanel mainControlPanel;
 145 
 146     private static JTextArea instructionTextArea;
 147 
 148     private static JPanel resultButtonPanel;
 149     private static JButton passButton;
 150     private static JButton failButton;
 151     private static JButton addedButton;
 152 
 153     private static JPanel testPanel;
 154     private static JButton testButton;
 155     private static JLabel buttonPressCountLabel;
 156 
 157     private static GridBagLayout layout;
 158     private final CountDownLatch latch;
 159     public boolean testResult = false;
 160     public volatile Boolean isAdded = false;
 161     public static JTextArea resultsTextArea;
 162 
 163     public TestUI(CountDownLatch latch) throws Exception {
 164         this.latch = latch;
 165     }
 166 
 167     public final void createUI() {
 168         mainFrame = new JFrame("RemotePrinterStatusRefresh");
 169         layout = new GridBagLayout();
 170         mainControlPanel = new JPanel(layout);
 171         resultButtonPanel = new JPanel(layout);
 172         testPanel = new JPanel(layout);
 173         GridBagConstraints gbc = new GridBagConstraints();
 174 
 175         // Create Test instructions
 176         String instructions
 177                 = "This test displays the current list of printers(before) attached to \n"
 178                 + "this computer in the results panel.\n\n"
 179                 + "Please follow the below steps for this manual test\n"
 180                 + "--------------------------------------------------------------------\n"
 181                 + "Step 1: Add/Remove a new network printer and Wait for 4 minutes after adding/removing\n"
 182                 + "Step 2: Then click on 'Printer Added/Removed' button\n"
 183                 + "Step 2: Once the new network printer is added/removed, see if it is \n"
 184                 + "        the same as displayed/not displayed in the results panel.\n"
 185                 + "Step 3: If displayed/not displayed, then click 'Pass' else click on 'Fail' button";
 186 
 187         instructionTextArea = new JTextArea();
 188         instructionTextArea.setText(instructions);
 189         instructionTextArea.setEditable(false);
 190         instructionTextArea.setBorder(BorderFactory.
 191                 createTitledBorder("Test Instructions"));
 192 
 193         gbc.gridx = 0;
 194         gbc.gridy = 0;
 195         gbc.fill = GridBagConstraints.HORIZONTAL;
 196         mainControlPanel.add(instructionTextArea, gbc);
 197 
 198         gbc.gridx = 0;
 199         gbc.gridy = 1;
 200         testPanel.add(Box.createVerticalStrut(50));
 201         mainControlPanel.add(testPanel);
 202 
 203         addedButton = new JButton("Printer Added/Removed");
 204         addedButton.setActionCommand("Added");
 205         addedButton.addActionListener((ActionEvent e) -> {
 206             System.out.println("Added Button pressed!");
 207             isAdded = true;
 208         });
 209 
 210         // Create resultButtonPanel with Pass, Fail buttons
 211         passButton = new JButton("Pass");
 212         passButton.setActionCommand("Pass");
 213         passButton.addActionListener((ActionEvent e) -> {
 214             System.out.println("Pass Button pressed!");
 215             testResult = true;
 216             latch.countDown();
 217             disposeUI();
 218         });
 219 
 220         failButton = new JButton("Fail");
 221         failButton.setActionCommand("Fail");
 222         failButton.addActionListener((ActionEvent e) -> {
 223             System.out.println("Fail Button pressed!");
 224             testResult = false;
 225             latch.countDown();
 226             disposeUI();
 227         });
 228         
 229         gbc.gridx = 0;
 230         gbc.gridy = 0;
 231         resultButtonPanel.add(addedButton, gbc);
 232 
 233         gbc.gridx = 1;
 234         gbc.gridy = 0;
 235         resultButtonPanel.add(passButton, gbc);
 236 
 237         gbc.gridx = 2;
 238         gbc.gridy = 0;
 239         resultButtonPanel.add(failButton, gbc);
 240 
 241         resultsTextArea = new JTextArea();
 242         resultsTextArea.setEditable(false);
 243         resultsTextArea.setBorder(BorderFactory.
 244                 createTitledBorder("Results"));
 245 
 246         gbc.gridx = 0;
 247         gbc.gridy = 1;
 248         gbc.fill = GridBagConstraints.HORIZONTAL;
 249         mainControlPanel.add(resultsTextArea, gbc);
 250 
 251         gbc.gridx = 0;
 252         gbc.gridy = 2;        
 253         mainControlPanel.add(resultButtonPanel, gbc);
 254 
 255         mainFrame.add(mainControlPanel);
 256         mainFrame.pack();
 257         mainFrame.setVisible(true);
 258     }
 259 
 260     public void disposeUI() {
 261         mainFrame.dispose();
 262     }
 263 }