1 /*
2  * Copyright (c) 2007, 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  *
27  * @summary converted from VM Testbase nsk/jvmti/scenarios/hotswap/HS104/hs104t002.
28  * VM Testbase keywords: [quick, jpda, jvmti, noras, redefine, feature_hotswap]
29  * VM Testbase readme:
30  * Description :
31  * Case Name : Hotswap  hs104t002:
32  * class(es) in asynchronous manner within an JVMTI event
33  * when all fields (changed initial values), methods (changed bodies),
34  * attributes and the constant pool are changed in new class(es).
35  * Comments :
36  * All the threads would be invoking redefineClass method asynchronously,
37  * and redefine should be possible without any errors. Any error while redefining
38  * class is considered as test failure.
39  *
40  * @library /vmTestbase
41  *          /test/lib
42  * @run driver jdk.test.lib.FileInstaller . .
43  * @build nsk.jvmti.scenarios.hotswap.HS104.hs104t002.hs104t002
44  *
45  * @comment compile newclassXX to bin/newclassXX
46  * @run driver nsk.share.ExtraClassesBuilder
47  *      newclass00
48  *
49  * @run main/othervm/native
50  *      -agentlib:hs104t002=pathToNewByteCode=./bin
51  *      nsk.jvmti.scenarios.hotswap.HS104.hs104t002.hs104t002
52  */
53 
54 package nsk.jvmti.scenarios.hotswap.HS104.hs104t002;
55 
56 import nsk.share.jvmti.RedefineAgent;
57 import nsk.share.Wicket;
58 
59 /**
60  * This class extends <b>RedefineAgent</b>.
61  * @see nsk.share.jvmti.RedefineAgent
62  */
63 public class hs104t002 extends RedefineAgent {
64 
65     private static final int size = 30;
66 
67     private MyThread[] threadList = new MyThread[size];
68     private Wicket wicket;
69 
70     /**
71      * constructor for hs104t002.
72      */
hs104t002(String[] arg)73     public hs104t002(String[] arg) {
74         super(arg);
75         wicket = new Wicket();
76         for(int i=0; i < size; i++) {
77             threadList[i] = new MyThread(wicket);
78         }
79     }
80 
main(String[] arg)81     public static void main(String[] arg) {
82         arg = nsk.share.jvmti.JVMTITest.commonInit(arg);
83 
84         hs104t002 hsCase = new hs104t002(arg);
85         System.exit(hsCase.runAgent());
86     }
87 
88     /**
89      * A native method to redefine MyThread class.
90      */
redefineClasses()91     public static native void redefineClasses();
92 
93     /**
94      * Method is called from RedefineAgent work flow.
95      * @return boolean true. Considered true if and only if testcase passes.
96      */
agentMethod()97     public boolean agentMethod() {
98         boolean pass = false;
99         try {
100             if ( !startAllThreads() ) {
101                 return pass;
102             }
103             if ( !waitForAllThreads() ) {
104                 return pass;
105             }
106             if ( checkThreads() && redefineAttempted() &&
107                  isRedefined()  && agentStatus() ) {
108                 pass = true;
109             }
110         } catch(Exception exp) {
111             exp.printStackTrace();
112             // for any possible exception testcase is failure
113             pass=false;
114         }
115         if ( pass ) {
116             log.println(" Testcase hs104t002 :: Passed.");
117         } else {
118             log.println(" Testcase hs104t002 :: Failed.");
119         }
120         return pass;
121     }
122 
123     /**
124      * Would start all threads properly.
125      * @return boolean. Returns true only if all threads started properly
126      *
127      */
startAllThreads()128     public boolean startAllThreads() {
129         boolean started= false;
130         try {
131             for(MyThread thread : threadList) {
132                 thread.start();
133             }
134             //notify all the threads to start their jobs.
135             wicket.unlock();
136             started=true;
137             log.println(" startAllThreads :: All threads are running.");
138         } catch (IllegalStateException ise) {
139             log.complain(" startAllThreads :: Error occured while"
140                         +" waiting for threads.");
141             ise.printStackTrace();
142         }
143         return started;
144     }
145 
146     /**
147      * Checks for failure in redefineClass call.
148      * @return boolean true iff, all the threads could redefine successfully.
149      */
checkThreads()150     public boolean checkThreads() {
151         boolean passedAll = true;
152         int failedThreadCount=0;
153         for(MyThread thread : threadList) {
154             if (thread.getThreadState() != 100) {
155                 log.complain(" checkThreads :: Thread name ="+thread.getName()
156                      +", Expected state = 100, state = "
157                      +thread.getThreadState());
158                 failedThreadCount++;
159                 passedAll=false;
160             }
161         }
162         if ( !passedAll )  {
163             log.complain(" checkThreads :: Number of threads failed = "
164                  +failedThreadCount);
165         }
166 
167         return passedAll;
168     }
169 
170     /**
171      * @return boolean returns true iff all threads terminate properly.
172      */
waitForAllThreads()173     private boolean waitForAllThreads() {
174         boolean allExited = false;
175         try {
176             for(MyThread thread : threadList) {
177                 thread.join();
178             }
179             allExited= true;
180             log.println(" All threads terminated without "
181                 +"java.lang.InterruptedException.");
182         } catch(java.lang.InterruptedException ie ) {
183             log.complain(" waitForAllThreads ::"
184                  +" Got java.lang.InterruptedException."
185                  + "Test would fail.");
186             ie.printStackTrace();
187         }
188         return allExited;
189     }
190 }
191