opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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  
28 using System;
29 using System.Collections;
30 using System.Collections.Generic;
31 using System.Linq.Expressions;
32 using System.Reflection;
33 using System.Text;
34 using NUnit.Framework;
35 using OpenMetaverse;
36 using OpenSim.Framework;
37 using OpenSim.Tests.Common;
38  
39 namespace OpenSim.Data.Tests
40 {
41 //This is generic so that the lambda expressions will work right in IDEs.
42 public class PropertyScrambler<T>
43 {
44 readonly System.Collections.Generic.List<string> membersToNotScramble = new List<string>();
45  
46 private void AddExpressionToNotScrableList(Expression expression)
47 {
48 UnaryExpression unaryExpression = expression as UnaryExpression;
49 if (unaryExpression != null)
50 {
51 AddExpressionToNotScrableList(unaryExpression.Operand);
52 return;
53 }
54  
55 MemberExpression memberExpression = expression as MemberExpression;
56 if (memberExpression != null)
57 {
58 if (!(memberExpression.Member is PropertyInfo))
59 {
60 throw new NotImplementedException("I don't know how deal with a MemberExpression that is a " + expression.Type);
61 }
62 membersToNotScramble.Add(memberExpression.Member.Name);
63 return;
64 }
65  
66 throw new NotImplementedException("I don't know how to parse a " + expression.Type);
67 }
68  
69 public PropertyScrambler<T> DontScramble(Expression<Func<T, object>> expression)
70 {
71 AddExpressionToNotScrableList(expression.Body);
72 return this;
73 }
74  
75 public void Scramble(T obj)
76 {
77 internalScramble(obj);
78 }
79  
80 private void internalScramble(object obj)
81 {
82 PropertyInfo[] properties = obj.GetType().GetProperties();
83 foreach (var property in properties)
84 {
85 //Skip indexers of classes. We will assume that everything that has an indexer
86 // is also IEnumberable. May not always be true, but should be true normally.
87 if (property.GetIndexParameters().Length > 0)
88 continue;
89  
90 RandomizeProperty(obj, property, null);
91 }
92 //Now if it implments IEnumberable, it's probably some kind of list, so we should randomize
93 // everything inside of it.
94 IEnumerable enumerable = obj as IEnumerable;
95 if (enumerable != null)
96 {
97 foreach (object value in enumerable)
98 {
99 internalScramble(value);
100 }
101 }
102 }
103  
104 private readonly Random random = new Random();
105 private void RandomizeProperty(object obj, PropertyInfo property, object[] index)
106 {//I'd like a better way to compare, but I had lots of problems with InventoryFolderBase because the ID is inherited.
107 if (membersToNotScramble.Contains(property.Name))
108 return;
109 Type t = property.PropertyType;
110 if (!property.CanWrite)
111 return;
112 object value = property.GetValue(obj, index);
113 if (value == null)
114 return;
115  
116 if (t == typeof(string))
117 property.SetValue(obj, RandomName(), index);
118 else if (t == typeof(UUID))
119 property.SetValue(obj, UUID.Random(), index);
120 else if (t == typeof(sbyte))
121 property.SetValue(obj, (sbyte)random.Next(sbyte.MinValue, sbyte.MaxValue), index);
122 else if (t == typeof(short))
123 property.SetValue(obj, (short)random.Next(short.MinValue, short.MaxValue), index);
124 else if (t == typeof(int))
125 property.SetValue(obj, random.Next(), index);
126 else if (t == typeof(long))
127 property.SetValue(obj, random.Next() * int.MaxValue, index);
128 else if (t == typeof(byte))
129 property.SetValue(obj, (byte)random.Next(byte.MinValue, byte.MaxValue), index);
130 else if (t == typeof(ushort))
131 property.SetValue(obj, (ushort)random.Next(ushort.MinValue, ushort.MaxValue), index);
132 else if (t == typeof(uint))
133 property.SetValue(obj, Convert.ToUInt32(random.Next()), index);
134 else if (t == typeof(ulong))
135 property.SetValue(obj, Convert.ToUInt64(random.Next()) * Convert.ToUInt64(UInt32.MaxValue), index);
136 else if (t == typeof(bool))
137 property.SetValue(obj, true, index);
138 else if (t == typeof(byte[]))
139 {
140 byte[] bytes = new byte[30];
141 random.NextBytes(bytes);
142 property.SetValue(obj, bytes, index);
143 }
144 else
145 internalScramble(value);
146 }
147  
148 private string RandomName()
149 {
150 StringBuilder name = new StringBuilder();
151 int size = random.Next(5, 12);
152 for (int i = 0; i < size; i++)
153 {
154 char ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
155 name.Append(ch);
156 }
157 return name.ToString();
158 }
159 }
160  
161 [TestFixture]
162 public class PropertyScramblerTests : OpenSimTestCase
163 {
164 [Test]
165 public void TestScramble()
166 {
167 AssetBase actual = new AssetBase(UUID.Random(), "asset one", (sbyte)AssetType.Texture, UUID.Zero.ToString());
168 new PropertyScrambler<AssetBase>().Scramble(actual);
169 }
170  
171 [Test]
172 public void DontScramble()
173 {
174 UUID uuid = UUID.Random();
175 AssetBase asset = new AssetBase(uuid, "asset", (sbyte)AssetType.Texture, UUID.Zero.ToString());
176 new PropertyScrambler<AssetBase>()
177 .DontScramble(x => x.Metadata)
178 .DontScramble(x => x.FullID)
179 .DontScramble(x => x.ID)
180 .Scramble(asset);
181 Assert.That(asset.FullID, Is.EqualTo(uuid));
182 }
183 }
184 }