set test "Server Tests:"

# The setup_server procedure always uses a "fresh" server log file, so
# we don't need to create an empty log file that this test used to do.
global server_logfile

# Don't attempt these tests if the client/server are not available
if {! [setup_server]} then {
    untested "Server Tests"
    return
}

proc cleanup {} {
    global tmpdir
    catch {exec rm -f foo}
    catch {exec rm -fr $tmpdir}
    shutdown_server
}

# Whether the server can communicate with the client is tested in client.exp.
# Test that the the server can handle particular situations of interest.

#-------------------------------------------------------
# Building and running a simple module.
set subtest "simple"
set rc [stap_run_batch $srcdir/systemtap.server/hello.stp --use-server=$server_spec]
if {$rc == 0} { pass "$test $subtest" } else { fail "$test $subtest" }

#-------------------------------------------------------
# Try a "stap -L"
set subtest "listing"
set rc [stap_run_batch "" -L "syscall.open" --use-server=$server_spec]
if {$rc == 0} { pass "$test $subtest" } else { fail "$test $subtest" }

#-------------------------------------------------------
# Build and run a module using "-I" and "-e SCRIPT".
set subtest "tapset"
set rc [stap_run_batch "" -I $srcdir/systemtap.server/tapset -e "probe oneshot { foo() }" --use-server=$server_spec]
if {$rc == 0} { pass "$test $subtest" } else { fail "$test $subtest" }

#-------------------------------------------------------
# Build a module using stdin.
set subtest "stdin1"
set cmd {echo "probe oneshot { exit() }" | stap -vp4 --use-server=$server_spec -}
verbose -log "executing: $cmd"
set rc 0
if {[catch {eval exec $cmd} err]} {
    if {[lindex $::errorCode 0] eq "CHILDSTATUS"} {
	set rc [lindex $::errorCode 2]
    }
}
verbose -log "$err"
if {$rc} {
    fail "$test $subtest"
} else {
    pass "$test $subtest"
}

#-------------------------------------------------------
# Build another module using stdin.
set subtest "stdin2"
set cmd {stap -vp4 --use-server=$server_spec - < $srcdir/systemtap.server/hello.stp}
verbose -log "executing: $cmd"
set rc 0
if {[catch {eval exec $cmd} err]} {
    if {[lindex $::errorCode 0] eq "CHILDSTATUS"} {
	set rc [lindex $::errorCode 2]
    }
}
verbose -log "$err"
if {$rc} {
    fail "$test $subtest"
} else {
    pass "$test $subtest"
}

#-------------------------------------------------------
# Building, returning and using the uprobes.ko module.
set subtest "uprobes"
if {! [uprobes_p]} then {
    untested "$test $subtest tests"
} else {
    # First compile a test application.
    catch {exec gcc -g -o foo $srcdir/systemtap.base/jennie.c} err
    if {$err == "" && [file exists foo]} {
	pass "$test $subtest compile foo"
    } else {
	fail "$test $subtest compile foo"
    }
    set foo [exec pwd]/foo

    if {[inode_uprobes_p]} {
	# Make sure that uprobes.ko is not loaded
	catch {exec /sbin/rmmod uprobes}
    }

    # Now use the server to compile the uprobes.stp script
    set failed 1
    set tmpdir ""
    set cmd [concat stap -p4 $srcdir/$subdir/uprobes.stp $use_server -k -c $foo]
    send_log "executing: $cmd\n"
    eval spawn $cmd
    expect {
	-timeout 150
	-re {.*Keeping temporary directory \"(.*)\"\r\n} {
	    set tmpdir "$expect_out(1,string)"
	    set failed 0
	}
	-re {^.*\r\n} { exp_continue }
	timeout { 
	    kill -INT -[exp_pid] 2
	}
    }
    catch {close}; catch {wait}
    if {$failed == 0} {
	pass "$test $subtest -p4"
    } else {
	fail "$test $subtest -p4"
    }

    # Make sure that the uprobes.ko module was returned.
    if {"$tmpdir" == "" || [inode_uprobes_p]} {
	untested "$test $subtest uprobes returned"
    } else {
	if {[file exists $tmpdir/server/stap000000/uprobes/uprobes.ko]} {
	    pass "$test $subtest uprobes returned"
	} else {
	    fail "$test $subtest uprobes returned"
	}
    }

    if {! [installtest_p]} {
	untested "$test $subtest -p5";
	cleanup
	return
    }

    # Now do it again, but follow through to phase 5

    if {! [inode_uprobes_p]} {
	# Make sure that uprobes.ko is not loaded
	catch {exec /sbin/rmmod uprobes}
    }

    # Now use the server to compile and run the uprobes.stp script
    set failed 1
    set cmd {stap $srcdir/$subdir/uprobes.stp $use_server -c "$foo 1 2 3 4"}
    send_log "executing: $cmd\n"
    eval spawn $cmd
    set ok 0
    expect {
	-re {^process[^\r\n]+foo[^\r\n]+main[^\r\n]+arg[cv]=0x[0-9a-f]+\ +arg[cv]=0x[0-9a-f]+\r\n} { incr ok; exp_continue }
	-re {^process[^\r\n]+foo[^\r\n]+main[^\r\n]+return=0x0\r\n} { incr ok; exp_continue }
	-re {^[^\r\n]*\r\n} { exp_continue }
	-timeout 60
	timeout { }
	eof { }
    }
    catch {close}; catch {wait}
    if {$ok == 10} {
	pass "$test $subtest -p5"
    } else {
	fail "$test $subtest -p5 ($ok)"
    }
}

#-------------------------------------------------------
# avahi-daemon restart: PR 15872
# Make sure that the server can survive an avahi-daemon restart and still accept requests
# via avahi. We can only test this is avahi is available.
if {$avahi_ok_p != 1} {
    set dontTest 1
} else {
    set dontTest 0
}

if {$dontTest == 1} {
    untested "$test $subtest"
} else {
    set subtest "server reacts to avahi-daemon restart"
    # Notice we are using the tcl 'exec' command redirection of
    # '2>@1', which is equivalent to the shell's '2>&1'.
    if {[as_root "service avahi-daemon restart 2>@1"]} {
	# If the avahi daemon didn't restart properly, let's try to
	# fix it. If the daemon exits improperly, it can leave its pid
	# file behind which mean it can't be restarted.
	set pid_file "/run/avahi-daemon/pid"
	if {[file exists $pid_file]} {
	    verbose -log "Removing the avahi-daemon pid file"
	    as_root "rm -f $pid_file"

	    # Try to restart the daemon again.
	    if {[as_root "service avahi-daemon restart 2>@1"]} {
		# Could not restart the avahi daemon
		set dontTest 1
	    }
	} else {
	    # Could not restart the avahi daemon
	    set dontTest 1
	}
    }

    if {$dontTest == 0} {
	# Give the server time to react
	catch {exec sleep 1}
    }
}

if {$dontTest == 1} {
    untested "$test $subtest"
} else {
    set rc [catch {exec grep "Avahi client failure: Daemon connection failed" $server_logfile} result]
    if {$rc != 0} {
	fail "$test $subtest"
    } else {
	pass "$test $subtest"
    }
}

set subtest "server re-established avahi-daemon connection"
if {$dontTest == 1} {
    untested "$test $subtest"
} else {
    set rc [catch {exec grep -c {Adding Avahi service .Systemtap Compile Server.*} $server_logfile} result]
    # Make sure the target line was found more than once.
    if {$rc != 0 || $result < 2} {
	fail "$test $subtest"
    } else {
	pass "$test $subtest"
    }
}

set subtest "server still serves client requests"
if {$dontTest == 1 || ! [installtest_p]} then {
    untested "$test $subtest"
} else {
    # Contact the server directly, so that we know we're getting the one we want.
    set rc [stap_run_batch $srcdir/systemtap.server/hello.stp --use-server=$server_spec]
    if {$rc == 0} { pass "$test $subtest" } else { fail "$test $subtest" }
}

#-------------------------------------------------------
cleanup
