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