001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.apisupport.project.suite;
043:
044: import java.io.File;
045: import java.io.FileOutputStream;
046: import java.io.IOException;
047: import java.io.InputStream;
048: import java.net.URL;
049: import java.util.ArrayList;
050: import java.util.Arrays;
051: import java.util.Enumeration;
052: import java.util.LinkedList;
053: import java.util.List;
054: import java.util.jar.JarEntry;
055: import java.util.jar.JarFile;
056: import java.util.logging.Level;
057: import java.util.logging.Logger;
058: import org.netbeans.api.project.ProjectManager;
059: import org.netbeans.modules.apisupport.project.DialogDisplayerImpl;
060: import org.netbeans.modules.apisupport.project.InstalledFileLocatorImpl;
061: import org.netbeans.modules.apisupport.project.NbModuleProject;
062: import org.netbeans.modules.apisupport.project.TestBase;
063: import org.netbeans.modules.apisupport.project.layers.LayerTestBase;
064: import org.netbeans.modules.apisupport.project.ui.SuiteActions;
065: import org.netbeans.spi.project.ActionProvider;
066: import org.netbeans.spi.project.support.ant.AntProjectHelper;
067: import org.netbeans.spi.project.support.ant.EditableProperties;
068: import org.openide.DialogDescriptor;
069: import org.openide.execution.ExecutorTask;
070: import org.openide.filesystems.FileObject;
071: import org.openide.filesystems.FileUtil;
072: import org.openide.util.NbCollections;
073: import org.openide.util.Utilities;
074:
075: /**
076: * Checks building of ZIP support.
077: * @author Jaroslav Tulach
078: */
079: public class BuildZipDistributionTest extends TestBase {
080:
081: static {
082: // #65461: do not try to load ModuleInfo instances from ant module
083: System.setProperty(
084: "org.netbeans.core.startup.ModuleSystem.CULPRIT",
085: "true");
086: LayerTestBase.Lkp.setLookup(new Object[0]);
087: }
088:
089: private SuiteProject suite;
090: private Logger LOG;
091:
092: public BuildZipDistributionTest(String name) {
093: super (name);
094: }
095:
096: @Override
097: protected Level logLevel() {
098: return Level.FINE;
099: }
100:
101: protected @Override
102: void setUp() throws Exception {
103: clearWorkDir();
104:
105: LOG = Logger.getLogger("test." + getName());
106:
107: super .setUp();
108:
109: InstalledFileLocatorImpl.registerDestDir(destDirF);
110:
111: suite = TestBase.generateSuite(new File(getWorkDir(),
112: "projects"), "suite");
113: NbModuleProject proj = TestBase.generateSuiteComponent(suite,
114: "mod1");
115:
116: suite.open();
117: proj.open();
118:
119: LOG.info("Workdir " + getWorkDirPath());
120: }
121:
122: public void testBuildTheZipAppWhenAppNamePropIsNotSet()
123: throws Exception {
124: SuiteActions p = (SuiteActions) suite.getLookup().lookup(
125: ActionProvider.class);
126: assertNotNull("Provider is here", p);
127:
128: List l = Arrays.asList(p.getSupportedActions());
129: assertTrue("We support build-zip: " + l, l
130: .contains("build-zip"));
131:
132: DialogDisplayerImpl
133: .returnFromNotify(DialogDescriptor.NO_OPTION);
134: ExecutorTask task = p.invokeActionImpl("build-zip", suite
135: .getLookup());
136: assertNull("did not even run task", task);
137: }
138:
139: public void testBuildTheZipAppWhenAppNamePropIsSet()
140: throws Exception {
141: EditableProperties ep = suite.getHelper().getProperties(
142: AntProjectHelper.PROJECT_PROPERTIES_PATH);
143: ep.setProperty("app.name", "fakeapp");
144:
145: ep.setProperty("enabled.clusters", TestBase.CLUSTER_PLATFORM);
146: ep.setProperty("disabled.modules",
147: "org.netbeans.modules.autoupdate,"
148: + "org.openide.compat,"
149: + "org.netbeans.api.progress,"
150: + "org.netbeans.core.multiview,"
151: + "org.openide.util.enumerations" + "");
152: suite.getHelper().putProperties(
153: AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
154: ProjectManager.getDefault().saveProject(suite);
155:
156: SuiteActions p = (SuiteActions) suite.getLookup().lookup(
157: ActionProvider.class);
158: assertNotNull("Provider is here", p);
159:
160: List l = Arrays.asList(p.getSupportedActions());
161: assertTrue("We support build-zip: " + l, l
162: .contains("build-zip"));
163:
164: DialogDisplayerImpl
165: .returnFromNotify(DialogDescriptor.NO_OPTION);
166: ExecutorTask task = p.invokeActionImpl("build-zip", suite
167: .getLookup());
168:
169: assertNotNull("Task was started", task);
170: assertEquals("Finished ok", 0, task.result());
171:
172: FileObject[] arr = suite.getProjectDirectory().getChildren();
173: List<FileObject> subobj = new ArrayList<FileObject>(Arrays
174: .asList(arr));
175: subobj
176: .remove(suite.getProjectDirectory().getFileObject(
177: "mod1"));
178: subobj.remove(suite.getProjectDirectory().getFileObject(
179: "nbproject"));
180: subobj.remove(suite.getProjectDirectory().getFileObject(
181: "build.xml"));
182: subobj.remove(suite.getProjectDirectory()
183: .getFileObject("build"));
184: FileObject dist = suite.getProjectDirectory().getFileObject(
185: "dist");
186: assertNotNull("dist created", dist);
187: subobj.remove(dist);
188:
189: if (!subobj.isEmpty()) {
190: fail("There should be no created directories in the suite dir: "
191: + subobj);
192: }
193:
194: FileObject zip = dist.getFileObject("fakeapp.zip");
195: assertNotNull("ZIP file created: " + zip, zip);
196:
197: File zipF = FileUtil.toFile(zip);
198: JarFile zipJ = new JarFile(zipF);
199: Enumeration en = zipJ.entries();
200: int cntzip = 0;
201:
202: StringBuffer sb = new StringBuffer();
203: StringBuffer hidden = new StringBuffer();
204: while (en.hasMoreElements()) {
205: JarEntry entry = (JarEntry) en.nextElement();
206: sb.append("\n");
207: sb.append(entry.getName());
208: cntzip++;
209:
210: if (entry.getName().endsWith("_hidden")) {
211: hidden.append("\n");
212: hidden.append(entry.getName());
213: }
214: }
215:
216: if (cntzip == 0) {
217: fail("There should be at least one zip entry: " + sb);
218: }
219:
220: if (hidden.length() != 0) {
221: fail("There should be no hidden files in the zip file: "
222: + hidden);
223: }
224:
225: File expand = new File(getWorkDir(), "expand");
226: JarFile f = new JarFile(FileUtil.toFile(zip));
227: for (JarEntry jarEntry : NbCollections.iterable(f.entries())) {
228: String path = jarEntry.getName().replace('/',
229: File.separatorChar);
230: if (path.endsWith(File.separator)) {
231: continue;
232: }
233: File entry = new File(expand, path);
234: entry.getParentFile().mkdirs();
235: FileOutputStream os = new FileOutputStream(entry);
236: FileUtil.copy(f.getInputStream(jarEntry), os);
237: os.close();
238: }
239:
240: File root = new File(expand, "fakeapp");
241: File launch;
242: if (Utilities.isWindows()) {
243: launch = new File(new File(root, "bin"), "fakeapp.exe");
244: } else {
245: launch = new File(new File(root, "bin"), "fakeapp");
246: }
247:
248: assertTrue("Launcher exists " + launch, launch.canRead());
249:
250: run(launch, "*");
251:
252: String[] args = MainCallback.getArgs(getWorkDir());
253:
254: if (!Arrays.asList(args).contains("*")) {
255: fail("There should be a * in\n" + Arrays.asList(args));
256: }
257: }
258:
259: private File createNewJarFile(String prefix) throws IOException {
260: if (prefix == null) {
261: prefix = "modules";
262: }
263:
264: File dir = new File(this .getWorkDir(), prefix);
265: dir.mkdirs();
266:
267: int i = 0;
268: for (;;) {
269: File f = new File(dir, i++ + ".jar");
270: if (!f.exists()) {
271: f.createNewFile();
272: return f;
273: }
274: }
275: }
276:
277: private void run(File nbexec, String... args) throws Exception {
278:
279: URL tu = MainCallback.class.getProtectionDomain()
280: .getCodeSource().getLocation();
281: File testf = new File(tu.toURI());
282: assertTrue("file found: " + testf, testf.exists());
283:
284: LinkedList<String> allArgs = new LinkedList<String>(Arrays
285: .asList(args));
286: allArgs.addFirst("-J-Dnetbeans.mainclass="
287: + MainCallback.class.getName());
288: allArgs.addFirst(getWorkDirPath());
289: allArgs.addFirst("--userdir");
290: allArgs.addFirst(testf.getPath());
291: allArgs.addFirst("-cp:p");
292:
293: if (!Utilities.isWindows()) {
294: allArgs.addFirst(nbexec.getPath());
295: allArgs.addFirst("-x");
296: allArgs.addFirst("/bin/sh");
297: } else {
298: allArgs.addFirst(nbexec.getPath());
299: }
300:
301: String[] envp = { "jdkhome=" + System.getProperty("java.home") };
302:
303: StringBuffer sb = new StringBuffer();
304: Process p = Runtime.getRuntime().exec(
305: allArgs.toArray(new String[0]), envp,
306: nbexec.getParentFile());
307: int res = readOutput(sb, p);
308:
309: String output = sb.toString();
310:
311: assertEquals("Execution is ok: " + output, 0, res);
312: }
313:
314: private static int readOutput(final StringBuffer sb, Process p)
315: throws Exception {
316: class Read extends Thread {
317: private InputStream is;
318:
319: public Read(String name, InputStream is) {
320: super (name);
321: this .is = is;
322: setDaemon(true);
323: }
324:
325: @Override
326: public void run() {
327: byte[] arr = new byte[4096];
328: try {
329: for (;;) {
330: int len = is.read(arr);
331: if (len == -1) {
332: return;
333: }
334: sb.append(new String(arr, 0, len));
335: }
336: } catch (IOException ex) {
337: ex.printStackTrace();
338: }
339: }
340: }
341:
342: Read out = new Read("out", p.getInputStream());
343: Read err = new Read("err", p.getErrorStream());
344: out.start();
345: err.start();
346:
347: int res = p.waitFor();
348:
349: out.interrupt();
350: err.interrupt();
351: out.join();
352: err.join();
353:
354: return res;
355: }
356:
357: }
|