michael@0: /* michael@0: * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson michael@0: * michael@0: * Redistribution and use in source and binary forms, with or without michael@0: * modification, are permitted provided that the following conditions michael@0: * are met: michael@0: * 1. Redistributions of source code must retain the above copyright michael@0: * notice, this list of conditions and the following disclaimer. michael@0: * 2. Redistributions in binary form must reproduce the above copyright michael@0: * notice, this list of conditions and the following disclaimer in the michael@0: * documentation and/or other materials provided with the distribution. michael@0: * 3. The name of the author may not be used to endorse or promote products michael@0: * derived from this software without specific prior written permission. michael@0: * michael@0: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR michael@0: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES michael@0: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. michael@0: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, michael@0: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT michael@0: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, michael@0: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY michael@0: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF michael@0: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: */ michael@0: michael@0: #include michael@0: #include "event2/event_struct.h" michael@0: michael@0: #include "tinytest.h" michael@0: #include "tinytest_macros.h" michael@0: #include "../minheap-internal.h" michael@0: michael@0: static void michael@0: set_random_timeout(struct event *ev) michael@0: { michael@0: ev->ev_timeout.tv_sec = rand(); michael@0: ev->ev_timeout.tv_usec = rand() & 0xfffff; michael@0: ev->ev_timeout_pos.min_heap_idx = -1; michael@0: } michael@0: michael@0: static void michael@0: check_heap(struct min_heap *heap) michael@0: { michael@0: unsigned i; michael@0: for (i = 1; i < heap->n; ++i) { michael@0: unsigned parent_idx = (i-1)/2; michael@0: tt_want(evutil_timercmp(&heap->p[i]->ev_timeout, michael@0: &heap->p[parent_idx]->ev_timeout, >=)); michael@0: } michael@0: } michael@0: michael@0: static void michael@0: test_heap_randomized(void *ptr) michael@0: { michael@0: struct min_heap heap; michael@0: struct event *inserted[1024]; michael@0: struct event *e, *last_e; michael@0: int i; michael@0: michael@0: min_heap_ctor(&heap); michael@0: michael@0: for (i = 0; i < 1024; ++i) { michael@0: inserted[i] = malloc(sizeof(struct event)); michael@0: set_random_timeout(inserted[i]); michael@0: min_heap_push(&heap, inserted[i]); michael@0: } michael@0: check_heap(&heap); michael@0: michael@0: tt_assert(min_heap_size(&heap) == 1024); michael@0: michael@0: for (i = 0; i < 512; ++i) { michael@0: min_heap_erase(&heap, inserted[i]); michael@0: if (0 == (i % 32)) michael@0: check_heap(&heap); michael@0: } michael@0: tt_assert(min_heap_size(&heap) == 512); michael@0: michael@0: last_e = min_heap_pop(&heap); michael@0: while (1) { michael@0: e = min_heap_pop(&heap); michael@0: if (!e) michael@0: break; michael@0: tt_want(evutil_timercmp(&last_e->ev_timeout, michael@0: &e->ev_timeout, <=)); michael@0: } michael@0: tt_assert(min_heap_size(&heap) == 0); michael@0: end: michael@0: for (i = 0; i < 1024; ++i) michael@0: free(inserted[i]); michael@0: michael@0: min_heap_dtor(&heap); michael@0: } michael@0: michael@0: struct testcase_t minheap_testcases[] = { michael@0: { "randomized", test_heap_randomized, 0, NULL, NULL }, michael@0: END_OF_TESTCASES michael@0: };