Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit add11e91 authored by Yi Jin's avatar Yi Jin
Browse files

Add tests for reporter class

Test: Add test for Reporter class
Change-Id: Ic1d87a26dd4b8271bab7b03374c7a1d4d7b87f92
parent 8cb47b9a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -79,7 +79,10 @@ LOCAL_SRC_FILES := \
    src/Reporter.cpp \
    src/Section.cpp \
    src/protobuf.cpp \
    src/report_directory.cpp \
    src/section_list.cpp \
    tests/FdBuffer_test.cpp \
    tests/Reporter_test.cpp \
    tests/Section_test.cpp \

LOCAL_STATIC_LIBRARIES := \
+1 −2
Original line number Diff line number Diff line
@@ -153,7 +153,6 @@ ReportHandler::run_report()
            break;
        }
        reporter->batch.add(request);
        reporter->args.merge(request->args);
    }

    // Take the report, which might take a while. More requests might queue
+33 −16
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@
/**
 * The directory where the incident reports are stored.
 */
static const String8 INCIDENT_DIRECTORY("/data/misc/incidents");
static const char* INCIDENT_DIRECTORY = "/data/misc/incidents/";

// ================================================================================
static status_t write_all(int fd, uint8_t const* buf, size_t size)
@@ -68,6 +68,7 @@ ReportRequest::~ReportRequest()
// ================================================================================
ReportRequestSet::ReportRequestSet()
    :mRequests(),
     mSections(),
     mWritableCount(0),
     mMainFd(-1)
{
@@ -77,10 +78,12 @@ ReportRequestSet::~ReportRequestSet()
{
}

// TODO: dedup on exact same args and fd, report the status back to listener!
void
ReportRequestSet::add(const sp<ReportRequest>& request)
{
    mRequests.push_back(request);
    mSections.merge(request->args);
    mWritableCount++;
}

@@ -122,11 +125,16 @@ ReportRequestSet::write(uint8_t const* buf, size_t size)
    return mWritableCount > 0 ? NO_ERROR : err;
}

bool
ReportRequestSet::containsSection(int id) {
    return mSections.containsSection(id);
}

// ================================================================================
Reporter::Reporter()
    :args(),
     batch()
Reporter::Reporter() : Reporter(INCIDENT_DIRECTORY) { isTest = false; };

Reporter::Reporter(const char* directory)
    :batch()
{
    char buf[100];

@@ -134,10 +142,15 @@ Reporter::Reporter()
    mMaxSize = 100 * 1024 * 1024;
    mMaxCount = 100;

    // string ends up with '/' is a directory
    String8 dir = String8(directory);
    if (directory[dir.size() - 1] != '/') dir += "/";
    mIncidentDirectory = dir.string();

    // There can't be two at the same time because it's on one thread.
    mStartTime = time(NULL);
    strftime(buf, sizeof(buf), "/incident-%Y%m%d-%H%M%S", localtime(&mStartTime));
    mFilename = INCIDENT_DIRECTORY + buf;
    strftime(buf, sizeof(buf), "incident-%Y%m%d-%H%M%S", localtime(&mStartTime));
    mFilename = mIncidentDirectory + buf;
}

Reporter::~Reporter()
@@ -161,7 +174,7 @@ Reporter::runReport()
    }
    if (needMainFd) {
        // Create the directory
        err = create_directory(INCIDENT_DIRECTORY);
        if (!isTest) err = create_directory(mIncidentDirectory);
        if (err != NO_ERROR) {
            goto done;
        }
@@ -169,7 +182,7 @@ Reporter::runReport()
        // If there are too many files in the directory (for whatever reason),
        // delete the oldest ones until it's under the limit. Doing this first
        // does mean that we can go over, so the max size is not a hard limit.
        clean_directory(INCIDENT_DIRECTORY, mMaxSize, mMaxCount);
        if (!isTest) clean_directory(mIncidentDirectory, mMaxSize, mMaxCount);

        // Open the file.
        err = create_file(&mainFd);
@@ -214,7 +227,7 @@ Reporter::runReport()
        const int id = (*section)->id;
        ALOGD("Taking incident report section %d '%s'", id, (*section)->name.string());

        if (this->args.containsSection(id)) {
        if (this->batch.containsSection(id)) {
            // Notify listener of starting
            for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) {
                if ((*it)->listener != NULL && (*it)->args.containsSection(id)) {
@@ -270,7 +283,7 @@ done:
        // If the status was ok, delete the file. If not, leave it around until the next
        // boot or the next checkin. If the directory gets too big older files will
        // be rotated out.
        unlink(mFilename.c_str());
        if(!isTest) unlink(mFilename.c_str());
    }

    return REPORT_FINISHED;
@@ -284,7 +297,7 @@ Reporter::create_file(int* fd)
{
    const char* filename = mFilename.c_str();

    *fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0660);
    *fd = open(filename, O_CREAT | O_TRUNC | O_RDWR | O_CLOEXEC, 0660);
    if (*fd < 0) {
        ALOGE("Couldn't open incident file: %s (%s)", filename, strerror(errno));
        return -errno;
@@ -303,20 +316,24 @@ Reporter::create_file(int* fd)
    return NO_ERROR;
}

// ================================================================================
Reporter::run_report_status_t
Reporter::upload_backlog()
{
    DIR* dir;
    struct dirent* entry;
    struct stat st;
    status_t err;

    if ((err = create_directory(INCIDENT_DIRECTORY)) != NO_ERROR) {
        ALOGE("directory doesn't exist: %s", strerror(-err));
        return REPORT_FINISHED;
    }

    if ((dir = opendir(INCIDENT_DIRECTORY.string())) == NULL) {
        ALOGE("Couldn't open incident directory: %s", INCIDENT_DIRECTORY.string());
    if ((dir = opendir(INCIDENT_DIRECTORY)) == NULL) {
        ALOGE("Couldn't open incident directory: %s", INCIDENT_DIRECTORY);
        return REPORT_NEEDS_DROPBOX;
    }

    String8 dirbase(INCIDENT_DIRECTORY + "/");
    sp<DropBoxManager> dropbox = new DropBoxManager();

    // Enumerate, count and add up size
@@ -324,7 +341,7 @@ Reporter::upload_backlog()
        if (entry->d_name[0] == '.') {
            continue;
        }
        String8 filename = dirbase + entry->d_name;
        String8 filename = String8(INCIDENT_DIRECTORY) + entry->d_name;
        if (stat(filename.string(), &st) != 0) {
            ALOGE("Unable to stat file %s", filename.string());
            continue;
+7 −1
Original line number Diff line number Diff line
@@ -62,8 +62,10 @@ public:
    iterator begin() { return mRequests.begin(); }
    iterator end() { return mRequests.end(); }

    bool containsSection(int id);
private:
    vector<sp<ReportRequest>> mRequests;
    IncidentReportArgs mSections;
    int mWritableCount;
    int mMainFd;
};
@@ -77,10 +79,10 @@ public:
        REPORT_NEEDS_DROPBOX = 1
    };

    IncidentReportArgs args;
    ReportRequestSet batch;

    Reporter();
    Reporter(const char* directory);
    virtual ~Reporter();

    // Run the report as described in the batch and args parameters.
@@ -89,12 +91,16 @@ public:
    static run_report_status_t upload_backlog();

private:
    String8 mIncidentDirectory;

    string mFilename;
    off_t mMaxSize;
    size_t mMaxCount;
    time_t mStartTime;

    status_t create_file(int* fd);

    bool isTest = true; // default to true for testing
};


+1 −1
Original line number Diff line number Diff line
@@ -424,7 +424,7 @@ CommandSection::Execute(ReportRequestSet* requests) const
    status_t cmdStatus = waitForChild(cmdPid);
    status_t ihStatus  = waitForChild(ihPid);
    if (cmdStatus != NO_ERROR || ihStatus != NO_ERROR) {
        ALOGW("CommandSection '%s' abnormal child processes, return status: command: %s, incidnet helper: %s",
        ALOGW("CommandSection '%s' abnormal child processes, return status: command: %s, incident helper: %s",
            this->name.string(), strerror(-cmdStatus), strerror(-ihStatus));
        return cmdStatus != NO_ERROR ? cmdStatus : ihStatus;
    }
Loading