foundationdb/contrib/TraceLogHelper/Event.cs

263 lines
8.5 KiB
C#

/*
* Event.cs
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013-2020 Apple Inc. and the FoundationDB project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
namespace Magnesium
{
public enum Severity
{
SevDebug=5,
SevInfo=10,
SevWarn=20,
SevWarnAlways=30,
SevError=40,
};
public class Event
{
public double Time { get; set; }
public Severity Severity { get; set; }
public string Type { get; set; }
public string Machine { get; set; }
public string ID { get; set; }
public string WorkerDesc { get { return Machine + " " + ID; } }
public string TraceFile { get; set; }
public System.Xml.Linq.XElement original { get; set; }
static MyExpando emptyDetails = new MyExpando(new Dictionary<string, Object>());
MyExpando _Details = emptyDetails;
public dynamic Details { get{ return _Details; } }
public IDictionary<string,Object> DDetails { get { return _Details._members; }
set {
_Details = new MyExpando(value);
//foreach(var v in value)
// _Details.SetMember(v.Key, v.Value);
}
}
public Event ShallowCopy()
{
return (Event)MemberwiseClone();
}
class MyExpando : DynamicObject
{
public MyExpando(IDictionary<string, Object> init)
{
_members = init;
}
public IDictionary<string, Object> _members =
new Dictionary<string, Object>();
/// <summary>
/// When a new property is set,
/// add the property name and value to the dictionary
/// </summary>
public override bool TrySetMember
(SetMemberBinder binder, Object value)
{
if (!_members.ContainsKey(binder.Name))
_members.Add(binder.Name, value);
else
_members[binder.Name] = value;
return true;
}
public bool SetMember(string name, Object value)
{
if (!_members.ContainsKey(name))
_members.Add(name, value);
else
_members[name] = value;
return true;
}
/// <summary>
/// When user accesses something, return the value if we have it
/// </summary>
public override bool TryGetMember
(GetMemberBinder binder, out Object result)
{
if (_members.ContainsKey(binder.Name))
{
result = _members[binder.Name];
return true;
}
else
{
return base.TryGetMember(binder, out result);
}
}
/// <summary>
/// If a property value is a delegate, invoke it
/// </summary>
public override bool TryInvokeMember
(InvokeMemberBinder binder, Object[] args, out Object result)
{
if (_members.ContainsKey(binder.Name)
&& _members[binder.Name] is Delegate)
{
result = (_members[binder.Name] as Delegate).DynamicInvoke(args);
return true;
}
else
{
return base.TryInvokeMember(binder, args, out result);
}
}
/// <summary>
/// Return all dynamic member names
/// </summary>
/// <returns>
public override IEnumerable<string> GetDynamicMemberNames()
{
return _members.Keys;
}
}
public string FormatTestError(bool includeDetails)
{
string s = Type;
if (Type == "InternalError")
s = string.Format("{0} {1} {2}", Type, Details.File, Details.Line);
else if (Type == "TestFailure")
s = string.Format("{0} {1}", Type, Details.Reason);
else if (Type == "ValgrindError")
s = string.Format("{0} {1}", Type, Details.What);
else if (Type == "ExitCode")
s = string.Format("{0} 0x{1:x}", Type, int.Parse(Details.Code));
else if (Type == "StdErrOutput")
s = string.Format("{0}: {1}", Type, Details.Output);
else if (Type == "BTreeIntegrityCheck")
s = string.Format("{0}: {1}", Type, Details.ErrorDetail);
if (DDetails.ContainsKey("Error"))
s += " " + Details.Error;
if (DDetails.ContainsKey("WinErrorCode"))
s += " " + Details.WinErrorCode;
if (DDetails.ContainsKey("LinuxErrorCode"))
s += " " + Details.LinuxErrorCode;
if (DDetails.ContainsKey("Status"))
s += " Status=" + Details.Status;
if (DDetails.ContainsKey("In"))
s += " In " + Details.In;
if (DDetails.ContainsKey("SQLiteError"))
s += string.Format(" SQLiteError={0}({1})", Details.SQLiteError, Details.SQLiteErrorCode);
if (DDetails.ContainsKey("Details") && includeDetails)
s += ": " + Details.Details;
return s;
}
};
public class TestPlan : Event
{
public string TestUID;
public string TestFile;
public int randomSeed;
public bool Buggify;
public bool DeterminismCheck;
public string OldBinary;
};
public class Test : TestPlan
{
public string SourceVersion;
public double SimElapsedTime;
public double RealElapsedTime;
public bool ok;
public int passed, failed;
public int randomUnseed;
public long peakMemUsage;
public Event[] events; // Summarized events during the test
};
public struct AreaGraphPoint
{
public double X { get; set; }
public double Y { get; set; }
};
public struct LineGraphPoint
{
public double X { get; set; }
public double Y { get; set; }
public object Category { get; set; }
};
public class Interval
{
public double Begin { get; set; }
public double End { get; set; }
public string Category { get; set; }
public string Color { get; set; }
public string Detail { get; set; }
public object Object { get; set; }
};
public class MachineRole : Interval
{
public string Machine { get; set; }
public string Role { get; set; }
};
public class Location
{
public string Name;
public int Y;
};
//Specifies the type of LocationTime being used
public enum LocationTimeOp
{
//Designates a location in the code at a particular time
Normal = 0,
//Designates that this LocationTime maps one event ID to another
MapId
};
//Struct which houses a location in the code and a time which that location was hit
//The ID signifies the particular pass through the code
//Some of these objects act as special markers used to connect one ID to another
public struct LocationTime
{
public int id;
public double Time;
public Location Loc;
public LocationTimeOp locationTimeOp;
//If locationTimeOp == MapId, then this will hold the id of the event that should come after the id specified in the id field
public int childId;
};
}