lib/std/lang/alloc/tests.rad 4.0 KiB raw
1
//! Tests for the bump allocator.
2
3
use std::testing;
4
5
/// Test basic allocation.
6
@test fn testAllocBasic() throws (testing::TestError) {
7
    static STORAGE: [u8; 64] = undefined;
8
    let mut arena = super::new(&mut STORAGE[..]);
9
10
    let ptr = try! super::alloc(&mut arena, 4, 4);
11
    try testing::expect(super::used(&arena) == 4);
12
    try testing::expect(super::remaining(&arena) == 60);
13
}
14
15
/// Test that allocations are properly aligned.
16
@test fn testAllocAlignment() throws (testing::TestError) {
17
    static STORAGE: [u8; 64] = undefined;
18
    let mut arena = super::new(&mut STORAGE[..]);
19
20
    // Allocate 1 byte with 1-byte alignment.
21
    let p1 = try! super::alloc(&mut arena, 1, 1);
22
    try testing::expect(super::used(&arena) == 1);
23
24
    // Allocate 4 bytes with 4-byte alignment - should pad to offset 4.
25
    let p2 = try! super::alloc(&mut arena, 4, 4);
26
    try testing::expect(super::used(&arena) == 8); // 1 + 3 padding + 4
27
}
28
29
/// Test multiple allocations.
30
@test fn testAllocMultiple() throws (testing::TestError) {
31
    static STORAGE: [u8; 128] = undefined;
32
    let mut arena = super::new(&mut STORAGE[..]);
33
34
    let p1 = try! super::alloc(&mut arena, 8, 4);
35
    let p2 = try! super::alloc(&mut arena, 16, 4);
36
    let p3 = try! super::alloc(&mut arena, 4, 4);
37
38
    try testing::expect(super::used(&arena) == 28); // 8 + 16 + 4
39
}
40
41
/// Test that arena throws when exhausted.
42
@test fn testAllocExhausted() throws (testing::TestError) {
43
    static STORAGE: [u8; 16] = undefined;
44
    let mut arena = super::new(&mut STORAGE[..]);
45
46
    // This should succeed.
47
    let p1 = try! super::alloc(&mut arena, 8, 4);
48
49
    // This should also succeed.
50
    let p2 = try! super::alloc(&mut arena, 8, 4);
51
52
    // Arena is now full, this should fail.
53
    let mut failed = false;
54
    try super::alloc(&mut arena, 1, 1) catch {
55
        failed = true;
56
    };
57
    try testing::expect(failed);
58
}
59
60
/// Test that reset allows reuse of memory.
61
@test fn testAllocReset() throws (testing::TestError) {
62
    static STORAGE: [u8; 32] = undefined;
63
    let mut arena = super::new(&mut STORAGE[..]);
64
65
    let p1 = try! super::alloc(&mut arena, 16, 4);
66
    try testing::expect(super::used(&arena) == 16);
67
68
    super::reset(&mut arena);
69
    try testing::expect(super::used(&arena) == 0);
70
    try testing::expect(super::remaining(&arena) == 32);
71
72
    // Should be able to allocate again.
73
    let p2 = try! super::alloc(&mut arena, 32, 4);
74
}
75
76
/// Test alignment when offset is already aligned.
77
@test fn testAllocAlreadyAligned() throws (testing::TestError) {
78
    static STORAGE: [u8; 64] = undefined;
79
    let mut arena = super::new(&mut STORAGE[..]);
80
81
    // Allocate 4 bytes - offset becomes 4, already aligned for next 4-byte alloc.
82
    let p1 = try! super::alloc(&mut arena, 4, 4);
83
    try testing::expect(super::used(&arena) == 4);
84
85
    // Next 4-byte aligned allocation should not add padding.
86
    let p2 = try! super::alloc(&mut arena, 4, 4);
87
    try testing::expect(super::used(&arena) == 8);
88
}
89
90
/// Test allocation that would overflow with alignment padding.
91
@test fn testAllocOverflowWithPadding() throws (testing::TestError) {
92
    static STORAGE: [u8; 16] = undefined;
93
    let mut arena = super::new(&mut STORAGE[..]);
94
95
    // Allocate 1 byte, offset is now 1.
96
    let p1 = try! super::alloc(&mut arena, 1, 1);
97
98
    // Try to allocate 16 bytes with 4-byte alignment.
99
    // Aligned offset would be 4, then 4 + 16 = 20 > 16, so should fail.
100
    let mut failed = false;
101
    try super::alloc(&mut arena, 16, 4) catch {
102
        failed = true;
103
    };
104
    try testing::expect(failed);
105
}
106
107
/// Test the Allocator interface backed by an arena.
108
@test fn testAllocator() throws (testing::TestError) {
109
    static STORAGE: [u8; 256] = undefined;
110
    let mut arena = super::new(&mut STORAGE[..]);
111
    let a = super::arenaAllocator(&mut arena);
112
113
    // Allocate through the Allocator indirection.
114
    let p1 = a.func(a.ctx, 16, 4);
115
    try testing::expect(super::used(&arena) == 16);
116
117
    let p2 = a.func(a.ctx, 8, 8);
118
    try testing::expect(super::used(&arena) == 24);
119
120
    // Verify the pointers are distinct.
121
    try testing::expect(p1 as u64 != p2 as u64);
122
}