fb0e2b3609e201b2fe70420c7dbcc0bb8e867e8f
[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                         // Run from mcs/class/lib/<profile>
142                         var path = Path.GetDirectoryName (uri.AbsolutePath);
143                         path = Directory.GetParent (path).Parent.FullName;
144                         path = Path.Combine (path, "System.ServiceModel");
145                         path = Path.Combine (path, "Test");
146                         path = Path.Combine (path, "MetadataTests");
147                         path = Path.Combine (path, "Resources");
148                         var filename = Path.Combine (path, name);
149                         using (var stream = new StreamReader (filename)) {
150                                 var reader = new XmlTextReader (stream);
151                                 return MetadataSet.ReadFrom (reader);
152                         }
153                 }
154
155                 public static MetadataSet LoadMetadataFromResource (string name)
156                 {
157                         var asm = Assembly.GetExecutingAssembly ();
158                         if (!name.EndsWith (".xml"))
159                                 name = name + ".xml";
160                         
161                         var resname = "MetadataTests.Resources." + name;
162                         using (var stream = asm.GetManifestResourceStream (resname)) {
163                                 if (stream == null)
164                                         throw new InvalidOperationException (
165                                                 "No such resource: " + name);
166                                 var reader = new XmlTextReader (stream);
167                                 return MetadataSet.ReadFrom (reader);
168                         }
169                 }
170
171                 public static XmlDocument LoadConfigurationFromFile (string name)
172                 {
173                         var asm = Assembly.GetExecutingAssembly ();
174                         if (!name.EndsWith (".config"))
175                                 name = name + ".config";
176                         var uri = new Uri (asm.CodeBase);
177                         var path = Path.GetDirectoryName (uri.AbsolutePath);
178                         path = Directory.GetParent (path).Parent.FullName;
179                         path = Path.Combine (path, "System.ServiceModel");
180                         path = Path.Combine (path, "Test");
181                         path = Path.Combine (path, "MetadataTests");
182                         path = Path.Combine (path, "Resources");
183                         var filename = Path.Combine (path, name);
184                         using (var stream = new StreamReader (filename)) {
185                                 var xml = new XmlDocument ();
186                                 xml.Load (stream);
187                                 return xml;
188                         }
189                 }
190
191                 public static XmlDocument LoadConfigurationFromResource (string name)
192                 {
193                         var asm = Assembly.GetExecutingAssembly ();
194                         if (!name.EndsWith (".config"))
195                                 name = name + ".config";
196                         
197                         var resname = "MetadataTests.Resources." + name;
198                         using (var stream = asm.GetManifestResourceStream (resname)) {
199                                 if (stream == null)
200                                         throw new InvalidOperationException (
201                                                 "No such resource: " + name);
202                                 var xml = new XmlDocument ();
203                                 xml.Load (stream);
204                                 return xml;
205                         }
206                 }
207
208                 public static void SaveMetadataToFile (string filename, MetadataSet metadata)
209                 {
210                         if (File.Exists (filename))
211                                 return;
212
213                         using (var file = new StreamWriter (filename, false)) {
214                                 var writer = new XmlTextWriter (file);
215                                 writer.Formatting = Formatting.Indented;
216                                 metadata.WriteTo (writer);
217                         }
218
219                         Console.WriteLine ("Exported {0}.", filename);
220                 }
221
222                 internal static string SaveMetadataToString (MetadataSet metadata)
223                 {
224                         using (var ms = new MemoryStream ()) {
225                                 var writer = new XmlTextWriter (new StreamWriter (ms));
226                                 writer.Formatting = Formatting.Indented;
227                                 metadata.WriteTo (writer);
228                                 writer.Flush ();
229
230                                 return Encoding.UTF8.GetString (ms.GetBuffer (), 0, (int)ms.Position);
231                         }
232                 }
233
234                 internal static MetadataSet LoadMetadataFromString (string doc)
235                 {
236                         var buffer = Encoding.UTF8.GetBytes (doc);
237                         using (var ms = new MemoryStream (buffer)) {
238                                 var reader = new XmlTextReader (ms);
239                                 return MetadataSet.ReadFrom (reader);
240                         }
241                 }
242
243                 public static MetadataSet RoundTrip (string name)
244                 {
245                         var metadata = MetadataSamples.GetMetadataByName (name);
246
247                         var doc = SaveMetadataToString (metadata);
248                         return LoadMetadataFromString (doc);
249                 }
250
251                 public static void GenerateConfig (MetadataSet metadata, SysConfig config)
252                 {
253                         WsdlImporter importer = new WsdlImporter (metadata);
254                         
255                         var endpoints = importer.ImportAllEndpoints ();
256                         
257                         var generator = new ServiceContractGenerator (config);
258                         generator.Options = ServiceContractGenerationOptions.None;
259                         
260                         foreach (var endpoint in endpoints) {
261                                 ChannelEndpointElement channelElement;
262                                 generator.GenerateServiceEndpoint (endpoint, out channelElement);
263                         }
264                 }
265
266                 public static void GenerateConfig (string filename, MetadataSet metadata)
267                 {
268                         var fileMap = new ExeConfigurationFileMap ();
269                         fileMap.ExeConfigFilename = filename;
270                         var config = ConfigurationManager.OpenMappedExeConfiguration (
271                                 fileMap, ConfigurationUserLevel.None);
272                                 
273                         GenerateConfig (metadata, config);
274                         config.Save (ConfigurationSaveMode.Minimal);
275                         NormalizeConfig (filename);
276                 }
277
278                 internal static string SaveConfigToString (MetadataSet metadata)
279                 {
280                         var filename = Path.GetTempFileName ();
281                         File.Delete (filename);
282
283                         try {
284                                 GenerateConfig (filename, metadata);
285
286                                 using (var reader = new StreamReader (filename))
287                                         return reader.ReadToEnd ();
288                         } finally {
289                                 File.Delete (filename);
290                         }
291                 }
292                 
293                 public static void NormalizeConfig (string filename)
294                 {
295                         // Mono-specific hack.
296                         if (Environment.OSVersion.Platform == PlatformID.Win32NT)
297                                 return;
298
299                         var doc = new XmlDocument ();
300                         doc.Load (filename);
301                         var nav = doc.CreateNavigator ();
302                         
303                         var empty = new List<XPathNavigator> ();
304                         var iter = nav.Select ("/configuration/system.serviceModel//*");
305                         foreach (XPathNavigator node in iter) {
306                                 if (!node.HasChildren && !node.HasAttributes && string.IsNullOrEmpty (node.Value))
307                                         empty.Add (node);
308                         }
309                         foreach (var node in empty)
310                                 node.DeleteSelf ();
311                         
312                         var settings = new XmlWriterSettings ();
313                         settings.Indent = true;
314                         settings.NewLineHandling = NewLineHandling.Replace;
315                         
316                         using (var writer = XmlWriter.Create (filename, settings)) {
317                                 doc.WriteTo (writer);
318                         }
319                         Console.WriteLine ();
320                 }
321
322                 #endregion
323         }
324 }
325