static int test_drbg_reseed(int expect_success,
                            RAND_DRBG *master,
                            RAND_DRBG *public,
                            RAND_DRBG *private,
                            int expect_master_reseed,
                            int expect_public_reseed,
                            int expect_private_reseed,
                            time_t reseed_time
                           )
{
    unsigned char buf[32];
    time_t before_reseed, after_reseed;
    int expected_state = (expect_success ? DRBG_READY : DRBG_ERROR);

    /*
     * step 1: check preconditions
     */

    /* Test whether seed propagation is enabled */
    if (!TEST_int_ne(master->reseed_prop_counter, 0)
        || !TEST_int_ne(public->reseed_prop_counter, 0)
        || !TEST_int_ne(private->reseed_prop_counter, 0))
        return 0;

    /* Check whether the master DRBG's reseed counter is the largest one */
    if (!TEST_int_le(public->reseed_prop_counter, master->reseed_prop_counter)
        || !TEST_int_le(private->reseed_prop_counter, master->reseed_prop_counter))
        return 0;

    /*
     * step 2: generate random output
     */

    if (reseed_time == 0)
        reseed_time = time(NULL);

    /* Generate random output from the public and private DRBG */
    before_reseed = expect_master_reseed == 1 ? reseed_time : 0;
    if (!TEST_int_eq(RAND_bytes(buf, sizeof(buf)), expect_success)
        || !TEST_int_eq(RAND_priv_bytes(buf, sizeof(buf)), expect_success))
        return 0;
    after_reseed = time(NULL);


    /*
     * step 3: check postconditions
     */

    /* Test whether reseeding succeeded as expected */
    if (!TEST_int_eq(master->state, expected_state)
        || !TEST_int_eq(public->state, expected_state)
        || !TEST_int_eq(private->state, expected_state))
        return 0;

    if (expect_master_reseed >= 0) {
        /* Test whether master DRBG was reseeded as expected */
        if (!TEST_int_eq(master_ctx.reseed_count, expect_master_reseed))
            return 0;
    }

    if (expect_public_reseed >= 0) {
        /* Test whether public DRBG was reseeded as expected */
        if (!TEST_int_eq(public_ctx.reseed_count, expect_public_reseed))
            return 0;
    }

    if (expect_private_reseed >= 0) {
        /* Test whether public DRBG was reseeded as expected */
        if (!TEST_int_eq(private_ctx.reseed_count, expect_private_reseed))
            return 0;
    }

    if (expect_success == 1) {
        /* Test whether all three reseed counters are synchronized */
        if (!TEST_int_eq(public->reseed_prop_counter, master->reseed_prop_counter)
            || !TEST_int_eq(private->reseed_prop_counter, master->reseed_prop_counter))
            return 0;

        /* Test whether reseed time of master DRBG is set correctly */
        if (!TEST_time_t_le(before_reseed, master->reseed_time)
            || !TEST_time_t_le(master->reseed_time, after_reseed))
            return 0;

        /* Test whether reseed times of child DRBGs are synchronized with master */
        if (!TEST_time_t_ge(public->reseed_time, master->reseed_time)
            || !TEST_time_t_ge(private->reseed_time, master->reseed_time))
            return 0;
    } else {
        ERR_clear_error();
    }

    return 1;
}