blob: 20178cfb0ea7ef4f6a27d7b43fa8ef128c7e0aaf [file] [log] [blame]
Vinay Vishal57171472018-09-18 20:22:00 +05301/*
2 * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v. 2.0, which is available at
6 * http://www.eclipse.org/legal/epl-2.0.
7 *
8 * This Source Code may also be made available under the following Secondary
9 * Licenses when the conditions for such availability set forth in the
10 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11 * version 2 with the GNU Classpath Exception, which is available at
12 * https://www.gnu.org/software/classpath/license.html.
13 *
14 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15 */
16
17/*
18 * TestProgressObjectImpl.java
19 *
20 * Created on January 15, 2004, 10:10 AM
21 */
22
23import javax.enterprise.deploy.spi.status.ProgressListener;
24import org.glassfish.deployapi.ProgressObjectImpl;
25import org.glassfish.deployapi.TargetImpl;
26import org.glassfish.deployment.client.DeploymentFacilityFactory;
27import org.glassfish.deployment.client.DeploymentFacility;
28import org.glassfish.deployment.client.AbstractDeploymentFacility;
29import javax.enterprise.deploy.shared.StateType;
30
31import java.io.File;
32import java.io.PrintStream;
33import java.io.FileOutputStream;
34import java.io.FileNotFoundException;
35
36/**
37 *Makes sure that the ProgressObjectImpl class functions correctly.
38 *<p>
David Matějčekf4dc06a2021-05-17 12:10:57 +020039 *In particular, bug 4977764 reported that the ProgressObjectImpl class was susceptible to
Vinay Vishal57171472018-09-18 20:22:00 +053040 *concurrent update failures in the vector that holds registered progress listeners. The
41 *fireProgressEvent method worked with the vector of listeners itself rather than a clone of the vector.
42 *One of the listeners unregistered itself from the progress object, so when the iterator tried to
43 *get the next element it detected the concurrent update. So, the progress object now clones the vector
44 *temporarily in fireProgressEvent and iterates through the clone.
45 *
46 * @author tjquinn
47 */
48public class TestProgressObjectImpl {
49
50 private static final String here = "devtests/deployment/jsr88/misc";
David Matějčekf4dc06a2021-05-17 12:10:57 +020051
Vinay Vishal57171472018-09-18 20:22:00 +053052 /**
53 *Provides a concrete implementation of the progress object for testing. Note that the behavior being
54 *tested is actually that of the superclass ProgressObjectImpl.
55 */
56 public class MyProgressObjectImpl extends ProgressObjectImpl {
David Matějčekf4dc06a2021-05-17 12:10:57 +020057
Vinay Vishal57171472018-09-18 20:22:00 +053058 public MyProgressObjectImpl(TargetImpl target) {
59 super(target);
60 }
David Matějčekf4dc06a2021-05-17 12:10:57 +020061
Vinay Vishal57171472018-09-18 20:22:00 +053062 /**
63 *Required by the abstract class definition but not used during testing.
64 */
65 public void run() {}
David Matějčekf4dc06a2021-05-17 12:10:57 +020066
Vinay Vishal57171472018-09-18 20:22:00 +053067 /**
68 *Stands in as an operation that fires an event to registered listeners.
69 */
70 public void act() {
71 fireProgressEvent(StateType.RUNNING, "starting");
72 /*
73 *This is where any real work would be done. It's useful to test with two events just in case
74 *that would uncover any problems.
75 */
76 fireProgressEvent(StateType.COMPLETED, "done");
77 }
78 }
David Matějčekf4dc06a2021-05-17 12:10:57 +020079
Vinay Vishal57171472018-09-18 20:22:00 +053080 /**
81 *Adds a new listener during the event handling.
82 */
83 public class MeddlingListenerAdder implements ProgressListener {
David Matějčekf4dc06a2021-05-17 12:10:57 +020084
85
Vinay Vishal57171472018-09-18 20:22:00 +053086 public void handleProgressEvent(javax.enterprise.deploy.spi.status.ProgressEvent progressEvent) {
87 /*
88 *Meddle in the listener list by adding a new listener to the list. This should trigger the error
89 *in the original version of ProgressObjectImpl but should not in the fixed version.
90 */
91 TestProgressObjectImpl.this.theProgressObjectImpl.addProgressListener(new TestProgressObjectImpl.MeddlingListenerRemover());
92 }
David Matějčekf4dc06a2021-05-17 12:10:57 +020093
Vinay Vishal57171472018-09-18 20:22:00 +053094 }
David Matějčekf4dc06a2021-05-17 12:10:57 +020095
Vinay Vishal57171472018-09-18 20:22:00 +053096 /**
97 *Removes itself as a listener during the event handling.
98 */
99 public class MeddlingListenerRemover implements ProgressListener {
David Matějčekf4dc06a2021-05-17 12:10:57 +0200100
101
Vinay Vishal57171472018-09-18 20:22:00 +0530102 public void handleProgressEvent(javax.enterprise.deploy.spi.status.ProgressEvent progressEvent) {
103 /*
104 *Meddle in the listener list by removing itself from the list. This should trigger the error
105 *in the original version of ProgressObjectImpl but should not in the fixed version.
106 */
107 TestProgressObjectImpl.this.theProgressObjectImpl.removeProgressListener(this);
108 }
David Matějčekf4dc06a2021-05-17 12:10:57 +0200109
Vinay Vishal57171472018-09-18 20:22:00 +0530110 }
David Matějčekf4dc06a2021-05-17 12:10:57 +0200111
Vinay Vishal57171472018-09-18 20:22:00 +0530112 /* Local progress object implementation to be tested. */
113 private MyProgressObjectImpl theProgressObjectImpl;
David Matějčekf4dc06a2021-05-17 12:10:57 +0200114
Vinay Vishal57171472018-09-18 20:22:00 +0530115 /** Creates a new instance of TestProgressObjectImpl */
116 public TestProgressObjectImpl() {
117 }
David Matějčekf4dc06a2021-05-17 12:10:57 +0200118
Vinay Vishal57171472018-09-18 20:22:00 +0530119 /**
120 * @param args the command line arguments
121 */
122 public static void main(String[] args) {
123 TestProgressObjectImpl test = new TestProgressObjectImpl();
124 try {
125 test.run(args);
126 test.pass();
127 } catch (Throwable th) {
128 th.printStackTrace(System.out);
129 test.fail();
130 }
131 }
David Matějčekf4dc06a2021-05-17 12:10:57 +0200132
Vinay Vishal57171472018-09-18 20:22:00 +0530133 public void run(String[] args) {
134 addNewListenerDuringEventHandling();
135 }
136
137 /**
David Matějčekf4dc06a2021-05-17 12:10:57 +0200138 * Tamper with the listener list by adding a new listener during event handling.
Vinay Vishal57171472018-09-18 20:22:00 +0530139 */
140 private void addNewListenerDuringEventHandling() {
141 /*
142 *Create a TargetImpl just to satisfy the signature of the constructor for the progress object implementation.
143 */
144 DeploymentFacility df = DeploymentFacilityFactory.getDeploymentFacility();
145 TargetImpl target = new TargetImpl((AbstractDeploymentFacility)df, "test", "test");
146 theProgressObjectImpl = new MyProgressObjectImpl(target);
147 TestProgressObjectImpl.MeddlingListenerAdder meddlingListener1 = new TestProgressObjectImpl.MeddlingListenerAdder();
148 TestProgressObjectImpl.MeddlingListenerAdder meddlingListener2 = new TestProgressObjectImpl.MeddlingListenerAdder();
David Matějčekf4dc06a2021-05-17 12:10:57 +0200149
Vinay Vishal57171472018-09-18 20:22:00 +0530150 theProgressObjectImpl.addProgressListener(meddlingListener1);
151 theProgressObjectImpl.addProgressListener(meddlingListener2);
David Matějčekf4dc06a2021-05-17 12:10:57 +0200152
Vinay Vishal57171472018-09-18 20:22:00 +0530153 /*
154 *Fire an event that will change the listener set.
155 */
156 theProgressObjectImpl.act();
David Matějčekf4dc06a2021-05-17 12:10:57 +0200157
Vinay Vishal57171472018-09-18 20:22:00 +0530158 }
David Matějčekf4dc06a2021-05-17 12:10:57 +0200159
Vinay Vishal57171472018-09-18 20:22:00 +0530160 private void log(String message) {
161 System.out.println("[TestProgressObjectImpl]:: " + message);
162 }
163
164 private void pass() {
165 log("PASSED: " + here);
166 System.exit(0);
167 }
168
169 private void fail() {
170 log("FAILED: " + here);
171 System.exit(-1);
172 }
173}