Merge pull request #505 from roji/shutdown_flow
[mono.git] / mcs / class / System.ServiceModel / Test / MetadataTests / TestContext.cs
1 //
2 // ITestContext.cs
3 //
4 // Author:
5 //       Martin Baulig <martin.baulig@xamarin.com>
6 //
7 // Copyright (c) 2012 Xamarin Inc. (http://www.xamarin.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 // THE SOFTWARE.
26
27 using System;
28 using System.IO;
29 using System.Text;
30 using System.Configuration;
31 using System.Collections.Generic;
32 using System.Xml;
33 using System.Xml.XPath;
34 using System.Reflection;
35 using System.ServiceModel;
36 using System.ServiceModel.Channels;
37 using System.ServiceModel.Configuration;
38 using System.ServiceModel.Description;
39
40 using SysConfig = System.Configuration.Configuration;
41
42 namespace MonoTests.System.ServiceModel.MetadataTests {
43
44         public abstract class TestContext {
45
46                 #region Abstract API
47
48                 public abstract MetadataSet GetMetadata (string name);
49
50                 public abstract XmlDocument GetConfiguration (string name);
51
52                 #endregion
53
54                 #region Default Context
55
56                 public static TestContext LoadMetadataContext = new _LoadMetadataContext ();
57
58                 public static TestContext CreateMetadataContext = new _CreateMetadataContext ();
59
60                 public static TestContext RoundTripContext = new _RoundTripContext ();
61
62                 #endregion
63
64                 #region Implementations
65
66                 class _LoadMetadataContext : TestContext {
67                         public override MetadataSet GetMetadata (string name)
68                         {
69                                 return LoadMetadata (name);
70                         }
71
72                         public override XmlDocument GetConfiguration (string name)
73                         {
74                                 return LoadConfiguration (name);
75                         }
76                 }
77
78                 class _CreateMetadataContext : TestContext {
79                         public override MetadataSet GetMetadata (string name)
80                         {
81                                 return MetadataSamples.GetMetadataByName (name);
82                         }
83
84                         public override XmlDocument GetConfiguration (string name)
85                         {
86                                 var metadata = GetMetadata (name);
87                                 var doc = new XmlDocument ();
88                                 doc.LoadXml (SaveConfigToString (metadata));
89                                 return doc;
90                         }
91                 }
92
93                 class _RoundTripContext : TestContext {
94                         public override MetadataSet GetMetadata (string name)
95                         {
96                                 return RoundTrip (name);
97                         }
98
99                         public override XmlDocument GetConfiguration (string name)
100                         {
101                                 var metadata = GetMetadata (name);
102                                 var doc = new XmlDocument ();
103                                 doc.LoadXml (SaveConfigToString (metadata));
104                                 return doc;
105                         }
106                 }
107
108                 #endregion
109
110                 #region Public Static API
111
112                 public static MetadataSet LoadMetadata (string name)
113                 {
114 #if USE_EMBEDDED_METADATA
115                         return LoadMetadataFromResource (name);
116 #else
117                         return LoadMetadataFromFile (name);
118 #endif
119                 }
120
121                 public static XmlDocument LoadConfiguration (string name)
122                 {
123 #if USE_EMBEDDED_METADATA
124                         return LoadConfigurationFromResource (name);
125 #else
126                         return LoadConfigurationFromFile (name);
127 #endif
128                 }
129
130                 public static void SaveMetadata (string name, MetadataSet metadata)
131                 {
132                         SaveMetadataToFile (name, metadata);
133                 }
134
135                 public static MetadataSet LoadMetadataFromFile (string name)
136                 {
137                         var asm = Assembly.GetExecutingAssembly ();
138                         if (!name.EndsWith (".xml"))
139                                 name = name + ".xml";
140                         var uri = new Uri (asm.CodeBase);
141                         var path = Path.GetDirectoryName (uri.AbsolutePath);
142                         path = Path.Combine (path, "Test");
143                         path = Path.Combine (path, "MetadataTests");
144                         path = Path.Combine (path, "Resources");
145                         var filename = Path.Combine (path, name);
146                         using (var stream = new StreamReader (filename)) {
147                                 var reader = new XmlTextReader (stream);
148                                 return MetadataSet.ReadFrom (reader);
149                         }
150                 }
151
152                 public static MetadataSet LoadMetadataFromResource (string name)
153                 {
154                         var asm = Assembly.GetExecutingAssembly ();
155                         if (!name.EndsWith (".xml"))
156                                 name = name + ".xml";
157                         
158                         var resname = "MetadataTests.Resources." + name;
159                         using (var stream = asm.GetManifestResourceStream (resname)) {
160                                 if (stream == null)
161                                         throw new InvalidOperationException (
162                                                 "No such resource: " + name);
163                                 var reader = new XmlTextReader (stream);
164                                 return MetadataSet.ReadFrom (reader);
165                         }
166                 }
167
168                 public static XmlDocument LoadConfigurationFromFile (string name)
169                 {
170                         var asm = Assembly.GetExecutingAssembly ();
171                         if (!name.EndsWith (".config"))
172                                 name = name + ".config";
173                         var uri = new Uri (asm.CodeBase);
174                         var path = Path.GetDirectoryName (uri.AbsolutePath);
175                         path = Path.Combine (path, "Test");
176                         path = Path.Combine (path, "MetadataTests");
177                         path = Path.Combine (path, "Resources");
178                         var filename = Path.Combine (path, name);
179                         using (var stream = new StreamReader (filename)) {
180                                 var xml = new XmlDocument ();
181                                 xml.Load (stream);
182                                 return xml;
183                         }
184                 }
185
186                 public static XmlDocument LoadConfigurationFromResource (string name)
187                 {
188                         var asm = Assembly.GetExecutingAssembly ();
189                         if (!name.EndsWith (".config"))
190                                 name = name + ".config";
191                         
192                         var resname = "MetadataTests.Resources." + name;
193                         using (var stream = asm.GetManifestResourceStream (resname)) {
194                                 if (stream == null)
195                                         throw new InvalidOperationException (
196                                                 "No such resource: " + name);
197                                 var xml = new XmlDocument ();
198                                 xml.Load (stream);
199                                 return xml;
200                         }
201                 }
202
203                 public static void SaveMetadataToFile (string filename, MetadataSet metadata)
204                 {
205                         if (File.Exists (filename))
206                                 return;
207
208                         using (var file = new StreamWriter (filename, false)) {
209                                 var writer = new XmlTextWriter (file);
210                                 writer.Formatting = Formatting.Indented;
211                                 metadata.WriteTo (writer);
212                         }
213
214                         Console.WriteLine ("Exported {0}.", filename);
215                 }
216
217                 internal static string SaveMetadataToString (MetadataSet metadata)
218                 {
219                         using (var ms = new MemoryStream ()) {
220                                 var writer = new XmlTextWriter (new StreamWriter (ms));
221                                 writer.Formatting = Formatting.Indented;
222                                 metadata.WriteTo (writer);
223                                 writer.Flush ();
224
225                                 return Encoding.UTF8.GetString (ms.GetBuffer (), 0, (int)ms.Position);
226                         }
227                 }
228
229                 internal static MetadataSet LoadMetadataFromString (string doc)
230                 {
231                         var buffer = Encoding.UTF8.GetBytes (doc);
232                         using (var ms = new MemoryStream (buffer)) {
233                                 var reader = new XmlTextReader (ms);
234                                 return MetadataSet.ReadFrom (reader);
235                         }
236                 }
237
238                 public static MetadataSet RoundTrip (string name)
239                 {
240                         var metadata = MetadataSamples.GetMetadataByName (name);
241
242                         var doc = SaveMetadataToString (metadata);
243                         return LoadMetadataFromString (doc);
244                 }
245
246                 public static void GenerateConfig (MetadataSet metadata, SysConfig config)
247                 {
248                         WsdlImporter importer = new WsdlImporter (metadata);
249                         
250                         var endpoints = importer.ImportAllEndpoints ();
251                         
252                         var generator = new ServiceContractGenerator (config);
253                         generator.Options = ServiceContractGenerationOptions.None;
254                         
255                         foreach (var endpoint in endpoints) {
256                                 ChannelEndpointElement channelElement;
257                                 generator.GenerateServiceEndpoint (endpoint, out channelElement);
258                         }
259                 }
260
261                 public static void GenerateConfig (string filename, MetadataSet metadata)
262                 {
263                         var fileMap = new ExeConfigurationFileMap ();
264                         fileMap.ExeConfigFilename = filename;
265                         var config = ConfigurationManager.OpenMappedExeConfiguration (
266                                 fileMap, ConfigurationUserLevel.None);
267                                 
268                         GenerateConfig (metadata, config);
269                         config.Save (ConfigurationSaveMode.Minimal);
270                         NormalizeConfig (filename);
271                 }
272
273                 internal static string SaveConfigToString (MetadataSet metadata)
274                 {
275                         var filename = Path.GetTempFileName ();
276                         File.Delete (filename);
277
278                         try {
279                                 GenerateConfig (filename, metadata);
280
281                                 using (var reader = new StreamReader (filename))
282                                         return reader.ReadToEnd ();
283                         } finally {
284                                 File.Delete (filename);
285                         }
286                 }
287                 
288                 public static void NormalizeConfig (string filename)
289                 {
290                         // Mono-specific hack.
291                         if (Environment.OSVersion.Platform == PlatformID.Win32NT)
292                                 return;
293
294                         var doc = new XmlDocument ();
295                         doc.Load (filename);
296                         var nav = doc.CreateNavigator ();
297                         
298                         var empty = new List<XPathNavigator> ();
299                         var iter = nav.Select ("/configuration/system.serviceModel//*");
300                         foreach (XPathNavigator node in iter) {
301                                 if (!node.HasChildren && !node.HasAttributes && string.IsNullOrEmpty (node.Value))
302                                         empty.Add (node);
303                         }
304                         foreach (var node in empty)
305                                 node.DeleteSelf ();
306                         
307                         var settings = new XmlWriterSettings ();
308                         settings.Indent = true;
309                         settings.NewLineHandling = NewLineHandling.Replace;
310                         
311                         using (var writer = XmlWriter.Create (filename, settings)) {
312                                 doc.WriteTo (writer);
313                         }
314                         Console.WriteLine ();
315                 }
316
317                 #endregion
318         }
319 }
320