Merge remote branch 'upstream/master'
[mono.git] / mcs / class / System.Web / Test / tools / CachePQTestGenerator / Sequences.cs
1 //
2 //  Sequences.cs
3 //
4 //  Author:
5 //    Marek Habersack <grendel@twistedcode.net>
6 //
7 //  Copyright (c) 2010, Marek Habersack
8 //
9 //  All rights reserved.
10 //
11 //  Redistribution and use in source and binary forms, with or without modification, are permitted
12 //  provided that the following conditions are met:
13 //
14 //     * Redistributions of source code must retain the above copyright notice, this list of
15 //       conditions and the following disclaimer.
16 //     * Redistributions in binary form must reproduce the above copyright notice, this list of
17 //       conditions and the following disclaimer in the documentation and/or other materials
18 //       provided with the distribution.
19 //     * Neither the name of Marek Habersack nor the names of its contributors may be used to
20 //       endorse or promote products derived from this software without specific prior written
21 //       permission.
22 //
23 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 //  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 //  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 //  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 //  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 //  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 //  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 //  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 //  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 //  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 //  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 //
35 using System;
36 using System.Collections.Generic;
37 using System.IO;
38 using System.Text;
39 using System.Web.Caching;
40 using System.Xml;
41 using System.Xml.XPath;
42
43 namespace Tester
44 {
45         static partial class Sequences
46         {
47                 public static void Run (StringBuilder sb, string seqDir, string indent)
48                 {
49                         string[] files = Directory.GetFiles (seqDir, "*.seq");
50                         if (files == null || files.Length == 0)
51                                 return;
52
53                         int seqNum = 0;
54                         Array.Sort <string> (files);
55                         foreach (string f in files)
56                                 RunSequence (sb, indent, f, seqNum++);
57                 }
58
59                 static void RunSequence (StringBuilder sb, string initialIndent, string file, int seqNum)
60                 {
61                         Dictionary <Guid, int> cacheIndex;
62                         List <CacheItem> cacheItems;
63                         List <EDSequenceEntry> edSequence;
64
65                         LoadEDSequence (file, out cacheIndex, out cacheItems, out edSequence);
66
67                         if (edSequence == null || edSequence.Count == 0)
68                                 return;
69
70
71                         string listName = String.Format ("list_{0:00000}", seqNum);
72                         string testsName = String.Format ("tests_{0:00000}", seqNum);
73                         sb.AppendLine ();
74                         sb.FormatList (initialIndent, listName, cacheItems);
75
76                         sb.AppendLine ();
77                         sb.AppendFormat ("{0} string[] {1} = {{\n", initialIndent, testsName);
78
79                         string indent = initialIndent + "\t";
80                         int idx;
81                         var pq = new PriorityQueueState (listName, testsName);
82                         foreach (EDSequenceEntry entry in edSequence) {
83                                 idx = cacheIndex [entry.Item.Guid];
84
85                                 switch (entry.Type) {
86                                         case EDSequenceEntryType.Enqueue:
87                                                 sb.FormatEnqueue (indent, pq, cacheItems, idx);
88                                                 break;
89
90                                         case EDSequenceEntryType.Dequeue:
91                                                 sb.FormatDequeue (indent, pq);
92                                                 break;
93
94                                         case EDSequenceEntryType.Disable:
95                                                 sb.FormatDisableItem (indent, pq, cacheItems, idx);
96                                                 break;
97
98                                         case EDSequenceEntryType.Peek:
99                                                 sb.FormatPeek (indent, pq);
100                                                 break;
101                                 }
102                         }
103
104                         sb.FormatQueueSize (indent, pq);
105
106                         while (pq.Queue.Count > 0)
107                                 sb.FormatDequeue (indent, pq);
108                         sb.AppendFormat ("{0}}};", initialIndent);
109                         sb.AppendLine ();
110                         
111                         sb.SequenceMethodStart (initialIndent, file, seqNum);
112                         sb.AppendFormat ("{0}RunTest ({1}, {2});", indent, testsName, listName);
113                         sb.AppendLine ();
114                         
115                         sb.SequenceMethodEnd (initialIndent);
116                 }
117
118                 static List <EDSequenceEntry> LoadEDSequence (string file, out Dictionary <Guid, int> cacheIndex, out List <CacheItem> cacheItems,
119                                                               out List <EDSequenceEntry> edSequence)
120                 {
121                         var doc = new XPathDocument (file);
122                         XPathNavigator nav = doc.CreateNavigator (), current;
123                         XPathNodeIterator nodes = nav.Select ("/sequence/entry");
124                         CacheItem item;
125                         
126                         edSequence = new List <EDSequenceEntry> ();
127                         cacheIndex = new Dictionary <Guid, int> ();
128                         cacheItems = new List <CacheItem> ();
129                         
130                         while (nodes.MoveNext ()) {
131                                 current = nodes.Current;
132                                 item = CreateCacheItem (current, cacheIndex, cacheItems);
133                                 edSequence.Add (new EDSequenceEntry (item, current.GetRequiredAttribute <EDSequenceEntryType> ("type")));
134                         }
135                         
136                         return null;
137                 }
138
139                 static CacheItem CreateCacheItem (XPathNavigator node, Dictionary <Guid, int> cacheIndex, List <CacheItem> cacheItems)
140                 {
141                         Guid guid = node.GetRequiredAttribute <Guid> ("guid");
142                         int idx;
143
144                         if (cacheIndex.TryGetValue (guid, out idx))
145                                 return cacheItems [idx];
146                         
147                         var ret = new CacheItem ();
148
149                         ret.Key = node.GetRequiredAttribute <string> ("key");
150                         ret.AbsoluteExpiration = node.GetRequiredAttribute <DateTime> ("absoluteExpiration");
151                         ret.SlidingExpiration = node.GetRequiredAttribute <TimeSpan> ("slidingExpiration");
152                         ret.Priority = node.GetRequiredAttribute <CacheItemPriority> ("priority");
153                         ret.LastChange = node.GetRequiredAttribute <DateTime> ("lastChange");
154                         ret.ExpiresAt = node.GetRequiredAttribute <long> ("expiresAt");
155                         ret.Disabled = node.GetRequiredAttribute <bool> ("disabled");
156                         ret.Guid = guid;
157
158                         cacheItems.Add (ret);
159                         cacheIndex.Add (guid, cacheItems.Count - 1);
160                         
161                         return ret;
162                 }               
163         }
164 }