Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Services.Deployment/3.3/Tests/PluginStoreTest.cs @ 11297

Last change on this file since 11297 was 11171, checked in by ascheibe, 10 years ago

#2115 merged r11170 (copyright update) into trunk

File size: 18.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Diagnostics;
25using System.Linq;
26using Microsoft.VisualStudio.TestTools.UnitTesting;
27
28namespace HeuristicLab.Services.Deployment.Test {
29
30
31  /// <summary>
32  ///This is a test class for PluginStoreTest and is intended
33  ///to contain all PluginStoreTest Unit Tests
34  ///</summary>
35  [TestClass()]
36  public class PluginStoreTest {
37
38    private System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
39    private TestContext testContextInstance;
40
41    /// <summary>
42    ///Gets or sets the test context which provides
43    ///information about and functionality for the current test run.
44    ///</summary>
45    public TestContext TestContext {
46      get {
47        return testContextInstance;
48      }
49      set {
50        testContextInstance = value;
51      }
52    }
53
54    #region Additional test attributes
55    //
56    //You can use the following additional attributes as you write your tests:
57    //
58    //Use ClassInitialize to run code before running the first test in the class
59    //[ClassInitialize()]
60    //public static void MyClassInitialize(TestContext testContext)
61    //{
62    //}
63    //
64    //Use ClassCleanup to run code after all tests in a class have run
65    //[ClassCleanup()]
66    //public static void MyClassCleanup()
67    //{
68    //}
69    //
70    //Use TestInitialize to run code before running each test
71    //[TestInitialize()]
72    //public void MyTestInitialize()
73    //{
74    //}
75    //
76    //Use TestCleanup to run code after each test has run
77    //[TestCleanup()]
78    //public void MyTestCleanup()
79    //{
80    //}
81    //
82    #endregion
83
84
85    /// <summary>
86    ///A test for PluginFile
87    ///</summary>
88    [TestMethod()]
89    public void PluginFileTest() {
90      PluginStore target = new PluginStore();
91      #region insert and retrieve a plugin file
92      int oldCount = target.Plugins.Count();
93      // store a new entry in the db
94      string name = RandomName();
95      target.Persist(new PluginDescription(name, new Version(0, 1)), enc.GetBytes("Zipped " + name));
96      int newCount = target.Plugins.Count();
97      // make sure the new entry was added to the db
98      Assert.AreEqual(oldCount + 1, newCount);
99
100      // get matching description from db and try to retrieve the stored file
101      PluginDescription pluginDescription = target.Plugins.Where(p => p.Name == name).Single();
102      byte[] expected = enc.GetBytes("Zipped " + name);
103      byte[] actual = target.PluginFile(pluginDescription);
104      // check retrieved file
105      Assert.AreEqual(expected.Length, actual.Length);
106      for (int i = 0; i < expected.Length; i++) {
107        Assert.AreEqual(expected[i], actual[i]);
108      }
109      #endregion
110    }
111
112    /// <summary>
113    ///A test for Persist
114    ///</summary>
115    [TestMethod()]
116    public void PersistPluginTest() {
117      var vers01 = new Version(0, 1);
118      PluginStore target = new PluginStore();
119
120      #region persist single plugin without dependencies
121      {
122        string name = RandomName();
123        int oldCount = target.Plugins.Count();
124        PluginDescription pluginDescription = new PluginDescription(name, vers01);
125        byte[] pluginPackage = enc.GetBytes("Zipped " + name);
126        target.Persist(pluginDescription, pluginPackage);
127        int newCount = target.Plugins.Count();
128        Assert.AreEqual(oldCount + 1, newCount);
129      }
130      #endregion
131
132      #region persist a product with same name and version as an existent product
133      {
134        string name = RandomName();
135        int oldCount = target.Plugins.Count();
136        PluginDescription pluginDescription = new PluginDescription(name, vers01);
137        byte[] pluginPackage = enc.GetBytes("Zipped " + name);
138        target.Persist(pluginDescription, pluginPackage);
139        int newCount = target.Plugins.Count();
140        Assert.AreEqual(oldCount + 1, newCount);
141
142        // insert same name and version
143        oldCount = target.Plugins.Count();
144        pluginDescription = new PluginDescription(name, vers01);
145        pluginPackage = enc.GetBytes("Zipped " + name);
146        target.Persist(pluginDescription, pluginPackage);
147        newCount = target.Plugins.Count();
148        // make sure old entry was updated
149        Assert.AreEqual(oldCount, newCount);
150
151        // insert new with different version
152        oldCount = target.Plugins.Count();
153        pluginDescription = new PluginDescription(name, new Version(0, 2));
154        pluginPackage = enc.GetBytes("Zipped " + name);
155        target.Persist(pluginDescription, pluginPackage);
156        newCount = target.Plugins.Count();
157        // make sure a new entry was created
158        Assert.AreEqual(oldCount + 1, newCount);
159      }
160      #endregion
161
162      #region persist a plugin with an already persisted dependency
163      {
164        string name = RandomName();
165        PluginDescription dependency = new PluginDescription(name, vers01);
166        // insert dependency first
167        target.Persist(dependency, enc.GetBytes("Zipped " + name));
168
169        // persist another plugin that has a dependency on the first plugin
170        string name2 = RandomName();
171        int oldCount = target.Plugins.Count();
172
173        PluginDescription newEntity = new PluginDescription(name2, vers01, Enumerable.Repeat(dependency, 1));
174        byte[] newEntityPackage = enc.GetBytes("Zipped " + name2);
175        target.Persist(newEntity, newEntityPackage);
176        int newCount = target.Plugins.Count();
177        Assert.AreEqual(oldCount + 1, newCount); // only one new plugin should be added
178
179        // retrieve second plugin and check dependencies
180        newEntity = target.Plugins.Where(p => p.Name == name2).Single();
181        Assert.AreEqual(newEntity.Dependencies.Count(), 1);
182        Assert.AreEqual(newEntity.Dependencies.First().Name, name);
183      }
184      #endregion
185
186      #region try to persist a new  plugin with a non-existant dependency and check the expected exception
187      {
188        // try to persist a new plugin with a non-existant dependency
189        try {
190          string pluginName = RandomName();
191          string dependencyName = RandomName();
192          var dependency = new PluginDescription(dependencyName, vers01);
193          var newEntity = new PluginDescription(pluginName, vers01, Enumerable.Repeat(dependency, 1));
194          target.Persist(newEntity, enc.GetBytes("Zipped " + pluginName));
195          Assert.Fail("persist should fail with ArgumentException");
196        }
197        catch (ArgumentException) {
198          // this is expected
199          Assert.IsTrue(true, "expected exception");
200        }
201      }
202      #endregion
203
204      #region update the plugin file of an existing plugin
205      {
206        // insert new plugin
207        string pluginName = RandomName();
208        var newPlugin = new PluginDescription(pluginName, vers01);
209        target.Persist(newPlugin, enc.GetBytes("Zipped " + pluginName));
210
211        // update the plugin file
212        byte[] expected = enc.GetBytes("Zipped2 " + pluginName);
213        target.Persist(newPlugin, expected);
214        // check if the updated file is returned
215        byte[] actual = target.PluginFile(newPlugin);
216        // check retrieved file
217        Assert.AreEqual(expected.Length, actual.Length);
218        for (int i = 0; i < expected.Length; i++) {
219          Assert.AreEqual(expected[i], actual[i]);
220        }
221      }
222      #endregion
223
224      #region update the dependencies of an existing plugin
225      {
226        string dependency1Name = RandomName();
227        var newDependency1 = new PluginDescription(dependency1Name, vers01);
228        target.Persist(newDependency1, enc.GetBytes("Zipped " + dependency1Name));
229
230        string pluginName = RandomName();
231        var newPlugin = new PluginDescription(pluginName, vers01, Enumerable.Repeat(newDependency1, 1));
232        target.Persist(newPlugin, enc.GetBytes("Zipped " + pluginName));
233
234        // retrieve plugin
235        var dbPlugin = target.Plugins.Where(p => p.Name == pluginName).Single();
236        Assert.AreEqual(dbPlugin.Dependencies.Count(), 1);
237        Assert.AreEqual(dbPlugin.Dependencies.First().Name, dependency1Name);
238
239        // change dependencies
240        string dependency2Name = RandomName();
241        var newDependency2 = new PluginDescription(dependency2Name, vers01);
242        target.Persist(newDependency2, enc.GetBytes("Zipped " + pluginName));
243
244        newPlugin = new PluginDescription(pluginName, vers01, new PluginDescription[] { newDependency1, newDependency2 });
245        target.Persist(newPlugin, enc.GetBytes("Zipped " + pluginName));
246        // retrieve plugin
247        dbPlugin = target.Plugins.Where(p => p.Name == pluginName).Single();
248        Assert.AreEqual(dbPlugin.Dependencies.Count(), 2);
249      }
250      #endregion
251
252      #region try to insert a plugin that references the same dependency twice and check if the correct exception is thrown
253      {
254        string depName = RandomName();
255        var depPlugin = new PluginDescription(depName, vers01);
256        target.Persist(depPlugin, enc.GetBytes("Zipped " + depName));
257
258        // insert new plugin
259        string pluginName = RandomName();
260        var plugin = new PluginDescription(pluginName, vers01, new PluginDescription[] { depPlugin, depPlugin });
261        try {
262          target.Persist(plugin, enc.GetBytes("Zipped " + depName));
263          Assert.Fail("Expected ArgumentException");
264        }
265        catch (ArgumentException) {
266          Assert.IsTrue(true, "Exception thrown as expected");
267        }
268      }
269      #endregion
270
271      #region try to insert a plugin that with a cyclic reference
272      {
273        string depName = RandomName();
274        var depPlugin = new PluginDescription(depName, vers01);
275        target.Persist(depPlugin, enc.GetBytes("Zipped " + depName));
276
277        // update the plugin so that it has a dependency on itself
278        var plugin = new PluginDescription(depName, vers01, new PluginDescription[] { depPlugin });
279        try {
280          target.Persist(plugin, enc.GetBytes("Zipped " + depName));
281          Assert.Fail("Expected ArgumentException");
282        }
283        catch (ArgumentException) {
284          Assert.IsTrue(true, "Exception thrown as expected");
285        }
286      }
287      #endregion
288
289    }
290
291    /// <summary>
292    ///A test for Persist
293    ///</summary>
294    [TestMethod()]
295    public void PersistProductTest() {
296      Version vers01 = new Version(0, 1);
297      PluginStore target = new PluginStore();
298
299      #region persist a product without plugins to the db
300      {
301        string prodName = RandomName();
302        int oldCount = target.Products.Count();
303        ProductDescription product = new ProductDescription(prodName, vers01);
304        target.Persist(product);
305        int newCount = target.Products.Count();
306        Assert.AreEqual(oldCount + 1, newCount);
307      }
308      #endregion
309
310      #region persist a product with the same name and version as an existant product
311      {
312        string prodName = RandomName();
313        int oldCount = target.Products.Count();
314        ProductDescription product = new ProductDescription(prodName, vers01);
315        target.Persist(product);
316        int newCount = target.Products.Count();
317        Assert.AreEqual(oldCount + 1, newCount);
318
319        // write a product with same name and version
320        oldCount = target.Products.Count();
321        product = new ProductDescription(prodName, vers01);
322        target.Persist(product);
323        newCount = target.Products.Count();
324
325        // make sure that the old entry was updated
326        Assert.AreEqual(oldCount, newCount);
327
328        // write a product with same name and different version
329        oldCount = target.Products.Count();
330        product = new ProductDescription(prodName, new Version(0, 2));
331        target.Persist(product);
332        newCount = target.Products.Count();
333
334        // make sure that a new entry was created
335        Assert.AreEqual(oldCount + 1, newCount);
336      }
337      #endregion
338
339      #region try to persist a product referencing an non-existant plugin and check the expected exception
340      {
341        // try to persist a product referencing a non-existant plugin
342        string prodName = RandomName();
343        string pluginName = RandomName();
344        var plugin = new PluginDescription(pluginName, vers01);
345        var product = new ProductDescription(prodName, vers01, Enumerable.Repeat(plugin, 1));
346        try {
347          target.Persist(product);
348          Assert.Fail("persist should fail with ArgumentException");
349        }
350        catch (ArgumentException) {
351          // this is expected
352          Assert.IsTrue(true, "expected exception");
353        }
354      }
355      #endregion
356
357      #region persist a product with a single plugin reference
358      {
359        string prodName = RandomName();
360        string pluginName = RandomName();
361        var plugin = new PluginDescription(pluginName, vers01);
362        var product = new ProductDescription(prodName, vers01, Enumerable.Repeat(plugin, 1));
363
364        // persist the plugin first
365        int oldCount = target.Products.Count();
366        target.Persist(plugin, enc.GetBytes("Zipped " + plugin.Name));
367        target.Persist(product);
368        int newCount = target.Products.Count();
369        // make sure the store went through
370        Assert.AreEqual(oldCount + 1, newCount);
371        // retrieve the product and check if the plugin list was stored/retrieved correctly
372        var dbProd = target.Products.Where(p => p.Name == prodName).Single();
373        Assert.AreEqual(dbProd.Plugins.Count(), 1);
374        Assert.AreEqual(dbProd.Plugins.First().Name, pluginName);
375      }
376      #endregion
377
378      #region update the plugin list of an existing product
379      {
380        string prodName = RandomName();
381        string plugin1Name = RandomName();
382        var plugin1 = new PluginDescription(plugin1Name, vers01);
383        var product = new ProductDescription(prodName, vers01, Enumerable.Repeat(plugin1, 1));
384
385        // persist the plugin first
386        int oldCount = target.Products.Count();
387        target.Persist(plugin1, enc.GetBytes("Zipped " + plugin1.Name));
388        target.Persist(product);
389        int newCount = target.Products.Count();
390        // make sure the store went through
391        Assert.AreEqual(oldCount + 1, newCount);
392
393        var plugin2Name = RandomName();
394        var plugin2 = new PluginDescription(plugin2Name, vers01);
395        target.Persist(plugin2, enc.GetBytes("Zipped " + plugin2.Name));
396        product = new ProductDescription(prodName, vers01, new PluginDescription[] { plugin1, plugin2 });
397        oldCount = target.Products.Count();
398        target.Persist(product);
399        newCount = target.Products.Count();
400        // make sure that a new entry was not created
401        Assert.AreEqual(oldCount, newCount);
402
403        // check the plugin list of the product
404        var dbProduct = target.Products.Where(p => p.Name == prodName).Single();
405        Assert.AreEqual(dbProduct.Plugins.Count(), 2);
406      }
407      #endregion
408
409      #region insert a product which references the same plugin twice and check if the correct exception is thrown
410      {
411        string prodName = RandomName();
412        string plugin1Name = RandomName();
413        var plugin1 = new PluginDescription(plugin1Name, vers01);
414        var product = new ProductDescription(prodName, vers01, Enumerable.Repeat(plugin1, 2));
415
416        // persist the plugin first
417        target.Persist(plugin1, enc.GetBytes("Zipped " + plugin1.Name));
418        try {
419          target.Persist(product);
420          Assert.Fail("Expected ArgumentException");
421        }
422        catch (ArgumentException) {
423          Assert.IsTrue(true, "Expected exception was thrown.");
424        }
425      }
426      #endregion
427    }
428
429    [TestMethod]
430    public void InsertPluginPerformanceTest() {
431      int nPlugins = 100;
432      int maxDependencies = 10;
433      int avgZipFileLength = 32000;
434
435      var store = new PluginStore();
436      Version vers01 = new Version(0, 1);
437      // create a random byte array to represent file length
438      byte[] zippedConstant = new byte[avgZipFileLength];
439      Random r = new Random();
440      r.NextBytes(zippedConstant);
441
442      Stopwatch stopWatch = new Stopwatch();
443      stopWatch.Start();
444      // create plugins
445      List<PluginDescription> plugins = new List<PluginDescription>();
446      for (int i = 0; i < nPlugins; i++) {
447        string name = RandomName();
448        var dependencies = store.Plugins;
449        if (dependencies.Count() > maxDependencies) dependencies = dependencies.Take(maxDependencies);
450        var plugin = new PluginDescription(name, vers01, dependencies);
451        store.Persist(plugin, zippedConstant);
452        plugins.Add(plugin);
453      }
454      stopWatch.Stop();
455      Assert.Inconclusive("Created " + nPlugins + " plugins in " + stopWatch.ElapsedMilliseconds +
456        " ms (" + (double)stopWatch.ElapsedMilliseconds / nPlugins + " ms / plugin )");
457    }
458    [TestMethod]
459    public void InsertProductPerformanceTest() {
460      int nProducts = 50;
461      int avgProductPlugins = 30;
462
463      var store = new PluginStore();
464      Version vers01 = new Version(0, 1);
465      Stopwatch stopWatch = new Stopwatch();
466      Random r = new Random();
467      var plugins = store.Plugins.ToList();
468      stopWatch.Start();
469      // create products
470      for (int i = 0; i < nProducts; i++) {
471        string name = RandomName();
472        List<PluginDescription> prodPlugins = new List<PluginDescription>();
473        for (int j = 0; j < avgProductPlugins; j++) {
474          var selectedPlugin = plugins[r.Next(0, plugins.Count)];
475          if (!prodPlugins.Contains(selectedPlugin)) prodPlugins.Add(selectedPlugin);
476        }
477        var prod = new ProductDescription(name, vers01, prodPlugins);
478        store.Persist(prod);
479      }
480      stopWatch.Stop();
481      Assert.Inconclusive("Created " + nProducts + " products in " + stopWatch.ElapsedMilliseconds +
482        " ms (" + (double)stopWatch.ElapsedMilliseconds / nProducts + " ms / product )");
483    }
484
485    private string RandomName() {
486      return Guid.NewGuid().ToString();
487    }
488  }
489}
Note: See TracBrowser for help on using the repository browser.