# Utrace compile (pass 4) tests.  We can't run these as
# testsuite/buildok tests, since if the current kernel has no utrace
# support, those will fail - but not because of a problem with
# systemtap's utrace probes (but because of the lack of utrace).  So,
# this test script checks for the existence of utrace in the kernel.
# If utrace exists in the kernel, it tries some compile tests.  If
# utrace doesn't exist in the kernel, marks the tests as 'untested'.

proc dyninst_xfails {test} {
    # Use setup_xfail <pr number> <target triplet> for known bugs.
    #
    # (Note that tcl doesn't like comments directly inside the switch
    # statement, but comments can go in sub-blocks.)
    switch $test {
	"UTRACE_P4_03 (dyninst)" -
	"UTRACE_P4_03_pid (dyninst)" -
	"UTRACE_P4_04 (dyninst)" -
	"UTRACE_P4_04_pid (dyninst)" -
	"UTRACE_P4_08 (dyninst)" -
	"UTRACE_P4_09 (dyninst)" {
	    # Use setup_xfail DYNINST <target triplet> for known
	    # failures when running with the dyninst runtime (scripts
	    # that use unimplemented features, like 'process.syscall'
	    # probes).
	    setup_xfail DYNINST *-*-*
	}
    }
}

# start a program for probes reliant on a PID
set pid [exec sleep 1h &]

# Initialize variables
set begin_script {"probe process(\"/bin/ls\").begin { print(\"ls begin\") }"}
set end_script {"probe process(\"/bin/ls\").end { print(\"ls end\") }"}
set syscall_script {"probe process(\"/bin/ls\").syscall { printf(\"|%d\", \$syscall) }"}
set syscall_parms_script {"probe process(\"/bin/ls\").syscall { printf(\"|%s\", \$\$parms) }"}
set syscall_return_script {"probe process(\"/bin/ls\").syscall.return { printf(\"|%d\", \$syscall) }"}
set thread_begin_script {"probe process(\"/bin/ls\").thread.begin { print(\"ls thread.begin\") }"}
set thread_end_script {"probe process(\"/bin/ls\").thread.end { print(\"ls thread.end\") }"}
set all_begin_script {"probe process.begin { print(\"begin\") }"}

set pid_begin_script [string map "PID $pid" {"probe process(PID).begin { print(\"PID begin\") }"}]
set pid_end_script [string map "PID $pid" {"probe process(PID).end { print(\"PID end\") }"}]
set pid_syscall_script [string map "PID $pid" {"probe process(PID).syscall { printf(\"|%d\", \$syscall) }"}]
set pid_parms_script [string map "PID $pid" {"probe process(PID).syscall { printf(\"|%s\", \$\$parms) }"}]
set pid_syscall_return_script [string map "PID $pid" {"probe process(PID).syscall.return { printf(\"|%d\", \$syscall) }"}]
set pid_thread_begin_script [string map "PID $pid" {"probe process(PID).thread.begin { print(\"PID thread.begin\") }"}]
set pid_thread_end_script [string map "PID $pid" {"probe process(PID).thread.end { print(\"PID thread.end\") }"}]

#
# Do some utrace compile tests.
#

set TEST_NAME "UTRACE_P4_01"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling a begin script using a path
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $begin_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $begin_script
	}
    }
}

set TEST_NAME "UTRACE_P4_01_pid"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling a begin script using a pid
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $pid_begin_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $pid_begin_script
	}
    }
}

set TEST_NAME "UTRACE_P4_02"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling a end script using a path
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $end_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $end_script
	}
    }
}

set TEST_NAME "UTRACE_P4_02_pid"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling a end script using a pid
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $pid_end_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $pid_end_script
	}
    }
}

set TEST_NAME "UTRACE_P4_03"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling a syscall script using a path
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    #setup_xfail DYNINST *-*-*
	    stap_compile $test 1 $syscall_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $syscall_script
	}
    }
}

set TEST_NAME "UTRACE_P4_03_pid"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling a syscall script using a pid
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $pid_syscall_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $pid_syscall_script
	}
    }
}

set TEST_NAME "UTRACE_P4_04"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling a syscall return script using a path
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $syscall_return_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $syscall_return_script
	}
    }
}

set TEST_NAME "UTRACE_P4_04_pid"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling a syscall return script using a pid
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $pid_syscall_return_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $pid_syscall_return_script
	}
    }
}

set TEST_NAME "UTRACE_P4_05"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling an thread.begin script using a path
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $thread_begin_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $thread_begin_script
	}
    }
}

set TEST_NAME "UTRACE_P4_05_pid"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling an thread.begin script using a pid
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $pid_thread_begin_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $pid_thread_begin_script
	}
    }
}

set TEST_NAME "UTRACE_P4_06"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling an thread.end script using a path
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $thread_end_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $thread_end_script
	}
    }
}

set TEST_NAME "UTRACE_P4_06_pid"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling an thread.end script using a pid
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $pid_thread_end_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $pid_thread_end_script
	}
    }
}

set TEST_NAME "UTRACE_P4_07"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling an system-wide begin script
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $all_begin_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $all_begin_script
	}
    }
}

set TEST_NAME "UTRACE_P4_08"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling a syscall parms script using a path
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $syscall_parms_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $syscall_parms_script
	}
    }
}

set TEST_NAME "UTRACE_P4_09"
if {![utrace_p]} {
    untested "$TEST_NAME : no kernel utrace support found"
} else {
    # Try compiling a syscall parms script using a pid
    foreach runtime [get_runtime_list] {
	set test "$TEST_NAME"
	if {$runtime != ""} {
	    lappend test "($runtime)"
	    ${runtime}_xfails $test
	    stap_compile $test 1 $pid_parms_script --runtime=$runtime
	} else {
	    stap_compile $test 1 $pid_parms_script
	}
    }
}

# kill the process that we were using for testing probes
kill -INT $pid 2
catch {exec {}}
