示例#1
0
def test_environ_and_suppressions(monkeypatch, tmpdir):
    ""
    run_called = [0]

    class MyReductionJob(ReductionJob):

        def run(self, *args, **kwds):
            assert len(self.interesting.env_mod) == 2
            assert "GRZ_FORCED_CLOSE" in self.interesting.env_mod
            assert self.interesting.env_mod["GRZ_FORCED_CLOSE"] == "0"
            assert not self.interesting.target.forced_close
            assert "LSAN_OPTIONS" in self.interesting.env_mod
            assert len(re.split(r":(?![\\|/])", self.interesting.env_mod["LSAN_OPTIONS"])) == 2
            assert "detect_leaks=1" in self.interesting.env_mod["LSAN_OPTIONS"]
            assert "lsan.supp" in self.interesting.env_mod["LSAN_OPTIONS"]
            run_called[0] += 1

    status = ReduceStatus.start()
    job = MyReductionJob([], FakeTarget(), 60, False, False, 0, 1, 1, 3, 25, 60, status, None, False)
    monkeypatch.setattr(reduce, "ReductionJob", lambda *a, **kw: job)
    assert job.interesting.target.forced_close

    exe = tmpdir.ensure("binary")
    inp = tmpdir.ensure("input", dir=True)
    inp.ensure("env_vars.txt").write("LSAN_OPTIONS=detect_leaks=1\nGRZ_FORCED_CLOSE=0")
    inp.ensure("test_info.txt").write("landing page: test.html")
    inp.ensure("lsan.supp").write("foo")
    inp.ensure("test.html").write("fluff\nrequired\n")
    args = ReducerArgs().parse_args([exe.strpath, inp.strpath])
    reduce.main(args)
    assert run_called[0] == 1
示例#2
0
def test_main_strategies(job, monkeypatch, tmp_path):  # noqa pylint: disable=redefined-outer-name
    "strategies list should be respected"
    # uses the job fixture from test_reduce which reduces testcases to the string "required\n"
    monkeypatch.setattr(reduce, "ReductionJob", lambda *a, **kw: job)
    report_data = {"num_reports": 0}

    class FakeReporter(BaseFakeReporter):

        def __init__(self, *args, **kwds):
            super(FakeReporter, self).__init__(*args, **kwds)
            self.report_path = "foo"

        def _submit(self, _report, test_cases):
            assert len(test_cases) == 1, "too many test_cases: %r" % (test_cases,)
            tc = test_cases[0]
            assert len(tc._files.required) == 1, \
                "too many test_files: %r" % (tc._files.required,)
            assert tc.landing_page == "test.html"
            assert tc._files.required[0].data == b"'xxrequired'\n"
            report_data["num_reports"] += 1
    monkeypatch.setattr(reduce, "FilesystemReporter", FakeReporter)

    (tmp_path / "binary").touch()
    exe = tmp_path / "binary"
    (tmp_path / "input").mkdir()
    inp = tmp_path / "input"
    (inp / "test_info.txt").write_text("landing page: test.html")
    (inp / "test.html").write_bytes(b"fluff\n'xxrequired'\n")
    args = ReducerArgs().parse_args([str(exe), str(inp), "--strategy", "line"])
    assert reduce.main(args) == 0
    assert report_data["num_reports"] == 1
示例#3
0
def test_main_prefs(monkeypatch, tmp_path):
    "cmd line prefs should override prefs in the testcase"
    monkeypatch.setattr(reduce, "Interesting", FakeInteresting)
    run_called = [0]

    class MyReductionJob(ReductionJob):

        def run(self, *args, **kwds):
            result = ReductionJob.run(self, *args, **kwds)
            with open(self.interesting.target.prefs) as prefs_fp:
                assert "main prefs" == prefs_fp.read()
            run_called[0] += 1
            return result

    status = ReduceStatus.start()
    job = MyReductionJob([], FakeTarget(), 60, False, False, 0, 1, 1, 3, 25, 60, status, None, False)
    monkeypatch.setattr(reduce, "ReductionJob", lambda *a, **kw: job)

    (tmp_path / "binary").touch()
    exe = tmp_path / "binary"
    (tmp_path / "input").mkdir()
    inp = tmp_path / "input"
    (inp / "test_info.txt").write_text("landing page: test.html")
    (inp / "prefs.js").write_text("test prefs")
    (inp / "test.html").write_text("fluff\nrequired\n")
    (tmp_path / "prefs.js").write_text("main prefs")
    args = ReducerArgs().parse_args([str(exe), str(inp),
                                     "-p", str(tmp_path / "prefs.js")])
    assert reduce.main(args) == 0
    assert run_called[0] == 1
示例#4
0
def test_environ_and_suppressions(monkeypatch, tmp_path):
    ""
    run_called = [0]

    class MyReductionJob(TestMainReductionJob):
        __slots__ = []

        def __init__(self, *_args, **_kwds):
            super(MyReductionJob, self).__init__(tmp_path, create_binary=False)
            assert self.target.forced_close

        def run(self, *args, **kwds):
            assert len(self._env_mod) == 2
            assert "GRZ_FORCED_CLOSE" in self._env_mod
            assert self._env_mod["GRZ_FORCED_CLOSE"] == "0"
            assert not self.target.forced_close
            assert "LSAN_OPTIONS" in self._env_mod
            assert len(re.split(r":(?![\\|/])",
                                self._env_mod["LSAN_OPTIONS"])) == 2
            assert "detect_leaks=1" in self._env_mod["LSAN_OPTIONS"]
            assert "lsan.supp" in self._env_mod["LSAN_OPTIONS"]
            run_called[0] += 1

    exe = tmp_path / "binary"
    exe.touch()
    inp = tmp_path / "input"
    inp.mkdir()
    (inp / "env_vars.txt"
     ).write_text("LSAN_OPTIONS=detect_leaks=1\nGRZ_FORCED_CLOSE=0")
    (inp / "test_info.txt").write_text("landing page: test.html")
    (inp / "lsan.supp").write_text("foo")
    (inp / "test.html").write_text("fluff\nrequired\n")
    args = ReducerArgs().parse_args([str(exe), str(inp)])
    MyReductionJob.main(args)
    assert run_called[0] == 1
示例#5
0
def test_main_prefs(tmp_path):
    "cmd line prefs should override prefs in the testcase"
    run_called = [0]

    class MyReductionJob(TestMainReductionJob):
        __slots__ = []

        def __init__(self, *_args, **_kwds):
            super(MyReductionJob, self).__init__(tmp_path, create_binary=False)

        def run(self, *args, **kwds):
            result = super(MyReductionJob, self).run(*args, **kwds)
            with open(self.target.prefs) as prefs_fp:
                assert "main prefs" == prefs_fp.read()
            run_called[0] += 1
            return result

    (tmp_path / "binary").touch()
    exe = tmp_path / "binary"
    (tmp_path / "input").mkdir()
    inp = tmp_path / "input"
    (inp / "test_info.txt").write_text("landing page: test.html")
    (inp / "prefs.js").write_text("test prefs")
    (inp / "test.html").write_text("fluff\nrequired\n")
    (tmp_path / "prefs.js").write_text("main prefs")
    args = ReducerArgs().parse_args(
        [str(exe), str(inp), "-p",
         str(tmp_path / "prefs.js")])
    assert MyReductionJob.main(args) == 0
    assert run_called[0] == 1
示例#6
0
def test_main(tmp_path):  # noqa pylint: disable=redefined-outer-name
    "simple test that main functions"

    (tmp_path / "binary").touch()
    exe = tmp_path / "binary"
    (tmp_path / "input").mkdir()
    inp = tmp_path / "input"
    (inp / "test_info.txt").write_text("landing page: test.html")
    (inp / "test.html").write_text("fluff\nrequired\n")
    args = ReducerArgs().parse_args([str(exe), str(inp)])
    # uses the job fixture from test_reduce which reduces testcases to the string "required\n"
    assert TestMainReductionJob.main(args) == 0
示例#7
0
def test_main(job, monkeypatch, tmp_path):  # noqa pylint: disable=redefined-outer-name
    "simple test that main functions"
    # uses the job fixture from test_reduce which reduces testcases to the string "required\n"
    monkeypatch.setattr(reduce, "ReductionJob", lambda *a, **kw: job)

    (tmp_path / "binary").touch()
    exe = tmp_path / "binary"
    (tmp_path / "input").mkdir()
    inp = tmp_path / "input"
    (inp / "test_info.txt").write_text("landing page: test.html")
    (inp / "test.html").write_text("fluff\nrequired\n")
    args = ReducerArgs().parse_args([str(exe), str(inp)])
    assert reduce.main(args) == 0
示例#8
0
def test_parse_args(capsys, tmp_path):
    "test that grizzly.reduce args are accepted and validated"
    exe = tmp_path / "binary"
    inp = tmp_path / "input"

    # missing arg tests
    with pytest.raises(SystemExit):
        ReducerArgs().parse_args([])
    _, err = capsys.readouterr()
    with pytest.raises(SystemExit):
        ReducerArgs().parse_args([str(exe)])
    _, err = capsys.readouterr()

    # invalid binary tests
    with pytest.raises(SystemExit):
        ReducerArgs().parse_args([str(exe), str(inp)])
    _, err = capsys.readouterr()
    assert "error: file not found: %r" % (str(exe),) in err
    exe.mkdir()
    with pytest.raises(SystemExit):
        ReducerArgs().parse_args([str(exe), str(inp)])
    _, err = capsys.readouterr()
    assert "error: file not found: %r" % (str(exe),) in err
    exe.rmdir()
    exe.touch()

    # invalid input tests
    with pytest.raises(SystemExit):
        ReducerArgs().parse_args([str(exe), str(inp)])
    _, err = capsys.readouterr()
    assert "error: %r does not exist" % (str(inp),) in err
    inp.touch()
    with pytest.raises(SystemExit):
        ReducerArgs().parse_args([str(exe), str(inp)])
    _, err = capsys.readouterr()
    assert "error: Testcase should be a folder, zip, or html file" in err
    inp.unlink()
    with pytest.raises(SystemExit):
        ReducerFuzzManagerIDArgs().parse_args([str(exe), str(inp)])
    _, err = capsys.readouterr()
    assert "invalid int value" in err

    # valid binary & inputs
    (tmp_path / "input.zip").touch()
    zipf = tmp_path / "input.zip"
    ReducerArgs().parse_args([str(exe), str(zipf)])
    zipf.unlink()
    inp.mkdir()
    (inp / "test_info.txt").touch()
    ReducerArgs().parse_args([str(exe), str(inp)])
    ReducerFuzzManagerIDArgs().parse_args([str(exe), '123'])

    # sig/environ tests
    fname = tmp_path / "file.txt"
    for arg in ("--sig", "--environ"):
        with pytest.raises(SystemExit):
            ReducerArgs().parse_args([str(exe), str(inp), arg, str(fname)])
        _, err = capsys.readouterr()
        assert "error: file not found: %r" % (str(fname),) in err
        fname.mkdir()
        with pytest.raises(SystemExit):
            ReducerArgs().parse_args([str(exe), str(inp), arg, str(fname)])
        _, err = capsys.readouterr()
        assert "error: file not found: %r" % (str(fname),) in err
        fname.rmdir()
        fname.touch()
        ReducerArgs().parse_args([str(exe), str(inp), arg, str(fname)])
        fname.unlink()

    # repeat/min-crashes tests
    for arg in ("--repeat", "--min-crashes"):
        with pytest.raises(SystemExit):
            ReducerArgs().parse_args([str(exe), str(inp), arg, "abc"])
        with pytest.raises(SystemExit):
            ReducerArgs().parse_args([str(exe), str(inp), arg, "-1"])
        _, err = capsys.readouterr()
        assert "'%s' value must be positive" % (arg,) in err
        with pytest.raises(SystemExit):
            ReducerArgs().parse_args([str(exe), str(inp), arg, "0"])
        _, err = capsys.readouterr()
        assert "'%s' value must be positive" % (arg,) in err
        ReducerArgs().parse_args([str(exe), str(inp), arg, "1"])
        ReducerArgs().parse_args([str(exe), str(inp), arg, "10"])