changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > core / lisp/lib/rdb/tests.lisp

changeset 678: 2b7d5a8d63ac
parent: 97dd03beda03
author: Richard Westhaver <ellis@rwest.io>
date: Wed, 25 Sep 2024 21:39:39 -0400
permissions: -rw-r--r--
description: alien octets fix, workin with org-graph-db
1 (defpackage :rdb/tests
2  (:use :cl :std :rt :rocksdb :rdb :sb-ext :sb-alien :log :obj/query))
3 
4 (in-package :rdb/tests)
5 
6 (defsuite :rdb)
7 (in-suite :rdb)
8 (setq rt:*compile-tests* nil)
9 (rocksdb:load-rocksdb)
10 (setq *temp-db-destroy* t)
11 
12 (deftest minimal ()
13  "Test minimal functionality (open/close/put/get)."
14  (let ((db-path (format nil "/tmp/rdb-minimal-~a" (gensym))))
15  (with-db (db (open-db-raw db-path))
16  (put-kv-str-raw db "foo" "bar")
17  (is (string= (get-kv-str-raw db "foo") "bar"))
18  (close-db-raw db)
19  (destroy-db-raw db-path))))
20 
21 (deftest opts ()
22  "Ensure RDB-OPTS can be created, destructured, etc."
23  (let ((default (default-rdb-opts)))
24  ;; check defaults
25  (is (< 50 (hash-table-count (backfill-opts default :full t))))
26  (is (typep (rdb-opts-sap default) '(alien (* rocksdb-options))))
27  (is (eql t (get-opt default "create-if-missing")))
28  (is (eql t (set-opt default "enable-blob-files" t :push t)))
29  (is (eql t (get-opt default "enable-blob-files")))
30  (is (eql t (rocksdb-options-get-enable-blob-files (rdb-opts-sap default))))
31  (is (null (rocksdb-options-get-error-if-exists (rdb-opts-sap default))))))
32 
33 (deftest raw ()
34  "Test the raw RocksDB function wrappers."
35  (let ((path (merge-pathnames (symbol-name (gensym "rdb-raw")) "/tmp/")))
36  (with-open-db-raw (db path)
37  (dotimes (i 1000)
38  (let ((k (format nil "key~d" i))
39  (v (format nil "val~d" i)))
40  (put-kv-str-raw db k v)
41  (is (string= (get-kv-str-raw db k) v))))
42  (let ((cf (create-cf-raw db "cf1")))
43  (put-cf-str-raw db cf "bow" "wow")
44  (is (string= (get-cf-str-raw db cf "bow") "wow")))
45  (with-iter-raw (iter db)
46  (rocksdb:rocksdb-iter-seek-to-first iter)
47  (dotimes (i 999)
48  (rocksdb:rocksdb-iter-next iter)
49  (with-alien ((tslen size-t))
50  (rocksdb-iter-timestamp iter (addr tslen))
51  (is (zerop tslen)))
52  (is (rocksdb:rocksdb-iter-valid iter))
53  (is (string= (get-kv-str-raw db (iter-key-str-raw iter)) (iter-val-str-raw iter))))
54  (rocksdb:rocksdb-iter-next iter)
55  (is (not (rocksdb:rocksdb-iter-valid iter)))))
56  (destroy-db-raw path)))
57 
58 (deftest rdb ()
59  "Test RDB struct and methods."
60  ;; NOTE: passing a directory with trailing slash causes segfault - guess we gotta handle tht
61  (with-temp-db (db () :open t :destroy t)
62  (info! (hash-table-alist (backfill-opts db :full t)))
63  ;; get/set without cf
64  (put-kv-str-raw (rdb-db db) "key" "val")
65  (is (equal (get-kv-str-raw (rdb-db db) "key") "val"))
66  ;; push 3 cfs
67  (let ((cfs (list (make-rdb-cf "foo") (make-rdb-cf "bar") (make-rdb-cf "baz"))))
68  (dolist (cf cfs)
69  (push-cf cf db)))
70  (debug! (rdb-cfs db))
71  (create-cfs db)
72  ;; (flush-db db)
73  ;; FIX 2024-08-25:
74  (do-cfs (cf (rdb-cfs db))
75  (with-cf (cf cf)
76  (trace! cf)
77  ;; (insert-kv db (make-kv "key" "val") :cf cf)
78  ;; (is (equal (get-key db "key" :cf (rdb-cf-sap cf)) "val"))
79  ))
80  (rocksdb-cancel-all-background-work (rdb-db db) t)
81  ;; insert after background cancel
82  (insert-key db "test" "zaa")
83  (is (string= "zaa" (get-key db "test")))))
84 
85 (deftest temp-db ()
86  "Test WITH-TEMP-DB macro."
87  (with-temp-db (tmp (cf1 cf2 cf3 cf4) :destroy t)
88  (set-opt tmp :parallelism (num-cpus))
89  ;; https://github.com/facebook/rocksdb/wiki/unordered_write
90  (set-opt tmp :unordered-write t)
91  (set-opt tmp :enable-statistics t)
92  (set-opt tmp :statistics-level (rocksdb-statistics-level "all"))
93  (push-opts tmp)
94  (open-db tmp)
95  (create-cfs tmp)
96  (with-iter (it (create-iter tmp))
97  (iter-seek-to-first it)
98  (is (sequence:emptyp (iter-key it)))
99  (is (sequence:emptyp (iter-val it)))
100  (is (zerop (nth 1 (multiple-value-list (iter-timestamp it)))))
101  (is (not (iter-valid-p it)))
102  (iter-seek-to-last it)
103  (is (typep (iter-kv it) 'rdb-kv))
104  (is (sequence:emptyp (iter-key it)))
105  (is (sequence:emptyp (iter-val it)))
106  ;; (info! (iter-next it))
107  (rocksdb-iter-destroy (rdb-iter-sap it)))
108  (dotimes (i 10000)
109  (insert-key tmp (format nil "foo~A" i) (format nil "bar~A" i)))
110  (loop for i below 100
111  with n = (* i i)
112  do (is (string= (get-key tmp (format nil "foo~A" n)) (format nil "bar~A" n))))
113  (flush-db tmp)
114  ;; TODO: auto handle return type (get-prop-int)
115  (is (= 10000 (parse-integer (get-prop tmp "rocksdb.estimate-num-keys"))))
116  (debug! ;; some info about our db
117  (rdb-name tmp)
118  (get-prop tmp "rocksdb.dbstats")
119  (get-prop tmp "rocksdb.levelstats")
120  (print-stats tmp))))
121 
122 (deftest metadata ()
123  "Test metadata types: CF -> LEVEL -> SST-FILE."
124  (with-temp-db (tmp () :open t :destroy t)
125  (insert-key tmp "foo" "bar")
126  (flush-db tmp)
127  (let ((cf-meta (get-metadata tmp)))
128  (is (rdb-cf-metadata-p (pull-sap* cf-meta)))
129  (let ((level-meta (get-metadata cf-meta)))
130  (is (rdb-level-metadata-p (pull-sap* level-meta)))
131  (is (rdb-sst-file-metadata-p
132  (pull-sap* (get-metadata level-meta))))))))
133 
134 (deftest sst ()
135  "Test SST-FILE-WRITER and INGEST-DB."
136  (with-temp-db (tmp () :open t :destroy t)
137  ;; without macro
138  (let ((writer (make-sst-file-writer))
139  (path (namestring (merge-pathnames (format nil "/tmp/~A" (gensym "sst"))))))
140  (open-sst writer path)
141  (dotimes (i 10000)
142  (put-key writer (integer-to-octets i 64) (string-to-octets (format nil "~A" (gensym)))))
143  (finish-sst writer) ;; will fail on empty writer
144  (destroy-sst writer) ; TODO 2024-05-08: investigate -
145  ; doesn't seem to actually delete the
146  ; file, jst the writer?
147  (ingest-db tmp (list path))
148  (delete-file path)
149  ;; with macro
150  (with-sst (s :file path :destroy t)
151  (put-kv s (make-kv "nil" "nil")))
152  (delete-file path))))
153 
154 (deftest errors ()
155  "Test basic error handling."
156  (with-temp-db (errs () :open t :destroy t)
157  (signals rdb-error (open-db errs))))
158 
159 (deftest schema ()
160  "Test loading and handling of RDB-SCHEMA objects."
161  (let ((cf (load-field (make-rdb-cf "foo") (make-field :type '(string string)))))
162  (is (eql (rdb-cf-key-type cf) 'string))
163  (is (eql (rdb-cf-val-type cf) 'string))
164  (is (string= (rdb-cf-name cf) "foo"))
165  (with-temp-db (schema-no-cfs () :destroy t :open t)
166  (load-schema schema-no-cfs (make-schema (make-field :type nil)))
167  (is (= 1 (length (rdb-cfs schema-no-cfs)))))
168  (with-temp-db (schema-cfs (baz) :open t :destroy t)
169  (load-schema schema-cfs (make-schema (make-field :name "BAZ" :type '(octet-vector . string))))
170  (is (= 1 (length (rdb-cfs schema-cfs))))
171  (is (eql 'octet-vector (rdb-cf-key-type (aref (rdb-cfs schema-cfs) 0))))
172  (is (eql 'string (rdb-cf-val-type (aref (rdb-cfs schema-cfs) 0)))))))