示例#1
0
def test_multiple_profiles(bpf_program: BPFProgram, caplog):
    """
    Make sure that multiple profiles are created properly.
    """
    ls = which('ls')
    ps = which('ps')

    # There should be one profile after this
    subprocess.Popen(ls).wait()

    assert len(bpf_program.bpf['profiles']) >= 1

    # There should be two profiles after this
    subprocess.Popen(ps).wait()

    assert len(bpf_program.bpf['profiles']) >= 2

    # Make sure we can look up the profile by its key
    profile_key = calculate_profile_key(ls)
    bpf_program.bpf['profiles'][ct.c_uint64(profile_key)]
    # Make sure the profile has the correct name associated with it
    bpf_program.on_tick()
    assert bpf_program.profile_key_to_exe[profile_key] in ['ls', ls]

    # Make sure we can look up the profile by its key
    profile_key = calculate_profile_key(ps)
    bpf_program.bpf['profiles'][ct.c_uint64(profile_key)]
    # Make sure the profile has the correct name associated with it
    bpf_program.on_tick()
    assert bpf_program.profile_key_to_exe[profile_key] in ['ps', ps]
示例#2
0
def test_normal(bpf_program: BPFProgram, caplog):
    """
    Make sure that profiles normalize properly.
    """
    hello = project_path('tests/driver/hello')

    # Set normal wait so that we normalize right away
    bpf_program.change_setting(EBPH_SETTINGS.NORMAL_WAIT, 0)

    # Spawn several hello processes so that we can freeze AND normalize
    for _ in range(50):
        subprocess.Popen(hello, stdout=subprocess.DEVNULL).wait()
        bpf_program.on_tick()

    assert len(bpf_program.bpf['profiles']) >= 1

    # Fetch the profile for hello
    profile_key = calculate_profile_key(hello)
    profile = bpf_program.get_profile(profile_key)

    # We should now be normal
    assert profile.status & EBPH_PROFILE_STATUS.NORMAL
    assert not (profile.status &
                (EBPH_PROFILE_STATUS.FROZEN | EBPH_PROFILE_STATUS.TRAINING))
    assert profile.anomaly_count == 0
示例#3
0
def test_freeze(bpf_program: BPFProgram, caplog):
    """
    Make sure that profiles freeze properly.
    """
    hello = project_path('tests/driver/hello')

    # We want normal wait to be pretty high, but not so high that it wraps
    # around when the BPF program adds it to the current time.
    #
    # FIXME: We probably want to add a hard limit for normal wait
    # in the BPF program itself, since it probably doesn't make sense
    # to have normal wait be super long regardless.
    bpf_program.change_setting(EBPH_SETTINGS.NORMAL_WAIT, 2**60)

    # Spawn several hello processes so that we can freeze
    for _ in range(50):
        subprocess.Popen(hello, stdout=subprocess.DEVNULL).wait()
        bpf_program.on_tick()

    assert len(bpf_program.bpf['profiles']) >= 1

    # Fetch the profile for hello
    profile_key = calculate_profile_key(hello)
    profile = bpf_program.get_profile(profile_key)

    # We should be frozen with zero anomalies
    assert profile.status & (EBPH_PROFILE_STATUS.FROZEN
                             | EBPH_PROFILE_STATUS.TRAINING)
    assert not (profile.status & EBPH_PROFILE_STATUS.NORMAL)
    assert profile.anomaly_count == 0
示例#4
0
def test_one_profile(bpf_program: BPFProgram, caplog):
    """
    Make sure that a single profile is created properly.
    """
    ls = which('ls')

    # There should be at least one profile after this
    subprocess.Popen(ls).wait()

    assert len(bpf_program.bpf['profiles']) >= 1

    # Make sure we can look up the profile by its key
    profile_key = calculate_profile_key(ls)
    bpf_program.bpf['profiles'][ct.c_uint64(profile_key)]

    # Force a tick update here
    bpf_program.on_tick()

    # Make sure the profile has the correct name associated with it
    assert bpf_program.profile_key_to_exe[profile_key] in ['ls', ls]
示例#5
0
def test_sample_workload(bpf_program: BPFProgram, caplog):
    """
    Test profile creation for several processes executed within a shell script.
    """
    sample_workload = project_path('tests/driver/sample_workload.sh')
    subprocess.Popen(sample_workload).wait()

    # Profiles should at least include the following:
    profile_names = ['bash', 'ls', 'wc', 'ps', 'cat', 'echo', 'grep']
    profile_locations = [which(n) for n in profile_names]

    assert len(bpf_program.bpf['profiles']) >= 7

    # Force a tick update here
    bpf_program.on_tick()

    for n, p in zip(profile_names, profile_locations):
        # Make sure we can look up the profile by its key
        profile_key = calculate_profile_key(p)
        bpf_program.bpf['profiles'][ct.c_uint64(profile_key)]
        # Make sure the profile has the correct name associated with it
        assert bpf_program.profile_key_to_exe[profile_key] in [n, p]
示例#6
0
def test_anomaly(bpf_program: BPFProgram, caplog):
    """
    Make sure that anomalies in normal profiles are detected.
    """
    hello = project_path('tests/driver/hello')

    # Set normal wait so that we normalize right away
    bpf_program.change_setting(EBPH_SETTINGS.NORMAL_WAIT, 0)

    # Spawn several hello processes so that we can freeze AND normalize
    for _ in range(50):
        subprocess.Popen(hello, stdout=subprocess.DEVNULL).wait()
    bpf_program.on_tick()

    assert len(bpf_program.bpf['profiles']) >= 1

    # Fetch the profile for hello
    profile_key = calculate_profile_key(hello)
    profile = bpf_program.get_profile(profile_key)

    assert profile.status & EBPH_PROFILE_STATUS.NORMAL
    assert not (profile.status &
                (EBPH_PROFILE_STATUS.FROZEN | EBPH_PROFILE_STATUS.TRAINING))
    assert profile.anomaly_count == 0

    # This will cause an anomaly
    subprocess.Popen([hello, 'foo'], stdout=subprocess.DEVNULL).wait()
    bpf_program.on_tick()

    # Fetch profile again
    profile = bpf_program.get_profile(profile_key)

    # We should have seen an anomaly for the write system call
    # (as well as some others (e.g. EXIT_GROUP), but don't test for that)
    assert profile.anomaly_count > 0
    assert 'Anomalous WRITE' in caplog.text