/*
 * testOOM.c: Test out-of-memory handling
 *
 * See Copyright for the status of this software.
 *
 * Copyright 2003 Red Hat, Inc.
 * Written by: hp@redhat.com
 */

#include "testOOMlib.h"

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#include <string.h>

#define _TEST_INT_MAX 2147483647
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef NULL
#define NULL ((void*)0)
#endif

#include <libxml/xmlmemory.h>

static int fail_alloc_counter = _TEST_INT_MAX;
static int n_failures_per_failure = 1;
static int n_failures_this_failure = 0;
static int n_blocks_outstanding = 0;

/**
 * set_fail_alloc_counter:
 * @until_next_fail: number of successful allocs before one fails
 *
 * Sets the number of allocations until we simulate a failed
 * allocation. If set to 0, the next allocation to run
 * fails; if set to 1, one succeeds then the next fails; etc.
 * Set to _TEST_INT_MAX to not fail anything. 
 */
static void
set_fail_alloc_counter (int until_next_fail)
{
  fail_alloc_counter = until_next_fail;
}

/**
 * get_fail_alloc_counter:
 *
 * Returns the number of successful allocs until we'll simulate
 * a failed alloc.
 */
static int
get_fail_alloc_counter (void)
{
  return fail_alloc_counter;
}

/**
 * set_fail_alloc_failures:
 * @failures_per_failure: number to fail
 *
 * Sets how many mallocs to fail when the fail alloc counter reaches
 * 0.
 *
 */
static void
set_fail_alloc_failures (int failures_per_failure)
{
  n_failures_per_failure = failures_per_failure;
}

/**
 * decrement_fail_alloc_counter:
 *
 * Called when about to alloc some memory; if
 * it returns #TRUE, then the allocation should
 * fail. If it returns #FALSE, then the allocation
 * should not fail.
 *
 * returns #TRUE if this alloc should fail
 */
static int
decrement_fail_alloc_counter (void)
{
  if (fail_alloc_counter <= 0)
    {
      n_failures_this_failure += 1;
      if (n_failures_this_failure >= n_failures_per_failure)
        {
          fail_alloc_counter = _TEST_INT_MAX;

          n_failures_this_failure = 0;
        }
      
      return TRUE;
    }
  else
    {
      fail_alloc_counter -= 1;
      return FALSE;
    }
}

/**
 * test_get_malloc_blocks_outstanding:
 *
 * Get the number of outstanding malloc()'d blocks.
 *
 * Returns number of blocks
 */
int
test_get_malloc_blocks_outstanding (void)
{
  return n_blocks_outstanding;
}

void*
test_malloc (size_t bytes)
{  
  if (decrement_fail_alloc_counter ())
    {
      /* FAIL the malloc */
      return NULL;
    }
  
  if (bytes == 0) /* some system mallocs handle this, some don't */
    return NULL;
  else
    {
      void *mem;
      mem = xmlMemMalloc (bytes);

      if (mem)
        n_blocks_outstanding += 1;

      return mem;
    }
}

void*
test_realloc (void  *memory,
              size_t bytes)
{
  if (decrement_fail_alloc_counter ())
    {
      /* FAIL */
      return NULL;
    }
  
  if (bytes == 0) /* guarantee this is safe */
    {
      test_free (memory);
      return NULL;
    }
  else
    {
      void *mem;
      mem = xmlMemRealloc (memory, bytes);

      if (memory == NULL && mem != NULL)
        n_blocks_outstanding += 1;

      return mem;
    }
}

void
test_free (void  *memory)
{
  if (memory) /* we guarantee it's safe to free (NULL) */
    {
      n_blocks_outstanding -= 1;

      xmlMemFree (memory);
    }
}

char*
test_strdup (const char *str)
{
  int len;
  char *copy;
  
  if (str == NULL)
    return NULL;
  
  len = strlen (str);

  copy = test_malloc (len + 1);
  if (copy == NULL)
    return NULL;

  memcpy (copy, str, len + 1);
  
  return copy;
}

static int
run_failing_each_malloc (int                n_mallocs,
                         TestMemoryFunction func,
                         void              *data)
{
  n_mallocs += 10; /* fudge factor to ensure reallocs etc. are covered */
  
  while (n_mallocs >= 0)
    {      
      set_fail_alloc_counter (n_mallocs);

      if (!(* func) (data))
        return FALSE;
      
      n_mallocs -= 1;
    }

  set_fail_alloc_counter (_TEST_INT_MAX);

  return TRUE;
}

/**
 * test_oom_handling:
 * @func: function to call
 * @data: data to pass to function
 *
 * Tests how well the given function responds to out-of-memory
 * situations. Calls the function repeatedly, failing a different
 * call to malloc() each time. If the function ever returns #FALSE,
 * the test fails. The function should return #TRUE whenever something
 * valid (such as returning an error, or succeeding) occurs, and #FALSE
 * if it gets confused in some way.
 *
 * Returns #TRUE if the function never returns FALSE
 */
int
test_oom_handling (TestMemoryFunction  func,
                   void               *data)
{
  int approx_mallocs;

  /* Run once to see about how many mallocs are involved */
  
  set_fail_alloc_counter (_TEST_INT_MAX);

  if (!(* func) (data))
    return FALSE;

  approx_mallocs = _TEST_INT_MAX - get_fail_alloc_counter ();

  set_fail_alloc_failures (1);
  if (!run_failing_each_malloc (approx_mallocs, func, data))
    return FALSE;
  
  set_fail_alloc_failures (2);
  if (!run_failing_each_malloc (approx_mallocs, func, data))
    return FALSE;

  set_fail_alloc_failures (3);
  if (!run_failing_each_malloc (approx_mallocs, func, data))
    return FALSE;

  set_fail_alloc_counter (_TEST_INT_MAX);
  
  return TRUE;
}
