0%

修改peach源码

一、解析xml到dom

1、任何元素节点都要定义一个类,在Dom文件夹下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
namespace Peach.Core.Dom
{
[PitParsable("Field")]
public class Field : DataElement
{
public Field(string name) : base(name) { }

public static DataElement PitParser(PitParser context, XmlNode node, DataElementContainer parent)
{
var fieldName = node.getAttrString("name");
var fieldValue = node.getAttrString("value");

var field = new Field(fieldName);
field.DefaultValue = new Variant(fieldValue);

return field;
}
}
}

最重要的就是标记能被解析到,然后有个解析函数PitParser

2、PitParser解析,在Peach.Core.Analyzers

1
2
dataModelPitParsable["DataModel"] = typeof(DataModel);
dataElementPitParsable["Field"] = typeof(Field);

主要就是存储元素节点的字典,根据name获取解析方法解析。

然后,在handlePeach函数中添加相应节点的处理逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Pass 2 - 解析 ConfigModel
foreach (XmlNode child in node.ChildNodes)
{
if (child.Name == "ConfigModel")
{
var config = handleConfigModel(child, null);
if (config != null)
{
try
{
dom.confcigModels.Add(config.name, config);
}
catch (ArgumentException)
{
var entry = dataModelPitParsable.Where(kv => kv.Value == config.GetType()).Select(kv => kv.Key).FirstOrDefault();
var name = entry != null ? "<" + entry + ">" : "Config Model";
throw new PeachException("Error, a " + name + " element named '" + config.name + "' already exists.");
}
}
}
}

其中,dom类中需要增加相应变量的支持,比如confcigModels集合

  • Dom

    • Dom 是整个解析后的文档对象模型,包含所有的顶级元素,例如 StateModel、Agent、Publisher 等。
    • 它是全局的,存储了所有解析后的对象。
  • Test

    • Test 是 Dom 的一个子集,表示一个具体的测试配置。
    • 它引用了 Dom 中的某些对象(如 StateModel 和 Publisher),并将它们存储在自己的上下文中。

想解析存储到test中时,test类中也要有相应变量的支持。

二、测试引擎engine

取出一个configmodel来启动server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var assignedConfigKey = context.config.parallelNum % dom.configModels.Count;
ConfigModel assignedConfig = null;

int index = 0;
foreach (var key in dom.configModels.Keys)
{
if (index == assignedConfigKey)
{
assignedConfig = dom.configModels[key];
break;
}
index++;
}

Console.WriteLine("The current machine is executing the configmodel:");
Console.WriteLine(assignedConfig);


// Start agents
foreach (Dom.Agent agent in test.agents.Values)
{
// Only use agent if on correct platform
if ((agent.platform & Platform.GetOS()) != Platform.OS.None)
{
context.agentManager.AgentConnect(agent,assignedConfig);
context.agentManager.GetAgent(agent.name).SessionStarting();

// Note: We want to perfrom SessionStarting on each agent
// in turn. We do this incase the first agent starts
// a virtual machine that contains the second agent.
}
}

agent的调用链

Engine=>AgentManager=>AgentClient=>AgentServerLocal=>Agent=>monitor

AgentServerLocal继承自 AgentClient, AgentServerLocal里又有个Agent,Agent通过反射机制创建monitor的实例

三、runtime

在runtime下的ConsoleWatcher.cs可以输出迭代信息,获取覆盖率显示等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public HashSet<uint> seenPaths = new HashSet<uint>();

[DllImport("libcoverage.so")]
public static extern int get_edge_coverage_count();

[DllImport("libcoverage.so")]
public static extern uint get_path_hash();

[DllImport("libcoverage.so")]
public static extern void reset_path_hash();


protected override void Engine_IterationFinished(RunContext context, uint currentIteration)
{
int edgeHits = get_edge_coverage_count();
uint pathHash = get_path_hash();

bool isNew = seenPaths.Add(pathHash);

Console.WriteLine("[✓] Edge coverage count: " + edgeHits);
Console.WriteLine("[✓] Current path hash: 0x" + pathHash.ToString("X8") + (isNew ? " (new)" : " (duplicate)"));
Console.WriteLine("[=] Total unique paths so far: " + seenPaths.Count);

reset_path_hash();

Console.WriteLine();
}
------------- Thank you for reading -------------

Title - Artist
0:00