aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/Tests/PropertyScrambler.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Data/Tests/PropertyScrambler.cs')
-rw-r--r--OpenSim/Data/Tests/PropertyScrambler.cs186
1 files changed, 186 insertions, 0 deletions
diff --git a/OpenSim/Data/Tests/PropertyScrambler.cs b/OpenSim/Data/Tests/PropertyScrambler.cs
new file mode 100644
index 0000000..72aaff1
--- /dev/null
+++ b/OpenSim/Data/Tests/PropertyScrambler.cs
@@ -0,0 +1,186 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Linq.Expressions;
32using System.Reflection;
33using System.Text;
34using NUnit.Framework;
35using NUnit.Framework.SyntaxHelpers;
36using OpenMetaverse;
37using OpenSim.Framework;
38
39namespace OpenSim.Data.Tests
40{
41
42 //This is generic so that the lambda expressions will work right in IDEs.
43 public class PropertyScrambler<T>
44 {
45 readonly System.Collections.Generic.List<string> membersToNotScramble = new List<string>();
46
47 private void AddExpressionToNotScrableList(Expression expression)
48 {
49 UnaryExpression unaryExpression = expression as UnaryExpression;
50 if (unaryExpression != null)
51 {
52 AddExpressionToNotScrableList(unaryExpression.Operand);
53 return;
54 }
55
56 MemberExpression memberExpression = expression as MemberExpression;
57 if (memberExpression != null)
58 {
59 if (!(memberExpression.Member is PropertyInfo))
60 {
61 throw new NotImplementedException("I don't know how deal with a MemberExpression that is a " + expression.Type);
62 }
63 membersToNotScramble.Add(memberExpression.Member.Name);
64 return;
65 }
66
67 throw new NotImplementedException("I don't know how to parse a " + expression.Type);
68 }
69
70 public PropertyScrambler<T> DontScramble(Expression<Func<T, object>> expression)
71 {
72 AddExpressionToNotScrableList(expression.Body);
73 return this;
74 }
75
76 public void Scramble(T obj)
77 {
78 internalScramble(obj);
79 }
80
81 private void internalScramble(object obj)
82 {
83 PropertyInfo[] properties = obj.GetType().GetProperties();
84 foreach (var property in properties)
85 {
86 //Skip indexers of classes. We will assume that everything that has an indexer
87 // is also IEnumberable. May not always be true, but should be true normally.
88 if (property.GetIndexParameters().Length > 0)
89 continue;
90
91 RandomizeProperty(obj, property, null);
92 }
93 //Now if it implments IEnumberable, it's probably some kind of list, so we should randomize
94 // everything inside of it.
95 IEnumerable enumerable = obj as IEnumerable;
96 if (enumerable != null)
97 {
98 foreach (object value in enumerable)
99 {
100 internalScramble(value);
101 }
102 }
103 }
104
105 private readonly Random random = new Random();
106 private void RandomizeProperty(object obj, PropertyInfo property, object[] index)
107 {//I'd like a better way to compare, but I had lots of problems with InventoryFolderBase because the ID is inherited.
108 if (membersToNotScramble.Contains(property.Name))
109 return;
110 Type t = property.PropertyType;
111 if (!property.CanWrite)
112 return;
113 object value = property.GetValue(obj, index);
114 if (value == null)
115 return;
116
117 if (t == typeof(string))
118 property.SetValue(obj, RandomName(), index);
119 else if (t == typeof(UUID))
120 property.SetValue(obj, UUID.Random(), index);
121 else if (t == typeof(sbyte))
122 property.SetValue(obj, (sbyte)random.Next(sbyte.MinValue, sbyte.MaxValue), index);
123 else if (t == typeof(short))
124 property.SetValue(obj, (short)random.Next(short.MinValue, short.MaxValue), index);
125 else if (t == typeof(int))
126 property.SetValue(obj, random.Next(), index);
127 else if (t == typeof(long))
128 property.SetValue(obj, random.Next() * int.MaxValue, index);
129 else if (t == typeof(byte))
130 property.SetValue(obj, (byte)random.Next(byte.MinValue, byte.MaxValue), index);
131 else if (t == typeof(ushort))
132 property.SetValue(obj, (ushort)random.Next(ushort.MinValue, ushort.MaxValue), index);
133 else if (t == typeof(uint))
134 property.SetValue(obj, Convert.ToUInt32(random.Next()), index);
135 else if (t == typeof(ulong))
136 property.SetValue(obj, Convert.ToUInt64(random.Next()) * Convert.ToUInt64(UInt32.MaxValue), index);
137 else if (t == typeof(bool))
138 property.SetValue(obj, true, index);
139 else if (t == typeof(byte[]))
140 {
141 byte[] bytes = new byte[30];
142 random.NextBytes(bytes);
143 property.SetValue(obj, bytes, index);
144 }
145 else
146 internalScramble(value);
147 }
148
149 private string RandomName()
150 {
151 StringBuilder name = new StringBuilder();
152 int size = random.Next(5, 12);
153 for (int i = 0; i < size; i++)
154 {
155 char ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
156 name.Append(ch);
157 }
158 return name.ToString();
159 }
160 }
161
162 [TestFixture]
163 public class PropertyScramblerTests
164 {
165 [Test]
166 public void TestScramble()
167 {
168 AssetBase actual = new AssetBase(UUID.Random(), "asset one");
169 new PropertyScrambler<AssetBase>().Scramble(actual);
170 }
171
172 [Test]
173 public void DontScramble()
174 {
175 UUID uuid = UUID.Random();
176 AssetBase asset = new AssetBase();
177 asset.FullID = uuid;
178 new PropertyScrambler<AssetBase>()
179 .DontScramble(x => x.Metadata)
180 .DontScramble(x => x.FullID)
181 .DontScramble(x => x.ID)
182 .Scramble(asset);
183 Assert.That(asset.FullID, Is.EqualTo(uuid));
184 }
185 }
186} \ No newline at end of file