Skip to content

Commit 36edf20

Browse files
committed
feat(test): add comprehensive pgTAP functionality tests
Complete Task 3 from pgTAP implementation plan by adding functionality tests for: - Comparison operators: <, <=, >, >=, <> with ORE indexes (12 tests) - JSONB operators: ->, ->>, @>, <@ for encrypted data (13 tests) - Configuration management: add/remove/modify search config (12 tests) - Index terms: blake3, hmac_256, and ORE comparison functions (27 tests) Total: 64 additional tests covering core EQL functionality These tests validate: - Encrypted data comparison operations work correctly - JSONB extraction and containment operators function as expected - Configuration management maintains state correctly - Index term comparison functions return proper ordering results All tests use pgTAP assertions (ok, is, cmp_ok, lives_ok, isnt_empty) and follow the established pattern of setup/test/cleanup.
1 parent 5d40032 commit 36edf20

File tree

4 files changed

+719
-0
lines changed

4 files changed

+719
-0
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
-- Test EQL comparison operators
2+
-- Tests <, <=, >, >= operators for encrypted data with ORE indexes
3+
4+
BEGIN;
5+
6+
-- Plan: count of tests to run
7+
SELECT plan(12);
8+
9+
-- Setup test data
10+
SELECT lives_ok(
11+
'SELECT create_table_with_encrypted()',
12+
'Should create table with encrypted column'
13+
);
14+
15+
SELECT lives_ok(
16+
'SELECT seed_encrypted_json()',
17+
'Should seed encrypted data'
18+
);
19+
20+
-- Test 1: Less than operator with ORE index
21+
DO $$
22+
DECLARE
23+
e eql_v2_encrypted;
24+
BEGIN
25+
e := create_encrypted_ore_json(42);
26+
27+
PERFORM ok(
28+
(SELECT count(*) FROM encrypted WHERE e < e) >= 1,
29+
'Less than operator < works with ORE encrypted data'
30+
);
31+
END;
32+
$$ LANGUAGE plpgsql;
33+
34+
-- Test 2: Less than or equal operator with ORE index
35+
DO $$
36+
DECLARE
37+
e eql_v2_encrypted;
38+
BEGIN
39+
e := create_encrypted_ore_json(42);
40+
41+
PERFORM ok(
42+
(SELECT count(*) FROM encrypted WHERE e <= e) >= 1,
43+
'Less than or equal operator <= works with ORE encrypted data'
44+
);
45+
END;
46+
$$ LANGUAGE plpgsql;
47+
48+
-- Test 3: Greater than operator with ORE index
49+
DO $$
50+
DECLARE
51+
e eql_v2_encrypted;
52+
BEGIN
53+
e := create_encrypted_ore_json(1);
54+
55+
PERFORM ok(
56+
(SELECT count(*) FROM encrypted WHERE e > e) >= 1,
57+
'Greater than operator > works with ORE encrypted data'
58+
);
59+
END;
60+
$$ LANGUAGE plpgsql;
61+
62+
-- Test 4: Greater than or equal operator with ORE index
63+
DO $$
64+
DECLARE
65+
e eql_v2_encrypted;
66+
BEGIN
67+
e := create_encrypted_ore_json(1);
68+
69+
PERFORM ok(
70+
(SELECT count(*) FROM encrypted WHERE e >= e) >= 1,
71+
'Greater than or equal operator >= works with ORE encrypted data'
72+
);
73+
END;
74+
$$ LANGUAGE plpgsql;
75+
76+
-- Test 5: Not equal operator
77+
DO $$
78+
DECLARE
79+
e eql_v2_encrypted;
80+
BEGIN
81+
e := create_encrypted_json(1, 'hm');
82+
83+
PERFORM ok(
84+
(SELECT count(*) FROM encrypted WHERE e <> e) >= 1,
85+
'Not equal operator <> works with encrypted data'
86+
);
87+
END;
88+
$$ LANGUAGE plpgsql;
89+
90+
-- Test 6: eql_v2.lt() function
91+
DO $$
92+
DECLARE
93+
e eql_v2_encrypted;
94+
BEGIN
95+
e := create_encrypted_ore_json(42);
96+
97+
PERFORM ok(
98+
(SELECT count(*) FROM encrypted WHERE eql_v2.lt(e, e)) >= 1,
99+
'eql_v2.lt() function works with ORE encrypted data'
100+
);
101+
END;
102+
$$ LANGUAGE plpgsql;
103+
104+
-- Test 7: eql_v2.lte() function
105+
DO $$
106+
DECLARE
107+
e eql_v2_encrypted;
108+
BEGIN
109+
e := create_encrypted_ore_json(42);
110+
111+
PERFORM ok(
112+
(SELECT count(*) FROM encrypted WHERE eql_v2.lte(e, e)) >= 1,
113+
'eql_v2.lte() function works with ORE encrypted data'
114+
);
115+
END;
116+
$$ LANGUAGE plpgsql;
117+
118+
-- Test 8: eql_v2.gt() function
119+
DO $$
120+
DECLARE
121+
e eql_v2_encrypted;
122+
BEGIN
123+
e := create_encrypted_ore_json(1);
124+
125+
PERFORM ok(
126+
(SELECT count(*) FROM encrypted WHERE eql_v2.gt(e, e)) >= 1,
127+
'eql_v2.gt() function works with ORE encrypted data'
128+
);
129+
END;
130+
$$ LANGUAGE plpgsql;
131+
132+
-- Test 9: eql_v2.gte() function
133+
DO $$
134+
DECLARE
135+
e eql_v2_encrypted;
136+
BEGIN
137+
e := create_encrypted_ore_json(1);
138+
139+
PERFORM ok(
140+
(SELECT count(*) FROM encrypted WHERE eql_v2.gte(e, e)) >= 1,
141+
'eql_v2.gte() function works with ORE encrypted data'
142+
);
143+
END;
144+
$$ LANGUAGE plpgsql;
145+
146+
-- Test 10: eql_v2.neq() function
147+
DO $$
148+
DECLARE
149+
e eql_v2_encrypted;
150+
BEGIN
151+
e := create_encrypted_json(1, 'hm');
152+
153+
PERFORM ok(
154+
(SELECT count(*) FROM encrypted WHERE eql_v2.neq(e, e)) >= 1,
155+
'eql_v2.neq() function works with encrypted data'
156+
);
157+
END;
158+
$$ LANGUAGE plpgsql;
159+
160+
-- Cleanup
161+
SELECT lives_ok(
162+
'SELECT drop_table_with_encrypted()',
163+
'Should drop test table'
164+
);
165+
166+
SELECT finish();
167+
ROLLBACK;
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
-- Test EQL configuration management
2+
-- Tests add_search_config, remove_search_config, modify_search_config functions
3+
4+
BEGIN;
5+
6+
-- Plan: count of tests to run
7+
SELECT plan(12);
8+
9+
-- Helper function for checking if search config exists
10+
CREATE OR REPLACE FUNCTION _search_config_exists(table_name text, column_name text, index_name text, state text DEFAULT 'pending')
11+
RETURNS boolean
12+
LANGUAGE sql STRICT PARALLEL SAFE
13+
BEGIN ATOMIC
14+
SELECT EXISTS (SELECT id FROM eql_v2_configuration c
15+
WHERE c.state = _search_config_exists.state AND
16+
c.data #> array['tables', table_name, column_name, 'indexes'] ? index_name);
17+
END;
18+
19+
-- Clean configuration table
20+
SELECT lives_ok(
21+
'TRUNCATE TABLE eql_v2_configuration',
22+
'Should truncate configuration table'
23+
);
24+
25+
-- Test 1: Add search config creates pending configuration
26+
DO $$
27+
BEGIN
28+
PERFORM eql_v2.add_search_config('users', 'name', 'match', migrating => true);
29+
30+
PERFORM ok(
31+
_search_config_exists('users', 'name', 'match'),
32+
'add_search_config creates pending configuration with match index'
33+
);
34+
END;
35+
$$ LANGUAGE plpgsql;
36+
37+
-- Test 2: Add search config with cast
38+
DO $$
39+
BEGIN
40+
PERFORM eql_v2.add_search_config('users', 'age', 'unique', 'int', migrating => true);
41+
42+
PERFORM ok(
43+
_search_config_exists('users', 'age', 'unique'),
44+
'add_search_config creates configuration with cast'
45+
);
46+
47+
PERFORM ok(
48+
EXISTS (SELECT id FROM eql_v2_configuration c
49+
WHERE c.state = 'pending' AND
50+
c.data #> array['tables', 'users', 'age'] ? 'cast_as'),
51+
'Configuration includes cast_as field'
52+
);
53+
END;
54+
$$ LANGUAGE plpgsql;
55+
56+
-- Test 3: Remove search config
57+
DO $$
58+
BEGIN
59+
PERFORM eql_v2.remove_search_config('users', 'name', 'match', migrating => true);
60+
61+
PERFORM ok(
62+
NOT _search_config_exists('users', 'name', 'match'),
63+
'remove_search_config removes match index'
64+
);
65+
END;
66+
$$ LANGUAGE plpgsql;
67+
68+
-- Test 4: Configuration preserved after removing all indexes
69+
DO $$
70+
BEGIN
71+
PERFORM eql_v2.remove_search_config('users', 'age', 'unique', migrating => true);
72+
73+
PERFORM ok(
74+
EXISTS (SELECT FROM eql_v2_configuration c WHERE c.state = 'pending'),
75+
'Pending configuration still exists after removing all indexes'
76+
);
77+
78+
PERFORM ok(
79+
(SELECT data #> array['tables', 'users', 'age', 'indexes'] = '{}'
80+
FROM eql_v2_configuration c WHERE c.state = 'pending'),
81+
'Indexes object is empty after removal'
82+
);
83+
END;
84+
$$ LANGUAGE plpgsql;
85+
86+
-- Test 5: Modify search config
87+
SELECT lives_ok(
88+
'TRUNCATE TABLE eql_v2_configuration',
89+
'Should truncate configuration table for modify test'
90+
);
91+
92+
DO $$
93+
BEGIN
94+
PERFORM eql_v2.add_search_config('users', 'email', 'match', migrating => true);
95+
PERFORM eql_v2.modify_search_config('users', 'email', 'match', 'text', '{"option": "value"}'::jsonb, migrating => true);
96+
97+
PERFORM ok(
98+
EXISTS (SELECT id FROM eql_v2_configuration c
99+
WHERE c.state = 'pending' AND
100+
c.data #> array['tables', 'users', 'email', 'indexes', 'match'] ? 'option'),
101+
'modify_search_config adds options to index configuration'
102+
);
103+
END;
104+
$$ LANGUAGE plpgsql;
105+
106+
-- Test 6: Add column to existing table
107+
SELECT lives_ok(
108+
'TRUNCATE TABLE eql_v2_configuration',
109+
'Should truncate configuration table for column test'
110+
);
111+
112+
DO $$
113+
BEGIN
114+
PERFORM create_table_with_encrypted();
115+
116+
PERFORM eql_v2.add_column('encrypted', 'e', migrating => true);
117+
118+
PERFORM cmp_ok(
119+
(SELECT count(*) FROM eql_v2_configuration c WHERE c.state = 'pending'),
120+
'=',
121+
1::bigint,
122+
'add_column creates pending configuration'
123+
);
124+
END;
125+
$$ LANGUAGE plpgsql;
126+
127+
-- Test 7: Remove column
128+
DO $$
129+
BEGIN
130+
PERFORM eql_v2.remove_column('encrypted', 'e', migrating => true);
131+
132+
PERFORM ok(
133+
(SELECT data #> array['tables'] = '{}'
134+
FROM eql_v2_configuration c WHERE c.state = 'pending'),
135+
'remove_column empties tables configuration'
136+
);
137+
138+
PERFORM drop_table_with_encrypted();
139+
END;
140+
$$ LANGUAGE plpgsql;
141+
142+
-- Cleanup helper function
143+
DROP FUNCTION _search_config_exists(text, text, text, text);
144+
145+
SELECT finish();
146+
ROLLBACK;

0 commit comments

Comments
 (0)