我们正在开发mutation testing system based on LLVM。系统支持使用GoogleTest的C ++项目,我正在尝试支持Rust。为此,我们需要完成以下步骤:
挑战在于通过LLVM IR API找到单元测试方法。
考虑the following example。它有4个测试和一个测试人员功能:
main
这是编译此Rust代码时生成的the slightly prettified LLVM IR。
在探索了LLVM IR一段时间之后,人们可以注意到Rust / Cargo通过调用test_main_static
函数的函数public class Utilities {
static boolean availability;
static FirebaseDatabase fireDb = FirebaseDatabase.getInstance();
static DatabaseReference dbRef1;
private static boolean checkAvailability(String ID) {
/**check in firebase if the generated ID exists. if it exists return false, else return true**/
final String id = ID;
availability = true;
dbRef1 = fireDb.getReference("xdsdads");
dbRef1.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
try {
if (dataSnapshot.hasChild(id) || dataSnapshot.hasChild("Room:" + id)) {
Log.d("key", "Key exists!");
availability = false;
} else {
availability = true;
}
} catch (Exception e) {
Log.d("Error", "error getting key" + e.toString());
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Log.d("Availability","" + availability);
return availability;
}
public static String generateID() {
/**generates ID **/
String ID = "";
Random random = new Random();
for (int i = 0; i < 8; i++) {
if (i < 4) {
ID = ID + giveAlphabet(random.nextInt(26));
} else {
ID = ID + random.nextInt(9);
}
}
Log.d("ID",ID);
if (checkAvailability(ID)) {
return ID;
} else {
return generateID();
}
}
public static String giveAlphabet(int i) {
/**returns an alphabet from A-Z**/
String[] alphabet = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
String output = "";
try {
if (i >= 0 && i < 26) {
output = alphabet[i];
} else {
throw new Exception("Value not between 0-26 cannot generate Alphabet");
}
} catch (Exception e) {
Log.d("Exception at Beacon", e.toString());
}
return output;
}
运行测试,该函数给出了描述数组。每个描述都是一对测试函数名称和测试函数指针。 See the @ref.e
at line 47
我们的挑战是通过解析这个复杂的结构布局来收集这些测试的函数指针,以便稍后我们可以通过LLVM JIT为它们提供我们积累的函数指针来运行这些函数。
我们将采用的明显的暴力方法是运行此结构布局并仔细解析结构并找到测试函数的正确偏移量。这种方法似乎无法在不同版本的Rust或LLVM IR中移植,可能在将来发生变化。
除了手动解析偏移的默认值之外,找到测试函数指针的最简单且同时可靠的方法是什么?
答案 0 :(得分:1)
我made it work使用我在问题中概述的蛮力方法。使用LLVM C ++ API,我们:
test_main_static
@ref.e
test_main_static
的引用
@ref.e
结构并找到测试函数指针这种方法似乎有效但我们仍担心它可能无法在不同版本的Rust / LLVM中移植。我们接下来的步骤之一是实现rustc --test
生成的LLVM IR的完整性检查。另一个步骤是在实际代码库上尝试这个RustTestFinder
,看看我们是否有任何问题。
我仍然感谢rustc --test
生成的有关LLVM IR的任何信息,这些信息可以使事情变得更加直截了当。