blob: 1e2e762520845e199b32ee53acd103031b06d180 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <stdio.h>
#include <fuzz-utils/fuzzer.h>
#include <fuzz-utils/path.h>
#include <zircon/types.h>
#include "fuzzer-fixture.h"
namespace fuzzing {
namespace testing {
// |fuzzing::testing::Fuzzer| exposes internal APIs for testing and buffers output.
class TestFuzzer : public Fuzzer {
public:
TestFuzzer();
~TestFuzzer() override;
const FuzzerFixture& fixture() const { return fixture_; }
// Resets the out and err buffers to be unallocated.
void Reset() override;
// Sets up the test fuzzer to buffer output with a Zircon-standalone test fixture
bool InitZircon();
// Sets up the test fuzzer to buffer output with a test fixture of Fuchsia packages
bool InitFuchsia();
// Resets |test| and reconstructs it from the |cmdline| in the context of the current fixture.
zx_status_t Eval(const char* cmdline);
// Returns the value associated with the given |key|, or null if unset.
const char* GetOption(const char* key) { return options().get(key); }
// Invoke the base method with the saved arguments.
zx_status_t Run() { return Fuzzer::Run(&args_); }
// Checks if the (case-insensitive) substring is in the buffered output
bool InStdOut(const char* needle);
bool InStdErr(const char* needle);
// Returns the index in "argv" of the arg produced from |fmt| and any variadic parameters, or -1
// if it isn't found.
int FindArg(const char* fmt, const fbl::String& arg);
int FindArg(const fbl::String& arg) { return FindArg("%s", arg); }
// Various fixture locations
const char* executable() const { return executable_.c_str(); }
const char* manifest() const { return manifest_.c_str(); }
const char* dictionary() const { return dictionary_.c_str(); }
const char* data_path() const { return data_path_.c_str(); }
fbl::String data_path(const char* relpath) { return data_path_.Join(relpath); }
// Expose parent class methods
zx_status_t SetOption(const fbl::String& option) { return Fuzzer::SetOption(option); }
zx_status_t SetOption(const fbl::String& key, const fbl::String& val) {
return Fuzzer::SetOption(key, val);
}
zx_status_t RebasePath(const fbl::String& package, Path* out) {
return Fuzzer::RebasePath(package, out);
}
zx_status_t GetPackagePath(const fbl::String& package, Path* out) {
return Fuzzer::GetPackagePath(package, out);
}
void FindZirconFuzzers(const fbl::String& zircon_path, const fbl::String& target,
StringMap* out) {
Fuzzer::FindZirconFuzzers(zircon_path, target, out);
}
void FindFuchsiaFuzzers(const fbl::String& package, const fbl::String& target, StringMap* out) {
Fuzzer::FindFuchsiaFuzzers(package, target, out);
}
void FindFuzzers(const fbl::String& name, StringMap* out) { Fuzzer::FindFuzzers(name, out); }
// Exposes |Fuzzer::CheckProcess| optionally overriding the executable name to look for.
bool CheckProcess(zx_handle_t process, const char* executable = nullptr);
protected:
// Overrides |Fuzzer::Execute| to simply save the subprocess' command line without spawning it.
zx_status_t Execute() override;
private:
// Sets up the test fuzzer to buffer output without changing the test fixture
bool Init();
// The current test fixture
FuzzerFixture fixture_;
// The arguments passed to the subprocess
StringList args_;
// Test info, captured by |Execute|
fbl::String executable_;
fbl::String manifest_;
fbl::String dictionary_;
Path data_path_;
// Output stream
FILE* out_;
char* outbuf_;
size_t outbuflen_;
// Error stream
FILE* err_;
char* errbuf_;
size_t errbuflen_;
};
} // namespace testing
} // namespace fuzzing