1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//! JE TCK port: `com.sleepycat.je.DatabaseEntryTest`.
//!
//! Behaviour-level ports. Targets DatabaseEntry's offset / size /
//! partial accessors as they interact with `Database::put` and
//! `Cursor::get`.
//!
//! Adaptations
//!
//! - JE's `DatabaseEntry` exposes a settable byte array via `getData()`
//! then in-place mutation; noxu's `DatabaseEntry` wraps a `bytes::Bytes`
//! so we build the buffer up front and use `set_offset` / `set_size`
//! in the same way JE callers do via `setOffset` / `setSize`.
//! - noxu's partial-put protocol returns
//! `NoxuError::IllegalArgument` if the supplied data length does not
//! match the partial length, so the partial-put test uses an
//! explicit `Some(&[])` byte slice.
use noxu_db::{
DatabaseConfig, DatabaseEntry, EnvironmentConfig, Get, OperationStatus,
};
use tempfile::TempDir;
fn open_env_db() -> (TempDir, noxu_db::Environment, noxu_db::Database) {
let dir = TempDir::new().unwrap();
let env_cfg = EnvironmentConfig::new(dir.path().to_path_buf())
.with_allow_create(true)
.with_transactional(true);
let env = noxu_db::Environment::open(env_cfg).unwrap();
let db_cfg =
DatabaseConfig::new().with_allow_create(true).with_transactional(true);
let db = env.open_database(None, "DatabaseEntryTest", &db_cfg).unwrap();
(dir, env, db)
}
// ---------------------------------------------------------------------------
// DatabaseEntryTest.testBasic
// ---------------------------------------------------------------------------
/// Port of `DatabaseEntryTest.testBasic`. Exercises constructors,
/// `set_data` (clears the offset), and `get_size`.
#[test]
fn database_entry_test_basic() {
let foo = vec![1u8; 10];
// Constructor that takes a byte array.
let mut a = DatabaseEntry::from_bytes(&foo);
assert_eq!(foo.len(), a.len());
assert_eq!(foo.as_slice(), a.data_opt().unwrap());
// Set the data to empty (JE: setData(null)). Noxu has no Option,
// but set_data(&[]) gives us the same observable state.
a.set_data(&[]);
assert_eq!(0, a.len());
// Constructor that sets the data later.
let mut later = DatabaseEntry::new();
assert_eq!(0, later.len());
later.set_data(&foo);
assert_eq!(foo.as_slice(), later.data_opt().unwrap());
// Set offset, then reset data and offset should be reset.
let mut off = DatabaseEntry::from_bytes(&foo);
off.set_offset(1);
off.set_size(1);
assert_eq!(1, off.offset());
assert_eq!(1, off.len());
off.set_data(&foo);
assert_eq!(0, off.offset());
assert_eq!(foo.len(), off.len());
}
// ---------------------------------------------------------------------------
// DatabaseEntryTest.testOffset
// ---------------------------------------------------------------------------
/// Port of `DatabaseEntryTest.testOffset`. A 30-byte buffer with the
/// "interesting" 10 bytes at offset 10 round-trips through `Database::put`
/// and `Cursor::get`: the stored payload is the 10-byte window, and the
/// returned entry has offset=0, size=10.
#[test]
fn database_entry_test_offset() {
let (_dir, env, db) = open_env_db();
const N_BYTES: u8 = 30;
let buf: Vec<u8> = (0..N_BYTES).collect();
let mut original_key = DatabaseEntry::from_bytes(&buf);
let mut original_data = DatabaseEntry::from_bytes(&buf);
original_key.set_size(10);
original_key.set_offset(10);
original_data.set_size(10);
original_data.set_offset(10);
db.put(&original_key, &original_data).unwrap();
let txn = env.begin_transaction(None).unwrap();
let mut cursor = db.open_cursor_in(&txn, None).unwrap();
let mut found_key = DatabaseEntry::new();
let mut found_data = DatabaseEntry::new();
let s =
cursor.get(&mut found_key, &mut found_data, Get::First, None).unwrap();
assert_eq!(OperationStatus::Success, s);
// Returned entries always start at offset 0 with size = stored payload.
assert_eq!(0, found_key.offset());
assert_eq!(0, found_data.offset());
assert_eq!(10, found_key.len());
assert_eq!(10, found_data.len());
let key_data = found_key.data_opt().unwrap();
let val_data = found_data.data_opt().unwrap();
for i in 0..10 {
assert_eq!((i + 10) as u8, key_data[i]);
assert_eq!((i + 10) as u8, val_data[i]);
}
drop(cursor);
txn.commit().unwrap();
}