• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 /*
19  * $Id$
20  */
21 
22 /*
23  *
24  * ParameterTest.java
25  *
26  */
27 package org.apache.qetest.trax;
28 
29 import android.platform.test.annotations.FlakyTest;
30 import java.io.BufferedReader;
31 import java.io.File;
32 import java.io.FileInputStream;
33 import java.io.IOException;
34 import java.io.InputStreamReader;
35 import java.util.Properties;
36 
37 import javax.xml.transform.Source;
38 import javax.xml.transform.Templates;
39 import javax.xml.transform.Transformer;
40 import javax.xml.transform.TransformerFactory;
41 import javax.xml.transform.stream.StreamResult;
42 import javax.xml.transform.stream.StreamSource;
43 
44 import org.apache.qetest.FileBasedTest;
45 import org.apache.qetest.Logger;
46 import org.apache.qetest.OutputNameManager;
47 import org.apache.qetest.QetestUtils;
48 import org.apache.qetest.xsl.XSLTestfileInfo;
49 import org.apache.xml.utils.DefaultErrorHandler;
50 import org.junit.Test;
51 
52 //-------------------------------------------------------------------------
53 
54 /**
55  * Functional test of various usages of parameters in transforms.
56  * @author shane_curcuru@lotus.com
57  * @version $Id$
58  */
59 public class ParameterTest extends FileBasedTest
60 {
61 
62     /**
63      * Provides nextName(), currentName() functionality for tests
64      * that may produce any number of output files.
65      */
66     protected OutputNameManager outNames;
67 
68     /** Information about an xsl/xml file pair for transforming.  */
69     protected XSLTestfileInfo paramTest = new XSLTestfileInfo();
70 
71     /** Information about an xsl/xml file pair for transforming.  */
72     protected XSLTestfileInfo paramTest2 = new XSLTestfileInfo();
73 
74     /** Subdirectory under test\tests\api for our xsl/xml files.  */
75     public static final String TRAX_SUBDIR = "trax";
76 
77 
78     /** Just initialize test name, comment, numTestCases. */
ParameterTest()79     public ParameterTest()
80     {
81         numTestCases = 3;  // REPLACE_num
82         testName = "ParameterTest";
83         testComment = "Functional test of various usages of parameters in transforms";
84     }
85 
86 
87     /**
88      * Initialize this test - Set names of xml/xsl test files, etc.
89      *
90      * @param p Properties to initialize from (if needed)
91      * @return false if we should abort the test; true otherwise
92      */
doTestFileInit(Properties p)93     public boolean doTestFileInit(Properties p)
94     {
95         File outSubDir = new File(outputDir + File.separator + TRAX_SUBDIR);
96         if (!outSubDir.mkdirs())
97             reporter.logWarningMsg("Could not create output dir: " + outSubDir);
98         // Initialize an output name manager to that dir with .out extension
99         outNames = new OutputNameManager(outputDir + File.separator + TRAX_SUBDIR
100                                          + File.separator + testName, ".out");
101 
102         String testBasePath = inputDir
103                               + File.separator
104                               + TRAX_SUBDIR
105                               + File.separator;
106         String goldBasePath = goldDir
107                               + File.separator
108                               + TRAX_SUBDIR
109                               + File.separator;
110 
111         paramTest.inputName = QetestUtils.filenameToURL(testBasePath + "ParameterTest.xsl");
112         paramTest.xmlName = QetestUtils.filenameToURL(testBasePath + "ParameterTest.xml");
113 
114         paramTest2.inputName = QetestUtils.filenameToURL(testBasePath + "ParameterTest2.xsl");
115         paramTest2.xmlName = QetestUtils.filenameToURL(testBasePath + "ParameterTest2.xml");
116         return true;
117     }
118 
119 
120     /** Array of test data for parameter testing.  */
121     protected String paramTests[][] =
122     {
123         // { paramName to test,
124         //   paramValue to test
125         //   expected output string,
126         //   description of the test
127         // }
128         {
129             "t1",
130             "'a'",
131             "<outt>false-notset,false-blank,false-a,false-1,'a'</outt>",
132             "(10)Select expr of a 'param' string"
133         },
134         {
135             "t1",
136             "a",
137             "<outt>false-notset,false-blank,true-a,false-1,a</outt>",
138             "(10a)Select expr of a param string"
139         },
140         {
141             "t1",
142             "'1'",
143             "<outt>false-notset,false-blank,false-a,false-1,'1'</outt>",
144             "(11)Select expr of a 'param' number"
145         },
146         {
147             "t1",
148             "1",
149             "<outt>false-notset,false-blank,false-a,true-1,1</outt>",
150             "(11a)Select expr of a param number"
151         },
152         {
153             "t1",
154             "''",
155             "<outt>false-notset,false-blank,false-a,false-1,''</outt>",
156             "(12)Select expr of a param 'blank' string"
157         },
158         {
159             "t1",
160             "",
161             "<outt>false-notset,true-blank,false-a,false-1,</outt>",
162             "(12a)Select expr of a param blank string"
163         },
164         /*{
165             "t1",
166             null,
167             "<outt>false-notset,false-blank,false-a,false-1,</outt>",
168             "(12b)Select expr of a null"
169         },*/
170         {
171             "p1",
172             "'foo'",
173             "'foo','foo';",
174             "(13)Stylesheet with literal 'param' value"
175         },
176         {
177             "p1",
178             "foo",
179             "foo,foo;",
180             "(13a)Stylesheet with literal param value"
181         },
182         {
183             "p1",
184             "'bar'",
185             "'bar','bar';",
186             "(14)Stylesheet with replaced/another literal 'param' value"
187         },
188         {
189             "p1",
190             "bar",
191             "bar,bar;",
192             "(14a)Stylesheet with replaced/another literal param value"
193         },
194         {
195             "p2",
196             "'&lt;item&gt;bar&lt;/item&gt;'",
197             "'&amp;lt;item&amp;gt;bar&amp;lt;/item&amp;gt;','&amp;lt;item&amp;gt;bar&amp;lt;/item&amp;gt;'; GHI,<B>GHI</B>; </outp>",
198             "(15)Stylesheet with 'param' value with nodes"
199         },
200         {
201             "p2",
202             "&lt;item&gt;bar&lt;/item&gt;",
203             "&amp;lt;item&amp;gt;bar&amp;lt;/item&amp;gt;,&amp;lt;item&amp;gt;bar&amp;lt;/item&amp;gt;;",
204             "(15a)Stylesheet with param value with nodes"
205         },
206         {
207             "p3",
208             "'foo3'",
209             "GHI,<B>GHI</B>;",
210             "(16)Stylesheet with literal 'param' value in a template, is not passed"
211         },
212         {
213             "p3",
214             "foo3",
215             "GHI,<B>GHI</B>;",
216             "(16a)Stylesheet with literal param value in a template, is not passed"
217         },
218         {
219             "s1",
220             "'foos'",
221             "'foos','foos';",
222             "(17)Stylesheet with literal 'param' select"
223         },
224         {
225             "s1",
226             "foos",
227             "foos,foos;",
228             "(17a)Stylesheet with literal param select"
229         },
230         {
231             "s1",
232             "'bars'",
233             "<outs>'bars','bars'; s2val,s2val; s3val,s3val; </outs>",
234             "(18)Stylesheet with replaced/another literal 'param' select"
235         },
236         {
237             "s1",
238             "bars",
239             "<outs>bars,bars; s2val,s2val; s3val,s3val; </outs>",
240             "(18a)Stylesheet with replaced/another literal param select"
241         },
242         {
243             "s2",
244             "'&lt;item/&gt;'",
245             "'&amp;lt;item/&amp;gt;','&amp;lt;item/&amp;gt;'; s3val,s3val; </outs>",
246             "(19)Stylesheet with nodes(?) 'param' select"
247         },
248         {
249             "s2",
250             "&lt;item/&gt;",
251             "&amp;lt;item/&amp;gt;,&amp;lt;item/&amp;gt;; s3val,s3val; </outs>",
252             "(19a)Stylesheet with nodes(?) param select"
253         },
254         {
255             "s3",
256             "foos3",
257             "s3val,s3val;",
258             "(20)Stylesheet with literal 'param' select in a template, is not passed"
259         },
260     }; // end of paramTests array
261 
262 
263     /**
264      * Setting various string-valued params.
265      * Just loops through array of simple test data.
266      *
267      * @return false if we should abort the test; true otherwise
268      */
testCase1()269     public boolean testCase1()
270     {
271         reporter.testCaseInit("Setting various simple string-valued params");
272         try
273         {
274             // Just loop through test elements and try each one
275             // Loop separately for each worker method
276             for (int i = 0; i < paramTests.length; i++)
277             {
278                 // Try on a completely independent
279                 //  transformer and sources each time
280                 testSetParam(paramTests[i][0], paramTests[i][1],
281                              new StreamSource(paramTest.xmlName), new StreamSource(paramTest.inputName),
282                              paramTests[i][2], paramTests[i][3]);
283             }
284         }
285         catch (Exception e)
286         {
287             reporter.logThrowable(Logger.ERRORMSG, e, "Testcase threw");
288             reporter.logErrorMsg("Testcase threw: " + e.toString());
289         }
290         reporter.testCaseClose();
291         return true;
292     }
293 
294 
295     /**
296      * Reuse the same transformer multiple times with params set.
297      * This also reproduces Bugzilla1611
298      *
299      * @return false if we should abort the test; true otherwise
300      */
testCase2()301     public boolean testCase2()
302     {
303         reporter.testCaseInit("Reuse the same transformer multiple times with params set");
304         TransformerFactory factory = null;
305         Templates templates = null;
306         Transformer transformer = null;
307         try
308         {
309             factory = TransformerFactory.newInstance();
310             templates = factory.newTemplates(new StreamSource(paramTest2.inputName));
311 
312             // Process the file as-is, without any params set
313             transformer = templates.newTransformer();
314             reporter.logInfoMsg("Transforming " + paramTest.xmlName + " with " + paramTest2.inputName);
315             transformer.transform(new StreamSource(paramTest.xmlName),
316                                   new StreamResult(outNames.nextName()));
317             // Verify the values are correct for no params set
318             checkFileContains(outNames.currentName(), "<globalVarAttr>ParameterTest.xml:</globalVarAttr>",
319                               "(2.0)Processing 1,2 w/no params into: " + outNames.currentName());
320 
321             // Do NOT call clearParameters here; reuse the transformer
322             reporter.logInfoMsg("Reused-Transforming " + paramTest2.xmlName + " with " + paramTest2.inputName);
323             transformer.transform(new StreamSource(paramTest2.xmlName),
324                                   new StreamResult(outNames.nextName()));
325             // Verify the values are correct for no params set
326             checkFileContains(outNames.currentName(), "<globalVarAttr>ParameterTest2.xml:</globalVarAttr>",
327                               "(2.0a) Bugzilla1611 Reused Transformer processing 2,2 w/no params into: " + outNames.currentName());
328 
329             // Do NOT call clearParameters here; reuse the transformer again
330             reporter.logInfoMsg("Reused-Transforming-again " + paramTest.xmlName + " with " + paramTest2.inputName);
331             transformer.transform(new StreamSource(paramTest.xmlName),
332                                   new StreamResult(outNames.nextName()));
333             // Verify the values are correct for no params set
334             checkFileContains(outNames.currentName(), "<globalVarAttr>ParameterTest.xml:</globalVarAttr>",
335                               "(2.0b) Bugzilla1611 Reused-Again Transformer processing 1,2 w/no params into: " + outNames.currentName());
336         }
337         catch (Exception e)
338         {
339             reporter.logThrowable(Logger.ERRORMSG, e, "Testcase threw");
340             reporter.logErrorMsg("Testcase threw: " + e.toString());
341         }
342         reporter.testCaseClose();
343         return true;
344     }
345 
346     /**
347      * Setting various string-valued params and reusing transformers.
348      * Creates one transformer first, then loops through array
349      * of simple test data re-using transformer.
350      *
351      * @return false if we should abort the test; true otherwise
352      */
testCase3()353     public boolean testCase3()
354     {
355         reporter.testCaseInit("Setting various string-valued params and re-using transformer");
356         TransformerFactory factory = null;
357         Templates templates = null;
358         Transformer transformer = null;
359         try
360         {
361             factory = TransformerFactory.newInstance();
362             factory.setErrorListener(new DefaultErrorHandler());
363             templates = factory.newTemplates(new StreamSource(paramTest.inputName));
364         }
365         catch (Exception e)
366         {
367             reporter.checkFail("Problem creating Templates; cannot continue testcase");
368             reporter.logThrowable(reporter.ERRORMSG, e,
369                                   "Problem creating Templates; cannot continue testcase");
370             return true;
371         }
372 
373         try
374         {
375             // Process the file as-is, without any params set
376             transformer = templates.newTransformer();
377             transformer.setErrorListener(new DefaultErrorHandler());
378             transformer.transform(new StreamSource(paramTest.xmlName),
379                                   new StreamResult(outNames.nextName()));
380             transformer.clearParameters();
381             // Verify each of the three kinds of params are correct
382             checkFileContains(outNames.currentName(), "<outp>ABC,<B>ABC</B>; DEF,<B>DEF</B>; GHI,<B>GHI</B>; </outp>",
383                               "(0) Stylesheet with default param value into: " + outNames.currentName());
384 
385             checkFileContains(
386                 outNames.currentName(),
387                 "<outs>s1val,s1val; s2val,s2val; s3val,s3val; </outs>",
388                 "(1) ... also with default param value in select expr into: " + outNames.currentName());
389             checkFileContains(
390                 outNames.currentName(),
391                 "<outt>true-notset,false-blank,false-a,false-1,notset</outt>",
392                 "(2) ... also with default param value in select expr into: " + outNames.currentName());
393 
394             // Just loop through test elements and try each one
395             for (int i = 0; i < paramTests.length; i++)
396             {
397                 // Re-use the transformer from above for each test
398                 transformer.clearParameters();
399                 testSetParam(paramTests[i][0], paramTests[i][1],
400                              transformer, new StreamSource(paramTest.xmlName), new StreamSource(paramTest.inputName),
401                              paramTests[i][2], paramTests[i][3]);
402             }
403         }
404         catch (Exception e)
405         {
406             reporter.logThrowable(Logger.ERRORMSG, e, "Testcase threw");
407             reporter.logErrorMsg("Testcase threw: " + e.toString());
408         }
409         reporter.testCaseClose();
410         return true;
411     }
412 
413 
414     /**
415      * Test setting a single string-valued parameter.
416      * Uses the supplied Transformer and calls setParameter()
417      * then transform(Source, Source), then uses the worker
418      * method checkFileContains() to validate and output results.
419      *
420      * @param paramName simple name of parameter
421      * @param paramVal String value of parameter
422      * @param transformer object to use
423      * @param xmlSource object to use in transform
424      * @param xslStylesheet object to use in transform
425      * @param checkString to look for in output file (logged)
426      * @param comment to log with check() call
427      * @return true if pass, false otherwise
428      */
testSetParam(String paramName, String paramVal, Transformer transformer, Source xmlSource, Source xslStylesheet, String checkString, String comment)429     protected boolean testSetParam(String paramName, String paramVal,
430                                    Transformer transformer,
431                                    Source xmlSource,
432                                    Source xslStylesheet,
433                                    String checkString, String comment)
434     {
435         try
436         {
437             reporter.logTraceMsg("setParameter(" + paramName + ", " + paramVal +")");
438             transformer.setParameter(paramName, paramVal);
439             reporter.logTraceMsg("transform(" + xmlSource.getSystemId() + ", " + xslStylesheet.getSystemId() +", ...)");
440             transformer.transform(xmlSource, new StreamResult(outNames.nextName()));
441         }
442         catch (Throwable t)
443         {
444             reporter.logThrowable(Logger.ERRORMSG, t, "testSetParam unexpectedly threw");
445             reporter.logErrorMsg("//@todo HACK: intermittent NPE; please report to curcuru@apache.org if you get this");
446             reporter.logErrorMsg("//@todo HACK: intermittent NPE; please report to curcuru@apache.org if you get this");
447             reporter.logErrorMsg("//@todo HACK: intermittent NPE; please report to curcuru@apache.org if you get this");
448             // Since we the NPE is intermittent, and we want the rest
449             //  of this test in the smoketest, I'll go against my
450             //  better nature and ignore this fail
451             return true; //HACK: should be removed when fixed
452         }
453         return checkFileContains(outNames.currentName(), checkString,
454                                  "Reused:" + comment + " into: " + outNames.currentName());
455     }
456 
457 
458     /**
459      * Test setting a single string-valued parameter.
460      * Creates a Transformer and calls setParameter()
461      * then transform(Source, Source), then uses the worker
462      * method checkFileContains() to validate and output results.
463      *
464      * @param paramName simple name of parameter
465      * @param paramVal String value of parameter
466      * @param xmlSource object to use in transform
467      * @param xslStylesheet object to use in transform
468      * @param checkString to look for in output file (logged)
469      * @param comment to log with check() call
470      * @return true if pass, false otherwise
471      */
testSetParam(String paramName, String paramVal, Source xmlSource, Source xslStylesheet, String checkString, String comment)472     protected boolean testSetParam(String paramName, String paramVal,
473                                    Source xmlSource,
474                                    Source xslStylesheet,
475                                    String checkString, String comment)
476     {
477         try
478         {
479             TransformerFactory factory = TransformerFactory.newInstance();
480             factory.setErrorListener(new DefaultErrorHandler());
481             Transformer transformer = factory.newTransformer(xslStylesheet);
482             transformer.setErrorListener(new DefaultErrorHandler());
483 
484             reporter.logTraceMsg("setParameter(" + paramName + ", " + paramVal +")");
485             transformer.setParameter(paramName, paramVal);
486             reporter.logTraceMsg("transform(" + xmlSource.getSystemId() + ", " + xslStylesheet.getSystemId() +", ...)");
487             transformer.transform(xmlSource, new StreamResult(outNames.nextName()));
488         }
489         catch (Throwable t)
490         {
491             reporter.logThrowable(Logger.ERRORMSG, t, "testSetParam unexpectedly threw");
492         }
493         return checkFileContains(outNames.currentName(), checkString,
494                                  "New:" + comment + " into: " + outNames.currentName());
495     }
496 
497 
498     /**
499      * Checks and reports if a file contains a certain string
500      * (all within one line).
501      * We should really consider validating the entire output
502      * file, but this is the important funtionality, and it makes
503      * maintaining the test and gold data easier (since it's all
504      * in this file).
505      *
506      * @param fName local path/name of file to check
507      * @param checkStr String to look for in the file
508      * @param comment to log with the check() call
509      * @return true if pass, false otherwise
510      */
checkFileContains(String fName, String checkStr, String comment)511     protected boolean checkFileContains(String fName, String checkStr,
512                                         String comment)
513     {
514         boolean passFail = false;
515         File f = new File(fName);
516 
517         if (!f.exists())
518         {
519             reporter.checkFail("checkFileContains(" + fName
520                                + ") does not exist: " + comment);
521             return false;
522         }
523 
524         try
525         {
526             InputStreamReader is = new InputStreamReader(new FileInputStream(f), "UTF-8");
527             BufferedReader br = new BufferedReader(is);
528 
529             for (;;)
530             {
531                 String inbuf = br.readLine();
532                 if (inbuf == null)
533                     break;
534 
535                 if (inbuf.indexOf(checkStr) >= 0)
536                 {
537                     passFail = true;
538                     reporter.logTraceMsg(
539                         "checkFileContains passes with line: " + inbuf);
540                     break;
541                 }
542             }
543         }
544         catch (IOException ioe)
545         {
546             reporter.checkFail("checkFileContains(" + fName + ") threw: "
547                                + ioe.toString() + " for: " + comment);
548 
549             return false;
550         }
551 
552         if (!passFail)
553         {
554             reporter.logErrorMsg("checkFileContains failed to find: " + checkStr);
555         }
556         reporter.check(passFail, true, comment);
557         return passFail;
558     }
559 
560 
561     /**
562      * Convenience method to print out usage information - update if needed.
563      * @return String denoting usage of this test class
564      */
usage()565     public String usage()
566     {
567         return ("Common [optional] options supported by ParameterTest:\n"
568                 + "(Note: assumes inputDir=.\\tests\\api)\n"
569                 + super.usage());   // Grab our parent classes usage as well
570     }
571 
572 
573     /**
574      * Main method to run test from the command line - can be left alone.
575      * @param args command line argument array
576      */
main(String[] args)577     public static void main(String[] args)
578     {
579         ParameterTest app = new ParameterTest();
580         app.doMain(args);
581     }
582 
583     // Android-added: Run main method as a JUnit test case.
584     @FlakyTest(bugId = 292520220)
585     @Test
main()586     public void main() {
587         main(new String[0]);
588     }
589 }
590