static char* test_scaling_equivalence()
{
    load_histograms();

    mu_assert(
            "Averages should be equivalent",
            compare_values(
                    hdr_mean(cor_histogram) * 512,
                    hdr_mean(scaled_cor_histogram),
                    0.000001));

    mu_assert(
            "Total count should be equivalent",
            compare_int64(
                    cor_histogram->total_count,
                    scaled_cor_histogram->total_count));

    int64_t expected_99th = hdr_value_at_percentile(cor_histogram, 99.0) * 512;
    int64_t scaled_99th = hdr_value_at_percentile(scaled_cor_histogram, 99.0);
    mu_assert(
            "99%'iles should be equivalent",
            compare_int64(
                    hdr_lowest_equivalent_value(cor_histogram, expected_99th),
                    hdr_lowest_equivalent_value(scaled_cor_histogram, scaled_99th)));

    mu_assert(
            "Max should be equivalent",
            compare_int64(hdr_max(cor_histogram) * 512, hdr_max(scaled_cor_histogram)));

    return 0;
}
static char* test_encode_and_decode()
{
    load_histograms();

    size_t raw_histogram_size = hdr_get_memory_size(cor_histogram);

    uint8_t* buffer = (uint8_t*) malloc(hdr_get_memory_size(cor_histogram));

    size_t encode_result = hdr_encode(cor_histogram, buffer, raw_histogram_size);

    mu_assert("Did not encode", encode_result != 0);
    mu_assert("Incorrect size", encode_result <= raw_histogram_size);

    struct hdr_histogram* loaded_histogram = NULL;
    hdr_decode(buffer, raw_histogram_size, &loaded_histogram);

    int compare_result = memcmp(cor_histogram, loaded_histogram, raw_histogram_size);

    if (compare_result != 0)
    {
        uint8_t* a = (uint8_t*) cor_histogram;
        uint8_t* b = (uint8_t*) loaded_histogram;
        for (int i = 0; i < raw_histogram_size; i++)
        {
            if (a[i] != b[i])
            {
                printf("Mismatch at %d: %x - %x\n", i, a[i] & 0xFF, b[i] & 0xFF);
            }
        }
    }

    mu_assert("Comparison did not match", compare_result == 0);

    return 0;
}
static char* test_encode_and_decode_compressed()
{
    load_histograms();

    size_t raw_histogram_size = hdr_get_memory_size(raw_histogram);

    uint8_t* buffer = (uint8_t*) malloc(hdr_get_memory_size(raw_histogram));

    size_t encode_result = hdr_encode_compressed(raw_histogram, buffer, raw_histogram_size);

    mu_assert("Did not encode", encode_result == 0);

    int32_t compressed_length = hdr_get_compressed_length(buffer);

    struct hdr_histogram* loaded_histogram = NULL;
    int decode_result = hdr_decode_compressed(buffer, compressed_length, &loaded_histogram);

    if (decode_result != 0)
    {
        printf("%s\n", hdr_strerror(decode_result));
    }
    mu_assert("Did not decode", decode_result == 0);

    mu_assert("Loaded histogram is null", loaded_histogram != NULL);
    int compare_result = memcmp(raw_histogram, loaded_histogram, raw_histogram_size);

    mu_assert("Comparison did not match", compare_result == 0);

    return 0;
}
static char* test_encode_and_decode_compressed2()
{
    load_histograms();

    uint8_t* buffer = NULL;
    size_t len = 0;
    int rc = 0;
    struct hdr_histogram* actual = NULL;
    struct hdr_histogram* expected = cor_histogram;

    rc = hdr_encode_compressed(expected, &buffer, &len);
    mu_assert("Did not encode", validate_return_code(rc));

    rc = hdr_decode_compressed(buffer, len, &actual);
    mu_assert("Did not decode", validate_return_code(rc));

    mu_assert("Loaded histogram is null", actual != NULL);

    mu_assert(
            "Comparison did not match",
            compare_histogram(expected, actual));

    free(actual);

    return 0;
}
static char* test_percentiles()
{
    load_histograms();

    mu_assert("Value at 30% not 1000.0",
              compare_percentile(hdr_value_at_percentile(raw_histogram, 30.0), 1000.0, 0.001));
    mu_assert("Value at 99% not 1000.0",
              compare_percentile(hdr_value_at_percentile(raw_histogram, 99.0), 1000.0, 0.001));
    mu_assert("Value at 99.99% not 1000.0",
              compare_percentile(hdr_value_at_percentile(raw_histogram, 99.99), 1000.0, 0.001));
    mu_assert("Value at 99.999% not 100000000.0",
              compare_percentile(hdr_value_at_percentile(raw_histogram, 99.999), 100000000.0, 0.001));
    mu_assert("Value at 100% not 100000000.0",
              compare_percentile(hdr_value_at_percentile(raw_histogram, 100.0), 100000000.0, 0.001));

    mu_assert("Value at 30% not 1000.0",
              compare_percentile(hdr_value_at_percentile(cor_histogram, 30.0), 1000.0, 0.001));
    mu_assert("Value at 50% not 1000.0",
              compare_percentile(hdr_value_at_percentile(cor_histogram, 50.0), 1000.0, 0.001));
    mu_assert("Value at 75% not 50000000.0",
              compare_percentile(hdr_value_at_percentile(cor_histogram, 75.0), 50000000.0, 0.001));
    mu_assert("Value at 90% not 80000000.0",
              compare_percentile(hdr_value_at_percentile(cor_histogram, 90.0), 80000000.0, 0.001));
    mu_assert("Value at 99% not 98000000.0",
              compare_percentile(hdr_value_at_percentile(cor_histogram, 99.0), 98000000.0, 0.001));
    mu_assert("Value at 99.999% not 100000000.0",
              compare_percentile(hdr_value_at_percentile(cor_histogram, 99.999), 100000000.0, 0.001));
    mu_assert("Value at 100% not 100000000.0",
              compare_percentile(hdr_value_at_percentile(cor_histogram, 100.0), 100000000.0, 0.001));

    return 0;
}
static char* test_encode_and_decode_base64()
{
    load_histograms();

    uint8_t* buffer = NULL;
    uint8_t* decoded = NULL;
    char* encoded = NULL;
    size_t len = 0;
    int rc = 0;

    rc = hdr_encode_compressed(cor_histogram, &buffer, &len);
    mu_assert("Did not encode", validate_return_code(rc));

    size_t encoded_len = hdr_base64_encoded_len(len);
    size_t decoded_len = hdr_base64_decoded_len(encoded_len);
    encoded = calloc(encoded_len + 1, sizeof(char));
    decoded = calloc(decoded_len, sizeof(uint8_t));

    hdr_base64_encode(buffer, len, encoded, encoded_len);
    hdr_base64_decode(encoded, encoded_len, decoded, decoded_len);

    mu_assert("Should be same", memcmp(buffer, decoded, len) == 0);

    return 0;
}
char* test_get_total_count()
{
    load_histograms();
    mu_assert("Total count is 10,001", compare_int64(10001, raw_histogram->values.total_count));
    mu_assert("Total count is 20,000", compare_int64(20000, histogram->values.total_count));

    return 0;
}
char* test_get_max_value()
{
    load_histograms();
    mu_assert(
        "Max value is 100000000",
        hdr_dbl_values_are_equivalent(histogram, INT64_C(100) * 1000 * 1000, hdr_dbl_max(histogram)));

    return 0;
}
char* test_get_min_value()
{
    load_histograms();
    mu_assert(
        "Min value is 1000",
        hdr_dbl_values_are_equivalent(histogram, INT64_C(1000), hdr_dbl_min(histogram)));

    return 0;
}
static char* test_total_count()
{
    load_histograms();

    mu_assert("Total raw count != 10001",       raw_histogram->total_count == 10001);
    mu_assert("Total corrected count != 20000", cor_histogram->total_count == 20000);

    return 0;
}
static char* test_get_min_value()
{
    load_histograms();

    mu_assert("hdr_min(raw_histogram) != 1000", hdr_min(raw_histogram) == 1000L);
    mu_assert("hdr_min(cor_histogram) != 1000", hdr_min(cor_histogram) == 1000L);

    return 0;
}
static char* test_linear_values()
{
    load_histograms();
    struct hdr_linear_iter iter;
    int index;

    // Raw Histogram
    hdr_linear_iter_init(&iter, raw_histogram, 100000);
    index = 0;
    while (hdr_linear_iter_next(&iter))
    {
        int64_t count_added_in_this_bucket = iter.count_added_in_this_iteration_step;

        if (index == 0)
        {
            mu_assert("Count at 0 is not 10000", count_added_in_this_bucket == 10000);
        }
        else if (index == 999)
        {
            mu_assert("Count at 999 is not 1", count_added_in_this_bucket == 1);
        }
        else
        {
            mu_assert("Count should be 0", count_added_in_this_bucket == 0);
        }

        index++;
    }
    mu_assert("Should of met 1000 values", index == 1000);

    // Corrected Histogram

    hdr_linear_iter_init(&iter, cor_histogram, 10000);
    index = 0;
    int64_t total_added_count = 0;
    while (hdr_linear_iter_next(&iter))
    {
        int64_t count_added_in_this_bucket = iter.count_added_in_this_iteration_step;

        if (index == 0)
        {
            mu_assert("Count at 0 is not 10001", count_added_in_this_bucket == 10001);
        }

        total_added_count += count_added_in_this_bucket;
        index++;
    }
    mu_assert("Should of met 10001 values", index == 10000);
    mu_assert("Should of met 20000 counts", total_added_count == 20000);

    return 0;
}
static char* test_get_max_value()
{
    load_histograms();


    int64_t actual_raw_max = hdr_max(raw_histogram);
    mu_assert("hdr_max(raw_histogram) != 100000000L",
              hdr_values_are_equivalent(raw_histogram, actual_raw_max, 100000000L));
    int64_t actual_cor_max = hdr_max(cor_histogram);
    mu_assert("hdr_max(cor_histogram) != 100000000L",
              hdr_values_are_equivalent(cor_histogram, actual_cor_max, 100000000L));

    return 0;
}
static char* test_logarithmic_values()
{
    load_histograms();
    struct hdr_log_iter iter;
    int index;

    hdr_log_iter_init(&iter, raw_histogram, 10000, 2.0);
    index = 0;

    while(hdr_log_iter_next(&iter))
    {
        long count_added_in_this_bucket = iter.count_added_in_this_iteration_step;
        if (index == 0)
        {
            mu_assert("Raw Logarithmic 10 msec bucket # 0 added a count of 10000", 10000 == count_added_in_this_bucket);
        }
        else if (index == 14)
        {
            mu_assert("Raw Logarithmic 10 msec bucket # 14 added a count of 1", 1 == count_added_in_this_bucket);
        }
        else
        {
            mu_assert("Raw Logarithmic 10 msec bucket added a count of 0", 0 == count_added_in_this_bucket);
        }

        index++;
    }

    mu_assert("Should of seen 14 values", index - 1 == 14);

    hdr_log_iter_init(&iter, cor_histogram, 10000, 2.0);
    index = 0;
    int total_added_count = 0;
    while (hdr_log_iter_next(&iter))
    {
        long count_added_in_this_bucket = iter.count_added_in_this_iteration_step;

        if (index == 0)
        {
            mu_assert("Corrected Logarithmic 10 msec bucket # 0 added a count of 10001", 10001 == count_added_in_this_bucket);
        }
        total_added_count += count_added_in_this_bucket;
        index++;
    }

    mu_assert("Should of seen 14 values", index - 1 == 14);
    mu_assert("Should of seen count of 20000", total_added_count == 20000);

    return 0;
}
char *test_scaling_equivalence() {
    load_histograms();

    mu_assert("total count should be the same",
              compare_int64(histogram->values.total_count, scaled_histogram->values.total_count));

    mu_assert("averages should be equivalent",
              compare_double(
                  hdr_dbl_mean(histogram) * 512,
                  hdr_dbl_mean(scaled_histogram),
                  hdr_dbl_mean(scaled_histogram) * 0.000001));

    mu_assert("99%'iles should be equivalent",
              compare_double(
                  hdr_dbl_highest_equivalent_value(scaled_histogram, hdr_dbl_value_at_percentile(histogram, 99.0)) * 512.0,
                  hdr_dbl_highest_equivalent_value(scaled_histogram, hdr_dbl_value_at_percentile(scaled_histogram, 99.0)),
                  hdr_dbl_highest_equivalent_value(
                      scaled_histogram, hdr_dbl_value_at_percentile(scaled_histogram, 99.0)) * 0.000001));

    mu_assert("Max should be equivalent",
              compare_double(
                  hdr_dbl_highest_equivalent_value(scaled_histogram, hdr_dbl_max(histogram) * 512),
                  hdr_dbl_max(scaled_histogram),
                  hdr_dbl_max(scaled_histogram) * 0.000001));

    mu_assert("total count should be the same",
              compare_int64(
                  post_corrected_histogram->values.total_count,
                  post_corrected_scaled_histogram->values.total_count));

    mu_assert("99%'iles should be equivalent",
              compare_double(
                  hdr_dbl_lowest_equivalent_value(
                      post_corrected_histogram, hdr_dbl_value_at_percentile(post_corrected_histogram, 99.0)) * 512.0,
                  hdr_dbl_lowest_equivalent_value(
                      post_corrected_scaled_histogram, hdr_dbl_value_at_percentile(post_corrected_scaled_histogram, 99.0)),
                  hdr_dbl_lowest_equivalent_value(
                      post_corrected_scaled_histogram,
                      hdr_dbl_value_at_percentile(post_corrected_scaled_histogram, 99.0)) * 0.000001));

    mu_assert("Max should be equivalent",
              compare_double(
                  hdr_dbl_highest_equivalent_value(
                      post_corrected_scaled_histogram, hdr_dbl_max(post_corrected_histogram)) * 512,
                  hdr_dbl_max(post_corrected_scaled_histogram),
                  hdr_dbl_max(post_corrected_scaled_histogram)));

    return 0;
}
static char* test_recorded_values()
{
    load_histograms();
    struct hdr_recorded_iter iter;
    int index;

    // Raw Histogram
    hdr_recorded_iter_init(&iter, raw_histogram);

    index = 0;
    while (hdr_recorded_iter_next(&iter))
    {
        int64_t count_added_in_this_bucket = iter.count_added_in_this_iteration_step;
        if (index == 0)
        {
            mu_assert("Value at 0 is not 10000", count_added_in_this_bucket == 10000);
        }
        else
        {
            mu_assert("Value at 1 is not 1", count_added_in_this_bucket == 1);
        }

        index++;
    }
    mu_assert("Should have encountered 2 values", index == 2);

    // Corrected Histogram
    hdr_recorded_iter_init(&iter, cor_histogram);

    index = 0;
    int64_t total_added_count = 0;
    while (hdr_recorded_iter_next(&iter))
    {
        int64_t count_added_in_this_bucket = iter.count_added_in_this_iteration_step;
        if (index == 0)
        {
            mu_assert("Count at 0 is not 10000", count_added_in_this_bucket == 10000);
        }
        mu_assert("Count should not be 0", iter.iter.count_at_index != 0);
        mu_assert("Count at value iterated to should be count added in this step",
                  iter.iter.count_at_index == count_added_in_this_bucket);
        total_added_count += count_added_in_this_bucket;
        index++;
    }
    mu_assert("Total counts should be 20000", total_added_count == 20000);

    return 0;
}
static char* test_bounds_check_on_decode()
{
    load_histograms();

    uint8_t* buffer = NULL;
    size_t len = 0;
    int rc = 0;
    struct hdr_histogram* actual = NULL;
    struct hdr_histogram* expected = cor_histogram;

    rc = hdr_encode_compressed(expected, &buffer, &len);
    mu_assert("Did not encode", validate_return_code(rc));

    rc = hdr_decode_compressed(buffer, len - 1, &actual);
    mu_assert("Should have be invalid", compare_int64(EINVAL, rc));
    mu_assert("Should not have built histogram", NULL == actual);

    return 0;
}
static char* test_reset()
{
    load_histograms();

    // before
    mu_assert("Value at 99% == 0.0", hdr_value_at_percentile(raw_histogram, 99.0) != 0);
    mu_assert("Value at 99% == 0.0", hdr_value_at_percentile(cor_histogram, 99.0) != 0);

    hdr_reset(raw_histogram);
    hdr_reset(cor_histogram);

    //after
    mu_assert("Total raw count != 0",       raw_histogram->total_count == 0);
    mu_assert("Total corrected count != 0", cor_histogram->total_count == 0);

    mu_assert("Value at 99% not 0.0", hdr_value_at_percentile(raw_histogram, 99.0) == 0);
    mu_assert("Value at 99% not 0.0", hdr_value_at_percentile(cor_histogram, 99.0) == 0);

    return 0;
}