1
2
3
4
5 package com.jguild.jrpm.test;
6
7 import java.io.ByteArrayOutputStream;
8 import java.io.File;
9 import java.io.IOException;
10 import java.io.OutputStream;
11 import java.net.URL;
12 import java.util.StringTokenizer;
13
14 import junit.framework.TestCase;
15
16 import org.apache.log4j.ConsoleAppender;
17 import org.apache.log4j.Logger;
18 import org.apache.log4j.SimpleLayout;
19
20 import com.jguild.jrpm.io.RPMFile;
21 import com.jguild.jrpm.io.constant.EnumIf;
22 import com.jguild.jrpm.io.constant.RPMHeaderTag;
23 import com.jguild.jrpm.io.datatype.DataTypeIf;
24
25 /***
26 * Test case to compare jRPM against an installed instance of rpm.
27 *
28 * @author kuss @warn For this test to work you need rpm installed on your
29 * system.
30 */
31 public class NativeRPMTest extends TestCase {
32
33 private static final Logger logger = Logger
34 .getLogger(RPMFileParsingTest.class);
35
36 private static final String RPM_FILE = "ElectricFence-2.2.2-15.i386.rpm";
37
38 /***
39 * Test if all tag names are supported by jRPM. The tags will be querried
40 * from a installed instance of rpm with the option --querytags. Than all
41 * tags are compared to the tags defined in jRPM.
42 *
43 * @throws IOException
44 * if an io error occur @warn For this test to work you need rpm
45 * installed on your system.
46 */
47 public void testKnownTypes() throws IOException {
48 String originTypes = runRPM("--querytags");
49 StringTokenizer strToken = new StringTokenizer(originTypes, "\r\n");
50
51 int error = 0;
52 while (strToken.hasMoreTokens()) {
53 String tagName = strToken.nextToken();
54 EnumIf enum = RPMHeaderTag.getEnumByName(tagName);
55 assertNotNull("TAG <" + tagName + "> not found", enum);
56 if (enum.equals(RPMHeaderTag.UNKNOWN)) {
57 logger.error("TAG <" + tagName + "> not found");
58 error++;
59 }
60
61
62 }
63 assertFalse(error + " Errors", error > 0);
64 }
65
66 /***
67 * Tests the jRPM for correct returned tags. The tags will be querried from
68 * a installed instance of rpm with the options --querytags. Than the
69 * results of rpm and jRPM are compared for each tag. If one tag differs
70 * the test will fail.
71 *
72 * @throws IOException
73 * if some io error occurs @warn For this test to work you need
74 * rpm installed on your system.
75 */
76 public void testTestRPMFile() throws IOException {
77 String originTypes = runRPM("--querytags");
78 StringTokenizer strToken = new StringTokenizer(originTypes, "\r\n");
79 RPMFile rpmFile = new RPMFile(getTestRPMFile(RPM_FILE));
80 rpmFile.parse();
81 String rpmPath = getTestRPMFile(RPM_FILE).toString();
82 assertNotNull(rpmPath);
83 assertFalse(rpmPath.equals(""));
84
85
86 if (System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0) {
87 rpmPath = rpmPath.replace('//', '/');
88 }
89
90 if (logger.isDebugEnabled()) {
91 logger.debug("Starting compare for " + RPM_FILE + " ...");
92 }
93
94 int errors = 0;
95 int ok = 0;
96
97 while (strToken.hasMoreTokens()) {
98 String tagName = strToken.nextToken();
99 DataTypeIf rpmData = rpmFile.getTag(tagName);
100 long tagId = rpmFile.getTagIdForName(tagName);
101 String jrpmTagValue = (rpmData != null) ? rpmData.toString() : "";
102 StringTokenizer jrpmToken = new StringTokenizer(jrpmTagValue, "[],");
103
104 String origTagValue = "";
105
106
107 if (rpmData == null || !rpmData.isArray()) {
108 origTagValue = runRPM("-qp --queryformat \"%{" + tagName
109 + "}\" " + rpmPath);
110 } else {
111 origTagValue = runRPM("-qp --queryformat \"//[[%{" + tagName
112 + "}, ]//]\" " + rpmPath);
113 }
114
115 while (origTagValue.indexOf("(none)") >= 0) {
116 origTagValue = origTagValue.replaceAll("//(none//)", "");
117 }
118
119 while (origTagValue.indexOf("(unknown type)") >= 0) {
120 origTagValue = origTagValue
121 .replaceAll("//(unknown type//)", "");
122 }
123
124 if (origTagValue.endsWith("\r\n")) {
125 origTagValue = origTagValue.substring(0,
126 origTagValue.length() - 2);
127 }
128
129 StringTokenizer origToken = new StringTokenizer(origTagValue, "[],");
130 int origTokenCount = origToken.countTokens();
131
132 if (rpmData != null && rpmData.isArray()) {
133 origTokenCount--;
134 }
135
136 if (jrpmToken.countTokens() != origTokenCount) {
137 logger.error(tagName + ":" + tagId + " not ok! "
138 + jrpmToken.countTokens() + ":" + origTokenCount + " <"
139 + jrpmTagValue + "> <" + origTagValue + ">");
140 errors++;
141 } else {
142 logger.debug(tagName + ":" + tagId + " ok! <" + origTagValue
143 + ">");
144 ok++;
145 }
146
147
148 }
149
150 assertFalse(errors + " Errors found;see log error output (" + ok
151 + " values ok)", errors > 0);
152 }
153
154 protected void setUp() throws Exception {
155 if (!Logger.getLogger("com.jguild.jrpm").getAllAppenders()
156 .hasMoreElements()) {
157 Logger.getLogger("com.jguild.jrpm").addAppender(
158 new ConsoleAppender(new SimpleLayout()));
159 }
160
161
162 String version = runRPM("--version");
163 int index = version.indexOf("4.");
164 assertFalse("RPM version > 4 is needed!", index < 0);
165
166 super.setUp();
167 }
168
169 protected void tearDown() throws Exception {
170 super.tearDown();
171 }
172
173 private File getTestRPMFile(String name) {
174 URL rpmUrl = NativeRPMTest.class.getClassLoader().getResource(name);
175 return new File(rpmUrl.getFile());
176 }
177
178 /***
179 * Run an installed instance of rpm with the defined parameters.
180 *
181 * @param command
182 * Options to run rpm with
183 * @return stdout as a string
184 * @throws IOException
185 * if an io error occurs during accessing rpm
186 */
187 private static String runRPM(String command) throws IOException {
188 Process rpmProc = Runtime.getRuntime().exec("rpm " + command);
189
190 OutputStream err = new ByteArrayOutputStream();
191 OutputStream out = new ByteArrayOutputStream();
192
193
194 StreamGobbler errorGobbler = new StreamGobbler(
195 rpmProc.getErrorStream(), err);
196
197
198 StreamGobbler outputGobbler = new StreamGobbler(rpmProc
199 .getInputStream(), out);
200
201
202 errorGobbler.start();
203 outputGobbler.start();
204
205 try {
206
207 rpmProc.waitFor();
208 } catch (InterruptedException e) {
209
210 }
211
212 return out.toString();
213 }
214 }