diff options
author | Rob Mensching <rob@firegiant.com> | 2022-03-31 11:56:14 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2022-03-31 18:01:06 -0700 |
commit | 47582b162368e8edf7a3b11c13b8e9dabc5f0a26 (patch) | |
tree | 2c4063eff325684bed39de0edacd7866a257ae02 /src/dtf/test | |
parent | 167296c42497c4e95f0d5d71168542d747655981 (diff) | |
download | wix-47582b162368e8edf7a3b11c13b8e9dabc5f0a26.tar.gz wix-47582b162368e8edf7a3b11c13b8e9dabc5f0a26.tar.bz2 wix-47582b162368e8edf7a3b11c13b8e9dabc5f0a26.zip |
Provide managed CA and Embedded UI DTF libraries via NuGet
Lots of refactoring to bring the SFX tooling back into the 'dtf'
layer since they are (in the end) tightly coupled to some DTF
assemblies. Also refactored the DTF tests into their own folder
and added a couple integration tests to build using the new CA/UI
NuGet package.
Closes wixtoolset/issues#6080
Diffstat (limited to 'src/dtf/test')
18 files changed, 4679 insertions, 0 deletions
diff --git a/src/dtf/test/WixToolsetTests.Dtf.Compression.Cab/CabTest.cs b/src/dtf/test/WixToolsetTests.Dtf.Compression.Cab/CabTest.cs new file mode 100644 index 00000000..981ecc69 --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.Compression.Cab/CabTest.cs | |||
@@ -0,0 +1,1165 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | namespace WixToolset.Dtf.Test | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using System.Text; | ||
8 | using System.Threading; | ||
9 | using System.Collections.Generic; | ||
10 | using System.Runtime.Serialization; | ||
11 | using System.Runtime.Serialization.Formatters.Binary; | ||
12 | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
13 | using WixToolset.Dtf.Compression; | ||
14 | using WixToolset.Dtf.Compression.Cab; | ||
15 | |||
16 | [TestClass] | ||
17 | public class CabTest | ||
18 | { | ||
19 | public CabTest() | ||
20 | { | ||
21 | } | ||
22 | |||
23 | [TestInitialize] | ||
24 | public void Initialize() | ||
25 | { | ||
26 | } | ||
27 | |||
28 | [TestCleanup] | ||
29 | public void Cleanup() | ||
30 | { | ||
31 | } | ||
32 | |||
33 | [TestMethod] | ||
34 | public void CabinetMultithread() | ||
35 | { | ||
36 | this.multithreadExceptions = new List<Exception>(); | ||
37 | |||
38 | const int threadCount = 10; | ||
39 | IList<Thread> threads = new List<Thread>(threadCount); | ||
40 | |||
41 | for (int i = 0; i < threadCount; i++) | ||
42 | { | ||
43 | Thread thread = new Thread(new ThreadStart(this.CabinetMultithreadWorker)); | ||
44 | thread.Name = "CabinetMultithreadWorker_" + i; | ||
45 | threads.Add(thread); | ||
46 | } | ||
47 | |||
48 | foreach (Thread thread in threads) | ||
49 | { | ||
50 | thread.Start(); | ||
51 | } | ||
52 | |||
53 | foreach (Thread thread in threads) | ||
54 | { | ||
55 | thread.Join(); | ||
56 | } | ||
57 | |||
58 | foreach (Exception ex in this.multithreadExceptions) | ||
59 | { | ||
60 | Console.WriteLine(); | ||
61 | Console.WriteLine(ex); | ||
62 | } | ||
63 | Assert.AreEqual<int>(0, this.multithreadExceptions.Count); | ||
64 | } | ||
65 | |||
66 | private IList<Exception> multithreadExceptions; | ||
67 | |||
68 | private void CabinetMultithreadWorker() | ||
69 | { | ||
70 | try | ||
71 | { | ||
72 | string threadName = Thread.CurrentThread.Name; | ||
73 | int threadNumber = Int32.Parse(threadName.Substring(threadName.IndexOf('_') + 1)); | ||
74 | this.RunCabinetPackUnpack(100, 10240 + threadNumber, 0, 0, CompressionLevel.Normal); | ||
75 | } | ||
76 | catch (Exception ex) | ||
77 | { | ||
78 | this.multithreadExceptions.Add(ex); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | [TestMethod] | ||
83 | public void CabinetFileCounts() | ||
84 | { | ||
85 | this.RunCabinetPackUnpack(0, 10, 0, 0, CompressionLevel.Normal); | ||
86 | this.RunCabinetPackUnpack(1, 10, 0, 0, CompressionLevel.Normal); | ||
87 | this.RunCabinetPackUnpack(100, 10, 0, 0, CompressionLevel.Normal); | ||
88 | } | ||
89 | |||
90 | [TestMethod] | ||
91 | [Ignore] // Takes ~5 minutes and 66000 is over the 65535 limit anyway. | ||
92 | public void CabinetExtremeFileCounts() | ||
93 | { | ||
94 | this.RunCabinetPackUnpack(66000, 10); | ||
95 | } | ||
96 | |||
97 | [TestMethod] | ||
98 | public void CabinetFileSizes() | ||
99 | { | ||
100 | this.RunCabinetPackUnpack(1, 0, 0, 0, CompressionLevel.Normal); | ||
101 | this.RunCabinetPackUnpack(1, 1, 0, 0, CompressionLevel.Normal); | ||
102 | this.RunCabinetPackUnpack(1, 2, 0, 0, CompressionLevel.Normal); | ||
103 | this.RunCabinetPackUnpack(1, 3, 0, 0, CompressionLevel.Normal); | ||
104 | this.RunCabinetPackUnpack(1, 4, 0, 0, CompressionLevel.Normal); | ||
105 | this.RunCabinetPackUnpack(1, 5, 0, 0, CompressionLevel.Normal); | ||
106 | this.RunCabinetPackUnpack(1, 6, 0, 0, CompressionLevel.Normal); | ||
107 | // Skip file sizes 7-9: see "buggy" file sizes test below. | ||
108 | this.RunCabinetPackUnpack(1, 10, 0, 0, CompressionLevel.Normal); | ||
109 | this.RunCabinetPackUnpack(1, 11, 0, 0, CompressionLevel.Normal); | ||
110 | this.RunCabinetPackUnpack(1, 12, 0, 0, CompressionLevel.Normal); | ||
111 | this.RunCabinetPackUnpack(1, 100 * 1024, 0, 0, CompressionLevel.Normal); | ||
112 | this.RunCabinetPackUnpack(1, 10 * 1024 * 1024, 0, 0, CompressionLevel.Normal); | ||
113 | } | ||
114 | |||
115 | [TestMethod] | ||
116 | public void CabinetBuggyFileSizes() | ||
117 | { | ||
118 | // Windows' cabinet.dll has a known bug (#55001 in Windows OS Bugs) | ||
119 | // LZX compression causes an AV with file sizes of 7, 8, or 9 bytes. | ||
120 | try | ||
121 | { | ||
122 | this.RunCabinetPackUnpack(1, 7, 0, 0, CompressionLevel.Normal); | ||
123 | this.RunCabinetPackUnpack(1, 8, 0, 0, CompressionLevel.Normal); | ||
124 | this.RunCabinetPackUnpack(1, 9, 0, 0, CompressionLevel.Normal); | ||
125 | } | ||
126 | catch (AccessViolationException) | ||
127 | { | ||
128 | Assert.Fail("Known 7,8,9 file size bug detected in Windows' cabinet.dll."); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | [Timeout(36000000), TestMethod] | ||
133 | [Ignore] // Takes too long to run regularly. | ||
134 | public void CabinetExtremeFileSizes() | ||
135 | { | ||
136 | this.RunCabinetPackUnpack(10, 512L * 1024 * 1024); // 5GB | ||
137 | //this.RunCabinetPackUnpack(1, 5L * 1024 * 1024 * 1024); // 5GB | ||
138 | } | ||
139 | |||
140 | [TestMethod] | ||
141 | public void CabinetFolders() | ||
142 | { | ||
143 | this.RunCabinetPackUnpack(0, 10, 1, 0, CompressionLevel.Normal); | ||
144 | this.RunCabinetPackUnpack(1, 10, 1, 0, CompressionLevel.Normal); | ||
145 | this.RunCabinetPackUnpack(100, 10, 1, 0, CompressionLevel.Normal); | ||
146 | |||
147 | IList<ArchiveFileInfo> fileInfo; | ||
148 | fileInfo = this.RunCabinetPackUnpack(7, 100 * 1024, 250 * 1024, 0, CompressionLevel.None); | ||
149 | Assert.AreEqual<int>(2, ((CabFileInfo) fileInfo[fileInfo.Count - 1]).CabinetFolderNumber, | ||
150 | "Testing whether cabinet has the correct # of folders."); | ||
151 | |||
152 | fileInfo = this.RunCabinetPackUnpack(10, 100 * 1024, 250 * 1024, 0, CompressionLevel.None); | ||
153 | Assert.AreEqual<int>(3, ((CabFileInfo) fileInfo[fileInfo.Count - 1]).CabinetFolderNumber, | ||
154 | "Testing whether cabinet has the correct # of folders."); | ||
155 | |||
156 | fileInfo = this.RunCabinetPackUnpack(2, 100 * 1024, 40 * 1024, 0, CompressionLevel.None); | ||
157 | Assert.AreEqual<int>(1, ((CabFileInfo) fileInfo[fileInfo.Count - 1]).CabinetFolderNumber, | ||
158 | "Testing whether cabinet has the correct # of folders."); | ||
159 | } | ||
160 | |||
161 | [TestMethod] | ||
162 | public void CabinetArchiveCounts() | ||
163 | { | ||
164 | IList<ArchiveFileInfo> fileInfo; | ||
165 | fileInfo = this.RunCabinetPackUnpack(10, 100 * 1024, 0, 400 * 1024, CompressionLevel.None); | ||
166 | Assert.AreEqual<int>(2, fileInfo[fileInfo.Count - 1].ArchiveNumber, | ||
167 | "Testing whether archive spans the correct # of cab files."); | ||
168 | |||
169 | fileInfo = this.RunCabinetPackUnpack(2, 90 * 1024, 0, 40 * 1024, CompressionLevel.None); | ||
170 | Assert.AreEqual<int>(2, fileInfo[fileInfo.Count - 1].ArchiveNumber, | ||
171 | "Testing whether archive spans the correct # of cab files."); | ||
172 | } | ||
173 | |||
174 | [TestMethod] | ||
175 | public void CabinetProgress() | ||
176 | { | ||
177 | CompressionTestUtil.ExpectedProgress = new List<int[]>(new int[][] { | ||
178 | // StatusType, CurFile,TotalFiles,CurFolder,CurCab,TotalCabs | ||
179 | new int[] { (int) ArchiveProgressType.StartFile, 0, 15, 0, 0, 1 }, | ||
180 | new int[] { (int) ArchiveProgressType.FinishFile, 0, 15, 0, 0, 1 }, | ||
181 | new int[] { (int) ArchiveProgressType.StartFile, 1, 15, 0, 0, 1 }, | ||
182 | new int[] { (int) ArchiveProgressType.FinishFile, 1, 15, 0, 0, 1 }, | ||
183 | new int[] { (int) ArchiveProgressType.StartFile, 2, 15, 1, 0, 1 }, | ||
184 | new int[] { (int) ArchiveProgressType.FinishFile, 2, 15, 1, 0, 1 }, | ||
185 | new int[] { (int) ArchiveProgressType.StartFile, 3, 15, 1, 0, 1 }, | ||
186 | new int[] { (int) ArchiveProgressType.FinishFile, 3, 15, 1, 0, 1 }, | ||
187 | new int[] { (int) ArchiveProgressType.StartFile, 4, 15, 2, 0, 1 }, | ||
188 | new int[] { (int) ArchiveProgressType.FinishFile, 4, 15, 2, 0, 1 }, | ||
189 | new int[] { (int) ArchiveProgressType.StartFile, 5, 15, 2, 0, 1 }, | ||
190 | new int[] { (int) ArchiveProgressType.FinishFile, 5, 15, 2, 0, 1 }, | ||
191 | new int[] { (int) ArchiveProgressType.StartFile, 6, 15, 3, 0, 1 }, | ||
192 | new int[] { (int) ArchiveProgressType.FinishFile, 6, 15, 3, 0, 1 }, | ||
193 | new int[] { (int) ArchiveProgressType.StartFile, 7, 15, 3, 0, 1 }, | ||
194 | new int[] { (int) ArchiveProgressType.FinishFile, 7, 15, 3, 0, 1 }, | ||
195 | new int[] { (int) ArchiveProgressType.StartArchive, 7, 15, 3, 0, 1 }, | ||
196 | new int[] { (int) ArchiveProgressType.FinishArchive, 7, 15, 3, 0, 1 }, | ||
197 | new int[] { (int) ArchiveProgressType.StartFile, 8, 15, 4, 1, 2 }, | ||
198 | new int[] { (int) ArchiveProgressType.FinishFile, 8, 15, 4, 1, 2 }, | ||
199 | new int[] { (int) ArchiveProgressType.StartFile, 9, 15, 4, 1, 2 }, | ||
200 | new int[] { (int) ArchiveProgressType.FinishFile, 9, 15, 4, 1, 2 }, | ||
201 | new int[] { (int) ArchiveProgressType.StartFile, 10, 15, 5, 1, 2 }, | ||
202 | new int[] { (int) ArchiveProgressType.FinishFile, 10, 15, 5, 1, 2 }, | ||
203 | new int[] { (int) ArchiveProgressType.StartFile, 11, 15, 5, 1, 2 }, | ||
204 | new int[] { (int) ArchiveProgressType.FinishFile, 11, 15, 5, 1, 2 }, | ||
205 | new int[] { (int) ArchiveProgressType.StartFile, 12, 15, 6, 1, 2 }, | ||
206 | new int[] { (int) ArchiveProgressType.FinishFile, 12, 15, 6, 1, 2 }, | ||
207 | new int[] { (int) ArchiveProgressType.StartFile, 13, 15, 6, 1, 2 }, | ||
208 | new int[] { (int) ArchiveProgressType.FinishFile, 13, 15, 6, 1, 2 }, | ||
209 | new int[] { (int) ArchiveProgressType.StartArchive, 13, 15, 6, 1, 2 }, | ||
210 | new int[] { (int) ArchiveProgressType.FinishArchive, 13, 15, 6, 1, 2 }, | ||
211 | new int[] { (int) ArchiveProgressType.StartFile, 14, 15, 7, 2, 3 }, | ||
212 | new int[] { (int) ArchiveProgressType.FinishFile, 14, 15, 7, 2, 3 }, | ||
213 | new int[] { (int) ArchiveProgressType.StartArchive, 14, 15, 7, 2, 3 }, | ||
214 | new int[] { (int) ArchiveProgressType.FinishArchive, 14, 15, 7, 2, 3 }, | ||
215 | // StatusType, CurFile,TotalFiles,CurFolder,CurCab,TotalCabs | ||
216 | new int[] { (int) ArchiveProgressType.StartArchive, 0, 15, 0, 0, 3 }, | ||
217 | new int[] { (int) ArchiveProgressType.StartFile, 0, 15, 0, 0, 3 }, | ||
218 | new int[] { (int) ArchiveProgressType.FinishFile, 0, 15, 0, 0, 3 }, | ||
219 | new int[] { (int) ArchiveProgressType.StartFile, 1, 15, 0, 0, 3 }, | ||
220 | new int[] { (int) ArchiveProgressType.FinishFile, 1, 15, 0, 0, 3 }, | ||
221 | new int[] { (int) ArchiveProgressType.StartFile, 2, 15, 1, 0, 3 }, | ||
222 | new int[] { (int) ArchiveProgressType.FinishFile, 2, 15, 1, 0, 3 }, | ||
223 | new int[] { (int) ArchiveProgressType.StartFile, 3, 15, 1, 0, 3 }, | ||
224 | new int[] { (int) ArchiveProgressType.FinishFile, 3, 15, 1, 0, 3 }, | ||
225 | new int[] { (int) ArchiveProgressType.StartFile, 4, 15, 2, 0, 3 }, | ||
226 | new int[] { (int) ArchiveProgressType.FinishFile, 4, 15, 2, 0, 3 }, | ||
227 | new int[] { (int) ArchiveProgressType.StartFile, 5, 15, 2, 0, 3 }, | ||
228 | new int[] { (int) ArchiveProgressType.FinishFile, 5, 15, 2, 0, 3 }, | ||
229 | new int[] { (int) ArchiveProgressType.StartFile, 6, 15, 3, 0, 3 }, | ||
230 | new int[] { (int) ArchiveProgressType.FinishArchive, 6, 15, 3, 0, 3 }, | ||
231 | new int[] { (int) ArchiveProgressType.StartArchive, 6, 15, 3, 1, 3 }, | ||
232 | new int[] { (int) ArchiveProgressType.FinishFile, 6, 15, 3, 1, 3 }, | ||
233 | new int[] { (int) ArchiveProgressType.StartFile, 7, 15, 3, 1, 3 }, | ||
234 | new int[] { (int) ArchiveProgressType.FinishFile, 7, 15, 3, 1, 3 }, | ||
235 | new int[] { (int) ArchiveProgressType.StartFile, 8, 15, 4, 1, 3 }, | ||
236 | new int[] { (int) ArchiveProgressType.FinishFile, 8, 15, 4, 1, 3 }, | ||
237 | new int[] { (int) ArchiveProgressType.StartFile, 9, 15, 4, 1, 3 }, | ||
238 | new int[] { (int) ArchiveProgressType.FinishFile, 9, 15, 4, 1, 3 }, | ||
239 | new int[] { (int) ArchiveProgressType.StartFile, 10, 15, 5, 1, 3 }, | ||
240 | new int[] { (int) ArchiveProgressType.FinishFile, 10, 15, 5, 1, 3 }, | ||
241 | new int[] { (int) ArchiveProgressType.StartFile, 11, 15, 5, 1, 3 }, | ||
242 | new int[] { (int) ArchiveProgressType.FinishFile, 11, 15, 5, 1, 3 }, | ||
243 | new int[] { (int) ArchiveProgressType.StartFile, 12, 15, 6, 1, 3 }, | ||
244 | new int[] { (int) ArchiveProgressType.FinishArchive, 12, 15, 6, 1, 3 }, | ||
245 | new int[] { (int) ArchiveProgressType.StartArchive, 12, 15, 6, 2, 3 }, | ||
246 | new int[] { (int) ArchiveProgressType.FinishFile, 12, 15, 6, 2, 3 }, | ||
247 | new int[] { (int) ArchiveProgressType.StartFile, 13, 15, 6, 2, 3 }, | ||
248 | new int[] { (int) ArchiveProgressType.FinishFile, 13, 15, 6, 2, 3 }, | ||
249 | new int[] { (int) ArchiveProgressType.StartFile, 14, 15, 7, 2, 3 }, | ||
250 | new int[] { (int) ArchiveProgressType.FinishFile, 14, 15, 7, 2, 3 }, | ||
251 | new int[] { (int) ArchiveProgressType.FinishArchive, 14, 15, 7, 2, 3 }, | ||
252 | }); | ||
253 | |||
254 | try | ||
255 | { | ||
256 | this.RunCabinetPackUnpack(15, 20 * 1024, 1 * 1024, 130 * 1024, CompressionLevel.None); | ||
257 | } | ||
258 | finally | ||
259 | { | ||
260 | CompressionTestUtil.ExpectedProgress = null; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | [TestMethod] | ||
265 | public void CabArchiveSizeParam() | ||
266 | { | ||
267 | Console.WriteLine("Testing various values for the maxArchiveSize parameter."); | ||
268 | this.RunCabinetPackUnpack(5, 1024, 0, Int64.MinValue); | ||
269 | this.RunCabinetPackUnpack(5, 1024, 0, -1); | ||
270 | this.RunCabinetPackUnpack(5, 10, 0, 2); | ||
271 | this.RunCabinetPackUnpack(5, 100, 0, 256); | ||
272 | this.RunCabinetPackUnpack(5, 24000, 0, 32768); | ||
273 | this.RunCabinetPackUnpack(5, 1024, 0, Int64.MaxValue); | ||
274 | } | ||
275 | |||
276 | [TestMethod] | ||
277 | public void CabFolderSizeParam() | ||
278 | { | ||
279 | Console.WriteLine("Testing various values for the maxFolderSize parameter."); | ||
280 | this.RunCabinetPackUnpack(5, 10, Int64.MinValue, 0); | ||
281 | this.RunCabinetPackUnpack(5, 10, -1, 0); | ||
282 | this.RunCabinetPackUnpack(5, 10, 2, 0); | ||
283 | this.RunCabinetPackUnpack(5, 10, 16, 0); | ||
284 | this.RunCabinetPackUnpack(5, 10, 100, 0); | ||
285 | this.RunCabinetPackUnpack(5, 10, Int64.MaxValue, 0); | ||
286 | } | ||
287 | |||
288 | [TestMethod] | ||
289 | public void CabCompLevelParam() | ||
290 | { | ||
291 | Console.WriteLine("Testing various values for the compressionLevel parameter."); | ||
292 | this.RunCabinetPackUnpack(5, 1024, 0, 0, CompressionLevel.None); | ||
293 | this.RunCabinetPackUnpack(5, 1024, 0, 0, CompressionLevel.Min); | ||
294 | this.RunCabinetPackUnpack(5, 1024, 0, 0, CompressionLevel.Normal); | ||
295 | this.RunCabinetPackUnpack(5, 1024, 0, 0, CompressionLevel.Max); | ||
296 | this.RunCabinetPackUnpack(5, 1024, 0, 0, (CompressionLevel) ((int) CompressionLevel.None - 1)); | ||
297 | this.RunCabinetPackUnpack(5, 1024, 0, 0, (CompressionLevel) ((int) CompressionLevel.Max + 1)); | ||
298 | this.RunCabinetPackUnpack(5, 1024, 0, 0, (CompressionLevel) Int32.MinValue); | ||
299 | this.RunCabinetPackUnpack(5, 1024, 0, 0, (CompressionLevel) Int32.MaxValue); | ||
300 | } | ||
301 | |||
302 | [TestMethod] | ||
303 | public void CabEngineNullParams() | ||
304 | { | ||
305 | string[] testFiles = new string[] { "test.txt" }; | ||
306 | ArchiveFileStreamContext streamContext = new ArchiveFileStreamContext("test.cab", null, null); | ||
307 | |||
308 | using (CabEngine cabEngine = new CabEngine()) | ||
309 | { | ||
310 | cabEngine.CompressionLevel = CompressionLevel.None; | ||
311 | |||
312 | CompressionTestUtil.TestCompressionEngineNullParams( | ||
313 | cabEngine, streamContext, testFiles); | ||
314 | } | ||
315 | } | ||
316 | |||
317 | [TestMethod] | ||
318 | public void CabBadPackStreamContexts() | ||
319 | { | ||
320 | string[] testFiles = new string[] { "test.txt" }; | ||
321 | CompressionTestUtil.GenerateRandomFile(testFiles[0], 0, 20000); | ||
322 | |||
323 | using (CabEngine cabEngine = new CabEngine()) | ||
324 | { | ||
325 | cabEngine.CompressionLevel = CompressionLevel.None; | ||
326 | |||
327 | CompressionTestUtil.TestBadPackStreamContexts(cabEngine, "test.cab", testFiles); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | [TestMethod] | ||
332 | public void CabEngineNoTempFileTest() | ||
333 | { | ||
334 | int txtSize = 10240; | ||
335 | CompressionTestUtil.GenerateRandomFile("testnotemp.txt", 0, txtSize); | ||
336 | |||
337 | ArchiveFileStreamContext streamContext = new ArchiveFileStreamContext("testnotemp.cab", null, null); | ||
338 | |||
339 | using (CabEngine cabEngine = new CabEngine()) | ||
340 | { | ||
341 | cabEngine.UseTempFiles = false; | ||
342 | cabEngine.Pack(streamContext, new string[] { "testnotemp.txt" }); | ||
343 | } | ||
344 | |||
345 | new CabInfo("testnotemp.cab").UnpackFile("testnotemp.txt", "testnotemp2.txt"); | ||
346 | Assert.AreEqual(txtSize, new FileInfo("testnotemp2.txt").Length); | ||
347 | } | ||
348 | |||
349 | [TestMethod] | ||
350 | public void CabExtractorIsCabinet() | ||
351 | { | ||
352 | int txtSize = 10240; | ||
353 | CompressionTestUtil.GenerateRandomFile("test.txt", 0, txtSize); | ||
354 | new CabInfo("test.cab").PackFiles(null, new string[] { "test.txt" }, null); | ||
355 | using (CabEngine cabEngine = new CabEngine()) | ||
356 | { | ||
357 | bool isCab; | ||
358 | using (Stream fileStream = File.OpenRead("test.txt")) | ||
359 | { | ||
360 | isCab = cabEngine.IsArchive(fileStream); | ||
361 | } | ||
362 | Assert.IsFalse(isCab); | ||
363 | using (Stream cabStream = File.OpenRead("test.cab")) | ||
364 | { | ||
365 | isCab = cabEngine.IsArchive(cabStream); | ||
366 | } | ||
367 | Assert.IsTrue(isCab); | ||
368 | using (Stream cabStream = File.OpenRead("test.cab")) | ||
369 | { | ||
370 | using (Stream fileStream = new FileStream("test.txt", FileMode.Open, FileAccess.ReadWrite)) | ||
371 | { | ||
372 | fileStream.Seek(0, SeekOrigin.End); | ||
373 | byte[] buf = new byte[1024]; | ||
374 | int count; | ||
375 | while ((count = cabStream.Read(buf, 0, buf.Length)) > 0) | ||
376 | { | ||
377 | fileStream.Write(buf, 0, count); | ||
378 | } | ||
379 | fileStream.Seek(0, SeekOrigin.Begin); | ||
380 | isCab = cabEngine.IsArchive(fileStream); | ||
381 | } | ||
382 | } | ||
383 | Assert.IsFalse(isCab); | ||
384 | using (Stream fileStream = new FileStream("test.txt", FileMode.Open, FileAccess.ReadWrite)) | ||
385 | { | ||
386 | fileStream.Write(new byte[] { (byte) 'M', (byte) 'S', (byte) 'C', (byte) 'F' }, 0, 4); | ||
387 | fileStream.Seek(0, SeekOrigin.Begin); | ||
388 | isCab = cabEngine.IsArchive(fileStream); | ||
389 | } | ||
390 | Assert.IsFalse(isCab); | ||
391 | } | ||
392 | } | ||
393 | |||
394 | [TestMethod] | ||
395 | public void CabExtractorFindOffset() | ||
396 | { | ||
397 | int txtSize = 10240; | ||
398 | CompressionTestUtil.GenerateRandomFile("test.txt", 0, txtSize); | ||
399 | new CabInfo("test.cab").PackFiles(null, new string[] { "test.txt" }, null); | ||
400 | using (CabEngine cabEngine = new CabEngine()) | ||
401 | { | ||
402 | long offset; | ||
403 | using (Stream fileStream = File.OpenRead("test.txt")) | ||
404 | { | ||
405 | offset = cabEngine.FindArchiveOffset(fileStream); | ||
406 | } | ||
407 | Assert.AreEqual<long>(-1, offset); | ||
408 | using (Stream cabStream = File.OpenRead("test.cab")) | ||
409 | { | ||
410 | using (Stream fileStream = new FileStream("test.txt", FileMode.Open, FileAccess.ReadWrite)) | ||
411 | { | ||
412 | fileStream.Seek(0, SeekOrigin.End); | ||
413 | byte[] buf = new byte[1024]; | ||
414 | int count; | ||
415 | while ((count = cabStream.Read(buf, 0, buf.Length)) > 0) | ||
416 | { | ||
417 | fileStream.Write(buf, 0, count); | ||
418 | } | ||
419 | fileStream.Seek(0, SeekOrigin.Begin); | ||
420 | offset = cabEngine.FindArchiveOffset(fileStream); | ||
421 | } | ||
422 | } | ||
423 | Assert.AreEqual<long>(txtSize, offset); | ||
424 | } | ||
425 | } | ||
426 | |||
427 | [TestMethod] | ||
428 | public void CabExtractorGetFiles() | ||
429 | { | ||
430 | IList<ArchiveFileInfo> fileInfo; | ||
431 | CabInfo cabInfo = new CabInfo("testgetfiles.cab"); | ||
432 | int txtSize = 10240; | ||
433 | CompressionTestUtil.GenerateRandomFile("testgetfiles0.txt", 0, txtSize); | ||
434 | CompressionTestUtil.GenerateRandomFile("testgetfiles1.txt", 1, txtSize); | ||
435 | cabInfo.PackFiles(null, new string[] { "testgetfiles0.txt", "testgetfiles1.txt" }, null); | ||
436 | using (CabEngine cabEngine = new CabEngine()) | ||
437 | { | ||
438 | IList<string> files; | ||
439 | using (Stream cabStream = File.OpenRead("testgetfiles.cab")) | ||
440 | { | ||
441 | files = cabEngine.GetFiles(cabStream); | ||
442 | } | ||
443 | Assert.IsNotNull(files); | ||
444 | Assert.AreEqual<int>(2, files.Count); | ||
445 | Assert.AreEqual<string>("testgetfiles0.txt", files[0]); | ||
446 | Assert.AreEqual<string>("testgetfiles1.txt", files[1]); | ||
447 | |||
448 | using (Stream cabStream = File.OpenRead("testgetfiles.cab")) | ||
449 | { | ||
450 | files = cabEngine.GetFiles(new ArchiveFileStreamContext("testgetfiles.cab"), null); | ||
451 | } | ||
452 | Assert.IsNotNull(files); | ||
453 | Assert.AreEqual<int>(2, files.Count); | ||
454 | Assert.AreEqual<string>("testgetfiles0.txt", files[0]); | ||
455 | Assert.AreEqual<string>("testgetfiles1.txt", files[1]); | ||
456 | |||
457 | using (Stream cabStream = File.OpenRead("testgetfiles.cab")) | ||
458 | { | ||
459 | fileInfo = cabEngine.GetFileInfo(cabStream); | ||
460 | } | ||
461 | Assert.IsNotNull(fileInfo); | ||
462 | Assert.AreEqual<int>(2, fileInfo.Count); | ||
463 | Assert.AreEqual<string>("testgetfiles0.txt", fileInfo[0].Name); | ||
464 | Assert.AreEqual<string>("testgetfiles1.txt", fileInfo[1].Name); | ||
465 | using (Stream cabStream = File.OpenRead("testgetfiles.cab")) | ||
466 | { | ||
467 | fileInfo = cabEngine.GetFileInfo(new ArchiveFileStreamContext("testgetfiles.cab"), null); | ||
468 | } | ||
469 | Assert.IsNotNull(fileInfo); | ||
470 | Assert.AreEqual<int>(2, fileInfo.Count); | ||
471 | Assert.AreEqual<string>("testgetfiles0.txt", fileInfo[0].Name); | ||
472 | Assert.AreEqual<string>("testgetfiles1.txt", fileInfo[1].Name); | ||
473 | } | ||
474 | |||
475 | fileInfo = this.RunCabinetPackUnpack(15, 20 * 1024, 1 * 1024, 130 * 1024); | ||
476 | Assert.IsNotNull(fileInfo); | ||
477 | Assert.AreEqual<int>(15, fileInfo.Count); | ||
478 | for (int i = 0; i < fileInfo.Count; i++) | ||
479 | { | ||
480 | Assert.IsNull(fileInfo[i].Archive); | ||
481 | Assert.AreEqual<string>(TEST_FILENAME_PREFIX + i + ".txt", fileInfo[i].Name); | ||
482 | Assert.IsTrue(DateTime.Now - fileInfo[i].LastWriteTime < new TimeSpan(0, 1, 0)); | ||
483 | } | ||
484 | } | ||
485 | |||
486 | [TestMethod] | ||
487 | public void CabExtractorExtract() | ||
488 | { | ||
489 | int txtSize = 40960; | ||
490 | CabInfo cabInfo = new CabInfo("test.cab"); | ||
491 | CompressionTestUtil.GenerateRandomFile("test0.txt", 0, txtSize); | ||
492 | CompressionTestUtil.GenerateRandomFile("test1.txt", 1, txtSize); | ||
493 | cabInfo.PackFiles(null, new string[] { "test0.txt", "test1.txt" }, null); | ||
494 | using (CabEngine cabEngine = new CabEngine()) | ||
495 | { | ||
496 | using (Stream cabStream = File.OpenRead("test.cab")) | ||
497 | { | ||
498 | using (Stream exStream = cabEngine.Unpack(cabStream, "test0.txt")) | ||
499 | { | ||
500 | string str = new StreamReader(exStream).ReadToEnd(); | ||
501 | string expected = new StreamReader("test0.txt").ReadToEnd(); | ||
502 | Assert.AreEqual<string>(expected, str); | ||
503 | } | ||
504 | cabStream.Seek(0, SeekOrigin.Begin); | ||
505 | using (Stream exStream = cabEngine.Unpack(cabStream, "test1.txt")) | ||
506 | { | ||
507 | string str = new StreamReader(exStream).ReadToEnd(); | ||
508 | string expected = new StreamReader("test1.txt").ReadToEnd(); | ||
509 | Assert.AreEqual<string>(expected, str); | ||
510 | } | ||
511 | } | ||
512 | using (Stream txtStream = File.OpenRead("test0.txt")) | ||
513 | { | ||
514 | Exception caughtEx = null; | ||
515 | try | ||
516 | { | ||
517 | cabEngine.Unpack(txtStream, "test0.txt"); | ||
518 | } | ||
519 | catch (Exception ex) { caughtEx = ex; } | ||
520 | Assert.IsInstanceOfType(caughtEx, typeof(CabException)); | ||
521 | Assert.AreEqual<int>(2, ((CabException) caughtEx).Error); | ||
522 | Assert.AreEqual<int>(0, ((CabException) caughtEx).ErrorCode); | ||
523 | Assert.AreEqual<string>("Cabinet file does not have the correct format.", caughtEx.Message); | ||
524 | } | ||
525 | } | ||
526 | } | ||
527 | |||
528 | [TestMethod] | ||
529 | public void CabBadUnpackStreamContexts() | ||
530 | { | ||
531 | int txtSize = 40960; | ||
532 | CabInfo cabInfo = new CabInfo("test2.cab"); | ||
533 | CompressionTestUtil.GenerateRandomFile("cabtest-0.txt", 0, txtSize); | ||
534 | CompressionTestUtil.GenerateRandomFile("cabtest-1.txt", 1, txtSize); | ||
535 | cabInfo.PackFiles(null, new string[] { "cabtest-0.txt", "cabtest-1.txt" }, null); | ||
536 | |||
537 | using (CabEngine cabEngine = new CabEngine()) | ||
538 | { | ||
539 | CompressionTestUtil.TestBadUnpackStreamContexts(cabEngine, "test2.cab"); | ||
540 | } | ||
541 | } | ||
542 | |||
543 | [TestMethod] | ||
544 | public void CabinetExtractUpdate() | ||
545 | { | ||
546 | int fileCount = 5, fileSize = 2048; | ||
547 | string dirA = String.Format("{0}-{1}-A", fileCount, fileSize); | ||
548 | if (Directory.Exists(dirA)) Directory.Delete(dirA, true); | ||
549 | Directory.CreateDirectory(dirA); | ||
550 | string dirB = String.Format("{0}-{1}-B", fileCount, fileSize); | ||
551 | if (Directory.Exists(dirB)) Directory.Delete(dirB, true); | ||
552 | Directory.CreateDirectory(dirB); | ||
553 | |||
554 | string[] files = new string[fileCount]; | ||
555 | for (int iFile = 0; iFile < fileCount; iFile++) | ||
556 | { | ||
557 | files[iFile] = "€" + iFile + ".txt"; | ||
558 | CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[iFile]), iFile, fileSize); | ||
559 | } | ||
560 | |||
561 | CabInfo cabInfo = new CabInfo("testupdate.cab"); | ||
562 | cabInfo.Pack(dirA); | ||
563 | cabInfo.Unpack(dirB); | ||
564 | |||
565 | DateTime originalTime = File.GetLastWriteTime(Path.Combine(dirA, "€1.txt")); | ||
566 | DateTime pastTime = originalTime - new TimeSpan(0, 5, 0); | ||
567 | DateTime futureTime = originalTime + new TimeSpan(0, 5, 0); | ||
568 | |||
569 | using (CabEngine cabEngine = new CabEngine()) | ||
570 | { | ||
571 | string cabName = "testupdate.cab"; | ||
572 | ArchiveFileStreamContext streamContext = new ArchiveFileStreamContext(cabName, dirB, null); | ||
573 | streamContext.ExtractOnlyNewerFiles = true; | ||
574 | |||
575 | Assert.AreEqual<bool>(true, streamContext.ExtractOnlyNewerFiles); | ||
576 | Assert.IsNotNull(streamContext.ArchiveFiles); | ||
577 | Assert.AreEqual<int>(1, streamContext.ArchiveFiles.Count); | ||
578 | Assert.AreEqual<string>(cabName, streamContext.ArchiveFiles[0]); | ||
579 | Assert.AreEqual<string>(dirB, streamContext.Directory); | ||
580 | |||
581 | File.SetLastWriteTime(Path.Combine(dirB, "€1.txt"), futureTime); | ||
582 | cabEngine.Unpack(streamContext, null); | ||
583 | Assert.IsTrue(File.GetLastWriteTime(Path.Combine(dirB, "€1.txt")) - originalTime > new TimeSpan(0, 4, 55)); | ||
584 | |||
585 | File.SetLastWriteTime(Path.Combine(dirB, "€1.txt"), pastTime); | ||
586 | File.SetLastWriteTime(Path.Combine(dirB, "€2.txt"), pastTime); | ||
587 | File.SetAttributes(Path.Combine(dirB, "€2.txt"), FileAttributes.ReadOnly); | ||
588 | File.SetAttributes(Path.Combine(dirB, "€2.txt"), FileAttributes.Hidden); | ||
589 | File.SetAttributes(Path.Combine(dirB, "€2.txt"), FileAttributes.System); | ||
590 | |||
591 | cabEngine.Unpack(streamContext, null); | ||
592 | Assert.IsTrue((File.GetLastWriteTime(Path.Combine(dirB, "€1.txt")) - originalTime).Duration() < new TimeSpan(0, 0, 5)); | ||
593 | |||
594 | // Just test the rest of the streamContext properties here. | ||
595 | IDictionary<string, string> testMap = new Dictionary<string, string>(); | ||
596 | streamContext = new ArchiveFileStreamContext(cabName, dirB, testMap); | ||
597 | Assert.AreSame(testMap, streamContext.Files); | ||
598 | |||
599 | Assert.IsFalse(streamContext.EnableOffsetOpen); | ||
600 | streamContext.EnableOffsetOpen = true; | ||
601 | Assert.IsTrue(streamContext.EnableOffsetOpen); | ||
602 | streamContext = new ArchiveFileStreamContext(cabName, ".", testMap); | ||
603 | Assert.AreEqual<string>(".", streamContext.Directory); | ||
604 | string[] testArchiveFiles = new string[] { cabName }; | ||
605 | streamContext = new ArchiveFileStreamContext(testArchiveFiles, ".", testMap); | ||
606 | Assert.AreSame(testArchiveFiles, streamContext.ArchiveFiles); | ||
607 | } | ||
608 | } | ||
609 | |||
610 | [TestMethod] | ||
611 | public void CabinetOffset() | ||
612 | { | ||
613 | int txtSize = 10240; | ||
614 | CompressionTestUtil.GenerateRandomFile("test.txt", 0, txtSize); | ||
615 | CompressionTestUtil.GenerateRandomFile("base.txt", 1, 2 * txtSize + 4); | ||
616 | |||
617 | ArchiveFileStreamContext streamContext = new ArchiveFileStreamContext("base.txt", null, null); | ||
618 | streamContext.EnableOffsetOpen = true; | ||
619 | |||
620 | using (CabEngine cabEngine = new CabEngine()) | ||
621 | { | ||
622 | cabEngine.Pack(streamContext, new string[] { "test.txt" }); | ||
623 | } | ||
624 | |||
625 | Assert.IsTrue(new FileInfo("base.txt").Length > 2 * txtSize + 4); | ||
626 | |||
627 | string saveText; | ||
628 | using (Stream txtStream = File.OpenRead("test.txt")) | ||
629 | { | ||
630 | saveText = new StreamReader(txtStream).ReadToEnd(); | ||
631 | } | ||
632 | File.Delete("test.txt"); | ||
633 | |||
634 | using (CabEngine cex = new CabEngine()) | ||
635 | { | ||
636 | cex.Unpack(streamContext, null); | ||
637 | } | ||
638 | string testText; | ||
639 | using (Stream txtStream = File.OpenRead("test.txt")) | ||
640 | { | ||
641 | testText = new StreamReader(txtStream).ReadToEnd(); | ||
642 | } | ||
643 | Assert.AreEqual<string>(saveText, testText); | ||
644 | } | ||
645 | |||
646 | [TestMethod] | ||
647 | public void CabinetUtfPaths() | ||
648 | { | ||
649 | string[] files = new string[] | ||
650 | { | ||
651 | "어그리먼트送信ポート1ßà_Agreement.txt", | ||
652 | "콘토소ßà_MyProfile.txt", | ||
653 | "파트너1ßà_PartnerProfile.txt", | ||
654 | }; | ||
655 | |||
656 | string dirA = "utf8-A"; | ||
657 | if (Directory.Exists(dirA)) Directory.Delete(dirA, true); | ||
658 | Directory.CreateDirectory(dirA); | ||
659 | string dirB = "utf8-B"; | ||
660 | if (Directory.Exists(dirB)) Directory.Delete(dirB, true); | ||
661 | Directory.CreateDirectory(dirB); | ||
662 | |||
663 | int txtSize = 1024; | ||
664 | CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[0]), 0, txtSize); | ||
665 | CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[1]), 1, txtSize); | ||
666 | CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[2]), 2, txtSize); | ||
667 | |||
668 | ArchiveFileStreamContext streamContextA = new ArchiveFileStreamContext("utf8.cab", dirA, null); | ||
669 | using (CabEngine cabEngine = new CabEngine()) | ||
670 | { | ||
671 | cabEngine.Pack(streamContextA, files); | ||
672 | } | ||
673 | |||
674 | ArchiveFileStreamContext streamContextB = new ArchiveFileStreamContext("utf8.cab", dirB, null); | ||
675 | using (CabEngine cex = new CabEngine()) | ||
676 | { | ||
677 | cex.Unpack(streamContextB, null); | ||
678 | } | ||
679 | |||
680 | bool directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB); | ||
681 | Assert.IsTrue(directoryMatch, | ||
682 | "Testing whether cabinet output directory matches input directory."); | ||
683 | } | ||
684 | |||
685 | [TestMethod] | ||
686 | //[Ignore] // Requires clean environment. | ||
687 | public void CabInfoProperties() | ||
688 | { | ||
689 | Exception caughtEx; | ||
690 | CabInfo cabInfo = new CabInfo("test.cab"); | ||
691 | int txtSize = 10240; | ||
692 | CompressionTestUtil.GenerateRandomFile("test00.txt", 0, txtSize); | ||
693 | CompressionTestUtil.GenerateRandomFile("test01.txt", 1, txtSize); | ||
694 | cabInfo.PackFiles(null, new string[] { "test00.txt", "test01.txt" }, null); | ||
695 | |||
696 | Assert.AreEqual<string>(new FileInfo("test.cab").Directory.FullName, cabInfo.Directory.FullName, "CabInfo.FullName"); | ||
697 | Assert.AreEqual<string>(new FileInfo("test.cab").DirectoryName, cabInfo.DirectoryName, "CabInfo.DirectoryName"); | ||
698 | Assert.AreEqual<long>(new FileInfo("test.cab").Length, cabInfo.Length, "CabInfo.Length"); | ||
699 | Assert.AreEqual<string>("test.cab", cabInfo.Name, "CabInfo.Name"); | ||
700 | Assert.AreEqual<string>(new FileInfo("test.cab").FullName, cabInfo.ToString(), "CabInfo.ToString()"); | ||
701 | cabInfo.CopyTo("test3.cab"); | ||
702 | caughtEx = null; | ||
703 | try | ||
704 | { | ||
705 | cabInfo.CopyTo("test3.cab"); | ||
706 | } | ||
707 | catch (Exception ex) { caughtEx = ex; } | ||
708 | Assert.IsInstanceOfType(caughtEx, typeof(IOException), "CabInfo.CopyTo() caught exception: " + caughtEx); | ||
709 | cabInfo.CopyTo("test3.cab", true); | ||
710 | cabInfo.MoveTo("test4.cab"); | ||
711 | Assert.AreEqual<string>("test4.cab", cabInfo.Name); | ||
712 | Assert.IsTrue(cabInfo.Exists, "CabInfo.Exists()"); | ||
713 | Assert.IsTrue(cabInfo.IsValid(), "CabInfo.IsValid"); | ||
714 | cabInfo.Delete(); | ||
715 | Assert.IsFalse(cabInfo.Exists, "!CabInfo.Exists()"); | ||
716 | } | ||
717 | |||
718 | [TestMethod] | ||
719 | //[Ignore] // Requires clean environment. | ||
720 | public void CabInfoNullParams() | ||
721 | { | ||
722 | int fileCount = 10, fileSize = 1024; | ||
723 | string dirA = String.Format("{0}-{1}-A", fileCount, fileSize); | ||
724 | if (Directory.Exists(dirA)) Directory.Delete(dirA, true); | ||
725 | Directory.CreateDirectory(dirA); | ||
726 | string dirB = String.Format("{0}-{1}-B", fileCount, fileSize); | ||
727 | if (Directory.Exists(dirB)) Directory.Delete(dirB, true); | ||
728 | Directory.CreateDirectory(dirB); | ||
729 | |||
730 | string[] files = new string[fileCount]; | ||
731 | for (int iFile = 0; iFile < fileCount; iFile++) | ||
732 | { | ||
733 | files[iFile] = "cabinfo-" + iFile + ".txt"; | ||
734 | CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[iFile]), iFile, fileSize); | ||
735 | } | ||
736 | |||
737 | CabInfo cabInfo = new CabInfo("testnull.cab"); | ||
738 | |||
739 | CompressionTestUtil.TestArchiveInfoNullParams(cabInfo, dirA, dirB, files); | ||
740 | } | ||
741 | |||
742 | [TestMethod] | ||
743 | public void CabInfoGetFiles() | ||
744 | { | ||
745 | IList<CabFileInfo> fileInfo; | ||
746 | CabInfo cabInfo = new CabInfo("test.cab"); | ||
747 | int txtSize = 10240; | ||
748 | CompressionTestUtil.GenerateRandomFile("testinfo0.txt", 0, txtSize); | ||
749 | CompressionTestUtil.GenerateRandomFile("testinfo1.txt", 1, txtSize); | ||
750 | cabInfo.PackFiles(null, new string[] { "testinfo0.txt", "testinfo1.txt" }, null); | ||
751 | |||
752 | fileInfo = cabInfo.GetFiles(); | ||
753 | Assert.IsNotNull(fileInfo); | ||
754 | Assert.AreEqual<int>(2, fileInfo.Count); | ||
755 | Assert.AreEqual<string>("testinfo0.txt", fileInfo[0].Name); | ||
756 | Assert.AreEqual<string>("testinfo1.txt", fileInfo[1].Name); | ||
757 | |||
758 | fileInfo = cabInfo.GetFiles("*.txt"); | ||
759 | Assert.IsNotNull(fileInfo); | ||
760 | Assert.AreEqual<int>(2, fileInfo.Count); | ||
761 | Assert.AreEqual<string>("testinfo0.txt", fileInfo[0].Name); | ||
762 | Assert.AreEqual<string>("testinfo1.txt", fileInfo[1].Name); | ||
763 | |||
764 | fileInfo = cabInfo.GetFiles("testinfo1.txt"); | ||
765 | Assert.IsNotNull(fileInfo); | ||
766 | Assert.AreEqual<int>(1, fileInfo.Count); | ||
767 | Assert.AreEqual<string>("testinfo1.txt", fileInfo[0].Name); | ||
768 | } | ||
769 | |||
770 | [TestMethod] | ||
771 | public void CabInfoCompressExtract() | ||
772 | { | ||
773 | int fileCount = 10, fileSize = 1024; | ||
774 | string dirA = String.Format("{0}-{1}-A", fileCount, fileSize); | ||
775 | if (Directory.Exists(dirA)) Directory.Delete(dirA, true); | ||
776 | Directory.CreateDirectory(dirA); | ||
777 | Directory.CreateDirectory(Path.Combine(dirA, "sub")); | ||
778 | string dirB = String.Format("{0}-{1}-B", fileCount, fileSize); | ||
779 | if (Directory.Exists(dirB)) Directory.Delete(dirB, true); | ||
780 | Directory.CreateDirectory(dirB); | ||
781 | |||
782 | string[] files = new string[fileCount]; | ||
783 | for (int iFile = 0; iFile < fileCount; iFile++) | ||
784 | { | ||
785 | files[iFile] = "€" + iFile + ".txt"; | ||
786 | CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[iFile]), iFile, fileSize); | ||
787 | } | ||
788 | CompressionTestUtil.GenerateRandomFile(Path.Combine(Path.Combine(dirA, "sub"), "€-.txt"), fileCount + 1, fileSize); | ||
789 | |||
790 | CabInfo cabInfo = new CabInfo("test.cab"); | ||
791 | cabInfo.Pack(dirA); | ||
792 | cabInfo.Unpack(dirB); | ||
793 | bool directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB); | ||
794 | Assert.IsFalse(directoryMatch, | ||
795 | "Testing whether cabinet output directory matches input directory."); | ||
796 | Directory.Delete(dirB, true); | ||
797 | Directory.CreateDirectory(dirB); | ||
798 | cabInfo.Pack(dirA, true, CompressionLevel.Normal, null); | ||
799 | cabInfo.Unpack(dirB); | ||
800 | directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB); | ||
801 | Assert.IsTrue(directoryMatch, | ||
802 | "Testing whether cabinet output directory matches input directory."); | ||
803 | Directory.Delete(dirB, true); | ||
804 | Directory.Delete(Path.Combine(dirA, "sub"), true); | ||
805 | Directory.CreateDirectory(dirB); | ||
806 | cabInfo.Delete(); | ||
807 | |||
808 | cabInfo.PackFiles(dirA, files, null); | ||
809 | cabInfo.UnpackFiles(files, dirB, null); | ||
810 | directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB); | ||
811 | Assert.IsTrue(directoryMatch, | ||
812 | "Testing whether cabinet output directory matches input directory."); | ||
813 | Directory.Delete(dirB, true); | ||
814 | Directory.CreateDirectory(dirB); | ||
815 | cabInfo.Delete(); | ||
816 | |||
817 | IDictionary<string, string> testMap = new Dictionary<string, string>(files.Length); | ||
818 | for (int iFile = 0; iFile < fileCount; iFile++) | ||
819 | { | ||
820 | testMap[files[iFile] + ".key"] = files[iFile]; | ||
821 | } | ||
822 | cabInfo.PackFileSet(dirA, testMap); | ||
823 | cabInfo.UnpackFileSet(testMap, dirB); | ||
824 | directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB); | ||
825 | Assert.IsTrue(directoryMatch, | ||
826 | "Testing whether cabinet output directory matches input directory."); | ||
827 | Directory.Delete(dirB, true); | ||
828 | Directory.CreateDirectory(dirB); | ||
829 | |||
830 | testMap.Remove(files[1] + ".key"); | ||
831 | cabInfo.UnpackFileSet(testMap, dirB); | ||
832 | directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB); | ||
833 | Assert.IsFalse(directoryMatch, | ||
834 | "Testing whether cabinet output directory matches input directory."); | ||
835 | Directory.Delete(dirB, true); | ||
836 | Directory.CreateDirectory(dirB); | ||
837 | cabInfo.Delete(); | ||
838 | |||
839 | cabInfo.PackFiles(dirA, files, null); | ||
840 | cabInfo.UnpackFile("€2.txt", Path.Combine(dirB, "test.txt")); | ||
841 | Assert.IsTrue(File.Exists(Path.Combine(dirB, "test.txt"))); | ||
842 | Assert.AreEqual<int>(1, Directory.GetFiles(dirB).Length); | ||
843 | } | ||
844 | |||
845 | [TestMethod] | ||
846 | //[Ignore] // Requires clean environment. | ||
847 | public void CabFileInfoProperties() | ||
848 | { | ||
849 | CabInfo cabInfo = new CabInfo("test.cab"); | ||
850 | int txtSize = 10240; | ||
851 | CompressionTestUtil.GenerateRandomFile("test00.txt", 0, txtSize); | ||
852 | CompressionTestUtil.GenerateRandomFile("test01.txt", 1, txtSize); | ||
853 | File.SetAttributes("test01.txt", FileAttributes.ReadOnly | FileAttributes.Archive); | ||
854 | DateTime testTime = File.GetLastWriteTime("test01.txt"); | ||
855 | cabInfo.PackFiles(null, new string[] { "test00.txt", "test01.txt" }, null); | ||
856 | File.SetAttributes("test01.txt", FileAttributes.Archive); | ||
857 | |||
858 | CabFileInfo cfi = new CabFileInfo(cabInfo, "test01.txt"); | ||
859 | Assert.AreEqual(cabInfo.FullName, cfi.CabinetName); | ||
860 | Assert.AreEqual<int>(0, ((CabFileInfo) cfi).CabinetFolderNumber); | ||
861 | Assert.AreEqual<string>(Path.Combine(cabInfo.FullName, "test01.txt"), cfi.FullName); | ||
862 | cfi = new CabFileInfo(cabInfo, "test01.txt"); | ||
863 | Assert.IsTrue(cfi.Exists); | ||
864 | cfi = new CabFileInfo(cabInfo, "test01.txt"); | ||
865 | Assert.AreEqual<long>(txtSize, cfi.Length); | ||
866 | cfi = new CabFileInfo(cabInfo, "test00.txt"); | ||
867 | Assert.AreEqual<FileAttributes>(FileAttributes.Archive, cfi.Attributes); | ||
868 | cfi = new CabFileInfo(cabInfo, "test01.txt"); | ||
869 | Assert.AreEqual<FileAttributes>(FileAttributes.ReadOnly | FileAttributes.Archive, cfi.Attributes); | ||
870 | cfi = new CabFileInfo(cabInfo, "test01.txt"); | ||
871 | Assert.IsTrue((testTime - cfi.LastWriteTime).Duration() < new TimeSpan(0, 0, 5)); | ||
872 | Assert.AreEqual<string>(Path.Combine(cabInfo.FullName, "test01.txt"), cfi.ToString()); | ||
873 | cfi.CopyTo("testcopy.txt"); | ||
874 | Assert.IsTrue(File.Exists("testCopy.txt")); | ||
875 | Assert.AreEqual<long>(cfi.Length, new FileInfo("testCopy.txt").Length); | ||
876 | |||
877 | Exception caughtEx = null; | ||
878 | try | ||
879 | { | ||
880 | cfi.CopyTo("testcopy.txt", false); | ||
881 | } | ||
882 | catch (Exception ex) { caughtEx = ex; } | ||
883 | Assert.IsInstanceOfType(caughtEx, typeof(IOException)); | ||
884 | } | ||
885 | |||
886 | [TestMethod] | ||
887 | public void CabFileInfoOpenText() | ||
888 | { | ||
889 | CabInfo cabInfo = new CabInfo("test.cab"); | ||
890 | int txtSize = 10240; | ||
891 | CompressionTestUtil.GenerateRandomFile("test00.txt", 0, txtSize); | ||
892 | CompressionTestUtil.GenerateRandomFile("test01.txt", 1, txtSize); | ||
893 | |||
894 | string expectedText = File.ReadAllText("test01.txt"); | ||
895 | |||
896 | cabInfo.PackFiles(null, new string[] { "test00.txt", "test01.txt" }, null); | ||
897 | |||
898 | CabFileInfo cfi = new CabFileInfo(cabInfo, "test01.txt"); | ||
899 | using (StreamReader cabFileReader = cfi.OpenText()) | ||
900 | { | ||
901 | string text = cabFileReader.ReadToEnd(); | ||
902 | Assert.AreEqual(expectedText, text); | ||
903 | |||
904 | // Check the assumption that the cab can't be deleted while a stream is open. | ||
905 | Exception caughtEx = null; | ||
906 | try | ||
907 | { | ||
908 | File.Delete(cabInfo.FullName); | ||
909 | } | ||
910 | catch (Exception ex) | ||
911 | { | ||
912 | caughtEx = ex; | ||
913 | } | ||
914 | |||
915 | Assert.IsInstanceOfType(caughtEx, typeof(IOException)); | ||
916 | } | ||
917 | |||
918 | // Ensure all streams are closed after disposing of the StreamReader returned by OpenText. | ||
919 | File.Delete(cabInfo.FullName); | ||
920 | } | ||
921 | |||
922 | [TestMethod] | ||
923 | public void CabFileInfoNullParams() | ||
924 | { | ||
925 | Exception caughtEx; | ||
926 | CabInfo cabInfo = new CabInfo("test.cab"); | ||
927 | int txtSize = 10240; | ||
928 | CompressionTestUtil.GenerateRandomFile("test00.txt", 0, txtSize); | ||
929 | CompressionTestUtil.GenerateRandomFile("test01.txt", 1, txtSize); | ||
930 | cabInfo.PackFiles(null, new string[] { "test00.txt", "test01.txt" }, null); | ||
931 | CabFileInfo cfi = new CabFileInfo(cabInfo, "test01.txt"); | ||
932 | |||
933 | caughtEx = null; | ||
934 | try | ||
935 | { | ||
936 | new CabFileInfo(null, "test00.txt"); | ||
937 | } | ||
938 | catch (Exception ex) { caughtEx = ex; } | ||
939 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException)); | ||
940 | caughtEx = null; | ||
941 | try | ||
942 | { | ||
943 | new CabFileInfo(cabInfo, null); | ||
944 | } | ||
945 | catch (Exception ex) { caughtEx = ex; } | ||
946 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException)); | ||
947 | caughtEx = null; | ||
948 | try | ||
949 | { | ||
950 | cfi.CopyTo(null); | ||
951 | } | ||
952 | catch (Exception ex) { caughtEx = ex; } | ||
953 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException)); | ||
954 | } | ||
955 | |||
956 | [TestMethod] | ||
957 | public void CabInfoSerialization() | ||
958 | { | ||
959 | CabInfo cabInfo = new CabInfo("testser.cab"); | ||
960 | int txtSize = 10240; | ||
961 | CompressionTestUtil.GenerateRandomFile("testser00.txt", 0, txtSize); | ||
962 | CompressionTestUtil.GenerateRandomFile("testser01.txt", 1, txtSize); | ||
963 | cabInfo.PackFiles(null, new string[] { "testser00.txt", "testser01.txt" }, null); | ||
964 | ArchiveFileInfo cfi = cabInfo.GetFiles()[1]; | ||
965 | |||
966 | MemoryStream memStream = new MemoryStream(); | ||
967 | |||
968 | BinaryFormatter formatter = new BinaryFormatter(); | ||
969 | |||
970 | memStream.Seek(0, SeekOrigin.Begin); | ||
971 | formatter.Serialize(memStream, cabInfo); | ||
972 | memStream.Seek(0, SeekOrigin.Begin); | ||
973 | CabInfo cabInfo2 = (CabInfo) formatter.Deserialize(memStream); | ||
974 | Assert.AreEqual<string>(cabInfo.FullName, cabInfo2.FullName); | ||
975 | |||
976 | memStream.Seek(0, SeekOrigin.Begin); | ||
977 | formatter.Serialize(memStream, cfi); | ||
978 | memStream.Seek(0, SeekOrigin.Begin); | ||
979 | CabFileInfo cfi2 = (CabFileInfo) formatter.Deserialize(memStream); | ||
980 | Assert.AreEqual<string>(cfi.FullName, cfi2.FullName); | ||
981 | Assert.AreEqual<long>(cfi.Length, cfi2.Length); | ||
982 | |||
983 | CabException cabEx = new CabException(); | ||
984 | memStream.Seek(0, SeekOrigin.Begin); | ||
985 | formatter.Serialize(memStream, cabEx); | ||
986 | memStream.Seek(0, SeekOrigin.Begin); | ||
987 | formatter.Deserialize(memStream); | ||
988 | |||
989 | cabEx = new CabException("Test exception.", null); | ||
990 | Assert.AreEqual<string>("Test exception.", cabEx.Message); | ||
991 | } | ||
992 | |||
993 | [TestMethod] | ||
994 | public void CabFileStreamContextNullParams() | ||
995 | { | ||
996 | ArchiveFileStreamContext streamContext = null; | ||
997 | Exception caughtEx = null; | ||
998 | try | ||
999 | { | ||
1000 | streamContext = new ArchiveFileStreamContext(null); | ||
1001 | } | ||
1002 | catch (Exception ex) { caughtEx = ex; } | ||
1003 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Passing null to constructor."); | ||
1004 | caughtEx = null; | ||
1005 | try | ||
1006 | { | ||
1007 | streamContext = new ArchiveFileStreamContext(new string[] { }, "testDir", new Dictionary<string, string>()); | ||
1008 | } | ||
1009 | catch (Exception ex) { caughtEx = ex; } | ||
1010 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Passing 0-length array to constructor."); | ||
1011 | caughtEx = null; | ||
1012 | try | ||
1013 | { | ||
1014 | streamContext = new ArchiveFileStreamContext(new string[] { "test.cab" }, null, null); | ||
1015 | } | ||
1016 | catch (Exception ex) { caughtEx = ex; } | ||
1017 | Assert.IsNull(caughtEx); | ||
1018 | } | ||
1019 | |||
1020 | [TestMethod] | ||
1021 | public void CabinetTruncateOnCreate() | ||
1022 | { | ||
1023 | CabInfo cabInfo = new CabInfo("testtruncate.cab"); | ||
1024 | int txtSize = 20240; | ||
1025 | CompressionTestUtil.GenerateRandomFile("testtruncate0.txt", 0, txtSize); | ||
1026 | CompressionTestUtil.GenerateRandomFile("testtruncate1.txt", 1, txtSize); | ||
1027 | cabInfo.PackFiles(null, new string[] { "testtruncate0.txt", "testtruncate1.txt" }, null); | ||
1028 | |||
1029 | long size1 = cabInfo.Length; | ||
1030 | |||
1031 | txtSize /= 5; | ||
1032 | CompressionTestUtil.GenerateRandomFile("testtruncate2.txt", 2, txtSize); | ||
1033 | CompressionTestUtil.GenerateRandomFile("testtruncate3.txt", 3, txtSize); | ||
1034 | cabInfo.PackFiles(null, new string[] { "testtruncate2.txt", "testtruncate3.txt" }, null); | ||
1035 | |||
1036 | // The newly created cab file should be smaller than before. | ||
1037 | Assert.AreNotEqual<long>(size1, cabInfo.Length, "Checking that cabinet file got truncated when creating a smaller cab in-place."); | ||
1038 | } | ||
1039 | |||
1040 | [TestMethod] | ||
1041 | public void CabTruncatedArchive() | ||
1042 | { | ||
1043 | CabInfo cabInfo = new CabInfo("test-t.cab"); | ||
1044 | CompressionTestUtil.GenerateRandomFile("cabtest-0.txt", 0, 5); | ||
1045 | CompressionTestUtil.GenerateRandomFile("cabtest-1.txt", 1, 5); | ||
1046 | cabInfo.PackFiles(null, new string[] { "cabtest-0.txt", "cabtest-1.txt" }, null); | ||
1047 | |||
1048 | CompressionTestUtil.TestTruncatedArchive(cabInfo, typeof(CabException)); | ||
1049 | } | ||
1050 | private const string TEST_FILENAME_PREFIX = "\x20AC"; | ||
1051 | |||
1052 | private IList<ArchiveFileInfo> RunCabinetPackUnpack(int fileCount, long fileSize) | ||
1053 | { | ||
1054 | return RunCabinetPackUnpack(fileCount, fileSize, 0, 0); | ||
1055 | } | ||
1056 | private IList<ArchiveFileInfo> RunCabinetPackUnpack(int fileCount, long fileSize, | ||
1057 | long maxFolderSize, long maxArchiveSize) | ||
1058 | { | ||
1059 | return this.RunCabinetPackUnpack(fileCount, fileSize, maxFolderSize, maxArchiveSize, CompressionLevel.Normal); | ||
1060 | } | ||
1061 | private IList<ArchiveFileInfo> RunCabinetPackUnpack(int fileCount, long fileSize, | ||
1062 | long maxFolderSize, long maxArchiveSize, CompressionLevel compLevel) | ||
1063 | { | ||
1064 | Console.WriteLine("Creating cabinet with {0} files of size {1}", | ||
1065 | fileCount, fileSize); | ||
1066 | Console.WriteLine("MaxFolderSize={0}, MaxArchiveSize={1}, CompressionLevel={2}", | ||
1067 | maxFolderSize, maxArchiveSize, compLevel); | ||
1068 | |||
1069 | string dirA = String.Format("{0}-{1}-A", fileCount, fileSize); | ||
1070 | if (Directory.Exists(dirA)) Directory.Delete(dirA, true); | ||
1071 | Directory.CreateDirectory(dirA); | ||
1072 | string dirB = String.Format("{0}-{1}-B", fileCount, fileSize); | ||
1073 | if (Directory.Exists(dirB)) Directory.Delete(dirB, true); | ||
1074 | Directory.CreateDirectory(dirB); | ||
1075 | |||
1076 | string[] files = new string[fileCount]; | ||
1077 | for (int iFile = 0; iFile < fileCount; iFile++) | ||
1078 | { | ||
1079 | files[iFile] = TEST_FILENAME_PREFIX + iFile + ".txt"; | ||
1080 | CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[iFile]), iFile, fileSize); | ||
1081 | } | ||
1082 | |||
1083 | string[] archiveNames = new string[100]; | ||
1084 | for (int i = 0; i < archiveNames.Length; i++) | ||
1085 | { | ||
1086 | archiveNames[i] = String.Format("{0}-{1}{2}{3}.cab", fileCount, fileSize, | ||
1087 | (i == 0 ? "" : "-"), (i == 0 ? "" : i.ToString())); | ||
1088 | } | ||
1089 | |||
1090 | string progressTextFile = String.Format("progress_{0}-{1}.txt", fileCount, fileSize); | ||
1091 | CompressionTestUtil testUtil = new CompressionTestUtil(progressTextFile); | ||
1092 | |||
1093 | IList<ArchiveFileInfo> fileInfo; | ||
1094 | using (CabEngine cabEngine = new CabEngine()) | ||
1095 | { | ||
1096 | cabEngine.CompressionLevel = compLevel; | ||
1097 | |||
1098 | File.AppendAllText(progressTextFile, | ||
1099 | "\r\n\r\n====================================================\r\nCREATE\r\n\r\n"); | ||
1100 | cabEngine.Progress += testUtil.PrintArchiveProgress; | ||
1101 | |||
1102 | OptionStreamContext streamContext = new OptionStreamContext(archiveNames, dirA, null); | ||
1103 | if (maxFolderSize == 1) | ||
1104 | { | ||
1105 | streamContext.OptionHandler = | ||
1106 | delegate(string optionName, object[] parameters) | ||
1107 | { | ||
1108 | if (optionName == "nextFolder") return true; | ||
1109 | return null; | ||
1110 | }; | ||
1111 | } | ||
1112 | else if (maxFolderSize > 1) | ||
1113 | { | ||
1114 | streamContext.OptionHandler = | ||
1115 | delegate(string optionName, object[] parameters) | ||
1116 | { | ||
1117 | if (optionName == "maxFolderSize") return maxFolderSize; | ||
1118 | return null; | ||
1119 | }; | ||
1120 | } | ||
1121 | cabEngine.Pack(streamContext, files, maxArchiveSize); | ||
1122 | |||
1123 | IList<string> createdArchiveNames = new List<string>(archiveNames.Length); | ||
1124 | for (int i = 0; i < archiveNames.Length; i++) | ||
1125 | { | ||
1126 | if (File.Exists(archiveNames[i])) | ||
1127 | { | ||
1128 | createdArchiveNames.Add(archiveNames[i]); | ||
1129 | } | ||
1130 | else | ||
1131 | { | ||
1132 | break; | ||
1133 | } | ||
1134 | } | ||
1135 | |||
1136 | Console.WriteLine("Listing cabinet with {0} files of size {1}", | ||
1137 | fileCount, fileSize); | ||
1138 | File.AppendAllText(progressTextFile, "\r\n\r\nLIST\r\n\r\n"); | ||
1139 | fileInfo = cabEngine.GetFileInfo( | ||
1140 | new ArchiveFileStreamContext(createdArchiveNames, null, null), null); | ||
1141 | |||
1142 | Assert.AreEqual<int>(fileCount, fileInfo.Count); | ||
1143 | if (fileCount > 0) | ||
1144 | { | ||
1145 | int folders = ((CabFileInfo) fileInfo[fileInfo.Count - 1]).CabinetFolderNumber + 1; | ||
1146 | if (maxFolderSize == 1) | ||
1147 | { | ||
1148 | Assert.AreEqual<int>(fileCount, folders); | ||
1149 | } | ||
1150 | } | ||
1151 | |||
1152 | Console.WriteLine("Extracting cabinet with {0} files of size {1}", | ||
1153 | fileCount, fileSize); | ||
1154 | File.AppendAllText(progressTextFile, "\r\n\r\nEXTRACT\r\n\r\n"); | ||
1155 | cabEngine.Unpack(new ArchiveFileStreamContext(createdArchiveNames, dirB, null), null); | ||
1156 | } | ||
1157 | |||
1158 | bool directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB); | ||
1159 | Assert.IsTrue(directoryMatch, | ||
1160 | "Testing whether cabinet output directory matches input directory."); | ||
1161 | |||
1162 | return fileInfo; | ||
1163 | } | ||
1164 | } | ||
1165 | } | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.Compression.Cab/WixToolsetTests.Dtf.Compression.Cab.csproj b/src/dtf/test/WixToolsetTests.Dtf.Compression.Cab/WixToolsetTests.Dtf.Compression.Cab.csproj new file mode 100644 index 00000000..636cedc6 --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.Compression.Cab/WixToolsetTests.Dtf.Compression.Cab.csproj | |||
@@ -0,0 +1,43 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
3 | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="Current"> | ||
4 | <PropertyGroup> | ||
5 | <ProjectGuid>{4544158C-2D63-4146-85FF-62169280144E}</ProjectGuid> | ||
6 | <OutputType>Library</OutputType> | ||
7 | <RootNamespace>WixToolsetTests.Dtf.Cab</RootNamespace> | ||
8 | <AssemblyName>WixToolsetTests.Dtf.Cab</AssemblyName> | ||
9 | <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||
10 | <CreateDocumentation>false</CreateDocumentation> | ||
11 | <SignOutput>false</SignOutput> | ||
12 | <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> | ||
13 | </PropertyGroup> | ||
14 | |||
15 | <ItemGroup> | ||
16 | <Compile Include="CabTest.cs" /> | ||
17 | </ItemGroup> | ||
18 | |||
19 | <ItemGroup> | ||
20 | <Reference Include="System" /> | ||
21 | <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | ||
22 | <Reference Include="System.Data" /> | ||
23 | <Reference Include="System.Xml" /> | ||
24 | </ItemGroup> | ||
25 | |||
26 | <ItemGroup> | ||
27 | <ProjectReference Include="..\..\WixToolset.Dtf.Compression\WixToolset.Dtf.Compression.csproj"> | ||
28 | <Project>{45D81DAB-0559-4836-8106-CE9987FD4AB5}</Project> | ||
29 | <Name>WixToolset.Dtf.Compression</Name> | ||
30 | </ProjectReference> | ||
31 | <ProjectReference Include="..\..\WixToolset.Dtf.Compression.Cab\WixToolset.Dtf.Compression.Cab.csproj"> | ||
32 | <Project>{E56C0ED3-FA2F-4CA9-A1C0-2E796BB0BF80}</Project> | ||
33 | <Name>WixToolset.Dtf.Compression.Cab</Name> | ||
34 | </ProjectReference> | ||
35 | <ProjectReference Include="..\WixToolsetTests.Dtf.Compression\WixToolsetTests.Dtf.Compression.csproj"> | ||
36 | <Project>{F045FFC1-05F9-4EA2-9F03-E1CBDB7BC4F9}</Project> | ||
37 | <Name>WixToolsetTests.Dtf.Compression</Name> | ||
38 | </ProjectReference> | ||
39 | </ItemGroup> | ||
40 | |||
41 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> | ||
42 | <Target Name="Pack" DependsOnTargets="Build" /> | ||
43 | </Project> | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.Compression.Zip/WixToolsetTests.Dtf.Compression.Zip.csproj b/src/dtf/test/WixToolsetTests.Dtf.Compression.Zip/WixToolsetTests.Dtf.Compression.Zip.csproj new file mode 100644 index 00000000..d46776d8 --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.Compression.Zip/WixToolsetTests.Dtf.Compression.Zip.csproj | |||
@@ -0,0 +1,41 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
3 | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="Current"> | ||
4 | <PropertyGroup> | ||
5 | <ProjectGuid>{328799BB-7B03-4B28-8180-4132211FD07D}</ProjectGuid> | ||
6 | <OutputType>Library</OutputType> | ||
7 | <RootNamespace>WixToolsetTests.Dtf</RootNamespace> | ||
8 | <AssemblyName>WixToolsetTests.Dtf.Zip</AssemblyName> | ||
9 | <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||
10 | <CreateDocumentation>false</CreateDocumentation> | ||
11 | <SignOutput>false</SignOutput> | ||
12 | <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> | ||
13 | </PropertyGroup> | ||
14 | |||
15 | <ItemGroup> | ||
16 | <Compile Include="ZipTest.cs" /> | ||
17 | </ItemGroup> | ||
18 | |||
19 | <ItemGroup> | ||
20 | <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | ||
21 | <Reference Include="System" /> | ||
22 | </ItemGroup> | ||
23 | |||
24 | <ItemGroup> | ||
25 | <ProjectReference Include="..\..\WixToolset.Dtf.Compression\WixToolset.Dtf.Compression.csproj"> | ||
26 | <Project>{45D81DAB-0559-4836-8106-CE9987FD4AB5}</Project> | ||
27 | <Name>WixToolset.Dtf.Compression</Name> | ||
28 | </ProjectReference> | ||
29 | <ProjectReference Include="..\..\WixToolset.Dtf.Compression.Zip\WixToolset.Dtf.Compression.Zip.csproj"> | ||
30 | <Project>{E4C60A57-8AFE-4FF3-9058-ACAC6A069533}</Project> | ||
31 | <Name>WixToolset.Dtf.Compression.Zip</Name> | ||
32 | </ProjectReference> | ||
33 | <ProjectReference Include="..\WixToolsetTests.Dtf.Compression\WixToolsetTests.Dtf.Compression.csproj"> | ||
34 | <Project>{F045FFC1-05F9-4EA2-9F03-E1CBDB7BC4F9}</Project> | ||
35 | <Name>WixToolsetTests.Dtf.Compression</Name> | ||
36 | </ProjectReference> | ||
37 | </ItemGroup> | ||
38 | |||
39 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> | ||
40 | <Target Name="Pack" DependsOnTargets="Build" /> | ||
41 | </Project> | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.Compression.Zip/ZipTest.cs b/src/dtf/test/WixToolsetTests.Dtf.Compression.Zip/ZipTest.cs new file mode 100644 index 00000000..b264ad5b --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.Compression.Zip/ZipTest.cs | |||
@@ -0,0 +1,518 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | namespace WixToolset.Dtf.Test | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using System.Text; | ||
8 | using System.Collections.Generic; | ||
9 | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
10 | using WixToolset.Dtf.Compression; | ||
11 | using WixToolset.Dtf.Compression.Zip; | ||
12 | |||
13 | [TestClass] | ||
14 | public class ZipTest | ||
15 | { | ||
16 | public ZipTest() | ||
17 | { | ||
18 | } | ||
19 | |||
20 | [TestInitialize] | ||
21 | public void Initialize() | ||
22 | { | ||
23 | } | ||
24 | |||
25 | [TestCleanup] | ||
26 | public void Cleanup() | ||
27 | { | ||
28 | } | ||
29 | |||
30 | [TestMethod] | ||
31 | public void ZipFileCounts() | ||
32 | { | ||
33 | this.RunZipPackUnpack(0, 10, 0); | ||
34 | this.RunZipPackUnpack(0, 100000, 0); | ||
35 | this.RunZipPackUnpack(1, 10, 0); | ||
36 | this.RunZipPackUnpack(100, 10, 0); | ||
37 | } | ||
38 | |||
39 | [TestMethod] | ||
40 | [Ignore] // Takes too long to run regularly. | ||
41 | public void ZipExtremeFileCounts() | ||
42 | { | ||
43 | this.RunZipPackUnpack(66000, 10, 0); | ||
44 | } | ||
45 | |||
46 | [TestMethod] | ||
47 | public void ZipFileSizes() | ||
48 | { | ||
49 | this.RunZipPackUnpack(1, 0, 0); | ||
50 | for (int n = 1; n <= 33; n++) | ||
51 | { | ||
52 | this.RunZipPackUnpack(1, n, 0); | ||
53 | } | ||
54 | this.RunZipPackUnpack(1, 100 * 1024, 0); | ||
55 | this.RunZipPackUnpack(1, 10 * 1024 * 1024, 0); | ||
56 | } | ||
57 | |||
58 | [Timeout(36000000), TestMethod] | ||
59 | [Ignore] // Takes too long to run regularly. | ||
60 | public void ZipExtremeFileSizes() | ||
61 | { | ||
62 | //this.RunZipPackUnpack(10, 512L * 1024 * 1024, 0); // 5GB | ||
63 | this.RunZipPackUnpack(1, 5L * 1024 * 1024 * 1024, 0, CompressionLevel.None); // 5GB | ||
64 | } | ||
65 | |||
66 | [TestMethod] | ||
67 | public void ZipArchiveCounts() | ||
68 | { | ||
69 | IList<ArchiveFileInfo> fileInfo; | ||
70 | fileInfo = this.RunZipPackUnpack(10, 100 * 1024, 400 * 1024, CompressionLevel.None); | ||
71 | Assert.AreEqual<int>(2, fileInfo[fileInfo.Count - 1].ArchiveNumber, | ||
72 | "Testing whether archive spans the correct # of zip files."); | ||
73 | |||
74 | fileInfo = this.RunZipPackUnpack(2, 90 * 1024, 40 * 1024, CompressionLevel.None); | ||
75 | Assert.AreEqual<int>(2, fileInfo[fileInfo.Count - 1].ArchiveNumber, | ||
76 | "Testing whether archive spans the correct # of zip files."); | ||
77 | } | ||
78 | |||
79 | [TestMethod] | ||
80 | public void ZipProgress() | ||
81 | { | ||
82 | CompressionTestUtil.ExpectedProgress = new List<int[]>(new int[][] { | ||
83 | // StatusType, CurFile,TotalFiles,CurFolder,CurArchive,TotalArchives | ||
84 | new int[] { (int) ArchiveProgressType.StartArchive, 0, 15, 0, 0, 1 }, | ||
85 | new int[] { (int) ArchiveProgressType.StartFile, 0, 15, 0, 0, 1 }, | ||
86 | new int[] { (int) ArchiveProgressType.FinishFile, 0, 15, 0, 0, 1 }, | ||
87 | new int[] { (int) ArchiveProgressType.StartFile, 1, 15, 0, 0, 1 }, | ||
88 | new int[] { (int) ArchiveProgressType.FinishFile, 1, 15, 0, 0, 1 }, | ||
89 | new int[] { (int) ArchiveProgressType.StartFile, 2, 15, 0, 0, 1 }, | ||
90 | new int[] { (int) ArchiveProgressType.FinishFile, 2, 15, 0, 0, 1 }, | ||
91 | new int[] { (int) ArchiveProgressType.StartFile, 3, 15, 0, 0, 1 }, | ||
92 | new int[] { (int) ArchiveProgressType.FinishFile, 3, 15, 0, 0, 1 }, | ||
93 | new int[] { (int) ArchiveProgressType.StartFile, 4, 15, 0, 0, 1 }, | ||
94 | new int[] { (int) ArchiveProgressType.FinishFile, 4, 15, 0, 0, 1 }, | ||
95 | new int[] { (int) ArchiveProgressType.StartFile, 5, 15, 0, 0, 1 }, | ||
96 | new int[] { (int) ArchiveProgressType.FinishFile, 5, 15, 0, 0, 1 }, | ||
97 | new int[] { (int) ArchiveProgressType.StartFile, 6, 15, 0, 0, 1 }, | ||
98 | new int[] { (int) ArchiveProgressType.FinishArchive, 6, 15, 0, 0, 1 }, | ||
99 | new int[] { (int) ArchiveProgressType.StartArchive, 6, 15, 0, 1, 2 }, | ||
100 | new int[] { (int) ArchiveProgressType.FinishFile, 6, 15, 0, 1, 2 }, | ||
101 | new int[] { (int) ArchiveProgressType.StartFile, 7, 15, 0, 1, 2 }, | ||
102 | new int[] { (int) ArchiveProgressType.FinishFile, 7, 15, 0, 1, 2 }, | ||
103 | new int[] { (int) ArchiveProgressType.StartFile, 8, 15, 0, 1, 2 }, | ||
104 | new int[] { (int) ArchiveProgressType.FinishFile, 8, 15, 0, 1, 2 }, | ||
105 | new int[] { (int) ArchiveProgressType.StartFile, 9, 15, 0, 1, 2 }, | ||
106 | new int[] { (int) ArchiveProgressType.FinishFile, 9, 15, 0, 1, 2 }, | ||
107 | new int[] { (int) ArchiveProgressType.StartFile, 10, 15, 0, 1, 2 }, | ||
108 | new int[] { (int) ArchiveProgressType.FinishFile, 10, 15, 0, 1, 2 }, | ||
109 | new int[] { (int) ArchiveProgressType.StartFile, 11, 15, 0, 1, 2 }, | ||
110 | new int[] { (int) ArchiveProgressType.FinishFile, 11, 15, 0, 1, 2 }, | ||
111 | new int[] { (int) ArchiveProgressType.StartFile, 12, 15, 0, 1, 2 }, | ||
112 | new int[] { (int) ArchiveProgressType.FinishArchive, 12, 15, 0, 1, 2 }, | ||
113 | new int[] { (int) ArchiveProgressType.StartArchive, 12, 15, 0, 2, 3 }, | ||
114 | new int[] { (int) ArchiveProgressType.FinishFile, 12, 15, 0, 2, 3 }, | ||
115 | new int[] { (int) ArchiveProgressType.StartFile, 13, 15, 0, 2, 3 }, | ||
116 | new int[] { (int) ArchiveProgressType.FinishFile, 13, 15, 0, 2, 3 }, | ||
117 | new int[] { (int) ArchiveProgressType.StartFile, 14, 15, 0, 2, 3 }, | ||
118 | new int[] { (int) ArchiveProgressType.FinishFile, 14, 15, 0, 2, 3 }, | ||
119 | new int[] { (int) ArchiveProgressType.FinishArchive, 14, 15, 0, 2, 3 }, | ||
120 | // StatusType, CurFile,TotalFiles,CurFolder,CurArchive,TotalArchives | ||
121 | new int[] { (int) ArchiveProgressType.StartArchive, 0, 15, 0, 0, 3 }, | ||
122 | new int[] { (int) ArchiveProgressType.StartFile, 0, 15, 0, 0, 3 }, | ||
123 | new int[] { (int) ArchiveProgressType.FinishFile, 0, 15, 0, 0, 3 }, | ||
124 | new int[] { (int) ArchiveProgressType.StartFile, 1, 15, 0, 0, 3 }, | ||
125 | new int[] { (int) ArchiveProgressType.FinishFile, 1, 15, 0, 0, 3 }, | ||
126 | new int[] { (int) ArchiveProgressType.StartFile, 2, 15, 0, 0, 3 }, | ||
127 | new int[] { (int) ArchiveProgressType.FinishFile, 2, 15, 0, 0, 3 }, | ||
128 | new int[] { (int) ArchiveProgressType.StartFile, 3, 15, 0, 0, 3 }, | ||
129 | new int[] { (int) ArchiveProgressType.FinishFile, 3, 15, 0, 0, 3 }, | ||
130 | new int[] { (int) ArchiveProgressType.StartFile, 4, 15, 0, 0, 3 }, | ||
131 | new int[] { (int) ArchiveProgressType.FinishFile, 4, 15, 0, 0, 3 }, | ||
132 | new int[] { (int) ArchiveProgressType.StartFile, 5, 15, 0, 0, 3 }, | ||
133 | new int[] { (int) ArchiveProgressType.FinishFile, 5, 15, 0, 0, 3 }, | ||
134 | new int[] { (int) ArchiveProgressType.StartFile, 6, 15, 0, 0, 3 }, | ||
135 | new int[] { (int) ArchiveProgressType.FinishArchive, 6, 15, 0, 0, 3 }, | ||
136 | new int[] { (int) ArchiveProgressType.StartArchive, 6, 15, 0, 1, 3 }, | ||
137 | new int[] { (int) ArchiveProgressType.FinishFile, 6, 15, 0, 1, 3 }, | ||
138 | new int[] { (int) ArchiveProgressType.StartFile, 7, 15, 0, 1, 3 }, | ||
139 | new int[] { (int) ArchiveProgressType.FinishFile, 7, 15, 0, 1, 3 }, | ||
140 | new int[] { (int) ArchiveProgressType.StartFile, 8, 15, 0, 1, 3 }, | ||
141 | new int[] { (int) ArchiveProgressType.FinishFile, 8, 15, 0, 1, 3 }, | ||
142 | new int[] { (int) ArchiveProgressType.StartFile, 9, 15, 0, 1, 3 }, | ||
143 | new int[] { (int) ArchiveProgressType.FinishFile, 9, 15, 0, 1, 3 }, | ||
144 | new int[] { (int) ArchiveProgressType.StartFile, 10, 15, 0, 1, 3 }, | ||
145 | new int[] { (int) ArchiveProgressType.FinishFile, 10, 15, 0, 1, 3 }, | ||
146 | new int[] { (int) ArchiveProgressType.StartFile, 11, 15, 0, 1, 3 }, | ||
147 | new int[] { (int) ArchiveProgressType.FinishFile, 11, 15, 0, 1, 3 }, | ||
148 | new int[] { (int) ArchiveProgressType.StartFile, 12, 15, 0, 1, 3 }, | ||
149 | new int[] { (int) ArchiveProgressType.FinishArchive, 12, 15, 0, 1, 3 }, | ||
150 | new int[] { (int) ArchiveProgressType.StartArchive, 12, 15, 0, 2, 3 }, | ||
151 | new int[] { (int) ArchiveProgressType.FinishFile, 12, 15, 0, 2, 3 }, | ||
152 | new int[] { (int) ArchiveProgressType.StartFile, 13, 15, 0, 2, 3 }, | ||
153 | new int[] { (int) ArchiveProgressType.FinishFile, 13, 15, 0, 2, 3 }, | ||
154 | new int[] { (int) ArchiveProgressType.StartFile, 14, 15, 0, 2, 3 }, | ||
155 | new int[] { (int) ArchiveProgressType.FinishFile, 14, 15, 0, 2, 3 }, | ||
156 | new int[] { (int) ArchiveProgressType.FinishArchive, 14, 15, 0, 2, 3 }, | ||
157 | }); | ||
158 | CompressionTestUtil.ExpectedProgress = null; | ||
159 | |||
160 | try | ||
161 | { | ||
162 | this.RunZipPackUnpack(15, 20 * 1024, 130 * 1024, CompressionLevel.None); | ||
163 | } | ||
164 | finally | ||
165 | { | ||
166 | CompressionTestUtil.ExpectedProgress = null; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | [TestMethod] | ||
171 | //[Ignore] // Requires clean environment. | ||
172 | public void ZipArchiveSizes() | ||
173 | { | ||
174 | Console.WriteLine("Testing various values for the maxArchiveSize parameter."); | ||
175 | this.RunZipPackUnpack(5, 1024, Int64.MinValue); | ||
176 | this.RunZipPackUnpack(5, 1024, -1); | ||
177 | this.RunZipPackUnpack(2, 10, 0); | ||
178 | |||
179 | this.RunZipPackUnpack(1, 10, 1); | ||
180 | this.RunZipPackUnpack(2, 10, 2); | ||
181 | this.RunZipPackUnpack(2, 10, 3); | ||
182 | this.RunZipPackUnpack(2, 10, 4); | ||
183 | this.RunZipPackUnpack(2, 10, 5); | ||
184 | this.RunZipPackUnpack(2, 10, 6); | ||
185 | this.RunZipPackUnpack(2, 10, 7); | ||
186 | this.RunZipPackUnpack(5, 10, 8); | ||
187 | this.RunZipPackUnpack(5, 10, 9); | ||
188 | this.RunZipPackUnpack(5, 10, 10); | ||
189 | this.RunZipPackUnpack(5, 10, 11); | ||
190 | this.RunZipPackUnpack(5, 10, 12); | ||
191 | |||
192 | this.RunZipPackUnpack(5, 101, 255); | ||
193 | this.RunZipPackUnpack(5, 102, 256); | ||
194 | this.RunZipPackUnpack(5, 103, 257); | ||
195 | this.RunZipPackUnpack(5, 24000, 32768); | ||
196 | this.RunZipPackUnpack(5, 1024, Int64.MaxValue); | ||
197 | } | ||
198 | |||
199 | [TestMethod] | ||
200 | public void ZipCompLevelParam() | ||
201 | { | ||
202 | Console.WriteLine("Testing various values for the compressionLevel parameter."); | ||
203 | this.RunZipPackUnpack(5, 1024, 0, CompressionLevel.None); | ||
204 | this.RunZipPackUnpack(5, 1024, 0, CompressionLevel.Min); | ||
205 | this.RunZipPackUnpack(5, 1024, 0, CompressionLevel.Normal); | ||
206 | this.RunZipPackUnpack(5, 1024, 0, CompressionLevel.Max); | ||
207 | this.RunZipPackUnpack(5, 1024, 0, (CompressionLevel) ((int) CompressionLevel.None - 1)); | ||
208 | this.RunZipPackUnpack(5, 1024, 0, (CompressionLevel) ((int) CompressionLevel.Max + 1)); | ||
209 | this.RunZipPackUnpack(5, 1024, 0, (CompressionLevel) Int32.MinValue); | ||
210 | this.RunZipPackUnpack(5, 1024, 0, (CompressionLevel) Int32.MaxValue); | ||
211 | } | ||
212 | |||
213 | [TestMethod] | ||
214 | public void ZipInfoGetFiles() | ||
215 | { | ||
216 | IList<ZipFileInfo> fileInfos; | ||
217 | ZipInfo zipInfo = new ZipInfo("testgetfiles.zip"); | ||
218 | |||
219 | int txtSize = 10240; | ||
220 | CompressionTestUtil.GenerateRandomFile("testinfo0.txt", 0, txtSize); | ||
221 | CompressionTestUtil.GenerateRandomFile("testinfo1.txt", 1, txtSize); | ||
222 | CompressionTestUtil.GenerateRandomFile("testinfo2.ini", 2, txtSize); | ||
223 | zipInfo.PackFiles(null, new string[] { "testinfo0.txt", "testinfo1.txt", "testinfo2.ini" }, null); | ||
224 | |||
225 | fileInfos = zipInfo.GetFiles(); | ||
226 | Assert.IsNotNull(fileInfos); | ||
227 | Assert.AreEqual<int>(3, fileInfos.Count); | ||
228 | Assert.AreEqual<string>("testinfo0.txt", fileInfos[0].Name); | ||
229 | Assert.AreEqual<string>("testinfo1.txt", fileInfos[1].Name); | ||
230 | Assert.AreEqual<string>("testinfo2.ini", fileInfos[2].Name); | ||
231 | |||
232 | fileInfos = zipInfo.GetFiles("*.txt"); | ||
233 | Assert.IsNotNull(fileInfos); | ||
234 | Assert.AreEqual<int>(2, fileInfos.Count); | ||
235 | Assert.AreEqual<string>("testinfo0.txt", fileInfos[0].Name); | ||
236 | Assert.AreEqual<string>("testinfo1.txt", fileInfos[1].Name); | ||
237 | |||
238 | fileInfos = zipInfo.GetFiles("testinfo1.txt"); | ||
239 | Assert.IsNotNull(fileInfos); | ||
240 | Assert.AreEqual<int>(1, fileInfos.Count); | ||
241 | Assert.AreEqual<string>("testinfo1.txt", fileInfos[0].Name); | ||
242 | Assert.IsTrue(DateTime.Now - fileInfos[0].LastWriteTime < TimeSpan.FromMinutes(1), | ||
243 | "Checking ZipFileInfo.LastWriteTime is current."); | ||
244 | } | ||
245 | |||
246 | [TestMethod] | ||
247 | //[Ignore] // Requires clean environment. | ||
248 | public void ZipInfoNullParams() | ||
249 | { | ||
250 | int fileCount = 10, fileSize = 1024; | ||
251 | string dirA = String.Format("{0}-{1}-A", fileCount, fileSize); | ||
252 | if (Directory.Exists(dirA)) Directory.Delete(dirA, true); | ||
253 | Directory.CreateDirectory(dirA); | ||
254 | string dirB = String.Format("{0}-{1}-B", fileCount, fileSize); | ||
255 | if (Directory.Exists(dirB)) Directory.Delete(dirB, true); | ||
256 | Directory.CreateDirectory(dirB); | ||
257 | |||
258 | string[] files = new string[fileCount]; | ||
259 | for (int iFile = 0; iFile < fileCount; iFile++) | ||
260 | { | ||
261 | files[iFile] = "zipinfo-" + iFile + ".txt"; | ||
262 | CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[iFile]), iFile, fileSize); | ||
263 | } | ||
264 | |||
265 | ZipInfo zipInfo = new ZipInfo("testnull.zip"); | ||
266 | |||
267 | CompressionTestUtil.TestArchiveInfoNullParams(zipInfo, dirA, dirB, files); | ||
268 | } | ||
269 | |||
270 | [TestMethod] | ||
271 | public void ZipFileInfoNullParams() | ||
272 | { | ||
273 | Exception caughtEx; | ||
274 | ZipInfo zipInfo = new ZipInfo("test.zip"); | ||
275 | int txtSize = 10240; | ||
276 | CompressionTestUtil.GenerateRandomFile("test00.txt", 0, txtSize); | ||
277 | CompressionTestUtil.GenerateRandomFile("test01.txt", 1, txtSize); | ||
278 | zipInfo.PackFiles(null, new string[] { "test00.txt", "test01.txt" }, null); | ||
279 | ZipFileInfo zfi = new ZipFileInfo(zipInfo, "test01.txt"); | ||
280 | |||
281 | caughtEx = null; | ||
282 | try | ||
283 | { | ||
284 | new ZipFileInfo(null, "test00.txt"); | ||
285 | } | ||
286 | catch (Exception ex) { caughtEx = ex; } | ||
287 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException)); | ||
288 | caughtEx = null; | ||
289 | try | ||
290 | { | ||
291 | new ZipFileInfo(zipInfo, null); | ||
292 | } | ||
293 | catch (Exception ex) { caughtEx = ex; } | ||
294 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException)); | ||
295 | caughtEx = null; | ||
296 | try | ||
297 | { | ||
298 | zfi.CopyTo(null); | ||
299 | } | ||
300 | catch (Exception ex) { caughtEx = ex; } | ||
301 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException)); | ||
302 | } | ||
303 | |||
304 | [TestMethod] | ||
305 | public void ZipEngineNullParams() | ||
306 | { | ||
307 | string[] testFiles = new string[] { "test.txt" }; | ||
308 | ArchiveFileStreamContext streamContext = new ArchiveFileStreamContext("test.zip", null, null); | ||
309 | |||
310 | using (ZipEngine zipEngine = new ZipEngine()) | ||
311 | { | ||
312 | zipEngine.CompressionLevel = CompressionLevel.None; | ||
313 | |||
314 | CompressionTestUtil.TestCompressionEngineNullParams(zipEngine, streamContext, testFiles); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | [TestMethod] | ||
319 | public void ZipBadPackStreamContexts() | ||
320 | { | ||
321 | string[] testFiles = new string[] { "test.txt" }; | ||
322 | CompressionTestUtil.GenerateRandomFile(testFiles[0], 0, 20000); | ||
323 | |||
324 | using (ZipEngine zipEngine = new ZipEngine()) | ||
325 | { | ||
326 | zipEngine.CompressionLevel = CompressionLevel.None; | ||
327 | |||
328 | CompressionTestUtil.TestBadPackStreamContexts(zipEngine, "test.zip", testFiles); | ||
329 | } | ||
330 | } | ||
331 | |||
332 | [TestMethod] | ||
333 | public void ZipBadUnpackStreamContexts() | ||
334 | { | ||
335 | int txtSize = 40960; | ||
336 | ZipInfo zipInfo = new ZipInfo("test2.zip"); | ||
337 | CompressionTestUtil.GenerateRandomFile("ziptest-0.txt", 0, txtSize); | ||
338 | CompressionTestUtil.GenerateRandomFile("ziptest-1.txt", 1, txtSize); | ||
339 | zipInfo.PackFiles(null, new string[] { "ziptest-0.txt", "ziptest-1.txt" }, null); | ||
340 | |||
341 | using (ZipEngine zipEngine = new ZipEngine()) | ||
342 | { | ||
343 | CompressionTestUtil.TestBadUnpackStreamContexts(zipEngine, "test2.zip"); | ||
344 | } | ||
345 | } | ||
346 | |||
347 | [TestMethod] | ||
348 | [Ignore] // Failed on build server, need to investigate. | ||
349 | public void ZipTruncatedArchive() | ||
350 | { | ||
351 | ZipInfo zipInfo = new ZipInfo("test-t.zip"); | ||
352 | CompressionTestUtil.GenerateRandomFile("ziptest-0.txt", 0, 5); | ||
353 | CompressionTestUtil.GenerateRandomFile("ziptest-1.txt", 1, 5); | ||
354 | zipInfo.PackFiles(null, new string[] { "ziptest-0.txt", "ziptest-1.txt" }, null); | ||
355 | |||
356 | CompressionTestUtil.TestTruncatedArchive(zipInfo, typeof(ZipException)); | ||
357 | } | ||
358 | |||
359 | /* | ||
360 | [TestMethod] | ||
361 | public void ZipUnpack() | ||
362 | { | ||
363 | IList<ZipFileInfo> fileInfos; | ||
364 | foreach (FileInfo zipFile in new DirectoryInfo("D:\\temp").GetFiles("*.zip")) | ||
365 | { | ||
366 | Console.WriteLine("====================================================="); | ||
367 | Console.WriteLine(zipFile.FullName); | ||
368 | Console.WriteLine("====================================================="); | ||
369 | ZipInfo zipTest = new ZipInfo(zipFile.FullName); | ||
370 | fileInfos = zipTest.GetFiles(); | ||
371 | Assert.AreNotEqual<int>(0, fileInfos.Count); | ||
372 | foreach (ArchiveFileInfo file in fileInfos) | ||
373 | { | ||
374 | Console.WriteLine("{0}\t{1}\t{2}", Path.Combine(file.Path, file.Name), file.Length, file.LastWriteTime); | ||
375 | } | ||
376 | |||
377 | Directory.CreateDirectory(Path.GetFileNameWithoutExtension(zipFile.Name)); | ||
378 | zipTest.Unpack(Path.GetFileNameWithoutExtension(zipFile.Name)); | ||
379 | } | ||
380 | } | ||
381 | */ | ||
382 | |||
383 | /* | ||
384 | [TestMethod] | ||
385 | public void ZipUnpackSelfExtractor() | ||
386 | { | ||
387 | ZipInfo zipTest = new ZipInfo(@"C:\temp\testzip.exe"); | ||
388 | IList<ZipFileInfo> fileInfos = zipTest.GetFiles(); | ||
389 | Assert.AreNotEqual<int>(0, fileInfos.Count); | ||
390 | foreach (ArchiveFileInfo file in fileInfos) | ||
391 | { | ||
392 | Console.WriteLine("{0}\t{1}\t{2}", Path.Combine(file.Path, file.Name), file.Length, file.LastWriteTime); | ||
393 | } | ||
394 | |||
395 | string extractDir = Path.GetFileNameWithoutExtension(zipTest.Name); | ||
396 | Directory.CreateDirectory(extractDir); | ||
397 | zipTest.Unpack(extractDir); | ||
398 | } | ||
399 | */ | ||
400 | |||
401 | private const string TEST_FILENAME_PREFIX = "\x20AC"; | ||
402 | |||
403 | private IList<ArchiveFileInfo> RunZipPackUnpack(int fileCount, long fileSize, | ||
404 | long maxArchiveSize) | ||
405 | { | ||
406 | return this.RunZipPackUnpack(fileCount, fileSize, maxArchiveSize, CompressionLevel.Normal); | ||
407 | } | ||
408 | |||
409 | private IList<ArchiveFileInfo> RunZipPackUnpack(int fileCount, long fileSize, | ||
410 | long maxArchiveSize, CompressionLevel compLevel) | ||
411 | { | ||
412 | Console.WriteLine("Creating zip archive with {0} files of size {1}", | ||
413 | fileCount, fileSize); | ||
414 | Console.WriteLine("MaxArchiveSize={0}, CompressionLevel={1}", maxArchiveSize, compLevel); | ||
415 | |||
416 | string dirA = String.Format("{0}-{1}-A", fileCount, fileSize); | ||
417 | if (Directory.Exists(dirA)) Directory.Delete(dirA, true); | ||
418 | Directory.CreateDirectory(dirA); | ||
419 | string dirB = String.Format("{0}-{1}-B", fileCount, fileSize); | ||
420 | if (Directory.Exists(dirB)) Directory.Delete(dirB, true); | ||
421 | Directory.CreateDirectory(dirB); | ||
422 | |||
423 | string[] files = new string[fileCount]; | ||
424 | for (int iFile = 0; iFile < fileCount; iFile++) | ||
425 | { | ||
426 | files[iFile] = TEST_FILENAME_PREFIX + iFile + ".txt"; | ||
427 | CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[iFile]), iFile, fileSize); | ||
428 | } | ||
429 | |||
430 | string[] archiveNames = new string[1000]; | ||
431 | for (int i = 0; i < archiveNames.Length; i++) | ||
432 | { | ||
433 | if (i < 100) | ||
434 | { | ||
435 | archiveNames[i] = String.Format( | ||
436 | (i == 0 ? "{0}-{1}.zip" : "{0}-{1}.z{2:d02}"), | ||
437 | fileCount, fileSize, i); | ||
438 | } | ||
439 | else | ||
440 | { | ||
441 | archiveNames[i] = String.Format( | ||
442 | "{0}-{1}.{2:d03}", fileCount, fileSize, i); | ||
443 | } | ||
444 | } | ||
445 | |||
446 | string progressTextFile = String.Format("progress_{0}-{1}.txt", fileCount, fileSize); | ||
447 | CompressionTestUtil testUtil = new CompressionTestUtil(progressTextFile); | ||
448 | |||
449 | IList<ArchiveFileInfo> fileInfo; | ||
450 | using (ZipEngine zipEngine = new ZipEngine()) | ||
451 | { | ||
452 | zipEngine.CompressionLevel = compLevel; | ||
453 | |||
454 | File.AppendAllText(progressTextFile, | ||
455 | "\r\n\r\n====================================================\r\nCREATE\r\n\r\n"); | ||
456 | zipEngine.Progress += testUtil.PrintArchiveProgress; | ||
457 | |||
458 | OptionStreamContext streamContext = new OptionStreamContext(archiveNames, dirA, null); | ||
459 | streamContext.OptionHandler = | ||
460 | delegate(string optionName, object[] parameters) | ||
461 | { | ||
462 | // For testing purposes, force zip64 for only moderately large files. | ||
463 | switch (optionName) | ||
464 | { | ||
465 | case "forceZip64": | ||
466 | return fileSize > UInt16.MaxValue; | ||
467 | default: | ||
468 | return null; | ||
469 | } | ||
470 | }; | ||
471 | |||
472 | zipEngine.Pack(streamContext, files, maxArchiveSize); | ||
473 | |||
474 | string checkArchiveName = archiveNames[0]; | ||
475 | if (File.Exists(archiveNames[1])) checkArchiveName = archiveNames[1]; | ||
476 | using (Stream archiveStream = File.OpenRead(checkArchiveName)) | ||
477 | { | ||
478 | bool isArchive = zipEngine.IsArchive(archiveStream); | ||
479 | Assert.IsTrue(isArchive, "Checking that created archive appears valid."); | ||
480 | } | ||
481 | |||
482 | IList<string> createdArchiveNames = new List<string>(archiveNames.Length); | ||
483 | for (int i = 0; i < archiveNames.Length; i++) | ||
484 | { | ||
485 | if (File.Exists(archiveNames[i])) | ||
486 | { | ||
487 | createdArchiveNames.Add(archiveNames[i]); | ||
488 | } | ||
489 | else | ||
490 | { | ||
491 | break; | ||
492 | } | ||
493 | } | ||
494 | |||
495 | Assert.AreNotEqual<int>(0, createdArchiveNames.Count); | ||
496 | |||
497 | Console.WriteLine("Listing zip archive with {0} files of size {1}", | ||
498 | fileCount, fileSize); | ||
499 | File.AppendAllText(progressTextFile, "\r\n\r\nLIST\r\n\r\n"); | ||
500 | fileInfo = zipEngine.GetFileInfo( | ||
501 | new ArchiveFileStreamContext(createdArchiveNames, null, null), null); | ||
502 | |||
503 | Assert.AreEqual<int>(fileCount, fileInfo.Count); | ||
504 | |||
505 | Console.WriteLine("Extracting zip archive with {0} files of size {1}", | ||
506 | fileCount, fileSize); | ||
507 | File.AppendAllText(progressTextFile, "\r\n\r\nEXTRACT\r\n\r\n"); | ||
508 | zipEngine.Unpack(new ArchiveFileStreamContext(createdArchiveNames, dirB, null), null); | ||
509 | } | ||
510 | |||
511 | bool directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB); | ||
512 | Assert.IsTrue(directoryMatch, | ||
513 | "Testing whether zip output directory matches input directory."); | ||
514 | |||
515 | return fileInfo; | ||
516 | } | ||
517 | } | ||
518 | } | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.Compression/CompressionTestUtil.cs b/src/dtf/test/WixToolsetTests.Dtf.Compression/CompressionTestUtil.cs new file mode 100644 index 00000000..e7a5373d --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.Compression/CompressionTestUtil.cs | |||
@@ -0,0 +1,649 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | using System; | ||
4 | using System.IO; | ||
5 | using System.Text; | ||
6 | using System.Collections.Generic; | ||
7 | using System.Security.Cryptography; | ||
8 | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
9 | using WixToolset.Dtf.Compression; | ||
10 | |||
11 | namespace WixToolset.Dtf.Test | ||
12 | { | ||
13 | public class CompressionTestUtil | ||
14 | { | ||
15 | private static MD5 md5 = new MD5CryptoServiceProvider(); | ||
16 | |||
17 | private string progressTextFile; | ||
18 | |||
19 | public CompressionTestUtil(string progressTextFile) | ||
20 | { | ||
21 | this.progressTextFile = progressTextFile; | ||
22 | } | ||
23 | |||
24 | public static IList<int[]> ExpectedProgress | ||
25 | { | ||
26 | get { return CompressionTestUtil.expectedProgress; } | ||
27 | set { CompressionTestUtil.expectedProgress = value; } | ||
28 | } | ||
29 | private static IList<int[]> expectedProgress; | ||
30 | |||
31 | public void PrintArchiveProgress(object source, ArchiveProgressEventArgs e) | ||
32 | { | ||
33 | switch (e.ProgressType) | ||
34 | { | ||
35 | case ArchiveProgressType.StartFile: | ||
36 | { | ||
37 | Console.WriteLine("StartFile: {0}", e.CurrentFileName); | ||
38 | } break; | ||
39 | case ArchiveProgressType.FinishFile: | ||
40 | { | ||
41 | Console.WriteLine("FinishFile: {0}", e.CurrentFileName); | ||
42 | } break; | ||
43 | case ArchiveProgressType.StartArchive: | ||
44 | { | ||
45 | Console.WriteLine("StartArchive: {0} : {1}", e.CurrentArchiveNumber, e.CurrentArchiveName); | ||
46 | } break; | ||
47 | case ArchiveProgressType.FinishArchive: | ||
48 | { | ||
49 | Console.WriteLine("FinishArchive: {0} : {1}", e.CurrentArchiveNumber, e.CurrentArchiveName); | ||
50 | } break; | ||
51 | } | ||
52 | |||
53 | File.AppendAllText(this.progressTextFile, e.ToString().Replace("\n", Environment.NewLine)); | ||
54 | |||
55 | if (CompressionTestUtil.expectedProgress != null && | ||
56 | e.ProgressType != ArchiveProgressType.PartialFile && | ||
57 | e.ProgressType != ArchiveProgressType.PartialArchive) | ||
58 | { | ||
59 | Assert.AreNotEqual<int>(0, CompressionTestUtil.expectedProgress.Count); | ||
60 | int[] expected = CompressionTestUtil.expectedProgress[0]; | ||
61 | CompressionTestUtil.expectedProgress.RemoveAt(0); | ||
62 | Assert.AreEqual<ArchiveProgressType>((ArchiveProgressType) expected[0], e.ProgressType, "Checking ProgressType."); | ||
63 | Assert.AreEqual<int>(expected[1], e.CurrentFileNumber, "Checking CurrentFileNumber."); | ||
64 | Assert.AreEqual<int>(expected[2], e.TotalFiles, "Checking TotalFiles."); | ||
65 | Assert.AreEqual<int>(expected[4], e.CurrentArchiveNumber, "Checking CurrentArchiveNumber."); | ||
66 | Assert.AreEqual<int>(expected[5], e.TotalArchives, "Checking TotalArchives."); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | public static bool CompareDirectories(string dirA, string dirB) | ||
71 | { | ||
72 | bool difference = false; | ||
73 | Console.WriteLine("Comparing directories {0}, {1}", dirA, dirB); | ||
74 | |||
75 | string[] filesA = Directory.GetFiles(dirA); | ||
76 | string[] filesB = Directory.GetFiles(dirB); | ||
77 | for (int iA = 0; iA < filesA.Length; iA++) | ||
78 | { | ||
79 | filesA[iA] = Path.GetFileName(filesA[iA]); | ||
80 | } | ||
81 | for (int iB = 0; iB < filesB.Length; iB++) | ||
82 | { | ||
83 | filesB[iB] = Path.GetFileName(filesB[iB]); | ||
84 | } | ||
85 | Array.Sort(filesA); | ||
86 | Array.Sort(filesB); | ||
87 | |||
88 | for (int iA = 0, iB = 0; iA < filesA.Length || iB < filesB.Length; ) | ||
89 | { | ||
90 | int comp; | ||
91 | if (iA == filesA.Length) | ||
92 | { | ||
93 | comp = 1; | ||
94 | } | ||
95 | else if (iB == filesB.Length) | ||
96 | { | ||
97 | comp = -1; | ||
98 | } | ||
99 | else | ||
100 | { | ||
101 | comp = String.Compare(filesA[iA], filesB[iB]); | ||
102 | } | ||
103 | if (comp < 0) | ||
104 | { | ||
105 | Console.WriteLine("< " + filesA[iA]); | ||
106 | difference = true; | ||
107 | iA++; | ||
108 | } | ||
109 | else if (comp > 0) | ||
110 | { | ||
111 | Console.WriteLine("> " + filesB[iB]); | ||
112 | difference = true; | ||
113 | iB++; | ||
114 | } | ||
115 | else | ||
116 | { | ||
117 | string fileA = Path.Combine(dirA, filesA[iA]); | ||
118 | string fileB = Path.Combine(dirB, filesB[iB]); | ||
119 | |||
120 | byte[] hashA; | ||
121 | byte[] hashB; | ||
122 | |||
123 | lock (CompressionTestUtil.md5) | ||
124 | { | ||
125 | using (Stream fileAStream = File.OpenRead(fileA)) | ||
126 | { | ||
127 | hashA = CompressionTestUtil.md5.ComputeHash(fileAStream); | ||
128 | } | ||
129 | using (Stream fileBStream = File.OpenRead(fileB)) | ||
130 | { | ||
131 | hashB = CompressionTestUtil.md5.ComputeHash(fileBStream); | ||
132 | } | ||
133 | } | ||
134 | |||
135 | for (int i = 0; i < hashA.Length; i++) | ||
136 | { | ||
137 | if (hashA[i] != hashB[i]) | ||
138 | { | ||
139 | Console.WriteLine("~ " + filesA[iA]); | ||
140 | difference = true; | ||
141 | break; | ||
142 | } | ||
143 | } | ||
144 | |||
145 | iA++; | ||
146 | iB++; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | string[] dirsA = Directory.GetDirectories(dirA); | ||
151 | string[] dirsB = Directory.GetDirectories(dirB); | ||
152 | for (int iA = 0; iA < dirsA.Length; iA++) | ||
153 | { | ||
154 | dirsA[iA] = Path.GetFileName(dirsA[iA]); | ||
155 | } | ||
156 | for (int iB = 0; iB < dirsB.Length; iB++) | ||
157 | { | ||
158 | dirsB[iB] = Path.GetFileName(dirsB[iB]); | ||
159 | } | ||
160 | Array.Sort(dirsA); | ||
161 | Array.Sort(dirsB); | ||
162 | |||
163 | for (int iA = 0, iB = 0; iA < dirsA.Length || iB < dirsB.Length; ) | ||
164 | { | ||
165 | int comp; | ||
166 | if (iA == dirsA.Length) | ||
167 | { | ||
168 | comp = 1; | ||
169 | } | ||
170 | else if (iB == dirsB.Length) | ||
171 | { | ||
172 | comp = -1; | ||
173 | } | ||
174 | else | ||
175 | { | ||
176 | comp = String.Compare(dirsA[iA], dirsB[iB]); | ||
177 | } | ||
178 | if (comp < 0) | ||
179 | { | ||
180 | Console.WriteLine("< {0}\\", dirsA[iA]); | ||
181 | difference = true; | ||
182 | iA++; | ||
183 | } | ||
184 | else if (comp > 0) | ||
185 | { | ||
186 | Console.WriteLine("> {1}\\", dirsB[iB]); | ||
187 | difference = true; | ||
188 | iB++; | ||
189 | } | ||
190 | else | ||
191 | { | ||
192 | string subDirA = Path.Combine(dirA, dirsA[iA]); | ||
193 | string subDirB = Path.Combine(dirB, dirsB[iB]); | ||
194 | if (!CompressionTestUtil.CompareDirectories(subDirA, subDirB)) | ||
195 | { | ||
196 | difference = true; | ||
197 | } | ||
198 | iA++; | ||
199 | iB++; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | return !difference; | ||
204 | } | ||
205 | |||
206 | |||
207 | public static void GenerateRandomFile(string path, int seed, long size) | ||
208 | { | ||
209 | Console.WriteLine("Generating random file {0} (seed={1}, size={2})", | ||
210 | path, seed, size); | ||
211 | Random random = new Random(seed); | ||
212 | bool easy = random.Next(2) == 1; | ||
213 | int chunk = 1024 * random.Next(1, 100); | ||
214 | using (TextWriter tw = new StreamWriter( | ||
215 | File.Create(path, 4096), Encoding.ASCII)) | ||
216 | { | ||
217 | for (long count = 0; count < size; count++) | ||
218 | { | ||
219 | char c = (char) (easy ? random.Next('a', 'b' + 1) | ||
220 | : random.Next(32, 127)); | ||
221 | tw.Write(c); | ||
222 | if (--chunk == 0) | ||
223 | { | ||
224 | chunk = 1024 * random.Next(1, 101); | ||
225 | easy = random.Next(2) == 1; | ||
226 | } | ||
227 | } | ||
228 | } | ||
229 | } | ||
230 | |||
231 | public static void TestArchiveInfoNullParams( | ||
232 | ArchiveInfo archiveInfo, | ||
233 | string dirA, | ||
234 | string dirB, | ||
235 | string[] files) | ||
236 | { | ||
237 | Exception caughtEx = null; | ||
238 | try | ||
239 | { | ||
240 | archiveInfo.PackFiles(null, null, files); | ||
241 | } | ||
242 | catch (Exception ex) { caughtEx = ex; } | ||
243 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
244 | caughtEx = null; | ||
245 | try | ||
246 | { | ||
247 | archiveInfo.PackFiles(null, files, new string[] { }); | ||
248 | } | ||
249 | catch (Exception ex) { caughtEx = ex; } | ||
250 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentOutOfRangeException), "Caught exception: " + caughtEx); | ||
251 | caughtEx = null; | ||
252 | try | ||
253 | { | ||
254 | archiveInfo.PackFileSet(dirA, null); | ||
255 | } | ||
256 | catch (Exception ex) { caughtEx = ex; } | ||
257 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
258 | caughtEx = null; | ||
259 | try | ||
260 | { | ||
261 | archiveInfo.PackFiles(null, files, files); | ||
262 | } | ||
263 | catch (Exception ex) { caughtEx = ex; } | ||
264 | Assert.IsInstanceOfType(caughtEx, typeof(FileNotFoundException), "Caught exception: " + caughtEx); | ||
265 | caughtEx = null; | ||
266 | try | ||
267 | { | ||
268 | archiveInfo.PackFiles(dirA, null, files); | ||
269 | } | ||
270 | catch (Exception ex) { caughtEx = ex; } | ||
271 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
272 | caughtEx = null; | ||
273 | try | ||
274 | { | ||
275 | archiveInfo.PackFiles(dirA, files, null); | ||
276 | } | ||
277 | catch (Exception ex) { caughtEx = ex; } | ||
278 | Assert.IsNull(caughtEx, "Caught exception: " + caughtEx); | ||
279 | |||
280 | caughtEx = null; | ||
281 | try | ||
282 | { | ||
283 | archiveInfo.CopyTo(null); | ||
284 | } | ||
285 | catch (Exception ex) { caughtEx = ex; } | ||
286 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
287 | caughtEx = null; | ||
288 | try | ||
289 | { | ||
290 | archiveInfo.CopyTo(null, true); | ||
291 | } | ||
292 | catch (Exception ex) { caughtEx = ex; } | ||
293 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
294 | caughtEx = null; | ||
295 | try | ||
296 | { | ||
297 | archiveInfo.MoveTo(null); | ||
298 | } | ||
299 | catch (Exception ex) { caughtEx = ex; } | ||
300 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
301 | caughtEx = null; | ||
302 | try | ||
303 | { | ||
304 | archiveInfo.GetFiles(null); | ||
305 | } | ||
306 | catch (Exception ex) { caughtEx = ex; } | ||
307 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
308 | caughtEx = null; | ||
309 | try | ||
310 | { | ||
311 | archiveInfo.UnpackFile(null, "test.txt"); | ||
312 | } | ||
313 | catch (Exception ex) { caughtEx = ex; } | ||
314 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
315 | caughtEx = null; | ||
316 | try | ||
317 | { | ||
318 | archiveInfo.UnpackFile("test.txt", null); | ||
319 | } | ||
320 | catch (Exception ex) { caughtEx = ex; } | ||
321 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
322 | caughtEx = null; | ||
323 | try | ||
324 | { | ||
325 | archiveInfo.UnpackFiles(null, dirB, files); | ||
326 | } | ||
327 | catch (Exception ex) { caughtEx = ex; } | ||
328 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
329 | caughtEx = null; | ||
330 | try | ||
331 | { | ||
332 | archiveInfo.UnpackFiles(files, null, null); | ||
333 | } | ||
334 | catch (Exception ex) { caughtEx = ex; } | ||
335 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
336 | caughtEx = null; | ||
337 | try | ||
338 | { | ||
339 | archiveInfo.UnpackFiles(files, null, files); | ||
340 | } | ||
341 | catch (Exception ex) { caughtEx = ex; } | ||
342 | Assert.IsNull(caughtEx, "Caught exception: " + caughtEx); | ||
343 | caughtEx = null; | ||
344 | try | ||
345 | { | ||
346 | archiveInfo.UnpackFiles(files, dirB, null); | ||
347 | } | ||
348 | catch (Exception ex) { caughtEx = ex; } | ||
349 | Assert.IsNull(caughtEx, "Caught exception: " + caughtEx); | ||
350 | caughtEx = null; | ||
351 | try | ||
352 | { | ||
353 | archiveInfo.UnpackFiles(files, dirB, new string[] { }); | ||
354 | } | ||
355 | catch (Exception ex) { caughtEx = ex; } | ||
356 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentOutOfRangeException), "Caught exception: " + caughtEx); | ||
357 | caughtEx = null; | ||
358 | try | ||
359 | { | ||
360 | archiveInfo.UnpackFileSet(null, dirB); | ||
361 | } | ||
362 | catch (Exception ex) { caughtEx = ex; } | ||
363 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
364 | } | ||
365 | |||
366 | public static void TestCompressionEngineNullParams( | ||
367 | CompressionEngine engine, | ||
368 | ArchiveFileStreamContext streamContext, | ||
369 | string[] testFiles) | ||
370 | { | ||
371 | Exception caughtEx; | ||
372 | |||
373 | Console.WriteLine("Testing null streamContext."); | ||
374 | caughtEx = null; | ||
375 | try | ||
376 | { | ||
377 | engine.Pack(null, testFiles); | ||
378 | } | ||
379 | catch (Exception ex) { caughtEx = ex; } | ||
380 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
381 | caughtEx = null; | ||
382 | try | ||
383 | { | ||
384 | engine.Pack(null, testFiles, 0); | ||
385 | } | ||
386 | catch (Exception ex) { caughtEx = ex; } | ||
387 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
388 | |||
389 | Console.WriteLine("Testing null files."); | ||
390 | caughtEx = null; | ||
391 | try | ||
392 | { | ||
393 | engine.Pack(streamContext, null); | ||
394 | } | ||
395 | catch (Exception ex) { caughtEx = ex; } | ||
396 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
397 | |||
398 | Console.WriteLine("Testing null files."); | ||
399 | caughtEx = null; | ||
400 | try | ||
401 | { | ||
402 | engine.Pack(streamContext, null, 0); | ||
403 | } | ||
404 | catch (Exception ex) { caughtEx = ex; } | ||
405 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
406 | |||
407 | |||
408 | Console.WriteLine("Testing null stream."); | ||
409 | caughtEx = null; | ||
410 | try | ||
411 | { | ||
412 | engine.IsArchive(null); | ||
413 | } | ||
414 | catch (Exception ex) { caughtEx = ex; } | ||
415 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
416 | caughtEx = null; | ||
417 | try | ||
418 | { | ||
419 | engine.FindArchiveOffset(null); | ||
420 | } | ||
421 | catch (Exception ex) { caughtEx = ex; } | ||
422 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
423 | caughtEx = null; | ||
424 | try | ||
425 | { | ||
426 | engine.GetFiles(null); | ||
427 | } | ||
428 | catch (Exception ex) { caughtEx = ex; } | ||
429 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
430 | caughtEx = null; | ||
431 | try | ||
432 | { | ||
433 | engine.GetFileInfo(null); | ||
434 | } | ||
435 | catch (Exception ex) { caughtEx = ex; } | ||
436 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
437 | caughtEx = null; | ||
438 | try | ||
439 | { | ||
440 | engine.Unpack(null, "testUnpack.txt"); | ||
441 | } | ||
442 | catch (Exception ex) { caughtEx = ex; } | ||
443 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
444 | Console.WriteLine("Testing null streamContext."); | ||
445 | caughtEx = null; | ||
446 | try | ||
447 | { | ||
448 | engine.GetFiles(null, null); | ||
449 | } | ||
450 | catch (Exception ex) { caughtEx = ex; } | ||
451 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
452 | caughtEx = null; | ||
453 | try | ||
454 | { | ||
455 | engine.GetFileInfo(null, null); | ||
456 | } | ||
457 | catch (Exception ex) { caughtEx = ex; } | ||
458 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
459 | caughtEx = null; | ||
460 | try | ||
461 | { | ||
462 | engine.Unpack((IUnpackStreamContext) null, null); | ||
463 | } | ||
464 | catch (Exception ex) { caughtEx = ex; } | ||
465 | Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); | ||
466 | } | ||
467 | |||
468 | public static void TestBadPackStreamContexts( | ||
469 | CompressionEngine engine, string archiveName, string[] testFiles) | ||
470 | { | ||
471 | Exception caughtEx; | ||
472 | |||
473 | Console.WriteLine("Testing streamContext that returns null from GetName."); | ||
474 | caughtEx = null; | ||
475 | try | ||
476 | { | ||
477 | engine.Pack( | ||
478 | new MisbehavingStreamContext(archiveName, null, null, false, false, true, true, true, true), | ||
479 | testFiles); | ||
480 | } | ||
481 | catch (Exception ex) { caughtEx = ex; } | ||
482 | Assert.IsTrue(caughtEx is FileNotFoundException, "Caught exception: " + caughtEx); | ||
483 | Console.WriteLine("Testing streamContext that returns null from OpenArchive."); | ||
484 | caughtEx = null; | ||
485 | try | ||
486 | { | ||
487 | engine.Pack( | ||
488 | new MisbehavingStreamContext(archiveName, null, null, false, true, false, true, true, true), | ||
489 | testFiles); | ||
490 | } | ||
491 | catch (Exception ex) { caughtEx = ex; } | ||
492 | Assert.IsTrue(caughtEx is FileNotFoundException, "Caught exception: " + caughtEx); | ||
493 | Console.WriteLine("Testing streamContext that returns null from OpenFile."); | ||
494 | caughtEx = null; | ||
495 | try | ||
496 | { | ||
497 | engine.Pack( | ||
498 | new MisbehavingStreamContext(archiveName, null, null, false, true, true, true, false, true), | ||
499 | testFiles); | ||
500 | } | ||
501 | catch (Exception ex) { caughtEx = ex; } | ||
502 | Assert.IsNull(caughtEx, "Caught exception: " + caughtEx); | ||
503 | Console.WriteLine("Testing streamContext that throws on GetName."); | ||
504 | caughtEx = null; | ||
505 | try | ||
506 | { | ||
507 | engine.Pack( | ||
508 | new MisbehavingStreamContext(archiveName, null, null, true, false, true, true, true, true), | ||
509 | testFiles); | ||
510 | } | ||
511 | catch (Exception ex) { caughtEx = ex; } | ||
512 | Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); | ||
513 | Console.WriteLine("Testing streamContext that throws on OpenArchive."); | ||
514 | caughtEx = null; | ||
515 | try | ||
516 | { | ||
517 | engine.Pack( | ||
518 | new MisbehavingStreamContext(archiveName, null, null, true, true, false, true, true, true), | ||
519 | testFiles); | ||
520 | } | ||
521 | catch (Exception ex) { caughtEx = ex; } | ||
522 | Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); | ||
523 | Console.WriteLine("Testing streamContext that throws on CloseArchive."); | ||
524 | caughtEx = null; | ||
525 | try | ||
526 | { | ||
527 | engine.Pack( | ||
528 | new MisbehavingStreamContext(archiveName, null, null, true, true, true, false, true, true), | ||
529 | testFiles); | ||
530 | } | ||
531 | catch (Exception ex) { caughtEx = ex; } | ||
532 | Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); | ||
533 | Console.WriteLine("Testing streamContext that throws on OpenFile."); | ||
534 | caughtEx = null; | ||
535 | try | ||
536 | { | ||
537 | engine.Pack( | ||
538 | new MisbehavingStreamContext(archiveName, null, null, true, true, true, true, false, true), | ||
539 | testFiles); | ||
540 | } | ||
541 | catch (Exception ex) { caughtEx = ex; } | ||
542 | Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); | ||
543 | Console.WriteLine("Testing streamContext that throws on CloseFile."); | ||
544 | caughtEx = null; | ||
545 | try | ||
546 | { | ||
547 | engine.Pack( | ||
548 | new MisbehavingStreamContext(archiveName, null, null, true, true, true, true, true, false), | ||
549 | testFiles); | ||
550 | } | ||
551 | catch (Exception ex) { caughtEx = ex; } | ||
552 | Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); | ||
553 | } | ||
554 | |||
555 | public static void TestBadUnpackStreamContexts( | ||
556 | CompressionEngine engine, string archiveName) | ||
557 | { | ||
558 | Exception caughtEx; | ||
559 | |||
560 | Console.WriteLine("Testing streamContext that returns null from OpenArchive."); | ||
561 | caughtEx = null; | ||
562 | try | ||
563 | { | ||
564 | engine.Unpack(new MisbehavingStreamContext(archiveName, null, null, false, true, false, true, true, true), null); | ||
565 | } | ||
566 | catch (Exception ex) { caughtEx = ex; } | ||
567 | Assert.IsInstanceOfType(caughtEx, typeof(FileNotFoundException), "Caught exception: " + caughtEx); | ||
568 | Console.WriteLine("Testing streamContext that returns null from OpenFile."); | ||
569 | caughtEx = null; | ||
570 | try | ||
571 | { | ||
572 | engine.Unpack(new MisbehavingStreamContext(archiveName, null, null, false, true, true, true, false, true), null); | ||
573 | } | ||
574 | catch (Exception ex) { caughtEx = ex; } | ||
575 | Assert.IsNull(caughtEx, "Caught exception: " + caughtEx); | ||
576 | Console.WriteLine("Testing streamContext that throws on OpenArchive."); | ||
577 | caughtEx = null; | ||
578 | try | ||
579 | { | ||
580 | engine.Unpack(new MisbehavingStreamContext(archiveName, null, null, true, true, false, true, true, true), null); | ||
581 | } | ||
582 | catch (Exception ex) { caughtEx = ex; } | ||
583 | Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); | ||
584 | Console.WriteLine("Testing streamContext that throws on CloseArchive."); | ||
585 | caughtEx = null; | ||
586 | try | ||
587 | { | ||
588 | engine.Unpack(new MisbehavingStreamContext(archiveName, null, null, true, true, true, false, true, true), null); | ||
589 | } | ||
590 | catch (Exception ex) { caughtEx = ex; } | ||
591 | Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); | ||
592 | Console.WriteLine("Testing streamContext that throws on OpenFile."); | ||
593 | caughtEx = null; | ||
594 | try | ||
595 | { | ||
596 | engine.Unpack(new MisbehavingStreamContext(archiveName, null, null, true, true, true, true, false, true), null); | ||
597 | } | ||
598 | catch (Exception ex) { caughtEx = ex; } | ||
599 | Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); | ||
600 | Console.WriteLine("Testing streamContext that throws on CloseFile."); | ||
601 | caughtEx = null; | ||
602 | try | ||
603 | { | ||
604 | engine.Unpack(new MisbehavingStreamContext(archiveName, null, null, true, true, true, true, true, false), null); | ||
605 | } | ||
606 | catch (Exception ex) { caughtEx = ex; } | ||
607 | Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); | ||
608 | } | ||
609 | |||
610 | public static void TestTruncatedArchive( | ||
611 | ArchiveInfo archiveInfo, Type expectedExceptionType) | ||
612 | { | ||
613 | for (long len = archiveInfo.Length - 1; len >= 0; len--) | ||
614 | { | ||
615 | string testArchive = String.Format("{0}.{1:d06}", | ||
616 | archiveInfo.FullName, len); | ||
617 | if (File.Exists(testArchive)) | ||
618 | { | ||
619 | File.Delete(testArchive); | ||
620 | } | ||
621 | |||
622 | archiveInfo.CopyTo(testArchive); | ||
623 | using (FileStream truncateStream = | ||
624 | File.Open(testArchive, FileMode.Open, FileAccess.ReadWrite)) | ||
625 | { | ||
626 | truncateStream.SetLength(len); | ||
627 | } | ||
628 | |||
629 | ArchiveInfo testArchiveInfo = (ArchiveInfo) archiveInfo.GetType() | ||
630 | .GetConstructor(new Type[] { typeof(string) }).Invoke(new object[] { testArchive }); | ||
631 | |||
632 | Exception caughtEx = null; | ||
633 | try | ||
634 | { | ||
635 | testArchiveInfo.GetFiles(); | ||
636 | } | ||
637 | catch (Exception ex) { caughtEx = ex; } | ||
638 | File.Delete(testArchive); | ||
639 | |||
640 | if (caughtEx != null) | ||
641 | { | ||
642 | Assert.IsInstanceOfType(caughtEx, expectedExceptionType, | ||
643 | String.Format("Caught exception listing archive truncated to {0}/{1} bytes", | ||
644 | len, archiveInfo.Length)); | ||
645 | } | ||
646 | } | ||
647 | } | ||
648 | } | ||
649 | } | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.Compression/MisbehavingStreamContext.cs b/src/dtf/test/WixToolsetTests.Dtf.Compression/MisbehavingStreamContext.cs new file mode 100644 index 00000000..2531f3bc --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.Compression/MisbehavingStreamContext.cs | |||
@@ -0,0 +1,202 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | using System; | ||
4 | using System.IO; | ||
5 | using System.Collections.Generic; | ||
6 | using WixToolset.Dtf.Compression; | ||
7 | |||
8 | namespace WixToolset.Dtf.Test | ||
9 | { | ||
10 | public class MisbehavingStreamContext : ArchiveFileStreamContext | ||
11 | { | ||
12 | public const string EXCEPTION = "Test exception."; | ||
13 | |||
14 | private bool throwEx; | ||
15 | private bool getName; | ||
16 | private bool openArchive; | ||
17 | private bool closeArchive; | ||
18 | private bool openFile; | ||
19 | private bool closeFile; | ||
20 | private int closeFileCount; | ||
21 | |||
22 | public MisbehavingStreamContext( | ||
23 | string cabinetFile, | ||
24 | string directory, | ||
25 | IDictionary<string, string> files, | ||
26 | bool throwEx, | ||
27 | bool getName, | ||
28 | bool openArchive, | ||
29 | bool closeArchive, | ||
30 | bool openFile, | ||
31 | bool closeFile) | ||
32 | : base(cabinetFile, directory, files) | ||
33 | { | ||
34 | this.throwEx = throwEx; | ||
35 | this.getName = getName; | ||
36 | this.openArchive = openArchive; | ||
37 | this.closeArchive = closeArchive; | ||
38 | this.openFile = openFile; | ||
39 | this.closeFile = closeFile; | ||
40 | } | ||
41 | |||
42 | public override string GetArchiveName(int archiveNumber) | ||
43 | { | ||
44 | if (!this.getName) | ||
45 | { | ||
46 | if (throwEx) | ||
47 | { | ||
48 | throw new Exception(EXCEPTION); | ||
49 | } | ||
50 | else | ||
51 | { | ||
52 | return null; | ||
53 | } | ||
54 | } | ||
55 | return base.GetArchiveName(archiveNumber); | ||
56 | } | ||
57 | |||
58 | public override Stream OpenArchiveWriteStream( | ||
59 | int archiveNumber, | ||
60 | string archiveName, | ||
61 | bool truncate, | ||
62 | CompressionEngine compressionEngine) | ||
63 | { | ||
64 | if (!this.openArchive) | ||
65 | { | ||
66 | if (throwEx) | ||
67 | { | ||
68 | throw new Exception(EXCEPTION); | ||
69 | } | ||
70 | else | ||
71 | { | ||
72 | return null; | ||
73 | } | ||
74 | } | ||
75 | return base.OpenArchiveWriteStream( | ||
76 | archiveNumber, archiveName, truncate, compressionEngine); | ||
77 | } | ||
78 | |||
79 | public override void CloseArchiveWriteStream( | ||
80 | int archiveNumber, | ||
81 | string archiveName, | ||
82 | Stream stream) | ||
83 | { | ||
84 | if (!this.closeArchive) | ||
85 | { | ||
86 | if (throwEx) | ||
87 | { | ||
88 | this.closeArchive = true; | ||
89 | throw new Exception(EXCEPTION); | ||
90 | } | ||
91 | return; | ||
92 | } | ||
93 | base.CloseArchiveWriteStream(archiveNumber, archiveName, stream); | ||
94 | } | ||
95 | |||
96 | public override Stream OpenFileReadStream( | ||
97 | string path, | ||
98 | out FileAttributes attributes, | ||
99 | out DateTime lastWriteTime) | ||
100 | { | ||
101 | if (!this.openFile) | ||
102 | { | ||
103 | if (throwEx) | ||
104 | { | ||
105 | throw new Exception(EXCEPTION); | ||
106 | } | ||
107 | else | ||
108 | { | ||
109 | attributes = FileAttributes.Normal; | ||
110 | lastWriteTime = DateTime.MinValue; | ||
111 | return null; | ||
112 | } | ||
113 | } | ||
114 | return base.OpenFileReadStream(path, out attributes, out lastWriteTime); | ||
115 | } | ||
116 | |||
117 | public override void CloseFileReadStream(string path, Stream stream) | ||
118 | { | ||
119 | if (!this.closeFile && ++closeFileCount == 2) | ||
120 | { | ||
121 | if (throwEx) | ||
122 | { | ||
123 | throw new Exception(EXCEPTION); | ||
124 | } | ||
125 | return; | ||
126 | } | ||
127 | base.CloseFileReadStream(path, stream); | ||
128 | } | ||
129 | |||
130 | public override Stream OpenArchiveReadStream( | ||
131 | int archiveNumber, | ||
132 | string archiveName, | ||
133 | CompressionEngine compressionEngine) | ||
134 | { | ||
135 | if (!this.openArchive) | ||
136 | { | ||
137 | if (throwEx) | ||
138 | { | ||
139 | throw new Exception(EXCEPTION); | ||
140 | } | ||
141 | else | ||
142 | { | ||
143 | return null; | ||
144 | } | ||
145 | } | ||
146 | return base.OpenArchiveReadStream(archiveNumber, archiveName, compressionEngine); | ||
147 | } | ||
148 | |||
149 | public override void CloseArchiveReadStream( | ||
150 | int archiveNumber, | ||
151 | string archiveName, | ||
152 | Stream stream) | ||
153 | { | ||
154 | if (!this.closeArchive) | ||
155 | { | ||
156 | if (throwEx) | ||
157 | { | ||
158 | this.closeArchive = true; | ||
159 | throw new Exception(EXCEPTION); | ||
160 | } | ||
161 | return; | ||
162 | } | ||
163 | base.CloseArchiveReadStream(archiveNumber, archiveName, stream); | ||
164 | } | ||
165 | |||
166 | public override Stream OpenFileWriteStream( | ||
167 | string path, | ||
168 | long fileSize, | ||
169 | DateTime lastWriteTime) | ||
170 | { | ||
171 | if (!this.openFile) | ||
172 | { | ||
173 | if (throwEx) | ||
174 | { | ||
175 | throw new Exception(EXCEPTION); | ||
176 | } | ||
177 | else | ||
178 | { | ||
179 | return null; | ||
180 | } | ||
181 | } | ||
182 | return base.OpenFileWriteStream(path, fileSize, lastWriteTime); | ||
183 | } | ||
184 | |||
185 | public override void CloseFileWriteStream( | ||
186 | string path, | ||
187 | Stream stream, | ||
188 | FileAttributes attributes, | ||
189 | DateTime lastWriteTime) | ||
190 | { | ||
191 | if (!this.closeFile && ++closeFileCount == 2) | ||
192 | { | ||
193 | if (throwEx) | ||
194 | { | ||
195 | throw new Exception(EXCEPTION); | ||
196 | } | ||
197 | return; | ||
198 | } | ||
199 | base.CloseFileWriteStream(path, stream, attributes, lastWriteTime); | ||
200 | } | ||
201 | } | ||
202 | } | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.Compression/OptionStreamContext.cs b/src/dtf/test/WixToolsetTests.Dtf.Compression/OptionStreamContext.cs new file mode 100644 index 00000000..98354d97 --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.Compression/OptionStreamContext.cs | |||
@@ -0,0 +1,42 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | using System; | ||
4 | using System.Collections.Generic; | ||
5 | using WixToolset.Dtf.Compression; | ||
6 | |||
7 | namespace WixToolset.Dtf.Test | ||
8 | { | ||
9 | public class OptionStreamContext : ArchiveFileStreamContext | ||
10 | { | ||
11 | private PackOptionHandler packOptionHandler; | ||
12 | |||
13 | public OptionStreamContext(IList<string> archiveFiles, string directory, IDictionary<string, string> files) | ||
14 | : base(archiveFiles, directory, files) | ||
15 | { | ||
16 | } | ||
17 | |||
18 | public delegate object PackOptionHandler(string optionName, object[] parameters); | ||
19 | |||
20 | public PackOptionHandler OptionHandler | ||
21 | { | ||
22 | get | ||
23 | { | ||
24 | return this.packOptionHandler; | ||
25 | } | ||
26 | set | ||
27 | { | ||
28 | this.packOptionHandler = value; | ||
29 | } | ||
30 | } | ||
31 | |||
32 | public override object GetOption(string optionName, object[] parameters) | ||
33 | { | ||
34 | if (this.OptionHandler == null) | ||
35 | { | ||
36 | return null; | ||
37 | } | ||
38 | |||
39 | return this.OptionHandler(optionName, parameters); | ||
40 | } | ||
41 | } | ||
42 | } | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.Compression/WixToolsetTests.Dtf.Compression.csproj b/src/dtf/test/WixToolsetTests.Dtf.Compression/WixToolsetTests.Dtf.Compression.csproj new file mode 100644 index 00000000..628d36c5 --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.Compression/WixToolsetTests.Dtf.Compression.csproj | |||
@@ -0,0 +1,36 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
3 | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="Current"> | ||
4 | <PropertyGroup> | ||
5 | <ProjectGuid>{F045FFC1-05F9-4EA2-9F03-E1CBDB7BC4F9}</ProjectGuid> | ||
6 | <OutputType>Library</OutputType> | ||
7 | <RootNamespace>WixToolsetTests.Dtf</RootNamespace> | ||
8 | <AssemblyName>WixToolsetTests.Dtf.Compression</AssemblyName> | ||
9 | <CreateDocumentation>false</CreateDocumentation> | ||
10 | <SignOutput>false</SignOutput> | ||
11 | <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> | ||
12 | </PropertyGroup> | ||
13 | |||
14 | <ItemGroup> | ||
15 | <Compile Include="CompressionTestUtil.cs" /> | ||
16 | <Compile Include="MisbehavingStreamContext.cs" /> | ||
17 | <Compile Include="OptionStreamContext.cs" /> | ||
18 | </ItemGroup> | ||
19 | |||
20 | <ItemGroup> | ||
21 | <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | ||
22 | <Reference Include="System" /> | ||
23 | <Reference Include="System.Data" /> | ||
24 | <Reference Include="System.Xml" /> | ||
25 | </ItemGroup> | ||
26 | |||
27 | <ItemGroup> | ||
28 | <ProjectReference Include="..\..\WixToolset.Dtf.Compression\WixToolset.Dtf.Compression.csproj"> | ||
29 | <Project>{45D81DAB-0559-4836-8106-CE9987FD4AB5}</Project> | ||
30 | <Name>WixToolset.Dtf.Compression</Name> | ||
31 | </ProjectReference> | ||
32 | </ItemGroup> | ||
33 | |||
34 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> | ||
35 | <Target Name="Pack" DependsOnTargets="Build" /> | ||
36 | </Project> | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/CustomActionTest.cs b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/CustomActionTest.cs new file mode 100644 index 00000000..bf843024 --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/CustomActionTest.cs | |||
@@ -0,0 +1,206 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | namespace WixToolset.Dtf.Test | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using System.Text; | ||
8 | using System.Collections.Generic; | ||
9 | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
10 | using WixToolset.Dtf.WindowsInstaller; | ||
11 | |||
12 | [TestClass] | ||
13 | public class CustomActionTest | ||
14 | { | ||
15 | public CustomActionTest() | ||
16 | { | ||
17 | } | ||
18 | |||
19 | [TestMethod] | ||
20 | [Ignore] // Currently fails. | ||
21 | public void CustomActionTest1() | ||
22 | { | ||
23 | InstallLogModes logEverything = | ||
24 | InstallLogModes.FatalExit | | ||
25 | InstallLogModes.Error | | ||
26 | InstallLogModes.Warning | | ||
27 | InstallLogModes.User | | ||
28 | InstallLogModes.Info | | ||
29 | InstallLogModes.ResolveSource | | ||
30 | InstallLogModes.OutOfDiskSpace | | ||
31 | InstallLogModes.ActionStart | | ||
32 | InstallLogModes.ActionData | | ||
33 | InstallLogModes.CommonData | | ||
34 | InstallLogModes.Progress | | ||
35 | InstallLogModes.Initialize | | ||
36 | InstallLogModes.Terminate | | ||
37 | InstallLogModes.ShowDialog; | ||
38 | |||
39 | Installer.SetInternalUI(InstallUIOptions.Silent); | ||
40 | ExternalUIHandler prevHandler = Installer.SetExternalUI( | ||
41 | WindowsInstallerTest.ExternalUILogger, logEverything); | ||
42 | |||
43 | try | ||
44 | { | ||
45 | string[] customActions = new string[] { "SampleCA1", "SampleCA2" }; | ||
46 | #if DEBUG | ||
47 | string caDir = @"..\..\..\..\..\build\debug\x86\"; | ||
48 | #else | ||
49 | string caDir = @"..\..\..\..\..\build\ship\x86\"; | ||
50 | #endif | ||
51 | caDir = Path.GetFullPath(caDir); | ||
52 | string caFile = "WixToolset.Dtf.Samples.ManagedCA.dll"; | ||
53 | string caProduct = "CustomActionTest.msi"; | ||
54 | |||
55 | this.CreateCustomActionProduct(caProduct, caDir + caFile, customActions, false); | ||
56 | |||
57 | Exception caughtEx = null; | ||
58 | try | ||
59 | { | ||
60 | Installer.InstallProduct(caProduct, String.Empty); | ||
61 | } | ||
62 | catch (Exception ex) { caughtEx = ex; } | ||
63 | Assert.IsInstanceOfType(caughtEx, typeof(InstallCanceledException), | ||
64 | "Exception thrown while installing product: " + caughtEx); | ||
65 | |||
66 | string arch = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"); | ||
67 | string arch2 = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432"); | ||
68 | if (arch == "AMD64" || arch2 == "AMD64") | ||
69 | { | ||
70 | caDir = caDir.Replace("x86", "x64"); | ||
71 | |||
72 | this.CreateCustomActionProduct(caProduct, caDir + caFile, customActions, true); | ||
73 | |||
74 | caughtEx = null; | ||
75 | try | ||
76 | { | ||
77 | Installer.InstallProduct(caProduct, String.Empty); | ||
78 | } | ||
79 | catch (Exception ex) { caughtEx = ex; } | ||
80 | Assert.IsInstanceOfType(caughtEx, typeof(InstallCanceledException), | ||
81 | "Exception thrown while installing 64bit product: " + caughtEx); | ||
82 | } | ||
83 | } | ||
84 | finally | ||
85 | { | ||
86 | Installer.SetExternalUI(prevHandler, InstallLogModes.None); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | private void CreateCustomActionProduct( | ||
91 | string msiFile, string customActionFile, IList<string> customActions, bool sixtyFourBit) | ||
92 | { | ||
93 | using (Database db = new Database(msiFile, DatabaseOpenMode.CreateDirect)) | ||
94 | { | ||
95 | WindowsInstallerUtils.InitializeProductDatabase(db, sixtyFourBit); | ||
96 | WindowsInstallerUtils.CreateTestProduct(db); | ||
97 | |||
98 | if (!File.Exists(customActionFile)) | ||
99 | throw new FileNotFoundException(customActionFile); | ||
100 | |||
101 | using (Record binRec = new Record(2)) | ||
102 | { | ||
103 | binRec[1] = Path.GetFileName(customActionFile); | ||
104 | binRec.SetStream(2, customActionFile); | ||
105 | |||
106 | db.Execute("INSERT INTO `Binary` (`Name`, `Data`) VALUES (?, ?)", binRec); | ||
107 | } | ||
108 | |||
109 | using (Record binRec2 = new Record(2)) | ||
110 | { | ||
111 | binRec2[1] = "TestData"; | ||
112 | binRec2.SetStream(2, new MemoryStream(Encoding.UTF8.GetBytes("This is a test data stream."))); | ||
113 | |||
114 | db.Execute("INSERT INTO `Binary` (`Name`, `Data`) VALUES (?, ?)", binRec2); | ||
115 | } | ||
116 | |||
117 | for (int i = 0; i < customActions.Count; i++) | ||
118 | { | ||
119 | db.Execute( | ||
120 | "INSERT INTO `CustomAction` (`Action`, `Type`, `Source`, `Target`) VALUES ('{0}', 1, '{1}', '{2}')", | ||
121 | customActions[i], | ||
122 | Path.GetFileName(customActionFile), | ||
123 | customActions[i]); | ||
124 | db.Execute( | ||
125 | "INSERT INTO `InstallExecuteSequence` (`Action`, `Condition`, `Sequence`) VALUES ('{0}', '', {1})", | ||
126 | customActions[i], | ||
127 | 101 + i); | ||
128 | } | ||
129 | |||
130 | db.Execute("INSERT INTO `Property` (`Property`, `Value`) VALUES ('SampleCATest', 'TestValue')"); | ||
131 | |||
132 | db.Commit(); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | [TestMethod] | ||
137 | public void CustomActionData() | ||
138 | { | ||
139 | string dataString = "Key1=Value1;Key2=;Key3;Key4=Value=4;Key5"; | ||
140 | string dataString2 = "Key1=;Key2=Value2;Key3;Key4;Key6=Value;;6=6;Key7=Value7"; | ||
141 | |||
142 | CustomActionData data = new CustomActionData(dataString); | ||
143 | Assert.AreEqual<string>(dataString, data.ToString()); | ||
144 | |||
145 | data["Key1"] = String.Empty; | ||
146 | data["Key2"] = "Value2"; | ||
147 | data["Key4"] = null; | ||
148 | data.Remove("Key5"); | ||
149 | data["Key6"] = "Value;6=6"; | ||
150 | data["Key7"] = "Value7"; | ||
151 | |||
152 | Assert.AreEqual<string>(dataString2, data.ToString()); | ||
153 | |||
154 | MyDataClass myData = new MyDataClass(); | ||
155 | myData.Member1 = "test1"; | ||
156 | myData.Member2 = "test2"; | ||
157 | data.AddObject("MyData", myData); | ||
158 | |||
159 | string myDataString = data.ToString(); | ||
160 | CustomActionData data2 = new CustomActionData(myDataString); | ||
161 | |||
162 | MyDataClass myData2 = data2.GetObject<MyDataClass>("MyData"); | ||
163 | Assert.AreEqual<MyDataClass>(myData, myData2); | ||
164 | |||
165 | List<string> myComplexDataObject = new List<string>(); | ||
166 | myComplexDataObject.Add("CValue1"); | ||
167 | myComplexDataObject.Add("CValue2"); | ||
168 | myComplexDataObject.Add("CValue3"); | ||
169 | |||
170 | CustomActionData myComplexData = new CustomActionData(); | ||
171 | myComplexData.AddObject("MyComplexData", myComplexDataObject); | ||
172 | myComplexData.AddObject("NestedData", data); | ||
173 | string myComplexDataString = myComplexData.ToString(); | ||
174 | |||
175 | CustomActionData myComplexData2 = new CustomActionData(myComplexDataString); | ||
176 | List<string> myComplexDataObject2 = myComplexData2.GetObject<List<string>>("MyComplexData"); | ||
177 | |||
178 | Assert.AreEqual<int>(myComplexDataObject.Count, myComplexDataObject2.Count); | ||
179 | for (int i = 0; i < myComplexDataObject.Count; i++) | ||
180 | { | ||
181 | Assert.AreEqual<string>(myComplexDataObject[i], myComplexDataObject2[i]); | ||
182 | } | ||
183 | |||
184 | data2 = myComplexData2.GetObject<CustomActionData>("NestedData"); | ||
185 | Assert.AreEqual<string>(data.ToString(), data2.ToString()); | ||
186 | } | ||
187 | |||
188 | public class MyDataClass | ||
189 | { | ||
190 | public string Member1; | ||
191 | public string Member2; | ||
192 | |||
193 | public override bool Equals(object obj) | ||
194 | { | ||
195 | MyDataClass other = obj as MyDataClass; | ||
196 | return other != null && this.Member1 == other.Member1 && this.Member2 == other.Member2; | ||
197 | } | ||
198 | |||
199 | public override int GetHashCode() | ||
200 | { | ||
201 | return (this.Member1 != null ? this.Member1.GetHashCode() : 0) ^ | ||
202 | (this.Member2 != null ? this.Member2.GetHashCode() : 0); | ||
203 | } | ||
204 | } | ||
205 | } | ||
206 | } | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/WixToolsetTests.Dtf.WindowsInstaller.CustomActions.csproj b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/WixToolsetTests.Dtf.WindowsInstaller.CustomActions.csproj new file mode 100644 index 00000000..a2f45fde --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/WixToolsetTests.Dtf.WindowsInstaller.CustomActions.csproj | |||
@@ -0,0 +1,32 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
3 | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="Current"> | ||
4 | <PropertyGroup> | ||
5 | <ProjectGuid>{137D376B-989F-4FEA-9A67-01D8D38CA0DE}</ProjectGuid> | ||
6 | <OutputType>Library</OutputType> | ||
7 | <RootNamespace>WixToolsetTests.Dtf</RootNamespace> | ||
8 | <AssemblyName>WixToolsetTests.Dtf.WindowsInstaller.CustomActions</AssemblyName> | ||
9 | <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||
10 | <CreateDocumentation>false</CreateDocumentation> | ||
11 | <SignOutput>false</SignOutput> | ||
12 | <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> | ||
13 | </PropertyGroup> | ||
14 | |||
15 | <ItemGroup> | ||
16 | <Compile Include="CustomActionTest.cs" /> | ||
17 | </ItemGroup> | ||
18 | |||
19 | <ItemGroup> | ||
20 | <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | ||
21 | <Reference Include="System" /> | ||
22 | <Reference Include="System.Windows.Forms" /> | ||
23 | <Reference Include="$(OutputPath)\WixToolset.Dtf.WindowsInstaller.dll" /> | ||
24 | <ProjectReference Include="..\WixToolsetTests.Dtf.WindowsInstaller\WixToolsetTests.Dtf.WindowsInstaller.csproj"> | ||
25 | <Project>{16F5202F-9276-4166-975C-C9654BAF8012}</Project> | ||
26 | <Name>WixToolsetTests.Dtf.WindowsInstaller</Name> | ||
27 | </ProjectReference> | ||
28 | </ItemGroup> | ||
29 | |||
30 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> | ||
31 | <Target Name="Pack" DependsOnTargets="Build" /> | ||
32 | </Project> | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller.Linq/LinqTest.cs b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller.Linq/LinqTest.cs new file mode 100644 index 00000000..7776a1c3 --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller.Linq/LinqTest.cs | |||
@@ -0,0 +1,509 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | using System; | ||
4 | using System.Text; | ||
5 | using System.Collections; | ||
6 | using System.Collections.Generic; | ||
7 | using System.Linq; | ||
8 | using System.Linq.Expressions; | ||
9 | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
10 | using WixToolset.Dtf.WindowsInstaller; | ||
11 | using WixToolset.Dtf.WindowsInstaller.Linq; | ||
12 | |||
13 | namespace WixToolset.Dtf.Test | ||
14 | { | ||
15 | [TestClass] | ||
16 | public class LinqTest | ||
17 | { | ||
18 | private void InitLinqTestDatabase(QDatabase db) | ||
19 | { | ||
20 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
21 | WindowsInstallerUtils.CreateTestProduct(db); | ||
22 | |||
23 | db.Execute( | ||
24 | "INSERT INTO `Feature` (`Feature`, `Title`, `Description`, `Level`, `Attributes`) VALUES ('{0}', '{1}', '{2}', {3}, {4})", | ||
25 | "TestFeature2", | ||
26 | "Test Feature 2", | ||
27 | "Test Feature 2 Description", | ||
28 | 1, | ||
29 | (int) FeatureAttributes.None); | ||
30 | |||
31 | WindowsInstallerUtils.AddRegistryComponent( | ||
32 | db, "TestFeature2", "MyTestRegComp", | ||
33 | Guid.NewGuid().ToString("B"), | ||
34 | "SOFTWARE\\Microsoft\\DTF\\Test", | ||
35 | "MyTestRegComp", "test"); | ||
36 | WindowsInstallerUtils.AddRegistryComponent( | ||
37 | db, "TestFeature2", "MyTestRegComp2", | ||
38 | Guid.NewGuid().ToString("B"), | ||
39 | "SOFTWARE\\Microsoft\\DTF\\Test", | ||
40 | "MyTestRegComp2", "test2"); | ||
41 | WindowsInstallerUtils.AddRegistryComponent( | ||
42 | db, "TestFeature2", "excludeComp", | ||
43 | Guid.NewGuid().ToString("B"), | ||
44 | "SOFTWARE\\Microsoft\\DTF\\Test", | ||
45 | "MyTestRegComp3", "test3"); | ||
46 | |||
47 | db.Commit(); | ||
48 | |||
49 | db.Log = Console.Out; | ||
50 | } | ||
51 | |||
52 | [TestMethod] | ||
53 | public void LinqSimple() | ||
54 | { | ||
55 | using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create)) | ||
56 | { | ||
57 | this.InitLinqTestDatabase(db); | ||
58 | |||
59 | var comps = from c in db.Components | ||
60 | select c; | ||
61 | |||
62 | int count = 0; | ||
63 | foreach (var c in comps) | ||
64 | { | ||
65 | Console.WriteLine(c); | ||
66 | count++; | ||
67 | } | ||
68 | |||
69 | Assert.AreEqual<int>(4, count); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | [TestMethod] | ||
74 | public void LinqWhereNull() | ||
75 | { | ||
76 | using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create)) | ||
77 | { | ||
78 | this.InitLinqTestDatabase(db); | ||
79 | |||
80 | var features = from f in db.Features | ||
81 | where f.Description != null | ||
82 | select f; | ||
83 | |||
84 | int count = 0; | ||
85 | foreach (var f in features) | ||
86 | { | ||
87 | Console.WriteLine(f); | ||
88 | Assert.AreEqual<string>("TestFeature2", f.Feature); | ||
89 | count++; | ||
90 | } | ||
91 | |||
92 | Assert.AreEqual<int>(1, count); | ||
93 | |||
94 | var features2 = from f in db.Features | ||
95 | where f.Description == null | ||
96 | select f; | ||
97 | |||
98 | count = 0; | ||
99 | foreach (var f in features2) | ||
100 | { | ||
101 | Console.WriteLine(f); | ||
102 | Assert.AreEqual<string>("TestFeature1", f.Feature); | ||
103 | count++; | ||
104 | } | ||
105 | |||
106 | Assert.AreEqual<int>(1, count); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | [TestMethod] | ||
111 | public void LinqWhereOperators() | ||
112 | { | ||
113 | using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create)) | ||
114 | { | ||
115 | this.InitLinqTestDatabase(db); | ||
116 | |||
117 | for (int i = 0; i < 100; i++) | ||
118 | { | ||
119 | var newFile = db.Files.NewRecord(); | ||
120 | newFile.File = "TestFile" + i; | ||
121 | newFile.Component_ = "TestComponent"; | ||
122 | newFile.FileName = "TestFile" + i + ".txt"; | ||
123 | newFile.FileSize = i % 10; | ||
124 | newFile.Sequence = i; | ||
125 | newFile.Insert(); | ||
126 | } | ||
127 | |||
128 | var files1 = from f in db.Files where f.Sequence < 40 select f; | ||
129 | Assert.AreEqual<int>(40, files1.AsEnumerable().Count()); | ||
130 | |||
131 | var files2 = from f in db.Files where f.Sequence <= 40 select f; | ||
132 | Assert.AreEqual<int>(41, files2.AsEnumerable().Count()); | ||
133 | |||
134 | var files3 = from f in db.Files where f.Sequence > 40 select f; | ||
135 | Assert.AreEqual<int>(59, files3.AsEnumerable().Count()); | ||
136 | |||
137 | var files4 = from f in db.Files where f.Sequence >= 40 select f; | ||
138 | Assert.AreEqual<int>(60, files4.AsEnumerable().Count()); | ||
139 | |||
140 | var files5 = from f in db.Files where 40 < f.Sequence select f; | ||
141 | Assert.AreEqual<int>(59, files5.AsEnumerable().Count()); | ||
142 | |||
143 | var files6 = from f in db.Files where 40 <= f.Sequence select f; | ||
144 | Assert.AreEqual<int>(60, files6.AsEnumerable().Count()); | ||
145 | |||
146 | var files7 = from f in db.Files where 40 > f.Sequence select f; | ||
147 | Assert.AreEqual<int>(40, files7.AsEnumerable().Count()); | ||
148 | |||
149 | var files8 = from f in db.Files where 40 >= f.Sequence select f; | ||
150 | Assert.AreEqual<int>(41, files8.AsEnumerable().Count()); | ||
151 | |||
152 | var files9 = from f in db.Files where f.Sequence == 40 select f; | ||
153 | Assert.AreEqual<int>(40, files9.AsEnumerable().First().Sequence); | ||
154 | |||
155 | var files10 = from f in db.Files where f.Sequence != 40 select f; | ||
156 | Assert.AreEqual<int>(99, files10.AsEnumerable().Count()); | ||
157 | |||
158 | var files11 = from f in db.Files where 40 == f.Sequence select f; | ||
159 | Assert.AreEqual<int>(40, files11.AsEnumerable().First().Sequence); | ||
160 | |||
161 | var files12 = from f in db.Files where 40 != f.Sequence select f; | ||
162 | Assert.AreEqual<int>(99, files12.AsEnumerable().Count()); | ||
163 | } | ||
164 | } | ||
165 | |||
166 | [TestMethod] | ||
167 | public void LinqShapeSelect() | ||
168 | { | ||
169 | using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create)) | ||
170 | { | ||
171 | this.InitLinqTestDatabase(db); | ||
172 | |||
173 | Console.WriteLine("Running LINQ query 1."); | ||
174 | var features1 = from f in db.Features | ||
175 | select new { Name = f.Feature, | ||
176 | Desc = f.Description }; | ||
177 | |||
178 | int count = 0; | ||
179 | foreach (var f in features1) | ||
180 | { | ||
181 | Console.WriteLine(f); | ||
182 | count++; | ||
183 | } | ||
184 | |||
185 | Assert.AreEqual<int>(2, count); | ||
186 | |||
187 | Console.WriteLine(); | ||
188 | Console.WriteLine("Running LINQ query 2."); | ||
189 | var features2 = from f in db.Features | ||
190 | where f.Description != null | ||
191 | select new { Name = f.Feature, | ||
192 | Desc = f.Description.ToLower() }; | ||
193 | |||
194 | count = 0; | ||
195 | foreach (var f in features2) | ||
196 | { | ||
197 | Console.WriteLine(f); | ||
198 | Assert.AreEqual<string>("TestFeature2", f.Name); | ||
199 | count++; | ||
200 | } | ||
201 | |||
202 | Assert.AreEqual<int>(1, count); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | [TestMethod] | ||
207 | public void LinqUpdateNullableString() | ||
208 | { | ||
209 | using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create)) | ||
210 | { | ||
211 | this.InitLinqTestDatabase(db); | ||
212 | |||
213 | string newDescription = "New updated feature description."; | ||
214 | |||
215 | var features = from f in db.Features | ||
216 | where f.Description != null | ||
217 | select f; | ||
218 | |||
219 | int count = 0; | ||
220 | foreach (var f in features) | ||
221 | { | ||
222 | Console.WriteLine(f); | ||
223 | Assert.AreEqual<string>("TestFeature2", f.Feature); | ||
224 | f.Description = newDescription; | ||
225 | count++; | ||
226 | } | ||
227 | |||
228 | Assert.AreEqual<int>(1, count); | ||
229 | |||
230 | var features2 = from f in db.Features | ||
231 | where f.Description == newDescription | ||
232 | select f; | ||
233 | count = 0; | ||
234 | foreach (var f in features2) | ||
235 | { | ||
236 | Console.WriteLine(f); | ||
237 | Assert.AreEqual<string>("TestFeature2", f.Feature); | ||
238 | f.Description = null; | ||
239 | count++; | ||
240 | } | ||
241 | |||
242 | Assert.AreEqual<int>(1, count); | ||
243 | |||
244 | var features3 = from f in db.Features | ||
245 | where f.Description == null | ||
246 | select f.Feature; | ||
247 | count = 0; | ||
248 | foreach (var f in features3) | ||
249 | { | ||
250 | Console.WriteLine(f); | ||
251 | count++; | ||
252 | } | ||
253 | |||
254 | Assert.AreEqual<int>(2, count); | ||
255 | |||
256 | db.Commit(); | ||
257 | } | ||
258 | } | ||
259 | |||
260 | [TestMethod] | ||
261 | public void LinqInsertDelete() | ||
262 | { | ||
263 | using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create)) | ||
264 | { | ||
265 | this.InitLinqTestDatabase(db); | ||
266 | |||
267 | var newProp = db.Properties.NewRecord(); | ||
268 | newProp.Property = "TestNewProp1"; | ||
269 | newProp.Value = "TestNewValue"; | ||
270 | newProp.Insert(); | ||
271 | |||
272 | string prop = (from p in db.Properties | ||
273 | where p.Property == "TestNewProp1" | ||
274 | select p.Value).AsEnumerable().First(); | ||
275 | Assert.AreEqual<string>("TestNewValue", prop); | ||
276 | |||
277 | newProp.Delete(); | ||
278 | |||
279 | int propCount = (from p in db.Properties | ||
280 | where p.Property == "TestNewProp1" | ||
281 | select p.Value).AsEnumerable().Count(); | ||
282 | Assert.AreEqual<int>(0, propCount); | ||
283 | |||
284 | db.Commit(); | ||
285 | } | ||
286 | } | ||
287 | |||
288 | [TestMethod] | ||
289 | public void LinqQueryQRecord() | ||
290 | { | ||
291 | using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create)) | ||
292 | { | ||
293 | this.InitLinqTestDatabase(db); | ||
294 | |||
295 | var installFilesSeq = (from a in db["InstallExecuteSequence"] | ||
296 | where a["Action"] == "InstallFiles" | ||
297 | select a["Sequence"]).AsEnumerable().First(); | ||
298 | Assert.AreEqual<string>("4000", installFilesSeq); | ||
299 | } | ||
300 | } | ||
301 | |||
302 | [TestMethod] | ||
303 | public void LinqOrderBy() | ||
304 | { | ||
305 | using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create)) | ||
306 | { | ||
307 | this.InitLinqTestDatabase(db); | ||
308 | |||
309 | var actions = from a in db.InstallExecuteSequences | ||
310 | orderby a.Sequence | ||
311 | select a.Action; | ||
312 | foreach (var a in actions) | ||
313 | { | ||
314 | Console.WriteLine(a); | ||
315 | } | ||
316 | |||
317 | var files = from f in db.Files | ||
318 | orderby f.FileSize, f["Sequence"] | ||
319 | where f.Attributes == FileAttributes.None | ||
320 | select f; | ||
321 | |||
322 | foreach (var f in files) | ||
323 | { | ||
324 | Console.WriteLine(f); | ||
325 | } | ||
326 | } | ||
327 | } | ||
328 | |||
329 | [TestMethod] | ||
330 | public void LinqTwoWayJoin() | ||
331 | { | ||
332 | using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create)) | ||
333 | { | ||
334 | this.InitLinqTestDatabase(db); | ||
335 | int count; | ||
336 | |||
337 | var regs = from r in db.Registries | ||
338 | join c in db["Component"] on r.Component_ equals c["Component"] | ||
339 | where c["Component"] == "MyTestRegComp" && | ||
340 | r.Root == RegistryRoot.UserOrMachine | ||
341 | select new { Reg = r.Registry, Dir = c["Directory_"] }; | ||
342 | |||
343 | count = 0; | ||
344 | foreach (var r in regs) | ||
345 | { | ||
346 | Console.WriteLine(r); | ||
347 | count++; | ||
348 | } | ||
349 | Assert.AreEqual<int>(1, count); | ||
350 | |||
351 | var regs2 = from r in db.Registries | ||
352 | join c in db.Components on r.Component_ equals c.Component | ||
353 | where c.Component == "MyTestRegComp" && | ||
354 | r.Root == RegistryRoot.UserOrMachine | ||
355 | select new { Reg = r, Dir = c.Directory_ }; | ||
356 | |||
357 | count = 0; | ||
358 | foreach (var r in regs2) | ||
359 | { | ||
360 | Assert.IsNotNull(r.Reg.Registry); | ||
361 | Console.WriteLine(r); | ||
362 | count++; | ||
363 | } | ||
364 | Assert.AreEqual<int>(1, count); | ||
365 | |||
366 | var regs3 = from r in db.Registries | ||
367 | join c in db.Components on r.Component_ equals c.Component | ||
368 | where c.Component == "MyTestRegComp" && | ||
369 | r.Root == RegistryRoot.UserOrMachine | ||
370 | select r; | ||
371 | |||
372 | count = 0; | ||
373 | foreach (var r in regs3) | ||
374 | { | ||
375 | Assert.IsNotNull(r.Registry); | ||
376 | Console.WriteLine(r); | ||
377 | count++; | ||
378 | } | ||
379 | Assert.AreEqual<int>(1, count); | ||
380 | |||
381 | } | ||
382 | } | ||
383 | |||
384 | [TestMethod] | ||
385 | public void LinqFourWayJoin() | ||
386 | { | ||
387 | using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create)) | ||
388 | { | ||
389 | this.InitLinqTestDatabase(db); | ||
390 | int count; | ||
391 | |||
392 | IList<string> pretest = db.ExecuteStringQuery( | ||
393 | "SELECT `Feature`.`Feature` " + | ||
394 | "FROM `Feature`, `FeatureComponents`, `Component`, `Registry` " + | ||
395 | "WHERE `Feature`.`Feature` = `FeatureComponents`.`Feature_` " + | ||
396 | "AND `FeatureComponents`.`Component_` = `Component`.`Component` " + | ||
397 | "AND `Component`.`Component` = `Registry`.`Component_` " + | ||
398 | "AND (`Registry`.`Registry` = 'MyTestRegCompReg1')"); | ||
399 | Assert.AreEqual<int>(1, pretest.Count); | ||
400 | |||
401 | var features = from f in db.Features | ||
402 | join fc in db.FeatureComponents on f.Feature equals fc.Feature_ | ||
403 | join c in db.Components on fc.Component_ equals c.Component | ||
404 | join r in db.Registries on c.Component equals r.Component_ | ||
405 | where r.Registry == "MyTestRegCompReg1" | ||
406 | select f.Feature; | ||
407 | |||
408 | count = 0; | ||
409 | foreach (var featureName in features) | ||
410 | { | ||
411 | Console.WriteLine(featureName); | ||
412 | count++; | ||
413 | } | ||
414 | Assert.AreEqual<int>(1, count); | ||
415 | |||
416 | } | ||
417 | } | ||
418 | |||
419 | [TestMethod] | ||
420 | public void EnumTable() | ||
421 | { | ||
422 | using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create)) | ||
423 | { | ||
424 | this.InitLinqTestDatabase(db); | ||
425 | int count = 0; | ||
426 | foreach (var comp in db.Components) | ||
427 | { | ||
428 | Console.WriteLine(comp); | ||
429 | count++; | ||
430 | } | ||
431 | Assert.AreNotEqual<int>(0, count); | ||
432 | } | ||
433 | } | ||
434 | |||
435 | [TestMethod] | ||
436 | public void DatabaseAsQueryable() | ||
437 | { | ||
438 | using (Database db = new Database("testlinq.msi", DatabaseOpenMode.Create)) | ||
439 | { | ||
440 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
441 | WindowsInstallerUtils.CreateTestProduct(db); | ||
442 | |||
443 | var comps = from c in db.AsQueryable().Components | ||
444 | select c; | ||
445 | |||
446 | int count = 0; | ||
447 | foreach (var c in comps) | ||
448 | { | ||
449 | Console.WriteLine(c); | ||
450 | count++; | ||
451 | } | ||
452 | |||
453 | Assert.AreEqual<int>(1, count); | ||
454 | } | ||
455 | } | ||
456 | |||
457 | [TestMethod] | ||
458 | public void EnumProducts() | ||
459 | { | ||
460 | var products = from p in ProductInstallation.AllProducts | ||
461 | where p.Publisher == ".NET Foundation" | ||
462 | select new { Name = p.ProductName, | ||
463 | Ver = p.ProductVersion, | ||
464 | Company = p.Publisher, | ||
465 | InstallDate = p.InstallDate, | ||
466 | PackageCode = p.AdvertisedPackageCode }; | ||
467 | |||
468 | foreach (var p in products) | ||
469 | { | ||
470 | Console.WriteLine(p); | ||
471 | Assert.IsTrue(p.Company == ".NET Foundation"); | ||
472 | } | ||
473 | } | ||
474 | |||
475 | [TestMethod] | ||
476 | public void EnumFeatures() | ||
477 | { | ||
478 | foreach (var p in ProductInstallation.AllProducts) | ||
479 | { | ||
480 | Console.WriteLine(p.ProductName); | ||
481 | |||
482 | foreach (var f in p.Features) | ||
483 | { | ||
484 | Console.WriteLine("\t" + f.FeatureName); | ||
485 | } | ||
486 | } | ||
487 | } | ||
488 | |||
489 | [TestMethod] | ||
490 | public void EnumComponents() | ||
491 | { | ||
492 | var comps = from c in ComponentInstallation.AllComponents | ||
493 | where c.State == InstallState.Local && | ||
494 | c.Product.Publisher == ".NET Foundation" | ||
495 | select c.Path; | ||
496 | |||
497 | int count = 0; | ||
498 | foreach (var c in comps) | ||
499 | { | ||
500 | if (++count == 100) break; | ||
501 | |||
502 | Console.WriteLine(c); | ||
503 | } | ||
504 | |||
505 | Assert.AreEqual<int>(100, count); | ||
506 | } | ||
507 | } | ||
508 | |||
509 | } | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller.Linq/WixToolsetTests.Dtf.WindowsInstaller.Linq.csproj b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller.Linq/WixToolsetTests.Dtf.WindowsInstaller.Linq.csproj new file mode 100644 index 00000000..c34494b7 --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller.Linq/WixToolsetTests.Dtf.WindowsInstaller.Linq.csproj | |||
@@ -0,0 +1,42 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
3 | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="Current"> | ||
4 | <PropertyGroup> | ||
5 | <ProjectGuid>{4F55F9B8-D8B6-41EB-8796-221B4CD98324}</ProjectGuid> | ||
6 | <OutputType>Library</OutputType> | ||
7 | <RootNamespace>WixToolsetTests.Dtf</RootNamespace> | ||
8 | <AssemblyName>WixToolsetTests.Dtf.Linq</AssemblyName> | ||
9 | <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||
10 | <CreateDocumentation>false</CreateDocumentation> | ||
11 | <SignOutput>false</SignOutput> | ||
12 | <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> | ||
13 | </PropertyGroup> | ||
14 | |||
15 | <ItemGroup> | ||
16 | <Compile Include="LinqTest.cs" /> | ||
17 | </ItemGroup> | ||
18 | |||
19 | <ItemGroup> | ||
20 | <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | ||
21 | <Reference Include="System" /> | ||
22 | <Reference Include="System.Core" /> | ||
23 | </ItemGroup> | ||
24 | |||
25 | <ItemGroup> | ||
26 | <ProjectReference Include="..\..\WixToolset.Dtf.WindowsInstaller\WixToolset.Dtf.WindowsInstaller.csproj"> | ||
27 | <Project>{85225597-5121-4361-8332-4E3246D5BBF5}</Project> | ||
28 | <Name>WixToolset.Dtf.WindowsInstaller</Name> | ||
29 | </ProjectReference> | ||
30 | <ProjectReference Include="..\..\WixToolset.Dtf.WindowsInstaller.Linq\WixToolset.Dtf.WindowsInstaller.Linq.csproj"> | ||
31 | <Project>{7E66313B-C6D4-4729-8422-4D1474E0E6F7}</Project> | ||
32 | <Name>WixToolset.Dtf.WindowsInstaller.Linq</Name> | ||
33 | </ProjectReference> | ||
34 | <ProjectReference Include="..\WixToolsetTests.Dtf.WindowsInstaller\WixToolsetTests.Dtf.WindowsInstaller.csproj"> | ||
35 | <Project>{16F5202F-9276-4166-975C-C9654BAF8012}</Project> | ||
36 | <Name>WixToolsetTests.Dtf.WindowsInstaller</Name> | ||
37 | </ProjectReference> | ||
38 | </ItemGroup> | ||
39 | |||
40 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> | ||
41 | <Target Name="Pack" DependsOnTargets="Build" /> | ||
42 | </Project> \ No newline at end of file | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/EmbeddedExternalUI.cs b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/EmbeddedExternalUI.cs new file mode 100644 index 00000000..b0fc00a8 --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/EmbeddedExternalUI.cs | |||
@@ -0,0 +1,173 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | namespace WixToolset.Dtf.Test | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using System.Reflection; | ||
8 | using System.Windows.Forms; | ||
9 | using System.Globalization; | ||
10 | using System.Collections.Generic; | ||
11 | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
12 | using WixToolset.Dtf.WindowsInstaller; | ||
13 | using View = WixToolset.Dtf.WindowsInstaller.View; | ||
14 | |||
15 | [TestClass] | ||
16 | public class EmbeddedExternalUI | ||
17 | { | ||
18 | const InstallLogModes TestLogModes = | ||
19 | InstallLogModes.FatalExit | | ||
20 | InstallLogModes.Error | | ||
21 | InstallLogModes.Warning | | ||
22 | InstallLogModes.User | | ||
23 | InstallLogModes.Info | | ||
24 | InstallLogModes.ResolveSource | | ||
25 | InstallLogModes.OutOfDiskSpace | | ||
26 | InstallLogModes.ActionStart | | ||
27 | InstallLogModes.ActionData | | ||
28 | InstallLogModes.CommonData; | ||
29 | |||
30 | #if DEBUG | ||
31 | const string EmbeddedUISampleBinDir = @"..\..\build\debug\"; | ||
32 | #else | ||
33 | const string EmbeddedUISampleBinDir = @"..\..\build\release\"; | ||
34 | #endif | ||
35 | |||
36 | [TestMethod] | ||
37 | [Ignore] // Requires elevation. | ||
38 | public void EmbeddedUISingleInstall() | ||
39 | { | ||
40 | string dbFile = "EmbeddedUISingleInstall.msi"; | ||
41 | string productCode; | ||
42 | |||
43 | string uiDir = Path.GetFullPath(EmbeddedExternalUI.EmbeddedUISampleBinDir); | ||
44 | string uiFile = "WixToolset.Dtf.Samples.EmbeddedUI.dll"; | ||
45 | |||
46 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
47 | { | ||
48 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
49 | WindowsInstallerUtils.CreateTestProduct(db); | ||
50 | |||
51 | productCode = db.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0]; | ||
52 | |||
53 | using (Record uiRec = new Record(5)) | ||
54 | { | ||
55 | uiRec[1] = "TestEmbeddedUI"; | ||
56 | uiRec[2] = Path.GetFileNameWithoutExtension(uiFile) + ".Wrapper.dll"; | ||
57 | uiRec[3] = 1; | ||
58 | uiRec[4] = (int) ( | ||
59 | EmbeddedExternalUI.TestLogModes | | ||
60 | InstallLogModes.Progress | | ||
61 | InstallLogModes.Initialize | | ||
62 | InstallLogModes.Terminate | | ||
63 | InstallLogModes.ShowDialog); | ||
64 | uiRec.SetStream(5, Path.Combine(uiDir, uiFile)); | ||
65 | db.Execute(db.Tables["MsiEmbeddedUI"].SqlInsertString, uiRec); | ||
66 | } | ||
67 | |||
68 | db.Commit(); | ||
69 | } | ||
70 | |||
71 | Installer.SetInternalUI(InstallUIOptions.Full); | ||
72 | |||
73 | ProductInstallation installation = new ProductInstallation(productCode); | ||
74 | Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed before starting."); | ||
75 | |||
76 | Exception caughtEx = null; | ||
77 | try | ||
78 | { | ||
79 | Installer.EnableLog(EmbeddedExternalUI.TestLogModes, "install.log"); | ||
80 | Installer.InstallProduct(dbFile, String.Empty); | ||
81 | } | ||
82 | catch (Exception ex) { caughtEx = ex; } | ||
83 | Assert.IsNull(caughtEx, "Exception thrown while installing product: " + caughtEx); | ||
84 | |||
85 | Assert.IsTrue(installation.IsInstalled, "Checking that product is installed."); | ||
86 | Console.WriteLine(); | ||
87 | Console.WriteLine(); | ||
88 | Console.WriteLine(); | ||
89 | Console.WriteLine("==================================================================="); | ||
90 | Console.WriteLine(); | ||
91 | Console.WriteLine(); | ||
92 | Console.WriteLine(); | ||
93 | |||
94 | try | ||
95 | { | ||
96 | Installer.EnableLog(EmbeddedExternalUI.TestLogModes, "uninstall.log"); | ||
97 | Installer.InstallProduct(dbFile, "REMOVE=All"); | ||
98 | } | ||
99 | catch (Exception ex) { caughtEx = ex; } | ||
100 | Assert.IsNull(caughtEx, "Exception thrown while uninstalling product: " + caughtEx); | ||
101 | } | ||
102 | |||
103 | // This test does not pass if run normally. | ||
104 | // It only passes when a failure is injected into the EmbeddedUI launcher. | ||
105 | ////[TestMethod] | ||
106 | public void EmbeddedUIInitializeFails() | ||
107 | { | ||
108 | string dbFile = "EmbeddedUIInitializeFails.msi"; | ||
109 | string productCode; | ||
110 | |||
111 | string uiDir = Path.GetFullPath(EmbeddedExternalUI.EmbeddedUISampleBinDir); | ||
112 | string uiFile = "WixToolset.Dtf.Samples.EmbeddedUI.dll"; | ||
113 | |||
114 | // A number that will be used to check whether a type 19 CA runs. | ||
115 | const string magicNumber = "3.14159265358979323846264338327950"; | ||
116 | |||
117 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
118 | { | ||
119 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
120 | WindowsInstallerUtils.CreateTestProduct(db); | ||
121 | |||
122 | const string failureActionName = "EmbeddedUIInitializeFails"; | ||
123 | db.Execute("INSERT INTO `CustomAction` (`Action`, `Type`, `Source`, `Target`) " + | ||
124 | "VALUES ('{0}', 19, '', 'Logging magic number: {1}')", failureActionName, magicNumber); | ||
125 | |||
126 | // This type 19 CA (launch condition) is given a condition of 'UILevel = 3' so that it only runs if the | ||
127 | // installation is running in BASIC UI mode, which is what we expect if the EmbeddedUI fails to initialize. | ||
128 | db.Execute("INSERT INTO `InstallExecuteSequence` (`Action`, `Condition`, `Sequence`) " + | ||
129 | "VALUES ('{0}', 'UILevel = 3', 1)", failureActionName); | ||
130 | |||
131 | productCode = db.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0]; | ||
132 | |||
133 | using (Record uiRec = new Record(5)) | ||
134 | { | ||
135 | uiRec[1] = "TestEmbeddedUI"; | ||
136 | uiRec[2] = Path.GetFileNameWithoutExtension(uiFile) + ".Wrapper.dll"; | ||
137 | uiRec[3] = 1; | ||
138 | uiRec[4] = (int)( | ||
139 | EmbeddedExternalUI.TestLogModes | | ||
140 | InstallLogModes.Progress | | ||
141 | InstallLogModes.Initialize | | ||
142 | InstallLogModes.Terminate | | ||
143 | InstallLogModes.ShowDialog); | ||
144 | uiRec.SetStream(5, Path.Combine(uiDir, uiFile)); | ||
145 | db.Execute(db.Tables["MsiEmbeddedUI"].SqlInsertString, uiRec); | ||
146 | } | ||
147 | |||
148 | db.Commit(); | ||
149 | } | ||
150 | |||
151 | Installer.SetInternalUI(InstallUIOptions.Full); | ||
152 | |||
153 | ProductInstallation installation = new ProductInstallation(productCode); | ||
154 | Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed before starting."); | ||
155 | |||
156 | string logFile = "install.log"; | ||
157 | Exception caughtEx = null; | ||
158 | try | ||
159 | { | ||
160 | Installer.EnableLog(EmbeddedExternalUI.TestLogModes, logFile); | ||
161 | Installer.InstallProduct(dbFile, String.Empty); | ||
162 | } | ||
163 | catch (Exception ex) { caughtEx = ex; } | ||
164 | Assert.IsInstanceOfType(caughtEx, typeof(InstallerException), | ||
165 | "Excpected InstallerException installing product; caught: " + caughtEx); | ||
166 | |||
167 | Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed."); | ||
168 | |||
169 | string logText = File.ReadAllText(logFile); | ||
170 | Assert.IsTrue(logText.Contains(magicNumber), "Checking that the type 19 custom action ran."); | ||
171 | } | ||
172 | } | ||
173 | } | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/Schema.cs b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/Schema.cs new file mode 100644 index 00000000..26c172c9 --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/Schema.cs | |||
@@ -0,0 +1,238 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | namespace WixToolset.Dtf.Test | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using System.Collections.Generic; | ||
8 | using System.Text; | ||
9 | using WixToolset.Dtf.WindowsInstaller; | ||
10 | |||
11 | public static class Schema | ||
12 | { | ||
13 | public static IList<TableInfo> Tables | ||
14 | { | ||
15 | get | ||
16 | { | ||
17 | return new TableInfo[] | ||
18 | { | ||
19 | Binary, | ||
20 | Component, | ||
21 | CustomAction, | ||
22 | Directory, | ||
23 | EmbeddedUI, | ||
24 | Feature, | ||
25 | FeatureComponents, | ||
26 | File, | ||
27 | InstallExecuteSequence, | ||
28 | Media, | ||
29 | Property, | ||
30 | Registry | ||
31 | }; | ||
32 | } | ||
33 | } | ||
34 | |||
35 | #region Table data | ||
36 | |||
37 | public static TableInfo Binary { get { return new TableInfo( | ||
38 | "Binary", | ||
39 | new ColumnInfo[] | ||
40 | { | ||
41 | new ColumnInfo("Name", typeof(String), 72, true), | ||
42 | new ColumnInfo("Data", typeof(Stream), 0, true), | ||
43 | }, | ||
44 | new string[] { "Name" }); | ||
45 | } } | ||
46 | |||
47 | public static TableInfo Component { get { return new TableInfo( | ||
48 | "Component", | ||
49 | new ColumnInfo[] | ||
50 | { | ||
51 | new ColumnInfo("Component", typeof(String), 72, true), | ||
52 | new ColumnInfo("ComponentId", typeof(String), 38, false), | ||
53 | new ColumnInfo("Directory_", typeof(String), 72, true), | ||
54 | new ColumnInfo("Attributes", typeof(Int16), 2, true), | ||
55 | new ColumnInfo("Condition", typeof(String), 255, false), | ||
56 | new ColumnInfo("KeyPath", typeof(String), 72, false), | ||
57 | }, | ||
58 | new string[] { "Component" }); | ||
59 | } } | ||
60 | |||
61 | public static TableInfo CustomAction { get { return new TableInfo( | ||
62 | "CustomAction", | ||
63 | new ColumnInfo[] | ||
64 | { | ||
65 | new ColumnInfo("Action", typeof(String), 72, true), | ||
66 | new ColumnInfo("Type", typeof(Int16), 2, true), | ||
67 | new ColumnInfo("Source", typeof(String), 64, false), | ||
68 | new ColumnInfo("Target", typeof(String), 255, false), | ||
69 | }, | ||
70 | new string[] { "Action" }); | ||
71 | } } | ||
72 | |||
73 | public static TableInfo Directory { get { return new TableInfo( | ||
74 | "Directory", | ||
75 | new ColumnInfo[] | ||
76 | { | ||
77 | new ColumnInfo("Directory", typeof(String), 72, true), | ||
78 | new ColumnInfo("Directory_Parent", typeof(String), 72, false), | ||
79 | new ColumnInfo("DefaultDir", typeof(String), 255, true, false, true), | ||
80 | }, | ||
81 | new string[] { "Directory" }); | ||
82 | } } | ||
83 | |||
84 | public static TableInfo EmbeddedUI { get { return new TableInfo( | ||
85 | "MsiEmbeddedUI", | ||
86 | new ColumnInfo[] | ||
87 | { | ||
88 | new ColumnInfo("MsiEmbeddedUI", typeof(String), 72, true), | ||
89 | new ColumnInfo("FileName", typeof(String), 72, true), | ||
90 | new ColumnInfo("Attributes", typeof(Int16), 2, true), | ||
91 | new ColumnInfo("MessageFilter", typeof(Int32), 4, false), | ||
92 | new ColumnInfo("Data", typeof(Stream), 0, true), | ||
93 | }, | ||
94 | new string[] { "MsiEmbeddedUI" }); | ||
95 | } } | ||
96 | |||
97 | public static TableInfo Feature { get { return new TableInfo( | ||
98 | "Feature", | ||
99 | new ColumnInfo[] | ||
100 | { | ||
101 | new ColumnInfo("Feature", typeof(String), 38, true), | ||
102 | new ColumnInfo("Feature_Parent", typeof(String), 38, false), | ||
103 | new ColumnInfo("Title", typeof(String), 64, false, false, true), | ||
104 | new ColumnInfo("Description", typeof(String), 64, false, false, true), | ||
105 | new ColumnInfo("Display", typeof(Int16), 2, false), | ||
106 | new ColumnInfo("Level", typeof(Int16), 2, true), | ||
107 | new ColumnInfo("Directory_", typeof(String), 72, false), | ||
108 | new ColumnInfo("Attributes", typeof(Int16), 2, true), | ||
109 | }, | ||
110 | new string[] { "Feature" }); | ||
111 | } } | ||
112 | |||
113 | public static TableInfo FeatureComponents { get { return new TableInfo( | ||
114 | "FeatureComponents", | ||
115 | new ColumnInfo[] | ||
116 | { | ||
117 | new ColumnInfo("Feature_", typeof(String), 38, true), | ||
118 | new ColumnInfo("Component_", typeof(String), 72, true), | ||
119 | }, | ||
120 | new string[] { "Feature_", "Component_" }); | ||
121 | } } | ||
122 | |||
123 | public static TableInfo File { get { return new TableInfo( | ||
124 | "File", | ||
125 | new ColumnInfo[] | ||
126 | { | ||
127 | new ColumnInfo("File", typeof(String), 72, true), | ||
128 | new ColumnInfo("Component_", typeof(String), 72, true), | ||
129 | new ColumnInfo("FileName", typeof(String), 255, true, false, true), | ||
130 | new ColumnInfo("FileSize", typeof(Int32), 4, true), | ||
131 | new ColumnInfo("Version", typeof(String), 72, false), | ||
132 | new ColumnInfo("Language", typeof(String), 20, false), | ||
133 | new ColumnInfo("Attributes", typeof(Int16), 2, false), | ||
134 | new ColumnInfo("Sequence", typeof(Int16), 2, true), | ||
135 | }, | ||
136 | new string[] { "File" }); | ||
137 | } } | ||
138 | |||
139 | public static TableInfo InstallExecuteSequence { get { return new TableInfo( | ||
140 | "InstallExecuteSequence", | ||
141 | new ColumnInfo[] | ||
142 | { | ||
143 | new ColumnInfo("Action", typeof(String), 72, true), | ||
144 | new ColumnInfo("Condition", typeof(String), 255, false), | ||
145 | new ColumnInfo("Sequence", typeof(Int16), 2, true), | ||
146 | }, | ||
147 | new string[] { "Action" }); | ||
148 | } } | ||
149 | |||
150 | public static TableInfo Media { get { return new TableInfo( | ||
151 | "Media", | ||
152 | new ColumnInfo[] | ||
153 | { | ||
154 | new ColumnInfo("DiskId", typeof(Int16), 2, true), | ||
155 | new ColumnInfo("LastSequence", typeof(Int16), 2, true), | ||
156 | new ColumnInfo("DiskPrompt", typeof(String), 64, false, false, true), | ||
157 | new ColumnInfo("Cabinet", typeof(String), 255, false), | ||
158 | new ColumnInfo("VolumeLabel", typeof(String), 32, false), | ||
159 | new ColumnInfo("Source", typeof(String), 32, false), | ||
160 | }, | ||
161 | new string[] { "DiskId" }); | ||
162 | } } | ||
163 | |||
164 | public static TableInfo Property { get { return new TableInfo( | ||
165 | "Property", | ||
166 | new ColumnInfo[] | ||
167 | { | ||
168 | new ColumnInfo("Property", typeof(String), 72, true), | ||
169 | new ColumnInfo("Value", typeof(String), 255, true), | ||
170 | }, | ||
171 | new string[] { "Property" }); | ||
172 | } } | ||
173 | |||
174 | public static TableInfo Registry { get { return new TableInfo( | ||
175 | "Registry", | ||
176 | new ColumnInfo[] | ||
177 | { | ||
178 | new ColumnInfo("Registry", typeof(String), 72, true), | ||
179 | new ColumnInfo("Root", typeof(Int16), 2, true), | ||
180 | new ColumnInfo("Key", typeof(String), 255, true, false, true), | ||
181 | new ColumnInfo("Name", typeof(String), 255, false, false, true), | ||
182 | new ColumnInfo("Value", typeof(String), 0, false, false, true), | ||
183 | new ColumnInfo("Component_", typeof(String), 72, true), | ||
184 | }, | ||
185 | new string[] { "Registry" }); | ||
186 | } } | ||
187 | |||
188 | #endregion | ||
189 | |||
190 | } | ||
191 | |||
192 | public class Action | ||
193 | { | ||
194 | public readonly string Name; | ||
195 | public readonly int Sequence; | ||
196 | |||
197 | public Action(string name, int sequence) | ||
198 | { | ||
199 | this.Name = name; | ||
200 | this.Sequence = sequence; | ||
201 | } | ||
202 | |||
203 | } | ||
204 | |||
205 | public class Sequence | ||
206 | { | ||
207 | public static IList<Action> InstallExecute | ||
208 | { | ||
209 | get | ||
210 | { | ||
211 | return new Action[] | ||
212 | { | ||
213 | new Action("CostInitialize", 800), | ||
214 | new Action("FileCost", 900), | ||
215 | new Action("CostFinalize", 1000), | ||
216 | new Action("InstallValidate", 1400), | ||
217 | new Action("InstallInitialize", 1500), | ||
218 | new Action("ProcessComponents", 1600), | ||
219 | new Action("UnpublishComponents", 1700), | ||
220 | new Action("UnpublishFeatures", 1800), | ||
221 | new Action("RemoveRegistryValues", 2600), | ||
222 | new Action("RemoveFiles", 3500), | ||
223 | new Action("RemoveFolders", 3600), | ||
224 | new Action("CreateFolders", 3700), | ||
225 | new Action("MoveFiles", 3800), | ||
226 | new Action("InstallFiles", 4000), | ||
227 | new Action("WriteRegistryValues", 5000), | ||
228 | new Action("RegisterProduct", 6100), | ||
229 | new Action("PublishComponents", 6200), | ||
230 | new Action("PublishFeatures", 6300), | ||
231 | new Action("PublishProduct", 6400), | ||
232 | new Action("InstallFinalize", 6600), | ||
233 | }; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | } | ||
238 | } | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTest.cs b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTest.cs new file mode 100644 index 00000000..f994dfef --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTest.cs | |||
@@ -0,0 +1,409 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | namespace WixToolset.Dtf.Test | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using System.Windows.Forms; | ||
8 | using System.Globalization; | ||
9 | using System.Collections.Generic; | ||
10 | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
11 | using WixToolset.Dtf.WindowsInstaller; | ||
12 | using View = WixToolset.Dtf.WindowsInstaller.View; | ||
13 | |||
14 | [TestClass] | ||
15 | public class WindowsInstallerTest | ||
16 | { | ||
17 | public WindowsInstallerTest() | ||
18 | { | ||
19 | } | ||
20 | |||
21 | [TestInitialize()] | ||
22 | public void Initialize() | ||
23 | { | ||
24 | } | ||
25 | |||
26 | [TestCleanup()] | ||
27 | public void Cleanup() | ||
28 | { | ||
29 | } | ||
30 | |||
31 | [TestMethod] | ||
32 | [Ignore] // Currently fails. | ||
33 | public void InstallerErrorMessages() | ||
34 | { | ||
35 | string msg3002 = Installer.GetErrorMessage(3002); | ||
36 | Console.WriteLine("3002=" + msg3002); | ||
37 | Assert.IsNotNull(msg3002); | ||
38 | Assert.IsTrue(msg3002.Length > 0); | ||
39 | } | ||
40 | |||
41 | [TestMethod] | ||
42 | public void InstallerDatabaseSchema() | ||
43 | { | ||
44 | string dbFile = "InstallerDatabaseSchema.msi"; | ||
45 | |||
46 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
47 | { | ||
48 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
49 | db.Commit(); | ||
50 | } | ||
51 | |||
52 | Assert.IsTrue(File.Exists(dbFile), "Checking whether created database file " + dbFile + " exists."); | ||
53 | |||
54 | using (Database db = new Database(dbFile, DatabaseOpenMode.ReadOnly)) | ||
55 | { | ||
56 | TableCollection tables = db.Tables; | ||
57 | Assert.AreEqual<int>(Schema.Tables.Count, tables.Count, "Counting tables."); | ||
58 | Assert.AreEqual<int>(Schema.Property.Columns.Count, tables["Property"].Columns.Count, "Counting columns in Property table."); | ||
59 | |||
60 | foreach (TableInfo tableInfo in tables) | ||
61 | { | ||
62 | Console.WriteLine(tableInfo.Name); | ||
63 | foreach (ColumnInfo columnInfo in tableInfo.Columns) | ||
64 | { | ||
65 | Console.WriteLine("\t{0} {1}", columnInfo.Name, columnInfo.ColumnDefinitionString); | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | |||
71 | [TestMethod] | ||
72 | public void InstallerViewTables() | ||
73 | { | ||
74 | string dbFile = "InstallerViewTables.msi"; | ||
75 | |||
76 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
77 | { | ||
78 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
79 | db.Commit(); | ||
80 | |||
81 | using (View view1 = db.OpenView("SELECT `Property`, `Value` FROM `Property` WHERE `Value` IS NOT NULL")) | ||
82 | { | ||
83 | IList<TableInfo> viewTables = view1.Tables; | ||
84 | Assert.IsNotNull(viewTables); | ||
85 | Assert.AreEqual<int>(1, viewTables.Count); | ||
86 | Assert.AreEqual<String>("Property", viewTables[0].Name); | ||
87 | } | ||
88 | |||
89 | using (View view2 = db.OpenView("INSERT INTO `Property` (`Property`, `Value`) VALUES ('TestViewTables', 1)")) | ||
90 | { | ||
91 | IList<TableInfo> viewTables = view2.Tables; | ||
92 | Assert.IsNotNull(viewTables); | ||
93 | Assert.AreEqual<int>(1, viewTables.Count); | ||
94 | Assert.AreEqual<String>("Property", viewTables[0].Name); | ||
95 | } | ||
96 | |||
97 | using (View view3 = db.OpenView("UPDATE `Property` SET `Value` = 2 WHERE `Property` = 'TestViewTables'")) | ||
98 | { | ||
99 | IList<TableInfo> viewTables = view3.Tables; | ||
100 | Assert.IsNotNull(viewTables); | ||
101 | Assert.AreEqual<int>(1, viewTables.Count); | ||
102 | Assert.AreEqual<String>("Property", viewTables[0].Name); | ||
103 | } | ||
104 | |||
105 | using (View view4 = db.OpenView("alter table Property hold")) | ||
106 | { | ||
107 | IList<TableInfo> viewTables = view4.Tables; | ||
108 | Assert.IsNotNull(viewTables); | ||
109 | Assert.AreEqual<int>(1, viewTables.Count); | ||
110 | Assert.AreEqual<String>("Property", viewTables[0].Name); | ||
111 | } | ||
112 | } | ||
113 | } | ||
114 | |||
115 | [TestMethod] | ||
116 | public void InstallerInstallProduct() | ||
117 | { | ||
118 | string dbFile = "InstallerInstallProduct.msi"; | ||
119 | string productCode; | ||
120 | |||
121 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
122 | { | ||
123 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
124 | WindowsInstallerUtils.CreateTestProduct(db); | ||
125 | |||
126 | productCode = db.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0]; | ||
127 | |||
128 | db.Commit(); | ||
129 | } | ||
130 | |||
131 | ProductInstallation installation = new ProductInstallation(productCode); | ||
132 | Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed before starting."); | ||
133 | |||
134 | Installer.SetInternalUI(InstallUIOptions.Silent); | ||
135 | ExternalUIHandler prevHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUILogger, | ||
136 | InstallLogModes.FatalExit | | ||
137 | InstallLogModes.Error | | ||
138 | InstallLogModes.Warning | | ||
139 | InstallLogModes.User | | ||
140 | InstallLogModes.Info | | ||
141 | InstallLogModes.ResolveSource | | ||
142 | InstallLogModes.OutOfDiskSpace | | ||
143 | InstallLogModes.ActionStart | | ||
144 | InstallLogModes.ActionData | | ||
145 | InstallLogModes.CommonData | | ||
146 | InstallLogModes.Progress | | ||
147 | InstallLogModes.Initialize | | ||
148 | InstallLogModes.Terminate | | ||
149 | InstallLogModes.ShowDialog); | ||
150 | Assert.IsNull(prevHandler, "Checking that returned previous UI handler is null."); | ||
151 | |||
152 | Exception caughtEx = null; | ||
153 | try | ||
154 | { | ||
155 | Installer.InstallProduct(dbFile, String.Empty); | ||
156 | } | ||
157 | catch (Exception ex) { caughtEx = ex; } | ||
158 | Assert.IsNull(caughtEx, "Exception thrown while installing product: " + caughtEx); | ||
159 | |||
160 | prevHandler = Installer.SetExternalUI(prevHandler, InstallLogModes.None); | ||
161 | Assert.AreEqual<ExternalUIHandler>(WindowsInstallerTest.ExternalUILogger, prevHandler, "Checking that previously-set UI handler is returned."); | ||
162 | |||
163 | Assert.IsTrue(installation.IsInstalled, "Checking that product is installed."); | ||
164 | Console.WriteLine(); | ||
165 | Console.WriteLine(); | ||
166 | Console.WriteLine(); | ||
167 | Console.WriteLine("==================================================================="); | ||
168 | Console.WriteLine(); | ||
169 | Console.WriteLine(); | ||
170 | Console.WriteLine(); | ||
171 | |||
172 | ExternalUIRecordHandler prevRecHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUIRecordLogger, | ||
173 | InstallLogModes.FatalExit | | ||
174 | InstallLogModes.Error | | ||
175 | InstallLogModes.Warning | | ||
176 | InstallLogModes.User | | ||
177 | InstallLogModes.Info | | ||
178 | InstallLogModes.ResolveSource | | ||
179 | InstallLogModes.OutOfDiskSpace | | ||
180 | InstallLogModes.ActionStart | | ||
181 | InstallLogModes.ActionData | | ||
182 | InstallLogModes.CommonData | | ||
183 | InstallLogModes.Progress | | ||
184 | InstallLogModes.Initialize | | ||
185 | InstallLogModes.Terminate | | ||
186 | InstallLogModes.ShowDialog); | ||
187 | Assert.IsNull(prevRecHandler, "Checking that returned previous UI record handler is null."); | ||
188 | |||
189 | try | ||
190 | { | ||
191 | Installer.InstallProduct(dbFile, "REMOVE=All"); | ||
192 | } | ||
193 | catch (Exception ex) { caughtEx = ex; } | ||
194 | Assert.IsNull(caughtEx, "Exception thrown while installing product: " + caughtEx); | ||
195 | |||
196 | Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed after removing."); | ||
197 | |||
198 | prevRecHandler = Installer.SetExternalUI(prevRecHandler, InstallLogModes.None); | ||
199 | Assert.AreEqual<ExternalUIRecordHandler>(WindowsInstallerTest.ExternalUIRecordLogger, prevRecHandler, "Checking that previously-set UI record handler is returned."); | ||
200 | } | ||
201 | |||
202 | public static MessageResult ExternalUILogger( | ||
203 | InstallMessage messageType, | ||
204 | string message, | ||
205 | MessageButtons buttons, | ||
206 | MessageIcon icon, | ||
207 | MessageDefaultButton defaultButton) | ||
208 | { | ||
209 | Console.WriteLine("{0}: {1}", messageType, message); | ||
210 | return MessageResult.None; | ||
211 | } | ||
212 | |||
213 | public static MessageResult ExternalUIRecordLogger( | ||
214 | InstallMessage messageType, | ||
215 | Record messageRecord, | ||
216 | MessageButtons buttons, | ||
217 | MessageIcon icon, | ||
218 | MessageDefaultButton defaultButton) | ||
219 | { | ||
220 | if (messageRecord != null) | ||
221 | { | ||
222 | if (messageRecord.FormatString.Length == 0 && messageRecord.FieldCount > 0) | ||
223 | { | ||
224 | messageRecord.FormatString = "1: [1] 2: [2] 3: [3] 4: [4] 5: [5]"; | ||
225 | } | ||
226 | Console.WriteLine("{0}: {1}", messageType, messageRecord.ToString()); | ||
227 | } | ||
228 | else | ||
229 | { | ||
230 | Console.WriteLine("{0}: (null)", messageType); | ||
231 | } | ||
232 | return MessageResult.None; | ||
233 | } | ||
234 | |||
235 | [TestMethod] | ||
236 | [Ignore] // Currently fails. | ||
237 | public void InstallerMessageResources() | ||
238 | { | ||
239 | string message1101 = Installer.GetErrorMessage(1101); | ||
240 | Console.WriteLine("Message 1101: " + message1101); | ||
241 | Assert.IsNotNull(message1101); | ||
242 | Assert.IsTrue(message1101.Contains("file")); | ||
243 | |||
244 | message1101 = Installer.GetErrorMessage(1101, CultureInfo.GetCultureInfo(1033)); | ||
245 | Console.WriteLine("Message 1101: " + message1101); | ||
246 | Assert.IsNotNull(message1101); | ||
247 | Assert.IsTrue(message1101.Contains("file")); | ||
248 | |||
249 | string message2621 = Installer.GetErrorMessage(2621); | ||
250 | Console.WriteLine("Message 2621: " + message2621); | ||
251 | Assert.IsNotNull(message2621); | ||
252 | Assert.IsTrue(message2621.Contains("DLL")); | ||
253 | |||
254 | string message3002 = Installer.GetErrorMessage(3002); | ||
255 | Console.WriteLine("Message 3002: " + message3002); | ||
256 | Assert.IsNotNull(message3002); | ||
257 | Assert.IsTrue(message3002.Contains("sequencing")); | ||
258 | } | ||
259 | |||
260 | [TestMethod] | ||
261 | public void EnumComponentQualifiers() | ||
262 | { | ||
263 | foreach (ComponentInstallation comp in ComponentInstallation.AllComponents) | ||
264 | { | ||
265 | bool qualifiers = false; | ||
266 | foreach (ComponentInstallation.Qualifier qualifier in comp.Qualifiers) | ||
267 | { | ||
268 | if (!qualifiers) | ||
269 | { | ||
270 | Console.WriteLine(comp.Path); | ||
271 | qualifiers = true; | ||
272 | } | ||
273 | |||
274 | Console.WriteLine("\t{0}: {1}", qualifier.QualifierCode, qualifier.Data); | ||
275 | } | ||
276 | } | ||
277 | } | ||
278 | |||
279 | [TestMethod] | ||
280 | public void DeleteRecord() | ||
281 | { | ||
282 | string dbFile = "DeleteRecord.msi"; | ||
283 | |||
284 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
285 | { | ||
286 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
287 | WindowsInstallerUtils.CreateTestProduct(db); | ||
288 | |||
289 | string query = "SELECT `Property`, `Value` FROM `Property` WHERE `Property` = 'UpgradeCode'"; | ||
290 | |||
291 | using (View view = db.OpenView(query)) | ||
292 | { | ||
293 | view.Execute(); | ||
294 | |||
295 | Record rec = view.Fetch(); | ||
296 | |||
297 | Console.WriteLine("Calling ToString() : " + rec); | ||
298 | |||
299 | view.Delete(rec); | ||
300 | } | ||
301 | |||
302 | Assert.AreEqual(0, db.ExecuteStringQuery(query).Count); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | [TestMethod] | ||
307 | public void InsertRecordThenTryFormatString() | ||
308 | { | ||
309 | string dbFile = "InsertRecordThenTryFormatString.msi"; | ||
310 | |||
311 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
312 | { | ||
313 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
314 | WindowsInstallerUtils.CreateTestProduct(db); | ||
315 | |||
316 | string parameterFormatString = "[1]"; | ||
317 | string[] properties = new string[] | ||
318 | { | ||
319 | "SonGoku", "Over 9000", | ||
320 | }; | ||
321 | |||
322 | string query = "SELECT `Property`, `Value` FROM `Property`"; | ||
323 | |||
324 | using (View view = db.OpenView(query)) | ||
325 | { | ||
326 | using (Record rec = new Record(2)) | ||
327 | { | ||
328 | rec[1] = properties[0]; | ||
329 | rec[2] = properties[1]; | ||
330 | rec.FormatString = parameterFormatString; | ||
331 | Console.WriteLine("Format String before inserting: " + rec.FormatString); | ||
332 | view.Insert(rec); | ||
333 | |||
334 | Console.WriteLine("Format String after inserting: " + rec.FormatString); | ||
335 | // After inserting, the format string is invalid. | ||
336 | Assert.AreEqual(String.Empty, rec.ToString()); | ||
337 | |||
338 | // Setting the format string manually makes it valid again. | ||
339 | rec.FormatString = parameterFormatString; | ||
340 | Assert.AreEqual(properties[0], rec.ToString()); | ||
341 | } | ||
342 | } | ||
343 | } | ||
344 | } | ||
345 | |||
346 | [TestMethod] | ||
347 | public void SeekRecordThenTryFormatString() | ||
348 | { | ||
349 | string dbFile = "SeekRecordThenTryFormatString.msi"; | ||
350 | |||
351 | using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) | ||
352 | { | ||
353 | WindowsInstallerUtils.InitializeProductDatabase(db); | ||
354 | WindowsInstallerUtils.CreateTestProduct(db); | ||
355 | |||
356 | string parameterFormatString = "[1]"; | ||
357 | string[] properties = new string[] | ||
358 | { | ||
359 | "SonGoku", "Over 9000", | ||
360 | }; | ||
361 | |||
362 | string query = "SELECT `Property`, `Value` FROM `Property`"; | ||
363 | |||
364 | using (View view = db.OpenView(query)) | ||
365 | { | ||
366 | using (Record rec = new Record(2)) | ||
367 | { | ||
368 | rec[1] = properties[0]; | ||
369 | rec[2] = properties[1]; | ||
370 | rec.FormatString = parameterFormatString; | ||
371 | Console.WriteLine("Record fields before seeking: " + rec[0] + " " + rec[1] + " " + rec[2]); | ||
372 | view.Seek(rec); | ||
373 | |||
374 | //TODO: Why does view.Seek remove the record fields? | ||
375 | Console.WriteLine("Record fields after seeking: " + rec[0] + " " + rec[1] + " " + rec[2]); | ||
376 | // After inserting, the format string is invalid. | ||
377 | Assert.AreEqual(String.Empty, rec.ToString()); | ||
378 | } | ||
379 | } | ||
380 | } | ||
381 | } | ||
382 | |||
383 | [TestMethod] | ||
384 | public void TestToString() | ||
385 | { | ||
386 | string defaultString = "1: "; | ||
387 | string vegetaShout = "It's OVER 9000!!"; | ||
388 | string gokuPowerLevel = "9001"; | ||
389 | string nappaInquiry = "Vegeta, what's the Scouter say about his power level?"; | ||
390 | string parameterFormatString = "[1]"; | ||
391 | |||
392 | Record rec = new Record(1); | ||
393 | Assert.AreEqual(defaultString, rec.ToString(), "Testing default FormatString"); | ||
394 | |||
395 | rec.FormatString = String.Empty; | ||
396 | Assert.AreEqual(defaultString, rec.ToString(), "Explicitly set the FormatString to the empty string."); | ||
397 | |||
398 | rec.FormatString = vegetaShout; | ||
399 | Assert.AreEqual(vegetaShout, rec.ToString(), "Testing text only (empty FormatString)"); | ||
400 | |||
401 | rec.FormatString = gokuPowerLevel; | ||
402 | Assert.AreEqual(gokuPowerLevel, rec.ToString(), "Testing numbers only from a record that wasn't fetched."); | ||
403 | |||
404 | Record rec2 = new Record(nappaInquiry); | ||
405 | rec2.FormatString = parameterFormatString; | ||
406 | Assert.AreEqual(nappaInquiry, rec2.ToString(), "Testing text with a FormatString set."); | ||
407 | } | ||
408 | } | ||
409 | } | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTransactions.cs b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTransactions.cs new file mode 100644 index 00000000..3bdf5acd --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTransactions.cs | |||
@@ -0,0 +1,161 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | namespace WixToolset.Dtf.Test | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using System.Windows.Forms; | ||
8 | using System.Globalization; | ||
9 | using System.Collections.Generic; | ||
10 | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
11 | using WixToolset.Dtf.WindowsInstaller; | ||
12 | using View = WixToolset.Dtf.WindowsInstaller.View; | ||
13 | |||
14 | [TestClass] | ||
15 | public class WindowsInstallerTransactions | ||
16 | { | ||
17 | [TestInitialize()] | ||
18 | public void Initialize() | ||
19 | { | ||
20 | } | ||
21 | |||
22 | [TestCleanup()] | ||
23 | public void Cleanup() | ||
24 | { | ||
25 | } | ||
26 | |||
27 | [TestMethod] | ||
28 | [Ignore] // Requires elevation. | ||
29 | public void InstallerTransactTwoProducts() | ||
30 | { | ||
31 | string dbFile1 = "InstallerTransactProduct1.msi"; | ||
32 | string dbFile2 = "InstallerTransactProduct2.msi"; | ||
33 | string productCode1; | ||
34 | string productCode2; | ||
35 | |||
36 | using (Database db1 = new Database(dbFile1, DatabaseOpenMode.CreateDirect)) | ||
37 | { | ||
38 | WindowsInstallerUtils.InitializeProductDatabase(db1); | ||
39 | WindowsInstallerUtils.CreateTestProduct(db1); | ||
40 | |||
41 | productCode1 = db1.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0]; | ||
42 | |||
43 | db1.Commit(); | ||
44 | } | ||
45 | |||
46 | using (Database db2 = new Database(dbFile2, DatabaseOpenMode.CreateDirect)) | ||
47 | { | ||
48 | WindowsInstallerUtils.InitializeProductDatabase(db2); | ||
49 | WindowsInstallerUtils.CreateTestProduct(db2); | ||
50 | |||
51 | productCode2 = db2.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0]; | ||
52 | |||
53 | db2.Commit(); | ||
54 | } | ||
55 | |||
56 | ProductInstallation installation1 = new ProductInstallation(productCode1); | ||
57 | ProductInstallation installation2 = new ProductInstallation(productCode2); | ||
58 | Assert.IsFalse(installation1.IsInstalled, "Checking that product 1 is not installed before starting."); | ||
59 | Assert.IsFalse(installation2.IsInstalled, "Checking that product 2 is not installed before starting."); | ||
60 | |||
61 | Installer.SetInternalUI(InstallUIOptions.Silent); | ||
62 | ExternalUIHandler prevHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUILogger, | ||
63 | InstallLogModes.FatalExit | | ||
64 | InstallLogModes.Error | | ||
65 | InstallLogModes.Warning | | ||
66 | InstallLogModes.User | | ||
67 | InstallLogModes.Info | | ||
68 | InstallLogModes.ResolveSource | | ||
69 | InstallLogModes.OutOfDiskSpace | | ||
70 | InstallLogModes.ActionStart | | ||
71 | InstallLogModes.ActionData | | ||
72 | InstallLogModes.CommonData | | ||
73 | InstallLogModes.Progress | | ||
74 | InstallLogModes.Initialize | | ||
75 | InstallLogModes.Terminate | | ||
76 | InstallLogModes.ShowDialog); | ||
77 | Assert.IsNull(prevHandler, "Checking that returned previous UI handler is null."); | ||
78 | |||
79 | Transaction transaction = new Transaction("TestInstallTransaction", TransactionAttributes.None); | ||
80 | |||
81 | Exception caughtEx = null; | ||
82 | try | ||
83 | { | ||
84 | Installer.InstallProduct(dbFile1, String.Empty); | ||
85 | } | ||
86 | catch (Exception ex) { caughtEx = ex; } | ||
87 | Assert.IsNull(caughtEx, "Exception thrown while installing product 1: " + caughtEx); | ||
88 | |||
89 | Console.WriteLine(); | ||
90 | Console.WriteLine("==================================================================="); | ||
91 | Console.WriteLine(); | ||
92 | |||
93 | try | ||
94 | { | ||
95 | Installer.InstallProduct(dbFile2, String.Empty); | ||
96 | } | ||
97 | catch (Exception ex) { caughtEx = ex; } | ||
98 | Assert.IsNull(caughtEx, "Exception thrown while installing product 2: " + caughtEx); | ||
99 | |||
100 | transaction.Commit(); | ||
101 | transaction.Close(); | ||
102 | |||
103 | prevHandler = Installer.SetExternalUI(prevHandler, InstallLogModes.None); | ||
104 | Assert.AreEqual<ExternalUIHandler>(WindowsInstallerTest.ExternalUILogger, prevHandler, "Checking that previously-set UI handler is returned."); | ||
105 | |||
106 | Assert.IsTrue(installation1.IsInstalled, "Checking that product 1 is installed."); | ||
107 | Assert.IsTrue(installation2.IsInstalled, "Checking that product 2 is installed."); | ||
108 | |||
109 | Console.WriteLine(); | ||
110 | Console.WriteLine(); | ||
111 | Console.WriteLine(); | ||
112 | Console.WriteLine("==================================================================="); | ||
113 | Console.WriteLine("==================================================================="); | ||
114 | Console.WriteLine(); | ||
115 | Console.WriteLine(); | ||
116 | Console.WriteLine(); | ||
117 | |||
118 | ExternalUIRecordHandler prevRecHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUIRecordLogger, | ||
119 | InstallLogModes.FatalExit | | ||
120 | InstallLogModes.Error | | ||
121 | InstallLogModes.Warning | | ||
122 | InstallLogModes.User | | ||
123 | InstallLogModes.Info | | ||
124 | InstallLogModes.ResolveSource | | ||
125 | InstallLogModes.OutOfDiskSpace | | ||
126 | InstallLogModes.ActionStart | | ||
127 | InstallLogModes.ActionData | | ||
128 | InstallLogModes.CommonData | | ||
129 | InstallLogModes.Progress | | ||
130 | InstallLogModes.Initialize | | ||
131 | InstallLogModes.Terminate | | ||
132 | InstallLogModes.ShowDialog); | ||
133 | Assert.IsNull(prevRecHandler, "Checking that returned previous UI record handler is null."); | ||
134 | |||
135 | transaction = new Transaction("TestUninstallTransaction", TransactionAttributes.None); | ||
136 | |||
137 | try | ||
138 | { | ||
139 | Installer.InstallProduct(dbFile1, "REMOVE=All"); | ||
140 | } | ||
141 | catch (Exception ex) { caughtEx = ex; } | ||
142 | Assert.IsNull(caughtEx, "Exception thrown while removing product 1: " + caughtEx); | ||
143 | |||
144 | try | ||
145 | { | ||
146 | Installer.InstallProduct(dbFile2, "REMOVE=All"); | ||
147 | } | ||
148 | catch (Exception ex) { caughtEx = ex; } | ||
149 | Assert.IsNull(caughtEx, "Exception thrown while removing product 2: " + caughtEx); | ||
150 | |||
151 | transaction.Commit(); | ||
152 | transaction.Close(); | ||
153 | |||
154 | Assert.IsFalse(installation1.IsInstalled, "Checking that product 1 is not installed after removing."); | ||
155 | Assert.IsFalse(installation2.IsInstalled, "Checking that product 2 is not installed after removing."); | ||
156 | |||
157 | prevRecHandler = Installer.SetExternalUI(prevRecHandler, InstallLogModes.None); | ||
158 | Assert.AreEqual<ExternalUIRecordHandler>(WindowsInstallerTest.ExternalUIRecordLogger, prevRecHandler, "Checking that previously-set UI record handler is returned."); | ||
159 | } | ||
160 | } | ||
161 | } | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerUtils.cs b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerUtils.cs new file mode 100644 index 00000000..644f1988 --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerUtils.cs | |||
@@ -0,0 +1,174 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | namespace WixToolset.Dtf.Test | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections.Generic; | ||
7 | using System.Text; | ||
8 | using WixToolset.Dtf.WindowsInstaller; | ||
9 | |||
10 | public class WindowsInstallerUtils | ||
11 | { | ||
12 | public static void InitializeProductDatabase(Database db) | ||
13 | { | ||
14 | InitializeProductDatabase(db, false); | ||
15 | } | ||
16 | |||
17 | public static void InitializeProductDatabase(Database db, bool sixtyFourBit) | ||
18 | { | ||
19 | db.SummaryInfo.CodePage = (short) Encoding.Default.CodePage; | ||
20 | db.SummaryInfo.Title = "Windows Installer Test"; | ||
21 | db.SummaryInfo.Subject = db.SummaryInfo.Title; | ||
22 | db.SummaryInfo.Author = typeof(WindowsInstallerUtils).Assembly.FullName; | ||
23 | db.SummaryInfo.CreatingApp = db.SummaryInfo.Author; | ||
24 | db.SummaryInfo.Comments = typeof(WindowsInstallerUtils).FullName + ".CreateBasicDatabase()"; | ||
25 | db.SummaryInfo.Keywords = "Installer,MSI,Database"; | ||
26 | db.SummaryInfo.PageCount = 300; | ||
27 | db.SummaryInfo.WordCount = 0; | ||
28 | db.SummaryInfo.RevisionNumber = Guid.NewGuid().ToString("B").ToUpper(); | ||
29 | db.SummaryInfo.Template = (sixtyFourBit ? "x64" : "Intel") + ";0"; | ||
30 | |||
31 | foreach (TableInfo tableInfo in Schema.Tables) | ||
32 | { | ||
33 | db.Execute(tableInfo.SqlCreateString); | ||
34 | } | ||
35 | |||
36 | db.Execute("INSERT INTO `Directory` (`Directory`, `DefaultDir`) VALUES ('TARGETDIR', 'SourceDir')"); | ||
37 | db.Execute("INSERT INTO `Directory` (`Directory`, `Directory_Parent`, `DefaultDir`) VALUES ('ProgramFilesFolder', 'TARGETDIR', '.')"); | ||
38 | |||
39 | foreach (Action action in Sequence.InstallExecute) | ||
40 | { | ||
41 | db.Execute("INSERT INTO `InstallExecuteSequence` (`Action`, `Sequence`) VALUES ('{0}', {1})", | ||
42 | action.Name, action.Sequence); | ||
43 | } | ||
44 | } | ||
45 | |||
46 | public const string UpgradeCode = "{05955FE8-005F-4695-A81F-D559338065BB}"; | ||
47 | |||
48 | public static void CreateTestProduct(Database db) | ||
49 | { | ||
50 | Guid productGuid = Guid.NewGuid(); | ||
51 | |||
52 | string[] properties = new string[] | ||
53 | { | ||
54 | "ProductCode", productGuid.ToString("B").ToUpper(), | ||
55 | "UpgradeCode", UpgradeCode, | ||
56 | "ProductName", "Windows Installer Test Product " + productGuid.ToString("P").ToUpper(), | ||
57 | "ProductVersion", "1.0.0.0000", | ||
58 | }; | ||
59 | |||
60 | using (View view = db.OpenView("INSERT INTO `Property` (`Property`, `Value`) VALUES (?, ?)")) | ||
61 | { | ||
62 | using (Record rec = new Record(2)) | ||
63 | { | ||
64 | for (int i = 0; i < properties.Length; i += 2) | ||
65 | { | ||
66 | rec[1] = properties[i]; | ||
67 | rec[2] = properties[i + 1]; | ||
68 | view.Execute(rec); | ||
69 | } | ||
70 | } | ||
71 | } | ||
72 | |||
73 | int randomId = new Random().Next(10000); | ||
74 | string productDir = "TestDir" + randomId; | ||
75 | db.Execute( | ||
76 | "INSERT INTO `Directory` (`Directory`, `Directory_Parent`, `DefaultDir`) " + | ||
77 | "VALUES ('TestDir', 'ProgramFilesFolder', 'TestDir|{0}:.')", productDir); | ||
78 | |||
79 | string compId = Guid.NewGuid().ToString("B").ToUpper(); | ||
80 | db.Execute( | ||
81 | "INSERT INTO `Component` " + | ||
82 | "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `KeyPath`) " + | ||
83 | "VALUES ('{0}', '{1}', '{2}', {3}, '{4}')", | ||
84 | "TestRegComp1", | ||
85 | compId, | ||
86 | "TestDir", | ||
87 | (int) ComponentAttributes.RegistryKeyPath, | ||
88 | "TestReg1"); | ||
89 | |||
90 | string productReg = "TestReg" + randomId; | ||
91 | db.Execute( | ||
92 | "INSERT INTO `Registry` (`Registry`, `Root`, `Key`, `Component_`) VALUES ('{0}', {1}, '{2}', '{3}')", | ||
93 | "TestReg1", | ||
94 | -1, | ||
95 | @"Software\Microsoft\Windows Installer Test\" + productReg, | ||
96 | "TestRegComp1"); | ||
97 | |||
98 | db.Execute( | ||
99 | "INSERT INTO `Feature` (`Feature`, `Title`, `Level`, `Attributes`) VALUES ('{0}', '{1}', {2}, {3})", | ||
100 | "TestFeature1", | ||
101 | "Test Feature 1", | ||
102 | 1, | ||
103 | (int) FeatureAttributes.None); | ||
104 | |||
105 | db.Execute( | ||
106 | "INSERT INTO `FeatureComponents` (`Feature_`, `Component_`) VALUES ('{0}', '{1}')", | ||
107 | "TestFeature1", | ||
108 | "TestRegComp1"); | ||
109 | } | ||
110 | |||
111 | public static void AddFeature(Database db, string featureName) | ||
112 | { | ||
113 | db.Execute( | ||
114 | "INSERT INTO `Feature` (`Feature`, `Title`, `Level`, `Attributes`) VALUES ('{0}', '{1}', {2}, {3})", | ||
115 | featureName, | ||
116 | featureName, | ||
117 | 1, | ||
118 | (int) FeatureAttributes.None); | ||
119 | } | ||
120 | |||
121 | public static void AddRegistryComponent(Database db, | ||
122 | string featureName, string compName, string compId, | ||
123 | string keyName, string keyValueName, string value) | ||
124 | { | ||
125 | db.Execute( | ||
126 | "INSERT INTO `Component` " + | ||
127 | "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `KeyPath`) " + | ||
128 | "VALUES ('{0}', '{1}', '{2}', {3}, '{4}')", | ||
129 | compName, | ||
130 | compId, | ||
131 | "TestDir", | ||
132 | (int) ComponentAttributes.RegistryKeyPath, | ||
133 | compName + "Reg1"); | ||
134 | db.Execute( | ||
135 | "INSERT INTO `Registry` (`Registry`, `Root`, `Key`, `Name`, `Value`, `Component_`) VALUES ('{0}', {1}, '{2}', '{3}', '{4}', '{5}')", | ||
136 | compName + "Reg1", | ||
137 | -1, | ||
138 | @"Software\Microsoft\Windows Installer Test\" + keyName, | ||
139 | keyValueName, | ||
140 | value, | ||
141 | compName); | ||
142 | db.Execute( | ||
143 | "INSERT INTO `FeatureComponents` (`Feature_`, `Component_`) VALUES ('{0}', '{1}')", | ||
144 | featureName, | ||
145 | compName); | ||
146 | } | ||
147 | |||
148 | public static void AddFileComponent(Database db, | ||
149 | string featureName, string compName, string compId, | ||
150 | string fileKey, string fileName) | ||
151 | { | ||
152 | db.Execute( | ||
153 | "INSERT INTO `Component` " + | ||
154 | "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `KeyPath`) " + | ||
155 | "VALUES ('{0}', '{1}', '{2}', {3}, '{4}')", | ||
156 | compName, | ||
157 | compId, | ||
158 | "TestDir", | ||
159 | (int) ComponentAttributes.None, | ||
160 | fileKey); | ||
161 | db.Execute( | ||
162 | "INSERT INTO `File` " + | ||
163 | "(`File`, `Component_`, `FileName`, `FileSize`, `Attributes`, `Sequence`) " + | ||
164 | "VALUES ('{0}', '{1}', '{2}', 1, 0, 1)", | ||
165 | fileKey, | ||
166 | compName, | ||
167 | fileName); | ||
168 | db.Execute( | ||
169 | "INSERT INTO `FeatureComponents` (`Feature_`, `Component_`) VALUES ('{0}', '{1}')", | ||
170 | featureName, | ||
171 | compName); | ||
172 | } | ||
173 | } | ||
174 | } | ||
diff --git a/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WixToolsetTests.Dtf.WindowsInstaller.csproj b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WixToolsetTests.Dtf.WindowsInstaller.csproj new file mode 100644 index 00000000..eaa273ed --- /dev/null +++ b/src/dtf/test/WixToolsetTests.Dtf.WindowsInstaller/WixToolsetTests.Dtf.WindowsInstaller.csproj | |||
@@ -0,0 +1,39 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
3 | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="Current"> | ||
4 | <PropertyGroup> | ||
5 | <ProjectGuid>{16F5202F-9276-4166-975C-C9654BAF8012}</ProjectGuid> | ||
6 | <OutputType>Library</OutputType> | ||
7 | <RootNamespace>WixToolsetTests.Dtf</RootNamespace> | ||
8 | <AssemblyName>WixToolsetTests.Dtf.WindowsInstaller</AssemblyName> | ||
9 | <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||
10 | <CreateDocumentation>false</CreateDocumentation> | ||
11 | <SignOutput>false</SignOutput> | ||
12 | <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> | ||
13 | </PropertyGroup> | ||
14 | |||
15 | <ItemGroup> | ||
16 | <Compile Include="EmbeddedExternalUI.cs" /> | ||
17 | <Compile Include="Schema.cs" /> | ||
18 | <Compile Include="WindowsInstallerTest.cs" /> | ||
19 | <Compile Include="WindowsInstallerTransactions.cs" /> | ||
20 | <Compile Include="WindowsInstallerUtils.cs" /> | ||
21 | </ItemGroup> | ||
22 | |||
23 | <ItemGroup> | ||
24 | <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | ||
25 | <Reference Include="System" /> | ||
26 | <Reference Include="System.Windows.Forms" /> | ||
27 | <Reference Include="System.Xml" /> | ||
28 | </ItemGroup> | ||
29 | |||
30 | <ItemGroup> | ||
31 | <ProjectReference Include="..\..\WixToolset.Dtf.WindowsInstaller\WixToolset.Dtf.WindowsInstaller.csproj"> | ||
32 | <Project>{85225597-5121-4361-8332-4E3246D5BBF5}</Project> | ||
33 | <Name>WixToolset.Dtf.WindowsInstaller</Name> | ||
34 | </ProjectReference> | ||
35 | </ItemGroup> | ||
36 | |||
37 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> | ||
38 | <Target Name="Pack" DependsOnTargets="Build" /> | ||
39 | </Project> | ||