2using System.Collections;
3using System.Collections.Concurrent;
4using System.Collections.Generic;
5using System.Diagnostics;
7using System.Linq.Expressions;
8using System.Reflection;
26using Microsoft.VisualStudio.TestTools.UnitTesting;
31using TestCategory =
NUnit.Framework.CategoryAttribute;
39 [System.Diagnostics.CodeAnalysis.SuppressMessage(
"Microsoft.Design",
"CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable")]
44 private const int Recursions_Before_Calming_Down = 8;
48 private const int Max_ReRandomize_Attempts = 20;
51 private const int Max_Recursive_Calls = 16;
54 private const double Min_Random = -1
E9;
57 private const double Max_Random = 1
E9;
65 private Random _random => thread_safe_random.Value;
74 (_targetAnalysisProfile = _samples.AnalysisProfile.Posted);
75 set => _targetAnalysisProfile = value;
101 Console.WriteLine(
$"Seed for tests is: {seed} - but note that if tests are being run " +
102 "concurrently, this seed cannot be used to reproduce the same results. " +
103 "For a seed to guarantee the same results every time, tests must be run one at a time, " +
104 "or with parallelism disabled on the test runner itself (MSTest or NUnit).");
164 (
Prior ==
null ?
"Recursion Stack: " :
$"{Prior} > ") +
Type.NiceTypeName();
188 if (!(
T.IsPrimitive ||
T.IsValueType ||
T ==
typeof(
object) ||
T ==
typeof(
string)))
189 currentRecursion.LogIndented(
$"Create randomized instance ({currentRecursion.Depth}): " +
190 $"{desiredType.NiceTypeName()}");
198 return _random.Next(2) == 0;
201 return _samples.SimulationStartDate.AddDays(_random.Next(-365, 366));
203 else if (
T.IsIntegerType())
210 int random = _random.Next(min, (
int)Max_Random);
214 else if (
T.IsNumeric())
216 double random = _random.NextDouble() * (Max_Random - Min_Random) + Min_Random;
221 return T.GetEnumValues().GetValue(_random.Next(
T.GetEnumValues().Length));
225 _random.Next(4) == 0 ?
typeof(
bool) :
268 if (
T.IsAbstract ||
T.IsInterface)
270 "because it is an abstract class or interface.");
281 $"from an array of {itemsType.NiceTypeName()} failed: {ex.Message}",
ex);
293 string message =
$"No rules for generating a random value of type: \"{T.NiceTypeName()}\".";
298 return T.IsValueType ?
Activator.CreateInstance(
T) :
null;
301 #region Type Specific Random Generation Helpers
321 throw new ArgumentException(
"This function requires a generic reference type. " +
322 $"The type given was {referenceType.NiceTypeName()}");
333 throw new Exception(
$"Missing Reference Constructor {runtimeType.NiceTypeName()}(string)");
336 new object[] {
Guid.NewGuid().ToString() });
339 throw new Exception(
$"CreateRandomizedReference called for a type {referenceType.NiceTypeName()}, " +
340 "but this routine should not being used for IReference<ILayerSource> properties. " +
341 "All those properties should be using GenerateNestedLayerSourceReference.");
366 currentRecursion.LogIndented(
"Opted to find an existing resource of type " +
367 $"{T.NiceTypeName()} on thread {Thread.CurrentThread.ManagedThreadId}");
372 currentRecursion.LogIndented(
$"No satisfactory existing {T.NiceTypeName()} found. " +
373 "Reverting to generating a new resource.");
382 string reqDescription =
$"Post a randomly generated {T.NiceTypeName()}";
388 string error =
$"Failed to generate a valid {T.NiceTypeName()}. " +
389 $"Post of the resource to reference failed with: {ex.Message}" +
390 $"\nStructure looks like:\n{res.Serialize()}";
407 currentRecursion.LogIndented(
$"Failed to generate a valid {T.NiceTypeName()}. Returning null.");
437 currentRecursion.LogIndented(
"Recursion Level is low, generating a reference to " +
438 $"every instantiable subtype of {contentType.NiceTypeName()}.");
440 .Where(
x =>
x !=
null).ToList().ForEach(
x =>
481 throw new ArgumentException(
$"The desired type {T.NiceTypeName()} must derive from IAPIType.");
487 currentRecursion.LogIndented(
$"Recursion level ({recursionLevel}) is too high " +
488 $"({Max_Recursive_Calls}) to generate a new resource. Returning a null object.");
502 currentRecursion.LogIndented(
$"Recursion level ({recursionLevel}) is getting high " +
503 $"(>{Recursions_Before_Calming_Down}) - looking for existing resources " +
504 $"of type {T.NiceTypeName()}");
508 return Resolve(
existing).DeepCopy();
516 if (
T.IsInterface ||
T.IsAbstract)
526 nextRecursion.LogIndented(
"Elected to generate an instance of the " +
527 $"instantiable derived type: {instantiableType.NiceTypeName()}");
533 throw new PropertyGenerationException(
"Cannot create an instance of the type " +
534 $"{instantiableType.NiceTypeName()} because it has no empty constructor.");
538 catch (PropertyGenerationException
e)
553 if (_random.Next(2) == 0)
559 List<
Perspective.
Base> values = TestSuite_Perspective.CombinablePerspectiveValues
560 .Where(p => _random.Next(2) == 0).ToList();
562 if (values.Count == 0) values.Add(
593 $"referenced by the target analysis profile ({Target_AnalysisProfile.id})");
604 $"{currentRecursion.Type.NiceTypeName()} whose data file we can copy)");
614 CachedResourcesOfType(
T).OrderBy(
random => _random.NextDouble());
632 string description = !selectedForReuse.resolved ?
null :
633 $"description: \"{(selectedForReuse.GetValue() as IStoredAPIResource)?.description}\" ";
635 $"{selectedForReuse.GetType().NiceTypeName()} from the recursion context " +
636 $"({description}id: {selectedForReuse.ref_id})");
660 currentRecursion.LogIndented(
$"Opted to use a standard sample {T.NiceTypeName()}");
665 currentRecursion.LogIndented(
$"Could not find any existing {T.NiceTypeName()} to reference.");
677 p.PropertyType.GetGenericArguments()[0]
is Type
sampleType &&
679 .OrderBy(
random => _random.NextDouble());
690 #region Cached Existing Resources
705 private uint _trackInsertionOrder = 0;
737 throw new ArgumentException(
"Cannot cache resources that have not been posted.");
746 $"previously cached as a more weakly typed {cached.GetType().NiceTypeName()} " +
747 "which is preventing the cached instance from being reused now.");
754 _knownResourcesByType.Where(
kvp =>
kvp.Key ==
T ||
T.IsAssignableFrom(
kvp.Key))
761 .Values.OrderBy(
t =>
t.Item1).Select(
t =>
t.Item2));
768 throw new Exception(
"Resolve should not be used when reflection class " +
769 "is configured for offline resource generation.");
772 return reference.resolved ?
reference.GetValue() :
778 #endregion Cached Existing Resources
807 Debug.WriteLine(
"UploadResourceData was give a resource that already has a data_file " +
808 $"reference ({resource.data_file.ref_id}). Polling until ready.");
822#pragma warning disable CS0618
825#pragma warning restore CS0618
840 Assert.Fail(
"Reflection-based data upload error: Not sure what sort of " +
841 $"data to upload for this resources of type: {resource.GetType()}");
849 string error =
"Upload data failed for resource of type " +
850 $"{resource.GetType().NiceTypeName()} failed: {ex.Message}" +
851 $"\nStructure looks like:\n{resource.Serialize()}";
852 Console.WriteLine(
$"Error: {error}");
876 Type
T = result.GetType();
879 foreach (
PropertyInfo prop in T.GetUserFacingProperties(
true,
true).OrderByDescending(
883 throw new Exception(
"GetUserFacingProperties returned a read-only property " +
884 "even though only writable properties were requested. Property was: " +
885 $"{T.NiceTypeName()} property {prop.PropertyType.NiceTypeName()} " +
886 $"{prop.DeclaringType.NiceTypeName()}.{prop.Name}");
891 int max_attempts = currentRecursion.Depth >= Recursions_Before_Calming_Down ? 1
892 : Max_ReRandomize_Attempts;
900 catch (PropertyGenerationException
ex)
905 },
o => !(
o is PropertyGenerationException),
906 () =>
"RandomizePropertyValue method failed: " +
last_error,
925 "An object instance is required for several validation checks.");
930 "The caller should make sure they are handling this property appropriately.");
937 else if (
prop.Name.Contains(
"currency"))
975 propertyValue = _random.NextDouble() < 0.5 ? Target_AnalysisProfile.simulation :
976 CreateRandomizedReference(
prop.PropertyType,
997 .
Select(
_ => _samples.SimulationStartDate.AddYears(2).AddDays(_random.Next(366)))
998 .OrderBy(date => date).ToList();
1060 int sourcesToGenerate = currentRecursion.Depth > Recursions_Before_Calming_Down ? 1 :
1061 _random.Next(1, 1 + Recursions_Before_Calming_Down -
currentRecursion.Depth);
1077 sources = sources.GroupBy(r => r.ref_id, (
id,
grp) =>
grp.First());
1106 () =>
"The generated layer or one of its dependencies is not valid " +
1115 if ((source.
layer_views?.Any() ??
false) && _random.Next(2) == 1)
1119 source.layer_views =
null;
1136 currentRecursion.LogIndented(
"Warning: The StaticPortfolio generated randomly " +
1137 "contained some layers that were not compatible with the source analysis " +
1138 "profile. This should no longer be happening. As a workaround, the invalid " +
1139 "layers have been removed.");
1147 "The generated portfolio reference didn't contain " +
1148 "any layers that are valid to use with the current analysis profile " +
1158 if (source.
portfolio !=
null && _random.Next(2) == 1)
1162 source.portfolio =
null;
1165 set =>
set.
Any(), () =>
"None of the generated layer_views' Layers " +
1166 "were compatible with this PortfolioView's analysis profile.",
1170#pragma warning disable 618
1182#pragma warning restore 618
1230 _random.NextDouble() * (Max_Random - ((
RangeFilter)
obj).begin_value);
1233 _random.NextDouble() * (((
RangeFilter)
obj).end_value - Min_Random);
1294 currentRecursion.LogIndented(
"Warning: The loss_sets list generated randomly " +
1295 "contained some that were not compatible with the target analysis profile." +
1296 "This should no longer be happening. As a workaround, the invalid " +
1297 "loss sets have been removed.");
1300 result => result.Count > 0, () =>
"All of the referenced loss sets " +
1301 "referenced an event catalog not in the analysis profile.",
1333 domains => domains.Any(), () =>
"None of the domain's Layers generated " +
1334 "were compatible with this OptimizationView's analysis profile.",
1349 if (_random.Next(2) == 1) monetary_unit_overrides.Add(
"Date");
1350 if (_random.Next(2) == 1) monetary_unit_overrides.Add(
"Rate");
1362 string testName =
topOfStack ==
null ?
"Unknown" :
$"{topOfStack.ReflectedType?.NiceTypeName()}.{topOfStack.Name}";
1366 propertyValue =
$"Randomly Generated {obj.GetType().NiceTypeName()} for test: \"{testName}\". {Output.RandomString(1, 10, _random)}";
1368 propertyValue =
$"Randomly Generated {obj.GetType().NiceTypeName()}. {Output.RandomString(1, 10, _random)}";
1373 else if ((!
prop.PropertyType.IsValueType ||
Nullable.GetUnderlyingType(
prop.PropertyType) !=
null) &&
1387 double minimum =
gt ==
null ? Min_Random :
Math.Max(Min_Random,
1388 gt.CanEqual ?
gt.GreaterThanValue :
gt.GreaterThanValue +
interval);
1389 double maximum =
lt ==
null ? Max_Random :
Math.Min(Max_Random,
1427 throw new PropertyGenerationException(
"Failed to correctly generate property " +
1428 $"\'{prop.Name}\' for new {obj.GetType().NiceTypeName()}. Value of " +
1429 $"{Output.AutoFormat(propertyValue)} did not meet criteria of the " +
1430 $"validation attributes: {Output.AutoFormat(invalidAttributes)}.");
1456 $"{prop.PropertyType.NiceTypeName()} \'{prop.DeclaringType.NiceTypeName()}.{prop.Name}\'";
1474 $"an analysis whose analysis profile ({analysis.analysis_profile.ref_id}) does not match " +
1475 $"the current configured Reflection.Target_AnalysisProfile ({Target_AnalysisProfile.id}).");
1489 newValue = _samples.LossSet_YELTLossSet.Posted.data_file;
1492 newValue = _samples.LossSet_YLTLossSet.Posted.data_file;
1493#pragma warning disable 618
1496 "to a binary YELT because there is no sample resource with this type of data.");
1497#pragma warning restore 618
1504 $"{obj.GetType()} with a {prop.DeclaringType}.data_file to reuse.");
1512 "of this layer_view because it contains nested references to other layer_views " +
1513 "whose analysis_profiles would have to be changed as well to match.");
1517 "without setting it's portfolio reference to null first.");
1520 "without setting it's layer_views collection to null first.");
1523 "PortfolioView without changing all its layer_views to match the new analysis_profile.");
1531 "creating a duplicate analysis profile via re-post.");
1537 "AnalysisProfile without changing it's simulation to match.");
1541 "when validation is enabled, or it becomes invalid to use with this analysis profile.");
1545 "OptimizationView without changing all its domain layers to match the currency.");
1549 "\"LossNetOfAggregateTerms\" loss set with an assigned data file, " +
1550 "because its data_file may contain reinstatement information.");
1551#pragma warning disable 618
1556 "because \"LossGross\" is the only acceptable value for NestedLayerLossSets.");
1559 "with an assigned data file, because its data_file likely will not match the new data_type.");
1560#pragma warning restore 618
1563 "AttributeFilter without risking changing the type of values that are valid.");
1567 "changing its name - because the server requires each Optimization.Function to have a unique name.");
1573 sink = _samples.Layer_QuotaShare.AsReference,
1579 newValue =
fdp.payments.Select(
_ => _random.NextDouble()).ToList();
1584 currentRecursion.LogIndented(
$"A \"quick rule\" was used to change {propertyDescription} " +
1585 $"on an instance of type {obj.GetType().NiceTypeName()} from a value of " +
1586 $"{Output.AutoFormat(currentValue)} to a value of {Output.AutoFormat(newValue)}");
1593 errMessage !=
null ?
$"RandomizePropertyValue method failed: {errMessage}" :
1594 $"The new value generated is equal to the original value ({duplicateValue})";
1647 currentRecursion.LogIndented(
"Found a fallback rule for modifying the property " +
1648 "since random generation failed.");
1653 $"an instance of type {obj.GetType().NiceTypeName()} from a value of " +
1654 $"{Output.AutoFormat(currentValue)} to a value of {Output.AutoFormat(newValue)}");
1685 PostCopy(Resolve(
reference)).ToReference(
true);
1694 throw new Exception(
"PostCopy should not be used when reflection class " +
1695 "is configured for offline resource generation.");
1700 Console.WriteLine(
$"Created a copy of {resource.GetType().NiceTypeName()} {resource.id} " +
1701 $"with new id {copy.id}");
1705 #region Specific Property Generation Helper Routines
1708 private bool LayerSourcesRequireLayerReference(RecursionContext
recursionInfo) =>
1762 !
typeExclusions.Contains(
t.GetGenericArguments()[0])).OrderBy(
t => _random.NextDouble()).First();
1764 !
typeExclusions.Contains(
t.GetGenericArguments()[0].GetGenericArguments()[0]))
1765 .OrderBy(
t => _random.NextDouble()).First();
1771 int roll = _random.Next(5);
1780 .Change(
l =>
l.id,
null).ToReference();
1795 bool modified =
false;
1798 if (
temp.analysis_profile.ref_id !=
owner.analysis_profile.ref_id)
1800 temp.analysis_profile =
owner.analysis_profile;
1807 recursionInfo.LogIndented(
"Warning: The generated PortfolioView.layer_views list " +
1808 "contained a randomly generated layer that was not compabile with the " +
1809 "target analysis profile. This should no longer be happening. " +
1810 "As a workaround, the invalid layer has been removed: " +
temp.layer.Serialize());
1850 Resolve(layer), Resolve(
owner.analysis_profile)));
1881 currentLayer.description =
"Required for Optimization";
1899 min = _random.Next(-2000, 2000) / 1000
d,
1902 newDomainEntry.max = _random.Next(10) == 0 ? newDomainEntry.min :
1926 .Select(
t =>
t.s).ToArray();
1928 Assert.Fail(
"Reflection-based LossFilter generation error: Could not find " +
1929 "a numeric column for making a filter of type " +
owner.GetType().NiceTypeName());
1938 string[]
headers = csv.Substring(0, csv.IndexOf(
'\n')).Split(
',');
1943 .Select(
t => (
int?)
t.i).FirstOrDefault();
1944 if (!index.HasValue)
1945 Assert.Fail(
"Reflection-based LossFilter generation error: Could not find " +
1946 "the randomly assigned LossFilter attribute name.");
1953 List<string> values = csv.Split(
'\n').Select(r => r.Split(
',')[index.Value])
1955 .
Skip(1).Distinct().ToList();
1957 object value =
GetStrongestType(values.ElementAt(_random.Next(values.Count)));
2008 return currencies.ElementAt(_random.Next(currencies.Count));
2039 "source_id because the sink contains no layer_view or loss set ids to reference:\n" +
2043 #endregion Specific Property Generation Helper Routines
2044 #endregion Type Specific Random Generation Helpers
2046 #region Validation Helper Methods
2088 string msg =
" to generate an acceptable " + (
property ==
null ?
"object" :
2089 $"value for the {property.ReflectedType.NiceTypeName()} property " +
2090 $"{property.DeclaringType.NiceTypeName()}.{property.Name}") +
2091 $" (type {(property?.PropertyType ?? typeof(T)).NiceTypeName()}) failed: ";
2105 recursionInfo.LogIndented(
$"Attempt {attempts}/{max_attempts} {error}");
2128 (
pi ==
property || pi.Name == property.Name &&
2131 #region Validation Against Analysis Profile
2136 analysis_profile?.exchange_rate_profile?.ref_id ==
null ?
2137 throw new ArgumentException(
"This analysis profile to has no exchange rate profile!") :
2138 _cachedValidCurrenciesByAnalysisProfile.
GetOrAdd(analysis_profile.exchange_rate_profile.ref_id,
_ =>
2141 .exchange_rate_table.GetValue();
2143 int ccyCol =
rows[0].Split(
',').Where((
col, index) =>
col.ToLower().Contains(
"currency"))
2144 .Select((
col, index) => index).First();
2146 StringComparer.InvariantCultureIgnoreCase) { fxTable.base_currency };
2193 return portfolio.layers.All(
lyr =>
2222 layerView.analysis_profile.ref_id != analysis_profile.
id)
2286#pragma warning disable 618
2292#pragma warning restore 618
2300 #endregion Validation Against Analysis Profile
2301 #endregion Validation Helper Methods
2303 #region Request Logging
2304 private int _nestedBrCalls = 0;
2307 public class TimedRequest : Tuple<DateTime, string, RecursionContext, int, int>
2333 lock (_requestTrackingLock)
2340 $"Thread {reqInfo.ThreadId} Started Request: {uniqueKey}");
2345 private void EndRequest(
string uniqueKey,
string message =
"")
2349 lock (_requestTrackingLock)
2352 if (_nestedBrCalls < 0)
2354 Debug.WriteLine(
"EndRequest called more than BeginRequest. Timings may be off.");
2359 log =
$"N:{_nestedBrCalls} Thread {reqInfo.ThreadId} " +
2360 $"Finished in {(DateTime.UtcNow - reqInfo.Start).TotalMilliseconds}ms: " +
2361 reqInfo.Description + (message ==
null ?
"" :
$" - {message}");
2365 #endregion Request Logging
2367 #region General Helper Methods
2371 private static volatile bool _isCachedAPIResourceCollectionsPopulated =
false;
2377 if (_isCachedAPIResourceCollectionsPopulated)
2378 return CachedUnsupportedTypes;
2380 lock (CachedUnsupportedTypes)
2383 if (_isCachedAPIResourceCollectionsPopulated)
2384 return CachedUnsupportedTypes;
2392 CachedUnsupportedTypes.Add(
unusable);
2394 foreach (Type
t in CachedUnsupportedTypes.ToList())
2397 _isCachedAPIResourceCollectionsPopulated =
true;
2398 return CachedUnsupportedTypes;
2422 $"Could not find any instantiable any objects of type {type.NiceTypeName()}");
2426 #region Recursive Tests
2435 if (
test(analysis))
return true;
2526#pragma warning disable 618
2536#pragma warning restore 618
2556#pragma warning disable 618
2567#pragma warning restore 618
2570 #endregion Recursive Tests
2571 #endregion General Helper Methods
Exposes the various sample CSV files as strings.
static string Loss_Set_1_Data
static string Event_Catalog_Data
static string YELTLossSet_10Trials_ForBinary
static string CustomFrequencyDistribution_Data
static string Exchange_Rate_Table
static string Static_Simulation_Data
static string CustomSeasonalityDistribution_Data
static string YELTLossSet_10Trials
static string YLTLossSet_10Trials
static string CustomSeverityDistribution_Data
static List< Fee > ListWithNestedFeeReference
Exposes sample resource objects, with built-in methods for injecting dependencies.
static readonly PollingOptions DataPollingOptions
Polling options to use when uploading a data file.
static Parameters UploadParams
The LargeDataUpload parameters to use when uploading data for test fixtures.
Test the Perspective Class.
static readonly Perspective.Base[] AllPerspectiveValues
A list of all perspective values.
static IEnumerable< Perspective > TestPerspectives
Create a list of distinct perspectives to test.
static bool IsFrequencyDistributionSafeToSimulate(IDiscreteDistribution frequencyDistribution)
We should not attempt to simulate a frequency distribution that might generate a huge number of occur...
static HashSet< Type > UnsupportedBackAllocatedLayerSinkTypes
Types that cannot be the sink of a Back-Allocated layer.
static IEnumerable< Type > PaymentPatternTypes
A list of "PaymentPattern" layer types for convenience (because they comes up in a lot of validation ...
static HashSet< Type > UnsupportedNestedSinkTypes
Types that cannot be the sink of a Nested layer.
static readonly HashSet< Type > UnsupportedOptimizationLayerTypes
The layer types which aren't supported by optimization views.
A series of generated messages and formatted strings for use in unit tests.
static string RandomString(int minLength, int maxLength, Random randomGenerator=null)
An exception throw when a random generation routine fails to produce a POSTable resource.
PropertyGenerationException(string message)
PropertyGenerationException(string message, Exception inner_exception)
Used to keep track of the recursive random generation process for objects and their attributes....
void LogIndented(string log)
Outputs the log with all newlines indented by an additional amount for every level of recursion.
RecursionContext(Type objectType, RecursionContext prior)
RecursionContext(Type objectType, int depth, RecursionContext prior)
RecursionContext(Type objectType, int depth)
RecursionContext Prior
The previous recursion context.
bool HasParent(Func< RecursionContext, bool > condition=null)
Test whether this RecursionContext has a parent. If a condition is given, returns true only if the pa...
Type Type
The type of resource being generated.
RecursionContext(Type objectType)
override string ToString()
bool MatchesCondition(Func< RecursionContext, bool > condition)
Test whether this RecursionContext or any prior matches the condition.
int Depth
The number of times we have recursed so far.
Small class to track a few properties of a request.
RecursionContext RecursionInfo
Current recursion level as determined by the caller.
int NestingLevel
Current recursion level as determined by the number of calls to "BeginRequest" without "EndRequest".
TimedRequest(DateTime start, string description, RecursionContext recursionLevel, int threadId, int nestingLevel)
A collection of filthy hacks to populate some fields of APIResources objects of any type.
bool LossSetIsValidForAnalysisProfile(LossSet to_validate, AnalysisProfile analysis_profile)
Validate that this LossSet is compatible with the current analysis profile, including recursive check...
string GetRandomCurrency()
Random currency must be a 3-character currency. In most cases, it must also be a currency for which w...
static IEnumerable< Type > GetAllInstantiableSubtypes(Type type)
Creates a list of types that can be derived from a given type.
bool AnyLayerSourceMatchesCriteria(ILayerSource rootLayerSource, Func< ILayerSource, bool > test, bool allocationSourcesOnly=false)
Recursively determines if the layer, or any inner layers it references match the specified criteria.
string PickBackAllocatedLayerSourceId(IReference< ILayerSource > sinkReference)
Finds a random source loss set or layer_view id within the specified sinkReference which can be used...
bool Validation_Enabled
When true, randomly generated properties will be validated to verify that they can be POSTed successf...
static ILayer GetLayerDefinition(ILayerSource layerSource)
Convert the ILayerSource to a layer instance by extracting the ILayerView.layer property if it is a I...
T FinalizePostedResource< T >(T posted)
Helper method for ensuring a newly posted resource is left in a finalized state.
bool ResourceIsValidForAnalysisProfile(IAPIResource to_validate, AnalysisProfile rootAp)
Validate that the specified resource is compatible with the current analysis profile (e....
T UploadResourceData< T >(T resource)
If this resource has data endpoints, try uploading some data!
IReference< IAPIResource > GetRandomExistingResource(Type T, RecursionContext currentRecursion)
Tries to find an existing (POSTed) resource of the specified type without generating a new one.
IReference< IAPIResource > GetSampleOfType(Type T)
Get a standard IInjectableResource<T> value matching the given type.
static bool IsProperty< TPropertyOwner >(PropertyInfo property, Expression< Func< TPropertyOwner, object > > propertyExpression)
Determines whether the object instance that returned the property is of the type TPropertyOwner and...
AnalysisProfile Target_AnalysisProfile
The default AnalysisProfile to use for various validation assurances.
T CreateRandomizedInstance< T >(RecursionContext parentRecursionInfo=null)
Overload of CreateRandomizedInstance that uses a compile-time type parameter and returns a strong typ...
T Resolve< T >(IReference< T > reference)
Resolves a reference in a way that benefits from caching, so that the same reference value never has ...
bool AnyLayerMatchesCriteria(ILayerSource rootlayerSource, Func< ILayer, bool > test, bool allocationSourcesOnly=false)
Recursively determines if the layer, or any inner layers it references match the specified criteria.
static T LimitAttempts< T >(Func< T > generator, Func< T, bool > validation_test, Func< string > get_error, PropertyInfo property=null, int max_attempts=Max_ReRandomize_Attempts, bool exception_on_failure=true, RecursionContext recursionInfo=null)
Attempt to generate a resource randomly, with some validation to see if the attempt was successful....
IReference< T > CacheResource< T >(T resource)
Cache some known posted resource so that it can be reused.
bool AnyAnalysisMatchesCriteria(IAPIAnalysis analysis, Func< IAPIAnalysis, bool > test)
Recursively determines if the layer, or any inner layers it references match the specified criteria.
Reflection(Samples samplesInstance=null, int? seedForRandom=null)
Instantiate a class that can be used to generate random resources via reflection.
bool AnyLossSetMatchesCriteria(LossSet root, Func< LossSet, bool > test)
Recursively determines if the loss set, or any inner loss sets it references match the specified crit...
HashSet< string > GetValidCurrenciesForAnalysisProfile(AnalysisProfile analysis_profile)
object GenerateAttributeValue(AttributeFilter owner, PropertyInfo prop)
object ChangePropertyValueRandomly(IAPIType obj, PropertyInfo prop, int max_attempts=Max_ReRandomize_Attempts, RecursionContext parentRecursionInfo=null)
Randomly change the specified property to some different value.
object CreateRandomizedInstance(Type desiredType, RecursionContext parentRecursionInfo=null)
Generates a new randomized object of the specified type.
T TryGenerate< T >(Func< T > generator, Func< T, bool > validation_test, Func< string > get_error, PropertyInfo property, bool exception_on_failure=true, RecursionContext recursionInfo=null)
Attempt to generate a resource randomly, with some validation to see if the attempt was successful....
bool LayerSourceIsValidForAnalysisProfile(ILayerSource to_validate, AnalysisProfile analysis_profile)
Validate that this ILayerSource is compatible with the current analysis profile, including recursive ...
Class used in unit tests to mark tests as skipped by using Assert.Inconclusive() method.
A custom exception class that includes the RestSharp.IRestResponse that generated the exception,...
IReference< AnalysisProfile > analysis_profile
The simulation's analysis profile.
Attribute used to define the default value assigned to the target_currency property by the server whe...
static string GetDefaultTargetCurrency(IAPIResource resource)
Determine what the default target currency will be based on the resource type and properties.
string id
The resource's unique identifier. It will be used in the request URL when requesting the resource fro...
Describes a collection of resources which can be listed.
A configuration of resources used to simulate a layer or portfolio.
IReference< Simulation > simulation
The Simulation to run.
List< IReference< LossFilter > > loss_filters
The LossFilters to bucket simulation results in.
List< IReference< EventCatalog > > event_catalogs
The EventCatalogs to use during this simulation.
Specifies that the property with this attribute should be greater than the specified amount.
Specifies that the property with this attribute should be less than the specified amount.
Specifies that the property with this attribute cannot be null when POSTing the resource to the serve...
Indicates that while the current APIResource-derived class can be constructed and potentially inlined...
Any attribute that can validate the value of a property.
Represents a file that has been uploaded to the server, usually in conjunction with some other resour...
Custom Distribution that describes a parametric loss set's frequency.
Custom Distribution that describes a parametric loss set's seasonality.
Custom Distribution that describes a parametric loss set's severity.
Representation of an event catalog. The event catalog may cover multiple region/perils,...
A rule indicating that the latest available exchange rate should be used.
A table containing exchange rate information.
Acts as a replacement for IAPIResourceView.back_allocations. Computes the proportion of some sink str...
A "delayed payment" payment pattern models claims being paid in instalments at specific dates followi...
List< double > payments
A list of fractional amounts, denoting how a loss amount will be split into payments....
A wrapper for a List<T> of IReference<ILayerSource> references that simplifies the construction and u...
Allows one or more source layers or layer_views to be attached as loss sources to some other layer de...
IReference< ILayerSource > sink
The layer that will take on the sources' forwarded losses.
Layer Policy is the rule on RecordType that determines how occurrences belonging to a particular Reco...
Surfaces the value-allocator specialty structure (which is treated as a "layer definition" by the API...
Perspective
The loss perspectives that can be used when computing proportions (proportioned_perspective) and allo...
A predicate that determines whether a loss should be included in the perspective or not.
A filter that does a test on some attribute.
string attribute
The attribute that is being filtered on.
A filter where the specified attribute's value is compared to some predetermined value.
A filter where the specified attribute must have a numeric value that is within the specified range o...
double begin_value
Values must be greater than this value to be included.
Attribute used to define the default value for the loss_type property.
static LossType GetDefaultLossTypeForLossSet(ILossSet lossSet)
Indicates what the default loss type would be for a given loss set.
Base class for all LossSet sub-types. A LossSet is a resource that generates sample (trial) losses wh...
Representation of a single loss set with an associated event loss table.
Representation of a Loaded loss set, whose losses are derived from an existing loss set and applies a...
Base for all conventional loss sets, which generate losses, have a server-generated loss profile,...
Base for all loss sets for which pre-generated loss data must be uploaded.
IReference< DataFile > data_file
A reference to the data attached to this resource. This field will automatically be created if you in...
Representation of a Nested layer loss set, which represents any loss set whose losses are derived fro...
Representation of a Parametric loss set.
The Quantile-Based Correlated Loss Sampling (QCLS) loss set is a simulated parametric loss set which ...
Representation of a loss set with an associated year-event-loss table.
DataType
The format of the data uploaded against this YELT.
Representation of a loss set with an associated simulated yearly losses table.
Representation of a monetary value with a currency.
A structure indicating the min/max share constraint for a layer.
The base class for custom optimization functions.
Representation of a set of Optimization Parameters.
The loss perspective determines what factors to include when computing a distribution.
Base
The set of available values and RecordTypes that can be used to construct a distribution or metrics r...
static Perspective FromEnums(params Base[] perspectives)
Construct a new Perspective that should include the specified Base perspective value or values.
Represents the Analysis of a Portfolio.
IReference< StaticPortfolio > portfolio
The portfolio from which this portfolioView was constructed. Can be supplied by the user on POST inst...
HashSet< IReference< ILayerView > > layer_views
The LayerViews included in this PortfolioView. Must be supplied when posting a new PortfolioView,...
Representation of a portfolio.
Representation of a simulation of a set of trials each representing an event occurrence sequence.
Representation of a portfolio.
A pre-simulated representation of a Simulation (SimGrid).
Utilities that reflect on a type or property expression.
Utility for resolving types given only the types name (Useful for parsing ambiguous JSON objects).
static List< Type > GetAllInstantiableSubtypes(Type type)
Attempts to create a list of types in the current application domain's assemblies derived from the gi...
static Type GetEnumerableType(Type type)
If the specified type implements IEnumerable<T>, returns the generic type argument....
Interface for resources that reference an analysis profile.
IReference< AnalysisProfile > analysis_profile
The analysis profile used to analyze the resource.
string target_currency
The default currency results are returned in. If not specified, the server will automatically select ...
Describes an APIResource class that adds a "/data" sub-resource, since this functionality is common t...
Describes an APIResource class that has a "status" property and corresponding "status_message" which ...
Interface for Base class used by all stored resources.
Represents any distribution that is discrete. With a discrete probability distribution,...
PortfolioView and LayerView interface.
Interface for Base class used by all resources.
Interface shared by all object types and resources returned by the Analyze Re server.
An interface for an object that provides access to some layer instance.
Represents the Analysis of a Layer.
ILayer layer
The layer contained in this LayerView.
Abstract representation of a layer.
Base interface for all reference entities.
Abstract representation of a layer with terms.
Abstract representation of a layer with terms.
DateTime? inception_date
The date and time when the contract takes effect.
An interface for pre-simulated loss sets some data associated with them, some hard-coded seasonality ...
Base for all conventional loss sets, which generate losses, have a server-generated loss profile,...
LossType
Indicates what types of losses are generated by this loss set.
@ currency
Reinstatement values represent a fixed dollar amount.
TaskStatus
The status of a data upload which may be in progress.
RecordType
The type of occurrence.